DJL运行时调用NDArray.any()抛出MXNet异常 调试模式下执行正常
问题根因
- MXNet报错
Unknown type enum 7对应的底层类型枚举为BOOLEAN类型,该错误由异步计算时序问题+数据类型匹配不兼容共同触发: - DJL的MXNet后端默认采用异步计算调度,断点调试时的等待间隙会让后台算子计算全部完成,
orthogonallyAccessibleMaskMax的内存已被正确填充为FLOAT32类型,因此调用any()不会报错;直接运行时前面的链式算子还未完成计算,调用any()时底层拿到的临时数据是中间阶段的BOOLEAN类型,触发类型不匹配异常。
解决方案
方案1(最优):调整类型转换时机,使用布尔类型调用any()
any()方法原生适配布尔类型NDArray,把类型转换操作后置到要存入infiniteSurfaceMask之前即可:
// 先保留布尔类型做存在性判断 NDArray boolMask = columns.get(index).eq(maxs.get(index)) .logicalAnd(infiniteSurfaceMask.neg()) .logicalAnd(deltaNormalsPositions.dot(loopArgumentsMatrixMax.get(index)).gt(RADIUS_TOLERANCE)); if (boolMask.any().getBoolean()) { // 需要使用FLOAT32类型时再做转换 infiniteSurfaceMask.add(boolMask.toType(DataType.FLOAT32, true)); }
方案2:主动阻塞等待计算完成
如果业务逻辑需要提前转换为FLOAT32类型,在调用any()之前主动调用waitToRead()阻塞等待算子计算完成即可:
NDArray orthogonallyAccessibleMaskMax = columns.get(index).eq(maxs.get(index)) .logicalAnd(infiniteSurfaceMask.neg()).logicalAnd( deltaNormalsPositions.dot(loopArgumentsMatrixMax.get(index)).gt(RADIUS_TOLERANCE)) .toType(DataType.FLOAT32, true); // 主动阻塞,等待NDArray计算完成 orthogonallyAccessibleMaskMax.waitToRead(); if (orthogonallyAccessibleMaskMax.any().getBoolean()) { infiniteSurfaceMask.add(orthogonallyAccessibleMaskMax); }
方案3:手动实现判断逻辑规避API兼容问题
也可以直接对FLOAT32类型的mask求和,通过求和结果是否大于0判断是否存在真值,绕开any()的底层类型校验:
if (orthogonallyAccessibleMaskMax.sum().getFloat() > 0) { infiniteSurfaceMask.add(orthogonallyAccessibleMaskMax); }
内容的提问来源于stack exchange,提问作者sbd2
相关产品推荐
相关产品推荐

