使用计算得到的Tensor进行slicing赋值时报错RuntimeError: The int64_t value(-1) is less than 0.

1 系统环境

硬件环境(Ascend/GPU/CPU): CPU

MindSpore版本: mindspore=1.8.1

执行模式(PyNative/ Graph):不限

Python版本: Python=3.9.13

操作系统平台: windows10

2 报错信息

2.1 问题描述

使用计算得到的Tensor进行slicing赋值时报错,但使用自己初始化的Tensor时不会。

Traceback (most recent call last):
  File "C:\Program Files\JetBrains\PyCharm 2022.3.1\plugins\python\helpers\pydev\_pydevd_bundle\pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<input>", line 1, in <module>
  File "C:\Users\Anaconda3\envs\gtn\lib\site-packages\mindspore\common\tensor.py", line 344, in __setitem__
    out = tensor_operator_registry.get('__setitem__')(self, index, value)
  File "C:\Users\Anaconda3\envs\gtn\lib\site-packages\mindspore\ops\composite\multitype_ops\_compile_utils.py", line 65, in _tensor_setitem
    return tensor_setitem_by_tensor(self, index, value)
  File "C:\Users\Anaconda3\envs\gtn\lib\site-packages\mindspore\ops\composite\multitype_ops\_compile_utils.py", line 792, in tensor_setitem_by_tensor
    return tensor_setitem_by_tensor_with_number(self, index, value)
  File "C:\Users\Anaconda3\envs\gtn\lib\site-packages\mindspore\ops\composite\multitype_ops\_compile_utils.py", line 874, in tensor_setitem_by_tensor_with_number
    return tensor_setitem_by_tensor_with_tensor(data, index, value)
  File "C:\Users\Anaconda3\envs\gtn\lib\site-packages\mindspore\ops\composite\multitype_ops\_compile_utils.py", line 864, in tensor_setitem_by_tensor_with_tensor
    return _tensor_setitem_by_int_tensor_with_tensor(data, index, value_tensor)
  File "C:\Users\Anaconda3\envs\gtn\lib\site-packages\mindspore\ops\composite\multitype_ops\_compile_utils.py", line 834, in _tensor_setitem_by_int_tensor_with_tensor
    index = F.select(index < 0, index + F.shape(data)[0], index)
  File "C:\Users\Anaconda3\envs\gtn\lib\site-packages\mindspore\common\tensor.py", line 329, in __lt__
    out = tensor_operator_registry.get('__lt__')(self, other)
  File "C:\Users\w84266017\Anaconda3\envs\gtn\lib\site-packages\mindspore\ops\primitive.py", line 294, in __call__
    return _run_op(self, self.name, args)
  File "C:\Users\Anaconda3\envs\gtn\lib\site-packages\mindspore\common\api.py", line 98, in wrapper
    results = fn(*arg, **kwargs)
  File "C:\Users\Anaconda3\envs\gtn\lib\site-packages\mindspore\ops\primitive.py", line 748, in _run_op
    output = real_run_op(obj, op_name, args)
RuntimeError: The int64_t value(-1) is less than 0.
----------------------------------------------------
- C++ Call Stack: (For framework developers)
----------------------------------------------------
mindspore/core/utils/convert_utils_base.h:66 LongToSize复制

2.2 脚本代码(代码格式,可上传附件)

import mindspore as ms

a = ms.Tensor([[1, 2, 3],
               [4, 5, 6],
               [7, 8, 9]])
b = ms.Tensor([2, 3, 3])

index = ms.Tensor([0])
a[index] = 1
a复制

重现问题脚本

import mindspore as ms

a = ms.Tensor([[1, 2, 3],
               [4, 5, 6],
               [7, 8, 9]])
b = ms.Tensor([2, 3, 3])

# to get index of "2", which should be [0]
index = (b == 2).nonzero().squeeze()
a[index] = 1  # bug here
a复制

期待结果

Tensor(shape=[3, 3], dtype=Int32, value=
[[1, 1, 1],
 [4, 5, 6],
 [7, 8, 9]])复制

3 根因分析

index = (b == 2).nonzero().squeeze() 和 index = ms.Tensor([0])的差别在于

前者会进行图编译, 在图编译过程中, 直接取index的值为-1

4 解决方案

对 index的值进行类型转换,这样图编译的时候就是获取实际运行的值,而不是-1

import mindspore as ms  
  
a = ms.Tensor([[1, 2, 3],  
               [4, 5, 6],  
               [7, 8, 9]])  
b = ms.Tensor([2, 3, 3])  
  
# to get index of "2", which should be [0]  
index = (b == 2).nonzero().squeeze()  
a[int(index)] = 1  
a