Repository: deepjavalibrary/djl
Pull request #2688 (2023-07-02 18:30:03)

Fixes rrror message in X.dot(w)
https://github.com/deepjavalibrary/djl/issues/2685

juliangamble: This is awesome. Thankyou. 

Patch:
diff --git a/.github/workflows/nightly_publish.yml b/.github/workflows/nightly_publish.yml
index cd6141a12..0a51c3d53 100644
--- a/.github/workflows/nightly_publish.yml
+++ b/.github/workflows/nightly_publish.yml
@@ -122,46 +122,6 @@ jobs:
           ./gradlew :integration:test "-Dai.djl.default_engine=OnnxRuntime"
           ./gradlew :integration:clean
 
-  test-cuda-102:
-    if: github.repository == 'deepjavalibrary/djl'
-    runs-on: [ self-hosted, gpu ]
-    container:
-      image: nvidia/cuda:10.2-cudnn8-runtime-ubuntu18.04
-      options: --gpus all --runtime=nvidia
-      env:
-        DJL_CACHE_DIR: /root/.djl.ai
-    timeout-minutes: 30
-    needs: create-runners
-    steps:
-      - name: Setup Environment
-        run: |
-          apt-get update
-          apt-get install -y software-properties-common wget locales libgomp1
-          locale-gen en_US.UTF-8
-      - uses: actions/checkout@v3
-      - name: Set up JDK 11
-        uses: actions/setup-java@v3
-        with:
-          java-version: 11
-          distribution: corretto
-      - uses: actions/cache@v3
-        with:
-          path: ~/.gradle/caches
-          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
-          restore-keys: |
-            ${{ runner.os }}-gradle-
-      - name: Test with Gradle
-        run: |
-          export PADDLE_VERSION=$(cat gradle.properties | awk -F '=' '/paddlepaddle_version/ {print $2}')
-          ./gradlew :integration:test
-          ./gradlew :integration:clean :integration:test -Dai.djl.default_engine=OnnxRuntime
-          ./gradlew :engines:mxnet:mxnet-model-zoo:test
-          ./gradlew :engines:pytorch:pytorch-model-zoo:test
-          ./gradlew :engines:onnxruntime:onnxruntime-engine:test
-          mkdir -p /root/.djl.ai/paddle/${PADDLE_VERSION}-cu102-linux-x86_64
-          LD_LIBRARY_PATH=/root/.djl.ai/paddle/${PADDLE_VERSION}-cu102-linux-x86_64:/usr/local/cuda/lib64 \
-          ./gradlew :engines:paddlepaddle:paddlepaddle-model-zoo:test
-
   test-cuda-118:
     if: github.repository == 'deepjavalibrary/djl'
     runs-on: [ self-hosted, gpu ]
@@ -203,7 +163,7 @@ jobs:
   publish:
     if: github.repository == 'deepjavalibrary/djl'
     runs-on: ubuntu-latest
-    needs: [ build, test-pytorch, test-tensorflow, test-aarch64, test-cuda-102, test-cuda-118 ]
+    needs: [ build, test-pytorch, test-tensorflow, test-aarch64, test-cuda-118 ]
     steps:
       - uses: actions/checkout@v3
       - name: Set up JDK 11
@@ -284,7 +244,7 @@ jobs:
   stop-runners:
     if: ${{ github.repository == 'deepjavalibrary/djl' && always() }}
     runs-on: [ self-hosted, scheduler ]
-    needs: [ create-runners, test-aarch64, test-cuda-102, test-cuda-118 ]
+    needs: [ create-runners, test-aarch64, test-cuda-118 ]
     steps:
       - name: Stop all instances
         run: |
diff --git a/api/src/main/java/ai/djl/modality/cv/output/BoundingBox.java b/api/src/main/java/ai/djl/modality/cv/output/BoundingBox.java
index e07627e75..3e582f463 100644
--- a/api/src/main/java/ai/djl/modality/cv/output/BoundingBox.java
+++ b/api/src/main/java/ai/djl/modality/cv/output/BoundingBox.java
@@ -41,7 +41,7 @@ public interface BoundingBox extends Serializable {
     Point getPoint();
 
     /**
-     * Gets the Intersection over Union (IoU) value between bounding boxes.
+     * Returns the Intersection over Union (IoU) value between bounding boxes.
      *
      * <p>Also known as <a href="https://en.wikipedia.org/wiki/Jaccard_index">Jaccard index</a>
      *
diff --git a/api/src/main/java/ai/djl/modality/cv/output/Rectangle.java b/api/src/main/java/ai/djl/modality/cv/output/Rectangle.java
index caad442f2..92afc6032 100644
--- a/api/src/main/java/ai/djl/modality/cv/output/Rectangle.java
+++ b/api/src/main/java/ai/djl/modality/cv/output/Rectangle.java
@@ -86,15 +86,26 @@ public class Rectangle implements BoundingBox {
     /** {@inheritDoc} */
     @Override
     public double getIoU(BoundingBox box) {
-        Rectangle rec = (Rectangle) box;
-        // caculate intesection lrtb
-        double left = Math.max(getX(), rec.getX());
-        double top = Math.max(getY(), rec.getY());
-        double right = Math.min(getX() + getWidth(), rec.getX() + rec.getWidth());
-        double bottom = Math.min(getY() + getHeight(), rec.getY() + rec.getHeight());
-        double intersection = (right - left) * (bottom - top);
-        return intersection
-                / (getWidth() * getHeight() + rec.getWidth() * rec.getHeight() - intersection);
+        Rectangle rect = box.getBounds();
+
+        // computing area of each rectangles
+        double s1 = (width + 1) * (height + 1);
+        double s2 = (rect.getWidth() + 1) * (rect.getHeight() + 1);
+        double sumArea = s1 + s2;
+
+        // find each edge of intersect rectangle
+        double left = Math.max(getX(), rect.getX());
+        double top = Math.max(getY(), rect.getY());
+        double right = Math.min(getX() + getWidth(), rect.getX() + rect.getWidth());
+        double bottom = Math.min(getY() + getHeight(), rect.getY() + rect.getHeight());
+
+        // judge if there is a intersect
+        if (left > right || top > bottom) {
+            return 0.0;
+        }
+
+        double intersect = (right - left + 1) * (bottom - top + 1);
+        return intersect / (sumArea - intersect);
     }
 
     /**
diff --git a/docs/pytorch/pytorch-djl-ndarray-cheatsheet.md b/docs/pytorch/pytorch-djl-ndarray-cheatsheet.md
index b0760b6eb..7416ec50b 100644
--- a/docs/pytorch/pytorch-djl-ndarray-cheatsheet.md
+++ b/docs/pytorch/pytorch-djl-ndarray-cheatsheet.md
@@ -58,7 +58,7 @@ tensor.tensor(a)
 ```
 
 ```
-float[][] array = {{1, 2, 3}, {4, 5, 6}};
+float[][] array = { {1, 2, 3}, {4, 5, 6} };
 NDArray nd = manager.create(array);
 ```
 
@@ -107,7 +107,7 @@ torch.zeros_like(a)
 NDArray ones = manager.ones(new Shape(1, 2, 3));
 NDarray zeros = manager.zeros(new Shape(1, 2, 3));
 
-NDArray a = manager.create(new float[][] {{1, 2, 3}, {4, 5, 6}});
+NDArray a = manager.create(new float[][] { {1, 2, 3}, {4, 5, 6} });
 ones = a.onesLike();
 zeros= a.zerosLike();
 ```
@@ -125,7 +125,7 @@ torch.tensor(a, requires_grad=True, dtype=float)
 ```
 
 ```
-NDArray a = manager.create(new float[][] {{1, 2, 3}, {4, 5, 6}});
+NDArray a = manager.create(new float[][] { {1, 2, 3}, {4, 5, 6} });
 a.setRequiresGradient(true);
 a
 ```
@@ -587,7 +587,7 @@ a.T
 Java
 
 ```
-var a = manager.create(new float[][] {{1, 2}, {3, 4}});
+var a = manager.create(new float[][] { {1, 2}, {3, 4} });
 a.transpose();
 ```
 
@@ -683,7 +683,7 @@ ND: (3) cpu() int32
 </details>
 
 ```
-var indices = manager.create(new int[][] {{2, 4}, {6, 8}});
+var indices = manager.create(new int[][] { {2, 4}, {6, 8} });
 a.get(indices);
 ```
 
@@ -705,7 +705,7 @@ ND: (2, 2) cpu() int32
 ### multi-dimension ndarray slice
 
 ```
-var a = manager.create(new int[][] {{5, 10, 20}, {30, 40, 50}, {60, 70, 80}});
+var a = manager.create(new int[][] { {5, 10, 20}, {30, 40, 50}, {60, 70, 80} });
 ```
 
 ---
@@ -1028,8 +1028,8 @@ ND: (2, 6) cpu() float32
 #### stack
 
 ```
-var images0 = manager.create(new int[][] {{128, 0, 0}, {0, 128, 0}});
-var images1 = manager.create(new int[][] {{0, 0, 128}, {127, 127, 127}});
+var images0 = manager.create(new int[][] { {128, 0, 0}, {0, 128, 0} });
+var images1 = manager.create(new int[][] { {0, 0, 128}, {127, 127, 127} });
 ```
 
 ```
@@ -1198,7 +1198,7 @@ torch.abs(tensor)
 ```
 
 ```
-var ndarray = manager.create(new int[][] {{1, 2}, {-1, -2}});
+var ndarray = manager.create(new int[][] { {1, 2}, {-1, -2} });
 ndarray.abs();
 ```
 
@@ -1226,7 +1226,7 @@ torch.ceil(tensor)
 ```
 
 ```
-var ndarray = manager.create(new double[][] {{1.0,1.1,1.2,1.3,1.4}, {1.5,1.6,1.7,1.8,1.9});
+var ndarray = manager.create(new double[][] { {1.0,1.1,1.2,1.3,1.4}, {1.5,1.6,1.7,1.8,1.9} });
 ndarray.ceil();
 ```
 
@@ -1254,7 +1254,7 @@ torch.floor(tensor)
 ```
 
 ```
-var ndarray = manager.create(new double[][] {{1.0,1.1,1.2,1.3,1.4}, {1.5,1.6,1.7,1.8,1.9});
+var ndarray = manager.create(new double[][] { {1.0,1.1,1.2,1.3,1.4}, {1.5,1.6,1.7,1.8,1.9} });
 ndarray.floor();
 ```
 
@@ -1282,7 +1282,7 @@ torch.round(tensor)
 ```
 
 ```
-var ndarray = manager.create(new double[][] {{1.0,1.1,1.2,1.3,1.4}, {1.5,1.6,1.7,1.8,1.9}});
+var ndarray = manager.create(new double[][] { {1.0,1.1,1.2,1.3,1.4}, {1.5,1.6,1.7,1.8,1.9} });
 ndarray.round();
 ```
 
@@ -1310,7 +1310,7 @@ torch.sign(tensor)
 ```
 
 ```
-var ndarray = manager.create(new double[][] {{-0.1, -0.0}, {0.0, 0.1});
+var ndarray = manager.create(new double[][] { {-0.1, -0.0}, {0.0, 0.1} });
 ndarray.sign();
 ```
 
@@ -1440,7 +1440,7 @@ torch.nonzero()
 ```
 
 ```
-var a = manager.create(new long[][] {{0.0,0.1}, {0.2,0.3}});
+var a = manager.create(new long[][] { {0.0,0.1}, {0.2,0.3} });
 a.nonzero();
 ```
 
@@ -1482,8 +1482,8 @@ torch.masked_select(t, mask)
 ```
 
 ```
-var ndarray = manager.create(new double[][] {{0.1, 0.2}, {0.3, 0.4}});
-var mask = manager.create(new boolean[][] {false, true}, {true,false}});
+var ndarray = manager.create(new double[][] { {0.1, 0.2}, {0.3, 0.4} });
+var mask = manager.create(new boolean[][] { {false, true}, {true,false} });
 ndarray.booleanMask(mask);
 ```
 
diff --git a/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/engine/PtNDArray.java b/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/engine/PtNDArray.java
index 65e0fb1b5..14195d17b 100644
--- a/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/engine/PtNDArray.java
+++ b/engines/pytorch/pytorch-engine/src/main/java/ai/djl/pytorch/engine/PtNDArray.java
@@ -1351,8 +1351,9 @@ public class PtNDArray extends NativeResource<Long> implements NDArray {
         int otherDim = other.getShape().dimension();
         if (selfDim != otherDim || selfDim > 2) {
             throw new UnsupportedOperationException(
-                    "Dimension mismatch or high dimensional dot operation is not supported. Please"
-                            + " use .matMul instead.");
+                    "Dimension mismatch or dimension is greater than 2.  Dot product is only"
+                            + " applied on two 1D vectors. For high dimensions, please use .matMul"
+                            + " instead.");
         }
         return JniUtils.dot(this, manager.from(other));
     }


Test patch:
diff --git a/api/src/test/java/ai/djl/modality/cv/output/RectangleTest.java b/api/src/test/java/ai/djl/modality/cv/output/RectangleTest.java
new file mode 100644
index 000000000..b4fc3bafa
--- /dev/null
+++ b/api/src/test/java/ai/djl/modality/cv/output/RectangleTest.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2023 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.modality.cv.output;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class RectangleTest {
+
+    @Test
+    public void testIoU() {
+        BoundingBox box = new Rectangle(1, 3, 4, 5);
+        Rectangle rect = new Rectangle(1, 2, 3, 4);
+        double iou = box.getIoU(rect);
+        Assert.assertEquals(iou, 0.47058823529411764, 0.00001);
+
+        rect = new Rectangle(6, 2, 3, 4);
+        iou = box.getIoU(rect);
+        Assert.assertEquals(iou, 0);
+    }
+}
diff --git a/api/src/test/java/ai/djl/modality/cv/output/package-info.java b/api/src/test/java/ai/djl/modality/cv/output/package-info.java
new file mode 100644
index 000000000..e3611e02f
--- /dev/null
+++ b/api/src/test/java/ai/djl/modality/cv/output/package-info.java
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2023 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.
+ */
+/** Contains tests for {@link ai.djl.modality.cv.output}. */
+package ai.djl.modality.cv.output;