1 系统环境
硬件环境(Ascend/GPU/CPU): Ascend/GPU/CPU
软件环境:
MindSpore 版本: 1.8.0
执行模式: 静态图 GRAPH
Python 版本: 3.7.6
操作系统平台: Linux
2 报错信息
2.1 问题描述
在Cell网络construct函数中,使用注释不正确导致的报错问题。
2.2 报错信息
IndentationError:There are incorrect indentations in definition or comment of function: 'Net.construct'.
2.3 脚本代码
from mindspore import context,nn
context.set_context(device_target="CPU")
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.y = 2.0
def construct(self, x):
# x + 2.0
return x + self.y # commit after code
net = Net()
print(net(1))
3 根因分析
报错信息是construct函数的定义或注释有缩进问题
但是python语法对类内部的注释并没有特别的限制, mindspore框架应该对construct代码进行处理的时候抛出的异常
相关异常信息:
mindspore/_extends/parse/parser.py", line 829
827 try:
828 ast_tokens = asttokens.ASTTokens(src, parse=True)
829 except IndentationError as idt_err:
830 idt_err.filename = self.filename
831 idt_err.lineno = self.line_offset
832 idt_err.msg = f"There are incorrect indentations in definition or comment of function: " \
833 f"'{self.function_name}'."
834 raise idt_err
835 ast_tokens_cache = (ast_tokens, self.col_offset)
836 Parser.ast_cache[hexstr] = ast_tokens_cache
调用asttokens.ASTTokens 发生了异常,该处代码会将construct的代码进行处理,该函数抛出了IndentationError
为了看为什么加注释为什么会导致异常,于是将src的具体内容打印出来。
异常情况下src:
def construct(self, x):
# x + 2.0
return x + self.y # commit after code
正常情况下src:
def construct(self, x):
# x + 2.0
return x + self.y # commit after code
所以mindspore应该是把construct这段的内容前面的空格整体去除了,而且应该去掉几个空格是按照整段代码中空格数最少的那一行来处理的。
823 src = dedent(original_src)
textwrap模块的dedent函数删除字符串中的前导空格,它解决了python代码缩进与书写多行字符串的冲突问题,避免在全局定义多行字符串。
所以注释的#不能超过def
至少定义时如下:
def construct(self, x):
# x + 2.0
return x + self.y # commit after code
4 解决方案
解决方案说明:construct的注释要与代码行对齐
修改后代码:
from mindspore import context,nn
context.set_context(device_target="CPU")
class Net(nn.Cell):
def __init__(self):
super(Net, self).__init__()
self.y = 2.0
def construct(self, x):
# x + 2.0
return x + self.y # commit after code
net = Net()
print(net(1))
print的结果是 3.0