1 /** 2 * Copyright 2020 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 <string> 18 #include "common/common_test.h" 19 #include "common/py_func_graph_fetcher.h" 20 21 #include "utils/log_adapter.h" 22 #include "pipeline/jit/parse/parse.h" 23 #include "debug/draw.h" 24 25 namespace mindspore { 26 namespace parse { 27 class TestParser : public UT::Common { 28 public: 29 TestParser() {} 30 virtual void SetUp(); 31 virtual void TearDown(); 32 33 py::function fn; 34 35 py::function GetPythonFunction(std::string function); 36 }; 37 38 void TestParser::SetUp() { UT::InitPythonPath(); } 39 40 void TestParser::TearDown() {} 41 42 py::function TestParser::GetPythonFunction(std::string function) { 43 // init resource 44 try { 45 fn = python_adapter::GetPyFn("gtest_input.pipeline.parse.parser_test", function.c_str()); 46 return fn; 47 } catch (...) { 48 MS_LOG(ERROR) << "get fn failure!!!"; 49 } 50 return py::none(); 51 } 52 53 TEST_F(TestParser, TestParseApi) { 54 // Test null fn 55 py::function fn_null; 56 FuncGraphPtr func_graph = ParsePythonCode(fn_null); 57 ASSERT_TRUE(nullptr == func_graph); 58 59 // Test parse api 60 GetPythonFunction("test_f"); 61 func_graph = ParsePythonCode(fn); 62 ASSERT_TRUE(nullptr != func_graph); 63 } 64 65 TEST_F(TestParser, TestParseAst) { 66 GetPythonFunction("test_f"); 67 68 ParseFunctionAst ast = ParseFunctionAst(fn); 69 bool succ = ast.InitParseAstInfo(); 70 ASSERT_TRUE(succ = true); 71 72 // get FunctionDef node 73 py::object node = ast.GetAstNode(); 74 75 // check arg 76 std::string fun_args[] = {"x", "y"}; 77 std::string fun_name = "test_f"; 78 py::list args = ast.GetArgs(node); 79 for (std::size_t i = 0; i < args.size(); i++) { 80 py::str pyArg = args[i].attr("arg"); 81 std::string arg = pyArg; 82 ASSERT_STREQ(arg.c_str(), fun_args[i].c_str()); 83 } 84 85 // check function name 86 // get function name 87 py::str name = python_adapter::GetPyObjAttr(node, "name"); 88 std::string function_name = name; 89 ASSERT_STREQ(function_name.c_str(), fun_name.c_str()); 90 } 91 92 TEST_F(TestParser, TestParseGraphSuccess) { 93 GetPythonFunction("test_f"); 94 // parse fn to graph 95 FuncGraphPtr func_graph = ParsePythonCode(fn); 96 ASSERT_TRUE(nullptr != func_graph); 97 } 98 99 TEST_F(TestParser, TestParseGraphIf) { 100 GetPythonFunction("test_if"); 101 102 FuncGraphPtr ret_val = ParsePythonCode(fn); 103 ASSERT_TRUE(nullptr != ret_val); 104 } 105 106 TEST_F(TestParser, TestParseGraphIfExp) { 107 GetPythonFunction("test_ifexp"); 108 109 FuncGraphPtr ret_val = ParsePythonCode(fn); 110 ASSERT_TRUE(nullptr != ret_val); 111 } 112 113 TEST_F(TestParser, TestParseGraphIfNested) { 114 GetPythonFunction("test_if_nested"); 115 116 FuncGraphPtr ret_val = ParsePythonCode(fn); 117 ASSERT_TRUE(nullptr != ret_val); 118 } 119 120 TEST_F(TestParser, TestParseWhile) { 121 GetPythonFunction("test_while"); 122 123 FuncGraphPtr ret_val = ParsePythonCode(fn); 124 ASSERT_TRUE(nullptr != ret_val); 125 } 126 127 TEST_F(TestParser, TestParseGraphNum) { 128 FuncGraphPtr ret_val; 129 GetPythonFunction("testDoNum"); 130 ret_val = ParsePythonCode(fn); 131 ASSERT_TRUE(nullptr != ret_val); 132 } 133 134 TEST_F(TestParser, TestParseGraphStr) { 135 FuncGraphPtr ret_val; 136 GetPythonFunction("testDoStr"); 137 ret_val = ParsePythonCode(fn); 138 ASSERT_TRUE(nullptr != ret_val); 139 } 140 141 TEST_F(TestParser, TestParseGraphNamedConst) { 142 FuncGraphPtr ret_val; 143 GetPythonFunction("testDoNamedConstTrue"); 144 ret_val = ParsePythonCode(fn); 145 ASSERT_TRUE(nullptr != ret_val); 146 GetPythonFunction("testDoNamedConstFalse"); 147 ret_val = ParsePythonCode(fn); 148 ASSERT_TRUE(nullptr != ret_val); 149 GetPythonFunction("testDoNamedConstNone"); 150 ret_val = ParsePythonCode(fn); 151 ASSERT_TRUE(nullptr != ret_val); 152 } 153 154 TEST_F(TestParser, TestParseGraphForStatement) { 155 GetPythonFunction("test_for"); 156 157 FuncGraphPtr func_graph = ParsePythonCode(fn); 158 ASSERT_TRUE(nullptr != func_graph); 159 160 // save the func_graph to manager 161 std::shared_ptr<FuncGraphManager> manager = Manage(func_graph); 162 163 // call resolve 164 bool ret_ = ResolveAll(manager); 165 166 ASSERT_TRUE(ret_); 167 } 168 169 TEST_F(TestParser, TestParseGraphCompareExprLt) { 170 GetPythonFunction("test_compare_lt"); 171 172 FuncGraphPtr ret_val = ParsePythonCode(fn); 173 ASSERT_TRUE(nullptr != ret_val); 174 } 175 176 TEST_F(TestParser, TestParseGraphCompareExprGt) { 177 GetPythonFunction("test_compare_gt"); 178 179 FuncGraphPtr ret_val = ParsePythonCode(fn); 180 ASSERT_TRUE(nullptr != ret_val); 181 } 182 183 TEST_F(TestParser, TestParseGraphCompareExprLe) { 184 GetPythonFunction("test_compare_le"); 185 FuncGraphPtr ret_val = ParsePythonCode(fn); 186 ASSERT_TRUE(nullptr != ret_val); 187 } 188 189 TEST_F(TestParser, TestParseGraphCompareExprNe) { 190 GetPythonFunction("test_compare_ne"); 191 FuncGraphPtr ret_val = ParsePythonCode(fn); 192 ASSERT_TRUE(nullptr != ret_val); 193 } 194 195 TEST_F(TestParser, TestParseGraphCompareExprGe) { 196 GetPythonFunction("test_compare_ge"); 197 FuncGraphPtr ret_val = ParsePythonCode(fn); 198 ASSERT_TRUE(nullptr != ret_val); 199 } 200 201 TEST_F(TestParser, TestParseGraphCompareExprEq) { 202 GetPythonFunction("test_compare_eq"); 203 FuncGraphPtr ret_val = ParsePythonCode(fn); 204 ASSERT_TRUE(nullptr != ret_val); 205 } 206 207 TEST_F(TestParser, TestParseGraphBoolOpTwoAnd) { 208 GetPythonFunction("test_boolop_two_and"); 209 210 FuncGraphPtr ret_val = ParsePythonCode(fn); 211 ASSERT_TRUE(nullptr != ret_val); 212 } 213 214 TEST_F(TestParser, TestParseGraphBoolOpThreeAnd) { 215 GetPythonFunction("test_boolop_three_and"); 216 FuncGraphPtr ret_val = ParsePythonCode(fn); 217 ASSERT_TRUE(nullptr != ret_val); 218 } 219 220 TEST_F(TestParser, TestParseGraphBoolOpTwoOr) { 221 GetPythonFunction("test_boolop_two_or"); 222 FuncGraphPtr ret_val = ParsePythonCode(fn); 223 ASSERT_TRUE(nullptr != ret_val); 224 } 225 226 TEST_F(TestParser, TestParseGraphBoolOpThreeOr) { 227 GetPythonFunction("test_boolop_three_or"); 228 229 FuncGraphPtr ret_val = ParsePythonCode(fn); 230 ASSERT_TRUE(nullptr != ret_val); 231 } 232 233 TEST_F(TestParser, TestParseGraphBoolOpMixAndOr) { 234 GetPythonFunction("test_boolop_mix_and_or"); 235 236 FuncGraphPtr ret_val = ParsePythonCode(fn); 237 ASSERT_TRUE(nullptr != ret_val); 238 } 239 240 TEST_F(TestParser, TestParseGraphLambda) { 241 GetPythonFunction("test_lambda"); 242 243 FuncGraphPtr ret_val = ParsePythonCode(fn); 244 ASSERT_TRUE(nullptr != ret_val); 245 } 246 247 TEST_F(TestParser, TestParseGraphFuncDef) { 248 GetPythonFunction("test_funcdef"); 249 250 FuncGraphPtr ret_val = ParsePythonCode(fn); 251 ASSERT_TRUE(nullptr != ret_val); 252 } 253 254 TEST_F(TestParser, TestParseGraphSimpleClosure) { 255 GetPythonFunction("test_simple_closure"); 256 257 FuncGraphPtr ret_val = ParsePythonCode(fn); 258 ASSERT_TRUE(nullptr != ret_val); 259 } 260 261 TEST_F(TestParser, TestParseGraphTestTuple) { 262 GetPythonFunction("test_tuple_fn"); 263 264 FuncGraphPtr ret_val = ParsePythonCode(fn); 265 ASSERT_TRUE(nullptr != ret_val); 266 } 267 268 TEST_F(TestParser, TestParseGraphTupleAssign) { 269 GetPythonFunction("test_assign_tuple"); 270 271 FuncGraphPtr ret_val = ParsePythonCode(fn); 272 ASSERT_TRUE(nullptr != ret_val); 273 } 274 275 TEST_F(TestParser, TestParseGraphTestList) { 276 GetPythonFunction("test_list_fn"); 277 278 FuncGraphPtr ret_val = ParsePythonCode(fn); 279 ASSERT_TRUE(nullptr != ret_val); 280 } 281 282 TEST_F(TestParser, TestParseGraphUnaryOp) { 283 GetPythonFunction("test_unary"); 284 285 FuncGraphPtr ret_val = ParsePythonCode(fn); 286 ASSERT_TRUE(nullptr != ret_val); 287 } 288 289 TEST_F(TestParser, TestParseGraphAguassign) { 290 GetPythonFunction("test_augassign"); 291 292 FuncGraphPtr ret_val = ParsePythonCode(fn); 293 ASSERT_TRUE(nullptr != ret_val); 294 } 295 296 TEST_F(TestParser, TestParseSystemFunction) { 297 GetPythonFunction("test_sys_call"); 298 299 FuncGraphPtr ret_val = ParsePythonCode(fn); 300 ASSERT_TRUE(nullptr != ret_val); 301 } 302 303 TEST_F(TestParser, TestParseGraphBoolNot) { 304 GetPythonFunction("test_bool_not"); 305 306 FuncGraphPtr ret_val = ParsePythonCode(fn); 307 ASSERT_TRUE(nullptr != ret_val); 308 309 // save the func_graph to manager 310 std::shared_ptr<FuncGraphManager> manager = Manage(ret_val); 311 312 // call resolve 313 bool ret_ = ResolveAll(manager); 314 315 ASSERT_TRUE(ret_); 316 } 317 318 TEST_F(TestParser, TestCallPythonFnUseTupleParamete) { 319 GetPythonFunction("test_call_fn_use_tuple"); 320 321 py::tuple params = py::tuple(5); 322 params[0] = 0; 323 params[1] = 1; 324 params[2] = 2.0; 325 params[3] = fn; 326 params[4] = "test_call_fn_use_tuple"; 327 py::object result = 328 python_adapter::CallPyFn("gtest_input.pipeline.parse.parser_test", "test_call_fn_use_tuple", params); 329 330 int ret_size = py::cast<int>(result); 331 332 ASSERT_EQ(ret_size, 5); 333 } 334 335 TEST_F(TestParser, TestParseGraphSubscriptSetitem) { 336 GetPythonFunction("test_subscript_setitem"); 337 338 FuncGraphPtr ret_val = ParsePythonCode(fn); 339 ASSERT_TRUE(nullptr != ret_val); 340 341 std::shared_ptr<FuncGraphManager> manager = Manage(ret_val); 342 bool ret_ = ResolveAll(manager); 343 ASSERT_TRUE(ret_); 344 } 345 346 TEST_F(TestParser, TestParseGraphDict) { 347 GetPythonFunction("test_dict"); 348 349 FuncGraphPtr ret_val = ParsePythonCode(fn); 350 ASSERT_TRUE(nullptr != ret_val); 351 352 std::shared_ptr<FuncGraphManager> manager = Manage(ret_val); 353 bool ret_ = ResolveAll(manager); 354 ASSERT_TRUE(ret_); 355 } 356 357 TEST_F(TestParser, TestParseGraphCallVargs) { 358 GetPythonFunction("test_call_variable"); 359 360 FuncGraphPtr ret_val = ParsePythonCode(fn); 361 ASSERT_TRUE(nullptr != ret_val); 362 363 std::shared_ptr<FuncGraphManager> manager = Manage(ret_val); 364 bool ret_ = ResolveAll(manager); 365 ASSERT_TRUE(ret_); 366 } 367 368 TEST_F(TestParser, TestParserUndefinedVar) { 369 py::function fn_ = python_adapter::GetPyFn("gtest_input.pipeline.parse.parser_test", "test_parse_undefined_var"); 370 371 // parse undefined var 372 EXPECT_THROW({ ParsePythonCode(fn_); }, std::runtime_error); 373 } 374 } // namespace parse 375 } // namespace mindspore 376