已合并
add histogramv2 ut #3696
xieshengwei1024创建于 7月1日
add histogramv2 ut #3696
已合并
xieshengwei1024创建于 7月1日
7 个文件变更+987-264
@@ -103,7 +103,7 @@ HPTG5@ops-math:
103 src:103 src:
104 release:104 release:
105 style:105 style:
106- - ops/ops-math/histogram_v2/op_host106+ - ops/ops-math/math/histogram_v2/op_host
107 opensource_style: null107 opensource_style: null
108 kernel_style: null108 kernel_style: null
109 unrelease:109 unrelease:
@@ -10,6 +10,7 @@
10 10 
11#include <array>11#include <array>
12#include <vector>12#include <vector>
13+#include <limits>
13#include "gtest/gtest.h"14#include "gtest/gtest.h"
14 15 
15#include "../../../op_host/op_api/aclnn_histc.h"16#include "../../../op_host/op_api/aclnn_histc.h"
@@ -17,232 +18,578 @@
17#include "op_api_ut_common/op_api_ut.h"18#include "op_api_ut_common/op_api_ut.h"
18#include "op_api_ut_common/scalar_desc.h"19#include "op_api_ut_common/scalar_desc.h"
19#include "op_api_ut_common/tensor_desc.h"20#include "op_api_ut_common/tensor_desc.h"
20- 21+#include "opdev/platform.h"
21 22 
22using namespace std;23using namespace std;
23 24 
24class l2_histc_test : public testing::Test {25class l2_histc_test : public testing::Test {
25- protected:26+protected:
26- static void SetUpTestCase() { cout << "histc_test SetUp" << endl; }27+ static void SetUpTestCase() { cout << "histc_test SetUp" << endl; }
27 28 
28- static void TearDownTestCase() { cout << "histc_test TearDown" << endl; }29+ static void TearDownTestCase() { cout << "histc_test TearDown" << endl; }
30+ 
31+ // Restore the default platform after every test (some tests switch platform to
32+ // exercise the AiCore / AiCPU / RegBase branches in histogram.cpp).
33+ void TearDown() override { op::SetPlatformSocVersion(op::SocVersion::ASCEND910B); }
29};34};
30 35 
31-TEST_F(l2_histc_test, case_000_workspace) {36+TEST_F(l2_histc_test, case_000_workspace)
32- auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);37+{
33- auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);38+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
34- int64_t bins = 3;39+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
35- auto minScalar = ScalarDesc(-9.0f);40+ int64_t bins = 3;
36- auto maxScalar = ScalarDesc(9.0f);41+ auto minScalar = ScalarDesc(-9.0f);
42+ auto maxScalar = ScalarDesc(9.0f);
37 43 
38- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));44+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
39 45 
40- uint64_t workspaceSize = 0;46+ uint64_t workspaceSize = 0;
41- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);47+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
42- EXPECT_EQ(aclRet, ACLNN_SUCCESS);48+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
43}49}
44 50 
45-TEST_F(l2_histc_test, case_001_float32_normal) {51+TEST_F(l2_histc_test, case_001_float32_normal)
46- auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);52+{
47- auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);53+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
48- int64_t bins = 3;54+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
49- auto minScalar = ScalarDesc(-9.0f);55+ int64_t bins = 3;
50- auto maxScalar = ScalarDesc(9.0f);56+ auto minScalar = ScalarDesc(-9.0f);
57+ auto maxScalar = ScalarDesc(9.0f);
51 58 
52- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));59+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
53 60 
54- uint64_t workspaceSize = 0;61+ uint64_t workspaceSize = 0;
55- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);62+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
56- EXPECT_EQ(aclRet, ACLNN_SUCCESS);63+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
57}64}
58 65 
59-TEST_F(l2_histc_test, case_002_float16_normal) {66+TEST_F(l2_histc_test, case_002_float16_normal)
60- auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT16, ACL_FORMAT_ND).ValueRange(-10, 10);67+{
61- auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);68+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT16, ACL_FORMAT_ND).ValueRange(-10, 10);
62- int64_t bins = 3;69+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
63- auto minScalar = ScalarDesc(-9.0f);70+ int64_t bins = 3;
64- auto maxScalar = ScalarDesc(9.0f);71+ auto minScalar = ScalarDesc(-9.0f);
72+ auto maxScalar = ScalarDesc(9.0f);
65 73 
66- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));74+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
67 75 
68- uint64_t workspaceSize = 0;76+ uint64_t workspaceSize = 0;
69- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);77+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
70- EXPECT_EQ(aclRet, ACLNN_SUCCESS);78+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
71}79}
72 80 
73-TEST_F(l2_histc_test, case_003_int32_normal) {81+TEST_F(l2_histc_test, case_003_int32_normal)
74- auto selfTensor = TensorDesc({3, 3}, ACL_INT32, ACL_FORMAT_ND).ValueRange(-10, 10);82+{
75- auto outTensor = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND);83+ auto selfTensor = TensorDesc({3, 3}, ACL_INT32, ACL_FORMAT_ND).ValueRange(-10, 10);
76- int64_t bins = 3;84+ auto outTensor = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND);
77- auto minScalar = ScalarDesc(-9.0f);85+ int64_t bins = 3;
78- auto maxScalar = ScalarDesc(9.0f);86+ auto minScalar = ScalarDesc(-9.0f);
87+ auto maxScalar = ScalarDesc(9.0f);
79 88 
80- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));89+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
81 90 
82- uint64_t workspaceSize = 0;91+ uint64_t workspaceSize = 0;
83- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);92+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
84- EXPECT_EQ(aclRet, ACLNN_SUCCESS);93+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
85}94}
86 95 
87-TEST_F(l2_histc_test, case_008_1_dim_input_tensor) {96+TEST_F(l2_histc_test, case_008_1_dim_input_tensor)
88- auto selfTensor = TensorDesc({8}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);97+{
89- auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);98+ auto selfTensor = TensorDesc({8}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
90- int64_t bins = 3;99+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
91- auto minScalar = ScalarDesc(-9.0f);100+ int64_t bins = 3;
92- auto maxScalar = ScalarDesc(9.0f);101+ auto minScalar = ScalarDesc(-9.0f);
102+ auto maxScalar = ScalarDesc(9.0f);
93 103 
94- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));104+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
95 105 
96- uint64_t workspaceSize = 0;106+ uint64_t workspaceSize = 0;
97- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);107+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
98- EXPECT_EQ(aclRet, ACLNN_SUCCESS);108+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
99}109}
100 110 
101-TEST_F(l2_histc_test, case_009_3_dim_input_tensor) {111+TEST_F(l2_histc_test, case_009_3_dim_input_tensor)
102- auto selfTensor = TensorDesc({1, 2, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);112+{
103- auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);113+ auto selfTensor = TensorDesc({1, 2, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
104- int64_t bins = 3;114+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
105- auto minScalar = ScalarDesc(-9.0f);115+ int64_t bins = 3;
106- auto maxScalar = ScalarDesc(9.0f);116+ auto minScalar = ScalarDesc(-9.0f);
117+ auto maxScalar = ScalarDesc(9.0f);
107 118 
108- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));119+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
109 120 
110- uint64_t workspaceSize = 0;121+ uint64_t workspaceSize = 0;
111- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);122+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
112- EXPECT_EQ(aclRet, ACLNN_SUCCESS);123+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
113}124}
114 125 
115-TEST_F(l2_histc_test, case_010_5_dim_input_tensor) {126+TEST_F(l2_histc_test, case_010_5_dim_input_tensor)
116- auto selfTensor = TensorDesc({1, 2, 3, 4, 5}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);127+{
117- auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);128+ auto selfTensor = TensorDesc({1, 2, 3, 4, 5}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
118- int64_t bins = 3;129+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
119- auto minScalar = ScalarDesc(-9.0f);130+ int64_t bins = 3;
120- auto maxScalar = ScalarDesc(9.0f);131+ auto minScalar = ScalarDesc(-9.0f);
132+ auto maxScalar = ScalarDesc(9.0f);
121 133 
122- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));134+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
123 135 
124- uint64_t workspaceSize = 0;136+ uint64_t workspaceSize = 0;
125- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);137+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
126- EXPECT_EQ(aclRet, ACLNN_SUCCESS);138+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
127}139}
128 140 
129-TEST_F(l2_histc_test, case_011_8_dim_input_tensor) {141+TEST_F(l2_histc_test, case_011_8_dim_input_tensor)
130- auto selfTensor = TensorDesc({1, 2, 3, 4, 5, 6, 7, 8}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);142+{
131- auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);143+ auto selfTensor = TensorDesc({1, 2, 3, 4, 5, 6, 7, 8}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
132- int64_t bins = 3;144+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
133- auto minScalar = ScalarDesc(-9.0f);145+ int64_t bins = 3;
134- auto maxScalar = ScalarDesc(9.0f);146+ auto minScalar = ScalarDesc(-9.0f);
147+ auto maxScalar = ScalarDesc(9.0f);
135 148 
136- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));149+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
137 150 
138- uint64_t workspaceSize = 0;151+ uint64_t workspaceSize = 0;
139- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);152+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
140- EXPECT_EQ(aclRet, ACLNN_SUCCESS);153+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
141}154}
142 155 
143-TEST_F(l2_histc_test, case_012_bins_coverage) {156+TEST_F(l2_histc_test, case_012_bins_coverage)
144- auto selfTensor = TensorDesc({3, 4}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);157+{
145- auto outTensor = TensorDesc({10}, ACL_FLOAT, ACL_FORMAT_ND);158+ auto selfTensor = TensorDesc({3, 4}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
146- int64_t bins = 10;159+ auto outTensor = TensorDesc({10}, ACL_FLOAT, ACL_FORMAT_ND);
147- auto minScalar = ScalarDesc(-10.0f);160+ int64_t bins = 10;
148- auto maxScalar = ScalarDesc(10.0f);161+ auto minScalar = ScalarDesc(-10.0f);
162+ auto maxScalar = ScalarDesc(10.0f);
149 163 
150- auto ut1 = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));164+ auto ut1 = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
151- uint64_t workspaceSize = 0;165+ uint64_t workspaceSize = 0;
152- aclnnStatus aclRet = ut1.TestGetWorkspaceSize(&workspaceSize);166+ aclnnStatus aclRet = ut1.TestGetWorkspaceSize(&workspaceSize);
153- EXPECT_EQ(aclRet, ACLNN_SUCCESS);167+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
154 168 
155- outTensor = TensorDesc({12}, ACL_FLOAT, ACL_FORMAT_ND);169+ outTensor = TensorDesc({12}, ACL_FLOAT, ACL_FORMAT_ND);
156- bins = 12;170+ bins = 12;
157- auto ut2 = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));171+ auto ut2 = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
158- workspaceSize = 0;172+ workspaceSize = 0;
159- aclRet = ut2.TestGetWorkspaceSize(&workspaceSize);173+ aclRet = ut2.TestGetWorkspaceSize(&workspaceSize);
160- EXPECT_EQ(aclRet, ACLNN_SUCCESS);174+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
161 175 
162- outTensor = TensorDesc({14}, ACL_FLOAT, ACL_FORMAT_ND);176+ outTensor = TensorDesc({14}, ACL_FLOAT, ACL_FORMAT_ND);
163- bins = 14;177+ bins = 14;
164- auto ut3 = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));178+ auto ut3 = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
165- workspaceSize = 0;179+ workspaceSize = 0;
166- aclRet = ut3.TestGetWorkspaceSize(&workspaceSize);180+ aclRet = ut3.TestGetWorkspaceSize(&workspaceSize);
167- EXPECT_EQ(aclRet, ACLNN_SUCCESS);181+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
168}182}
169 183 
170-TEST_F(l2_histc_test, case_014_NHWC) {184+TEST_F(l2_histc_test, case_014_NHWC)
171- auto selfTensor = TensorDesc({2, 3, 4, 5}, ACL_FLOAT, ACL_FORMAT_NHWC).ValueRange(-10, 10);185+{
172- auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_NHWC);186+ auto selfTensor = TensorDesc({2, 3, 4, 5}, ACL_FLOAT, ACL_FORMAT_NHWC).ValueRange(-10, 10);
173- int64_t bins = 3;187+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_NHWC);
174- auto minScalar = ScalarDesc(-10.0f);188+ int64_t bins = 3;
175- auto maxScalar = ScalarDesc(10.0f);189+ auto minScalar = ScalarDesc(-10.0f);
190+ auto maxScalar = ScalarDesc(10.0f);
176 191 
177- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));192+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
178- uint64_t workspaceSize = 0;193+ uint64_t workspaceSize = 0;
179- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);194+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
180- EXPECT_EQ(aclRet, ACLNN_SUCCESS);195+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
181}196}
182 197 
183-TEST_F(l2_histc_test, case_015_NCHW) {198+TEST_F(l2_histc_test, case_015_NCHW)
184- auto selfTensor = TensorDesc({2, 3, 4, 5}, ACL_FLOAT, ACL_FORMAT_NCHW).ValueRange(-10, 10);199+{
185- auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_NCHW);200+ auto selfTensor = TensorDesc({2, 3, 4, 5}, ACL_FLOAT, ACL_FORMAT_NCHW).ValueRange(-10, 10);
186- int64_t bins = 3;201+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_NCHW);
187- auto minScalar = ScalarDesc(-10.0f);202+ int64_t bins = 3;
188- auto maxScalar = ScalarDesc(10.0f);203+ auto minScalar = ScalarDesc(-10.0f);
204+ auto maxScalar = ScalarDesc(10.0f);
189 205 
190- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));206+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
191- uint64_t workspaceSize = 0;207+ uint64_t workspaceSize = 0;
192- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);208+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
193- EXPECT_EQ(aclRet, ACLNN_SUCCESS);209+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
194}210}
195 211 
196-TEST_F(l2_histc_test, case_016_HWCN) {212+TEST_F(l2_histc_test, case_016_HWCN)
197- auto selfTensor = TensorDesc({2, 3, 4, 5}, ACL_FLOAT, ACL_FORMAT_HWCN).ValueRange(-10, 10);213+{
198- auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_HWCN);214+ auto selfTensor = TensorDesc({2, 3, 4, 5}, ACL_FLOAT, ACL_FORMAT_HWCN).ValueRange(-10, 10);
199- int64_t bins = 3;215+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_HWCN);
200- auto minScalar = ScalarDesc(-10.0f);216+ int64_t bins = 3;
201- auto maxScalar = ScalarDesc(10.0f);217+ auto minScalar = ScalarDesc(-10.0f);
218+ auto maxScalar = ScalarDesc(10.0f);
202 219 
203- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));220+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
204- uint64_t workspaceSize = 0;221+ uint64_t workspaceSize = 0;
205- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);222+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
206- EXPECT_EQ(aclRet, ACLNN_SUCCESS);223+ EXPECT_EQ(aclRet, ACLNN_SUCCESS);
207}224}
208 225 
209-TEST_F(l2_histc_test, case_018_empty_tensor) {226+TEST_F(l2_histc_test, case_018_empty_tensor)
210- auto selfTensor = TensorDesc({2, 0}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);227+{
211- auto outTensor = TensorDesc({2}, ACL_FLOAT, ACL_FORMAT_ND);228+ auto selfTensor = TensorDesc({2, 0}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
212- int64_t bins = 2;229+ auto outTensor = TensorDesc({2}, ACL_FLOAT, ACL_FORMAT_ND);
213- auto minScalar = ScalarDesc(-10.0f);230+ int64_t bins = 2;
214- auto maxScalar = ScalarDesc(10.0f);231+ auto minScalar = ScalarDesc(-10.0f);
232+ auto maxScalar = ScalarDesc(10.0f);
215 233 
216- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));234+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
217- uint64_t workspaceSize = 0;235+ uint64_t workspaceSize = 0;
218- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);236+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
219- EXPECT_EQ(aclRet, ACL_SUCCESS);237+ EXPECT_EQ(aclRet, ACL_SUCCESS);
220}238}
221 239 
222-TEST_F(l2_histc_test, case_019_float32_min_greater_max) {240+TEST_F(l2_histc_test, case_019_float32_min_greater_max)
223- auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);241+{
224- auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);242+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
225- int64_t bins = 3;243+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
226- auto minScalar = ScalarDesc(9.0f);244+ int64_t bins = 3;
227- auto maxScalar = ScalarDesc(-9.0f);245+ auto minScalar = ScalarDesc(9.0f);
246+ auto maxScalar = ScalarDesc(-9.0f);
228 247 
229- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));248+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
230 249 
231- uint64_t workspaceSize = 0;250+ uint64_t workspaceSize = 0;
232- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);251+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
233- EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID);252+ EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID);
234}253}
235 254 
236-TEST_F(l2_histc_test, case_020_min_greater_max) {255+TEST_F(l2_histc_test, case_020_min_greater_max)
237- auto selfTensor = TensorDesc({3, 3}, ACL_INT32, ACL_FORMAT_ND).ValueRange(-10, 10);256+{
238- auto outTensor = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND);257+ auto selfTensor = TensorDesc({3, 3}, ACL_INT32, ACL_FORMAT_ND).ValueRange(-10, 10);
239- int64_t bins = 3;258+ auto outTensor = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND);
240- auto minScalar = ScalarDesc(9.0f);259+ int64_t bins = 3;
241- auto maxScalar = ScalarDesc(-9.0f);260+ auto minScalar = ScalarDesc(9.0f);
261+ auto maxScalar = ScalarDesc(-9.0f);
242 262 
243- auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));263+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
244 264 
245- uint64_t workspaceSize = 0;265+ uint64_t workspaceSize = 0;
246- aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);266+ aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspaceSize);
247- EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID);267+ EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID);
268+}
269+ 
270+// ---------------------- nullptr checks (CheckNotNull) ----------------------
271+TEST_F(l2_histc_test, case_021_null_self)
272+{
273+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
274+ int64_t bins = 3;
275+ auto minScalar = ScalarDesc(-9.0f);
276+ auto maxScalar = ScalarDesc(9.0f);
277+ auto ut = OP_API_UT(aclnnHistc, INPUT((aclTensor*)nullptr, bins, minScalar, maxScalar), OUTPUT(outTensor));
278+ uint64_t workspaceSize = 0;
279+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_NULLPTR);
280+}
281+ 
282+TEST_F(l2_histc_test, case_022_null_out)
283+{
284+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
285+ int64_t bins = 3;
286+ auto minScalar = ScalarDesc(-9.0f);
287+ auto maxScalar = ScalarDesc(9.0f);
288+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT((aclTensor*)nullptr));
289+ uint64_t workspaceSize = 0;
290+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_NULLPTR);
291+}
292+ 
293+TEST_F(l2_histc_test, case_023_null_min)
294+{
295+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
296+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
297+ int64_t bins = 3;
298+ auto maxScalar = ScalarDesc(9.0f);
299+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, (aclScalar*)nullptr, maxScalar), OUTPUT(outTensor));
300+ uint64_t workspaceSize = 0;
301+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_NULLPTR);
302+}
303+ 
304+TEST_F(l2_histc_test, case_024_null_max)
305+{
306+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
307+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
308+ int64_t bins = 3;
309+ auto minScalar = ScalarDesc(-9.0f);
310+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, (aclScalar*)nullptr), OUTPUT(outTensor));
311+ uint64_t workspaceSize = 0;
312+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_NULLPTR);
313+}
314+ 
315+// ---------------------- dtype validity (CheckDtypeValid) ----------------------
316+TEST_F(l2_histc_test, case_025_invalid_self_dtype)
317+{
318+ auto selfTensor = TensorDesc({3, 3}, ACL_DOUBLE, ACL_FORMAT_ND).ValueRange(-10, 10);
319+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
320+ int64_t bins = 3;
321+ auto minScalar = ScalarDesc(-9.0f);
322+ auto maxScalar = ScalarDesc(9.0f);
323+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
324+ uint64_t workspaceSize = 0;
325+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_INVALID);
326+}
327+ 
328+TEST_F(l2_histc_test, case_026_invalid_out_dtype)
329+{
330+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
331+ auto outTensor = TensorDesc({3}, ACL_DOUBLE, ACL_FORMAT_ND);
332+ int64_t bins = 3;
333+ auto minScalar = ScalarDesc(-9.0f);
334+ auto maxScalar = ScalarDesc(9.0f);
335+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
336+ uint64_t workspaceSize = 0;
337+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_INVALID);
338+}
339+ 
340+// ---------------------- bins / shape checks ----------------------
341+TEST_F(l2_histc_test, case_027_bins_non_positive)
342+{
343+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
344+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
345+ int64_t bins = 0;
346+ auto minScalar = ScalarDesc(-9.0f);
347+ auto maxScalar = ScalarDesc(9.0f);
348+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
349+ uint64_t workspaceSize = 0;
350+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_INVALID);
351+}
352+ 
353+TEST_F(l2_histc_test, case_028_out_wrong_dim)
354+{
355+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
356+ auto outTensor = TensorDesc({3, 1}, ACL_FLOAT, ACL_FORMAT_ND);
357+ int64_t bins = 3;
358+ auto minScalar = ScalarDesc(-9.0f);
359+ auto maxScalar = ScalarDesc(9.0f);
360+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
361+ uint64_t workspaceSize = 0;
362+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_INVALID);
363+}
364+ 
365+TEST_F(l2_histc_test, case_029_out_size_ne_bins)
366+{
367+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
368+ auto outTensor = TensorDesc({5}, ACL_FLOAT, ACL_FORMAT_ND);
369+ int64_t bins = 3;
370+ auto minScalar = ScalarDesc(-9.0f);
371+ auto maxScalar = ScalarDesc(9.0f);
372+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
373+ uint64_t workspaceSize = 0;
374+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_INVALID);
375+}
376+ 
377+TEST_F(l2_histc_test, case_030_self_exceed_max_dim)
378+{
379+ auto selfTensor = TensorDesc({1, 1, 1, 1, 1, 1, 1, 1, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
380+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
381+ int64_t bins = 3;
382+ auto minScalar = ScalarDesc(-9.0f);
383+ auto maxScalar = ScalarDesc(9.0f);
384+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
385+ uint64_t workspaceSize = 0;
386+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_INVALID);
387+}
388+ 
389+// ---------------------- min/max inf & nan (CheckMinMaxIsInfNan) ----------------------
390+TEST_F(l2_histc_test, case_031_min_pos_inf_only)
391+{
392+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
393+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
394+ int64_t bins = 3;
395+ auto minScalar = ScalarDesc(std::numeric_limits<float>::infinity());
396+ auto maxScalar = ScalarDesc(9.0f);
397+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
398+ uint64_t workspaceSize = 0;
399+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_INVALID);
400+}
401+ 
402+TEST_F(l2_histc_test, case_032_max_nan)
403+{
404+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
405+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
406+ int64_t bins = 3;
407+ auto minScalar = ScalarDesc(-9.0f);
408+ auto maxScalar = ScalarDesc(std::numeric_limits<float>::quiet_NaN());
409+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
410+ uint64_t workspaceSize = 0;
411+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_ERR_PARAM_INVALID);
412+}
413+ 
414+TEST_F(l2_histc_test, case_033_min_max_both_pos_inf)
415+{
416+ // min == max == +inf is a valid equal range (CheckMinMaxInfEqual) and triggers min/max recompute.
417+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
418+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
419+ int64_t bins = 3;
420+ auto minScalar = ScalarDesc(std::numeric_limits<float>::infinity());
421+ auto maxScalar = ScalarDesc(std::numeric_limits<float>::infinity());
422+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
423+ uint64_t workspaceSize = 0;
424+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
425+}
426+ 
427+TEST_F(l2_histc_test, case_034_min_max_both_neg_inf)
428+{
429+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
430+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
431+ int64_t bins = 3;
432+ auto minScalar = ScalarDesc(-std::numeric_limits<float>::infinity());
433+ auto maxScalar = ScalarDesc(-std::numeric_limits<float>::infinity());
434+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
435+ uint64_t workspaceSize = 0;
436+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
437+}
438+ 
439+// ---------------------- min == max recompute (NeedComputeMinMax / AllMinMax) ----------------------
440+TEST_F(l2_histc_test, case_035_float_min_eq_max)
441+{
442+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
443+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
444+ int64_t bins = 3;
445+ auto minScalar = ScalarDesc(0.0f);
446+ auto maxScalar = ScalarDesc(0.0f);
447+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
448+ uint64_t workspaceSize = 0;
449+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
450+}
451+ 
452+TEST_F(l2_histc_test, case_036_int_min_eq_max)
453+{
454+ auto selfTensor = TensorDesc({3, 3}, ACL_INT32, ACL_FORMAT_ND).ValueRange(-10, 10);
455+ auto outTensor = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND);
456+ int64_t bins = 3;
457+ auto minScalar = ScalarDesc(0.0f);
458+ auto maxScalar = ScalarDesc(0.0f);
459+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
460+ uint64_t workspaceSize = 0;
461+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
462+}
463+ 
464+TEST_F(l2_histc_test, case_037_scalar_self_min_eq_max)
465+{
466+ // 0-dim self exercises the AllMinMax dimNum == 0 branch.
467+ auto selfTensor = TensorDesc({}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-1, 1);
468+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
469+ int64_t bins = 3;
470+ auto minScalar = ScalarDesc(0.0f);
471+ auto maxScalar = ScalarDesc(0.0f);
472+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
473+ uint64_t workspaceSize = 0;
474+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
475+}
476+ 
477+// ---------------------- remaining integer dtypes ----------------------
478+TEST_F(l2_histc_test, case_038_int8_normal)
479+{
480+ auto selfTensor = TensorDesc({3, 3}, ACL_INT8, ACL_FORMAT_ND).ValueRange(-10, 10);
481+ auto outTensor = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND);
482+ int64_t bins = 3;
483+ auto minScalar = ScalarDesc(-9.0f);
484+ auto maxScalar = ScalarDesc(9.0f);
485+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
486+ uint64_t workspaceSize = 0;
487+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
488+}
489+ 
490+TEST_F(l2_histc_test, case_039_uint8_normal)
491+{
492+ auto selfTensor = TensorDesc({3, 3}, ACL_UINT8, ACL_FORMAT_ND).ValueRange(0, 10);
493+ auto outTensor = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND);
494+ int64_t bins = 3;
495+ auto minScalar = ScalarDesc(0.0f);
496+ auto maxScalar = ScalarDesc(9.0f);
497+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
498+ uint64_t workspaceSize = 0;
499+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
500+}
501+ 
502+TEST_F(l2_histc_test, case_040_int16_normal)
503+{
504+ auto selfTensor = TensorDesc({3, 3}, ACL_INT16, ACL_FORMAT_ND).ValueRange(-10, 10);
505+ auto outTensor = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND);
506+ int64_t bins = 3;
507+ auto minScalar = ScalarDesc(-9.0f);
508+ auto maxScalar = ScalarDesc(9.0f);
509+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
510+ uint64_t workspaceSize = 0;
511+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
512+}
513+ 
514+TEST_F(l2_histc_test, case_041_int64_normal)
515+{
516+ auto selfTensor = TensorDesc({3, 3}, ACL_INT64, ACL_FORMAT_ND).ValueRange(-10, 10);
517+ auto outTensor = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND);
518+ int64_t bins = 3;
519+ auto minScalar = ScalarDesc(-9.0f);
520+ auto maxScalar = ScalarDesc(9.0f);
521+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
522+ uint64_t workspaceSize = 0;
523+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
524+}
525+ 
526+// ---------------------- platform-specific dispatch (histogram.cpp) ----------------------
527+// RegBase (ascend950) with fp32 output exercises the AiCore RegBase desDtype branch.
528+TEST_F(l2_histc_test, case_042_regbase_out_fp32)
529+{
530+ op::SetPlatformSocVersion(op::SocVersion::ASCEND950);
531+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT16, ACL_FORMAT_ND).ValueRange(-10, 10);
532+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
533+ int64_t bins = 3;
534+ auto minScalar = ScalarDesc(-9.0f);
535+ auto maxScalar = ScalarDesc(9.0f);
536+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
537+ uint64_t workspaceSize = 0;
538+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
539+}
540+ 
541+// RegBase with min == max exercises the NeedComputeMinMax RegBase recompute path.
542+TEST_F(l2_histc_test, case_043_regbase_min_eq_max)
543+{
544+ op::SetPlatformSocVersion(op::SocVersion::ASCEND950);
545+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
546+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
547+ int64_t bins = 3;
548+ auto minScalar = ScalarDesc(0.0f);
549+ auto maxScalar = ScalarDesc(0.0f);
550+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
551+ uint64_t workspaceSize = 0;
552+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
553+}
554+ 
555+// A non-AiCore-supported arch (ascend910 / DAV_1001) routes to the AiCPU path.
556+TEST_F(l2_histc_test, case_044_aicpu_path)
557+{
558+ op::SetPlatformSocVersion(op::SocVersion::ASCEND910);
559+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
560+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
561+ int64_t bins = 3;
562+ auto minScalar = ScalarDesc(-9.0f);
563+ auto maxScalar = ScalarDesc(9.0f);
564+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
565+ uint64_t workspaceSize = 0;
566+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
567+}
568+ 
569+// AiCPU path with fp16 input exercises the desDtype fp16->fp32 promotion branch.
570+TEST_F(l2_histc_test, case_045_aicpu_fp16)
571+{
572+ op::SetPlatformSocVersion(op::SocVersion::ASCEND910);
573+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT16, ACL_FORMAT_ND).ValueRange(-10, 10);
574+ auto outTensor = TensorDesc({3}, ACL_FLOAT, ACL_FORMAT_ND);
575+ int64_t bins = 3;
576+ auto minScalar = ScalarDesc(-9.0f);
577+ auto maxScalar = ScalarDesc(9.0f);
578+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
579+ uint64_t workspaceSize = 0;
580+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
581+}
582+ 
583+// ascend310p (DAV_2002) is AiCore-supported and covers that npuArch branch.
584+TEST_F(l2_histc_test, case_046_dav2002_path)
585+{
586+ op::SetPlatformSocVersion(op::SocVersion::ASCEND310P);
587+ auto selfTensor = TensorDesc({3, 3}, ACL_FLOAT, ACL_FORMAT_ND).ValueRange(-10, 10);
588+ auto outTensor = TensorDesc({3}, ACL_INT32, ACL_FORMAT_ND);
589+ int64_t bins = 3;
590+ auto minScalar = ScalarDesc(-9.0f);
591+ auto maxScalar = ScalarDesc(9.0f);
592+ auto ut = OP_API_UT(aclnnHistc, INPUT(selfTensor, bins, minScalar, maxScalar), OUTPUT(outTensor));
593+ uint64_t workspaceSize = 0;
594+ EXPECT_EQ(ut.TestGetWorkspaceSize(&workspaceSize), ACLNN_SUCCESS);
248}595}
@@ -9,7 +9,17 @@
9# ----------------------------------------------------------------------------9# ----------------------------------------------------------------------------
10 10 
11if(UT_TEST_ALL OR OP_HOST_UT)11if(UT_TEST_ALL OR OP_HOST_UT)
12- add_modules_ut_sources(UT_NAME ${OP_TILING_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})12+ # HistogramV2 has two tiling templates selected by SoC (IsRegbaseSocVersion):
13+ # ascend950 -> arch35 (HistogramV2SimtTiling)
14+ # ascend310p/910_93/910b -> arch32 (HistogramV2MembaseTiling)
15+ # The tiling UT is compiled once per BUILD_SOC_VERSION, and tiling_context_faker sets the SoC
16+ # from BUILD_SOC_VERSION, so only the matching template is capable. Gate the arch-specific
17+ # tiling cases by ASCEND_COMPUTE_UNIT so each set is compiled only where its template runs.
18+ if("${ASCEND_COMPUTE_UNIT}" STREQUAL "ascend950")
19+ add_modules_ut_sources(UT_NAME ${OP_TILING_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR} TILING_DIR arch35)
20+ else()
21+ add_modules_ut_sources(UT_NAME ${OP_TILING_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR} TILING_DIR arch32)
22+ endif()
13 add_modules_ut_sources(UT_NAME ${OP_INFERSHAPE_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})23 add_modules_ut_sources(UT_NAME ${OP_INFERSHAPE_MODULE_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR})
14endif()24endif()
15 25 
@@ -0,0 +1,167 @@
1+/**
2+ * Copyright (c) 2025-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+// arch32 (non-RegBase: ascend310p / ascend910_93 / ascend910b) tiling UT. This file is compiled
12+// only for the arch32 builds (wired via TILING_DIR arch32 in the op_host tests CMakeLists), where
13+// IsRegbaseSocVersion() is false and the HistogramV2MembaseTiling template is selected. It covers
14+// the MemBase-specific tiling branches; MemBase GetShapeAttrsInfo does not validate inputs, so the
15+// input-validation failure cases live only in the arch35 (SIMT) UT.
16+ 
17+#include <iostream>
18+#include <vector>
19+#include <gtest/gtest.h>
20+#include "tiling_context_faker.h"
21+#include "tiling_case_executor.h"
22+ 
23+#include "../../../../op_host/histogram_v2_tiling.h"
24+ 
25+using namespace ge;
26+using namespace std;
27+ 
28+namespace {
29+using AV = Ops::Math::AnyValue;
30+using TD = gert::TilingContextPara::TensorDescription;
31+ 
32+class HistogramV2Tiling : public testing::Test {
33+protected:
34+ static void SetUpTestCase() { std::cout << "HistogramV2Tiling (arch32/MemBase) SetUp" << std::endl; }
35+ static void TearDownTestCase() { std::cout << "HistogramV2Tiling (arch32/MemBase) TearDown" << std::endl; }
36+};
37+ 
38+static bool RunTiling(const gert::TilingContextPara& para, uint64_t& tilingKey)
39+{
40+ TilingInfo info;
41+ bool ok = ExecuteTiling(para, info);
42+ tilingKey = static_cast<uint64_t>(info.tilingKey);
43+ return ok;
44+}
45+ 
46+static bool RunTiling(const gert::TilingContextPara& para)
47+{
48+ uint64_t key = 0;
49+ return RunTiling(para, key);
50+}
51+ 
52+// Build a HistogramV2 tiling param with 3 inputs (x, min, max) + 1 output (y).
53+static gert::TilingContextPara MakePara(void* compileInfo, const std::vector<int64_t>& xDims, ge::DataType xDtype,
54+ const std::vector<int64_t>& mmDims, ge::DataType mmDtype,
55+ const std::vector<int64_t>& yDims, ge::DataType yDtype, int64_t bins)
56+{
57+ gert::StorageShape xShape;
58+ for (auto d : xDims) {
59+ xShape.MutableOriginShape().AppendDim(d);
60+ xShape.MutableStorageShape().AppendDim(d);
61+ }
62+ gert::StorageShape mmShape;
63+ for (auto d : mmDims) {
64+ mmShape.MutableOriginShape().AppendDim(d);
65+ mmShape.MutableStorageShape().AppendDim(d);
66+ }
67+ gert::StorageShape yShape;
68+ for (auto d : yDims) {
69+ yShape.MutableOriginShape().AppendDim(d);
70+ yShape.MutableStorageShape().AppendDim(d);
71+ }
72+ return gert::TilingContextPara("HistogramV2",
73+ {
74+ TD(xShape, xDtype, ge::FORMAT_ND),
75+ TD(mmShape, mmDtype, ge::FORMAT_ND),
76+ TD(mmShape, mmDtype, ge::FORMAT_ND),
77+ },
78+ {
79+ TD(yShape, yDtype, ge::FORMAT_ND),
80+ },
81+ {
82+ gert::TilingContextPara::OpAttr("bins", AV::CreateFrom<int64_t>(bins)),
83+ },
84+ compileInfo);
85+}
86+ 
87+static optiling::HistogramV2CompileInfo MakeCompileInfo(int64_t coreNum = 64, NpuArch arch = NpuArch::DAV_2201)
88+{
89+ optiling::HistogramV2CompileInfo ci;
90+ ci.totalCoreNum = static_cast<int32_t>(coreNum);
91+ ci.ubSizePlatForm = 262144;
92+ ci.sysWorkspaceSize = 16 * 1024 * 1024;
93+ ci.npuArch = arch;
94+ return ci;
95+}
96+ 
97+// ---------------------- MemBase valid cases ----------------------
98+ 
99+TEST_F(HistogramV2Tiling, tiling_fp32_ub_full)
100+{
101+ auto ci = MakeCompileInfo();
102+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT, {1}, ge::DT_FLOAT, {100}, ge::DT_INT32, 100);
103+ EXPECT_TRUE(RunTiling(para));
104+}
105+ 
106+// dtype cases below exercise the MemBase SetTilingKeyMode dtype -> TilingKey dispatch
107+// (HISTOGRAM_V2_FP16 / INT32 / INT8 / UINT8 / INT16); int64 is covered separately below.
108+TEST_F(HistogramV2Tiling, tiling_fp16)
109+{
110+ auto ci = MakeCompileInfo();
111+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT16, {1}, ge::DT_FLOAT16, {100}, ge::DT_INT32, 100);
112+ EXPECT_TRUE(RunTiling(para));
113+}
114+ 
115+TEST_F(HistogramV2Tiling, tiling_int32)
116+{
117+ auto ci = MakeCompileInfo();
118+ auto para = MakePara(&ci, {256}, ge::DT_INT32, {1}, ge::DT_INT32, {100}, ge::DT_INT32, 100);
119+ EXPECT_TRUE(RunTiling(para));
120+}
121+ 
122+TEST_F(HistogramV2Tiling, tiling_int8)
123+{
124+ auto ci = MakeCompileInfo();
125+ auto para = MakePara(&ci, {256}, ge::DT_INT8, {1}, ge::DT_INT8, {100}, ge::DT_INT32, 100);
126+ EXPECT_TRUE(RunTiling(para));
127+}
128+ 
129+TEST_F(HistogramV2Tiling, tiling_uint8)
130+{
131+ auto ci = MakeCompileInfo();
132+ auto para = MakePara(&ci, {256}, ge::DT_UINT8, {1}, ge::DT_UINT8, {100}, ge::DT_INT32, 100);
133+ EXPECT_TRUE(RunTiling(para));
134+}
135+ 
136+TEST_F(HistogramV2Tiling, tiling_int16)
137+{
138+ auto ci = MakeCompileInfo();
139+ auto para = MakePara(&ci, {256}, ge::DT_INT16, {1}, ge::DT_INT16, {100}, ge::DT_INT32, 100);
140+ EXPECT_TRUE(RunTiling(para));
141+}
142+ 
143+// int64 exercises the MemBase TilingDataInCore int64 branch (tileLength / 2).
144+TEST_F(HistogramV2Tiling, tiling_int64)
145+{
146+ auto ci = MakeCompileInfo();
147+ auto para = MakePara(&ci, {256}, ge::DT_INT64, {1}, ge::DT_INT64, {100}, ge::DT_INT32, 100);
148+ EXPECT_TRUE(RunTiling(para));
149+}
150+ 
151+// npuArch DAV_2002 exercises the MemBase 310P branch (ubSelfLength_310P, userWorkspaceSize, ScheduleMode).
152+TEST_F(HistogramV2Tiling, tiling_membase_310p_branch)
153+{
154+ auto ci = MakeCompileInfo(64, NpuArch::DAV_2002);
155+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT, {1}, ge::DT_FLOAT, {100}, ge::DT_INT32, 100);
156+ EXPECT_TRUE(RunTiling(para));
157+}
158+ 
159+// totalLength < coreNum -> MemBase tailLength == 0 branch (coreNum reduced to 1).
160+TEST_F(HistogramV2Tiling, tiling_tail_length_zero)
161+{
162+ auto ci = MakeCompileInfo();
163+ auto para = MakePara(&ci, {1}, ge::DT_FLOAT, {1}, ge::DT_FLOAT, {100}, ge::DT_INT32, 100);
164+ EXPECT_TRUE(RunTiling(para));
165+}
166+ 
167+} // namespace
@@ -0,0 +1,238 @@
1+/**
2+ * Copyright (c) 2025-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+// arch35 (RegBase / ascend950) tiling UT. This file is compiled only for the ascend950 build
12+// (wired via TILING_DIR arch35 in the op_host tests CMakeLists), where IsRegbaseSocVersion() is
13+// true and the HistogramV2SimtTiling template is selected. No runtime SoC probing is needed:
14+// the SIMT template is the only capable template here, so failure cases assert directly.
15+ 
16+#include <iostream>
17+#include <vector>
18+#include <gtest/gtest.h>
19+#include "tiling_context_faker.h"
20+#include "tiling_case_executor.h"
21+ 
22+#include "../../../../op_host/histogram_v2_tiling.h"
23+ 
24+using namespace ge;
25+using namespace std;
26+ 
27+namespace {
28+using AV = Ops::Math::AnyValue;
29+using TD = gert::TilingContextPara::TensorDescription;
30+ 
31+class HistogramV2Tiling : public testing::Test {
32+protected:
33+ static void SetUpTestCase() { std::cout << "HistogramV2Tiling (arch35/SIMT) SetUp" << std::endl; }
34+ static void TearDownTestCase() { std::cout << "HistogramV2Tiling (arch35/SIMT) TearDown" << std::endl; }
35+};
36+ 
37+static bool RunTiling(const gert::TilingContextPara& para, uint64_t& tilingKey)
38+{
39+ TilingInfo info;
40+ bool ok = ExecuteTiling(para, info);
41+ tilingKey = static_cast<uint64_t>(info.tilingKey);
42+ return ok;
43+}
44+ 
45+static bool RunTiling(const gert::TilingContextPara& para)
46+{
47+ uint64_t key = 0;
48+ return RunTiling(para, key);
49+}
50+ 
51+// Build a HistogramV2 tiling param with 3 inputs (x, min, max) + 1 output (y).
52+static gert::TilingContextPara MakePara(void* compileInfo, const std::vector<int64_t>& xDims, ge::DataType xDtype,
53+ const std::vector<int64_t>& mmDims, ge::DataType mmDtype,
54+ const std::vector<int64_t>& yDims, ge::DataType yDtype, int64_t bins)
55+{
56+ gert::StorageShape xShape;
57+ for (auto d : xDims) {
58+ xShape.MutableOriginShape().AppendDim(d);
59+ xShape.MutableStorageShape().AppendDim(d);
60+ }
61+ gert::StorageShape mmShape;
62+ for (auto d : mmDims) {
63+ mmShape.MutableOriginShape().AppendDim(d);
64+ mmShape.MutableStorageShape().AppendDim(d);
65+ }
66+ gert::StorageShape yShape;
67+ for (auto d : yDims) {
68+ yShape.MutableOriginShape().AppendDim(d);
69+ yShape.MutableStorageShape().AppendDim(d);
70+ }
71+ return gert::TilingContextPara("HistogramV2",
72+ {
73+ TD(xShape, xDtype, ge::FORMAT_ND),
74+ TD(mmShape, mmDtype, ge::FORMAT_ND),
75+ TD(mmShape, mmDtype, ge::FORMAT_ND),
76+ },
77+ {
78+ TD(yShape, yDtype, ge::FORMAT_ND),
79+ },
80+ {
81+ gert::TilingContextPara::OpAttr("bins", AV::CreateFrom<int64_t>(bins)),
82+ },
83+ compileInfo);
84+}
85+ 
86+static optiling::HistogramV2CompileInfo MakeCompileInfo(int64_t coreNum = 64, NpuArch arch = NpuArch::DAV_2201)
87+{
88+ optiling::HistogramV2CompileInfo ci;
89+ ci.totalCoreNum = static_cast<int32_t>(coreNum);
90+ ci.ubSizePlatForm = 262144;
91+ ci.sysWorkspaceSize = 16 * 1024 * 1024;
92+ ci.npuArch = arch;
93+ return ci;
94+}
95+ 
96+// ---------------------- valid cases ----------------------
97+ 
98+TEST_F(HistogramV2Tiling, tiling_fp32_ub_full)
99+{
100+ auto ci = MakeCompileInfo();
101+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT, {1}, ge::DT_FLOAT, {100}, ge::DT_INT32, 100);
102+ EXPECT_TRUE(RunTiling(para));
103+}
104+ 
105+TEST_F(HistogramV2Tiling, tiling_fp16)
106+{
107+ auto ci = MakeCompileInfo();
108+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT16, {1}, ge::DT_FLOAT16, {100}, ge::DT_INT32, 100);
109+ EXPECT_TRUE(RunTiling(para));
110+}
111+ 
112+TEST_F(HistogramV2Tiling, tiling_int32)
113+{
114+ auto ci = MakeCompileInfo();
115+ auto para = MakePara(&ci, {256}, ge::DT_INT32, {1}, ge::DT_INT32, {100}, ge::DT_INT32, 100);
116+ EXPECT_TRUE(RunTiling(para));
117+}
118+ 
119+TEST_F(HistogramV2Tiling, tiling_int8)
120+{
121+ auto ci = MakeCompileInfo();
122+ auto para = MakePara(&ci, {256}, ge::DT_INT8, {1}, ge::DT_INT8, {100}, ge::DT_INT32, 100);
123+ EXPECT_TRUE(RunTiling(para));
124+}
125+ 
126+TEST_F(HistogramV2Tiling, tiling_uint8)
127+{
128+ auto ci = MakeCompileInfo();
129+ auto para = MakePara(&ci, {256}, ge::DT_UINT8, {1}, ge::DT_UINT8, {100}, ge::DT_INT32, 100);
130+ EXPECT_TRUE(RunTiling(para));
131+}
132+ 
133+TEST_F(HistogramV2Tiling, tiling_int16)
134+{
135+ auto ci = MakeCompileInfo();
136+ auto para = MakePara(&ci, {256}, ge::DT_INT16, {1}, ge::DT_INT16, {100}, ge::DT_INT32, 100);
137+ EXPECT_TRUE(RunTiling(para));
138+}
139+ 
140+// int64 exercises the SIMT dtype val 6 path.
141+TEST_F(HistogramV2Tiling, tiling_int64)
142+{
143+ auto ci = MakeCompileInfo();
144+ auto para = MakePara(&ci, {256}, ge::DT_INT64, {1}, ge::DT_INT64, {100}, ge::DT_INT32, 100);
145+ EXPECT_TRUE(RunTiling(para));
146+}
147+ 
148+// fp32 output for fp16 input (SIMT fp32-out key offset path).
149+TEST_F(HistogramV2Tiling, tiling_fp16_out_fp32)
150+{
151+ auto ci = MakeCompileInfo();
152+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT16, {1}, ge::DT_FLOAT16, {100}, ge::DT_FLOAT, 100);
153+ EXPECT_TRUE(RunTiling(para));
154+}
155+ 
156+// fp32 output for fp32 input.
157+TEST_F(HistogramV2Tiling, tiling_fp32_out_fp32)
158+{
159+ auto ci = MakeCompileInfo();
160+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT, {1}, ge::DT_FLOAT, {100}, ge::DT_FLOAT, 100);
161+ EXPECT_TRUE(RunTiling(para));
162+}
163+ 
164+// bins >= ubNumCanUse and totalLength > bins/100 -> SIMT UB_NOT_FULL branch.
165+TEST_F(HistogramV2Tiling, tiling_ub_not_full)
166+{
167+ auto ci = MakeCompileInfo();
168+ auto para = MakePara(&ci, {1000}, ge::DT_FLOAT, {1}, ge::DT_FLOAT, {60000}, ge::DT_INT32, 60000);
169+ EXPECT_TRUE(RunTiling(para));
170+}
171+ 
172+// bins >= ubNumCanUse and totalLength <= bins/100 -> SIMT UB_NOT_FULL_SIMT branch.
173+TEST_F(HistogramV2Tiling, tiling_ub_not_full_simt)
174+{
175+ auto ci = MakeCompileInfo();
176+ auto para = MakePara(&ci, {100}, ge::DT_FLOAT, {1}, ge::DT_FLOAT, {60000}, ge::DT_INT32, 60000);
177+ EXPECT_TRUE(RunTiling(para));
178+}
179+ 
180+// ---------------------- failure cases (SIMT GetShapeAttrsInfo validation) ----------------------
181+ 
182+TEST_F(HistogramV2Tiling, tiling_bins_non_positive)
183+{
184+ auto ci = MakeCompileInfo();
185+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT, {1}, ge::DT_FLOAT, {1}, ge::DT_INT32, -1);
186+ EXPECT_FALSE(RunTiling(para));
187+}
188+ 
189+TEST_F(HistogramV2Tiling, tiling_minmax_shape_invalid)
190+{
191+ auto ci = MakeCompileInfo();
192+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT, {2}, ge::DT_FLOAT, {100}, ge::DT_INT32, 100);
193+ EXPECT_FALSE(RunTiling(para));
194+}
195+ 
196+TEST_F(HistogramV2Tiling, tiling_minmax_dtype_mismatch)
197+{
198+ auto ci = MakeCompileInfo();
199+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT, {1}, ge::DT_FLOAT16, {100}, ge::DT_INT32, 100);
200+ EXPECT_FALSE(RunTiling(para));
201+}
202+ 
203+TEST_F(HistogramV2Tiling, tiling_unsupported_dtype)
204+{
205+ auto ci = MakeCompileInfo();
206+ auto para = MakePara(&ci, {256}, ge::DT_BF16, {1}, ge::DT_BF16, {100}, ge::DT_INT32, 100);
207+ EXPECT_FALSE(RunTiling(para));
208+}
209+ 
210+TEST_F(HistogramV2Tiling, tiling_out_size_ne_bins)
211+{
212+ auto ci = MakeCompileInfo();
213+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT, {1}, ge::DT_FLOAT, {50}, ge::DT_INT32, 100);
214+ EXPECT_FALSE(RunTiling(para));
215+}
216+ 
217+TEST_F(HistogramV2Tiling, tiling_fp32_out_int_input)
218+{
219+ auto ci = MakeCompileInfo();
220+ auto para = MakePara(&ci, {256}, ge::DT_INT32, {1}, ge::DT_INT32, {100}, ge::DT_FLOAT, 100);
221+ EXPECT_FALSE(RunTiling(para));
222+}
223+ 
224+TEST_F(HistogramV2Tiling, tiling_out_dtype_invalid)
225+{
226+ auto ci = MakeCompileInfo();
227+ auto para = MakePara(&ci, {256}, ge::DT_INT32, {1}, ge::DT_INT32, {100}, ge::DT_FLOAT16, 100);
228+ EXPECT_FALSE(RunTiling(para));
229+}
230+ 
231+TEST_F(HistogramV2Tiling, tiling_core_num_zero)
232+{
233+ auto ci = MakeCompileInfo(0);
234+ auto para = MakePara(&ci, {256}, ge::DT_FLOAT, {1}, ge::DT_FLOAT, {100}, ge::DT_INT32, 100);
235+ EXPECT_FALSE(RunTiling(para));
236+}
237+ 
238+} // namespace
@@ -14,14 +14,10 @@
14#include "base/registry/op_impl_space_registry_v2.h"14#include "base/registry/op_impl_space_registry_v2.h"
15 15 
16class HistogramV2Test : public testing::Test {16class HistogramV2Test : public testing::Test {
17- protected:17+protected:
18- static void SetUpTestCase() {18+ static void SetUpTestCase() { std::cout << "HistogramV2Test SetUp" << std::endl; }
19- std::cout << "HistogramV2Test SetUp" << std::endl;
20- }
21 19 
22- static void TearDownTestCase() {20+ static void TearDownTestCase() { std::cout << "HistogramV2Test TearDown" << std::endl; }
23- std::cout << "HistogramV2Test TearDown" << std::endl;
24- }
25};21};
26 22 
27static std::vector<int64_t> ToVector(const gert::Shape& shape)23static std::vector<int64_t> ToVector(const gert::Shape& shape)
@@ -34,42 +30,36 @@ static std::vector<int64_t> ToVector(const gert::Shape& shape)
34 return shapeVec;30 return shapeVec;
35}31}
36 32 
37-static void ExeTestCase(33+static void ExeTestCase(std::vector<std::vector<int64_t> > expectResults,
38- std::vector<std::vector<int64_t> > expectResults,34+ const std::vector<gert::StorageShape>& inputShapes, // 存储所有输入StorageShape参数
39- const std::vector<gert::StorageShape>& inputShapes, // 存储所有输入StorageShape参数35+ const std::vector<ge::DataType>& dtypes, // 存储所有DataType参数
40- const std::vector<ge::DataType>& dtypes, // 存储所有DataType参数36+ gert::StorageShape& outStorageShape, ge::graphStatus testCaseResult = ge::GRAPH_SUCCESS)
41- gert::StorageShape& outStorageShape,
42- ge::graphStatus testCaseResult = ge::GRAPH_SUCCESS)
43{37{
44 // 从vector中取出对应参数(保持原顺序)38 // 从vector中取出对应参数(保持原顺序)
45 const auto& x1StorageShape = inputShapes[0];39 const auto& x1StorageShape = inputShapes[0];
46 const auto& x2StorageShape = inputShapes[1];40 const auto& x2StorageShape = inputShapes[1];
47 const auto& x3StorageShape = inputShapes[2];41 const auto& x3StorageShape = inputShapes[2];
48 42 
49-
50 ge::DataType input1Dtype = dtypes[0];43 ge::DataType input1Dtype = dtypes[0];
51 ge::DataType outputDtype = dtypes[1];44 ge::DataType outputDtype = dtypes[1];
52 45 
53 /* make infershape context */46 /* make infershape context */
54- std::vector<gert::Tensor *> inputTensors = {47+ std::vector<gert::Tensor*> inputTensors = {(gert::Tensor*)&x1StorageShape, (gert::Tensor*)&x2StorageShape,
55- (gert::Tensor *)&x1StorageShape,48+ (gert::Tensor*)&x3StorageShape};
56- (gert::Tensor *)&x2StorageShape,
57- (gert::Tensor *)&x3StorageShape
58- };
59 const std::string& attrName = "bins";49 const std::string& attrName = "bins";
60 int64_t value = 100;50 int64_t value = 100;
61- std::vector<gert::StorageShape *> outputShapes = {&outStorageShape};51+ std::vector<gert::StorageShape*> outputShapes = {&outStorageShape};
62 auto contextHolder = gert::InferShapeContextFaker()52 auto contextHolder = gert::InferShapeContextFaker()
63- .SetOpType("HistogramV2")53+ .SetOpType("HistogramV2")
64- .NodeIoNum(3, 1)54+ .NodeIoNum(3, 1)
65- .NodeInputTd(0, input1Dtype, ge::FORMAT_ND, ge::FORMAT_ND)55+ .NodeInputTd(0, input1Dtype, ge::FORMAT_ND, ge::FORMAT_ND)
66- .NodeInputTd(1, input1Dtype, ge::FORMAT_ND, ge::FORMAT_ND)56+ .NodeInputTd(1, input1Dtype, ge::FORMAT_ND, ge::FORMAT_ND)
67- .NodeInputTd(2, input1Dtype, ge::FORMAT_ND, ge::FORMAT_ND)57+ .NodeInputTd(2, input1Dtype, ge::FORMAT_ND, ge::FORMAT_ND)
68- .NodeOutputTd(0, outputDtype, ge::FORMAT_ND, ge::FORMAT_ND)58+ .NodeOutputTd(0, outputDtype, ge::FORMAT_ND, ge::FORMAT_ND)
69- .InputTensors(inputTensors)59+ .InputTensors(inputTensors)
70- .OutputShapes(outputShapes)60+ .OutputShapes(outputShapes)
71- .Attr(attrName, value)61+ .Attr(attrName, value)
72- .Build();62+ .Build();
73 63 
74 /* get infershape func */64 /* get infershape func */
75 auto spaceRegistry = gert::DefaultOpImplSpaceRegistryV2::GetInstance().GetSpaceRegistry();65 auto spaceRegistry = gert::DefaultOpImplSpaceRegistryV2::GetInstance().GetSpaceRegistry();
@@ -87,13 +77,13 @@ TEST_F(HistogramV2Test, HistogramV2_infershape_case_0)
87{77{
88 // 用vector存储同类型参数(顺序与原参数列表一致)78 // 用vector存储同类型参数(顺序与原参数列表一致)
89 std::vector<gert::StorageShape> inputShapes = {79 std::vector<gert::StorageShape> inputShapes = {
90- {{16, 16}, {16, 16}}, 80+ {{16, 16}, {16, 16}},
91- {{16, 16}, {16, 16}}, 81+ {{16, 16}, {16, 16}},
92- {{16, 16}, {16, 16}}, 82+ {{16, 16}, {16, 16}},
93 };83 };
94 std::vector<ge::DataType> dtypes = {84 std::vector<ge::DataType> dtypes = {
95- ge::DT_FLOAT16, // input1Dtype85+ ge::DT_FLOAT16, // input1Dtype
96- ge::DT_FLOAT16 // outputDtype86+ ge::DT_FLOAT16 // outputDtype
97 };87 };
98 88 
99 std::vector<int64_t> expectResult = {100};89 std::vector<int64_t> expectResult = {100};
@@ -102,3 +92,35 @@ TEST_F(HistogramV2Test, HistogramV2_infershape_case_0)
102 // 简化后的函数调用92 // 简化后的函数调用
103 ExeTestCase({expectResult}, inputShapes, dtypes, outStorageShape, ge::GRAPH_SUCCESS);93 ExeTestCase({expectResult}, inputShapes, dtypes, outStorageShape, ge::GRAPH_SUCCESS);
104}94}
95+ 
96+// bins <= 0 should make InferShape fail (covers the OP_CHECK_IF error branch).
97+static void RunInferShapeWithBins(int64_t bins, ge::graphStatus expect)
98+{
99+ gert::StorageShape x0 = {{16, 16}, {16, 16}};
100+ gert::StorageShape x1 = {{16, 16}, {16, 16}};
101+ gert::StorageShape x2 = {{16, 16}, {16, 16}};
102+ gert::StorageShape outStorageShape = {};
103+ std::vector<gert::Tensor*> inputTensors = {(gert::Tensor*)&x0, (gert::Tensor*)&x1, (gert::Tensor*)&x2};
104+ std::vector<gert::StorageShape*> outputShapes = {&outStorageShape};
105+ auto contextHolder = gert::InferShapeContextFaker()
106+ .SetOpType("HistogramV2")
107+ .NodeIoNum(3, 1)
108+ .NodeInputTd(0, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND)
109+ .NodeInputTd(1, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND)
110+ .NodeInputTd(2, ge::DT_FLOAT16, ge::FORMAT_ND, ge::FORMAT_ND)
111+ .NodeOutputTd(0, ge::DT_INT32, ge::FORMAT_ND, ge::FORMAT_ND)
112+ .InputTensors(inputTensors)
113+ .OutputShapes(outputShapes)
114+ .Attr("bins", bins)
115+ .Build();
116+ auto spaceRegistry = gert::DefaultOpImplSpaceRegistryV2::GetInstance().GetSpaceRegistry();
117+ auto inferShapeFunc = spaceRegistry->GetOpImpl("HistogramV2")->infer_shape;
118+ ASSERT_NE(inferShapeFunc, nullptr);
119+ EXPECT_EQ(inferShapeFunc(contextHolder.GetContext()), expect);
120+}
121+ 
122+TEST_F(HistogramV2Test, HistogramV2_infershape_bins_negative) { RunInferShapeWithBins(-1, ge::GRAPH_FAILED); }
123+ 
124+TEST_F(HistogramV2Test, HistogramV2_infershape_bins_zero) { RunInferShapeWithBins(0, ge::GRAPH_FAILED); }
125+ 
126+TEST_F(HistogramV2Test, HistogramV2_infershape_bins_custom) { RunInferShapeWithBins(64, ge::GRAPH_SUCCESS); }
@@ -1,61 +0,0 @@
1-/**
2- * Copyright (c) 2025-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 <iostream>
12-#include <gtest/gtest.h>
13-#include "tiling_context_faker.h"
14-#include "tiling_case_executor.h"
15- 
16-#include "../../../op_host/histogram_v2_tiling.h"
17- 
18-using namespace ge;
19-using namespace std;
20-class HistogramV2Tiling : public testing::Test {
21-protected:
22- static void SetUpTestCase()
23- {
24- std::cout << "HistogramV2Tiling SetUp" << std::endl;
25- }
26- 
27- static void TearDownTestCase()
28- {
29- std::cout << "HistogramV2Tiling TearDown" << std::endl;
30- }
31-};
32- 
33-struct HistogramV2CompileInfo {
34- int32_t totalCoreNum = 0;
35- uint64_t ubSizePlatform = 0;
36- int64_t sysWorkspaceSize = 0;
37- NpuArch npuArch = NpuArch::DAV_2002;
38-};
39- 
40-TEST_F(HistogramV2Tiling, ascend910B1_test_tiling__001)
41-{
42- HistogramV2CompileInfo compileInfo = {64, 262144, 16 * 1024 * 1024};
43- gert::TilingContextPara tilingContextPara(
44- "HistogramV2",
45- {
46- {{{1, 1}, {1, 1}}, ge::DT_INT32, ge::FORMAT_ND},
47- {{{1, 1}, {1, 1}}, ge::DT_INT32, ge::FORMAT_ND},
48- {{{1, 1}, {1, 1}}, ge::DT_INT32, ge::FORMAT_ND},
49- },
50- {
51- {{{10, 10}, {10, 10}}, ge::DT_INT32, ge::FORMAT_ND},
52- },
53- {
54- gert::TilingContextPara::OpAttr("bins", Ops::Math::AnyValue::CreateFrom<int64_t>(100)),
55- },
56- &compileInfo);
57- uint64_t expectTilingKey = 102;
58- string expectTilingData = "100 57344 1 1 1 1 50 2 2 ";
59- std::vector<size_t> expectWorkspaces = {16777216};
60- // ExecuteTestCase(tilingContextPara, 0, expectTilingKey, expectTilingData, expectWorkspaces);
61-}