1 /**
2 * Copyright 2020-2021 Huawei Technologies Co., Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <iostream>
17 #include <memory>
18 #include <vector>
19
20 #include "common/common_test.h"
21 #include "ir/value.h"
22 #include "pybind_api/ir/primitive_py.h"
23 #include "pipeline/jit/parse/python_adapter.h"
24 #include "frontend/operator/ops.h"
25 #include "base/core_ops.h"
26
27 namespace mindspore {
28 namespace prim {
29
30 class TestOps : public UT::Common {
31 public:
TestOps()32 TestOps() {}
SetUp()33 virtual void SetUp() {}
34 };
35
36 // Arithmetic
TEST_F(TestOps,ScalarAddTest)37 TEST_F(TestOps, ScalarAddTest) {
38 auto prim = std::make_shared<Primitive>(prim::kScalarAdd);
39 ASSERT_EQ(prim->name(), kPrimScalarAdd->name());
40 }
41
TEST_F(TestOps,ScalarSubTest)42 TEST_F(TestOps, ScalarSubTest) {
43 auto prim = std::make_shared<Primitive>(prim::kScalarSub);
44 ASSERT_EQ(prim->name(), kPrimScalarSub->name());
45 }
46
TEST_F(TestOps,ScalarMulTest)47 TEST_F(TestOps, ScalarMulTest) {
48 auto prim = std::make_shared<Primitive>(prim::kScalarMul);
49 ASSERT_EQ(prim->name(), kPrimScalarMul->name());
50 }
51
TEST_F(TestOps,ScalarDivTest)52 TEST_F(TestOps, ScalarDivTest) {
53 auto prim = std::make_shared<Primitive>(prim::kScalarDiv);
54 ASSERT_EQ(prim->name(), kPrimScalarDiv->name());
55 }
56
TEST_F(TestOps,ScalarModTest)57 TEST_F(TestOps, ScalarModTest) {
58 auto prim = std::make_shared<Primitive>(prim::kScalarMod);
59 ASSERT_EQ(prim->name(), kPrimScalarMod->name());
60 }
61
TEST_F(TestOps,ScalarPowTest)62 TEST_F(TestOps, ScalarPowTest) {
63 auto prim = std::make_shared<Primitive>(prim::kScalarPow);
64 ASSERT_EQ(prim->name(), kPrimScalarPow->name());
65 }
66
TEST_F(TestOps,ScalarTruncTest)67 TEST_F(TestOps, ScalarTruncTest) {
68 auto prim = std::make_shared<Primitive>(prim::kScalarTrunc);
69 ASSERT_EQ(prim->name(), kPrimScalarTrunc->name());
70 }
71
TEST_F(TestOps,ScalarFloorTest)72 TEST_F(TestOps, ScalarFloorTest) {
73 auto prim = std::make_shared<Primitive>(prim::kScalarFloor);
74 ASSERT_EQ(prim->name(), kPrimScalarFloor->name());
75 }
76
TEST_F(TestOps,ScalarUaddTest)77 TEST_F(TestOps, ScalarUaddTest) {
78 auto prim = std::make_shared<Primitive>(prim::kScalarUadd);
79 ASSERT_EQ(prim->name(), kPrimScalarUadd->name());
80 }
81
TEST_F(TestOps,ScalarUsubTest)82 TEST_F(TestOps, ScalarUsubTest) {
83 auto prim = std::make_shared<Primitive>(prim::kScalarUsub);
84 ASSERT_EQ(prim->name(), kPrimScalarUsub->name());
85 }
86
TEST_F(TestOps,ScalarExpTest)87 TEST_F(TestOps, ScalarExpTest) {
88 auto prim = std::make_shared<Primitive>("scalar_exp");
89 ASSERT_EQ(prim->name(), kPrimScalarExp->name());
90 }
91
TEST_F(TestOps,ScalarLogTest)92 TEST_F(TestOps, ScalarLogTest) {
93 auto prim = std::make_shared<Primitive>("scalar_log");
94 ASSERT_EQ(prim->name(), kPrimScalarLog->name());
95 }
96
TEST_F(TestOps,ScalarSinTest)97 TEST_F(TestOps, ScalarSinTest) {
98 auto prim = std::make_shared<Primitive>("scalar_sin");
99 ASSERT_EQ(prim->name(), kPrimScalarSin->name());
100 }
101
TEST_F(TestOps,ScalarCosTest)102 TEST_F(TestOps, ScalarCosTest) {
103 auto prim = std::make_shared<Primitive>("scalar_cos");
104 ASSERT_EQ(prim->name(), kPrimScalarCos->name());
105 }
106
TEST_F(TestOps,ScalarTanTest)107 TEST_F(TestOps, ScalarTanTest) {
108 auto prim = std::make_shared<Primitive>("scalar_tan");
109 ASSERT_EQ(prim->name(), kPrimScalarTan->name());
110 }
111
112 // Comparisons
TEST_F(TestOps,ScalarEqTest)113 TEST_F(TestOps, ScalarEqTest) {
114 auto prim = std::make_shared<Primitive>("scalar_eq");
115 ASSERT_EQ(prim->name(), kPrimScalarEq->name());
116 }
117
TEST_F(TestOps,ScalarLtTest)118 TEST_F(TestOps, ScalarLtTest) {
119 auto prim = std::make_shared<Primitive>("scalar_lt");
120 ASSERT_EQ(prim->name(), kPrimScalarLt->name());
121 }
122
TEST_F(TestOps,ScalarGtTest)123 TEST_F(TestOps, ScalarGtTest) {
124 auto prim = std::make_shared<Primitive>("scalar_gt");
125 ASSERT_EQ(prim->name(), kPrimScalarGt->name());
126 }
127
TEST_F(TestOps,ScalarNeTest)128 TEST_F(TestOps, ScalarNeTest) {
129 auto prim = std::make_shared<Primitive>("scalar_ne");
130 ASSERT_EQ(prim->name(), kPrimScalarNe->name());
131 }
132
TEST_F(TestOps,ScalarLeTest)133 TEST_F(TestOps, ScalarLeTest) {
134 auto prim = std::make_shared<Primitive>("scalar_le");
135 ASSERT_EQ(prim->name(), kPrimScalarLe->name());
136 }
137
TEST_F(TestOps,ScalarGeTest)138 TEST_F(TestOps, ScalarGeTest) {
139 auto prim = std::make_shared<Primitive>("scalar_ge");
140 ASSERT_EQ(prim->name(), kPrimScalarGe->name());
141 }
142
TEST_F(TestOps,BoolNotTest)143 TEST_F(TestOps, BoolNotTest) {
144 auto prim = std::make_shared<Primitive>("bool_not");
145 ASSERT_EQ(prim->name(), kPrimBoolNot->name());
146 }
147
TEST_F(TestOps,BoolAndTest)148 TEST_F(TestOps, BoolAndTest) {
149 auto prim = std::make_shared<Primitive>("bool_and");
150 ASSERT_EQ(prim->name(), kPrimBoolAnd->name());
151 }
152
TEST_F(TestOps,BoolOrTest)153 TEST_F(TestOps, BoolOrTest) {
154 auto prim = std::make_shared<Primitive>("bool_or");
155 ASSERT_EQ(prim->name(), kPrimBoolOr->name());
156 }
157
TEST_F(TestOps,BoolEqTest)158 TEST_F(TestOps, BoolEqTest) {
159 auto prim = std::make_shared<Primitive>("bool_eq");
160 ASSERT_EQ(prim->name(), kPrimBoolEq->name());
161 }
162
163 // Type introspection
TEST_F(TestOps,TypeOfTest)164 TEST_F(TestOps, TypeOfTest) {
165 auto prim = std::make_shared<Primitive>("typeof");
166 ASSERT_EQ(prim->name(), kPrimTypeOf->name());
167 }
168
TEST_F(TestOps,HasTypeTest)169 TEST_F(TestOps, HasTypeTest) {
170 auto prim = std::make_shared<Primitive>("hastype");
171 ASSERT_EQ(prim->name(), kPrimHasType->name());
172 }
173
174 // Data structures
TEST_F(TestOps,MakeTupleTest)175 TEST_F(TestOps, MakeTupleTest) {
176 auto prim = std::make_shared<Primitive>("MakeTuple");
177 ASSERT_EQ(prim->name(), kPrimMakeTuple->name());
178 }
179
TEST_F(TestOps,MakeListTest)180 TEST_F(TestOps, MakeListTest) {
181 auto prim = std::make_shared<Primitive>("make_list");
182 ASSERT_EQ(prim->name(), kPrimMakeList->name());
183 }
184
TEST_F(TestOps,MakeRecordTest)185 TEST_F(TestOps, MakeRecordTest) {
186 auto prim = std::make_shared<Primitive>("make_record");
187 ASSERT_EQ(prim->name(), kPrimMakeRecord->name());
188 }
189
TEST_F(TestOps,TupleGetItemTest)190 TEST_F(TestOps, TupleGetItemTest) {
191 auto prim = std::make_shared<Primitive>(kTupleGetItem);
192 ASSERT_EQ(prim->name(), kPrimTupleGetItem->name());
193 }
194
TEST_F(TestOps,ListGetItemTest)195 TEST_F(TestOps, ListGetItemTest) {
196 auto prim = std::make_shared<Primitive>("list_getitem");
197 ASSERT_EQ(prim->name(), kPrimListGetItem->name());
198 }
199
TEST_F(TestOps,ArrayGetItemTest)200 TEST_F(TestOps, ArrayGetItemTest) {
201 auto prim = std::make_shared<Primitive>("array_getitem");
202 ASSERT_EQ(prim->name(), kPrimArrayGetItem->name());
203 }
204
TEST_F(TestOps,TupleSetItemTest)205 TEST_F(TestOps, TupleSetItemTest) {
206 auto prim = std::make_shared<Primitive>("tuple_setitem");
207 ASSERT_EQ(prim->name(), kPrimTupleSetItem->name());
208 }
209
TEST_F(TestOps,ListSetItemTest)210 TEST_F(TestOps, ListSetItemTest) {
211 auto prim = std::make_shared<Primitive>("list_setitem");
212 ASSERT_EQ(prim->name(), kPrimListSetItem->name());
213 }
214
TEST_F(TestOps,ArraySetItemTest)215 TEST_F(TestOps, ArraySetItemTest) {
216 auto prim = std::make_shared<Primitive>("array_setitem");
217 ASSERT_EQ(prim->name(), kPrimArraySetItem->name());
218 }
219
TEST_F(TestOps,ListAppendTest)220 TEST_F(TestOps, ListAppendTest) {
221 auto prim = std::make_shared<Primitive>("list_append");
222 ASSERT_EQ(prim->name(), kPrimListAppend->name());
223 }
224
TEST_F(TestOps,GetAttrTest)225 TEST_F(TestOps, GetAttrTest) {
226 auto prim = std::make_shared<Primitive>("getattr");
227 ASSERT_EQ(prim->name(), kPrimGetAttr->name());
228 }
229
TEST_F(TestOps,TupleLenTest)230 TEST_F(TestOps, TupleLenTest) {
231 auto prim = std::make_shared<Primitive>("tuple_len");
232 ASSERT_EQ(prim->name(), kPrimTupleLen->name());
233 }
234
TEST_F(TestOps,ListLenTest)235 TEST_F(TestOps, ListLenTest) {
236 auto prim = std::make_shared<Primitive>("list_len");
237 ASSERT_EQ(prim->name(), kPrimListLen->name());
238 }
239
TEST_F(TestOps,ArrayLenTest)240 TEST_F(TestOps, ArrayLenTest) {
241 auto prim = std::make_shared<Primitive>("array_len");
242 ASSERT_EQ(prim->name(), kPrimArrayLen->name());
243 }
244
TEST_F(TestOps,ListMapTest)245 TEST_F(TestOps, ListMapTest) {
246 auto prim = std::make_shared<Primitive>("list_map");
247 ASSERT_EQ(prim->name(), kPrimListMap->name());
248 }
249
TEST_F(TestOps,ListReduceTest)250 TEST_F(TestOps, ListReduceTest) {
251 auto prim = std::make_shared<Primitive>("list_reduce");
252 ASSERT_EQ(prim->name(), kPrimListReduce->name());
253 }
254
255 // Arrays
TEST_F(TestOps,ScalarToArrayTest)256 TEST_F(TestOps, ScalarToArrayTest) {
257 auto prim = std::make_shared<Primitive>("scalar_to_array");
258 ASSERT_EQ(prim->name(), kPrimScalarToArray->name());
259 }
260
TEST_F(TestOps,ArrayToScalarTest)261 TEST_F(TestOps, ArrayToScalarTest) {
262 auto prim = std::make_shared<Primitive>("array_to_scalar");
263 ASSERT_EQ(prim->name(), kPrimArrayToScalar->name());
264 }
265
TEST_F(TestOps,BroadCastShapeTest)266 TEST_F(TestOps, BroadCastShapeTest) {
267 auto prim = std::make_shared<Primitive>("broadcast_shape");
268 ASSERT_EQ(prim->name(), kPrimBroadcastShape->name());
269 }
270
TEST_F(TestOps,ArrayMapTest)271 TEST_F(TestOps, ArrayMapTest) {
272 auto prim = std::make_shared<Primitive>("array_map");
273 ASSERT_EQ(prim->name(), kPrimArrayMap->name());
274 }
275
TEST_F(TestOps,ArrayReduceTest)276 TEST_F(TestOps, ArrayReduceTest) {
277 auto prim = std::make_shared<Primitive>("array_reduce");
278 ASSERT_EQ(prim->name(), kPrimArrayReduce->name());
279 }
280
TEST_F(TestOps,DistributeTest)281 TEST_F(TestOps, DistributeTest) {
282 auto prim = std::make_shared<Primitive>("distribute");
283 ASSERT_EQ(prim->name(), kPrimDistribute->name());
284 }
285
TEST_F(TestOps,TransposeTest)286 TEST_F(TestOps, TransposeTest) {
287 auto prim = std::make_shared<Primitive>("Transpose");
288 ASSERT_EQ(prim->name(), kPrimTranspose->name());
289 }
290
TEST_F(TestOps,Im2ColTest)291 TEST_F(TestOps, Im2ColTest) {
292 auto prim = std::make_shared<Primitive>("im2col");
293 ASSERT_EQ(prim->name(), kPrimIm2Col->name());
294 }
295
TEST_F(TestOps,Col2ImTest)296 TEST_F(TestOps, Col2ImTest) {
297 auto prim = std::make_shared<Primitive>("col2im");
298 ASSERT_EQ(prim->name(), kPrimCol2Im->name());
299 }
300
TEST_F(TestOps,Im2ColV1Test)301 TEST_F(TestOps, Im2ColV1Test) {
302 auto prim = std::make_shared<Primitive>("im2col_v1");
303 ASSERT_EQ(prim->name(), kPrimIm2ColV1->name());
304 }
305
TEST_F(TestOps,Col2ImV1Test)306 TEST_F(TestOps, Col2ImV1Test) {
307 auto prim = std::make_shared<Primitive>("col2im_v1");
308 ASSERT_EQ(prim->name(), kPrimCol2ImV1->name());
309 }
310
311 // Statements
TEST_F(TestOps,SwitchTest)312 TEST_F(TestOps, SwitchTest) {
313 auto prim = std::make_shared<Primitive>("Switch");
314 ASSERT_EQ(prim->name(), kPrimSwitch->name());
315 }
316
TEST_F(TestOps,ReturnTest)317 TEST_F(TestOps, ReturnTest) {
318 auto prim = std::make_shared<Primitive>("Return");
319 ASSERT_EQ(prim->name(), kPrimReturn->name());
320 }
321
322 // Miscellaneous
323
TEST_F(TestOps,IdentityTest)324 TEST_F(TestOps, IdentityTest) {
325 auto prim = std::make_shared<Primitive>("identity");
326 ASSERT_EQ(prim->name(), kPrimIdentity->name());
327 }
328
TEST_F(TestOps,ResolveTest)329 TEST_F(TestOps, ResolveTest) {
330 auto prim = std::make_shared<Primitive>("resolve");
331 ASSERT_EQ(prim->name(), kPrimResolve->name());
332 }
333
TEST_F(TestOps,PartialTest)334 TEST_F(TestOps, PartialTest) {
335 auto prim = std::make_shared<Primitive>("Partial");
336 ASSERT_EQ(prim->name(), kPrimPartial->name());
337 }
338
TEST_F(TestOps,JTest)339 TEST_F(TestOps, JTest) {
340 auto prim = std::make_shared<Primitive>("J");
341 ASSERT_EQ(prim->name(), kPrimJ->name());
342 }
343
TEST_F(TestOps,EmbedTest)344 TEST_F(TestOps, EmbedTest) {
345 auto prim = std::make_shared<Primitive>("embed");
346 ASSERT_EQ(prim->name(), kPrimEmbed->name());
347 }
348
TEST_F(TestOps,EnvSetItemTest)349 TEST_F(TestOps, EnvSetItemTest) {
350 auto prim = std::make_shared<Primitive>("env_setitem");
351 ASSERT_EQ(prim->name(), kPrimEnvSetItem->name());
352 }
353
TEST_F(TestOps,EnvGetItemTest)354 TEST_F(TestOps, EnvGetItemTest) {
355 auto prim = std::make_shared<Primitive>("env_getitem");
356 ASSERT_EQ(prim->name(), kPrimEnvGetItem->name());
357 }
358
TEST_F(TestOps,EnvAddest)359 TEST_F(TestOps, EnvAddest) {
360 auto prim = std::make_shared<Primitive>("env_add");
361 ASSERT_EQ(prim->name(), kPrimEnvAdd->name());
362 }
363
364 // Neural Network
TEST_F(TestOps,Conv2dTest)365 TEST_F(TestOps, Conv2dTest) {
366 auto prim = std::make_shared<Primitive>("Conv2D");
367 ASSERT_EQ(prim->name(), kPrimConv2D->name());
368 }
369
TEST_F(TestOps,Conv2dAttrTest)370 TEST_F(TestOps, Conv2dAttrTest) {
371 Primitive prim("Conv2D");
372 prim.SetAttrs({
373 {"stride", MakeValue(static_cast<int64_t>(3))},
374 {"pad", MakeValue(static_cast<int64_t>(1))},
375 });
376 ASSERT_EQ(prim.name(), kPrimConv2D->name());
377
378 Int64Imm stride(3);
379 Int64Imm pad(1);
380 ASSERT_EQ(*prim.GetAttr("stride"), stride);
381 ASSERT_EQ(*prim.GetAttr("pad"), pad);
382 }
383
TEST_F(TestOps,CustomOpAttrTest)384 TEST_F(TestOps, CustomOpAttrTest) {
385 Primitive prim("CustomOp", true, kPrimTypePyInfer);
386 prim.SetAttrs({
387 {"attr1", MakeValue(static_cast<int64_t>(3))},
388 {"attr2", MakeValue(static_cast<int64_t>(1))},
389 });
390 ASSERT_EQ(prim.name(), std::string("CustomOp"));
391 ASSERT_EQ(prim.prim_type(), kPrimTypePyInfer);
392
393 auto attrs = prim.attrs();
394 for (auto attr : attrs) {
395 std::string prim_name = attr.first;
396 auto prim_value = attr.second;
397 std::cout << prim_name << std::endl;
398 std::cout << prim_value << std::endl;
399 }
400 }
401
TEST_F(TestOps,Conv2dBackpropInputTest)402 TEST_F(TestOps, Conv2dBackpropInputTest) {
403 auto prim = std::make_shared<Primitive>("Conv2DBackpropInput");
404 ASSERT_EQ(prim->name(), kPrimConv2DBackpropInput->name());
405 }
406
TEST_F(TestOps,Conv2dBackpropFilterTest)407 TEST_F(TestOps, Conv2dBackpropFilterTest) {
408 auto prim = std::make_shared<Primitive>("Conv2DBackpropFilter");
409 ASSERT_EQ(prim->name(), kPrimConv2DBackpropFilter->name());
410 }
411
TEST_F(TestOps,ReluTest)412 TEST_F(TestOps, ReluTest) {
413 auto prim = std::make_shared<Primitive>("ReLU");
414 ASSERT_EQ(prim->name(), kPrimRelu->name());
415 }
416
TEST_F(TestOps,PoolingTest)417 TEST_F(TestOps, PoolingTest) {
418 auto prim = std::make_shared<Primitive>("Pooling");
419 ASSERT_EQ(prim->name(), kPrimPooling->name());
420 }
421
TEST_F(TestOps,GetConv2DPrimPyTest)422 TEST_F(TestOps, GetConv2DPrimPyTest) {
423 auto conv2d_prim = prim::GetPythonOps("conv2d_prim", "gtest_input.pynative");
424 ASSERT_TRUE(conv2d_prim);
425 PrimitivePyPtr conv2d_ptr = dyn_cast<PrimitivePy>(conv2d_prim);
426 ASSERT_TRUE(conv2d_ptr);
427 if (nullptr != conv2d_ptr) {
428 MS_LOG(INFO) << "Get PrimitivePyPtr: " << conv2d_ptr->name();
429 if(!conv2d_ptr->HasComputeFunction()){
430 MS_LOG(EXCEPTION) << "" << conv2d_ptr->name() << "'s compute function is not implemented";
431 }
432
433 py::object conv2d_pyobj = parse::python_adapter::GetPyFn("gtest_input.pynative", "conv2d_prim");
434 py::dict opAttrs = py::getattr(conv2d_pyobj, "attrs");
435 std::unordered_map<std::string, ValuePtr> attrs{};
436 for (auto item : opAttrs) {
437 if (!py::isinstance<py::str>(item.first)) {
438 MS_LOG(EXCEPTION) << "type error in py dict convert";
439 }
440 std::string name = py::cast<std::string>(item.first);
441 MS_LOG(INFO) << "Attr name: " << name;
442
443 ValuePtr converted_ret;
444 parse::ConvertData(py::cast<py::object>(item.second), &converted_ret);
445 MS_LOG(INFO) << "Attr value: " << converted_ret->ToString();
446 attrs.emplace(name, converted_ret);
447 }
448 }
449
450 MS_LOG(INFO) << "Finish GetPyFnTest!";
451 }
452
453 } // namespace prim
454 } // namespace mindspore
455