GRAPH_MODE下运行ms_tensor = mint.ones_like(input_tensor, dtype=dtype)报错The pointer[device_address] is null.

1 系统环境

硬件环境(Ascend/GPU/CPU): Ascend910
MindSpore版本: mindspore=2.4.0
执行模式(PyNative/ Graph): Graph
Python版本: Python=3.9.10
操作系统平台: linux

2 报错信息

2.1 问题描述

运行下述代码报错:

2.2 脚本信息

import mindspore.numpy as mnp
import numpy as np
import mindspore as ms
from mindspore import mint, Tensor, ops, value_and_grad
from mindspore import context

# 设置为 GRAPH 模式
context.set_context(mode=context.GRAPH_MODE, device_target="Ascend")
# 设置为 PYNATIVE 模式
# context.set_context(mode=context.PYNATIVE_MODE)
"""
mindspore.mint.ones_like(input, *, dtype=None)
创建一个数值全为1的Tensor,shape和 input 相同,dtype由 dtype 决定。
如果 dtype = None,输出Tensor的数据类型会和 input 一致。
参数:input (Tensor) - 任意维度的Tensor。
关键字参数:dtype (mindspore.dtype, 可选) - 用来描述所创建的Tensor的 dtype。如果为 None ,那么将会使用 input 的dtype。默认值: None 。
返回:Tensor,具有与 input 相同的shape并填充了1。
异常:TypeError - input 不是Tensor。
"""

# 创建一个包含所有 Mindspore dtype 的列表
dtype_list = [
    ms.int8, ms.byte,
    ms.int16, ms.short,
    ms.int32, ms.intc,
    ms.int64, ms.intp,
    ms.uint8, ms.ubyte,
    # ms.uint16, ms.ushort,
    # ms.uint32, ms.uintc,
    # ms.uint64, ms.uintp,
    ms.float16, ms.half,
    ms.float32, ms.single,
    ms.float64, ms.double,
    # ms.bfloat16,
    # ms.complex64,
    # ms.complex128
]

def test_support_dtype(dtype_list):
    input_tensor = ms.tensor([[1, 2, 3], [4, 5, 6]], dtype=ms.float32)

    for dtype in dtype_list:
        try:
            ms_tensor = mint.ones_like(input_tensor, dtype=dtype)
            print(f"Success: MindSpore mint.ones_like() support {dtype}")
        except Exception as e:
            print(f"Error with dtype {dtype}: {e}")

if __name__ == "__main__":
    # 输入不同dtype,测试框架的支持度
    test_support_dtype(dtype_list)

2.3 报错信息

Error with dtype Float16: The pointer[device_address] is null.
- Framevork Unexpected ExceptionRaised
This exception is caused by franework's unexpected error. Please create an issue at https://gitee. con/nindspore/mindspore/issues to get help.
- C++ Call Stack: (For frameworkdevelopers)
mindspore/ccsrc/runtine/device/device_address_utils. cc: 1038CreatekernelTensor
Error with dtype Float32: The pointer[device_address] is null.
- Framevork Unexpected Exception Raised:
This exception is caused by franework's unexpected error. Please create an issue at https: //gitee. con/mindspore/mindspore/issues to get help.
- C++ Call Stack: (For franework developers)
mindspore/ccsrc/runtine/device/device_address_utils. cc: 1038 CreatekernelTensor复制

3 根因分析

测试代码虽然设置了图模式,但是并没有定义网络,所以相关算子还是运行在pynative模式下。

使用Graph模式需要设置ms.set_context(mode=ms.GRAPH_MODE),使用Cell类并且在construct函数中编写执行代码,此时construct函数的代码将会被编译成静态计算图。Cell定义详见Cell API文档。
但是即使代码写成如此,也不应该报错。应该是内部实现有问题,导致静态切换动态的时候出问题了。

4 解决方案

动静切换的问题需要修改mindspore代码。
原测试代码如果要测试mint.ones_like在图模式下,就需要定义在网络中,这样的话就是图模式下运行该算子。

import numpy as np  
import mindspore as ms  
from mindspore import mint, Tensor, ops, value_and_grad  
from mindspore import context  
    
# 设置为 GRAPH 模式  
context.set_context(mode=context.GRAPH_MODE, device_target="Ascend")  
# 设置为 PYNATIVE 模式  
# context.set_context(mode=context.PYNATIVE_MODE)  
"""  
mindspore.mint.ones_like(input, *, dtype=None)  
创建一个数值全为1的Tensor,shape和 input 相同,dtype由 dtype 决定。  
如果 dtype = None,输出Tensor的数据类型会和 input 一致。  
参数:input (Tensor) - 任意维度的Tensor。  
关键字参数:dtype (mindspore.dtype, 可选) - 用来描述所创建的Tensor的 dtype。如果为 None ,那么将会使用 input 的dtype。默认值: None 。  
返回:Tensor,具有与 input 相同的shape并填充了1。  
异常:TypeError - input 不是Tensor。  
"""  
    
# 创建一个包含所有 Mindspore dtype 的列表  
dtype_list = [  
    ms.int8, ms.byte,  
    ms.int16, ms.short,  
    ms.int32, ms.intc,  
    ms.int64, ms.intp,  
    ms.uint8, ms.ubyte,  
    # ms.uint16, ms.ushort,  
    # ms.uint32, ms.uintc,  
    # ms.uint64, ms.uintp,  
    ms.float16, ms.half,  
    ms.float32, ms.single,  
    ms.float64, ms.double,  
    # ms.bfloat16,  
    # ms.complex64,  
    # ms.complex128  
]  
    
    
class Network(ms.nn.Cell):  
    def __init__(self, dtype):  
        super().__init__()  
        self.dtype = dtype  
    def construct(self, x):  
        x = mint.ones_like(x, dtype=self.dtype)  
        return x  
def test_support_dtype(dtype_list):  
    input_tensor = ms.tensor([[1, 2, 3], [4, 5, 6]], dtype=ms.float32)  
    for dtype in dtype_list:  
        try:  
            n = Network(dtype)  
            n(input_tensor)  
            print(f"Success: MindSpore mint.ones_like() support {dtype}")  
        except Exception as e:  
            print(f"Error with dtype {dtype}: {e}")  
if __name__ == "__main__":  
    # 输入不同dtype,测试框架的支持度  
    test_support_dtype(dtype_list)