已合并
fix: enable double path for remainder scalar tensor #4018
zhang-song-rui创建于 7月13日
fix: enable double path for remainder scalar tensor #4018
已合并
zhang-song-rui创建于 7月13日
已删除 :master合入到cann/ops-mathmaster
2 个文件变更+111-82
Mmath/floor_mod/op_api/aclnn_remainder.cpp+72-82
@@ -30,18 +30,18 @@ using namespace op;
30extern "C" {30extern "C" {
31#endif31#endif
32 32 
33- static const std::initializer_list<op::DataType> ASCEND910_DTYPE_DTYPE_SUPPORT_LIST = {33+static const std::initializer_list<op::DataType> ASCEND910_DTYPE_DTYPE_SUPPORT_LIST = {
34- op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_FLOAT16, op::DataType::DT_FLOAT,34+ op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_FLOAT16, op::DataType::DT_FLOAT,
35- op::DataType::DT_DOUBLE};35+ op::DataType::DT_DOUBLE};
36- static const std::initializer_list<op::DataType> ASCEND910B_DTYPE_DTYPE_SUPPORT_LIST = {36+static const std::initializer_list<op::DataType> ASCEND910B_DTYPE_DTYPE_SUPPORT_LIST = {
37- op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_FLOAT16,37+ op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_FLOAT16,
38- op::DataType::DT_FLOAT, op::DataType::DT_DOUBLE, op::DataType::DT_BF16};38+ op::DataType::DT_FLOAT, op::DataType::DT_DOUBLE, op::DataType::DT_BF16};
39- static const std::initializer_list<op::DataType> ASCEND310P_DTYPE_DTYPE_SUPPORT_LIST = {39+static const std::initializer_list<op::DataType> ASCEND310P_DTYPE_DTYPE_SUPPORT_LIST = {
40- op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_FLOAT16, op::DataType::DT_FLOAT,40+ op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_FLOAT16, op::DataType::DT_FLOAT,
41- op::DataType::DT_DOUBLE};41+ op::DataType::DT_DOUBLE};
42- static const std::initializer_list<DataType> emptyDtypes = {};42+static const std::initializer_list<DataType> emptyDtypes = {};
43- static const std::initializer_list<op::DataType> DTYPE_SUPPORT_LIST_COMPLEX = {43+static const std::initializer_list<op::DataType> DTYPE_SUPPORT_LIST_COMPLEX = {op::DataType::DT_COMPLEX64,
44- op::DataType::DT_COMPLEX64, op::DataType::DT_COMPLEX128};44+ op::DataType::DT_COMPLEX128};
45 45 
46static const std::initializer_list<DataType>& GetDtypeSupportList(NpuArch npuArch, SocVersion socVersion)46static const std::initializer_list<DataType>& GetDtypeSupportList(NpuArch npuArch, SocVersion socVersion)
47{47{
@@ -175,9 +175,8 @@ static bool CheckPromoteType(const op::DataType selfDtype, const op::DataType ot
175 // 检查self和other能否做数据类型推导175 // 检查self和other能否做数据类型推导
176 auto promoteType = op::PromoteType(selfDtype, otherDtype);176 auto promoteType = op::PromoteType(selfDtype, otherDtype);
177 if (promoteType == DataType::DT_UNDEFINED) {177 if (promoteType == DataType::DT_UNDEFINED) {
178- OP_LOGE(178+ OP_LOGE(ACLNN_ERR_PARAM_INVALID, "self dtype %s and other dtype %s can not promote dtype.",
179- ACLNN_ERR_PARAM_INVALID, "self dtype %s and other dtype %s can not promote dtype.",179+ op::ToString(selfDtype).GetString(), op::ToString(otherDtype).GetString());
180- op::ToString(selfDtype).GetString(), op::ToString(otherDtype).GetString());
181 return false;180 return false;
182 }181 }
183 182 
@@ -191,9 +190,8 @@ static bool CheckPromoteType(const op::DataType selfDtype, const op::DataType ot
191 return false;190 return false;
192 }191 }
193 if (!CheckType(promoteType, DTYPE_SUPPORT_LIST)) {192 if (!CheckType(promoteType, DTYPE_SUPPORT_LIST)) {
194- OP_LOGE(193+ OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Promote type %s should be in dtype support list [%s].",
195- ACLNN_ERR_PARAM_INVALID, "Promote type %s should be in dtype support list [%s].",194+ op::ToString(promoteType).GetString(), op::ToString(DTYPE_SUPPORT_LIST).GetString());
196- op::ToString(promoteType).GetString(), op::ToString(DTYPE_SUPPORT_LIST).GetString());
197 return false;195 return false;
198 }196 }
199 197 
@@ -201,8 +199,8 @@ static bool CheckPromoteType(const op::DataType selfDtype, const op::DataType ot
201}199}
202 200 
203// 1. self和other没有complex 2. self能cast成castDtype 3. castDtype为算子支持的数据类型 4. castDtype能cast成out201// 1. self和other没有complex 2. self能cast成castDtype 3. castDtype为算子支持的数据类型 4. castDtype能cast成out
204-static bool CheckPromoteTypeTensorScalar(202+static bool CheckPromoteTypeTensorScalar(const op::DataType selfDtype, const op::DataType otherDtype,
205- const op::DataType selfDtype, const op::DataType otherDtype, const op::DataType outDtype)203+ const op::DataType outDtype)
206{204{
207 // 检查self和other没有为complex205 // 检查self和other没有为complex
208 if (CheckType(selfDtype, DTYPE_SUPPORT_LIST_COMPLEX) || CheckType(otherDtype, DTYPE_SUPPORT_LIST_COMPLEX)) {206 if (CheckType(selfDtype, DTYPE_SUPPORT_LIST_COMPLEX) || CheckType(otherDtype, DTYPE_SUPPORT_LIST_COMPLEX)) {
@@ -222,9 +220,8 @@ static bool CheckPromoteTypeTensorScalar(
222 return false;220 return false;
223 }221 }
224 if (!CheckType(castDtype, DTYPE_SUPPORT_LIST)) {222 if (!CheckType(castDtype, DTYPE_SUPPORT_LIST)) {
225- OP_LOGE(223+ OP_LOGE(ACLNN_ERR_PARAM_INVALID, "expected dtype %s should be in dtype support list [%s].",
226- ACLNN_ERR_PARAM_INVALID, "expected dtype %s should be in dtype support list [%s].",224+ op::ToString(castDtype).GetString(), op::ToString(DTYPE_SUPPORT_LIST).GetString());
227- op::ToString(castDtype).GetString(), op::ToString(DTYPE_SUPPORT_LIST).GetString());
228 return false;225 return false;
229 }226 }
230 227 
@@ -235,8 +232,8 @@ static bool CheckPromoteTypeTensorScalar(
235}232}
236 233 
237// 1. self和other没有complex 2. other能cast成outDtype 3. outDtype为算子支持的数据类型234// 1. self和other没有complex 2. other能cast成outDtype 3. outDtype为算子支持的数据类型
238-static bool CheckPromoteTypeScalarTensor(235+static bool CheckPromoteTypeScalarTensor(const op::DataType selfDtype, const op::DataType otherDtype,
239- const op::DataType selfDtype, const op::DataType otherDtype, const op::DataType outDtype)236+ const op::DataType outDtype)
240{237{
241 // 检查self和other没有为complex238 // 检查self和other没有为complex
242 if (CheckType(selfDtype, DTYPE_SUPPORT_LIST_COMPLEX) || CheckType(otherDtype, DTYPE_SUPPORT_LIST_COMPLEX)) {239 if (CheckType(selfDtype, DTYPE_SUPPORT_LIST_COMPLEX) || CheckType(otherDtype, DTYPE_SUPPORT_LIST_COMPLEX)) {
@@ -255,9 +252,8 @@ static bool CheckPromoteTypeScalarTensor(
255 return false;252 return false;
256 }253 }
257 if (!CheckType(outDtype, DTYPE_SUPPORT_LIST)) {254 if (!CheckType(outDtype, DTYPE_SUPPORT_LIST)) {
258- OP_LOGE(255+ OP_LOGE(ACLNN_ERR_PARAM_INVALID, "out dtype %s should be in dtype support list [%s].",
259- ACLNN_ERR_PARAM_INVALID, "out dtype %s should be in dtype support list [%s].",256+ op::ToString(outDtype).GetString(), op::ToString(DTYPE_SUPPORT_LIST).GetString());
260- op::ToString(outDtype).GetString(), op::ToString(DTYPE_SUPPORT_LIST).GetString());
261 return false;257 return false;
262 }258 }
263 259 
@@ -311,10 +307,9 @@ static bool CheckBroadcastShape(const aclTensor* self, const aclTensor* other, c
311 return true;307 return true;
312 }308 }
313 309 
314- OP_LOGE(310+ OP_LOGE(ACLNN_ERR_PARAM_INVALID,
315- ACLNN_ERR_PARAM_INVALID,311+ "expected consistent tensor shape for the broadcast shape and out, but got %s and %s respectively.",
316- "expected consistent tensor shape for the broadcast shape and out, but got %s and %s respectively.",312+ op::ToString(broadcastShape).GetString(), op::ToString(out->GetViewShape()).GetString());
317- op::ToString(broadcastShape).GetString(), op::ToString(out->GetViewShape()).GetString());
318 return false;313 return false;
319 }314 }
320 315 
@@ -372,8 +367,8 @@ static aclIntArray* GetTensorShape(const aclTensor* self, aclOpExecutor* executo
372}367}
373 368 
374// broadcast成对应shape369// broadcast成对应shape
375-static const aclTensor* BroadcastTensor(370+static const aclTensor* BroadcastTensor(const aclTensor* x, const aclTensor* out, const aclIntArray* broadcastShape,
376- const aclTensor* x, const aclTensor* out, const aclIntArray* broadcastShape, aclOpExecutor* executor)371+ aclOpExecutor* executor)
377{372{
378 // 涉及3维->4维,4维->5维,因此都reformat成ND373 // 涉及3维->4维,4维->5维,因此都reformat成ND
379 x = l0op::ReFormat(x, op::Format::FORMAT_ND);374 x = l0op::ReFormat(x, op::Format::FORMAT_ND);
@@ -396,9 +391,8 @@ static const aclTensor* BroadcastTensor(
396 return x;391 return x;
397}392}
398 393 
399-static aclnnStatus RemainderMainProcess(394+static aclnnStatus RemainderMainProcess(const aclTensor* selfContiguous, const aclTensor* otherContiguous,
400- const aclTensor* selfContiguous, const aclTensor* otherContiguous, const aclTensor* out, bool needUnsqueeze,395+ const aclTensor* out, bool needUnsqueeze, aclOpExecutor* executor)
401- aclOpExecutor* executor)
402{396{
403 auto remainderOut = l0op::FloorMod(selfContiguous, otherContiguous, executor);397 auto remainderOut = l0op::FloorMod(selfContiguous, otherContiguous, executor);
404 CHECK_RET(remainderOut != nullptr, ACLNN_ERR_INNER_NULLPTR);398 CHECK_RET(remainderOut != nullptr, ACLNN_ERR_INNER_NULLPTR);
@@ -461,9 +455,8 @@ static aclnnStatus CheckParamsTensorScalar(const aclTensor* self, const aclScala
461 // 2. self和out的shape一致455 // 2. self和out的shape一致
462 OP_CHECK_SHAPE_NOT_EQUAL(self, out, return ACLNN_ERR_PARAM_INVALID);456 OP_CHECK_SHAPE_NOT_EQUAL(self, out, return ACLNN_ERR_PARAM_INVALID);
463 // 3. self和other没有complex + self能cast成castDtype + castDtype为算子支持的数据类型 + castDtype能cast成out457 // 3. self和other没有complex + self能cast成castDtype + castDtype为算子支持的数据类型 + castDtype能cast成out
464- CHECK_RET(458+ CHECK_RET(CheckPromoteTypeTensorScalar(self->GetDataType(), other->GetDataType(), out->GetDataType()),
465- CheckPromoteTypeTensorScalar(self->GetDataType(), other->GetDataType(), out->GetDataType()),459+ ACLNN_ERR_PARAM_INVALID);
466- ACLNN_ERR_PARAM_INVALID);
467 // 4. 维度数不能超过8维460 // 4. 维度数不能超过8维
468 CHECK_RET(CheckTensorDimSize(self), ACLNN_ERR_PARAM_INVALID);461 CHECK_RET(CheckTensorDimSize(self), ACLNN_ERR_PARAM_INVALID);
469 CHECK_RET(CheckTensorDimSize(out), ACLNN_ERR_PARAM_INVALID);462 CHECK_RET(CheckTensorDimSize(out), ACLNN_ERR_PARAM_INVALID);
@@ -479,9 +472,8 @@ static aclnnStatus CheckParamsInplaceTensorScalar(const aclTensor* self, const a
479 // 2. self和out的shape一致472 // 2. self和out的shape一致
480 OP_CHECK_SHAPE_NOT_EQUAL(self, out, return ACLNN_ERR_PARAM_INVALID);473 OP_CHECK_SHAPE_NOT_EQUAL(self, out, return ACLNN_ERR_PARAM_INVALID);
481 // 3. self和other没有complex + self能cast成castDtype + castDtype为算子支持的数据类型 + castDtype能cast成out474 // 3. self和other没有complex + self能cast成castDtype + castDtype为算子支持的数据类型 + castDtype能cast成out
482- CHECK_RET(475+ CHECK_RET(CheckPromoteTypeTensorScalar(self->GetDataType(), other->GetDataType(), out->GetDataType()),
483- CheckPromoteTypeTensorScalar(self->GetDataType(), other->GetDataType(), out->GetDataType()),476+ ACLNN_ERR_PARAM_INVALID);
484- ACLNN_ERR_PARAM_INVALID);
485 // 4. 维度数不能超过8维477 // 4. 维度数不能超过8维
486 CHECK_RET(CheckTensorDimSize(self), ACLNN_ERR_PARAM_INVALID);478 CHECK_RET(CheckTensorDimSize(self), ACLNN_ERR_PARAM_INVALID);
487 CHECK_RET(CheckTensorDimSize(out), ACLNN_ERR_PARAM_INVALID);479 CHECK_RET(CheckTensorDimSize(out), ACLNN_ERR_PARAM_INVALID);
@@ -499,9 +491,8 @@ static aclnnStatus CheckParamsScalarTensor(const aclScalar* self, const aclTenso
499 // 2. other和out的shape一致491 // 2. other和out的shape一致
500 OP_CHECK_SHAPE_NOT_EQUAL(other, out, return ACLNN_ERR_PARAM_INVALID);492 OP_CHECK_SHAPE_NOT_EQUAL(other, out, return ACLNN_ERR_PARAM_INVALID);
501 // 3. self和other没有complex + other能cast成outDtype + outDtype为算子支持的数据类型493 // 3. self和other没有complex + other能cast成outDtype + outDtype为算子支持的数据类型
502- CHECK_RET(494+ CHECK_RET(CheckPromoteTypeScalarTensor(self->GetDataType(), other->GetDataType(), out->GetDataType()),
503- CheckPromoteTypeScalarTensor(self->GetDataType(), other->GetDataType(), out->GetDataType()),495+ ACLNN_ERR_PARAM_INVALID);
504- ACLNN_ERR_PARAM_INVALID);
505 // 4. 维度数不能超过8维496 // 4. 维度数不能超过8维
506 CHECK_RET(CheckTensorDimSize(other), ACLNN_ERR_PARAM_INVALID);497 CHECK_RET(CheckTensorDimSize(other), ACLNN_ERR_PARAM_INVALID);
507 CHECK_RET(CheckTensorDimSize(out), ACLNN_ERR_PARAM_INVALID);498 CHECK_RET(CheckTensorDimSize(out), ACLNN_ERR_PARAM_INVALID);
@@ -510,8 +501,8 @@ static aclnnStatus CheckParamsScalarTensor(const aclScalar* self, const aclTenso
510}501}
511 502 
512// Tensor self, Tensor other503// Tensor self, Tensor other
513-aclnnStatus ExecRemainderTensorTensorGetWorkspaceSize(504+aclnnStatus ExecRemainderTensorTensorGetWorkspaceSize(const aclTensor* self, const aclTensor* other, aclTensor* out,
514- const aclTensor* self, const aclTensor* other, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor)505+ uint64_t* workspaceSize, aclOpExecutor** executor)
515{506{
516 auto uniqueExecutor = CREATE_EXECUTOR();507 auto uniqueExecutor = CREATE_EXECUTOR();
517 CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR);508 CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR);
@@ -557,8 +548,8 @@ aclnnStatus ExecRemainderTensorTensorGetWorkspaceSize(
557 CHECK_RET(otherContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR);548 CHECK_RET(otherContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR);
558 549 
559 bool needUnsqueeze = (GetTensorDimNum(out) == 0);550 bool needUnsqueeze = (GetTensorDimNum(out) == 0);
560- auto remainderRes =551+ auto remainderRes = RemainderMainProcess(selfContiguous, otherContiguous, out, needUnsqueeze,
561- RemainderMainProcess(selfContiguous, otherContiguous, out, needUnsqueeze, uniqueExecutor.get());552+ uniqueExecutor.get());
562 CHECK_RET(remainderRes == ACLNN_SUCCESS, remainderRes);553 CHECK_RET(remainderRes == ACLNN_SUCCESS, remainderRes);
563 }554 }
564 555 
@@ -569,8 +560,8 @@ aclnnStatus ExecRemainderTensorTensorGetWorkspaceSize(
569}560}
570 561 
571// Tensor self, Scalar other562// Tensor self, Scalar other
572-aclnnStatus ExecRemainderTensorScalarGetWorkspaceSize(563+aclnnStatus ExecRemainderTensorScalarGetWorkspaceSize(const aclTensor* self, const aclScalar* other, aclTensor* out,
573- const aclTensor* self, const aclScalar* other, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor)564+ uint64_t* workspaceSize, aclOpExecutor** executor)
574{565{
575 auto uniqueExecutor = CREATE_EXECUTOR();566 auto uniqueExecutor = CREATE_EXECUTOR();
576 CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR);567 CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR);
@@ -589,8 +580,8 @@ aclnnStatus ExecRemainderTensorScalarGetWorkspaceSize(
589 auto selfCasted = l0op::Cast(selfContiguous, castDtype, uniqueExecutor.get());580 auto selfCasted = l0op::Cast(selfContiguous, castDtype, uniqueExecutor.get());
590 CHECK_RET(selfCasted != nullptr, ACLNN_ERR_INNER_NULLPTR);581 CHECK_RET(selfCasted != nullptr, ACLNN_ERR_INNER_NULLPTR);
591 582 
592- auto floorModOpOut =583+ auto floorModOpOut = l0op::FloorMod(selfCasted, uniqueExecutor.get()->ConvertToTensor(other, castDtype),
593- l0op::FloorMod(selfCasted, uniqueExecutor.get()->ConvertToTensor(other, castDtype), uniqueExecutor.get());584+ uniqueExecutor.get());
594 CHECK_RET(floorModOpOut != nullptr, ACLNN_ERR_INNER_NULLPTR);585 CHECK_RET(floorModOpOut != nullptr, ACLNN_ERR_INNER_NULLPTR);
595 586 
596 auto castOut = l0op::Cast(floorModOpOut, out->GetDataType(), uniqueExecutor.get());587 auto castOut = l0op::Cast(floorModOpOut, out->GetDataType(), uniqueExecutor.get());
@@ -607,8 +598,8 @@ aclnnStatus ExecRemainderTensorScalarGetWorkspaceSize(
607 CHECK_RET(otherContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR);598 CHECK_RET(otherContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR);
608 599 
609 bool needUnsqueeze = (GetTensorDimNum(out) == 0);600 bool needUnsqueeze = (GetTensorDimNum(out) == 0);
610- auto remainderRes =601+ auto remainderRes = RemainderMainProcess(selfContiguous, otherContiguous, out, needUnsqueeze,
611- RemainderMainProcess(selfContiguous, otherContiguous, out, needUnsqueeze, uniqueExecutor.get());602+ uniqueExecutor.get());
612 CHECK_RET(remainderRes == ACLNN_SUCCESS, remainderRes);603 CHECK_RET(remainderRes == ACLNN_SUCCESS, remainderRes);
613 }604 }
614 605 
@@ -619,8 +610,8 @@ aclnnStatus ExecRemainderTensorScalarGetWorkspaceSize(
619}610}
620 611 
621// 非inplace612// 非inplace
622-aclnnStatus aclnnRemainderTensorTensorGetWorkspaceSize(613+aclnnStatus aclnnRemainderTensorTensorGetWorkspaceSize(const aclTensor* self, const aclTensor* other, aclTensor* out,
623- const aclTensor* self, const aclTensor* other, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor)614+ uint64_t* workspaceSize, aclOpExecutor** executor)
624{615{
625 L2_DFX_PHASE_1(aclnnRemainderTensorTensor, DFX_IN(self, other), DFX_OUT(out));616 L2_DFX_PHASE_1(aclnnRemainderTensorTensor, DFX_IN(self, other), DFX_OUT(out));
626 auto ret = CheckParamsTensorTensor(self, other, out);617 auto ret = CheckParamsTensorTensor(self, other, out);
@@ -628,8 +619,8 @@ aclnnStatus aclnnRemainderTensorTensorGetWorkspaceSize(
628 return ExecRemainderTensorTensorGetWorkspaceSize(self, other, out, workspaceSize, executor);619 return ExecRemainderTensorTensorGetWorkspaceSize(self, other, out, workspaceSize, executor);
629}620}
630 621 
631-aclnnStatus aclnnRemainderTensorScalarGetWorkspaceSize(622+aclnnStatus aclnnRemainderTensorScalarGetWorkspaceSize(const aclTensor* self, const aclScalar* other, aclTensor* out,
632- const aclTensor* self, const aclScalar* other, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor)623+ uint64_t* workspaceSize, aclOpExecutor** executor)
633{624{
634 L2_DFX_PHASE_1(aclnnRemainderTensorScalar, DFX_IN(self, other), DFX_OUT(out));625 L2_DFX_PHASE_1(aclnnRemainderTensorScalar, DFX_IN(self, other), DFX_OUT(out));
635 auto ret = CheckParamsTensorScalar(self, other, out);626 auto ret = CheckParamsTensorScalar(self, other, out);
@@ -638,8 +629,8 @@ aclnnStatus aclnnRemainderTensorScalarGetWorkspaceSize(
638}629}
639 630 
640// Scalar self, Tensor other631// Scalar self, Tensor other
641-aclnnStatus aclnnRemainderScalarTensorGetWorkspaceSize(632+aclnnStatus aclnnRemainderScalarTensorGetWorkspaceSize(const aclScalar* self, const aclTensor* other, aclTensor* out,
642- const aclScalar* self, const aclTensor* other, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor)633+ uint64_t* workspaceSize, aclOpExecutor** executor)
643{634{
644 L2_DFX_PHASE_1(aclnnRemainderScalarTensor, DFX_IN(self, other), DFX_OUT(out));635 L2_DFX_PHASE_1(aclnnRemainderScalarTensor, DFX_IN(self, other), DFX_OUT(out));
645 auto uniqueExecutor = CREATE_EXECUTOR();636 auto uniqueExecutor = CREATE_EXECUTOR();
@@ -655,16 +646,15 @@ aclnnStatus aclnnRemainderScalarTensorGetWorkspaceSize(
655 return ACLNN_SUCCESS;646 return ACLNN_SUCCESS;
656 }647 }
657 auto npuArch = op::GetCurrentPlatformInfo().GetCurNpuArch();648 auto npuArch = op::GetCurrentPlatformInfo().GetCurNpuArch();
658- if (IsRegBase(npuArch) &&649+ if (IsRegBase(npuArch)) {
F

直接删除之后没有看到别的地方有对double处理

likedislike
zhang-song-rui
zhang-song-rui
7月17日 评论:
659- PromoteTypeScalarV35(other->GetDataType(), self->GetDataType()) != op::DataType::DT_DOUBLE) {
660 auto castDtype = PromoteTypeScalarV35(other->GetDataType(), self->GetDataType());650 auto castDtype = PromoteTypeScalarV35(other->GetDataType(), self->GetDataType());
661 auto otherContiguous = l0op::Contiguous(other, uniqueExecutor.get());651 auto otherContiguous = l0op::Contiguous(other, uniqueExecutor.get());
662 CHECK_RET(otherContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR);652 CHECK_RET(otherContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR);
663 auto otherCasted = l0op::Cast(otherContiguous, castDtype, uniqueExecutor.get());653 auto otherCasted = l0op::Cast(otherContiguous, castDtype, uniqueExecutor.get());
664 CHECK_RET(otherCasted != nullptr, ACLNN_ERR_INNER_NULLPTR);654 CHECK_RET(otherCasted != nullptr, ACLNN_ERR_INNER_NULLPTR);
665 655 
666- auto floorModOpOut =656+ auto floorModOpOut = l0op::FloorMod(uniqueExecutor.get()->ConvertToTensor(self, castDtype), otherCasted,
667- l0op::FloorMod(uniqueExecutor.get()->ConvertToTensor(self, castDtype), otherCasted, uniqueExecutor.get());657+ uniqueExecutor.get());
668 CHECK_RET(floorModOpOut != nullptr, ACLNN_ERR_INNER_NULLPTR);658 CHECK_RET(floorModOpOut != nullptr, ACLNN_ERR_INNER_NULLPTR);
atomgit-bot
atomgit-botatomgit-bot7月13日

🟠 High Priority

该变更移除了 aclnnRemainderScalarTensorGetWorkspaceSize 中 RegBase 分支对 DT_DOUBLE 的排除条件。变更前:当 PromoteTypeScalarV35 结果为 DT_DOUBLE 时走 else 分支(通用路径,可能走 AICPU 后端);变更后:DT_DOUBLE 场景也进入 RegBase 的 FloorMod 直接路径。

FloorMod 在 arch35 上的 AscendC kernel 实现(floor_mod_tiling_arch35.cppDoOpTiling(),第 80-107 行)仅支持 DT_FLOAT16DT_BF16DT_FLOATDT_INT32DT_INT64 五种类型,对 DT_DOUBLE 会进入 else 分支返回 ge::GRAPH_FAILED 并打印错误日志。kernel 的 DAG 定义(floor_mod_dag.h)也无 DT_DOUBLE 对应的 Op 模板。

对比同文件中另外两个类似函数 ExecRemainderTensorTensorGetWorkspaceSize(第 528 行)和 ExecRemainderTensorScalarGetWorkspaceSize(第 586 行),仍然保留了 && castDtype/promoteType != op::DataType::DT_DOUBLE 的守卫条件,说明该排除是刻意为之。

触发条件:在 RegBase(arch35)平台上,当 self(Scalar)或 other(Tensor)为 double 精度且类型提升结果为 DT_DOUBLE 时,进入该分支后将导致图编译/tiling 阶段失败,出现运行时错误。

建议:恢复对 DT_DOUBLE 的排除条件,保持与同文件中其他 RegBase FloorMod 路径一致的守卫逻辑。如果确实需要启用 double 路径,则应先在 arch35 的 FloorMod tiling 和 kernel DAG 中补齐 DT_DOUBLE 支持,再移除该守卫。

改动建议
649
- if (IsRegBase(npuArch)) {
649
+ if (IsRegBase(npuArch) &&
650
+ PromoteTypeScalarV35(other->GetDataType(), self->GetDataType()) != op::DataType::DT_DOUBLE) {
应用建议
likedislike
669 659 
670 auto castOut = l0op::Cast(floorModOpOut, out->GetDataType(), uniqueExecutor.get());660 auto castOut = l0op::Cast(floorModOpOut, out->GetDataType(), uniqueExecutor.get());
@@ -681,8 +671,8 @@ aclnnStatus aclnnRemainderScalarTensorGetWorkspaceSize(
681 CHECK_RET(otherContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR);671 CHECK_RET(otherContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR);
682 672 
683 bool needUnsqueeze = (GetTensorDimNum(out) == 0);673 bool needUnsqueeze = (GetTensorDimNum(out) == 0);
684- auto remainderRes =674+ auto remainderRes = RemainderMainProcess(selfContiguous, otherContiguous, out, needUnsqueeze,
685- RemainderMainProcess(selfContiguous, otherContiguous, out, needUnsqueeze, uniqueExecutor.get());675+ uniqueExecutor.get());
686 CHECK_RET(remainderRes == ACLNN_SUCCESS, remainderRes);676 CHECK_RET(remainderRes == ACLNN_SUCCESS, remainderRes);
687 }677 }
688 678 
@@ -693,8 +683,8 @@ aclnnStatus aclnnRemainderScalarTensorGetWorkspaceSize(
693}683}
694 684 
695// inplace685// inplace
696-aclnnStatus aclnnInplaceRemainderTensorTensorGetWorkspaceSize(686+aclnnStatus aclnnInplaceRemainderTensorTensorGetWorkspaceSize(aclTensor* selfRef, const aclTensor* other,
697- aclTensor* selfRef, const aclTensor* other, uint64_t* workspaceSize, aclOpExecutor** executor)687+ uint64_t* workspaceSize, aclOpExecutor** executor)
698{688{
699 L2_DFX_PHASE_1(aclnnInplaceRemainderTensorTensor, DFX_IN(selfRef, other), DFX_OUT(selfRef));689 L2_DFX_PHASE_1(aclnnInplaceRemainderTensorTensor, DFX_IN(selfRef, other), DFX_OUT(selfRef));
700 auto out = const_cast<aclTensor*>(selfRef);690 auto out = const_cast<aclTensor*>(selfRef);
@@ -703,8 +693,8 @@ aclnnStatus aclnnInplaceRemainderTensorTensorGetWorkspaceSize(
703 return ExecRemainderTensorTensorGetWorkspaceSize(selfRef, other, out, workspaceSize, executor);693 return ExecRemainderTensorTensorGetWorkspaceSize(selfRef, other, out, workspaceSize, executor);
704}694}
705 695 
706-aclnnStatus aclnnInplaceRemainderTensorScalarGetWorkspaceSize(696+aclnnStatus aclnnInplaceRemainderTensorScalarGetWorkspaceSize(aclTensor* selfRef, const aclScalar* other,
707- aclTensor* selfRef, const aclScalar* other, uint64_t* workspaceSize, aclOpExecutor** executor)697+ uint64_t* workspaceSize, aclOpExecutor** executor)
708{698{
709 L2_DFX_PHASE_1(aclnnInplaceRemainderTensorScalar, DFX_IN(selfRef, other), DFX_OUT(selfRef));699 L2_DFX_PHASE_1(aclnnInplaceRemainderTensorScalar, DFX_IN(selfRef, other), DFX_OUT(selfRef));
710 auto out = const_cast<aclTensor*>(selfRef);700 auto out = const_cast<aclTensor*>(selfRef);
@@ -714,40 +704,40 @@ aclnnStatus aclnnInplaceRemainderTensorScalarGetWorkspaceSize(
714}704}
715 705 
716// Tensor self, Tensor other706// Tensor self, Tensor other
717-aclnnStatus aclnnRemainderTensorTensor(707+aclnnStatus aclnnRemainderTensorTensor(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor,
718- void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream)708+ aclrtStream stream)
719{709{
720 L2_DFX_PHASE_2(aclnnRemainderTensorTensor);710 L2_DFX_PHASE_2(aclnnRemainderTensorTensor);
721 return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);711 return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);
722}712}
723 713 
724// Tensor self, Scalar other714// Tensor self, Scalar other
725-aclnnStatus aclnnRemainderTensorScalar(715+aclnnStatus aclnnRemainderTensorScalar(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor,
726- void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream)716+ aclrtStream stream)
727{717{
728 L2_DFX_PHASE_2(aclnnRemainderTensorScalar);718 L2_DFX_PHASE_2(aclnnRemainderTensorScalar);
729 return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);719 return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);
730}720}
731 721 
732// Scalar self, Tensor other722// Scalar self, Tensor other
733-aclnnStatus aclnnRemainderScalarTensor(723+aclnnStatus aclnnRemainderScalarTensor(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor,
734- void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream)724+ aclrtStream stream)
735{725{
736 L2_DFX_PHASE_2(aclnnRemainderScalarTensor);726 L2_DFX_PHASE_2(aclnnRemainderScalarTensor);
737 return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);727 return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);
738}728}
739 729 
740// Tensor self, Tensor other730// Tensor self, Tensor other
741-aclnnStatus aclnnInplaceRemainderTensorTensor(731+aclnnStatus aclnnInplaceRemainderTensorTensor(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor,
742- void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream)732+ aclrtStream stream)
743{733{
744 L2_DFX_PHASE_2(aclnnInplaceRemainderTensorTensor);734 L2_DFX_PHASE_2(aclnnInplaceRemainderTensorTensor);
745 return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);735 return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);
746}736}
747 737 
748// Tensor self, Scalar other738// Tensor self, Scalar other
749-aclnnStatus aclnnInplaceRemainderTensorScalar(739+aclnnStatus aclnnInplaceRemainderTensorScalar(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor,
750- void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream)740+ aclrtStream stream)
751{741{
752 L2_DFX_PHASE_2(aclnnInplaceRemainderTensorScalar);742 L2_DFX_PHASE_2(aclnnInplaceRemainderTensorScalar);
753 return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);743 return CommonOpExecutorRun(workspace, workspaceSize, executor, stream);
Amath/floor_mod/tests/ut/op_api/test_aclnn_remainder_scalar_tensor.cpp+39-0
@@ -0,0 +1,39 @@
1+/**
2+ * Copyright (c) 2026 Huawei Technologies Co., Ltd.
3+ * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4+ * CANN Open Software License Agreement Version 2.0 (the "License").
5+ * Please refer to the License for details. You may not use this file except in compliance with the License.
6+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7+ * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8+ * See LICENSE in the root of the software repository for the full text of the License.
9+ */
10+ 
11+#include <vector>
12+ 
13+#include "gtest/gtest.h"
14+ 
15+#include "math/floor_mod/op_api/aclnn_remainder.h"
16+#include "op_api_ut_common/op_api_ut.h"
17+#include "op_api_ut_common/scalar_desc.h"
18+#include "op_api_ut_common/tensor_desc.h"
19+#include "opdev/platform.h"
20+ 
21+using namespace op;
22+ 
23+class l2_remainder_scalar_tensor_ascend950_test : public testing::Test {
24+protected:
25+ void TearDown() override { SetPlatformNpuArch(NpuArch::DAV_2201); }
26+};
27+ 
28+TEST_F(l2_remainder_scalar_tensor_ascend950_test, double_scalar_int32_tensor_to_float16)
29+{
30+ SetPlatformNpuArch(NpuArch::DAV_3510);
31+ 
32+ auto self = ScalarDesc(2049.0);
33+ auto other = TensorDesc({1}, ACL_INT32, ACL_FORMAT_ND).Value(std::vector<int32_t>{2});
34+ auto out = TensorDesc({1}, ACL_FLOAT16, ACL_FORMAT_ND).Precision(0.0, 0.0);
35+ auto ut = OP_API_UT(aclnnRemainderScalarTensor, INPUT(self, other), OUTPUT(out));
36+ 
37+ uint64_t workspaceSize = 0;
38+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACL_SUCCESS);
39+}