[enco] Do NOT reduce identical objects with side effect (#2419)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Tue, 27 Nov 2018 02:35:44 +0000 (11:35 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Tue, 27 Nov 2018 02:35:44 +0000 (11:35 +0900)
* [enco] Do NOT reduce identical objects with side effect

Update on one object may have a side effect through its backing bag. So,
reduction in identical objects with side effect results in incorrect
compilation artifact.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
* Update the examples in the comment

contrib/enco/core/src/Transforms/IdenticalObjectReduction.cpp
contrib/enco/test/tflite/Regression_0001/INFERENCE [new file with mode: 0644]
contrib/enco/test/tflite/Regression_0001/test.recipe [new file with mode: 0644]

index 12cbb6c..03df6ec 100644 (file)
@@ -77,6 +77,50 @@ void reduce_identical_object(enco::Code *code)
       continue;
     }
 
+    if (ofm->bag()->reads()->size() > 0)
+    {
+      // Let us consider the following code:
+      //
+      // Bag:
+      //   %bag_0 = Bag(...)
+      //   %bag_1 = Bag(...)
+      //   %bag_2 = Bag(...)
+      //
+      // Object:
+      //   %obj_0 = FeatureObject(bag: %bag_0)
+      //   %obj_1 = FeatureObject(bag: %bag_1)
+      //
+      // Instr:
+      //   copy an object from %obj_0 into %obj_1
+      //   shuffle values from %bag_1 into %bag_2
+      //   eval Conv2D with %obj_1
+      //
+      // Identical Object Reduction (IOR) tries to eliminate the first copy via
+      // substitution (substitute all the occurrence of %obj_1 as use with %obj_0).
+      //
+      // Here is the code transformed by IOR:
+      //
+      // Bag:
+      //   %bag_0 = Bag(...)
+      //   %bag_1 = Bag(...)
+      //   %bag_2 = Bag(...)
+      //
+      // Object:
+      //   %obj_0 = FeatureObject(bag: %bag_0)
+      //   %obj_1 = FeatureObject(bag: %bag_1)
+      //
+      // Instr:
+      //   shuffle values from %bag_1 into %bag_2
+      //   eval Conv2D with %obj_0
+      //
+      // Note that there is no updater of %bag_1 after IOR, and thus the behavior
+      // of the first shuffle instruction has changed.
+      //
+      // This examples shows that it is impossible to simply substitute %obj_1
+      // with %obj_0 in the presence of readers over its backing bag.
+      continue;
+    }
+
     subst(copy->into(), copy->from());
 
     copy->detach();
diff --git a/contrib/enco/test/tflite/Regression_0001/INFERENCE b/contrib/enco/test/tflite/Regression_0001/INFERENCE
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/contrib/enco/test/tflite/Regression_0001/test.recipe b/contrib/enco/test/tflite/Regression_0001/test.recipe
new file mode 100644 (file)
index 0000000..e6f4eca
--- /dev/null
@@ -0,0 +1,50 @@
+operand {
+  name: "ifm"
+  type: FLOAT32
+  shape { dim: 1 dim: 3 dim: 3 dim: 2 }
+}
+operand {
+  name: "ker"
+  type: FLOAT32
+  shape { dim: 1 dim: 1 dim: 1 dim: 2 }
+  filler { tag: "gaussian" arg: "0.0" arg: "1.0" }
+}
+operand {
+  name: "bias"
+  type: FLOAT32
+  shape { dim: 1 }
+  filler { tag: "gaussian" arg: "0.0" arg: "1.0" }
+}
+operand {
+  name: "ofm"
+  type: FLOAT32
+  shape { dim: 1 dim: 3 dim: 3 dim: 1 }
+}
+operand {
+  name: "arr"
+  type: FLOAT32
+  shape { dim: 1 dim: 9 }
+}
+operand {
+  name: "shape"
+  type: INT32
+  shape { dim: 2 }
+  filler { tag: "explicit" arg: "-1" arg: "9" }
+}
+operation {
+  type: "Conv2D"
+  conv2d_options { padding: VALID stride_w: 1 stride_h: 1 activation: RELU6 }
+  input: "ifm"
+  input: "ker"
+  input: "bias"
+  output: "ofm"
+}
+operation {
+  type: "Reshape"
+  input: "ofm"
+  input: "shape"
+  output: "arr"
+  reshape_options { new_shape: [-1, 9] }
+}
+input: "ifm"
+output: "arr"