{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 依赖控制\n", "\n", "[![下载Notebook](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.0.0-alpha/resource/_static/logo_notebook.png)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.0.0-alpha/tutorials/experts/zh_cn/network/mindspore_dependency_control.ipynb) [![下载样例代码](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.0.0-alpha/resource/_static/logo_download_code.png)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.0.0-alpha/tutorials/experts/zh_cn/network/mindspore_dependency_control.py) [![查看源文件](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.0.0-alpha/resource/_static/logo_source.png)](https://gitee.com/mindspore/docs/blob/r2.0.0-alpha/tutorials/experts/source_zh_cn/network/dependency_control.ipynb)\n", "\n", "如果函数的运行结果依赖或影响外部状态,我们认为该函数具有副作用,比如函数会改变外部全局变量、函数的结果依赖全局变量的值。如果算子会改变输入参数的值或者算子的输出依赖全局参数的值,我们认为这是带副作用的算子。\n", "\n", "根据内存属性和IO状态,将副作用划分为内存副作用和IO副作用。当前内存副作用主要有Assign、优化器算子等等,IO副作用主要有Print算子。详细可以查看算子定义,内存副作用算子在定义中有side_effect_mem属性,IO副作用算子在定义中有side_effect_io属性。\n", "\n", "Depend用于处理依赖项操作。在大多数情况下,如果操作符有IO副作用或内存副作用,则将根据用户的语义执行它们,不需要另外使用Depend算子来保证执行顺序。在某些情况下,如果两个运算符A和B没有顺序依赖关系,并且A必须在B之前执行,我们建议使用Depend指定它们的执行顺序。使用方法如下:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "a = A(x)\n", "b = B(y)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在插入Depend算子后,如下:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```python\n", "a = A(x)\n", "y = Depend(y, a)\n", "b = B(y)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "值得说明的是,用于浮点数溢出状态检测的一组特殊算子它们存在隐含副作用,但又不属于IO副作用或内存副作用。此外,使用时还有严格的顺序要求,即:在使用NPUClearFloatStatus算子前需要保证NPUAllocFloatStatus已经执行,使用NPUGetFloatStatus算子前需要保证NPUClearFloatStatus已经执行。因为这些算子使用较少,目前的方案是保持它们的定义为无副作用形式,以Depend确保执行顺序。如下:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import mindspore as ms\n", "import mindspore.nn as nn\n", "from mindspore import ops, set_context, Tensor\n", "from mindspore import dtype as mstype\n", "\n", "set_context(mode=ms.GRAPH_MODE, device_target=\"Ascend\")\n", "\n", "class Net(nn.Cell):\n", " def __init__(self):\n", " super().__init__()\n", " self.alloc_status = ops.NPUAllocFloatStatus()\n", " self.get_status = ops.NPUGetFloatStatus()\n", " self.clear_status = ops.NPUClearFloatStatus()\n", " self.sub = ops.Sub()\n", " self.neg = ops.Neg()\n", "\n", " def construct(self, x):\n", " init = self.alloc_status()\n", " clear_status = self.clear_status(init)\n", " x = ops.depend(x, clear_status)\n", " res = self.sub(x, self.neg(x))\n", " init = ops.depend(init, res)\n", " get_status = self.get_status(init)\n", " res = ops.depend(res, get_status)\n", " return res\n", "\n", "value = 5\n", "data = np.full((2, 3), value, dtype=np.float16)\n", "x = Tensor(data, dtype=mstype.float16)\n", "net = Net()\n", "res = net(x)\n", "print(res)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "运行以上脚本,可以得到:\n", "\n", "```text\n", " [[10. 10. 10.]\n", " [10. 10. 10.]]\n", "```" ] } ], "metadata": { "interpreter": { "hash": "37cf91a68ac36b8a76a288ad2d126c7e4a4ba14aff99a672453c36232c072be7" }, "kernelspec": { "display_name": "MindSpore", "language": "python", "name": "mindspore" }, "language_info": { "name": "python", "version": "3.9.5" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }