MindSpore图编译报错TypeError: ‘int’ object is not iterable.

1 系统环境

硬件环境(Ascend/GPU/CPU): Ascend
MindSpore版本: 1.7.0
执行模式(PyNative/ Graph): Graph模式
Python版本: 3.7.5
操作系统平台: 不限

2 报错信息

2.1 问题描述

运行示例代码出现报错

2.2 报错信息

TypeError: ‘int’ object is not iterable.

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

import mindspore
from mindspore import ms_function

a = mindspore.Tensor([0, 0, 1, 1])
b = mindspore.Tensor([1, 1, 0, 0])

@ms_function
def func(a, b):
    return a & b

print(func(a, b))

3 根因分析

首先在昇腾910的notebook环境中运行脚本代码,最终一大段报错,其最早指向了func这个函数。

TypeError                                 Traceback (most recent call last)  
/tmp/ipykernel_10012/3214807805.py in <module>  
      9     return a & b  
     10   
---> 11 print(func(a, b))

又因为ms_function是将Python函数编译为一张可调用的MindSpore图。所以猜测可能是运算符出了问题。
这里尝试将与运算符换成加号,也就是两个Tensor直接相加。
如图,得到了正确的结果


因此,可以得出结论:
在MindSpore1.7.0版本中,图模式不支持“&”运算符。

4 解决方案

解决方法1:首先是升级MindSpore到最新版本,在2.0.0alpha版本中,上面的代码可以正常运行


解决方法2:
如果在不能升级版本的环境中,比如说ModelArts的昇腾环境,升级MindSpore版本驱动都会有问题,那就需要在MindSpore1.7版本内解决问题。
收先查找与运算相关的API,发现MindSpore.Ops的逐元素计算中有一个mindspore.ops.bitwise_and可以用得上。
这里还俩个大坑
第一个,MindSpore2.0中的and运算符的API和MindSpore1.7中的and运算符不一样,分别是2.0版本中的mindspore.ops.bitwise_and和1.7版本中mindspore.ops.BitwiseAnd
这俩个长得很像,用混了就会报错
第二个,MindSpore2.0中的bitwise_and支持CPU,GPU和Ascend三个平台,而1.7版本中的BitwiseAnd只支持Ascend平台
如果用在GPU或者CPU平台上,就会报错:

RuntimeError: mindspore/ccsrc/plugin/device/gpu/hal/device/kernel_info_setter.cc:100 SupportedTypeList] Unsupported op [BitwiseAnd] on GPU, Please confirm whether the device target setting is correct, or refer to the official website to query the operator support list.

最终使用1.7版本的BitwiseAnd|得到可以跑通的代码:

import mindspore   
from mindspore import ms_function   
    
a = mindspore.Tensor([0, 0, 1, 1])   
b = mindspore.Tensor([1, 1, 0, 0])   
    
bitwise_and = ops.BitwiseAnd()   
    
@ms_function   
def func(a, b):   
    return bitwise_and(a,b)   
    
print(func(a, b)) 

如图所示:

而如果要在2.0环境中使用ops中的与运算符,就更加容易一点:

import mindspore  
from mindspore import ms_function  
import mindspore.ops as ops  
    
a = mindspore.Tensor([0, 0, 1, 1])  
b = mindspore.Tensor([1, 1, 0, 0])  
    
@ms_function  
def func(a, b):  
    return ops.bitwise_and(a,b)  
    
print(func(a, b))

总而言之,2.0就是要好很多啦
解决方法3:
另外一种思路,既然ms_function和&运算相冲,那就先用numpy把与运算完成后再转换成MindSpore的Tensor。

import mindspore   
from mindspore import ms_function   
import numpy as np   
    
a = np.array([0, 0, 1, 1])   
b = np.array([1, 1, 0, 0])   
    
result = mindspore.Tensor(a & b)   
    
@ms_function   
def func(result):   
    return result   

print(func(result)) 

最终能得到正确结果