• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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