Repository: deepjavalibrary/djl
Pull request #1435 (2021-12-27 17:42:13)

Update demo blockrunner example code
Change-Id: Icc136256c2cf23784e0b7758dd4c4e0932141b7d

## Description ##

Brief description of what this PR is about

- If this change is a backward incompatible change, why must this change be made?
- Interesting edge cases to note here



Patch:
diff --git a/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/jni/IValue.java b/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/jni/IValue.java
index 472c6bdde..45b5866d9 100644
--- a/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/jni/IValue.java
+++ b/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/jni/IValue.java
@@ -250,6 +250,9 @@ public class IValue extends NativeResource<Long> {
      * @return a new {@code IValue} of type {@code NDArray[]}
      */
     public static IValue listFrom(IValue... list) {
+        if (list.length == 0) {
+            throw new IllegalArgumentException("Empty IValue list is not supported.");
+        }
         long[] tensors = Arrays.stream(list).mapToLong(IValue::getHandle).toArray();
         return new IValue(PyTorchLibrary.LIB.iValueFromList(tensors));
     }
diff --git a/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/jni/IValueUtils.java b/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/jni/IValueUtils.java
index 41cb8f57c..91f728b9e 100644
--- a/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/jni/IValueUtils.java
+++ b/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/jni/IValueUtils.java
@@ -73,7 +73,7 @@ public final class IValueUtils {
                 });
     }
 
-    private static IValue[] getInputs(NDList ndList) {
+    static IValue[] getInputs(NDList ndList) {
         List<PairList<String, PtNDArray>> outputs = new ArrayList<>();
         Map<String, Integer> indexMap = new ConcurrentHashMap<>();
         for (NDArray array : ndList) {
@@ -87,6 +87,10 @@ public final class IValueUtils {
                 int index = addToMap(indexMap, name, outputs);
                 PairList<String, PtNDArray> pl = outputs.get(index);
                 pl.add("[]", (PtNDArray) array);
+            } else if (name != null && Pattern.matches("\\w+\\(\\)", name)) {
+                int index = addToMap(indexMap, name, outputs);
+                PairList<String, PtNDArray> pl = outputs.get(index);
+                pl.add("()", (PtNDArray) array);
             } else {
                 PairList<String, PtNDArray> pl = new PairList<>();
                 pl.add(null, (PtNDArray) array);
@@ -98,12 +102,16 @@ public final class IValueUtils {
             PairList<String, PtNDArray> pl = outputs.get(i);
             String key = pl.get(0).getKey();
             if (key == null) {
-                // not List, Dict input
+                // not List, Dict, Tuple input
                 ret[i] = IValue.from(pl.get(0).getValue());
             } else if ("[]".equals(key)) {
                 // list
                 PtNDArray[] arrays = pl.values().toArray(new PtNDArray[0]);
                 ret[i] = IValue.listFrom(arrays);
+            } else if ("()".equals(key)) {
+                // Tuple
+                IValue[] arrays = pl.values().stream().map(IValue::from).toArray(IValue[]::new);
+                ret[i] = IValue.tupleFrom(arrays);
             } else {
                 Map<String, PtNDArray> map = new ConcurrentHashMap<>();
                 for (Pair<String, PtNDArray> pair : pl) {
diff --git a/website/demo.html b/website/demo.html
index 0110f624e..2eb4b3d6f 100644
--- a/website/demo.html
+++ b/website/demo.html
@@ -150,7 +150,7 @@
                             <li>
                                 <div class="collapsible-header"><i class="material-icons">filter_drama</i>Run Inference with DJL</div>
                                 <div class="collapsible-body">
-                                    <script src="https://gist.github.com/lanking520/2eaaf3bba094b10aaffebd999bd4ae88.js"></script>
+                                    <script src="https://gist.github.com/frankfliu/550f284c0e990e123ba95915219a56ac.js"></script>
                                     <p>You can copy with the code snippet above to run inference with MXNet. You can also try to change the Model URL to run inference on PyTorch and TensorFlow:</p>
                                     <p>PyTorch: Please select <b>PyTorch</b> in the engine selection dropdown and uncomment the <b>second modelUrl</b>. </p>
                                     <p>TensorFlow: Please select <b>TensorFlow</b> in the engine selection dropdown and uncomment the <b>third modelUrl</b>. </p>
@@ -236,7 +236,7 @@
 <script src="https://djl.ai/website/js/init.js"></script>
 <script src="https://cdn.jsdelivr.net/npm/vue"></script>
 <script src="./js/index.js"></script>
-    
+
 <script src="https://cdnjs.cloudflare.com/ajax/libs/xterm/3.14.5/xterm.min.js"></script>
 <script src="https://djl.ai/website/js/terminal.js"></script>
 <script src="https://djl.ai/website/js/doodle_draw.js"></script>


Test patch:
diff --git a/engines/pytorch/pytorch-engine/src/test/java/ai/djl/pytorch/integration/IValueTest.java b/engines/pytorch/pytorch-engine/src/test/java/ai/djl/pytorch/integration/IValueTest.java
index bb4f78b38..eebf7a159 100644
--- a/engines/pytorch/pytorch-engine/src/test/java/ai/djl/pytorch/integration/IValueTest.java
+++ b/engines/pytorch/pytorch-engine/src/test/java/ai/djl/pytorch/integration/IValueTest.java
@@ -137,6 +137,7 @@ public class IValueTest {
                 NDList list = ivalue.toNDList(manager);
                 Assert.assertEquals(list.size(), 3);
             }
+            Assert.assertThrows(() -> IValue.listFrom(new IValue[0]));
 
             try (IValue iv1 = IValue.from(array1);
                     IValue iv2 = IValue.from(array2);
diff --git a/engines/pytorch/pytorch-engine/src/test/java/ai/djl/pytorch/jni/IValueUtilsTest.java b/engines/pytorch/pytorch-engine/src/test/java/ai/djl/pytorch/jni/IValueUtilsTest.java
new file mode 100644
index 000000000..85b2bc94a
--- /dev/null
+++ b/engines/pytorch/pytorch-engine/src/test/java/ai/djl/pytorch/jni/IValueUtilsTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
+ * with the License. A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0/
+ *
+ * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
+ * and limitations under the License.
+ */
+package ai.djl.pytorch.jni;
+
+import ai.djl.ndarray.NDList;
+import ai.djl.ndarray.NDManager;
+import ai.djl.ndarray.types.Shape;
+import ai.djl.pytorch.engine.PtNDArray;
+import ai.djl.pytorch.engine.PtNDManager;
+import java.util.Arrays;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class IValueUtilsTest {
+    @Test
+    public void getInputsTestTupleSyntax() {
+        try (PtNDManager manager = (PtNDManager) NDManager.newBaseManager()) {
+            PtNDArray array1 = (PtNDArray) manager.zeros(new Shape(1));
+            array1.setName("Test()");
+            PtNDArray array2 = (PtNDArray) manager.ones(new Shape(1));
+            array2.setName("Test()");
+            NDList input = new NDList(array1, array2);
+            input.attach(manager);
+
+            IValue[] iValues = IValueUtils.getInputs(input);
+            Assert.assertEquals(iValues.length, 1);
+            Assert.assertTrue(iValues[0].isTuple());
+            Assert.assertEquals(iValues[0].toIValueTuple().length, 2);
+
+            Arrays.stream(iValues).forEach(IValue::close);
+        }
+    }
+}
diff --git a/engines/pytorch/pytorch-engine/src/test/java/ai/djl/pytorch/jni/package-info.java b/engines/pytorch/pytorch-engine/src/test/java/ai/djl/pytorch/jni/package-info.java
new file mode 100644
index 000000000..cbf682843
--- /dev/null
+++ b/engines/pytorch/pytorch-engine/src/test/java/ai/djl/pytorch/jni/package-info.java
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
+ * with the License. A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0/
+ *
+ * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
+ * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
+ * and limitations under the License.
+ */
+/** The integration test for testing PyTorch specific features. */
+package ai.djl.pytorch.jni;