{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 依赖控制\n",
    "\n",
    "[![下载Notebook](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.1/resource/_static/logo_notebook.svg)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.1/tutorials/experts/zh_cn/network/mindspore_dependency_control.ipynb) [![下载样例代码](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.1/resource/_static/logo_download_code.svg)](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/r2.1/tutorials/experts/zh_cn/network/mindspore_dependency_control.py) [![查看源文件](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/website-images/r2.1/resource/_static/logo_source.svg)](https://gitee.com/mindspore/docs/blob/r2.1/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",
    "\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 = ops.sub(x, ops.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": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.5"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}