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: 32 TestOps() {} 33 virtual void SetUp() {} 34 }; 35 36 // Arithmetic 37 TEST_F(TestOps, ScalarAddTest) { 38 auto prim = std::make_shared<Primitive>(prim::kScalarAdd); 39 ASSERT_EQ(prim->name(), kPrimScalarAdd->name()); 40 } 41 42 TEST_F(TestOps, ScalarSubTest) { 43 auto prim = std::make_shared<Primitive>(prim::kScalarSub); 44 ASSERT_EQ(prim->name(), kPrimScalarSub->name()); 45 } 46 47 TEST_F(TestOps, ScalarMulTest) { 48 auto prim = std::make_shared<Primitive>(prim::kScalarMul); 49 ASSERT_EQ(prim->name(), kPrimScalarMul->name()); 50 } 51 52 TEST_F(TestOps, ScalarDivTest) { 53 auto prim = std::make_shared<Primitive>(prim::kScalarDiv); 54 ASSERT_EQ(prim->name(), kPrimScalarDiv->name()); 55 } 56 57 TEST_F(TestOps, ScalarModTest) { 58 auto prim = std::make_shared<Primitive>(prim::kScalarMod); 59 ASSERT_EQ(prim->name(), kPrimScalarMod->name()); 60 } 61 62 TEST_F(TestOps, ScalarPowTest) { 63 auto prim = std::make_shared<Primitive>(prim::kScalarPow); 64 ASSERT_EQ(prim->name(), kPrimScalarPow->name()); 65 } 66 67 TEST_F(TestOps, ScalarTruncTest) { 68 auto prim = std::make_shared<Primitive>(prim::kScalarTrunc); 69 ASSERT_EQ(prim->name(), kPrimScalarTrunc->name()); 70 } 71 72 TEST_F(TestOps, ScalarFloorTest) { 73 auto prim = std::make_shared<Primitive>(prim::kScalarFloor); 74 ASSERT_EQ(prim->name(), kPrimScalarFloor->name()); 75 } 76 77 TEST_F(TestOps, ScalarUaddTest) { 78 auto prim = std::make_shared<Primitive>(prim::kScalarUadd); 79 ASSERT_EQ(prim->name(), kPrimScalarUadd->name()); 80 } 81 82 TEST_F(TestOps, ScalarUsubTest) { 83 auto prim = std::make_shared<Primitive>(prim::kScalarUsub); 84 ASSERT_EQ(prim->name(), kPrimScalarUsub->name()); 85 } 86 87 TEST_F(TestOps, ScalarExpTest) { 88 auto prim = std::make_shared<Primitive>("scalar_exp"); 89 ASSERT_EQ(prim->name(), kPrimScalarExp->name()); 90 } 91 92 TEST_F(TestOps, ScalarLogTest) { 93 auto prim = std::make_shared<Primitive>("scalar_log"); 94 ASSERT_EQ(prim->name(), kPrimScalarLog->name()); 95 } 96 97 TEST_F(TestOps, ScalarSinTest) { 98 auto prim = std::make_shared<Primitive>("scalar_sin"); 99 ASSERT_EQ(prim->name(), kPrimScalarSin->name()); 100 } 101 102 TEST_F(TestOps, ScalarCosTest) { 103 auto prim = std::make_shared<Primitive>("scalar_cos"); 104 ASSERT_EQ(prim->name(), kPrimScalarCos->name()); 105 } 106 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 113 TEST_F(TestOps, ScalarEqTest) { 114 auto prim = std::make_shared<Primitive>("scalar_eq"); 115 ASSERT_EQ(prim->name(), kPrimScalarEq->name()); 116 } 117 118 TEST_F(TestOps, ScalarLtTest) { 119 auto prim = std::make_shared<Primitive>("scalar_lt"); 120 ASSERT_EQ(prim->name(), kPrimScalarLt->name()); 121 } 122 123 TEST_F(TestOps, ScalarGtTest) { 124 auto prim = std::make_shared<Primitive>("scalar_gt"); 125 ASSERT_EQ(prim->name(), kPrimScalarGt->name()); 126 } 127 128 TEST_F(TestOps, ScalarNeTest) { 129 auto prim = std::make_shared<Primitive>("scalar_ne"); 130 ASSERT_EQ(prim->name(), kPrimScalarNe->name()); 131 } 132 133 TEST_F(TestOps, ScalarLeTest) { 134 auto prim = std::make_shared<Primitive>("scalar_le"); 135 ASSERT_EQ(prim->name(), kPrimScalarLe->name()); 136 } 137 138 TEST_F(TestOps, ScalarGeTest) { 139 auto prim = std::make_shared<Primitive>("scalar_ge"); 140 ASSERT_EQ(prim->name(), kPrimScalarGe->name()); 141 } 142 143 TEST_F(TestOps, BoolNotTest) { 144 auto prim = std::make_shared<Primitive>("bool_not"); 145 ASSERT_EQ(prim->name(), kPrimBoolNot->name()); 146 } 147 148 TEST_F(TestOps, BoolAndTest) { 149 auto prim = std::make_shared<Primitive>("bool_and"); 150 ASSERT_EQ(prim->name(), kPrimBoolAnd->name()); 151 } 152 153 TEST_F(TestOps, BoolOrTest) { 154 auto prim = std::make_shared<Primitive>("bool_or"); 155 ASSERT_EQ(prim->name(), kPrimBoolOr->name()); 156 } 157 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 164 TEST_F(TestOps, TypeOfTest) { 165 auto prim = std::make_shared<Primitive>("typeof"); 166 ASSERT_EQ(prim->name(), kPrimTypeOf->name()); 167 } 168 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 175 TEST_F(TestOps, MakeTupleTest) { 176 auto prim = std::make_shared<Primitive>("MakeTuple"); 177 ASSERT_EQ(prim->name(), kPrimMakeTuple->name()); 178 } 179 180 TEST_F(TestOps, MakeListTest) { 181 auto prim = std::make_shared<Primitive>("make_list"); 182 ASSERT_EQ(prim->name(), kPrimMakeList->name()); 183 } 184 185 TEST_F(TestOps, MakeRecordTest) { 186 auto prim = std::make_shared<Primitive>("make_record"); 187 ASSERT_EQ(prim->name(), kPrimMakeRecord->name()); 188 } 189 190 TEST_F(TestOps, TupleGetItemTest) { 191 auto prim = std::make_shared<Primitive>(kTupleGetItem); 192 ASSERT_EQ(prim->name(), kPrimTupleGetItem->name()); 193 } 194 195 TEST_F(TestOps, ListGetItemTest) { 196 auto prim = std::make_shared<Primitive>("list_getitem"); 197 ASSERT_EQ(prim->name(), kPrimListGetItem->name()); 198 } 199 200 TEST_F(TestOps, ArrayGetItemTest) { 201 auto prim = std::make_shared<Primitive>("array_getitem"); 202 ASSERT_EQ(prim->name(), kPrimArrayGetItem->name()); 203 } 204 205 TEST_F(TestOps, TupleSetItemTest) { 206 auto prim = std::make_shared<Primitive>("tuple_setitem"); 207 ASSERT_EQ(prim->name(), kPrimTupleSetItem->name()); 208 } 209 210 TEST_F(TestOps, ListSetItemTest) { 211 auto prim = std::make_shared<Primitive>("list_setitem"); 212 ASSERT_EQ(prim->name(), kPrimListSetItem->name()); 213 } 214 215 TEST_F(TestOps, ArraySetItemTest) { 216 auto prim = std::make_shared<Primitive>("array_setitem"); 217 ASSERT_EQ(prim->name(), kPrimArraySetItem->name()); 218 } 219 220 TEST_F(TestOps, ListAppendTest) { 221 auto prim = std::make_shared<Primitive>("list_append"); 222 ASSERT_EQ(prim->name(), kPrimListAppend->name()); 223 } 224 225 TEST_F(TestOps, GetAttrTest) { 226 auto prim = std::make_shared<Primitive>("getattr"); 227 ASSERT_EQ(prim->name(), kPrimGetAttr->name()); 228 } 229 230 TEST_F(TestOps, TupleLenTest) { 231 auto prim = std::make_shared<Primitive>("tuple_len"); 232 ASSERT_EQ(prim->name(), kPrimTupleLen->name()); 233 } 234 235 TEST_F(TestOps, ListLenTest) { 236 auto prim = std::make_shared<Primitive>("list_len"); 237 ASSERT_EQ(prim->name(), kPrimListLen->name()); 238 } 239 240 TEST_F(TestOps, ArrayLenTest) { 241 auto prim = std::make_shared<Primitive>("array_len"); 242 ASSERT_EQ(prim->name(), kPrimArrayLen->name()); 243 } 244 245 TEST_F(TestOps, ListMapTest) { 246 auto prim = std::make_shared<Primitive>("list_map"); 247 ASSERT_EQ(prim->name(), kPrimListMap->name()); 248 } 249 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 256 TEST_F(TestOps, ScalarToArrayTest) { 257 auto prim = std::make_shared<Primitive>("scalar_to_array"); 258 ASSERT_EQ(prim->name(), kPrimScalarToArray->name()); 259 } 260 261 TEST_F(TestOps, ArrayToScalarTest) { 262 auto prim = std::make_shared<Primitive>("array_to_scalar"); 263 ASSERT_EQ(prim->name(), kPrimArrayToScalar->name()); 264 } 265 266 TEST_F(TestOps, BroadCastShapeTest) { 267 auto prim = std::make_shared<Primitive>("broadcast_shape"); 268 ASSERT_EQ(prim->name(), kPrimBroadcastShape->name()); 269 } 270 271 TEST_F(TestOps, ArrayMapTest) { 272 auto prim = std::make_shared<Primitive>("array_map"); 273 ASSERT_EQ(prim->name(), kPrimArrayMap->name()); 274 } 275 276 TEST_F(TestOps, ArrayReduceTest) { 277 auto prim = std::make_shared<Primitive>("array_reduce"); 278 ASSERT_EQ(prim->name(), kPrimArrayReduce->name()); 279 } 280 281 TEST_F(TestOps, DistributeTest) { 282 auto prim = std::make_shared<Primitive>("distribute"); 283 ASSERT_EQ(prim->name(), kPrimDistribute->name()); 284 } 285 286 TEST_F(TestOps, TransposeTest) { 287 auto prim = std::make_shared<Primitive>("Transpose"); 288 ASSERT_EQ(prim->name(), kPrimTranspose->name()); 289 } 290 291 TEST_F(TestOps, Im2ColTest) { 292 auto prim = std::make_shared<Primitive>("im2col"); 293 ASSERT_EQ(prim->name(), kPrimIm2Col->name()); 294 } 295 296 TEST_F(TestOps, Col2ImTest) { 297 auto prim = std::make_shared<Primitive>("col2im"); 298 ASSERT_EQ(prim->name(), kPrimCol2Im->name()); 299 } 300 301 TEST_F(TestOps, Im2ColV1Test) { 302 auto prim = std::make_shared<Primitive>("im2col_v1"); 303 ASSERT_EQ(prim->name(), kPrimIm2ColV1->name()); 304 } 305 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 312 TEST_F(TestOps, SwitchTest) { 313 auto prim = std::make_shared<Primitive>("Switch"); 314 ASSERT_EQ(prim->name(), kPrimSwitch->name()); 315 } 316 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 324 TEST_F(TestOps, IdentityTest) { 325 auto prim = std::make_shared<Primitive>("identity"); 326 ASSERT_EQ(prim->name(), kPrimIdentity->name()); 327 } 328 329 TEST_F(TestOps, ResolveTest) { 330 auto prim = std::make_shared<Primitive>("resolve"); 331 ASSERT_EQ(prim->name(), kPrimResolve->name()); 332 } 333 334 TEST_F(TestOps, PartialTest) { 335 auto prim = std::make_shared<Primitive>("Partial"); 336 ASSERT_EQ(prim->name(), kPrimPartial->name()); 337 } 338 339 TEST_F(TestOps, JTest) { 340 auto prim = std::make_shared<Primitive>("J"); 341 ASSERT_EQ(prim->name(), kPrimJ->name()); 342 } 343 344 TEST_F(TestOps, EmbedTest) { 345 auto prim = std::make_shared<Primitive>("embed"); 346 ASSERT_EQ(prim->name(), kPrimEmbed->name()); 347 } 348 349 TEST_F(TestOps, EnvSetItemTest) { 350 auto prim = std::make_shared<Primitive>("env_setitem"); 351 ASSERT_EQ(prim->name(), kPrimEnvSetItem->name()); 352 } 353 354 TEST_F(TestOps, EnvGetItemTest) { 355 auto prim = std::make_shared<Primitive>("env_getitem"); 356 ASSERT_EQ(prim->name(), kPrimEnvGetItem->name()); 357 } 358 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 365 TEST_F(TestOps, Conv2dTest) { 366 auto prim = std::make_shared<Primitive>("Conv2D"); 367 ASSERT_EQ(prim->name(), kPrimConv2D->name()); 368 } 369 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 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 402 TEST_F(TestOps, Conv2dBackpropInputTest) { 403 auto prim = std::make_shared<Primitive>("Conv2DBackpropInput"); 404 ASSERT_EQ(prim->name(), kPrimConv2DBackpropInput->name()); 405 } 406 407 TEST_F(TestOps, Conv2dBackpropFilterTest) { 408 auto prim = std::make_shared<Primitive>("Conv2DBackpropFilter"); 409 ASSERT_EQ(prim->name(), kPrimConv2DBackpropFilter->name()); 410 } 411 412 TEST_F(TestOps, ReluTest) { 413 auto prim = std::make_shared<Primitive>("ReLU"); 414 ASSERT_EQ(prim->name(), kPrimRelu->name()); 415 } 416 417 TEST_F(TestOps, PoolingTest) { 418 auto prim = std::make_shared<Primitive>("Pooling"); 419 ASSERT_EQ(prim->name(), kPrimPooling->name()); 420 } 421 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