[locop] Define << operator and dependent class in the same namespace (#5800)
author박종현/On-Device Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Wed, 24 Jul 2019 07:08:47 +0000 (16:08 +0900)
committer오형석/On-Device Lab(SR)/Staff Engineer/삼성전자 <hseok82.oh@samsung.com>
Wed, 24 Jul 2019 07:08:47 +0000 (16:08 +0900)
The current implementation defines operator<< on loco::TensorShape
in anonymous namespace, which results in undefined behavior when it
is invoked from external libraries (such as pp).

This commit introduces FormattedTensorShape as a wrapper to mitigate
this undefined behavior.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
compiler/locop/src/FormattedGraph.cpp

index ef9ab4a..8645d87 100644 (file)
@@ -68,8 +68,30 @@ std::ostream &operator<<(std::ostream &os, const loco::Dimension &d)
   return os;
 }
 
-std::ostream &operator<<(std::ostream &os, const loco::TensorShape &shape)
+class FormattedTensorShape
 {
+public:
+  FormattedTensorShape(const loco::TensorShape *ptr) : _ptr{ptr}
+  {
+    // DO NOTHING
+  }
+
+public:
+  const loco::TensorShape &get(void) const { return *_ptr; }
+
+private:
+  const loco::TensorShape *_ptr;
+};
+
+inline FormattedTensorShape pretty(const loco::TensorShape &shape)
+{
+  return FormattedTensorShape{&shape};
+}
+
+std::ostream &operator<<(std::ostream &os, const FormattedTensorShape &f)
+{
+  const auto &shape = f.get();
+
   os << "[";
 
   if (shape.rank() > 0)
@@ -231,7 +253,7 @@ public:
     NodeDesc res{opname(node)};
 
     res.arg("from", symbol_lookup(*_symtbl, node->from()));
-    res.arg("shape", pp::fmt(tensor_shape(node)));
+    res.arg("shape", pp::fmt(pretty(tensor_shape(node))));
     res.state(NodeDesc::State::Complete);
 
     return res;
@@ -242,7 +264,7 @@ public:
     NodeDesc res{opname(node)};
 
     // TODO Print dtype
-    res.arg("shape", pp::fmt(tensor_shape(node)));
+    res.arg("shape", pp::fmt(pretty(tensor_shape(node))));
     res.state(NodeDesc::State::PartiallyKnown);
 
     return res;
@@ -263,7 +285,7 @@ public:
     NodeDesc res{opname(node)};
 
     // TODO Print data type
-    res.arg("shape", pp::fmt(tensor_shape(node)));
+    res.arg("shape", pp::fmt(pretty(tensor_shape(node))));
     res.state(NodeDesc::State::PartiallyKnown);
 
     return res;