1 /**
2 * Copyright 2021-2023 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
17 #ifndef MINDSPORE_CORE_IR_VALUE_H_
18 #define MINDSPORE_CORE_IR_VALUE_H_
19
20 #include <type_traits>
21 #include <algorithm>
22 #include <vector>
23 #include <string>
24 #include <memory>
25 #include <sstream>
26 #include <utility>
27 #include "base/base.h"
28 #include "ir/anf.h"
29 #include "ir/dtype.h"
30 #include "ir/scalar.h"
31 #include "ir/dtype/ref.h"
32 #include "utils/hashing.h"
33 #include "utils/ms_utils.h"
34
35 namespace mindspore {
36 /// \brief ValueSequence defines a Value class whose type is Sequence.
37 class MS_CORE_API ValueSequence : public Value {
38 public:
39 /// \brief ValueSequence display defines a Value class whose type is Sequence, such as Tuple.
40 ///
41 /// \param[in] elements Define the vector of elements of value.
ValueSequence(const ValuePtrList & elements)42 explicit ValueSequence(const ValuePtrList &elements) : elements_(elements) {
43 TypePtrList t_list;
44 (void)std::transform(elements.begin(), elements.end(), std::back_inserter(t_list), [](const ValuePtr &ele) {
45 MS_EXCEPTION_IF_NULL(ele);
46 return ele->type();
47 });
48 TypePtr t = std::make_shared<Tuple>(t_list);
49 type_ = t;
50 }
51
52 /// \brief ValueSequence defines a ValueNode whose type is Sequence.
53 ///
54 /// \param[in] elements Define the elements of value.
ValueSequence(const std::initializer_list<ValuePtr> & elements)55 ValueSequence(const std::initializer_list<ValuePtr> &elements) : elements_(elements.begin(), elements.end()) {
56 TypePtrList t_list;
57 (void)std::transform(elements_.begin(), elements_.end(), std::back_inserter(t_list), [](const ValuePtr &ele) {
58 MS_EXCEPTION_IF_NULL(ele);
59 return ele->type();
60 });
61 TypePtr t = std::make_shared<Tuple>(t_list);
62 type_ = t;
63 }
64 /// \brief Destructor of ValueSequence.
65 ~ValueSequence() override = default;
MS_DECLARE_PARENT(ValueSequence,Value)66 MS_DECLARE_PARENT(ValueSequence, Value)
67 /// \brief Get the Hash value of ValueSequence object.
68 ///
69 /// \return The hash value.
70 std::size_t hash() const override { return hash_combine(tid(), std::hash<std::size_t>{}(elements_.size())); }
71 /// \brief Get the element size of ValueSequence.
72 ///
73 /// \return The size of elements_.
size()74 std::size_t size() const { return elements_.size(); }
75 /// \brief Erase the elements in elements_ between 0 and idx.
76 ///
77 /// \param[in] idx Define the subscript of vector.
78 /// \return Whether the erase operation is successful.
79 bool erase(size_t idx);
80 /// \brief Access elements by subscript.
81 ///
82 /// \param[in] dim Define the subscript of vector.
83 /// \return The element whose subscript is dim.
84 const ValuePtr operator[](const std::size_t &dim) const;
85 /// \brief The value of ValueSequence object.
86 ///
87 /// \return The set of ValuePtr objects.
value()88 const ValuePtrList &value() const { return elements_; }
89 /// \brief Check whether the input is the current ValueSequence object.
90 ///
91 /// \param[in] other Define a Value object.
92 /// \return Whether the input is the current ValueSequence object.
93 bool operator==(const Value &other) const override;
94 /// \brief Compares two ValueSequence objects.
95 ///
96 /// \param[in] other Define a ValueSequence object.
97 /// \return Check whether the elements of the current object and the other object are the same.
98 bool operator==(const ValueSequence &other) const;
99 /// \brief Show each element ToString.
100 ///
101 /// \return The description of the ValueSequence object.
102 std::string ToString() const override;
103 /// \brief Show each element DumpText.
104 ///
105 /// \return The description of the ValueSequence object.
106 std::string DumpText() const override;
107
108 bool ContainsValueAny() const override;
109
110 protected:
111 ValuePtrList elements_;
112 };
113 using ValueSequencePtr = std::shared_ptr<ValueSequence>;
114
115 // For some old code in lite, still using typo names.
116 using ValueSequeue = ValueSequence;
117 using ValueSequeuePtr = ValueSequencePtr;
118
119 /// \brief ValueTuple defines a Value class whose type is Tuple.
120 class MS_CORE_API ValueTuple : public ValueSequence {
121 public:
122 /// \brief Constructor of ValueTuple.
123 ///
124 /// \param[in] elements Define the elements of the object.
ValueTuple(const std::vector<ValuePtr> & elements)125 explicit ValueTuple(const std::vector<ValuePtr> &elements) : ValueSequence(elements) {}
126 /// \brief Constructor of ValueTuple.
127 ///
128 /// \param[in] elements Define the elements of the object.
ValueTuple(const std::initializer_list<ValuePtr> & elements)129 ValueTuple(const std::initializer_list<ValuePtr> &elements) : ValueSequence(elements) {}
130 /// \brief Destructor of ValueTuple.
131 ~ValueTuple() override = default;
132 MS_DECLARE_PARENT(ValueTuple, ValueSequence)
133 /// \brief Get abstract of the ValueTuple object.
134 ///
135 /// \return The abstract of the ValueTuple object.
136 abstract::AbstractBasePtr ToAbstract() override;
137 /// \brief Show each element DumpText.
138 ///
139 /// \return The description of the ValueTuple object.
DumpText()140 std::string DumpText() const override { return "(" + ValueSequence::DumpText() + ")"; }
141 /// \brief Show each element ToString.
142 ///
143 /// \return The description of the ValueTuple object.
ToString()144 std::string ToString() const override { return "(" + ValueSequence::ToString() + ")"; }
145 };
146 using ValueTuplePtr = std::shared_ptr<ValueTuple>;
147
148 /// \brief ValueList defines a Value class whose type is List.
149 class MS_CORE_API ValueList : public ValueSequence {
150 public:
151 /// \brief Constructor of ValueList.
152 ///
153 /// \param[in] elements Define the elements of the object.
ValueList(const std::vector<ValuePtr> & elements)154 explicit ValueList(const std::vector<ValuePtr> &elements) : ValueSequence(elements) {}
155 /// \brief Constructor of ValueList.
156 ///
157 /// \param[in] elements Define the elements of the object.
ValueList(const std::initializer_list<ValuePtr> & elements)158 ValueList(const std::initializer_list<ValuePtr> &elements) : ValueSequence(elements) {}
159 /// \brief Destructor of ValueList.
160 ~ValueList() override = default;
161 MS_DECLARE_PARENT(ValueList, ValueSequence)
162 /// \brief Get abstract of the ValueList object.
163 ///
164 /// \return The abstract of the ValueList object.
165 abstract::AbstractBasePtr ToAbstract() override;
166 /// \brief Show each element DumpText.
167 ///
168 /// \return The description of the ValueList object.
DumpText()169 std::string DumpText() const override { return "[" + ValueSequence::DumpText() + "]"; }
170 /// \brief Show each element ToString.
171 ///
172 /// \return The description of the ValueList object.
ToString()173 std::string ToString() const override { return "[" + ValueSequence::ToString() + "]"; }
174 };
175 using ValueListPtr = std::shared_ptr<ValueList>;
MakeValue(const std::vector<ValuePtr> & v)176 inline ValuePtr MakeValue(const std::vector<ValuePtr> &v) { return std::make_shared<ValueTuple>(v); }
MakeValue(std::initializer_list<ValuePtr> v)177 inline ValuePtr MakeValue(std::initializer_list<ValuePtr> v) { return std::make_shared<ValueTuple>(v); }
178
179 template <typename T>
180 struct is_vector : public std::false_type {};
181 template <typename T, typename A>
182 struct is_vector<std::vector<T, A>> : public std::true_type {};
183
184 /// \brief Convert other type to ValueTuple.
185 ///
186 /// \param[in] vec Define the object to be converted.
187 /// \return ValuePtr a ValueTuple object.
188 template <typename T, typename U = typename std::enable_if<is_vector<T>::value, typename T::value_type>::type>
189 ValuePtr MakeValue(const T &vec) {
190 std::vector<ValuePtr> list;
191 (void)std::transform(vec.begin(), vec.end(), std::back_inserter(list), [](U ele) { return MakeValue(ele); });
192 return std::make_shared<ValueTuple>(list);
193 }
194
195 /// \brief ValueNamedTuple defines a Value class whose type is Tuple but the object is namedtuple.
196 class MS_CORE_API ValueNamedTuple : public ValueTuple {
197 public:
198 /// \brief Constructor of ValueNamedTuple.
199 ///
200 /// \param[in] elements Define the elements of the object.
201 ValueNamedTuple(const std::string &sub_class_name, const std::vector<ValuePtr> &keys,
202 const std::vector<ValuePtr> &values)
203 : ValueTuple(values), sub_class_name_(sub_class_name), keys_(keys) {}
204
205 /// \brief Destructor of ValueNamedTuple.
206 ~ValueNamedTuple() override = default;
207 MS_DECLARE_PARENT(ValueNamedTuple, ValueTuple)
208 // \brief Get abstract of the ValueNamedTuple object.
209 //
210 // \return The abstract of the ValueNamedTuple object.
211 abstract::AbstractBasePtr ToAbstract() override;
212 /// \brief Show the type name of namedtuple.
213 ///
214 /// \return The type name of the namedtuple object.
215 const std::string &sub_class_name() const { return sub_class_name_; }
216 /// \brief Show the label of namedtuple.
217 ///
218 /// \return The Label of the namedtuple object.
219 const std::vector<ValuePtr> &key() const { return keys_; }
220 /// \brief Show the ValueNamedTuple object.
221 ///
222 /// \return The description of the ValueNamedTuple object.
223 std::string ToString() const override;
224 /// \brief Show the ValueNamedTuple object DumpText.
225 ///
226 /// \return The description of the ValueNamedTuple object.
227 std::string DumpText() const override { return ToString(); }
228
229 bool ContainsValueAny() const override;
230
231 private:
232 std::string sub_class_name_;
233 std::vector<ValuePtr> keys_;
234 };
235 using ValueNamedTuplePtr = std::shared_ptr<ValueNamedTuple>;
236
237 /// \brief ValueSlice defines a Value class whose type is Slice.
238 class MS_CORE_API ValueSlice : public Value {
239 public:
240 /// \brief Constructor of ValueSlice.
241 ///
242 /// \param[in] start Define the start position of slice.
243 /// \param[in] stop Define the stop position of slice.
244 /// \param[in] step Define the space of slice.
245 ValueSlice(const ValuePtr &start, const ValuePtr &stop, const ValuePtr &step)
246 : start_(start), stop_(stop), step_(step) {}
247 /// \brief Destructor of ValueSlice.
248 ~ValueSlice() override = default;
249 MS_DECLARE_PARENT(ValueSlice, Value)
250 /// \brief Get the hash value of ValueSlice object.
251 ///
252 /// \return The hash value.
253 std::size_t hash() const override;
254 /// \brief Check whether the input is the current ValueSlice object.
255 ///
256 /// \param[in] other Define a Value object.
257 /// \return Whether the input is the current ValueSlice object.
258 bool operator==(const Value &other) const override;
259 /// \brief Compares two ValueSlice objects.
260 ///
261 /// \param[in] other Define a ValueSlice object.
262 /// \return Check whether the start, stop, step of the current object and the other object are the same.
263 bool operator==(const ValueSlice &other) const;
264 /// \brief Show the ValueSlice object ToString.
265 ///
266 /// \return The description of the ValueSlice object.
267 std::string ToString() const override;
268 /// \brief Get abstract of the ValueSlice object.
269 ///
270 /// \return The abstract of the ValueSlice object.
271 abstract::AbstractBasePtr ToAbstract() override;
272 /// \brief Show the ValueSlice object.
273 ///
274 /// \return The description of the ValueSlice object.
275 std::string DumpText() const override { return ToString(); }
276 /// \brief Get the start position of the slice object.
277 ///
278 /// \return The start position of the slice object.
279 ValuePtr start() const { return start_; }
280 /// \brief Get the stop position of the slice object.
281 ///
282 /// \return The stop position of the slice object.
283 ValuePtr stop() const { return stop_; }
284 /// \brief Get the step position of the slice object.
285 ///
286 /// \return The step position of the slice object.
287 ValuePtr step() const { return step_; }
288
289 bool ContainsValueAny() const override;
290
291 private:
292 ValuePtr start_;
293 ValuePtr stop_;
294 ValuePtr step_;
295 };
296 using ValueSlicePtr = std::shared_ptr<ValueSlice>;
297
298 /// \brief KeywordArg defines a Value class which has keyword.
299 class MS_CORE_API KeywordArg : public Value {
300 public:
301 /// \brief Constructor of KeywordArg.
302 ///
303 /// \param[in] key Define the key word.
304 /// \param[in] value Define the value associated with the keyword.
305 KeywordArg(const std::string &key, const ValuePtr &value) : key_(key), value_(value) {}
306 /// \brief Destructor of KeywordArg.
307 ~KeywordArg() override = default;
308 MS_DECLARE_PARENT(KeywordArg, Value)
309 /// \brief The hash value of the KeywordArg object.
310 ///
311 /// \return The hash value.
312 std::size_t hash() const override;
313 /// \brief Get key of the KeywordArg object.
314 ///
315 /// \return The key of the KeywordArg object.
316 std::string get_key() const { return key_; }
317 /// \brief Get value of the KeywordArg object.
318 ///
319 /// \return The value of the KeywordArg object.
320 ValuePtr get_value() const { return value_; }
321 /// \brief Check whether the input is the current KeywordArg object.
322 ///
323 /// \param[in] other Define a Value object.
324 /// \return Whether the input is the current KeywordArg object.
325 bool operator==(const Value &other) const override;
326 /// \brief Compares two KeywordArg objects.
327 ///
328 /// \param[in] other Define a KeywordArg object.
329 /// \return Check whether the key and value of the current object and the other object are the same.
330 bool operator==(const KeywordArg &other) const;
331 /// \brief Show the KeywordArg object.
332 ///
333 /// \return The description of the KeywordArg object.
334 std::string ToString() const override;
335 /// \brief Get abstract of the KeywordArg object.
336 ///
337 /// \return The abstract of the KeywordArg object.
338 abstract::AbstractBasePtr ToAbstract() override;
339 /// \brief Show the KeywordArg object DumpText.
340 ///
341 /// \return The description of the KeywordArg object.
342 std::string DumpText() const override { return ToString(); }
343
344 bool ContainsValueAny() const override { return value_->ContainsValueAny(); }
345
346 private:
347 std::string key_;
348 ValuePtr value_;
349 };
350 using KeywordArgPtr = std::shared_ptr<KeywordArg>;
351
352 /// \brief ValueDictionary defines a Value class whose type is Dictionary.
353 class MS_CORE_API ValueDictionary : public Value {
354 public:
355 /// \brief Constructor of ValueDictionary.
356 ///
357 /// \param[in] key_values Define the set of keys and values of Dictionary.
358 explicit ValueDictionary(const std::vector<std::pair<ValuePtr, ValuePtr>> &key_values) : key_values_(key_values) {}
359 /// \brief Destructor of ValueDictionary.
360 ~ValueDictionary() override = default;
361 MS_DECLARE_PARENT(ValueDictionary, Value)
362 /// \brief Get the hash value through key_values_ size.
363 ///
364 /// \return The hash value.
365 std::size_t hash() const override { return hash_combine(tid(), std::hash<std::size_t>{}(key_values_.size())); }
366 /// \brief Get the size of key_values_.
367 ///
368 /// \return The size of key_values_.
369 std::size_t size() const { return key_values_.size(); }
370 /// \brief 'operator[]' which can access value by key.
371 ///
372 /// \param[in] key Define the keyword.
373 /// \return The value associated with the keyword.
374 const ValuePtr operator[](const ValuePtr &key) const;
375 /// \brief The value of ValueDictionary object.
376 ///
377 /// \return The value of ValueDictionary object.
378 const std::vector<std::pair<ValuePtr, ValuePtr>> &value() const { return key_values_; }
379 /// \brief Check whether the input is the current ValueDictionary object.
380 ///
381 /// \param[in] other Define a Value object.
382 /// \return Whether the input is the current ValueDictionary object.
383 bool operator==(const Value &other) const override;
384 /// \brief Compares two ValueDictionary objects.
385 ///
386 /// \param[in] other Define a ValueDictionary object.
387 /// \return Check whether the keys and values of the current object and the other object are the same.
388 bool operator==(const ValueDictionary &other) const;
389 /// \brief Show the ValueDictionary object.
390 ///
391 /// \return The description of the ValueDictionary object.
392 std::string ToString() const override {
393 std::ostringstream buffer;
394 buffer << "{";
395 size_t index = 0;
396 for (const auto &kv : key_values_) {
397 // Only supports the key as string type currently.
398 ValuePtr key = kv.first;
399 ValuePtr value = kv.second;
400 MS_EXCEPTION_IF_NULL(key);
401 MS_EXCEPTION_IF_NULL(value);
402 buffer << "'" << key->ToString() << "': " << value->ToString();
403 if (index != key_values_.size() - 1) {
404 buffer << ", ";
405 }
406 index++;
407 }
408 buffer << "}";
409 return buffer.str();
410 }
411 /// \brief Get abstract of the ValueDictionary object.
412 ///
413 /// \return The abstract of the ValueDictionary object.
414 abstract::AbstractBasePtr ToAbstract() override;
415 /// \brief Show the ValueDictionary object DumpText.
416 ///
417 /// \return The description of the ValueDictionary object.
418 std::string DumpText() const override { return ToString(); }
419
420 bool ContainsValueAny() const override;
421
422 private:
423 std::vector<std::pair<ValuePtr, ValuePtr>> key_values_;
424 };
425 using ValueDictionaryPtr = std::shared_ptr<ValueDictionary>;
426
427 /// \brief StringImm defines a Value class whose type is String.
428 class MS_CORE_API StringImm : public Value {
429 public:
430 /// \brief Constructor of StringImm.
431 ///
432 /// \param[in] str Define the string.
433 explicit StringImm(const std::string &str) noexcept
434 : Value(kString), str_(str), hash_(std::hash<std::string>{}(str_)) {}
435 /// \brief Destructor of StringImm.
436 ~StringImm() override = default;
437 MS_DECLARE_PARENT(StringImm, Value)
438 /// \brief The hash value of the StringImm object.
439 ///
440 /// \return The hash value.
441 std::size_t hash() const override { return hash_; }
442 /// \brief Get the value of StringImm object.
443 ///
444 /// \return The value of StringImm object.
445 virtual const std::string &value() const { return str_; }
446 /// \brief Check whether the input is the current StringImm object.
447 ///
448 /// \param[in] other Define a Value object.
449 /// \return Whether the input is the current StringImm object.
450 bool operator==(const Value &other) const override;
451 /// \brief Compares two StringImm objects.
452 ///
453 /// \param[in] other Define a StringImm object.
454 /// \return Check whether the string of the current object and the other object are the same.
455 bool operator==(const StringImm &other) const;
456 /// \brief Get abstract of the StringImm object.
457 ///
458 /// \return The abstract of the StringImm object.
459 abstract::AbstractBasePtr ToAbstract() override;
460 /// \brief Show the StringImm object.
461 ///
462 /// \return The description of the StringImm object.
463 std::string ToString() const override { return str_; }
464 /// \brief Show the StringImm object DumpText.
465 ///
466 /// \return The description of the StringImm object.
467 std::string DumpText() const override {
468 std::ostringstream oss;
469 oss << "\"" << str_ << "\"";
470 return oss.str();
471 }
472
473 private:
474 std::string str_;
475 std::size_t hash_ = 0;
476 };
477 using StringImmPtr = std::shared_ptr<StringImm>;
478 IMM_TRAITS(StringImmPtr, std::string)
479 IMM_TRAITS(StringImmPtr, const char *)
480
481 /// \brief RefKey defines a class whose real type is String.
482 /// \brief Notice: RefKey is keep for compatible only, we use RefKey just as StringImm.
483 class MS_CORE_API RefKey final : public StringImm {
484 public:
485 /// \brief Constructor of RefKey.
486 ///
487 /// \param[in] str Define the string value of RefKey object.
488 explicit RefKey(const std::string &str) : StringImm(str) {}
489 /// \brief Destructor of RefKey.
490 ~RefKey() override = default;
491 MS_DECLARE_PARENT(RefKey, StringImm)
492
493 abstract::AbstractBasePtr ToAbstract() override {
494 MS_LOG(INTERNAL_EXCEPTION) << "RefKey can't be converted to abstract, ref_key: " << ToString();
495 }
496 };
497 using RefKeyPtr = std::shared_ptr<RefKey>;
498
499 /// \brief ValueAny defines a Value class which can be any Value type.
500 class MS_CORE_API ValueAny final : public Value {
501 public:
502 /// \brief Constructor of ValueAny.
503 ValueAny() = default;
504 /// \brief Destructor of ValueAny.
505 ~ValueAny() override = default;
506 MS_DECLARE_PARENT(ValueAny, Value)
507 /// \brief The hash value of the ValueAny object.
508 ///
509 /// \return The hash value.
510 std::size_t hash() const override { return tid(); }
511 /// \brief Check whether the input is the current ValueAny object.
512 ///
513 /// \param[in] other Define a Value object.
514 /// \return Whether the input is the current ValueAny object.
515 bool operator==(const Value &other) const override;
516 /// \brief Get abstract of the ValueAny object.
517 ///
518 /// \return The abstract of the ValueAny object.
519 abstract::AbstractBasePtr ToAbstract() override;
520
521 bool ContainsValueAny() const override { return true; }
522 };
523
524 GVAR_DEF(ValuePtr, kValueAny, std::make_shared<ValueAny>());
525
526 enum ValueProblemType : int { kDead = 0, kPoly = 1, kUndefined = 2 };
527
528 /// \brief ValueProblem defines a class for DeadNode and PolyNode.
529 class MS_CORE_API ValueProblem final : public Value {
530 public:
531 /// \brief Constructor of ValueProblem.
532 ///
533 /// \param[in] err_type Define the error value type.
534 explicit ValueProblem(ValueProblemType err_type) : err_type_(err_type) {}
535 /// \brief Destructor of RefKey.
536 ~ValueProblem() override = default;
537 MS_DECLARE_PARENT(ValueProblem, Value)
538 /// \brief The hash value of the ValueProblem object.
539 ///
540 /// \return The hash value.
541 std::size_t hash() const override { return tid(); }
542 /// \brief Check whether the input is the current ValueProblem object.
543 ///
544 /// \param[in] other Define a Value object.
545 /// \return Whether the input is the current ValueProblem object.
546 bool operator==(const Value &other) const override;
547 /// \brief Check whether the input is the current ValueProblem object.
548 ///
549 /// \param[in] other Define a ValueProblem object.
550 /// \return Whether the input is the current ValueProblem object.
551 bool operator==(const ValueProblem &other) const;
552 /// \brief Get abstract of the ValueProblem object.
553 ///
554 /// \return The abstract of the ValueProblem object.
555 abstract::AbstractBasePtr ToAbstract() override {
556 MS_LOG(INTERNAL_EXCEPTION) << "ValueProblem(" << ToString() << ") can't be converted to abstract.";
557 }
558 /// \brief Check whether the value belongs to DeadNode.
559 ///
560 /// \return Whether the value belongs to DeadNode.
561 bool IsDead() const { return err_type_ == kDead; }
562 /// \brief Check whether the value belongs to PolyNode.
563 ///
564 /// \return Whether the value belongs to PolyNode.
565 bool IsPoly() const { return err_type_ == kPoly; }
566 /// \brief Check whether the value belongs to UndefinedNode.
567 ///
568 /// \return Whether the value belongs to UndefinedNode.
569 bool IsUndefined() const { return err_type_ == kUndefined; }
570 /// \brief Show the ValueProblem object.
571 ///
572 /// \return The description of the ValueProblem object.
573 std::string ToString() const override {
574 if (IsDead()) {
575 return "DeadNode";
576 } else if (IsPoly()) {
577 return "PolyNode";
578 } else {
579 return "UndefinedNode";
580 }
581 }
582
583 private:
584 ValueProblemType err_type_{kDead};
585 };
586 using ValueProblemPtr = std::shared_ptr<ValueProblem>;
587
588 /// \brief Monad defines a Value class which is used in side effect.
589 class MS_CORE_API Monad : public Value {
590 public:
591 /// \brief Destructor of Monad.
592 ~Monad() override = default;
593 MS_DECLARE_PARENT(Monad, Value)
594 /// \brief Get abstract of the Monad object.
595 ///
596 /// \return The abstract of the Monad object.
597 abstract::AbstractBasePtr ToAbstract() override = 0;
598
599 protected:
600 /// \brief Constructor of Monad.
601 ///
602 /// \param[in] type Define the type of Monad object.
603 explicit Monad(const TypePtr &type) : Value(type) {}
604 };
605
606 /// \brief UMonad defines a Value class which related to memory side effect.
607 class MS_CORE_API UMonad final : public Monad {
608 public:
609 /// \brief Constructor of UMonad.
610 UMonad() : Monad(kUMonadType) {}
611 /// \brief Destructor of UMonad.
612 ~UMonad() override = default;
613 MS_DECLARE_PARENT(UMonad, Monad)
614 /// \brief The hash value of the UMonad object.
615 ///
616 /// \return The hash value.
617 std::size_t hash() const override { return tid(); }
618 /// \brief Check whether the input is UMonad object.
619 ///
620 /// \param[in] other Define a Value object.
621 /// \return Whether the input is UMonad object.
622 bool operator==(const Value &other) const override;
623 /// \brief Get abstract of the UMonad object.
624 ///
625 /// \return The abstract of the UMonad object.
626 abstract::AbstractBasePtr ToAbstract() override;
627 /// \brief Show the UMonad object.
628 ///
629 /// \return The description of the UMonad object.
630 std::string ToString() const override { return "U"; }
631 };
632 using UMonadPtr = std::shared_ptr<UMonad>;
633 MS_CORE_API extern const ValuePtr kUMonad;
634
635 /// \brief IOMonad defines a Value class which related to IO side effect.
636 class MS_CORE_API IOMonad final : public Monad {
637 public:
638 /// \brief Constructor of IOMonad.
639 IOMonad() : Monad(kIOMonadType) {}
640 /// \brief Destructor of IOMonad.
641 ~IOMonad() override = default;
642 MS_DECLARE_PARENT(IOMonad, Monad)
643 /// \brief The hash value of the UMonad object.
644 ///
645 /// \return The hash value.
646 std::size_t hash() const override { return tid(); }
647 /// \brief Check whether the input is IOMonad object.
648 ///
649 /// \param[in] other Define a Value object.
650 /// \return Whether the input is IOMonad object.
651 bool operator==(const Value &other) const override;
652 /// \brief Get abstract of the IOMonad object.
653 ///
654 /// \return The abstract of the IOMonad object.
655 abstract::AbstractBasePtr ToAbstract() override;
656 /// \brief Show the IOMonad object.
657 ///
658 /// \return The description of the IOMonad object.
659 std::string ToString() const override { return "IO"; }
660 };
661 using IOMonadPtr = std::shared_ptr<IOMonad>;
662 MS_CORE_API extern const ValuePtr kIOMonad;
663
664 template <>
665 inline const char *GetValue(const ValuePtr &value) {
666 MS_EXCEPTION_IF_NULL(value);
667 auto imm = value->cast<StringImmPtr>();
668 if (imm == nullptr) {
669 MS_LOG(INTERNAL_EXCEPTION) << "GetValue:" << value->ToString() << ", Type:" << value->type_name();
670 }
671 return common::SafeCStr(imm->value());
672 }
673
674 template <typename T, typename S = typename std::decay<T>::type,
675 typename U = typename std::enable_if<is_vector<S>::value, typename S::value_type>::type>
676 std::vector<U> GetValue(const ValuePtr &value) {
677 MS_EXCEPTION_IF_NULL(value);
678
679 if (!value->isa<ValueSequence>()) {
680 MS_LOG(INTERNAL_EXCEPTION) << "Error GetValue for value: " << value->ToString() << ", type: vector<"
681 << typeid(U).name() << ">";
682 }
683 std::vector<U> rets;
684 const std::vector<ValuePtr> &vals = value->cast<ValueSequencePtr>()->value();
685 (void)std::transform(vals.begin(), vals.end(), std::back_inserter(rets),
686 [](const ValuePtr &v) { return GetValue<U>(v); });
687 return rets;
688 }
689
690 inline ValueNodePtr NewValueNode(const ValuePtr &t) { return std::make_shared<ValueNode>(t); }
691
692 inline ValueNodePtr NewValueNode(const ValuePtr &t, NodeDebugInfoPtr &&debug_info) {
693 return std::make_shared<ValueNode>(t, std::move(debug_info));
694 }
695
696 template <typename T, typename _ = typename std::enable_if<!std::is_base_of<Value, T>::value>::type>
697 inline ValueNodePtr NewValueNode(const std::shared_ptr<T> &x) {
698 return NewValueNode(MakeValue(x));
699 }
700
701 template <typename T, typename _ = typename std::enable_if<!is_shared_ptr<T>::value>::type>
702 inline ValueNodePtr NewValueNode(const T &x) {
703 return NewValueNode(MakeValue(x));
704 }
705 } // namespace mindspore
706
707 #endif // MINDSPORE_CORE_IR_VALUE_H_
708