已合并
常量折叠和infershape整改 #4582
liu-lu创建于 21 天前
常量折叠和infershape整改 #4582
已合并
liu-lu创建于 21 天前
15 个文件变更+799-802
@@ -11,7 +11,7 @@
11set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62")11set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62")
12# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译12# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译
13set(SUPPORT_TILING_DIR "arch35" "arch35")13set(SUPPORT_TILING_DIR "arch35" "arch35")
14-add_all_modules_sources(OPTYPE add ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE)14+add_all_modules_sources(OPTYPE add ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE HOSTCPU TRUE)
15 15 
16add_kernel_sources(16add_kernel_sources(
17 KERNEL_SRC arch35/add.cpp17 KERNEL_SRC arch35/add.cpp
@@ -13,360 +13,340 @@
13#include <algorithm>13#include <algorithm>
14#include <complex>14#include <complex>
15 15 
16+#include "aicpu/math_aicpu_register.h"
16#include "utils/eigen_tensor.h"17#include "utils/eigen_tensor.h"
17#include "utils/kernel_util.h"18#include "utils/kernel_util.h"
18#include "cpu_kernel_utils.h"19#include "cpu_kernel_utils.h"
19 20 
20namespace {21namespace {
21-const char *const kAdd = "Add";22+const char* const kAdd = "Add";
22constexpr int64_t kParallelBytesThresh = 192LL * 1024LL;23constexpr int64_t kParallelBytesThresh = 192LL * 1024LL;
23// per-shard target ~256 KiB of output. Sized large enough to amortize24// per-shard target ~256 KiB of output. Sized large enough to amortize
24constexpr int64_t kBytesPerShard = 256LL * 1024LL;25constexpr int64_t kBytesPerShard = 256LL * 1024LL;
25-} // namespace26+} // namespace
26 27 
27namespace aicpu {28namespace aicpu {
28-uint32_t CheckPermissionType(const CpuKernelContext &ctx) {29+uint32_t CheckPermissionType(const CpuKernelContext& ctx)
29- const DataType input0_data_type = ctx.Input(kFirstInputIndex)->GetDataType();30+{
30- const DataType input1_data_type = ctx.Input(kSecondInputIndex)->GetDataType();31+ const DataType input0_data_type = ctx.Input(kFirstInputIndex)->GetDataType();
31- const DataType output_data_type = ctx.Output(kFirstOutputIndex)->GetDataType();32+ const DataType input1_data_type = ctx.Input(kSecondInputIndex)->GetDataType();
32- if (input0_data_type != output_data_type) {33+ const DataType output_data_type = ctx.Output(kFirstOutputIndex)->GetDataType();
33- KERNEL_LOG_ERROR(34+ if (input0_data_type != output_data_type) {
34- "[Add] Output must have the same dtype as input, but got "35+ KERNEL_LOG_ERROR("[Add] Output must have the same dtype as input, but got "
35- "input0[%s] input1[%s] output[%s].",36+ "input0[%s] input1[%s] output[%s].",
36- DTypeStr(input0_data_type).c_str(),37+ DTypeStr(input0_data_type).c_str(), DTypeStr(input1_data_type).c_str(),
37- DTypeStr(input1_data_type).c_str(),38+ DTypeStr(output_data_type).c_str());
38- DTypeStr(output_data_type).c_str());39+ return KERNEL_STATUS_PARAM_INVALID;
39- return KERNEL_STATUS_PARAM_INVALID;40+ }
40- }41+ return KERNEL_STATUS_OK;
41- return KERNEL_STATUS_OK;
42}42}
43 43 
44-uint32_t AddCpuKernel::Compute(CpuKernelContext &ctx) {44+uint32_t AddCpuKernel::Compute(CpuKernelContext& ctx)
45- KERNEL_HANDLE_ERROR(NormalMathCheck(ctx), "Normal match check params failed.");45+{
46- KERNEL_HANDLE_ERROR(CheckPermissionType(ctx), "Type permission check failed.");46+ KERNEL_HANDLE_ERROR(NormalMathCheck(ctx), "Normal match check params failed.");
47- Tensor *input0 = ctx.Input(kFirstInputIndex);47+ KERNEL_HANDLE_ERROR(CheckPermissionType(ctx), "Type permission check failed.");
48- Tensor *input1 = ctx.Input(kSecondInputIndex);48+ Tensor* input0 = ctx.Input(kFirstInputIndex);
49- if ((input0->GetDataSize() == 0) || (input1->GetDataSize() == 0)) {49+ Tensor* input1 = ctx.Input(kSecondInputIndex);
50- KERNEL_LOG_INFO("[%s] Input is empty tensor.", ctx.GetOpType().c_str());50+ if ((input0->GetDataSize() == 0) || (input1->GetDataSize() == 0)) {
51- return KERNEL_STATUS_OK;51+ KERNEL_LOG_INFO("[%s] Input is empty tensor.", ctx.GetOpType().c_str());
52- }52+ return KERNEL_STATUS_OK;
53+ }
53 54 
54- const DataType input0_data_type = input0->GetDataType();55+ const DataType input0_data_type = input0->GetDataType();
55- KERNEL_LOG_INFO("[%s] Compute begin, dtype=%d, in0_bytes=%lu, in1_bytes=%lu, out_bytes=%lu.",56+ KERNEL_LOG_INFO("[%s] Compute begin, dtype=%d, in0_bytes=%lu, in1_bytes=%lu, out_bytes=%lu.",
56- ctx.GetOpType().c_str(), static_cast<int>(input0_data_type),57+ ctx.GetOpType().c_str(), static_cast<int>(input0_data_type), input0->GetDataSize(),
57- input0->GetDataSize(), input1->GetDataSize(),58+ input1->GetDataSize(), ctx.Output(kFirstOutputIndex)->GetDataSize());
58- ctx.Output(kFirstOutputIndex)->GetDataSize());
59 59 
60- // choose compute function depend on dataType60+ // choose compute function depend on dataType
61- switch (input0_data_type) {61+ switch (input0_data_type) {
62- case DT_FLOAT16:62+ case DT_FLOAT16:
63- return AddCompute<Eigen::half>(ctx);63+ return AddCompute<Eigen::half>(ctx);
64- case DT_FLOAT:64+ case DT_FLOAT:
65- return AddCompute<float>(ctx);65+ return AddCompute<float>(ctx);
66- case DT_DOUBLE:66+ case DT_DOUBLE:
67- return AddCompute<double>(ctx);67+ return AddCompute<double>(ctx);
68- case DT_INT8:68+ case DT_INT8:
69- return AddCompute<int8_t>(ctx);69+ return AddCompute<int8_t>(ctx);
70- case DT_INT16:70+ case DT_INT16:
71- return AddCompute<int16_t>(ctx);71+ return AddCompute<int16_t>(ctx);
72- case DT_INT32:72+ case DT_INT32:
73- return AddCompute<int32_t>(ctx);73+ return AddCompute<int32_t>(ctx);
74- case DT_INT64:74+ case DT_INT64:
75- return AddCompute<int64_t>(ctx);75+ return AddCompute<int64_t>(ctx);
76- case DT_UINT8:76+ case DT_UINT8:
77- return AddCompute<uint8_t>(ctx);77+ return AddCompute<uint8_t>(ctx);
78- case DT_UINT16:78+ case DT_UINT16:
79- return AddCompute<uint16_t>(ctx);79+ return AddCompute<uint16_t>(ctx);
80- case DT_UINT32:80+ case DT_UINT32:
81- return AddCompute<uint32_t>(ctx);81+ return AddCompute<uint32_t>(ctx);
82- case DT_UINT64:82+ case DT_UINT64:
83- return AddCompute<uint64_t>(ctx);83+ return AddCompute<uint64_t>(ctx);
84- case DT_COMPLEX64:84+ case DT_COMPLEX64:
85- return AddCompute<std::complex<float>>(ctx);85+ return AddCompute<std::complex<float>>(ctx);
86- case DT_COMPLEX128:86+ case DT_COMPLEX128:
87- return AddCompute<std::complex<double>>(ctx);87+ return AddCompute<std::complex<double>>(ctx);
88- default:88+ default:
89- KERNEL_LOG_ERROR(89+ KERNEL_LOG_ERROR("[%s] Data type of input is not supported, got dtype=[%s]. "
90- "[%s] Data type of input is not supported, got dtype=[%s]. "90+ "Expect one of {FP16,FP32,FP64,INT8..INT64,UINT8..UINT64,CPX64,CPX128}.",
91- "Expect one of {FP16,FP32,FP64,INT8..INT64,UINT8..UINT64,CPX64,CPX128}.",91+ ctx.GetOpType().c_str(), DTypeStr(input0_data_type).c_str());
92- ctx.GetOpType().c_str(), DTypeStr(input0_data_type).c_str());92+ return KERNEL_STATUS_PARAM_INVALID;
93- return KERNEL_STATUS_PARAM_INVALID;93+ }
94- }
95}94}
96 95 
97template <typename Body>96template <typename Body>
98-uint32_t AddCpuKernel::RunMaybeParallel(const CpuKernelContext &ctx,97+uint32_t AddCpuKernel::RunMaybeParallel(const CpuKernelContext& ctx, const char* tag, int64_t total, int64_t elem_bytes,
99- const char *tag, int64_t total,98+ const Body& body) const
100- int64_t elem_bytes,99+{
101- const Body &body) const {100+ const int64_t total_bytes = total * elem_bytes;
102- const int64_t total_bytes = total * elem_bytes;101+ if (total_bytes < kParallelBytesThresh) {
103- if (total_bytes < kParallelBytesThresh) {102+ KERNEL_LOG_INFO("[%s] %s serial path, total_bytes=%ld.", ctx.GetOpType().c_str(), tag, total_bytes);
104- KERNEL_LOG_INFO("[%s] %s serial path, total_bytes=%ld.",103+ body(0, total);
105- ctx.GetOpType().c_str(), tag, total_bytes);104+ return KERNEL_STATUS_OK;
106- body(0, total);105+ }
106+ // Guard against zero/negative elem_bytes. All current callers pass
107+ // sizeof(T) which is always >= 1, but this keeps the divisor safe for
108+ // any future caller and silences static analyzers.
109+ if (__builtin_expect(elem_bytes <= 0, 0)) {
110+ KERNEL_LOG_ERROR("[%s] %s invalid elem_bytes=%ld, fallback to serial.", ctx.GetOpType().c_str(), tag,
111+ elem_bytes);
112+ body(0, total);
113+ return KERNEL_STATUS_OK;
114+ }
115+ const int64_t per_unit = std::max<int64_t>(1, kBytesPerShard / elem_bytes);
116+ KERNEL_LOG_INFO("[%s] %s parallel path, total=%ld, per_unit=%ld.", ctx.GetOpType().c_str(), tag, total, per_unit);
117+ const uint32_t rc = CpuKernelUtils::ParallelFor(ctx, total, per_unit, body);
118+ if (__builtin_expect(rc != KERNEL_STATUS_OK, 0)) {
119+ KERNEL_LOG_ERROR("[%s] %s ParallelFor failed, rc=%u, total=%ld, per_unit=%ld.", ctx.GetOpType().c_str(), tag,
120+ rc, total, per_unit);
121+ return rc;
122+ }
107 return KERNEL_STATUS_OK;123 return KERNEL_STATUS_OK;
108- }124+}
109- // Guard against zero/negative elem_bytes. All current callers pass125+ 
110- // sizeof(T) which is always >= 1, but this keeps the divisor safe for126+template <typename T>
111- // any future caller and silences static analyzers.127+uint32_t AddCpuKernel::AddSameShape(const CpuKernelContext& ctx, const T* x0, const T* x1, T* y, int64_t total) const
112- if (__builtin_expect(elem_bytes <= 0, 0)) {128+{
113- KERNEL_LOG_ERROR("[%s] %s invalid elem_bytes=%ld, fallback to serial.",129+ auto body = [x0, x1, y](int64_t beg, int64_t end) {
114- ctx.GetOpType().c_str(), tag, elem_bytes);130+ const T* __restrict__ a = x0 + beg;
115- body(0, total);131+ const T* __restrict__ b = x1 + beg;
132+ T* __restrict__ o = y + beg;
133+ const int64_t n = end - beg;
134+ for (int64_t i = 0; i < n; ++i) {
135+ o[i] = a[i] + b[i];
136+ }
137+ };
138+ return RunMaybeParallel(ctx, "same-shape", total, static_cast<int64_t>(sizeof(T)), body);
139+}
140+ 
141+template <typename T>
142+uint32_t AddCpuKernel::AddScalarBcast(const CpuKernelContext& ctx, const T* vec, T scalar_val, T* y,
143+ int64_t total) const
144+{
145+ auto body = [vec, scalar_val, y](int64_t beg, int64_t end) {
146+ const T* __restrict__ a = vec + beg;
147+ T* __restrict__ o = y + beg;
148+ const T s = scalar_val;
149+ const int64_t n = end - beg;
150+ for (int64_t i = 0; i < n; ++i) {
151+ o[i] = a[i] + s;
152+ }
153+ };
154+ return RunMaybeParallel(ctx, "scalar-bcast", total, static_cast<int64_t>(sizeof(T)), body);
155+}
156+ 
157+template <typename T>
158+uint32_t AddCpuKernel::AddGenericBcast(const CpuKernelContext& ctx, BCalcInfo& calc_info) const
159+{
160+ (void)ctx;
161+ return AddCalculateWithRankCheck<T>(ctx, calc_info);
162+}
163+ 
164+uint32_t AddCpuKernel::ValidateAndBroadcast(const CpuKernelContext& ctx, BCalcInfo& calc_info) const
165+{
166+ // Raw-shape validation (must match the original kernel's failure modes):
167+ // 1. Any raw tensor rank > 8 is rejected even if size-1 dims could be
168+ // squeezed away by Bcast (keeps parity with the original Eigen path
169+ // that switches on calc_info.shape_out.size() up to kRank8).
170+ // 2. Both inputs must broadcast to the declared output shape; otherwise
171+ // reject. Bcast internally only derives a compatible broadcast shape
172+ // from the two inputs and never cross-checks the output tensor.
173+ const auto& raw0 = calc_info.input_0->GetTensorShape()->GetDimSizes();
174+ const auto& raw1 = calc_info.input_1->GetTensorShape()->GetDimSizes();
175+ const auto& raw_out = calc_info.output->GetTensorShape()->GetDimSizes();
176+ if (raw0.size() > static_cast<size_t>(kRank8) || raw1.size() > static_cast<size_t>(kRank8) ||
177+ raw_out.size() > static_cast<size_t>(kRank8)) {
178+ KERNEL_LOG_ERROR("[%s] Rank of input/output must be <= 8, got in0_rank=%zu, "
179+ "in1_rank=%zu, out_rank=%zu.",
180+ ctx.GetOpType().c_str(), raw0.size(), raw1.size(), raw_out.size());
181+ return KERNEL_STATUS_PARAM_INVALID;
182+ }
183+ 
184+ Bcast bcast;
185+ if (bcast.GenerateBcastInfo(calc_info) != KERNEL_STATUS_OK) {
186+ KERNEL_LOG_ERROR("[%s] Generate broadcast info failed.", ctx.GetOpType().c_str());
187+ return KERNEL_STATUS_PARAM_INVALID;
188+ }
189+ bcast.GetBcastVec(calc_info);
190+ 
191+ // Validate declared output shape against the broadcast result. The rank
192+ // must match and every dim must equal the broadcast dim.
193+ if (raw_out.size() != calc_info.shape_out.size()) {
194+ KERNEL_LOG_ERROR("[%s] Output rank [%zu] does not match broadcast rank [%zu].", ctx.GetOpType().c_str(),
195+ raw_out.size(), calc_info.shape_out.size());
196+ return KERNEL_STATUS_PARAM_INVALID;
197+ }
198+ for (size_t i = 0; i < raw_out.size(); ++i) {
199+ if (raw_out[i] != calc_info.shape_out[i]) {
200+ KERNEL_LOG_ERROR("[%s] Output dim[%zu]=%ld mismatches broadcast dim=%ld.", ctx.GetOpType().c_str(), i,
201+ raw_out[i], calc_info.shape_out[i]);
202+ return KERNEL_STATUS_PARAM_INVALID;
203+ }
204+ }
116 return KERNEL_STATUS_OK;205 return KERNEL_STATUS_OK;
117- }
118- const int64_t per_unit = std::max<int64_t>(1, kBytesPerShard / elem_bytes);
119- KERNEL_LOG_INFO("[%s] %s parallel path, total=%ld, per_unit=%ld.",
120- ctx.GetOpType().c_str(), tag, total, per_unit);
121- const uint32_t rc = CpuKernelUtils::ParallelFor(ctx, total, per_unit, body);
122- if (__builtin_expect(rc != KERNEL_STATUS_OK, 0)) {
123- KERNEL_LOG_ERROR("[%s] %s ParallelFor failed, rc=%u, total=%ld, per_unit=%ld.",
124- ctx.GetOpType().c_str(), tag, rc, total, per_unit);
125- return rc;
126- }
127- return KERNEL_STATUS_OK;
128}206}
129 207 
130template <typename T>208template <typename T>
131-uint32_t AddCpuKernel::AddSameShape(const CpuKernelContext &ctx, const T *x0,209+uint32_t AddCpuKernel::AddCompute(const CpuKernelContext& ctx) const
132- const T *x1, T *y, int64_t total) const {210+{
133- auto body = [x0, x1, y](int64_t beg, int64_t end) {211+ BCalcInfo calc_info;
134- const T *__restrict__ a = x0 + beg;212+ calc_info.input_0 = ctx.Input(kFirstInputIndex);
135- const T *__restrict__ b = x1 + beg;213+ calc_info.input_1 = ctx.Input(kSecondInputIndex);
136- T *__restrict__ o = y + beg;214+ calc_info.output = ctx.Output(kFirstOutputIndex);
137- const int64_t n = end - beg;215+ 
138- for (int64_t i = 0; i < n; ++i) {216+ KERNEL_CHECK_NULLPTR(calc_info.input_0->GetData(), KERNEL_STATUS_PARAM_INVALID, "[%s] Get input[0] data failed",
139- o[i] = a[i] + b[i];217+ ctx.GetOpType().c_str())
218+ KERNEL_CHECK_NULLPTR(calc_info.input_1->GetData(), KERNEL_STATUS_PARAM_INVALID, "[%s] Get input[1] data failed",
219+ ctx.GetOpType().c_str())
220+ KERNEL_CHECK_NULLPTR(calc_info.output->GetData(), KERNEL_STATUS_PARAM_INVALID, "[%s] Get output data failed",
221+ ctx.GetOpType().c_str())
222+ 
223+ T* const x0_ptr = PtrToPtr<void, T>(calc_info.input_0->GetData());
224+ T* const x1_ptr = PtrToPtr<void, T>(calc_info.input_1->GetData());
225+ T* const y_ptr = PtrToPtr<void, T>(calc_info.output->GetData());
226+ 
227+ const int64_t n0 = calc_info.input_0->NumElements();
228+ const int64_t n1 = calc_info.input_1->NumElements();
229+ const int64_t ny = calc_info.output->NumElements();
230+ 
231+ KERNEL_LOG_INFO("[%s] Input[0] size=%lu, Input[1] size=%lu, Output size=%lu.", ctx.GetOpType().c_str(),
232+ calc_info.input_0->GetDataSize(), calc_info.input_1->GetDataSize(),
233+ calc_info.output->GetDataSize());
234+ 
235+ const uint32_t vrc = ValidateAndBroadcast(ctx, calc_info);
236+ if (vrc != KERNEL_STATUS_OK) {
237+ return vrc;
140 }238 }
141- };
142- return RunMaybeParallel(ctx, "same-shape", total,
143- static_cast<int64_t>(sizeof(T)), body);
144-}
145 239 
146-template <typename T>240+ const auto& raw0 = calc_info.input_0->GetTensorShape()->GetDimSizes();
147-uint32_t AddCpuKernel::AddScalarBcast(const CpuKernelContext &ctx, const T *vec,241+ const auto& raw1 = calc_info.input_1->GetTensorShape()->GetDimSizes();
148- T scalar_val, T *y,242+ const auto& raw_out = calc_info.output->GetTensorShape()->GetDimSizes();
149- int64_t total) const {243+ 
150- auto body = [vec, scalar_val, y](int64_t beg, int64_t end) {244+ if (raw0 == raw1 && raw0 == raw_out && n0 == n1 && n0 == ny) {
151- const T *__restrict__ a = vec + beg;245+ KERNEL_LOG_INFO("[%s] same-shape branch selected, elems=%ld.", ctx.GetOpType().c_str(), ny);
152- T *__restrict__ o = y + beg;246+ return AddSameShape<T>(ctx, x0_ptr, x1_ptr, y_ptr, ny);
153- const T s = scalar_val;
154- const int64_t n = end - beg;
155- for (int64_t i = 0; i < n; ++i) {
156- o[i] = a[i] + s;
157 }247 }
158- };248+ if (n0 == 1 && n1 == ny && raw1 == raw_out) {
159- return RunMaybeParallel(ctx, "scalar-bcast", total,249+ KERNEL_LOG_INFO("[%s] x0-scalar bcast branch selected, elems=%ld.", ctx.GetOpType().c_str(), ny);
160- static_cast<int64_t>(sizeof(T)), body);250+ return AddScalarBcast<T>(ctx, x1_ptr, *x0_ptr, y_ptr, ny);
161-}
162- 
163-template <typename T>
164-uint32_t AddCpuKernel::AddGenericBcast(const CpuKernelContext &ctx,
165- BCalcInfo &calc_info) const {
166- (void)ctx;
167- return AddCalculateWithRankCheck<T>(ctx, calc_info);
168-}
169- 
170-uint32_t AddCpuKernel::ValidateAndBroadcast(const CpuKernelContext &ctx,
171- BCalcInfo &calc_info) const {
172- // Raw-shape validation (must match the original kernel's failure modes):
173- // 1. Any raw tensor rank > 8 is rejected even if size-1 dims could be
174- // squeezed away by Bcast (keeps parity with the original Eigen path
175- // that switches on calc_info.shape_out.size() up to kRank8).
176- // 2. Both inputs must broadcast to the declared output shape; otherwise
177- // reject. Bcast internally only derives a compatible broadcast shape
178- // from the two inputs and never cross-checks the output tensor.
179- const auto &raw0 = calc_info.input_0->GetTensorShape()->GetDimSizes();
180- const auto &raw1 = calc_info.input_1->GetTensorShape()->GetDimSizes();
181- const auto &raw_out = calc_info.output->GetTensorShape()->GetDimSizes();
182- if (raw0.size() > static_cast<size_t>(kRank8) ||
183- raw1.size() > static_cast<size_t>(kRank8) ||
184- raw_out.size() > static_cast<size_t>(kRank8)) {
185- KERNEL_LOG_ERROR(
186- "[%s] Rank of input/output must be <= 8, got in0_rank=%zu, "
187- "in1_rank=%zu, out_rank=%zu.",
188- ctx.GetOpType().c_str(), raw0.size(), raw1.size(), raw_out.size());
189- return KERNEL_STATUS_PARAM_INVALID;
190- }
191- 
192- Bcast bcast;
193- if (bcast.GenerateBcastInfo(calc_info) != KERNEL_STATUS_OK) {
194- KERNEL_LOG_ERROR("[%s] Generate broadcast info failed.",
195- ctx.GetOpType().c_str());
196- return KERNEL_STATUS_PARAM_INVALID;
197- }
198- bcast.GetBcastVec(calc_info);
199- 
200- // Validate declared output shape against the broadcast result. The rank
201- // must match and every dim must equal the broadcast dim.
202- if (raw_out.size() != calc_info.shape_out.size()) {
203- KERNEL_LOG_ERROR(
204- "[%s] Output rank [%zu] does not match broadcast rank [%zu].",
205- ctx.GetOpType().c_str(), raw_out.size(), calc_info.shape_out.size());
206- return KERNEL_STATUS_PARAM_INVALID;
207- }
208- for (size_t i = 0; i < raw_out.size(); ++i) {
209- if (raw_out[i] != calc_info.shape_out[i]) {
210- KERNEL_LOG_ERROR(
211- "[%s] Output dim[%zu]=%ld mismatches broadcast dim=%ld.",
212- ctx.GetOpType().c_str(), i, raw_out[i], calc_info.shape_out[i]);
213- return KERNEL_STATUS_PARAM_INVALID;
214 }251 }
215- }252+ if (n1 == 1 && n0 == ny && raw0 == raw_out) {
216- return KERNEL_STATUS_OK;253+ KERNEL_LOG_INFO("[%s] x1-scalar bcast branch selected, elems=%ld.", ctx.GetOpType().c_str(), ny);
217-}254+ return AddScalarBcast<T>(ctx, x0_ptr, *x1_ptr, y_ptr, ny);
218- 255+ }
219-template <typename T>256+ return AddGenericBcast<T>(ctx, calc_info);
220-uint32_t AddCpuKernel::AddCompute(const CpuKernelContext &ctx) const {257+}
221- BCalcInfo calc_info;258+ 
222- calc_info.input_0 = ctx.Input(kFirstInputIndex);259+template <typename T>
223- calc_info.input_1 = ctx.Input(kSecondInputIndex);260+uint32_t AddCpuKernel::AddCalculateWithRankCheck(const CpuKernelContext& ctx, BCalcInfo& calc_info) const
224- calc_info.output = ctx.Output(kFirstOutputIndex);261+{
225- 262+ const int32_t rank = static_cast<int32_t>(calc_info.shape_out.size());
226- KERNEL_CHECK_NULLPTR(calc_info.input_0->GetData(),263+ switch (rank) {
227- KERNEL_STATUS_PARAM_INVALID, "[%s] Get input[0] data failed",264+ case 0: {
228- ctx.GetOpType().c_str())265+ // Rank-0 already handled by same-shape fast path, but keep for safety.
229- KERNEL_CHECK_NULLPTR(calc_info.input_1->GetData(),266+ const T v0 = *PtrToPtr<void, const T>(calc_info.input_0->GetData());
230- KERNEL_STATUS_PARAM_INVALID, "[%s] Get input[1] data failed",267+ const T v1 = *PtrToPtr<void, const T>(calc_info.input_1->GetData());
231- ctx.GetOpType().c_str())268+ T* value_out = PtrToPtr<void, T>(calc_info.output->GetData());
232- KERNEL_CHECK_NULLPTR(calc_info.output->GetData(), KERNEL_STATUS_PARAM_INVALID,269+ *value_out = v0 + v1;
233- "[%s] Get output data failed", ctx.GetOpType().c_str())270+ return KERNEL_STATUS_OK;
234- 271+ }
235- T *const x0_ptr = PtrToPtr<void, T>(calc_info.input_0->GetData());272+ case kRank1:
236- T *const x1_ptr = PtrToPtr<void, T>(calc_info.input_1->GetData());273+ return AddCalculateWithAlignedCheck<kRank1, T>(ctx, calc_info);
237- T *const y_ptr = PtrToPtr<void, T>(calc_info.output->GetData());274+ case kRank2:
238- 275+ return AddCalculateWithAlignedCheck<kRank2, T>(ctx, calc_info);
239- const int64_t n0 = calc_info.input_0->NumElements();276+ case kRank3:
240- const int64_t n1 = calc_info.input_1->NumElements();277+ return AddCalculateWithAlignedCheck<kRank3, T>(ctx, calc_info);
241- const int64_t ny = calc_info.output->NumElements();278+ case kRank4:
242- 279+ return AddCalculateWithAlignedCheck<kRank4, T>(ctx, calc_info);
243- KERNEL_LOG_INFO("[%s] Input[0] size=%lu, Input[1] size=%lu, Output size=%lu.",280+ case kRank5:
244- ctx.GetOpType().c_str(), calc_info.input_0->GetDataSize(),281+ return AddCalculateWithAlignedCheck<kRank5, T>(ctx, calc_info);
245- calc_info.input_1->GetDataSize(),282+ case kRank6:
246- calc_info.output->GetDataSize());283+ return AddCalculateWithAlignedCheck<kRank6, T>(ctx, calc_info);
247- 284+ case kRank7:
248- const uint32_t vrc = ValidateAndBroadcast(ctx, calc_info);285+ return AddCalculateWithAlignedCheck<kRank7, T>(ctx, calc_info);
249- if (vrc != KERNEL_STATUS_OK) {286+ case kRank8:
250- return vrc;287+ return AddCalculateWithAlignedCheck<kRank8, T>(ctx, calc_info);
251- }288+ default:
252- 289+ KERNEL_LOG_ERROR("[%s] Rank of output must be in [0,8], got rank=%zu.", ctx.GetOpType().c_str(),
253- const auto &raw0 = calc_info.input_0->GetTensorShape()->GetDimSizes();290+ calc_info.shape_out.size());
254- const auto &raw1 = calc_info.input_1->GetTensorShape()->GetDimSizes();291+ return KERNEL_STATUS_PARAM_INVALID;
255- const auto &raw_out = calc_info.output->GetTensorShape()->GetDimSizes();
256- 
257- if (raw0 == raw1 && raw0 == raw_out && n0 == n1 && n0 == ny) {
258- KERNEL_LOG_INFO("[%s] same-shape branch selected, elems=%ld.",
259- ctx.GetOpType().c_str(), ny);
260- return AddSameShape<T>(ctx, x0_ptr, x1_ptr, y_ptr, ny);
261- }
262- if (n0 == 1 && n1 == ny && raw1 == raw_out) {
263- KERNEL_LOG_INFO("[%s] x0-scalar bcast branch selected, elems=%ld.",
264- ctx.GetOpType().c_str(), ny);
265- return AddScalarBcast<T>(ctx, x1_ptr, *x0_ptr, y_ptr, ny);
266- }
267- if (n1 == 1 && n0 == ny && raw0 == raw_out) {
268- KERNEL_LOG_INFO("[%s] x1-scalar bcast branch selected, elems=%ld.",
269- ctx.GetOpType().c_str(), ny);
270- return AddScalarBcast<T>(ctx, x0_ptr, *x1_ptr, y_ptr, ny);
271- }
272- return AddGenericBcast<T>(ctx, calc_info);
273-}
274- 
275-template <typename T>
276-uint32_t AddCpuKernel::AddCalculateWithRankCheck(const CpuKernelContext &ctx,
277- BCalcInfo &calc_info) const {
278- const int32_t rank = static_cast<int32_t>(calc_info.shape_out.size());
279- switch (rank) {
280- case 0: {
281- // Rank-0 already handled by same-shape fast path, but keep for safety.
282- const T v0 = *PtrToPtr<void, const T>(calc_info.input_0->GetData());
283- const T v1 = *PtrToPtr<void, const T>(calc_info.input_1->GetData());
284- T *value_out = PtrToPtr<void, T>(calc_info.output->GetData());
285- *value_out = v0 + v1;
286- return KERNEL_STATUS_OK;
287 }292 }
288- case kRank1:
289- return AddCalculateWithAlignedCheck<kRank1, T>(ctx, calc_info);
290- case kRank2:
291- return AddCalculateWithAlignedCheck<kRank2, T>(ctx, calc_info);
292- case kRank3:
293- return AddCalculateWithAlignedCheck<kRank3, T>(ctx, calc_info);
294- case kRank4:
295- return AddCalculateWithAlignedCheck<kRank4, T>(ctx, calc_info);
296- case kRank5:
297- return AddCalculateWithAlignedCheck<kRank5, T>(ctx, calc_info);
298- case kRank6:
299- return AddCalculateWithAlignedCheck<kRank6, T>(ctx, calc_info);
300- case kRank7:
301- return AddCalculateWithAlignedCheck<kRank7, T>(ctx, calc_info);
302- case kRank8:
303- return AddCalculateWithAlignedCheck<kRank8, T>(ctx, calc_info);
304- default:
305- KERNEL_LOG_ERROR(
306- "[%s] Rank of output must be in [0,8], got rank=%zu.",
307- ctx.GetOpType().c_str(), calc_info.shape_out.size());
308- return KERNEL_STATUS_PARAM_INVALID;
309- }
310}293}
311 294 
312template <int32_t RANK, typename T>295template <int32_t RANK, typename T>
313-uint32_t AddCpuKernel::AddCalculateWithAlignedCheck(296+uint32_t AddCpuKernel::AddCalculateWithAlignedCheck(const CpuKernelContext& ctx, BCalcInfo& calc_info) const
314- const CpuKernelContext &ctx, BCalcInfo &calc_info) const {297+{
315- (void)ctx;298+ (void)ctx;
316- if (AlignedCheck(calc_info)) {299+ if (AlignedCheck(calc_info)) {
317- return AddCalculate<RANK, T, Eigen::Aligned>(calc_info);300+ return AddCalculate<RANK, T, Eigen::Aligned>(calc_info);
318- }301+ }
319- return AddCalculate<RANK, T, Eigen::Unaligned>(calc_info);302+ return AddCalculate<RANK, T, Eigen::Unaligned>(calc_info);
320}303}
321 304 
322-bool AddCpuKernel::AlignedCheck(const BCalcInfo &calc_info) const {305+bool AddCpuKernel::AlignedCheck(const BCalcInfo& calc_info) const
323- return AddrAlignedCheck(calc_info.input_0->GetData()) &&306+{
324- AddrAlignedCheck(calc_info.input_1->GetData()) &&307+ return AddrAlignedCheck(calc_info.input_0->GetData()) && AddrAlignedCheck(calc_info.input_1->GetData()) &&
325- AddrAlignedCheck(calc_info.output->GetData());308+ AddrAlignedCheck(calc_info.output->GetData());
326}309}
327 310 
328template <int32_t RANK, typename T, int32_t OPTION>311template <int32_t RANK, typename T, int32_t OPTION>
329-uint32_t AddCpuKernel::AddCalculate(BCalcInfo &calc_info) const {312+uint32_t AddCpuKernel::AddCalculate(BCalcInfo& calc_info) const
330- Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input0(313+{
331- PtrToPtr<void, T>(calc_info.input_0->GetData()),314+ Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input0(PtrToPtr<void, T>(calc_info.input_0->GetData()),
332- calc_info.input_0->GetTensorShape()->NumElements());315+ calc_info.input_0->GetTensorShape()->NumElements());
333- Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input1(316+ Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input1(PtrToPtr<void, T>(calc_info.input_1->GetData()),
334- PtrToPtr<void, T>(calc_info.input_1->GetData()),317+ calc_info.input_1->GetTensorShape()->NumElements());
335- calc_info.input_1->GetTensorShape()->NumElements());318+ Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> output(PtrToPtr<void, T>(calc_info.output->GetData()),
336- Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> output(319+ calc_info.output->GetTensorShape()->NumElements());
337- PtrToPtr<void, T>(calc_info.output->GetData()),320+ const auto& input_shape_0 = calc_info.input_0->GetTensorShape()->GetDimSizes();
338- calc_info.output->GetTensorShape()->NumElements());321+ const auto& input_shape_1 = calc_info.input_1->GetTensorShape()->GetDimSizes();
339- const auto &input_shape_0 = calc_info.input_0->GetTensorShape()->GetDimSizes();322+ if (input_shape_0.empty()) {
340- const auto &input_shape_1 = calc_info.input_1->GetTensorShape()->GetDimSizes();323+ const T v0 = *PtrToPtr<void, const T>(calc_info.input_0->GetData());
341- if (input_shape_0.empty()) {324+ output = v0 + input1;
342- const T v0 = *PtrToPtr<void, const T>(calc_info.input_0->GetData());325+ return KERNEL_STATUS_OK;
343- output = v0 + input1;326+ }
327+ 
328+ if (input_shape_1.empty()) {
329+ const T v1 = *PtrToPtr<void, const T>(calc_info.input_1->GetData());
330+ output = input0 + v1;
331+ return KERNEL_STATUS_OK;
332+ }
333+ 
334+ Eigen::DSizes<Eigen::DenseIndex, RANK> reshape0;
335+ Eigen::DSizes<Eigen::DenseIndex, RANK> reshape1;
336+ Eigen::DSizes<Eigen::DenseIndex, RANK> shape_out;
337+ Eigen::array<Eigen::DenseIndex, RANK> bcast0;
338+ Eigen::array<Eigen::DenseIndex, RANK> bcast1;
339+ 
340+ for (int32_t i = 0; i < RANK; i++) {
341+ reshape0[(RANK - i) - 1] = calc_info.reshape_0[i];
342+ reshape1[(RANK - i) - 1] = calc_info.reshape_1[i];
343+ shape_out[(RANK - i) - 1] = calc_info.shape_out[i];
344+ bcast0[(RANK - i) - 1] = calc_info.bcast_0[i];
345+ bcast1[(RANK - i) - 1] = calc_info.bcast_1[i];
346+ }
347+ output.reshape(shape_out) = input0.reshape(reshape0).broadcast(bcast0) + input1.reshape(reshape1).broadcast(bcast1);
344 return KERNEL_STATUS_OK;348 return KERNEL_STATUS_OK;
345- }
346- 
347- if (input_shape_1.empty()) {
348- const T v1 = *PtrToPtr<void, const T>(calc_info.input_1->GetData());
349- output = input0 + v1;
350- return KERNEL_STATUS_OK;
351- }
352- 
353- Eigen::DSizes<Eigen::DenseIndex, RANK> reshape0;
354- Eigen::DSizes<Eigen::DenseIndex, RANK> reshape1;
355- Eigen::DSizes<Eigen::DenseIndex, RANK> shape_out;
356- Eigen::array<Eigen::DenseIndex, RANK> bcast0;
357- Eigen::array<Eigen::DenseIndex, RANK> bcast1;
358- 
359- for (int32_t i = 0; i < RANK; i++) {
360- reshape0[(RANK - i) - 1] = calc_info.reshape_0[i];
361- reshape1[(RANK - i) - 1] = calc_info.reshape_1[i];
362- shape_out[(RANK - i) - 1] = calc_info.shape_out[i];
363- bcast0[(RANK - i) - 1] = calc_info.bcast_0[i];
364- bcast1[(RANK - i) - 1] = calc_info.bcast_1[i];
365- }
366- output.reshape(shape_out) = input0.reshape(reshape0).broadcast(bcast0) +
367- input1.reshape(reshape1).broadcast(bcast1);
368- return KERNEL_STATUS_OK;
369}349}
370 350 
371-REGISTER_CPU_KERNEL(kAdd, AddCpuKernel);351+OPS_MATH_REGISTER_CPU_KERNELV2(kAdd, AddCpuKernel);
372-} // namespace aicpu352+} // namespace aicpu
@@ -12,4 +12,4 @@
12set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62")12set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62")
13# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译13# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译
14set(SUPPORT_TILING_DIR "arch35" "arch35")14set(SUPPORT_TILING_DIR "arch35" "arch35")
15-add_all_modules_sources(OPTYPE round ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE)15+add_all_modules_sources(OPTYPE round ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE HOSTCPU TRUE)
@@ -11,6 +11,7 @@
11#include "round_aicpu.h"11#include "round_aicpu.h"
12 12 
13#include "unsupported/Eigen/CXX11/Tensor"13#include "unsupported/Eigen/CXX11/Tensor"
14+#include "aicpu/math_aicpu_register.h"
14#include "cpu_kernel_utils.h"15#include "cpu_kernel_utils.h"
15#include "utils/kernel_util.h"16#include "utils/kernel_util.h"
16#include "cpu_types.h"17#include "cpu_types.h"
@@ -18,144 +19,145 @@
18#include "status.h"19#include "status.h"
19 20 
20namespace {21namespace {
21-const char *const kRound = "Round";22+const char* const kRound = "Round";
22 23 
23-bool IsValueEqualForDouble(double a, double b) { 24+bool IsValueEqualForDouble(double a, double b)
24- bool has_inf = std::isinf(a) || std::isinf(b);25+{
25- bool has_nan = std::isnan(a) || std::isnan(b);26+ bool has_inf = std::isinf(a) || std::isinf(b);
26- if (has_inf || has_nan) {27+ bool has_nan = std::isnan(a) || std::isnan(b);
27- return a == b;28+ if (has_inf || has_nan) {
28- }29+ return a == b;
29- constexpr double epsilon = 1e-14;
30- return std::abs(a - b) <= epsilon * std::max(std::abs(a), std::abs(b));
31-}
32- 
33-template <typename T>
34-inline auto DoCompute(const T &x) -> const T {
35- T roundval = Eigen::numext::floor(x);
36- const T fraction = x - roundval;
37- const T point_five = T(.5);
38- bool is_point_five = std::is_same<T, double>::value ?
39- IsValueEqualForDouble(fraction, point_five) : aicpu::IsValueEqual<T>(fraction, point_five);
40- if (fraction > point_five) {
41- roundval += T(1.0);
42- } else if (is_point_five) {
43- const T nearest_even_int =
44- roundval - T(2) * Eigen::numext::floor(point_five * x);
45- bool is_odd = std::is_same<T, double>::value ?
46- IsValueEqualForDouble(nearest_even_int, T(1)) : aicpu::IsValueEqual<T>(nearest_even_int, T(1));
47- if (is_odd) {
48- roundval += T(1);
49 }30 }
50- }31+ constexpr double epsilon = 1e-14;
51- return roundval;32+ return std::abs(a - b) <= epsilon * std::max(std::abs(a), std::abs(b));
52}33}
53 34 
54template <typename T>35template <typename T>
55-inline auto ScalarRoundWithDecimals(const T &x, const T &pow_decimals, const bool &neg_flag) -> const T {36+inline auto DoCompute(const T& x) -> const T
56- T roundval = neg_flag ? DoCompute<T>(x / pow_decimals) : DoCompute<T>(x * pow_decimals);37+{
57- return neg_flag ? roundval * pow_decimals : roundval / pow_decimals;38+ T roundval = Eigen::numext::floor(x);
39+ const T fraction = x - roundval;
40+ const T point_five = T(.5);
41+ bool is_point_five = std::is_same<T, double>::value ? IsValueEqualForDouble(fraction, point_five) :
42+ aicpu::IsValueEqual<T>(fraction, point_five);
43+ if (fraction > point_five) {
44+ roundval += T(1.0);
45+ } else if (is_point_five) {
46+ const T nearest_even_int = roundval - T(2) * Eigen::numext::floor(point_five * x);
47+ bool is_odd = std::is_same<T, double>::value ? IsValueEqualForDouble(nearest_even_int, T(1)) :
48+ aicpu::IsValueEqual<T>(nearest_even_int, T(1));
49+ if (is_odd) {
50+ roundval += T(1);
51+ }
52+ }
53+ return roundval;
58}54}
55+ 
56+template <typename T>
57+inline auto ScalarRoundWithDecimals(const T& x, const T& pow_decimals, const bool& neg_flag) -> const T
58+{
59+ T roundval = neg_flag ? DoCompute<T>(x / pow_decimals) : DoCompute<T>(x * pow_decimals);
60+ return neg_flag ? roundval * pow_decimals : roundval / pow_decimals;
59}61}
62+} // namespace
60 63 
61namespace aicpu {64namespace aicpu {
62template <typename T>65template <typename T>
63-uint32_t RangeRound(CpuKernelContext &ctx, T *input, T *out, int64_t decimals) {66+uint32_t RangeRound(CpuKernelContext& ctx, T* input, T* out, int64_t decimals)
64- uint32_t ret = 0;67+{
65- uint32_t max_core_num = std::max(1U, aicpu::CpuKernelUtils::GetCPUNum(ctx));68+ uint32_t ret = 0;
66- int64_t input_datasize = ctx.Input(0)->NumElements();69+ uint32_t max_core_num = std::max(1U, aicpu::CpuKernelUtils::GetCPUNum(ctx));
67- auto per_unit_size = CeilMultiple(input_datasize, max_core_num);70+ int64_t input_datasize = ctx.Input(0)->NumElements();
68- if (decimals == 0) {71+ auto per_unit_size = CeilMultiple(input_datasize, max_core_num);
69- auto shard_copy = [&input, &out](int64_t start, int64_t end) {72+ if (decimals == 0) {
70- constexpr bool isInt = (Eigen::NumTraits<T>::IsInteger != 0);73+ auto shard_copy = [&input, &out](int64_t start, int64_t end) {
71- if (isInt) {74+ constexpr bool isInt = (Eigen::NumTraits<T>::IsInteger != 0);
72- for (int64_t i = start; i < end; ++i) {75+ if (isInt) {
73- out[i] = input[i];76+ for (int64_t i = start; i < end; ++i) {
77+ out[i] = input[i];
78+ }
79+ } else {
80+ for (int64_t i = start; i < end; ++i) {
81+ out[i] = DoCompute<T>(input[i]);
82+ }
83+ }
84+ };
85+ ret = CpuKernelUtils::ParallelFor(ctx, input_datasize, per_unit_size, shard_copy);
86+ } else {
87+ bool neg_flag = false;
88+ if (decimals < 0) {
89+ decimals = -decimals;
90+ neg_flag = true;
74 }91 }
75- } else {92+ const T pow_decimals = static_cast<T>(std::pow(10, decimals));
76- for (int64_t i = start; i < end; ++i) {93+ auto shard_copy = [&input, &out, &pow_decimals, &neg_flag](int64_t start, int64_t end) {
77- out[i] = DoCompute<T>(input[i]);94+ for (int64_t i = start; i < end; ++i) {
78- }95+ out[i] = ScalarRoundWithDecimals<T>(input[i], pow_decimals, neg_flag);
79- }96+ }
80- };97+ };
81- ret = CpuKernelUtils::ParallelFor(ctx, input_datasize, per_unit_size, shard_copy);98+ ret = CpuKernelUtils::ParallelFor(ctx, input_datasize, per_unit_size, shard_copy);
82- } else {
83- bool neg_flag = false;
84- if (decimals < 0) {
85- decimals = -decimals;
86- neg_flag = true;
87 }99 }
88- const T pow_decimals = static_cast<T>(std::pow(10, decimals));100+ return ret;
89- auto shard_copy = [&input, &out, &pow_decimals, &neg_flag](int64_t start, int64_t end) {
90- for (int64_t i = start; i < end; ++i) {
91- out[i] = ScalarRoundWithDecimals<T>(input[i], pow_decimals, neg_flag);
92- }
93- };
94- ret = CpuKernelUtils::ParallelFor(ctx, input_datasize, per_unit_size, shard_copy);
95- }
96- return ret;
97}101}
98 102 
99-bool RoundCpuKernel::CheckSupported(DataType input_type) const {103+bool RoundCpuKernel::CheckSupported(DataType input_type) const
100- switch (input_type) {104+{
101- case DT_FLOAT16:105+ switch (input_type) {
102- case DT_FLOAT:106+ case DT_FLOAT16:
103- case DT_DOUBLE:107+ case DT_FLOAT:
104- case DT_INT32:108+ case DT_DOUBLE:
105- case DT_INT64:109+ case DT_INT32:
106- return true;110+ case DT_INT64:
107- default:111+ return true;
108- KERNEL_LOG_ERROR("Unsupported input data type[%d]", static_cast<int32_t>(input_type));112+ default:
109- return false;113+ KERNEL_LOG_ERROR("Unsupported input data type[%d]", static_cast<int32_t>(input_type));
110- }114+ return false;
115+ }
111}116}
112 117 
113-uint32_t RoundCpuKernel::Compute(CpuKernelContext &ctx) {118+uint32_t RoundCpuKernel::Compute(CpuKernelContext& ctx)
114- Tensor *input_tensor = ctx.Input(0);119+{
115- KERNEL_CHECK_NULLPTR(input_tensor, KERNEL_STATUS_PARAM_INVALID, "Get input[0] failed")120+ Tensor* input_tensor = ctx.Input(0);
116- Tensor *output_tensor = ctx.Output(0);121+ KERNEL_CHECK_NULLPTR(input_tensor, KERNEL_STATUS_PARAM_INVALID, "Get input[0] failed")
117- KERNEL_CHECK_NULLPTR(output_tensor, KERNEL_STATUS_PARAM_INVALID, "Get output[0] failed")122+ Tensor* output_tensor = ctx.Output(0);
118- auto inputdata = input_tensor->GetData();123+ KERNEL_CHECK_NULLPTR(output_tensor, KERNEL_STATUS_PARAM_INVALID, "Get output[0] failed")
119- KERNEL_CHECK_NULLPTR(inputdata, KERNEL_STATUS_PARAM_INVALID, "Get input[0] data failed")124+ auto inputdata = input_tensor->GetData();
120- auto outputdata = output_tensor->GetData();125+ KERNEL_CHECK_NULLPTR(inputdata, KERNEL_STATUS_PARAM_INVALID, "Get input[0] data failed")
121- KERNEL_CHECK_NULLPTR(outputdata, KERNEL_STATUS_PARAM_INVALID, "Get output[0] data failed")126+ auto outputdata = output_tensor->GetData();
122- auto decimals_attr = ctx.GetAttr("decimals");127+ KERNEL_CHECK_NULLPTR(outputdata, KERNEL_STATUS_PARAM_INVALID, "Get output[0] data failed")
123- int64_t decimals = 0;128+ auto decimals_attr = ctx.GetAttr("decimals");
124- if (decimals_attr != nullptr) {129+ int64_t decimals = 0;
125- decimals = decimals_attr->GetInt();130+ if (decimals_attr != nullptr) {
126- }131+ decimals = decimals_attr->GetInt();
127- DataType inputtype = input_tensor->GetDataType();132+ }
128- if (!CheckSupported(inputtype)) {133+ DataType inputtype = input_tensor->GetDataType();
129- return KERNEL_STATUS_PARAM_INVALID;134+ if (!CheckSupported(inputtype)) {
130- }135+ return KERNEL_STATUS_PARAM_INVALID;
131- uint32_t ret = 0;136+ }
132- switch (inputtype) {137+ uint32_t ret = 0;
133- case DT_FLOAT16:138+ switch (inputtype) {
134- ret = RangeRound(ctx, static_cast<Eigen::half *>(inputdata),139+ case DT_FLOAT16:
135- static_cast<Eigen::half *>(outputdata), decimals);140+ ret = RangeRound(ctx, static_cast<Eigen::half*>(inputdata), static_cast<Eigen::half*>(outputdata),
136- break;141+ decimals);
137- case DT_FLOAT:142+ break;
138- ret = RangeRound(ctx, static_cast<float *>(inputdata),143+ case DT_FLOAT:
139- static_cast<float *>(outputdata), decimals);144+ ret = RangeRound(ctx, static_cast<float*>(inputdata), static_cast<float*>(outputdata), decimals);
140- break;145+ break;
141- case DT_DOUBLE:146+ case DT_DOUBLE:
142- ret = RangeRound(ctx, static_cast<double *>(inputdata),147+ ret = RangeRound(ctx, static_cast<double*>(inputdata), static_cast<double*>(outputdata), decimals);
143- static_cast<double *>(outputdata), decimals);148+ break;
144- break;149+ case DT_INT32:
145- case DT_INT32:150+ ret = RangeRound(ctx, static_cast<int32_t*>(inputdata), static_cast<int32_t*>(outputdata), decimals);
146- ret = RangeRound(ctx, static_cast<int32_t *>(inputdata),151+ break;
147- static_cast<int32_t *>(outputdata), decimals);152+ case DT_INT64:
148- break;153+ ret = RangeRound(ctx, static_cast<int64_t*>(inputdata), static_cast<int64_t*>(outputdata), decimals);
149- case DT_INT64:154+ break;
150- ret = RangeRound(ctx, static_cast<int64_t *>(inputdata),155+ default:
151- static_cast<int64_t *>(outputdata), decimals);156+ KERNEL_LOG_ERROR("Unsupported input data type[%d]", static_cast<int32_t>(inputtype));
152- break;157+ return KERNEL_STATUS_PARAM_INVALID;
153- default:158+ }
154- KERNEL_LOG_ERROR("Unsupported input data type[%d]", static_cast<int32_t>(inputtype));159+ return ret;
155- return KERNEL_STATUS_PARAM_INVALID;
156- }
157- return ret;
158}160}
159 161 
160-REGISTER_CPU_KERNEL(kRound, RoundCpuKernel);162+OPS_MATH_REGISTER_CPU_KERNELV2(kRound, RoundCpuKernel);
161-} // namespace aicpu163+} // namespace aicpu
@@ -1,11 +1,11 @@
1# ---------------------------------------------------------------------------------------------------------1# ---------------------------------------------------------------------------------------------------------
2# Copyright (c) 2025 Huawei Technologies Co., Ltd.2# Copyright (c) 2025 Huawei Technologies Co., Ltd.
3-# This program is free software, you can redistribute it and/or modify it under the terms and conditions of 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").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.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, 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. 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.8# See LICENSE in the root of the software repository for the full text of the License.
9# ---------------------------------------------------------------------------------------------------------9# ---------------------------------------------------------------------------------------------------------
10 10 
11-add_all_modules_sources(OPTYPE search_sorted ACLNNTYPE aclnn_exclude)11+add_all_modules_sources(OPTYPE search_sorted ACLNNTYPE aclnn_exclude HOSTCPU TRUE)
@@ -0,0 +1,30 @@
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 "log/log.h"
12+#include "register/op_impl_registry.h"
13+ 
14+using namespace ge;
15+namespace ops {
16+static graphStatus InferShape4SearchSorted(gert::InferShapeContext* context)
17+{
18+ OP_LOGI("Begin InferShape4SearchSorted");
19+ const gert::Shape* values_shape = context->GetInputShape(1);
20+ OP_CHECK_NULL_WITH_CONTEXT(context, values_shape);
21+ 
22+ gert::Shape* out_shape = context->GetOutputShape(0);
23+ OP_CHECK_NULL_WITH_CONTEXT(context, out_shape);
24+ *out_shape = *values_shape;
25+ 
26+ return GRAPH_SUCCESS;
27+}
28+ 
29+IMPL_OP_INFERSHAPE(SearchSorted).InferShape(InferShape4SearchSorted);
30+} // namespace ops
@@ -16,6 +16,7 @@
16#include <utility>16#include <utility>
17 17 
18#include "Eigen/Core"18#include "Eigen/Core"
19+#include "aicpu/math_aicpu_register.h"
19#include "cpu_kernel_utils.h"20#include "cpu_kernel_utils.h"
20#include "cpu_types.h"21#include "cpu_types.h"
21#include "log.h"22#include "log.h"
@@ -258,5 +259,5 @@ uint32_t SearchSortedKernel::Compute(CpuKernelContext& ctx)
258 return iter->second[output_dtype_](right_, sequence_t_, values_t_, sorter_t_, output_t_, ctx);259 return iter->second[output_dtype_](right_, sequence_t_, values_t_, sorter_t_, output_t_, ctx);
259}260}
260 261 
261-REGISTER_CPU_KERNEL(kSearchSorted, SearchSortedKernel);262+OPS_MATH_REGISTER_CPU_KERNELV2(kSearchSorted, SearchSortedKernel);
262} // namespace aicpu263} // namespace aicpu
@@ -12,4 +12,4 @@
12set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62")12set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62")
13# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译13# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译
14set(SUPPORT_TILING_DIR "arch35" "arch35")14set(SUPPORT_TILING_DIR "arch35" "arch35")
15-add_all_modules_sources(OPTYPE select_v2 ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE)15+add_all_modules_sources(OPTYPE select_v2 ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE HOSTCPU TRUE)
@@ -1,31 +0,0 @@
1-{
2- "SelectV2":{
3- "opInfo":{
4- "computeCost":"100",
5- "engine":"DNN_VM_AICPU",
6- "flagAsync":"False",
7- "flagPartial":"False",
8- "functionName":"RunCpuKernel",
9- "kernelSo":"libmath_aicpu_kernels.so",
10- "opKernelLib":"CUSTAICPUKernel",
11- "userDefined":"True",
12- "workspaceSize":"100"
13- },
14- "input0": {
15- "name": "condition",
16- "type": "DT_BOOL"
17- },
18- "input1": {
19- "name": "then",
20- "type": "DT_COMPLEX128,DT_COMPLEX64,DT_DOUBLE,DT_FLOAT,DT_FLOAT16,DT_INT16,DT_INT32,DT_INT64,DT_INT8,DT_UINT16,DT_UINT32,DT_UINT64,DT_UINT8,DT_BOOL"
21- },
22- "input2": {
23- "name": "else",
24- "type": "DT_COMPLEX128,DT_COMPLEX64,DT_DOUBLE,DT_FLOAT,DT_FLOAT16,DT_INT16,DT_INT32,DT_INT64,DT_INT8,DT_UINT16,DT_UINT32,DT_UINT64,DT_UINT8,DT_BOOL"
25- },
26- "output0": {
27- "name": "result",
28- "type": "DT_COMPLEX128,DT_COMPLEX64,DT_DOUBLE,DT_FLOAT,DT_FLOAT16,DT_INT16,DT_INT32,DT_INT64,DT_INT8,DT_UINT16,DT_UINT32,DT_UINT64,DT_UINT8,DT_BOOL"
29- }
30- }
31-}
@@ -13,6 +13,7 @@
13#include <algorithm>13#include <algorithm>
14#include <unordered_set>14#include <unordered_set>
15 15 
16+#include "aicpu/math_aicpu_register.h"
16#include "cpu_kernel_utils.h"17#include "cpu_kernel_utils.h"
17#include "utils/eigen_tensor.h"18#include "utils/eigen_tensor.h"
18 19 
@@ -22,324 +23,305 @@ const uint32_t kInputNum = 3;
22const int64_t kNoBroadcastValue = 1;23const int64_t kNoBroadcastValue = 1;
23const int64_t kNoRepeatElements = 2;24const int64_t kNoRepeatElements = 2;
24 25 
25-#define SELECTV2_COMPUTE_CASE(DTYPE, TYPE) \26+#define SELECTV2_COMPUTE_CASE(DTYPE, TYPE) \
26- case (DTYPE): { \27+ case (DTYPE): { \
27- KernelStatus result = Selectv2BuildBcast<TYPE>(ctx); \28+ KernelStatus result = Selectv2BuildBcast<TYPE>(ctx); \
28- if (result != KERNEL_STATUS_OK) { \29+ if (result != KERNEL_STATUS_OK) { \
29- KERNEL_LOG_ERROR("SelectV2 kernel compute failed."); \30+ KERNEL_LOG_ERROR("SelectV2 kernel compute failed."); \
30- return static_cast<uint32_t>(result); \31+ return static_cast<uint32_t>(result); \
31- } \32+ } \
32- break; \33+ break; \
33- }34+ }
34 35 
35-#define SELECTV2_DIM_CASE(RANK) \36+#define SELECTV2_DIM_CASE(RANK) \
36- case (RANK): { \37+ case (RANK): { \
37- KernelStatus result = \38+ KernelStatus result = SelectV2CalculateWithAlignedCheck<RANK, T>(calc_info); \
38- SelectV2CalculateWithAlignedCheck<RANK, T>(calc_info); \39+ if (result != KERNEL_STATUS_OK) { \
39- if (result != KERNEL_STATUS_OK) { \40+ KERNEL_LOG_ERROR("SelectV2 kernel compute failed."); \
40- KERNEL_LOG_ERROR("SelectV2 kernel compute failed."); \41+ return result; \
41- return result; \42+ } \
42- } \43+ break; \
43- break; \44+ }
44- }45+} // namespace
45-} // namespace
46 46 
47namespace aicpu {47namespace aicpu {
48-uint32_t Selectv2CpuKernel::Compute(CpuKernelContext& ctx) {48+uint32_t Selectv2CpuKernel::Compute(CpuKernelContext& ctx)
49- // check if input1 and input2 are of the same type49+{
50- if (Selectv2ParamCheck(ctx) != KERNEL_STATUS_OK) {50+ // check if input1 and input2 are of the same type
51- return static_cast<uint32_t>(KERNEL_STATUS_PARAM_INVALID);51+ if (Selectv2ParamCheck(ctx) != KERNEL_STATUS_OK) {
52- }52+ return static_cast<uint32_t>(KERNEL_STATUS_PARAM_INVALID);
53- // choose compute function depend on dataType53+ }
54- auto data_type =54+ // choose compute function depend on dataType
55- static_cast<DataType>(ctx.Input(kSecondInputIndex)->GetDataType());55+ auto data_type = static_cast<DataType>(ctx.Input(kSecondInputIndex)->GetDataType());
56- switch (data_type) {56+ switch (data_type) {
57- SELECTV2_COMPUTE_CASE(DT_FLOAT16, Eigen::half);57+ SELECTV2_COMPUTE_CASE(DT_FLOAT16, Eigen::half);
58- SELECTV2_COMPUTE_CASE(DT_FLOAT, float);58+ SELECTV2_COMPUTE_CASE(DT_FLOAT, float);
59- SELECTV2_COMPUTE_CASE(DT_DOUBLE, double);59+ SELECTV2_COMPUTE_CASE(DT_DOUBLE, double);
60- SELECTV2_COMPUTE_CASE(DT_INT8, int8_t);60+ SELECTV2_COMPUTE_CASE(DT_INT8, int8_t);
61- SELECTV2_COMPUTE_CASE(DT_INT16, int16_t);61+ SELECTV2_COMPUTE_CASE(DT_INT16, int16_t);
62- SELECTV2_COMPUTE_CASE(DT_INT32, int32_t);62+ SELECTV2_COMPUTE_CASE(DT_INT32, int32_t);
63- SELECTV2_COMPUTE_CASE(DT_INT64, int64_t);63+ SELECTV2_COMPUTE_CASE(DT_INT64, int64_t);
64- SELECTV2_COMPUTE_CASE(DT_UINT8, uint8_t);64+ SELECTV2_COMPUTE_CASE(DT_UINT8, uint8_t);
65- SELECTV2_COMPUTE_CASE(DT_UINT16, uint16_t);65+ SELECTV2_COMPUTE_CASE(DT_UINT16, uint16_t);
66- SELECTV2_COMPUTE_CASE(DT_UINT32, uint32_t);66+ SELECTV2_COMPUTE_CASE(DT_UINT32, uint32_t);
67- SELECTV2_COMPUTE_CASE(DT_UINT64, uint64_t);67+ SELECTV2_COMPUTE_CASE(DT_UINT64, uint64_t);
68- SELECTV2_COMPUTE_CASE(DT_COMPLEX64, std::complex<float>);68+ SELECTV2_COMPUTE_CASE(DT_COMPLEX64, std::complex<float>);
69- SELECTV2_COMPUTE_CASE(DT_COMPLEX128, std::complex<double>);69+ SELECTV2_COMPUTE_CASE(DT_COMPLEX128, std::complex<double>);
70- SELECTV2_COMPUTE_CASE(DT_BOOL, bool);70+ SELECTV2_COMPUTE_CASE(DT_BOOL, bool);
71- default:71+ default:
72- KERNEL_LOG_ERROR(72+ KERNEL_LOG_ERROR("[%s] Data type of input is not support, input data type is [%s].",
73- "[%s] Data type of input is not support, input data type is [%s].",73+ ctx.GetOpType().c_str(), DTypeStr(data_type).c_str());
74- ctx.GetOpType().c_str(), DTypeStr(data_type).c_str());74+ return static_cast<uint32_t>(KERNEL_STATUS_PARAM_INVALID);
75- return static_cast<uint32_t>(KERNEL_STATUS_PARAM_INVALID);75+ }
76- }76+ return static_cast<uint32_t>(KERNEL_STATUS_OK);
77- return static_cast<uint32_t>(KERNEL_STATUS_OK);
78}77}
79 78 
80-KernelStatus Selectv2CpuKernel::Selectv2ParamCheck(79+KernelStatus Selectv2CpuKernel::Selectv2ParamCheck(const CpuKernelContext& ctx) const
81- const CpuKernelContext& ctx) const {80+{
82- KERNEL_CHECK_FALSE((ctx.GetInputsSize() >= kInputNum),81+ KERNEL_CHECK_FALSE((ctx.GetInputsSize() >= kInputNum), KERNEL_STATUS_PARAM_INVALID,
83- KERNEL_STATUS_PARAM_INVALID,82+ "[%s] need [%u] inputs, but got [%u].", ctx.GetOpType().c_str(), kInputNum, ctx.GetInputsSize());
84- "[%s] need [%u] inputs, but got [%u].",83+ DataType input1_type = DT_INT8;
85- ctx.GetOpType().c_str(), kInputNum, ctx.GetInputsSize());84+ DataType input2_type = DT_UINT8;
86- DataType input1_type = DT_INT8;85+ for (uint32_t i = 0; i < kInputNum; ++i) {
87- DataType input2_type = DT_UINT8;86+ Tensor* input = ctx.Input(i);
88- for (uint32_t i = 0; i < kInputNum; ++i) {87+ KERNEL_CHECK_NULLPTR(input, KERNEL_STATUS_INNER_ERROR, "[%s] get input[%u] failed.", ctx.GetOpType().c_str(),
89- Tensor* input = ctx.Input(i);88+ i);
90- KERNEL_CHECK_NULLPTR(input, KERNEL_STATUS_INNER_ERROR,89+ if (i == kSecondInputIndex) {
91- "[%s] get input[%u] failed.", ctx.GetOpType().c_str(),90+ input1_type = input->GetDataType();
92- i);91+ }
93- if (i == kSecondInputIndex) {92+ if (i == kThirdInputIndex) {
94- input1_type = input->GetDataType();93+ input2_type = input->GetDataType();
94+ }
95+ // After confirming that it is a non-empty tensor, perform this step of
96+ // verification
97+ if (!IsEmptyTensor(input)) {
98+ auto input_data = input->GetData();
99+ KERNEL_CHECK_NULLPTR(input_data, KERNEL_STATUS_PARAM_INVALID, "[%s] get input[%u] tensor data is nullptr.",
100+ ctx.GetOpType().c_str(), i);
101+ }
95 }102 }
96- if (i == kThirdInputIndex) {103+ KERNEL_CHECK_FALSE((input1_type == input2_type), KERNEL_STATUS_PARAM_INVALID,
97- input2_type = input->GetDataType();104+ "The data type of input1 [%s] need be same with "
105+ "input2 [%s].",
106+ DTypeStr(input1_type).c_str(), DTypeStr(input2_type).c_str())
107+ Tensor* output = ctx.Output(kFirstOutputIndex);
108+ KERNEL_CHECK_NULLPTR(output, KERNEL_STATUS_INNER_ERROR, "[%s] get output failed.", ctx.GetOpType().c_str());
109+ if (!IsEmptyTensor(output)) {
110+ auto output_data = output->GetData();
111+ KERNEL_CHECK_NULLPTR(output_data, KERNEL_STATUS_PARAM_INVALID, "[%s] get output tensor data is nullptr.",
112+ ctx.GetOpType().c_str());
98 }113 }
99- // After confirming that it is a non-empty tensor, perform this step of114+ return KERNEL_STATUS_OK;
100- // verification
101- if (!IsEmptyTensor(input)) {
102- auto input_data = input->GetData();
103- KERNEL_CHECK_NULLPTR(input_data, KERNEL_STATUS_PARAM_INVALID,
104- "[%s] get input[%u] tensor data is nullptr.",
105- ctx.GetOpType().c_str(), i);
106- }
107- }
108- KERNEL_CHECK_FALSE((input1_type == input2_type), KERNEL_STATUS_PARAM_INVALID,
109- "The data type of input1 [%s] need be same with "
110- "input2 [%s].",
111- DTypeStr(input1_type).c_str(),
112- DTypeStr(input2_type).c_str())
113- Tensor* output = ctx.Output(kFirstOutputIndex);
114- KERNEL_CHECK_NULLPTR(output, KERNEL_STATUS_INNER_ERROR,
115- "[%s] get output failed.", ctx.GetOpType().c_str());
116- if (!IsEmptyTensor(output)) {
117- auto output_data = output->GetData();
118- KERNEL_CHECK_NULLPTR(output_data, KERNEL_STATUS_PARAM_INVALID,
119- "[%s] get output tensor data is nullptr.",
120- ctx.GetOpType().c_str());
121- }
122- return KERNEL_STATUS_OK;
123}115}
124 116 
125template <typename T>117template <typename T>
126-KernelStatus Selectv2CpuKernel::Selectv2BuildBcast(118+KernelStatus Selectv2CpuKernel::Selectv2BuildBcast(const CpuKernelContext& ctx)
127- const CpuKernelContext& ctx) {119+{
128- Tensor* input_0 = ctx.Input(kFirstInputIndex);120+ Tensor* input_0 = ctx.Input(kFirstInputIndex);
129- Tensor* input_1 = ctx.Input(kSecondInputIndex);121+ Tensor* input_1 = ctx.Input(kSecondInputIndex);
130- Tensor* input_2 = ctx.Input(kThirdInputIndex);122+ Tensor* input_2 = ctx.Input(kThirdInputIndex);
131- Tensor* output = ctx.Output(kFirstOutputIndex);123+ Tensor* output = ctx.Output(kFirstOutputIndex);
132 124 
133- if (input_0->GetDataSize() == 0 || input_1->GetDataSize() == 0 ||125+ if (input_0->GetDataSize() == 0 || input_1->GetDataSize() == 0 || input_2->GetDataSize() == 0) {
134- input_2->GetDataSize() == 0) {126+ KERNEL_LOG_WARN("SelectV2 kernel input tensor is empty.");
135- KERNEL_LOG_WARN("SelectV2 kernel input tensor is empty.");127+ return KERNEL_STATUS_OK;
136- return KERNEL_STATUS_OK;
137- }
138- 
139- KERNEL_LOG_DEBUG(
140- "Selectv2CpuKernel[%s], input0: size[%lu];"
141- "input1: size[%lu], input2: size[%lu], output: size[%lu].",
142- ctx.GetOpType().c_str(), input_0->GetDataSize(), input_1->GetDataSize(),
143- input_2->GetDataSize(), output->GetDataSize());
144- 
145- SelectV2BCalcInfo calc_info;
146- calc_info.input_0 = input_0;
147- calc_info.input_1 = input_1;
148- calc_info.input_2 = input_2;
149- calc_info.output = output;
150- 
151- // broadcast input
152- if (Selectv2GenerateBcastInfo(calc_info) != KERNEL_STATUS_OK) {
153- KERNEL_LOG_ERROR("[%s] Generate broadcast info failed.", kSelectV2);
154- return KERNEL_STATUS_PARAM_INVALID;
155- }
156- SelectV2GetBcastVec(calc_info);
157- int32_t rank = static_cast<int32_t>(calc_info.shape_out.size());
158- switch (rank) {
159- case SCALAR: {
160- bool v0 = *(reinterpret_cast<const bool*>(calc_info.input_0->GetData()));
161- T v1 = *(reinterpret_cast<const T*>(calc_info.input_1->GetData()));
162- T v2 = *(reinterpret_cast<const T*>(calc_info.input_2->GetData()));
163- T* value_out = reinterpret_cast<T*>(calc_info.output->GetData());
164- *(value_out) = (v0 == true) ? v1 : v2;
165- return KERNEL_STATUS_OK;
166 }128 }
167- SELECTV2_DIM_CASE(ONE_DIM);129+ 
168- SELECTV2_DIM_CASE(TWO_DIM);130+ KERNEL_LOG_DEBUG("Selectv2CpuKernel[%s], input0: size[%lu];"
169- SELECTV2_DIM_CASE(THREE_DIM);131+ "input1: size[%lu], input2: size[%lu], output: size[%lu].",
170- SELECTV2_DIM_CASE(FOUR_DIM);132+ ctx.GetOpType().c_str(), input_0->GetDataSize(), input_1->GetDataSize(), input_2->GetDataSize(),
171- SELECTV2_DIM_CASE(FIVE_DIM);133+ output->GetDataSize());
172- SELECTV2_DIM_CASE(SIX_DIM);134+ 
173- SELECTV2_DIM_CASE(SEVEN_DIM);135+ SelectV2BCalcInfo calc_info;
174- SELECTV2_DIM_CASE(EIGHT_DIM);136+ calc_info.input_0 = input_0;
175- default:137+ calc_info.input_1 = input_1;
176- KERNEL_LOG_ERROR("[%s] Rank of output should less than 9 but get [%zu].",138+ calc_info.input_2 = input_2;
177- ctx.GetOpType().c_str(), calc_info.shape_out.size());139+ calc_info.output = output;
178- return KERNEL_STATUS_PARAM_INVALID;140+ 
179- }141+ // broadcast input
180- return KERNEL_STATUS_OK;142+ if (Selectv2GenerateBcastInfo(calc_info) != KERNEL_STATUS_OK) {
143+ KERNEL_LOG_ERROR("[%s] Generate broadcast info failed.", kSelectV2);
144+ return KERNEL_STATUS_PARAM_INVALID;
145+ }
146+ SelectV2GetBcastVec(calc_info);
147+ int32_t rank = static_cast<int32_t>(calc_info.shape_out.size());
148+ switch (rank) {
149+ case SCALAR: {
150+ bool v0 = *(reinterpret_cast<const bool*>(calc_info.input_0->GetData()));
151+ T v1 = *(reinterpret_cast<const T*>(calc_info.input_1->GetData()));
152+ T v2 = *(reinterpret_cast<const T*>(calc_info.input_2->GetData()));
153+ T* value_out = reinterpret_cast<T*>(calc_info.output->GetData());
154+ *(value_out) = (v0 == true) ? v1 : v2;
155+ return KERNEL_STATUS_OK;
156+ }
157+ SELECTV2_DIM_CASE(ONE_DIM);
158+ SELECTV2_DIM_CASE(TWO_DIM);
159+ SELECTV2_DIM_CASE(THREE_DIM);
160+ SELECTV2_DIM_CASE(FOUR_DIM);
161+ SELECTV2_DIM_CASE(FIVE_DIM);
162+ SELECTV2_DIM_CASE(SIX_DIM);
163+ SELECTV2_DIM_CASE(SEVEN_DIM);
164+ SELECTV2_DIM_CASE(EIGHT_DIM);
165+ default:
166+ KERNEL_LOG_ERROR("[%s] Rank of output should less than 9 but get [%zu].", ctx.GetOpType().c_str(),
167+ calc_info.shape_out.size());
168+ return KERNEL_STATUS_PARAM_INVALID;
169+ }
170+ return KERNEL_STATUS_OK;
181}171}
182 172 
183template <int32_t RANK, typename T>173template <int32_t RANK, typename T>
184-KernelStatus Selectv2CpuKernel::SelectV2CalculateWithAlignedCheck(174+KernelStatus Selectv2CpuKernel::SelectV2CalculateWithAlignedCheck(SelectV2BCalcInfo& calc_info)
185- SelectV2BCalcInfo& calc_info) {175+{
186- if (AlignedCheck(calc_info)) {176+ if (AlignedCheck(calc_info)) {
187- return SelectV2Calculate<RANK, T, Eigen::Aligned>(calc_info);177+ return SelectV2Calculate<RANK, T, Eigen::Aligned>(calc_info);
188- }178+ }
189- return SelectV2Calculate<RANK, T, Eigen::Unaligned>(calc_info);179+ return SelectV2Calculate<RANK, T, Eigen::Unaligned>(calc_info);
190}180}
191 181 
192-bool Selectv2CpuKernel::AlignedCheck(const SelectV2BCalcInfo& calc_info) const {182+bool Selectv2CpuKernel::AlignedCheck(const SelectV2BCalcInfo& calc_info) const
193- return AddrAlignedCheck(calc_info.input_0->GetData()) &&183+{
194- AddrAlignedCheck(calc_info.input_1->GetData()) &&184+ return AddrAlignedCheck(calc_info.input_0->GetData()) && AddrAlignedCheck(calc_info.input_1->GetData()) &&
195- AddrAlignedCheck(calc_info.input_2->GetData()) &&185+ AddrAlignedCheck(calc_info.input_2->GetData()) && AddrAlignedCheck(calc_info.output->GetData());
196- AddrAlignedCheck(calc_info.output->GetData());
197}186}
198 187 
199template <int32_t RANK, typename T, int32_t OPTION>188template <int32_t RANK, typename T, int32_t OPTION>
200-KernelStatus Selectv2CpuKernel::SelectV2Calculate(SelectV2BCalcInfo& calc_info) {189+KernelStatus Selectv2CpuKernel::SelectV2Calculate(SelectV2BCalcInfo& calc_info)
201- Eigen::TensorMap<Eigen::Tensor<bool, 1>, OPTION> input0(190+{
202- static_cast<bool*>(calc_info.input_0->GetData()),191+ Eigen::TensorMap<Eigen::Tensor<bool, 1>, OPTION> input0(static_cast<bool*>(calc_info.input_0->GetData()),
203- calc_info.input_0->GetTensorShape()->NumElements());192+ calc_info.input_0->GetTensorShape()->NumElements());
204- Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input1(193+ Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input1(static_cast<T*>(calc_info.input_1->GetData()),
205- static_cast<T*>(calc_info.input_1->GetData()),194+ calc_info.input_1->GetTensorShape()->NumElements());
206- calc_info.input_1->GetTensorShape()->NumElements());195+ Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input2(static_cast<T*>(calc_info.input_2->GetData()),
207- Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input2(196+ calc_info.input_2->GetTensorShape()->NumElements());
208- static_cast<T*>(calc_info.input_2->GetData()),197+ Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> output(static_cast<T*>(calc_info.output->GetData()),
209- calc_info.input_2->GetTensorShape()->NumElements());198+ calc_info.output->GetTensorShape()->NumElements());
210- Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> output(
211- static_cast<T*>(calc_info.output->GetData()),
212- calc_info.output->GetTensorShape()->NumElements());
213 199 
214- Eigen::DSizes<Eigen::DenseIndex, RANK> reshape0;200+ Eigen::DSizes<Eigen::DenseIndex, RANK> reshape0;
215- Eigen::DSizes<Eigen::DenseIndex, RANK> reshape1;201+ Eigen::DSizes<Eigen::DenseIndex, RANK> reshape1;
216- Eigen::DSizes<Eigen::DenseIndex, RANK> reshape2;202+ Eigen::DSizes<Eigen::DenseIndex, RANK> reshape2;
217- Eigen::DSizes<Eigen::DenseIndex, RANK> shape_out;203+ Eigen::DSizes<Eigen::DenseIndex, RANK> shape_out;
218- Eigen::array<Eigen::DenseIndex, RANK> bcast0;204+ Eigen::array<Eigen::DenseIndex, RANK> bcast0;
219- Eigen::array<Eigen::DenseIndex, RANK> bcast1;205+ Eigen::array<Eigen::DenseIndex, RANK> bcast1;
220- Eigen::array<Eigen::DenseIndex, RANK> bcast2;206+ Eigen::array<Eigen::DenseIndex, RANK> bcast2;
221 207 
222- for (size_t i = 0; i < static_cast<size_t>(RANK); ++i) {208+ for (size_t i = 0; i < static_cast<size_t>(RANK); ++i) {
223- size_t index = (static_cast<size_t>(RANK) - i) - 1UL;209+ size_t index = (static_cast<size_t>(RANK) - i) - 1UL;
224- reshape0[index] = calc_info.reshape_0[i];210+ reshape0[index] = calc_info.reshape_0[i];
225- reshape1[index] = calc_info.reshape_1[i];211+ reshape1[index] = calc_info.reshape_1[i];
226- reshape2[index] = calc_info.reshape_2[i];212+ reshape2[index] = calc_info.reshape_2[i];
227- shape_out[index] = calc_info.shape_out[i];213+ shape_out[index] = calc_info.shape_out[i];
228- bcast0[index] = calc_info.bcast_0[i];214+ bcast0[index] = calc_info.bcast_0[i];
229- bcast1[index] = calc_info.bcast_1[i];215+ bcast1[index] = calc_info.bcast_1[i];
230- bcast2[index] = calc_info.bcast_2[i];216+ bcast2[index] = calc_info.bcast_2[i];
231- }217+ }
232 218 
233- output.reshape(shape_out) = input0.reshape(reshape0).broadcast(bcast0).select(219+ output.reshape(shape_out) = input0.reshape(reshape0).broadcast(bcast0).select(
234- input1.reshape(reshape1).broadcast(bcast1),220+ input1.reshape(reshape1).broadcast(bcast1), input2.reshape(reshape2).broadcast(bcast2));
235- input2.reshape(reshape2).broadcast(bcast2));221+ return KERNEL_STATUS_OK;
236- return KERNEL_STATUS_OK;
237}222}
238 223 
239-KernelStatus Selectv2CpuKernel::Selectv2GenerateBcastInfo(224+KernelStatus Selectv2CpuKernel::Selectv2GenerateBcastInfo(const SelectV2BCalcInfo& calc_info)
240- const SelectV2BCalcInfo& calc_info) {225+{
241- x_reshape_ = calc_info.input_0->GetTensorShape()->GetDimSizes();226+ x_reshape_ = calc_info.input_0->GetTensorShape()->GetDimSizes();
242- y_reshape_ = calc_info.input_1->GetTensorShape()->GetDimSizes();227+ y_reshape_ = calc_info.input_1->GetTensorShape()->GetDimSizes();
243- z_reshape_ = calc_info.input_2->GetTensorShape()->GetDimSizes();228+ z_reshape_ = calc_info.input_2->GetTensorShape()->GetDimSizes();
244- shape_out_ = calc_info.output->GetTensorShape()->GetDimSizes();229+ shape_out_ = calc_info.output->GetTensorShape()->GetDimSizes();
245 230 
246- std::reverse(x_reshape_.begin(), x_reshape_.end());231+ std::reverse(x_reshape_.begin(), x_reshape_.end());
247- std::reverse(y_reshape_.begin(), y_reshape_.end());232+ std::reverse(y_reshape_.begin(), y_reshape_.end());
248- std::reverse(z_reshape_.begin(), z_reshape_.end());233+ std::reverse(z_reshape_.begin(), z_reshape_.end());
249 234 
250- size_t dim_num_x = x_reshape_.size();235+ size_t dim_num_x = x_reshape_.size();
251- size_t dim_num_y = y_reshape_.size();236+ size_t dim_num_y = y_reshape_.size();
252- size_t dim_num_z = z_reshape_.size();237+ size_t dim_num_z = z_reshape_.size();
253 238 
254- size_t max_size = std::max({dim_num_x, dim_num_y, dim_num_z});239+ size_t max_size = std::max({dim_num_x, dim_num_y, dim_num_z});
255- if (dim_num_x != max_size) {240+ if (dim_num_x != max_size) {
256- x_reshape_.resize(max_size, kNoBroadcastValue);241+ x_reshape_.resize(max_size, kNoBroadcastValue);
257- }242+ }
258- if (dim_num_y != max_size) {243+ if (dim_num_y != max_size) {
259- y_reshape_.resize(max_size, kNoBroadcastValue);244+ y_reshape_.resize(max_size, kNoBroadcastValue);
260- }245+ }
261- if (dim_num_z != max_size) {246+ if (dim_num_z != max_size) {
262- z_reshape_.resize(max_size, kNoBroadcastValue);247+ z_reshape_.resize(max_size, kNoBroadcastValue);
263- }248+ }
264- std::reverse(x_reshape_.begin(), x_reshape_.end());249+ std::reverse(x_reshape_.begin(), x_reshape_.end());
265- std::reverse(y_reshape_.begin(), y_reshape_.end());250+ std::reverse(y_reshape_.begin(), y_reshape_.end());
266- std::reverse(z_reshape_.begin(), z_reshape_.end());251+ std::reverse(z_reshape_.begin(), z_reshape_.end());
267- // Check if shape match252+ // Check if shape match
268- if (shape_out_.size() != max_size) {253+ if (shape_out_.size() != max_size) {
269- KERNEL_LOG_ERROR("shape mismatch, max_dim_in=%zu, dim_out=%zu.", max_size,254+ KERNEL_LOG_ERROR("shape mismatch, max_dim_in=%zu, dim_out=%zu.", max_size, shape_out_.size());
270- shape_out_.size());255+ return KERNEL_STATUS_PARAM_INVALID;
271- return KERNEL_STATUS_PARAM_INVALID;256+ }
272- }257+ for (size_t i = 0; i < max_size; ++i) {
273- for (size_t i = 0; i < max_size; ++i) {258+ if (shape_out_[i] != std::max({x_reshape_[i], y_reshape_[i], z_reshape_[i]})) {
274- if (shape_out_[i] !=259+ KERNEL_LOG_ERROR("shape mismatch, index=%zu, dim_x=%ld, dim_y=%ld, dim_z=%ld"
275- std::max({x_reshape_[i], y_reshape_[i], z_reshape_[i]})) {260+ "dim_out=%ld.",
276- KERNEL_LOG_ERROR(261+ i, x_reshape_[i], y_reshape_[i], z_reshape_[i], shape_out_[i]);
277- "shape mismatch, index=%zu, dim_x=%ld, dim_y=%ld, dim_z=%ld"262+ return KERNEL_STATUS_PARAM_INVALID;
278- "dim_out=%ld.",263+ }
279- i, x_reshape_[i], y_reshape_[i], z_reshape_[i], shape_out_[i]);
280- return KERNEL_STATUS_PARAM_INVALID;
281 }264 }
282- }
283 265 
284- // genarate broarcast info266+ // genarate broarcast info
285- if (SelectV2BcastInfo(max_size) != KERNEL_STATUS_OK) {267+ if (SelectV2BcastInfo(max_size) != KERNEL_STATUS_OK) {
286- KERNEL_LOG_ERROR("SelectV2 genarate broarcast info failed.");268+ KERNEL_LOG_ERROR("SelectV2 genarate broarcast info failed.");
287- return KERNEL_STATUS_PARAM_INVALID;269+ return KERNEL_STATUS_PARAM_INVALID;
288- }270+ }
289- return KERNEL_STATUS_OK;271+ return KERNEL_STATUS_OK;
290}272}
291 273 
292-KernelStatus Selectv2CpuKernel::SelectV2BcastInfo(size_t max_size) {274+KernelStatus Selectv2CpuKernel::SelectV2BcastInfo(size_t max_size)
293- // genarate broarcast info275+{
294- x_bcast_.resize(max_size, kNoBroadcastValue);276+ // genarate broarcast info
295- y_bcast_.resize(max_size, kNoBroadcastValue);277+ x_bcast_.resize(max_size, kNoBroadcastValue);
296- z_bcast_.resize(max_size, kNoBroadcastValue);278+ y_bcast_.resize(max_size, kNoBroadcastValue);
297- for (size_t i = 0; i < max_size; ++i) {279+ z_bcast_.resize(max_size, kNoBroadcastValue);
298- // no need broadcast280+ for (size_t i = 0; i < max_size; ++i) {
299- if ((x_reshape_[i] == y_reshape_[i]) && (y_reshape_[i] == z_reshape_[i])) {281+ // no need broadcast
300- continue;282+ if ((x_reshape_[i] == y_reshape_[i]) && (y_reshape_[i] == z_reshape_[i])) {
301- }283+ continue;
284+ }
302 285 
303- if (SelectV2BcastCheck(x_reshape_[i], y_reshape_[i], z_reshape_[i]) !=286+ if (SelectV2BcastCheck(x_reshape_[i], y_reshape_[i], z_reshape_[i]) != KERNEL_STATUS_OK) {
304- KERNEL_STATUS_OK) {287+ KERNEL_LOG_ERROR("Broadcast not support, dim_x[%zu]=%ld, dim_y[%zu]=%ld.", i, x_reshape_[i], i,
305- KERNEL_LOG_ERROR("Broadcast not support, dim_x[%zu]=%ld, dim_y[%zu]=%ld.",288+ y_reshape_[i]);
306- i, x_reshape_[i], i, y_reshape_[i]);289+ return KERNEL_STATUS_PARAM_INVALID;
307- return KERNEL_STATUS_PARAM_INVALID;290+ }
291+ if (x_reshape_[i] == kNoBroadcastValue) {
292+ x_bcast_[i] = std::max(y_reshape_[i], z_reshape_[i]);
293+ }
294+ if (y_reshape_[i] == kNoBroadcastValue) {
295+ y_bcast_[i] = std::max(x_reshape_[i], z_reshape_[i]);
296+ }
297+ if (z_reshape_[i] == kNoBroadcastValue) {
298+ z_bcast_[i] = std::max(x_reshape_[i], y_reshape_[i]);
299+ }
308 }300 }
309- if (x_reshape_[i] == kNoBroadcastValue) {301+ return KERNEL_STATUS_OK;
310- x_bcast_[i] = std::max(y_reshape_[i], z_reshape_[i]);
311- }
312- if (y_reshape_[i] == kNoBroadcastValue) {
313- y_bcast_[i] = std::max(x_reshape_[i], z_reshape_[i]);
314- }
315- if (z_reshape_[i] == kNoBroadcastValue) {
316- z_bcast_[i] = std::max(x_reshape_[i], y_reshape_[i]);
317- }
318- }
319- return KERNEL_STATUS_OK;
320}302}
321 303 
322-KernelStatus Selectv2CpuKernel::SelectV2BcastCheck(const int64_t x,304+KernelStatus Selectv2CpuKernel::SelectV2BcastCheck(const int64_t x, const int64_t y, const int64_t z) const
323- const int64_t y,305+{
324- const int64_t z) const {306+ std::unordered_set<int64_t> set_tmp{x, y, z};
325- std::unordered_set<int64_t> set_tmp{x, y, z};307+ if (set_tmp.size() != kNoRepeatElements) {
326- if (set_tmp.size() != kNoRepeatElements) {308+ return KERNEL_STATUS_PARAM_INVALID;
327- return KERNEL_STATUS_PARAM_INVALID;309+ }
328- }310+ if (x != 1 && y != 1 && z != 1) {
329- if (x != 1 && y != 1 && z != 1) {311+ return KERNEL_STATUS_PARAM_INVALID;
330- return KERNEL_STATUS_PARAM_INVALID;312+ }
331- }313+ return KERNEL_STATUS_OK;
332- return KERNEL_STATUS_OK;
333}314}
334 315 
335-void Selectv2CpuKernel::SelectV2GetBcastVec(SelectV2BCalcInfo& calc_info) const {316+void Selectv2CpuKernel::SelectV2GetBcastVec(SelectV2BCalcInfo& calc_info) const
336- calc_info.reshape_0 = std::move(x_reshape_);317+{
337- calc_info.reshape_1 = std::move(y_reshape_);318+ calc_info.reshape_0 = std::move(x_reshape_);
338- calc_info.reshape_2 = std::move(z_reshape_);319+ calc_info.reshape_1 = std::move(y_reshape_);
339- calc_info.shape_out = std::move(shape_out_);320+ calc_info.reshape_2 = std::move(z_reshape_);
340- calc_info.bcast_0 = std::move(x_bcast_);321+ calc_info.shape_out = std::move(shape_out_);
341- calc_info.bcast_1 = std::move(y_bcast_);322+ calc_info.bcast_0 = std::move(x_bcast_);
342- calc_info.bcast_2 = std::move(z_bcast_);323+ calc_info.bcast_1 = std::move(y_bcast_);
324+ calc_info.bcast_2 = std::move(z_bcast_);
343}325}
344-REGISTER_CPU_KERNEL(kSelectV2, Selectv2CpuKernel);326+OPS_MATH_REGISTER_CPU_KERNELV2(kSelectV2, Selectv2CpuKernel);
345-} // namespace aicpu327+} // namespace aicpu
@@ -0,0 +1,36 @@
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 "register/op_def_registry.h"
12+#include "../../../common/inc/aicpu/aicpu_op_def.h"
13+ 
14+namespace ops {
15+class SelectV2 : public OpDef {
16+public:
17+ explicit SelectV2(const char* name) : OpDef(name)
18+ {
19+ this->Input("condition").DataType({ge::DT_BOOL});
20+ this->Input("then").DataType({ge::DT_COMPLEX128, ge::DT_COMPLEX64, ge::DT_DOUBLE, ge::DT_FLOAT, ge::DT_FLOAT16,
21+ ge::DT_INT16, ge::DT_INT32, ge::DT_INT64, ge::DT_INT8, ge::DT_UINT16,
22+ ge::DT_UINT32, ge::DT_UINT64, ge::DT_UINT8, ge::DT_BOOL});
23+ this->Input("else").DataType({ge::DT_COMPLEX128, ge::DT_COMPLEX64, ge::DT_DOUBLE, ge::DT_FLOAT, ge::DT_FLOAT16,
24+ ge::DT_INT16, ge::DT_INT32, ge::DT_INT64, ge::DT_INT8, ge::DT_UINT16,
25+ ge::DT_UINT32, ge::DT_UINT64, ge::DT_UINT8, ge::DT_BOOL});
26+ this->Output("result").DataType({ge::DT_COMPLEX128, ge::DT_COMPLEX64, ge::DT_DOUBLE, ge::DT_FLOAT,
27+ ge::DT_FLOAT16, ge::DT_INT16, ge::DT_INT32, ge::DT_INT64, ge::DT_INT8,
28+ ge::DT_UINT16, ge::DT_UINT32, ge::DT_UINT64, ge::DT_UINT8, ge::DT_BOOL});
29+ 
30+ ApplyMathAicpuDefaultCfg(*this);
31+ this->AICPU().ExtendCfgInfo(OP_INFO_OPS_FLAG.c_str(), OPEN_OPS_FLAG.c_str());
32+ }
33+};
34+ 
35+OP_ADD(SelectV2);
36+} // namespace ops
@@ -12,4 +12,4 @@
12set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62")12set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62")
13# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译13# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译
14set(SUPPORT_TILING_DIR "arch35" "arch35")14set(SUPPORT_TILING_DIR "arch35" "arch35")
15-add_all_modules_sources(OPTYPE square ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE)15+add_all_modules_sources(OPTYPE square ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE HOSTCPU TRUE)
@@ -12,6 +12,7 @@
12 12 
13#include <complex>13#include <complex>
14#include <unsupported/Eigen/CXX11/Tensor>14#include <unsupported/Eigen/CXX11/Tensor>
15+#include "aicpu/math_aicpu_register.h"
15#include "cpu_kernel_utils.h"16#include "cpu_kernel_utils.h"
16#include "cpu_types.h"17#include "cpu_types.h"
17#include "log.h"18#include "log.h"
@@ -40,9 +41,9 @@ const char* const kSquare{"Square"};
40namespace aicpu {41namespace aicpu {
41namespace detail {42namespace detail {
42template <typename T>43template <typename T>
43-typename std::enable_if<44+typename std::enable_if<std::is_same<T, std::complex<std::float_t>>::value ||
44- std::is_same<T, std::complex<std::float_t>>::value || std::is_same<T, std::complex<std::double_t>>::value,45+ std::is_same<T, std::complex<std::double_t>>::value,
45- void>::type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end)46+ void>::type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end)
46{47{
47 T* inner_input = input + begin;48 T* inner_input = input + begin;
48 T* inner_output = output + begin;49 T* inner_output = output + begin;
@@ -56,8 +57,8 @@ typename std::enable_if<
56}57}
57 58 
58template <typename T>59template <typename T>
59-typename std::enable_if<std::is_same<T, int32_t>::value || std::is_same<T, double_t>::value, void>::60+typename std::enable_if<std::is_same<T, int32_t>::value || std::is_same<T, double_t>::value,
60- type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end)61+ void>::type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end)
61{62{
62 int64_t length = end - begin;63 int64_t length = end - begin;
63 Eigen::TensorMap<Eigen::Tensor<T, 1>, Eigen::Aligned> tensor_x(input + begin, length);64 Eigen::TensorMap<Eigen::Tensor<T, 1>, Eigen::Aligned> tensor_x(input + begin, length);
@@ -66,9 +67,9 @@ typename std::enable_if<std::is_same<T, int32_t>::value || std::is_same<T, doubl
66}67}
67 68 
68template <typename T>69template <typename T>
69-typename std::enable_if<70+typename std::enable_if<std::is_same<T, int64_t>::value || std::is_same<T, float_t>::value ||
70- std::is_same<T, int64_t>::value || std::is_same<T, float_t>::value || std::is_same<T, Eigen::half>::value,71+ std::is_same<T, Eigen::half>::value,
71- void>::type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end)72+ void>::type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end)
72{73{
73 T* inner_input = input + begin;74 T* inner_input = input + begin;
74 T* inner_output = output + begin;75 T* inner_output = output + begin;
@@ -124,9 +125,8 @@ inline std::uint32_t ComputeSquare(const CpuKernelContext& ctx, const int64_t pa
124inline std::uint32_t SquareExtraCheck(const CpuKernelContext& ctx)125inline std::uint32_t SquareExtraCheck(const CpuKernelContext& ctx)
125{126{
126 if (ctx.Input(0)->GetDataType() != ctx.Output(0)->GetDataType()) {127 if (ctx.Input(0)->GetDataType() != ctx.Output(0)->GetDataType()) {
127- KERNEL_LOG_ERROR(128+ KERNEL_LOG_ERROR("The data type of the input [%s] need be the same as the ouput [%s].",
128- "The data type of the input [%s] need be the same as the ouput [%s].",129+ DTypeStr(ctx.Input(0)->GetDataType()).c_str(), DTypeStr(ctx.Output(0)->GetDataType()).c_str());
129- DTypeStr(ctx.Input(0)->GetDataType()).c_str(), DTypeStr(ctx.Output(0)->GetDataType()).c_str());
130 return KERNEL_STATUS_PARAM_INVALID;130 return KERNEL_STATUS_PARAM_INVALID;
131 }131 }
132 KERNEL_CHECK_NULLPTR(ctx.Input(0)->GetData(), KERNEL_STATUS_PARAM_INVALID, "Get input data failed.")132 KERNEL_CHECK_NULLPTR(ctx.Input(0)->GetData(), KERNEL_STATUS_PARAM_INVALID, "Get input data failed.")
@@ -134,18 +134,16 @@ inline std::uint32_t SquareExtraCheck(const CpuKernelContext& ctx)
134 std::vector<int64_t> input_dims = ctx.Input(0)->GetTensorShape()->GetDimSizes();134 std::vector<int64_t> input_dims = ctx.Input(0)->GetTensorShape()->GetDimSizes();
135 std::vector<int64_t> output_dims = ctx.Output(0)->GetTensorShape()->GetDimSizes();135 std::vector<int64_t> output_dims = ctx.Output(0)->GetTensorShape()->GetDimSizes();
136 if (input_dims.size() != output_dims.size()) {136 if (input_dims.size() != output_dims.size()) {
137- KERNEL_LOG_ERROR(137+ KERNEL_LOG_ERROR("The data dim of the input size [%lu] need be the same as the output "
138- "The data dim of the input size [%lu] need be the same as the output "138+ "size [%lu].",
139- "size [%lu].",139+ input_dims.size(), output_dims.size());
140- input_dims.size(), output_dims.size());
141 return KERNEL_STATUS_PARAM_INVALID;140 return KERNEL_STATUS_PARAM_INVALID;
142 }141 }
143 for (size_t index = 0; index < input_dims.size(); index++) {142 for (size_t index = 0; index < input_dims.size(); index++) {
144 if (input_dims[index] != output_dims[index]) {143 if (input_dims[index] != output_dims[index]) {
145- KERNEL_LOG_ERROR(144+ KERNEL_LOG_ERROR("The data dim[%lu]=%ld of the input need be the same as the output "
146- "The data dim[%lu]=%ld of the input need be the same as the output "145+ "dim[%lu]=%ld.",
147- "dim[%lu]=%ld.",146+ index, input_dims[index], index, output_dims[index]);
148- index, input_dims[index], index, output_dims[index]);
149 return KERNEL_STATUS_PARAM_INVALID;147 return KERNEL_STATUS_PARAM_INVALID;
150 }148 }
151 }149 }
@@ -187,5 +185,5 @@ std::uint32_t SquareCpuKernel::Compute(CpuKernelContext& ctx)
187 return detail::SquareCheck(ctx) ? KERNEL_STATUS_PARAM_INVALID : detail::SquareCompute(ctx);185 return detail::SquareCheck(ctx) ? KERNEL_STATUS_PARAM_INVALID : detail::SquareCompute(ctx);
188}186}
189 187 
190-REGISTER_CPU_KERNEL(kSquare, SquareCpuKernel);188+OPS_MATH_REGISTER_CPU_KERNELV2(kSquare, SquareCpuKernel);
191} // namespace aicpu189} // namespace aicpu
@@ -12,4 +12,4 @@
12set(SUPPORT_COMPUTE_UNIT "ascend950")12set(SUPPORT_COMPUTE_UNIT "ascend950")
13# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译13# 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译
14set(SUPPORT_TILING_DIR "arch35")14set(SUPPORT_TILING_DIR "arch35")
15-add_all_modules_sources(OPTYPE squared_difference ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE)15+add_all_modules_sources(OPTYPE squared_difference ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE HOSTCPU TRUE)
@@ -9,6 +9,7 @@
9 */9 */
10#include "squared_difference_aicpu.h"10#include "squared_difference_aicpu.h"
11 11 
12+#include "aicpu/math_aicpu_register.h"
12#include "cpu_kernel_utils.h"13#include "cpu_kernel_utils.h"
13#include "utils/eigen_tensor.h"14#include "utils/eigen_tensor.h"
14#include "utils/kernel_util.h"15#include "utils/kernel_util.h"
@@ -37,8 +38,8 @@ const int64_t kParallelDataNumSameShapeMid = 35 * 1024;
37namespace aicpu {38namespace aicpu {
38uint32_t SquaredDifferenceCpuKernel::Compute(CpuKernelContext& ctx)39uint32_t SquaredDifferenceCpuKernel::Compute(CpuKernelContext& ctx)
39{40{
40- KERNEL_HANDLE_ERROR(41+ KERNEL_HANDLE_ERROR(NormalCheck(ctx, kInputNum, kOutputNum),
41- NormalCheck(ctx, kInputNum, kOutputNum), "SquaredDifference check input and output number failed.");42+ "SquaredDifference check input and output number failed.");
42 KERNEL_HANDLE_ERROR(SquaredDifferenceCheck(ctx), "SquaredDifference check params failed.");43 KERNEL_HANDLE_ERROR(SquaredDifferenceCheck(ctx), "SquaredDifference check params failed.");
43 DataType data_type = ctx.Input(0)->GetDataType();44 DataType data_type = ctx.Input(0)->GetDataType();
44 switch (data_type) {45 switch (data_type) {
@@ -85,15 +86,13 @@ uint32_t SquaredDifferenceCpuKernel::SquaredDifferenceCheck(const CpuKernelConte
85 KERNEL_CHECK_NULLPTR(output->GetData(), KERNEL_STATUS_PARAM_INVALID, "Get output data failed")86 KERNEL_CHECK_NULLPTR(output->GetData(), KERNEL_STATUS_PARAM_INVALID, "Get output data failed")
86 DataType input0_type = input_0->GetDataType();87 DataType input0_type = input_0->GetDataType();
87 DataType input1_type = input_1->GetDataType();88 DataType input1_type = input_1->GetDataType();
88- KERNEL_CHECK_FALSE(89+ KERNEL_CHECK_FALSE((input0_type == input1_type), KERNEL_STATUS_PARAM_INVALID,
89- (input0_type == input1_type), KERNEL_STATUS_PARAM_INVALID,90+ "The data type of input0 [%s] need be same with "
90- "The data type of input0 [%s] need be same with "91+ "input1 [%s].",
91- "input1 [%s].",92+ DTypeStr(input0_type).c_str(), DTypeStr(input1_type).c_str())
92- DTypeStr(input0_type).c_str(), DTypeStr(input1_type).c_str())93+ KERNEL_LOG_DEBUG("SquaredDifferenceCpuKernel[%s], input0: size[%lu];"
93- KERNEL_LOG_DEBUG(94+ "input1: size[%lu], output: size[%lu].",
94- "SquaredDifferenceCpuKernel[%s], input0: size[%lu];"95+ ctx.GetOpType().c_str(), input_0->GetDataSize(), input_1->GetDataSize(), output->GetDataSize());
95- "input1: size[%lu], output: size[%lu].",
96- ctx.GetOpType().c_str(), input_0->GetDataSize(), input_1->GetDataSize(), output->GetDataSize());
97 96 
98 return KERNEL_STATUS_OK;97 return KERNEL_STATUS_OK;
99}98}
@@ -104,8 +103,8 @@ uint32_t SquaredDifferenceCpuKernel::SquaredDifferenceCheck(const CpuKernelConte
104// 3. input2 is a 1D tensor with only one element or input2 is scalar103// 3. input2 is a 1D tensor with only one element or input2 is scalar
105// 4. the shapes of input1 and input2 are different104// 4. the shapes of input1 and input2 are different
106template <typename T>105template <typename T>
107-void SquaredDifferenceCpuKernel::SpecialCompute(106+void SquaredDifferenceCpuKernel::SpecialCompute(BcastShapeType type, int64_t start, int64_t end, const T* input1,
108- BcastShapeType type, int64_t start, int64_t end, const T* input1, const T* input2, T* output)107+ const T* input2, T* output)
109{108{
110 switch (type) {109 switch (type) {
111 case BcastShapeType::SAME_SHAPE:110 case BcastShapeType::SAME_SHAPE:
@@ -228,8 +227,8 @@ uint32_t SquaredDifferenceCpuKernel::SquaredDifferenceCompute(const CpuKernelCon
228 auto input1_shape = input1_tensor->GetTensorShape()->GetDimSizes();227 auto input1_shape = input1_tensor->GetTensorShape()->GetDimSizes();
229 int64_t input1_elements_nums = input1_tensor->NumElements();228 int64_t input1_elements_nums = input1_tensor->NumElements();
230 229 
231- bool is_no_need_bcast =230+ bool is_no_need_bcast = (input0_shape == input1_shape) || (input0_elements_nums == 1) ||
232- (input0_shape == input1_shape) || (input0_elements_nums == 1) || (input1_elements_nums == 1);231+ (input1_elements_nums == 1);
233 if (is_no_need_bcast) {232 if (is_no_need_bcast) {
234 return NoBcastCompute<T>(ctx);233 return NoBcastCompute<T>(ctx);
235 } else {234 } else {
@@ -243,5 +242,5 @@ uint32_t SquaredDifferenceCpuKernel::SquaredDifferenceCompute(const CpuKernelCon
243 }242 }
244}243}
245 244 
246-REGISTER_CPU_KERNEL(kSquaredDifference, SquaredDifferenceCpuKernel);245+OPS_MATH_REGISTER_CPU_KERNELV2(kSquaredDifference, SquaredDifferenceCpuKernel);
247-} // namespace aicpu246+} // namespace aicpu