目前尝试调用带属性的算子出错,且错误看不懂,该如何解决?不带属性的算子我都能正常调用;
错误信息:MemoryError: std::bad_alloc
算子定义如下:
调用代码如下:
答案内容由AI生成,仅供参考:
将标量参数改为列表形式传递:
# 修改前(错误)
y = self.roll(x, ms.Tensor(1).astype(ms.int64), ms.Tensor(2).astype(ms.int64))
# 修改后(正确)
y = self.roll(x, ms.Tensor([1]).astype(ms.int64), ms.Tensor([2]).astype(ms.int64))
更新注册信息中的 attr 定义,明确指定为列表类型:
reg_info = ms.ops.CustomRegOp("MyRoll") \
.input(0, "x", "required") \
.attr(name='shifts', param_type='required', value_type='list_int', default_value=None) \
.attr(name='dims', param_type='required', value_type='list_int', default_value=None) \
.output(0, "y", "required") \
.dtype_format(DataType.F16_Default, DataType.F16_Default) \
.target("Ascend") \
.get_op_info()
class Roll(ms.nn.Cell):
def __init__(self, func, out_shape, out_dtype):
super(Roll, self).__init__()
reg_info = ms.ops.CustomRegOp("MyRoll") \
.input(0, "x", "required") \
.attr(name='shifts', param_type='required', value_type='list_int', default_value=None) \
.attr(name='dims', param_type='required', value_type='list_int', default_value=None) \
.output(0, "y", "required") \
.dtype_format(DataType.F16_Default, DataType.F16_Default) \
.target("Ascend") \
.get_op_info()
self.roll = ms.ops.Custom(func=func,
out_shape=out_shape,
out_dtype=out_dtype,
func_type="aot",
bprop=None,
reg_info=reg_info)
def construct(self, x):
# 正确传递列表型Tensor
y = self.roll(x,
ms.Tensor([1]).astype(ms.int64), # shifts=[1]
ms.Tensor([2]).astype(ms.int64)) # dims=[2]
return y
确保 C++ 算子定义中的属性声明与使用逻辑一致:
this->Attr("shifts").ListInt(); // 声明为列表int
this->Attr("dims").ListInt(); // 声明为列表int
并在推理函数 InferShape 和 InferDataType 中正确处理这些列表属性。
添加必要的日志输出以验证参数传递:
print("Input shape:", x.shape)
print("Shifts tensor:", ms.Tensor([1]).astype(ms.int64))
print("Dims tensor:", ms.Tensor([2]).astype(ms.int64))
您在尝试调用带属性(attr)的自定义 Ascend C 算子时遇到了 MemoryError: std::bad_alloc 错误,而无属性的算子可以正常调用。根据提供的代码和错误信息,问题主要集中在以下几个方面:
MemoryError: std::bad_alloc
[WARNING] Reg info type int64_t is not same with function prototype aclIntArray*
该警告明确指出:注册信息中属性类型 int64_t 与函数原型期望的 aclIntArray* 不匹配。
类型不匹配问题:在 C++ 算子定义中,shifts 和 dims 被定义为列表整数(.ListInt()),意味着它们应该是数组类型;但在 Python 调用时传递的是单个标量张量(ms.Tensor(1)),而非列表形式。
数据类型问题:您传递的是 int64 类型,但 Ascend 自定义算子接口可能期望特定格式(如 aclIntArray*),导致类型转换失败。
内存分配失败:由于类型不匹配,底层运行时无法正确解析参数,尝试非法内存访问或分配导致 std::bad_alloc。
将标量参数改为列表形式传递:
# 修改前(错误)
y = self.roll(x, ms.Tensor(1).astype(ms.int64), ms.Tensor(2).astype(ms.int64))
# 修改后(正确)
y = self.roll(x, ms.Tensor([1]).astype(ms.int64), ms.Tensor([2]).astype(ms.int64))
更新注册信息中的 attr 定义,明确指定为列表类型:
reg_info = ms.ops.CustomRegOp("MyRoll") \
.input(0, "x", "required") \
.attr(name='shifts', param_type='required', value_type='list_int', default_value=None) \
.attr(name='dims', param_type='required', value_type='list_int', default_value=None) \
.output(0, "y", "required") \
.dtype_format(DataType.F16_Default, DataType.F16_Default) \
.target("Ascend") \
.get_op_info()
class Roll(ms.nn.Cell):
def __init__(self, func, out_shape, out_dtype):
super(Roll, self).__init__()
reg_info = ms.ops.CustomRegOp("MyRoll") \
.input(0, "x", "required") \
.attr(name='shifts', param_type='required', value_type='list_int', default_value=None) \
.attr(name='dims', param_type='required', value_type='list_int', default_value=None) \
.output(0, "y", "required") \
.dtype_format(DataType.F16_Default, DataType.F16_Default) \
.target("Ascend") \
.get_op_info()
self.roll = ms.ops.Custom(func=func,
out_shape=out_shape,
out_dtype=out_dtype,
func_type="aot",
bprop=None,
reg_info=reg_info)
def construct(self, x):
# 正确传递列表型Tensor
y = self.roll(x,
ms.Tensor([1]).astype(ms.int64), # shifts=[1]
ms.Tensor([2]).astype(ms.int64)) # dims=[2]
return y
确保 C++ 算子定义中的属性声明与使用逻辑一致:
this->Attr("shifts").ListInt(); // 声明为列表int
this->Attr("dims").ListInt(); // 声明为列表int
并在推理函数 InferShape 和 InferDataType 中正确处理这些列表属性。
添加必要的日志输出以验证参数传递:
print("Input shape:", x.shape)
print("Shifts tensor:", ms.Tensor([1]).astype(ms.int64))
print("Dims tensor:", ms.Tensor([2]).astype(ms.int64))
ListInt() 时,必须使用列表传递值。int32 或确认框架支持的整型类型,避免潜在类型冲突。export ASCEND_GLOBAL_LOG_LEVEL=1
export ASCEND_SLOG_PRINT_TO_STDOUT=1
通过上述修改,应能解决 std::bad_alloc 内存分配错误,并成功调用带属性的 Ascend C 自定义算子。
上面AI回复的不对,那些情况我早就都测试过了,都一样的错误
ops.Custom动态图模式暂不支持非tensor输入。
动态图用CustomOpBuilder的方式使用自定义算子,参考教程: 基于CustomOpBuilder的自定义算子 | MindSpore 2.8.0 教程 | 昇思MindSpore社区
如果是aclnn算子可以参考: CustomOpBuilder 通过 AclnnOpRunner 接入 ACLNN 算子 | MindSpore 2.8.0 教程 | 昇思MindSpore社区
@zhouyifengCode 用户您好,MindSpore支撑人已经分析并给出了问题的原因,由于较长时间未看到您采纳回答,这里版主将进行采纳回答的结帖操作,如果还其他疑问请发新帖子提问,谢谢支持~
此话题已在最后回复的 60 分钟后被自动关闭。不再允许新回复。