动态图模式应用

下载Notebook下载样例代码查看源文件

在动态图模式下,MindSpore支持执行单算子、普通函数和网络,以及单独求梯度的操作。下面我们将通过示例代码详细介绍这几种操作的使用方法和注意事项。

执行操作

首先,我们导入相关依赖,并设置运行模式为动态图模式:

[1]:
import numpy as np
import mindspore.ops as ops
import mindspore.nn as nn
import mindspore as ms

ms.set_context(mode=ms.PYNATIVE_MODE)

执行单算子

下面为执行加法算子mindspore.ops.Add的示例代码:

[2]:
add = ops.Add()
x = ms.Tensor(np.array([1, 2]).astype(np.float32))
y = ms.Tensor(np.array([3, 5]).astype(np.float32))
z = add(x, y)
print("x:", x.asnumpy(), "\ny:", y.asnumpy(), "\nz:", z.asnumpy())
x: [1. 2.]
y: [3. 5.]
z: [4. 7.]

执行函数

执行自定义函数add_func,示例代码如下:

[3]:
add = ops.Add()

def add_func(x, y):
    z = add(x, y)
    z = add(z, x)
    return z

x = ms.Tensor(np.array([1, 2]).astype(np.float32))
y = ms.Tensor(np.array([3, 5]).astype(np.float32))
z = add_func(x, y)
print("x:", x.asnumpy(), "\ny:", y.asnumpy(), "\nz:", z.asnumpy())
x: [1. 2.]
y: [3. 5.]
z: [5. 9.]

执行网络

执行自定义网络Net,在construct中定义网络结构,示例代码如下:

[4]:
class Net(nn.Cell):
    def __init__(self):
        super(Net, self).__init__()
        self.mul = ops.Mul()

    def construct(self, x, y):
        return self.mul(x, y)

net = Net()
x = ms.Tensor(np.array([1.0, 2.0, 3.0]).astype(np.float32))
y = ms.Tensor(np.array([4.0, 5.0, 6.0]).astype(np.float32))
z = net(x, y)

print("x:", x.asnumpy(), "\ny:", y.asnumpy(), "\nz:", z.asnumpy())
x: [1. 2. 3.]
y: [4. 5. 6.]
z: [ 4. 10. 18.]

同步执行

在动态图模式下,为了提升性能,算子在device上使用了异步执行方式,因此在算子执行错误的时候,错误信息可能会在程序执行到最后才显示。针对这种情况,MindSpore增加了一个pynative_synchronize的设置来控制算子device上是否使用异步执行。

动态图模式下算子默认为异步执行,可以通过设置context来控制是否异步执行。当算子执行失败时,可以方便地通过调用栈看到出错的代码位置。示例代码如下:

import mindspore as ms

# 通过设置pynative_synchronize来使算子同步执行
ms.set_context(mode=ms.PYNATIVE_MODE, pynative_synchronize=True)

class Net(nn.Cell):
    def __init__(self):
        super(Net, self).__init__()
        self.get_next = ops.GetNext([ms.float32], [(1, 1)], 1, "test")

    def construct(self, x1,):
        x = self.get_next()
        x = x + x1
        return x

ms.set_context()
x1 = np.random.randn(1, 1).astype(np.float32)
net = Net()
output = net(ms.Tensor(x1))
print(output.asnumpy())

输出:此时算子为同步执行,当算子执行错误时,可以看到完整的调用栈,找到出错的代码行。

Traceback (most recent call last):
  File "test.py", line 24, in <module>
    output = net(ms.Tensor(x1))
  File ".../mindspore/nn/cell.py", line 602, in __call__
    raise err
  File ".../mindspore/nn/cell.py", line 599, in __call__
    output = self._run_construct(cast_inputs, kwargs)
  File ".../mindspore/nn/cell.py", line 429, in _run_construct
    output = self.construct(*cast_inputs, **kwargs)
  File "test.py", line 17, in construct
    x = self.get_next()
  File ".../mindspore/ops/primitive.py", line 294, in __call__
    return _run_op(self, self.name, args)
  File ".../mindspore/common/api.py", line 90, in wrapper
    results = fn(*arg, **kwargs)
  File ".../mindspore/ops/primitive.py", line 754, in _run_op
    output = real_run_op(obj, op_name, args)
RuntimeError: mindspore/ccsrc/plugin/device/gpu/kernel/data/dataset_iterator_kernel.cc:139 Launch] For 'GetNext', gpu Queue(test) Open Failed: 2