• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <memory>
17 
18 #include "common/common_test.h"
19 #include "ir/anf.h"
20 #include "ir/value.h"
21 #include "frontend/operator/composite/composite.h"
22 #include "frontend/operator/ops.h"
23 #include "pipeline/jit/static_analysis/prim.h"
24 #include "abstract/abstract_function.h"
25 #include "debug/trace.h"
26 
27 namespace mindspore {
28 using Shape = abstract::Shape;
29 
30 using AbstractScalar = abstract::AbstractScalar;
31 using AbstractScalarPtr = abstract::AbstractScalarPtr;
32 
33 using AbstractSlice = abstract::AbstractSlice;
34 using AbstractSlicePtr = abstract::AbstractSlicePtr;
35 
36 using AbstractTuple = abstract::AbstractTuple;
37 using AbstractTuplePtr = abstract::AbstractTuplePtr;
38 
39 using AbstractTensor = abstract::AbstractTensor;
40 using AbstractTensorPtr = abstract::AbstractTensorPtr;
41 
42 using AbstractNone = abstract::AbstractNone;
43 using AbstractAttribute = abstract::AbstractAttribute;
44 using AnalysisEngine = abstract::AnalysisEngine;
45 using AnalysisEnginePtr = abstract::AnalysisEnginePtr;
46 
47 class TestComposite : public UT::Common {
48  public:
49   virtual void SetUp();
50   virtual void TearDown();
51 
52   AnalysisEnginePtr engine_;
53 };
54 
SetUp()55 void TestComposite::SetUp() {
56   // init resource
57   std::shared_ptr<FuncGraphManager> graph_manager = MakeManager();
58   engine_ = std::make_shared<AnalysisEngine>(abstract::GetPrimEvaluatorConstructors(), graph_manager);
59 }
60 
TearDown()61 void TestComposite::TearDown() {
62   // destroy resource
63 }
64 
65 class UTCompositeUtils {
66  public:
ArrayInt32Of(std::initializer_list<int64_t> shp)67   static AbstractTensorPtr ArrayInt32Of(std::initializer_list<int64_t> shp) {
68     auto ele = std::make_shared<AbstractScalar>(kAnyValue, kInt64);
69     return std::make_shared<AbstractTensor>(ele, std::make_shared<Shape>(shp));
70   }
MakeFuncGraph(const MetaFuncGraphPtr & metaFuncGraphPtr,size_t nparam)71   static FuncGraphPtr MakeFuncGraph(const MetaFuncGraphPtr &metaFuncGraphPtr, size_t nparam) {
72     FuncGraphPtr func_graph = std::make_shared<FuncGraph>();
73     std::vector<AnfNodePtr> inputs;
74     inputs.push_back(NewValueNode(metaFuncGraphPtr));
75     for (size_t i = 0; i < nparam; i++) {
76       inputs.push_back(func_graph->add_parameter());
77     }
78     CNodePtr cnode_prim = func_graph->NewCNode(inputs);
79     inputs.clear();
80     inputs.push_back(NewValueNode(prim::kPrimReturn));
81     inputs.push_back(cnode_prim);
82     CNodePtr cnode_return = func_graph->NewCNode(inputs);
83     func_graph->set_return(cnode_return);
84     return func_graph;
85   }
86 };
87 
TEST_F(TestComposite,test_TupleSlice_arg_two_numbers)88 TEST_F(TestComposite, test_TupleSlice_arg_two_numbers) {
89   MetaFuncGraphPtr tupleSlicePtr = std::make_shared<prim::TupleSlice>("tuple_slice");
90   FuncGraphPtr tupleSliceGraphPtr = UTCompositeUtils::MakeFuncGraph(tupleSlicePtr, 3);
91 
92   AbstractBasePtrList eles;
93   auto tensor = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
94   size_t tuple_size = 6;
95   for (size_t i = 0; i < tuple_size; i++) {
96     eles.push_back(tensor);
97   }
98   auto tuple_tensor = std::make_shared<AbstractTuple>(eles);
99   auto start_index = std::make_shared<AbstractScalar>(static_cast<int64_t>(1));
100   auto stop_index = std::make_shared<AbstractScalar>(static_cast<int64_t>(5));
101   AbstractBasePtrList args_spec_list = {tuple_tensor, start_index, stop_index};
102 
103   try {
104     engine_->Run(tupleSliceGraphPtr, args_spec_list);
105     FAIL() << "Excepted exception :Args type is wrong";
106   } catch (std::runtime_error const &err) {
107     ASSERT_TRUE(std::string(err.what()).find("TupleSlice input args size should be 2, but got 3") != std::string::npos);
108   } catch (...) {
109     FAIL() << "Excepted exception :Args type is wrong";
110   }
111 }
112 
TEST_F(TestComposite,test_TupleSlice_arg_one_number)113 TEST_F(TestComposite, test_TupleSlice_arg_one_number) {
114   MetaFuncGraphPtr tupleSlicePtr = std::make_shared<prim::TupleSlice>("tuple_slice");
115   FuncGraphPtr tupleSliceGraphPtr = UTCompositeUtils::MakeFuncGraph(tupleSlicePtr, 2);
116 
117   AbstractBasePtrList eles;
118   auto tensor = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
119   size_t tuple_size = 6;
120   for (size_t i = 0; i < tuple_size; i++) {
121     eles.push_back(tensor);
122   }
123   auto tuple_tensor = std::make_shared<AbstractTuple>(eles);
124   auto start_index = std::make_shared<AbstractScalar>(static_cast<int64_t>(1));
125   AbstractBasePtrList args_spec_list = {tuple_tensor, start_index};
126 
127   try {
128     trace::ClearTraceStack();
129     engine_->Run(tupleSliceGraphPtr, args_spec_list);
130     FAIL() << "Excepted exception: Args type is wrong";
131   } catch (pybind11::type_error const &err) {
132     ASSERT_TRUE(true);
133   } catch (std::runtime_error const &err) {
134     if (std::strstr(err.what(), "TypeError") != nullptr) {
135       ASSERT_TRUE(true);
136     } else {
137       FAIL() << "Excepted exception: Args type is wrong, message: " << err.what();
138     }
139   } catch (...) {
140     FAIL() << "Excepted exception: Args type is wrong";
141   }
142 }
143 
TEST_F(TestComposite,test_TupleSlice_arg_slice)144 TEST_F(TestComposite, test_TupleSlice_arg_slice) {
145   std::shared_ptr<py::scoped_interpreter> env = parse::python_adapter::set_python_scoped();
146   MetaFuncGraphPtr tupleSlicePtr = std::make_shared<prim::TupleSlice>("tuple_slice");
147   FuncGraphPtr tupleSliceGraphPtr = UTCompositeUtils::MakeFuncGraph(tupleSlicePtr, 2);
148 
149   AbstractBasePtrList eles;
150   auto tensor = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
151   size_t tuple_size = 6;
152   for (size_t i = 0; i < tuple_size; i++) {
153     eles.push_back(tensor);
154   }
155   auto tuple_tensor = std::make_shared<AbstractTuple>(eles);
156   auto start_index = std::make_shared<AbstractScalar>(static_cast<int64_t>(1));
157   auto stop_index = std::make_shared<AbstractScalar>(static_cast<int64_t>(6));
158   auto step = std::make_shared<AbstractScalar>(static_cast<int64_t>(2));
159   auto slice = std::make_shared<AbstractSlice>(start_index, stop_index, step);
160   AbstractBasePtrList args_spec_list = {tuple_tensor, slice};
161 
162   AbstractTuplePtr ret = dyn_cast<AbstractTuple>(engine_->Run(tupleSliceGraphPtr, args_spec_list).inferred->abstract());
163   if (ret == nullptr) {
164     FAIL() << "Cast ret to abstract tuple failed.";
165   }
166   size_t real = ret->size();
167   size_t expect = 3;
168   ASSERT_EQ(real, expect);
169 }
170 
TEST_F(TestComposite,test_TupleSlice_arg_slice_step_none)171 TEST_F(TestComposite, test_TupleSlice_arg_slice_step_none) {
172   MetaFuncGraphPtr tupleSlicePtr = std::make_shared<prim::TupleSlice>("tuple_slice");
173   FuncGraphPtr tupleSliceGraphPtr = UTCompositeUtils::MakeFuncGraph(tupleSlicePtr, 2);
174 
175   AbstractBasePtrList eles;
176   auto tensor = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
177   size_t tuple_size = 6;
178   for (size_t i = 0; i < tuple_size; i++) {
179     eles.push_back(tensor);
180   }
181   auto tuple_tensor = std::make_shared<AbstractTuple>(eles);
182   auto start_index = std::make_shared<AbstractScalar>(static_cast<int64_t>(1));
183   auto stop_index = std::make_shared<AbstractScalar>(static_cast<int64_t>(5));
184   auto step = std::make_shared<AbstractNone>();
185   auto slice = std::make_shared<AbstractSlice>(start_index, stop_index, step);
186   AbstractBasePtrList args_spec_list = {tuple_tensor, slice};
187 
188   AbstractTuplePtr ret = dyn_cast<AbstractTuple>(engine_->Run(tupleSliceGraphPtr, args_spec_list).inferred->abstract());
189   if (ret == nullptr) {
190     FAIL() << "Cast ret to abstract tuple failed.";
191   }
192   size_t real = ret->size();
193   size_t expect = 4;
194   ASSERT_EQ(real, expect);
195 }
196 
TEST_F(TestComposite,test_TupleSlice_arg_slice_step_negative)197 TEST_F(TestComposite, test_TupleSlice_arg_slice_step_negative) {
198   MetaFuncGraphPtr tupleSlicePtr = std::make_shared<prim::TupleSlice>("tuple_slice");
199   FuncGraphPtr tupleSliceGraphPtr = UTCompositeUtils::MakeFuncGraph(tupleSlicePtr, 2);
200 
201   AbstractBasePtrList eles;
202   auto tensor = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
203   size_t tuple_size = 6;
204   for (size_t i = 0; i < tuple_size; i++) {
205     eles.push_back(tensor);
206   }
207   auto tuple_tensor = std::make_shared<AbstractTuple>(eles);
208   auto start_index = std::make_shared<AbstractNone>();
209   auto stop_index = std::make_shared<AbstractNone>();
210   auto step = std::make_shared<AbstractScalar>(static_cast<int64_t>(-1));
211   auto slice = std::make_shared<AbstractSlice>(start_index, stop_index, step);
212   AbstractBasePtrList args_spec_list = {tuple_tensor, slice};
213 
214   AbstractTuplePtr ret = dyn_cast<AbstractTuple>(engine_->Run(tupleSliceGraphPtr, args_spec_list).inferred->abstract());
215   if (ret == nullptr) {
216     FAIL() << "Cast ret to abstract tuple failed.";
217   }
218   size_t real = ret->size();
219   size_t expect = 6;
220   ASSERT_EQ(real, expect);
221 }
222 
TEST_F(TestComposite,test_TupleSlice_arg_slice_step_positive)223 TEST_F(TestComposite, test_TupleSlice_arg_slice_step_positive) {
224   MetaFuncGraphPtr tupleSlicePtr = std::make_shared<prim::TupleSlice>("tuple_slice");
225   FuncGraphPtr tupleSliceGraphPtr = UTCompositeUtils::MakeFuncGraph(tupleSlicePtr, 2);
226 
227   AbstractBasePtrList eles;
228   auto tensor = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
229   size_t tuple_size = 6;
230   for (size_t i = 0; i < tuple_size; i++) {
231     eles.push_back(tensor);
232   }
233   auto tuple_tensor = std::make_shared<AbstractTuple>(eles);
234   auto start_index = std::make_shared<AbstractScalar>(static_cast<int64_t>(-2));
235   auto stop_index = std::make_shared<AbstractNone>();
236   auto step = std::make_shared<AbstractScalar>(static_cast<int64_t>(-1));
237   auto slice = std::make_shared<AbstractSlice>(start_index, stop_index, step);
238   AbstractBasePtrList args_spec_list = {tuple_tensor, slice};
239 
240   AbstractTuplePtr ret = dyn_cast<AbstractTuple>(engine_->Run(tupleSliceGraphPtr, args_spec_list).inferred->abstract());
241   if (ret == nullptr) {
242     FAIL() << "Cast ret to abstract tuple failed.";
243   }
244   size_t real = ret->size();
245   size_t expect = 5;
246   ASSERT_EQ(real, expect);
247 }
248 
TEST_F(TestComposite,test_UnpackCall_3args)249 TEST_F(TestComposite, test_UnpackCall_3args) {
250   MetaFuncGraphPtr unPackCallPtr = std::make_shared<prim::UnpackCall>("UnPackCall");
251   FuncGraphPtr unPackCallGraphPtr = UTCompositeUtils::MakeFuncGraph(unPackCallPtr, 3);
252 
253   auto fn_arg= std::make_shared<abstract::PrimitiveAbstractClosure>(prim::kPrimMakeTuple);
254   AbstractTensorPtr tensor = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
255   AbstractBasePtrList eles;
256   for (size_t i = 0; i < 6; i++) {
257     eles.push_back(tensor);
258   }
259   AbstractTuplePtr tensor_tuple = std::make_shared<AbstractTuple>(eles);
260   AbstractTensorPtr arr_x = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
261   AbstractTensorPtr arr_y = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
262   AbstractTensorPtr arr_z = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
263   std::vector<AbstractAttribute> tensor_map{{"x", arr_x}, {"y", arr_y}, {"z", arr_z}};
264   abstract::AbstractDictionaryPtr tensor_dict = std::make_shared<abstract::AbstractDictionary>(tensor_map);
265 
266   AbstractBasePtrList args_spec_list = {fn_arg, tensor_tuple, tensor_dict};
267   AbstractTuplePtr ret = dyn_cast<AbstractTuple>(engine_->Run(unPackCallGraphPtr, args_spec_list).inferred->abstract());
268   if (ret == nullptr) {
269     FAIL() << "Cast ret to abstract tuple failed.";
270   }
271   size_t real = ret->size();
272   size_t expect = 9;
273   ASSERT_EQ(real, expect);
274 }
275 
TEST_F(TestComposite,test_UnpackCall_5args)276 TEST_F(TestComposite, test_UnpackCall_5args) {
277   MetaFuncGraphPtr unPackCallPtr = std::make_shared<prim::UnpackCall>("UnPackCall");
278   FuncGraphPtr unPackCallGraphPtr = UTCompositeUtils::MakeFuncGraph(unPackCallPtr, 5);
279 
280   auto fn_arg = std::make_shared<abstract::PrimitiveAbstractClosure>(prim::kPrimMakeTuple);
281   AbstractTensorPtr tensor = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
282   AbstractBasePtrList eles;
283   for (size_t i = 0; i < 6; i++) {
284     eles.push_back(tensor);
285   }
286   AbstractTuplePtr tensor_tuple = std::make_shared<AbstractTuple>(eles);
287   AbstractTensorPtr arr_x = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
288   AbstractTensorPtr arr_y = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
289   AbstractTensorPtr arr_z = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
290   std::vector<AbstractAttribute> tensor_map{{"x", arr_x}, {"y", arr_y}, {"z", arr_z}};
291   abstract::AbstractDictionaryPtr tensor_dict = std::make_shared<abstract::AbstractDictionary>(tensor_map);
292 
293   AbstractBasePtrList args_spec_list = {fn_arg, tensor_dict, tensor_tuple, tensor_dict, tensor_tuple};
294   AbstractTuplePtr ret = dyn_cast<AbstractTuple>(engine_->Run(unPackCallGraphPtr, args_spec_list).inferred->abstract());
295   if (ret == nullptr) {
296     FAIL() << "Cast ret to abstract tuple failed.";
297   }
298   size_t real = ret->size();
299   size_t expect = 18;
300   ASSERT_EQ(real, expect);
301 }
302 
TEST_F(TestComposite,test_ZipOperation)303 TEST_F(TestComposite, test_ZipOperation) {
304   MetaFuncGraphPtr zip_op = std::make_shared<prim::ZipOperation>("zip_op");
305   FuncGraphPtr zip_op_graph = UTCompositeUtils::MakeFuncGraph(zip_op, 1);
306 
307   AbstractBasePtrList eles;
308   auto tensor = UTCompositeUtils::ArrayInt32Of({2, 3, 4});
309   size_t tuple_size = 3;
310   for (size_t i = 0; i < tuple_size; i++) {
311     eles.push_back(tensor);
312   }
313   auto tuple = std::make_shared<AbstractTuple>(eles);
314   AbstractBasePtrList args_spec_list = {tuple};
315 
316   AbstractTuplePtr ret = dyn_cast<AbstractTuple>(engine_->Run(zip_op_graph, args_spec_list).inferred->abstract());
317   if (ret == nullptr) {
318     FAIL() << "Cast ret to abstract tuple failed.";
319   }
320   size_t real = ret->size();
321   size_t expect = 3;
322   ASSERT_EQ(real, expect);
323 }
324 }  // namespace mindspore
325