已合并
revert aicpu of scatter_elements_v2 #6574
青青吾心创建于 6月25日
revert aicpu of scatter_elements_v2 #6574
已合并
青青吾心创建于 6月25日
5 个文件变更+52-667
Mindex/scatter_elements/op_kernel_aicpu/CMakeLists.txt+0-19
@@ -12,18 +12,6 @@ set(ASCEND_OP_NAME "" CACHE STRING "Ascend op names to compile")
12set(OP_TYPE "scatter_elements")12set(OP_TYPE "scatter_elements")
13 13 
14skip_aicpu_kernel("${OP_TYPE}" "${ASCEND_OP_NAME}")14skip_aicpu_kernel("${OP_TYPE}" "${ASCEND_OP_NAME}")
15-if(SKIP_AICPU_FLAG)
16- foreach(_ops_var ASCEND_COMPILE_OPS COMPILED_OPS)
17- if(DEFINED ${_ops_var} AND NOT "${${_ops_var}}" STREQUAL "")
18- list(FIND ${_ops_var} "${OP_TYPE}" _op_index)
19- if(NOT _op_index EQUAL -1)
20- message(STATUS "[${OP_TYPE}] selected as dependency from ${_ops_var}: ${${_ops_var}}")
21- set(SKIP_AICPU_FLAG FALSE)
22- break()
23- endif()
24- endif()
25- endforeach()
26-endif()
27if(SKIP_AICPU_FLAG)15if(SKIP_AICPU_FLAG)
28 return()16 return()
29endif()17endif()
@@ -39,13 +27,6 @@ if (BUILD_WITH_INSTALLED_DEPENDENCY_CANN_PKG)
39 set_property(GLOBAL APPEND PROPERTY AICPU_OP_DEF_FILES ${AICPU_OPDEF_SRC})27 set_property(GLOBAL APPEND PROPERTY AICPU_OP_DEF_FILES ${AICPU_OPDEF_SRC})
40 set(OBJ_NAME scatter_elements_cust_obj)28 set(OBJ_NAME scatter_elements_cust_obj)
41 add_aicpu_cust_kernel_modules(${OBJ_NAME})29 add_aicpu_cust_kernel_modules(${OBJ_NAME})
42- if(NOT PREPROCESS_ONLY)
43- if(TARGET ${OBJ_NAME} AND NOT ${OBJ_NAME} IN_LIST AICPU_CUST_OBJ_TARGETS)
44- set(AICPU_CUST_OBJ_TARGETS
45- ${AICPU_CUST_OBJ_TARGETS} ${OBJ_NAME}
46- CACHE INTERNAL "All aicpu cust obj targets")
47- endif()
48- endif()
49 target_sources(${OBJ_NAME} PRIVATE ${AICPU_SRC})30 target_sources(${OBJ_NAME} PRIVATE ${AICPU_SRC})
50else()31else()
51 add_modules_sources(HOSTNAME ${OPHOST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR} OPTYPE scatter_elements ACLNNTYPE aclnn_exclude)32 add_modules_sources(HOSTNAME ${OPHOST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR} OPTYPE scatter_elements ACLNNTYPE aclnn_exclude)
Mindex/scatter_elements/op_kernel_aicpu/scatter_elements_aicpu.cpp+51-494
@@ -12,7 +12,6 @@
12 12 
13#include <atomic>13#include <atomic>
14#include <complex>14#include <complex>
15-#include <memory>
16#include <string>15#include <string>
17#include <vector>16#include <vector>
18 17 
@@ -31,176 +30,11 @@ const uint32_t kUpdatesInputIndex = 2;
31const uint8_t kReductionNone = 0;30const uint8_t kReductionNone = 0;
32const uint8_t kReductionAdd = 1;31const uint8_t kReductionAdd = 1;
33const uint8_t kReductionMul = 2;32const uint8_t kReductionMul = 2;
34-const uint8_t kReductionMax = 3;
35-const uint8_t kReductionMin = 4;
36-const uint8_t kReductionMean = 5;
37-const int64_t kBoolMajorityDivisor = 2;
38- 
39-inline int64_t FloorDiv(int64_t value, int64_t divisor) {
40- if (divisor == 0) {
41- return 0;
42- }
43- int64_t quotient = value / divisor;
44- int64_t remainder = value % divisor;
45- if (remainder != 0 && value < 0) {
46- --quotient;
47- }
48- return quotient;
49-}
50- 
51-template <typename T>
52-inline T MeanDivide(T sum, int64_t count) {
53- if (count == 0) {
54- return T(0);
55- }
56- return sum / static_cast<T>(count);
57-}
58- 
59-template <>
60-inline int8_t MeanDivide<int8_t>(int8_t sum, int64_t count) {
61- if (count == 0) {
62- return 0;
63- }
64- return static_cast<int8_t>(FloorDiv(static_cast<int64_t>(sum), count));
65-}
66- 
67-template <>
68-inline int16_t MeanDivide<int16_t>(int16_t sum, int64_t count) {
69- if (count == 0) {
70- return 0;
71- }
72- return static_cast<int16_t>(FloorDiv(static_cast<int64_t>(sum), count));
73-}
74- 
75-template <>
76-inline int32_t MeanDivide<int32_t>(int32_t sum, int64_t count) {
77- if (count == 0) {
78- return 0;
79- }
80- return static_cast<int32_t>(FloorDiv(static_cast<int64_t>(sum), count));
81-}
82- 
83-template <>
84-inline int64_t MeanDivide<int64_t>(int64_t sum, int64_t count) {
85- if (count == 0) {
86- return 0;
87- }
88- return FloorDiv(sum, count);
89-}
90- 
91-template <typename T>
92-class MeanReductionHelper {
93- public:
94- explicit MeanReductionHelper(int64_t size) : size_(size) {
95- counts_.resize(size, 0);
96- sums_.resize(size, T(0));
97- }
98- 
99- void AddUpdate(int64_t index, T value) {
100- sums_[index] += value;
101- counts_[index]++;
102- }
103- 
104- void Finalize(T *output) {
105- for (int64_t i = 0; i < size_; ++i) {
106- if (counts_[i] > 0) {
107- output[i] = MeanDivide(sums_[i], counts_[i]);
108- }
109- }
110- }
111- 
112- private:
113- int64_t size_;
114- std::vector<int64_t> counts_;
115- std::vector<T> sums_;
116-};
117- 
118-template <>
119-class MeanReductionHelper<std::complex<float>> {
120- public:
121- explicit MeanReductionHelper(int64_t size) : size_(size) {
122- counts_.resize(size, 0);
123- sums_.resize(size, std::complex<float>(0.0f, 0.0f));
124- }
125- 
126- void AddUpdate(int64_t index, std::complex<float> value) {
127- sums_[index] += value;
128- counts_[index]++;
129- }
130- 
131- void Finalize(std::complex<float> *output) {
132- for (int64_t i = 0; i < size_; ++i) {
133- if (counts_[i] > 0) {
134- output[i] = sums_[i] / static_cast<float>(counts_[i]);
135- }
136- }
137- }
138- 
139- private:
140- int64_t size_;
141- std::vector<int64_t> counts_;
142- std::vector<std::complex<float>> sums_;
143-};
144- 
145-template <>
146-class MeanReductionHelper<std::complex<double>> {
147- public:
148- explicit MeanReductionHelper(int64_t size) : size_(size) {
149- counts_.resize(size, 0);
150- sums_.resize(size, std::complex<double>(0.0, 0.0));
151- }
152- 
153- void AddUpdate(int64_t index, std::complex<double> value) {
154- sums_[index] += value;
155- counts_[index]++;
156- }
157- 
158- void Finalize(std::complex<double> *output) {
159- for (int64_t i = 0; i < size_; ++i) {
160- if (counts_[i] > 0) {
161- output[i] = sums_[i] / static_cast<double>(counts_[i]);
162- }
163- }
164- }
165- 
166- private:
167- int64_t size_;
168- std::vector<int64_t> counts_;
169- std::vector<std::complex<double>> sums_;
170-};
171- 
172-template <>
173-class MeanReductionHelper<bool> {
174- public:
175- explicit MeanReductionHelper(int64_t size) : size_(size) {
176- counts_.resize(size, 0);
177- sums_.resize(size, 0);
178- }
179- 
180- void AddUpdate(int64_t index, bool value) {
181- sums_[index] += value ? 1 : 0;
182- counts_[index]++;
183- }
184- 
185- void Finalize(bool *output) {
186- for (int64_t i = 0; i < size_; ++i) {
187- if (counts_[i] > 0) {
188- output[i] = sums_[i] > (counts_[i] / kBoolMajorityDivisor);
189- }
190- }
191- }
192- 
193- private:
194- int64_t size_;
195- std::vector<int64_t> counts_;
196- std::vector<int64_t> sums_;
197-};
198 33 
199struct ScatterElementsComputeInfo {34struct ScatterElementsComputeInfo {
200 int64_t total_value_num = 0;35 int64_t total_value_num = 0;
201 int64_t axis_value = 0;36 int64_t axis_value = 0;
202 uint8_t reduction_flag = kReductionNone;37 uint8_t reduction_flag = kReductionNone;
203- bool include_self = true;
204 int64_t value_dim_num_x1 = 0;38 int64_t value_dim_num_x1 = 0;
205 int64_t value_dim_num_x2 = 0;39 int64_t value_dim_num_x2 = 0;
206 int64_t value_dim_num_x3 = 0;40 int64_t value_dim_num_x3 = 0;
@@ -226,279 +60,35 @@ std::vector<int64_t> GetTensorDims(const std::shared_ptr<TensorShape> &shape, in
226}60}
227 61 
228uint8_t GetReductionFlag(const std::string &rdt_value) {62uint8_t GetReductionFlag(const std::string &rdt_value) {
229- if (rdt_value == "add" || rdt_value == "sum") {63+ if (rdt_value == "add") {
230 return kReductionAdd;64 return kReductionAdd;
231 }65 }
232- if (rdt_value == "mul" || rdt_value == "prod") {66+ if (rdt_value == "mul") {
233 return kReductionMul;67 return kReductionMul;
234 }68 }
235- if (rdt_value == "max" || rdt_value == "amax") {69+ 
236- return kReductionMax;
237- }
238- if (rdt_value == "min" || rdt_value == "amin") {
239- return kReductionMin;
240- }
241- if (rdt_value == "mean") {
242- return kReductionMean;
243- }
244 return kReductionNone;70 return kReductionNone;
245}71}
246 72 
247template <typename T>73template <typename T>
248-inline void AddComputeWithSelf(T *output, const T *update, int64_t index, int64_t update_idx) {74+inline void ApplyReduction(const T *updates, T *output, int64_t index_value, int64_t update_index, uint8_t flag) {
249- output[index] += update[update_idx];75+ if (flag == kReductionNone) {
250-}76+ output[index_value] = updates[update_index];
251- 77+ } else if (flag == kReductionAdd) {
252-template <typename T>78+ output[index_value] += updates[update_index];
253-inline void MulComputeWithSelf(T *output, const T *update, int64_t index, int64_t update_idx) {
254- output[index] *= update[update_idx];
255-}
256- 
257-template <typename T>
258-inline void MaxComputeWithSelf(T *output, const T *update, int64_t index, int64_t update_idx) {
259- if (update[update_idx] > output[index]) {
260- output[index] = update[update_idx];
261- }
262-}
263- 
264-template <typename T>
265-inline void MinComputeWithSelf(T *output, const T *update, int64_t index, int64_t update_idx) {
266- if (update[update_idx] < output[index]) {
267- output[index] = update[update_idx];
268- }
269-}
270- 
271-template <typename T>
272-inline void AddComputeWithoutSelf(T *output, const T *update, int64_t index, int64_t update_idx,
273- int64_t update_count) {
274- if (update_count == 0) {
275- output[index] = update[update_idx];
276 } else {79 } else {
277- output[index] += update[update_idx];80+ output[index_value] *= updates[update_index];
278 }81 }
279}82}
280 83 
281-template <typename T>84+template <>
282-inline void MulComputeWithoutSelf(T *output, const T *update, int64_t index, int64_t update_idx,85+inline void ApplyReduction(const bool *updates, bool *output, int64_t index_value, int64_t update_index, uint8_t flag) {
283- int64_t update_count) {86+ if (flag == kReductionAdd) {
284- if (update_count == 0) {87+ output[index_value] = output[index_value] || updates[update_index];
285- output[index] = update[update_idx];88+ } else if (flag == kReductionMul) {
89+ output[index_value] = output[index_value] && updates[update_index];
286 } else {90 } else {
287- output[index] *= update[update_idx];91+ output[index_value] = updates[update_index];
288- }
289-}
290- 
291-template <typename T>
292-inline void MaxComputeWithoutSelf(T *output, const T *update, int64_t index, int64_t update_idx,
293- int64_t update_count) {
294- if (update_count == 0) {
295- output[index] = update[update_idx];
296- } else if (update[update_idx] > output[index]) {
297- output[index] = update[update_idx];
298- }
299-}
300- 
301-template <typename T>
302-inline void MinComputeWithoutSelf(T *output, const T *update, int64_t index, int64_t update_idx,
303- int64_t update_count) {
304- if (update_count == 0) {
305- output[index] = update[update_idx];
306- } else if (update[update_idx] < output[index]) {
307- output[index] = update[update_idx];
308- }
309-}
310- 
311-template <>
312-inline void AddComputeWithSelf<bool>(bool *output, const bool *update, int64_t index, int64_t update_idx) {
313- output[index] = output[index] || update[update_idx];
314-}
315- 
316-template <>
317-inline void MulComputeWithSelf<bool>(bool *output, const bool *update, int64_t index, int64_t update_idx) {
318- output[index] = output[index] && update[update_idx];
319-}
320- 
321-template <>
322-inline void MaxComputeWithSelf<bool>(bool *output, const bool *update, int64_t index, int64_t update_idx) {
323- output[index] = output[index] || update[update_idx];
324-}
325- 
326-template <>
327-inline void MinComputeWithSelf<bool>(bool *output, const bool *update, int64_t index, int64_t update_idx) {
328- output[index] = output[index] && update[update_idx];
329-}
330- 
331-template <>
332-inline void AddComputeWithoutSelf<bool>(bool *output, const bool *update, int64_t index, int64_t update_idx,
333- int64_t update_count) {
334- if (update_count == 0) {
335- output[index] = update[update_idx];
336- } else {
337- output[index] = output[index] || update[update_idx];
338- }
339-}
340- 
341-template <>
342-inline void MulComputeWithoutSelf<bool>(bool *output, const bool *update, int64_t index, int64_t update_idx,
343- int64_t update_count) {
344- if (update_count == 0) {
345- output[index] = update[update_idx];
346- } else {
347- output[index] = output[index] && update[update_idx];
348- }
349-}
350- 
351-template <>
352-inline void MaxComputeWithoutSelf<bool>(bool *output, const bool *update, int64_t index, int64_t update_idx,
353- int64_t update_count) {
354- if (update_count == 0) {
355- output[index] = update[update_idx];
356- } else {
357- output[index] = output[index] || update[update_idx];
358- }
359-}
360- 
361-template <>
362-inline void MinComputeWithoutSelf<bool>(bool *output, const bool *update, int64_t index, int64_t update_idx,
363- int64_t update_count) {
364- if (update_count == 0) {
365- output[index] = update[update_idx];
366- } else {
367- output[index] = output[index] && update[update_idx];
368- }
369-}
370- 
371-template <>
372-inline void MaxComputeWithSelf<std::complex<float>>(std::complex<float> *output, const std::complex<float> *update,
373- int64_t index, int64_t update_idx) {
374- auto update_norm = std::norm(update[update_idx]);
375- auto output_norm = std::norm(output[index]);
376- if (update_norm > output_norm) {
377- output[index] = update[update_idx];
378- }
379-}
380- 
381-template <>
382-inline void MinComputeWithSelf<std::complex<float>>(std::complex<float> *output, const std::complex<float> *update,
383- int64_t index, int64_t update_idx) {
384- auto update_norm = std::norm(update[update_idx]);
385- auto output_norm = std::norm(output[index]);
386- if (update_norm < output_norm) {
387- output[index] = update[update_idx];
388- }
389-}
390- 
391-template <>
392-inline void MaxComputeWithSelf<std::complex<double>>(std::complex<double> *output,
393- const std::complex<double> *update, int64_t index,
394- int64_t update_idx) {
395- auto update_norm = std::norm(update[update_idx]);
396- auto output_norm = std::norm(output[index]);
397- if (update_norm > output_norm) {
398- output[index] = update[update_idx];
399- }
400-}
401- 
402-template <>
403-inline void MinComputeWithSelf<std::complex<double>>(std::complex<double> *output,
404- const std::complex<double> *update, int64_t index,
405- int64_t update_idx) {
406- auto update_norm = std::norm(update[update_idx]);
407- auto output_norm = std::norm(output[index]);
408- if (update_norm < output_norm) {
409- output[index] = update[update_idx];
410- }
411-}
412- 
413-template <typename T, bool kGreater>
414-inline void ComplexComputeWithoutSelf(T *output, const T *update, int64_t index, int64_t update_idx,
415- int64_t update_count) {
416- auto update_norm = std::norm(update[update_idx]);
417- if (update_count == 0) {
418- output[index] = update[update_idx];
419- return;
420- }
421- auto output_norm = std::norm(output[index]);
422- if ((kGreater && update_norm > output_norm) || (!kGreater && update_norm < output_norm)) {
423- output[index] = update[update_idx];
424- }
425-}
426- 
427-template <>
428-inline void MaxComputeWithoutSelf<std::complex<float>>(std::complex<float> *output,
429- const std::complex<float> *update, int64_t index,
430- int64_t update_idx, int64_t update_count) {
431- ComplexComputeWithoutSelf<std::complex<float>, true>(output, update, index, update_idx, update_count);
432-}
433- 
434-template <>
435-inline void MinComputeWithoutSelf<std::complex<float>>(std::complex<float> *output,
436- const std::complex<float> *update, int64_t index,
437- int64_t update_idx, int64_t update_count) {
438- ComplexComputeWithoutSelf<std::complex<float>, false>(output, update, index, update_idx, update_count);
439-}
440- 
441-template <>
442-inline void MaxComputeWithoutSelf<std::complex<double>>(std::complex<double> *output,
443- const std::complex<double> *update, int64_t index,
444- int64_t update_idx, int64_t update_count) {
445- ComplexComputeWithoutSelf<std::complex<double>, true>(output, update, index, update_idx, update_count);
446-}
447- 
448-template <>
449-inline void MinComputeWithoutSelf<std::complex<double>>(std::complex<double> *output,
450- const std::complex<double> *update, int64_t index,
451- int64_t update_idx, int64_t update_count) {
452- ComplexComputeWithoutSelf<std::complex<double>, false>(output, update, index, update_idx, update_count);
453-}
454- 
455-template <typename T>
456-inline void NoneCompute(T *output, const T *update, int64_t index, int64_t update_idx) {
457- output[index] = update[update_idx];
458-}
459- 
460-inline bool NeedUpdateCounts(const ScatterElementsComputeInfo &info) {
461- return !info.include_self &&
462- (info.reduction_flag == kReductionAdd || info.reduction_flag == kReductionMul ||
463- info.reduction_flag == kReductionMax || info.reduction_flag == kReductionMin);
464-}
465- 
466-template <typename T>
467-inline void ApplyScatterReduction(const ScatterElementsComputeInfo &info, const T *updates, T *output,
468- int64_t index_value, int64_t update_idx, std::vector<int64_t> &update_counts,
469- MeanReductionHelper<T> *mean_helper) {
470- if (info.reduction_flag == kReductionNone) {
471- NoneCompute(output, updates, index_value, update_idx);
472- } else if (info.reduction_flag == kReductionAdd) {
473- if (NeedUpdateCounts(info)) {
474- AddComputeWithoutSelf(output, updates, index_value, update_idx, update_counts[index_value]);
475- update_counts[index_value]++;
476- } else {
477- AddComputeWithSelf(output, updates, index_value, update_idx);
478- }
479- } else if (info.reduction_flag == kReductionMul) {
480- if (NeedUpdateCounts(info)) {
481- MulComputeWithoutSelf(output, updates, index_value, update_idx, update_counts[index_value]);
482- update_counts[index_value]++;
483- } else {
484- MulComputeWithSelf(output, updates, index_value, update_idx);
485- }
486- } else if (info.reduction_flag == kReductionMax) {
487- if (NeedUpdateCounts(info)) {
488- MaxComputeWithoutSelf(output, updates, index_value, update_idx, update_counts[index_value]);
489- update_counts[index_value]++;
490- } else {
491- MaxComputeWithSelf(output, updates, index_value, update_idx);
492- }
493- } else if (info.reduction_flag == kReductionMin) {
494- if (NeedUpdateCounts(info)) {
495- MinComputeWithoutSelf(output, updates, index_value, update_idx, update_counts[index_value]);
496- update_counts[index_value]++;
497- } else {
498- MinComputeWithSelf(output, updates, index_value, update_idx);
499- }
500- } else if (info.reduction_flag == kReductionMean && mean_helper != nullptr) {
501- mean_helper->AddUpdate(index_value, updates[update_idx]);
502 }92 }
503}93}
504 94 
@@ -508,10 +98,8 @@ uint32_t InitScatterElementsInfo(const CpuKernelContext &ctx, ScatterElementsCom
508 auto *updates_tensor = ctx.Input(kUpdatesInputIndex);98 auto *updates_tensor = ctx.Input(kUpdatesInputIndex);
509 auto *axis = ctx.GetAttr("axis");99 auto *axis = ctx.GetAttr("axis");
510 auto *reduction = ctx.GetAttr("reduction");100 auto *reduction = ctx.GetAttr("reduction");
511- auto *include_self_attr = ctx.GetAttr("include_self");
512 info.total_value_num = data_tensor->NumElements();101 info.total_value_num = data_tensor->NumElements();
513 info.axis_value = axis == nullptr ? 0 : axis->GetInt();102 info.axis_value = axis == nullptr ? 0 : axis->GetInt();
514- info.include_self = include_self_attr == nullptr ? true : include_self_attr->GetBool();
515 info.reduction_flag = GetReductionFlag(reduction == nullptr ? "none" : reduction->GetString());103 info.reduction_flag = GetReductionFlag(reduction == nullptr ? "none" : reduction->GetString());
516 info.value_dim_num_x1 = data_tensor->GetTensorShape()->GetDims();104 info.value_dim_num_x1 = data_tensor->GetTensorShape()->GetDims();
517 info.value_dim_num_x2 = indices_tensor->GetTensorShape()->GetDims();105 info.value_dim_num_x2 = indices_tensor->GetTensorShape()->GetDims();
@@ -545,10 +133,10 @@ uint32_t BuildScatterElementsInfo(ScatterElementsComputeInfo &info) {
545 }133 }
546 if (i > 0) {134 if (i > 0) {
547 sub_data_fix *= info.value_dim_x1[i];135 sub_data_fix *= info.value_dim_x1[i];
548- info.data_dim_vec.push_back(sub_data_fix);
549 sub_index_fix *= info.value_dim_x2[i];136 sub_index_fix *= info.value_dim_x2[i];
550- info.index_dim_vec.push_back(sub_index_fix);
551 sub_src_fix *= info.value_dim_x3[i];137 sub_src_fix *= info.value_dim_x3[i];
138+ info.data_dim_vec.push_back(sub_data_fix);
139+ info.index_dim_vec.push_back(sub_index_fix);
552 info.src_dim_vec.push_back(sub_src_fix);140 info.src_dim_vec.push_back(sub_src_fix);
553 }141 }
554 }142 }
@@ -559,9 +147,9 @@ uint32_t BuildScatterElementsInfo(ScatterElementsComputeInfo &info) {
559 147 
560template <typename TI>148template <typename TI>
561uint32_t NormalizeIndicesValue(const ScatterElementsComputeInfo &info, TI raw_value, int64_t &indices_value) {149uint32_t NormalizeIndicesValue(const ScatterElementsComputeInfo &info, TI raw_value, int64_t &indices_value) {
562- KERNEL_CHECK_FALSE(raw_value >= info.axis_dim_value * -1 && raw_value < info.axis_dim_value,150+ KERNEL_CHECK_FALSE(raw_value >= info.axis_dim_value * -1 && raw_value < info.axis_dim_value, KERNEL_STATUS_PARAM_INVALID,
563- KERNEL_STATUS_PARAM_INVALID, "Indices value %ld is out of bound %ld",151+ "Indices value %ld is out of bound %ld", static_cast<int64_t>(raw_value),
564- static_cast<int64_t>(raw_value), static_cast<int64_t>(info.axis_dim_value));152+ static_cast<int64_t>(info.axis_dim_value));
565 indices_value = raw_value < 0 ? raw_value + info.axis_dim_value : raw_value;153 indices_value = raw_value < 0 ? raw_value + info.axis_dim_value : raw_value;
566 return KERNEL_STATUS_OK;154 return KERNEL_STATUS_OK;
567}155}
@@ -584,45 +172,37 @@ uint32_t CalcScatterIndices(const ScatterElementsComputeInfo &info, int64_t flat
584 return KERNEL_STATUS_OK;172 return KERNEL_STATUS_OK;
585}173}
586 174 
587-template <typename TI>175+template <typename T, typename TI>
588-uint32_t ResolveScatterIndex(const ScatterElementsComputeInfo &info, const TI *indices_data, int64_t flat_index,176+uint32_t ScatterSameNum(const ScatterElementsComputeInfo &info, const TI *indices_data, const T *updates, T *output) {
589- bool check_src_index, int64_t &index_value, int64_t &src_index) {177+ for (int64_t i = 0; i < info.update_value_num; ++i) {
590- int64_t indices_value = 0;178+ int64_t indices_value = 0;
591- auto ret = NormalizeIndicesValue(info, indices_data[flat_index], indices_value);179+ int64_t index_value = 0;
592- KERNEL_CHECK_FALSE(ret == KERNEL_STATUS_OK, ret, "NormalizeIndicesValue failed");180+ int64_t src_index = 0;
593- CalcScatterIndices(info, flat_index, indices_value, index_value, src_index);181+ auto ret = NormalizeIndicesValue(info, indices_data[i], indices_value);
594- KERNEL_CHECK_FALSE(index_value < info.total_value_num, KERNEL_STATUS_PARAM_INVALID,182+ KERNEL_CHECK_FALSE(ret == KERNEL_STATUS_OK, ret, "NormalizeIndicesValue failed");
595- "Update index %ld greater than %ld which is overflow", index_value, info.total_value_num);183+ CalcScatterIndices(info, i, indices_value, index_value, src_index);
596- if (check_src_index) {184+ KERNEL_CHECK_FALSE(index_value < info.total_value_num, KERNEL_STATUS_PARAM_INVALID,
185+ "Update index %ld greater than %ld which is overflow", index_value, info.total_value_num);
186+ ApplyReduction(updates, output, index_value, i, info.reduction_flag);
187+ }
188+ return KERNEL_STATUS_OK;
189+}
190+ 
191+template <typename T, typename TI>
192+uint32_t ScatterDiffNum(const ScatterElementsComputeInfo &info, const TI *indices_data, const T *updates, T *output) {
193+ for (int64_t i = 0; i < info.update_value_num; ++i) {
194+ int64_t indices_value = 0;
195+ int64_t index_value = 0;
196+ int64_t src_index = 0;
197+ auto ret = NormalizeIndicesValue(info, indices_data[i], indices_value);
198+ KERNEL_CHECK_FALSE(ret == KERNEL_STATUS_OK, ret, "NormalizeIndicesValue failed");
199+ CalcScatterIndices(info, i, indices_value, index_value, src_index);
200+ KERNEL_CHECK_FALSE(index_value < info.total_value_num, KERNEL_STATUS_PARAM_INVALID,
201+ "Update index %ld greater than %ld which is overflow", index_value, info.total_value_num);
597 KERNEL_CHECK_FALSE(src_index < info.update_src_num, KERNEL_STATUS_PARAM_INVALID,202 KERNEL_CHECK_FALSE(src_index < info.update_src_num, KERNEL_STATUS_PARAM_INVALID,
598 "src index %ld greater than src total numbers %ld which is overflow", src_index,203 "src index %ld greater than src total numbers %ld which is overflow", src_index,
599 info.update_src_num);204 info.update_src_num);
600- }205+ ApplyReduction(updates, output, index_value, src_index, info.reduction_flag);
601- return KERNEL_STATUS_OK;
602-}
603- 
604-template <typename T, typename TI>
605-uint32_t ScatterSameNum(const ScatterElementsComputeInfo &info, const TI *indices_data, const T *updates, T *output,
606- std::vector<int64_t> &update_counts, MeanReductionHelper<T> *mean_helper) {
607- for (int64_t i = 0; i < info.update_value_num; ++i) {
608- int64_t index_value = 0;
609- int64_t src_index = 0;
610- auto ret = ResolveScatterIndex(info, indices_data, i, false, index_value, src_index);
611- KERNEL_CHECK_FALSE(ret == KERNEL_STATUS_OK, ret, "ResolveScatterIndex failed");
612- ApplyScatterReduction(info, updates, output, index_value, i, update_counts, mean_helper);
613- }
614- return KERNEL_STATUS_OK;
615-}
616- 
617-template <typename T, typename TI>
618-uint32_t ScatterDiffNum(const ScatterElementsComputeInfo &info, const TI *indices_data, const T *updates, T *output,
619- std::vector<int64_t> &update_counts, MeanReductionHelper<T> *mean_helper) {
620- for (int64_t i = 0; i < info.update_value_num; ++i) {
621- int64_t index_value = 0;
622- int64_t src_index = 0;
623- auto ret = ResolveScatterIndex(info, indices_data, i, true, index_value, src_index);
624- KERNEL_CHECK_FALSE(ret == KERNEL_STATUS_OK, ret, "ResolveScatterIndex failed");
625- ApplyScatterReduction(info, updates, output, index_value, src_index, update_counts, mean_helper);
626 }206 }
627 return KERNEL_STATUS_OK;207 return KERNEL_STATUS_OK;
628}208}
@@ -728,38 +308,15 @@ uint32_t ScatterElementsCpuKernel::DoCompute(const CpuKernelContext &ctx) {
728 KERNEL_LOG_INFO("[%s] input of updates is empty tensor.", ctx.GetOpType().c_str());308 KERNEL_LOG_INFO("[%s] input of updates is empty tensor.", ctx.GetOpType().c_str());
729 return UpdateOutput<T>(ctx, info.total_value_num);309 return UpdateOutput<T>(ctx, info.total_value_num);
730 }310 }
731- 
732 ret = BuildScatterElementsInfo(info);311 ret = BuildScatterElementsInfo(info);
733 KERNEL_CHECK_FALSE(ret == KERNEL_STATUS_OK, ret, "BuildScatterElementsInfo failed");312 KERNEL_CHECK_FALSE(ret == KERNEL_STATUS_OK, ret, "BuildScatterElementsInfo failed");
734 ret = UpdateOutput<T>(ctx, info.total_value_num);313 ret = UpdateOutput<T>(ctx, info.total_value_num);
735 KERNEL_CHECK_FALSE(ret == KERNEL_STATUS_OK, ret, "UpdateOutput failed");314 KERNEL_CHECK_FALSE(ret == KERNEL_STATUS_OK, ret, "UpdateOutput failed");
736- 
737 auto *indices_data = reinterpret_cast<TI *>(ctx.Input(1)->GetData());315 auto *indices_data = reinterpret_cast<TI *>(ctx.Input(1)->GetData());
738 auto *updates = reinterpret_cast<T *>(ctx.Input(kUpdatesInputIndex)->GetData());316 auto *updates = reinterpret_cast<T *>(ctx.Input(kUpdatesInputIndex)->GetData());
739 auto *output = reinterpret_cast<T *>(ctx.Output(0)->GetData());317 auto *output = reinterpret_cast<T *>(ctx.Output(0)->GetData());
740- std::vector<int64_t> update_counts;318+ return info.update_value_num == info.update_src_num ? ScatterSameNum(info, indices_data, updates, output)
741- if (NeedUpdateCounts(info)) {319+ : ScatterDiffNum(info, indices_data, updates, output);
742- update_counts.resize(info.total_value_num, 0);
743- }
744- std::unique_ptr<MeanReductionHelper<T>> mean_helper;
745- if (info.reduction_flag == kReductionMean) {
746- mean_helper.reset(new MeanReductionHelper<T>(info.total_value_num));
747- if (info.include_self) {
748- auto *input_data = reinterpret_cast<T *>(ctx.Input(0)->GetData());
749- for (int64_t i = 0; i < info.total_value_num; ++i) {
750- mean_helper->AddUpdate(i, input_data[i]);
751- }
752- }
753- }
754- 
755- ret = info.update_value_num == info.update_src_num
756- ? ScatterSameNum(info, indices_data, updates, output, update_counts, mean_helper.get())
757- : ScatterDiffNum(info, indices_data, updates, output, update_counts, mean_helper.get());
758- KERNEL_CHECK_FALSE(ret == KERNEL_STATUS_OK, ret, "ScatterElements reduce failed");
759- if (info.reduction_flag == kReductionMean && mean_helper != nullptr) {
760- mean_helper->Finalize(output);
761- }
762- return KERNEL_STATUS_OK;
763}320}
764 321 
765REGISTER_CPU_KERNEL(kScatterElements, ScatterElementsCpuKernel);322REGISTER_CPU_KERNEL(kScatterElements, ScatterElementsCpuKernel);
Mindex/scatter_elements/op_kernel_aicpu/scatter_elements_aicpu_def.cpp+0-5
@@ -25,12 +25,7 @@ public:
25 this->Input("updates").ParamType(REQUIRED).DataType(data_types);25 this->Input("updates").ParamType(REQUIRED).DataType(data_types);
26 this->Output("y").ParamType(REQUIRED).DataType(data_types);26 this->Output("y").ParamType(REQUIRED).DataType(data_types);
27 27 
28- this->Attr("axis").AttrType(OPTIONAL).Int(0);
29- this->Attr("reduction").AttrType(OPTIONAL).String("none");
30- this->Attr("include_self").AttrType(OPTIONAL).Bool(true);
31- 
32 ApplyNnAicpuDefaultCfg(*this);28 ApplyNnAicpuDefaultCfg(*this);
33- this->AICPU().ExtendCfgInfo(OP_INFO_OPS_FLAG.c_str(), OPEN_OPS_FLAG.c_str());
34 }29 }
35};30};
36 31 
Mindex/scatter_elements/tests/ut/op_kernel_aicpu/test_scatter_elements.cpp+0-148
@@ -40,17 +40,6 @@ class TEST_SCATTER_ELEMENTS_UT : public testing::Test {};
40 .Attr("reduction", reduction) \40 .Attr("reduction", reduction) \
41 .Output({"y", data_types[3], shapes[3], datas[3]})41 .Output({"y", data_types[3], shapes[3], datas[3]})
42 42 
43-#define CREATE_NODEDEF_WITH_INCLUDE_SELF(shapes, data_types, datas, axis, reduction, include_self) \
44- auto node_def = CpuKernelUtils::CreateNodeDef(); \
45- NodeDefBuilder(node_def.get(), "ScatterElements", "ScatterElements") \
46- .Input({"data", data_types[0], shapes[0], datas[0]}) \
47- .Input({"indices", data_types[1], shapes[1], datas[1]}) \
48- .Input({"updates", data_types[2], shapes[2], datas[2]}) \
49- .Attr("axis", axis) \
50- .Attr("reduction", reduction) \
51- .Attr("include_self", include_self) \
52- .Output({"y", data_types[3], shapes[3], datas[3]})
53- 
54template <typename T, typename Index>43template <typename T, typename Index>
55void RunScatterElementsKernel(const vector<vector<int64_t>> &shapes, const vector<DataType> &data_types, const T *input_data,44void RunScatterElementsKernel(const vector<vector<int64_t>> &shapes, const vector<DataType> &data_types, const T *input_data,
56 const Index *input_indices, const T *input_updates, T *expect_output, int64_t axis,45 const Index *input_indices, const T *input_updates, T *expect_output, int64_t axis,
@@ -88,44 +77,6 @@ void RunScatterElementsKernel(const vector<vector<int64_t>> &shapes, const vecto
88 EXPECT_TRUE(CompareResult(output.get(), expect_output, output_size));77 EXPECT_TRUE(CompareResult(output.get(), expect_output, output_size));
89}78}
90 79 
91-template <typename T, typename Index>
92-void RunScatterElementsKernelWithIncludeSelf(const vector<vector<int64_t>> &shapes, const vector<DataType> &data_types,
93- const T *input_data, const Index *input_indices, const T *input_updates,
94- T *expect_output, int64_t axis, const string &reduction,
95- bool include_self) {
96- auto calc_size = [](const vector<int64_t> &shape) -> uint64_t {
97- return shape.empty() ? 0 : accumulate(shape.begin(), shape.end(), 1LL, multiplies<int64_t>());
98- };
99- 
100- const uint64_t data_size = calc_size(shapes[0]);
101- const uint64_t indices_size = calc_size(shapes[1]);
102- const uint64_t updates_size = calc_size(shapes[2]);
103- const uint64_t output_size = calc_size(shapes[3]);
104- auto data = make_unique<T[]>(data_size);
105- auto indices = make_unique<Index[]>(indices_size);
106- auto updates = make_unique<T[]>(updates_size);
107- auto output = make_unique<T[]>(output_size);
108- 
109- for (uint64_t i = 0; i < data_size; ++i) {
110- data[i] = input_data[i];
111- }
112- for (uint64_t i = 0; i < indices_size; ++i) {
113- indices[i] = input_indices[i];
114- }
115- for (uint64_t i = 0; i < updates_size; ++i) {
116- updates[i] = input_updates[i];
117- }
118- for (uint64_t i = 0; i < output_size; ++i) {
119- output[i] = T();
120- }
121- 
122- vector<void *> datas = {static_cast<void *>(data.get()), static_cast<void *>(indices.get()),
123- static_cast<void *>(updates.get()), static_cast<void *>(output.get())};
124- CREATE_NODEDEF_WITH_INCLUDE_SELF(shapes, data_types, datas, axis, reduction, include_self);
125- RUN_KERNEL(node_def, HOST, KERNEL_STATUS_OK);
126- EXPECT_TRUE(CompareResult(output.get(), expect_output, output_size));
127-}
128- 
129TEST_F(TEST_SCATTER_ELEMENTS_UT, DATA_TYPE_DT_DOUBLE_NONE_SUCC) {80TEST_F(TEST_SCATTER_ELEMENTS_UT, DATA_TYPE_DT_DOUBLE_NONE_SUCC) {
130 vector<DataType> data_types = {DT_DOUBLE, DT_INT64, DT_DOUBLE, DT_DOUBLE};81 vector<DataType> data_types = {DT_DOUBLE, DT_INT64, DT_DOUBLE, DT_DOUBLE};
131 vector<vector<int64_t>> shapes = {{1, 5}, {1, 2}, {1, 2}, {1, 5}};82 vector<vector<int64_t>> shapes = {{1, 5}, {1, 2}, {1, 2}, {1, 5}};
@@ -168,102 +119,3 @@ TEST_F(TEST_SCATTER_ELEMENTS_UT, FAILED_OUT_OF_BOUND_INDEX) {
168 CREATE_NODEDEF(shapes, data_types, datas, 1, "none");119 CREATE_NODEDEF(shapes, data_types, datas, 1, "none");
169 RUN_KERNEL(node_def, HOST, KERNEL_STATUS_PARAM_INVALID);120 RUN_KERNEL(node_def, HOST, KERNEL_STATUS_PARAM_INVALID);
170}121}
171- 
172-TEST_F(TEST_SCATTER_ELEMENTS_UT, DATA_TYPE_DT_FLOAT_ADD_INCLUDE_SELF_COMPARE_SUCC) {
173- vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT};
174- vector<vector<int64_t>> shapes = {{1, 5}, {1, 3}, {1, 3}, {1, 5}};
175- float input_data[5] = {1, 2, 3, 4, 5};
176- int32_t input_indices[3] = {0, 0, 4};
177- float input_updates[3] = {10, 20, 30};
178- float expect_output_with_self[5] = {31, 2, 3, 4, 35};
179- float expect_output_without_self[5] = {30, 2, 3, 4, 30};
180- 
181- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
182- expect_output_with_self, 1, "add", true);
183- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
184- expect_output_without_self, 1, "add", false);
185-}
186- 
187-TEST_F(TEST_SCATTER_ELEMENTS_UT, DATA_TYPE_DT_INT32_MAX_INCLUDE_SELF_COMPARE_SUCC) {
188- vector<DataType> data_types = {DT_INT32, DT_INT32, DT_INT32, DT_INT32};
189- vector<vector<int64_t>> shapes = {{1, 3}, {1, 2}, {1, 2}, {1, 3}};
190- int32_t input_data[3] = {5, 1, 8};
191- int32_t input_indices[2] = {0, 2};
192- int32_t input_updates[2] = {3, 10};
193- int32_t expect_output_with_self[3] = {5, 1, 10};
194- int32_t expect_output_without_self[3] = {3, 1, 10};
195- 
196- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
197- expect_output_with_self, 1, "max", true);
198- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
199- expect_output_without_self, 1, "max", false);
200-}
201- 
202-TEST_F(TEST_SCATTER_ELEMENTS_UT, DATA_TYPE_DT_INT32_MIN_INCLUDE_SELF_COMPARE_SUCC) {
203- vector<DataType> data_types = {DT_INT32, DT_INT32, DT_INT32, DT_INT32};
204- vector<vector<int64_t>> shapes = {{1, 3}, {1, 2}, {1, 2}, {1, 3}};
205- int32_t input_data[3] = {5, 1, 8};
206- int32_t input_indices[2] = {0, 2};
207- int32_t input_updates[2] = {10, 3};
208- int32_t expect_output_with_self[3] = {5, 1, 3};
209- int32_t expect_output_without_self[3] = {10, 1, 3};
210- 
211- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
212- expect_output_with_self, 1, "min", true);
213- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
214- expect_output_without_self, 1, "min", false);
215-}
216- 
217-TEST_F(TEST_SCATTER_ELEMENTS_UT, DATA_TYPE_DT_DOUBLE_MEAN_INCLUDE_SELF_COMPARE_SUCC) {
218- vector<DataType> data_types = {DT_DOUBLE, DT_INT64, DT_DOUBLE, DT_DOUBLE};
219- vector<vector<int64_t>> shapes = {{1, 3}, {1, 3}, {1, 3}, {1, 3}};
220- double input_data[3] = {2, 4, 6};
221- int64_t input_indices[3] = {0, 0, 2};
222- double input_updates[3] = {4, 6, 8};
223- double expect_output_with_self[3] = {4, 4, 7};
224- double expect_output_without_self[3] = {5, 4, 8};
225- 
226- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
227- expect_output_with_self, 1, "mean", true);
228- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
229- expect_output_without_self, 1, "mean", false);
230-}
231- 
232-TEST_F(TEST_SCATTER_ELEMENTS_UT, DATA_TYPE_DT_INT16_MEAN_INCLUDE_SELF_COMPARE_SUCC) {
233- vector<DataType> data_types = {DT_INT16, DT_INT64, DT_INT16, DT_INT16};
234- vector<vector<int64_t>> shapes = {{1}, {1}, {1}, {1}};
235- int16_t input_data[1] = {-5};
236- int64_t input_indices[1] = {0};
237- int16_t input_updates[1] = {2};
238- int16_t expect_output[1] = {-2};
239- 
240- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
241- expect_output, 0, "mean", true);
242-}
243- 
244-TEST_F(TEST_SCATTER_ELEMENTS_UT, DATA_TYPE_DT_INT64_ADD_WITHOUT_SELF_COMPARE_SUCC) {
245- vector<DataType> data_types = {DT_INT64, DT_INT64, DT_INT64, DT_INT64};
246- vector<vector<int64_t>> shapes = {{1}, {1}, {1}, {1}};
247- int64_t input_data[1] = {5};
248- int64_t input_indices[1] = {0};
249- int64_t input_updates[1] = {2};
250- int64_t expect_output[1] = {2};
251- 
252- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
253- expect_output, 0, "add", false);
254-}
255- 
256-TEST_F(TEST_SCATTER_ELEMENTS_UT, DATA_TYPE_DT_FLOAT_MUL_INCLUDE_SELF_COMPARE_SUCC) {
257- vector<DataType> data_types = {DT_FLOAT, DT_INT32, DT_FLOAT, DT_FLOAT};
258- vector<vector<int64_t>> shapes = {{1, 5}, {1, 3}, {1, 3}, {1, 5}};
259- float input_data[5] = {2, 3, 4, 5, 6};
260- int32_t input_indices[3] = {0, 0, 4};
261- float input_updates[3] = {3, 4, 7};
262- float expect_output_with_self[5] = {24, 3, 4, 5, 42};
263- float expect_output_without_self[5] = {12, 3, 4, 5, 7};
264- 
265- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
266- expect_output_with_self, 1, "mul", true);
267- RunScatterElementsKernelWithIncludeSelf(shapes, data_types, input_data, input_indices, input_updates,
268- expect_output_without_self, 1, "mul", false);
269-}
Mindex/scatter_elements_v2/tests/st/aclnnScatterReduce/atk_aclnnScatterReduce.json+1-1
此文件变更行数或变更字符数较多,你可以直接 查看源码