Repository: deepjavalibrary/djl
Pull request #2276 (2023-01-01 22:52:17)

[integration] Increase test coverage for NDArrays.java
1. Fixes contentEquals bug for boolean type
2. Add NDUtilsTest

## 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


codecov-commenter: # [Codecov](https://codecov.io/gh/deepjavalibrary/djl/pull/2276?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary) Report
Base: **72.08**% // Head: **71.75**% // Decreases project coverage by **`-0.33%`** :warning:
> Coverage data is based on head [(`87f9f3d`)](https://codecov.io/gh/deepjavalibrary/djl/pull/2276?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary) compared to base [(`bb5073f`)](https://codecov.io/gh/deepjavalibrary/djl/commit/bb5073f7ffc33f1883621fc1783dbb01e70b418f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary).
> Patch coverage: 73.80% of modified lines in pull request are covered.

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff              @@
##             master    #2276      +/-   ##
============================================
- Coverage     72.08%   71.75%   -0.34%     
- Complexity     5126     6408    +1282     
============================================
  Files           473      631     +158     
  Lines         21970    28165    +6195     
  Branches       2351     2997     +646     
============================================
+ Hits          15838    20210    +4372     
- Misses         4925     6491    +1566     
- Partials       1207     1464     +257     
```


| [Impacted Files](https://codecov.io/gh/deepjavalibrary/djl/pull/2276?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary) | Coverage Δ | |
|---|---|---|
| [api/src/main/java/ai/djl/modality/cv/Image.java](https://codecov.io/gh/deepjavalibrary/djl/pull/2276/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L0ltYWdlLmphdmE=) | `69.23% <ø> (-4.11%)` | :arrow_down: |
| [...rc/main/java/ai/djl/modality/cv/MultiBoxPrior.java](https://codecov.io/gh/deepjavalibrary/djl/pull/2276/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L011bHRpQm94UHJpb3IuamF2YQ==) | `76.00% <ø> (ø)` | |
| [...rc/main/java/ai/djl/modality/cv/output/Joints.java](https://codecov.io/gh/deepjavalibrary/djl/pull/2276/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L291dHB1dC9Kb2ludHMuamF2YQ==) | `71.42% <ø> (ø)` | |
| [.../main/java/ai/djl/modality/cv/output/Landmark.java](https://codecov.io/gh/deepjavalibrary/djl/pull/2276/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L291dHB1dC9MYW5kbWFyay5qYXZh) | `100.00% <ø> (ø)` | |
| [...main/java/ai/djl/modality/cv/output/Rectangle.java](https://codecov.io/gh/deepjavalibrary/djl/pull/2276/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L291dHB1dC9SZWN0YW5nbGUuamF2YQ==) | `72.41% <0.00%> (ø)` | |
| [...i/djl/modality/cv/translator/BigGANTranslator.java](https://codecov.io/gh/deepjavalibrary/djl/pull/2276/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L3RyYW5zbGF0b3IvQmlnR0FOVHJhbnNsYXRvci5qYXZh) | `21.42% <0.00%> (-5.24%)` | :arrow_down: |
| [.../modality/cv/translator/ImageFeatureExtractor.java](https://codecov.io/gh/deepjavalibrary/djl/pull/2276/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L3RyYW5zbGF0b3IvSW1hZ2VGZWF0dXJlRXh0cmFjdG9yLmphdmE=) | `0.00% <0.00%> (ø)` | |
| [.../ai/djl/modality/cv/translator/YoloTranslator.java](https://codecov.io/gh/deepjavalibrary/djl/pull/2276/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L3RyYW5zbGF0b3IvWW9sb1RyYW5zbGF0b3IuamF2YQ==) | `27.77% <0.00%> (+18.95%)` | :arrow_up: |
| [...ain/java/ai/djl/modality/cv/util/NDImageUtils.java](https://codecov.io/gh/deepjavalibrary/djl/pull/2276/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L2N2L3V0aWwvTkRJbWFnZVV0aWxzLmphdmE=) | `59.21% <0.00%> (ø)` | |
| [api/src/main/java/ai/djl/modality/nlp/Decoder.java](https://codecov.io/gh/deepjavalibrary/djl/pull/2276/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary#diff-YXBpL3NyYy9tYWluL2phdmEvYWkvZGpsL21vZGFsaXR5L25scC9EZWNvZGVyLmphdmE=) | `63.63% <ø> (ø)` | |
| ... and [566 more](https://codecov.io/gh/deepjavalibrary/djl/pull/2276/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary) | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/deepjavalibrary/djl/pull/2276?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=deepjavalibrary).


Patch:
diff --git a/api/src/main/java/ai/djl/ndarray/NDArrays.java b/api/src/main/java/ai/djl/ndarray/NDArrays.java
index b73c20278..304b80393 100644
--- a/api/src/main/java/ai/djl/ndarray/NDArrays.java
+++ b/api/src/main/java/ai/djl/ndarray/NDArrays.java
@@ -199,7 +199,7 @@ public final class NDArrays {
      * @return the boolean {@link NDArray} for element-wise "Equals" comparison
      */
     public static NDArray eq(Number n, NDArray a) {
-        return a.eq(n);
+        return eq(a, n);
     }
 
     /**
@@ -264,7 +264,7 @@ public final class NDArrays {
      * @return the boolean {@link NDArray} for element-wise "Not equals" comparison
      */
     public static NDArray neq(Number n, NDArray a) {
-        return a.neq(n);
+        return neq(a, n);
     }
 
     /**
diff --git a/api/src/main/java/ai/djl/ndarray/NDUtils.java b/api/src/main/java/ai/djl/ndarray/NDUtils.java
index c84489554..13e882d04 100644
--- a/api/src/main/java/ai/djl/ndarray/NDUtils.java
+++ b/api/src/main/java/ai/djl/ndarray/NDUtils.java
@@ -23,7 +23,7 @@ public final class NDUtils {
     private NDUtils() {}
 
     /**
-     * Get {@link Shape} of the empty {@link NDArray} after applying reduction operations.
+     * Returns {@link Shape} of the empty {@link NDArray} after applying reduction operations.
      *
      * @param shape input shape
      * @param axis axis to apply reduction
diff --git a/engines/ml/lightgbm/src/main/java/ai/djl/ml/lightgbm/LgbmNDManager.java b/engines/ml/lightgbm/src/main/java/ai/djl/ml/lightgbm/LgbmNDManager.java
index 820ead340..b9f79a124 100644
--- a/engines/ml/lightgbm/src/main/java/ai/djl/ml/lightgbm/LgbmNDManager.java
+++ b/engines/ml/lightgbm/src/main/java/ai/djl/ml/lightgbm/LgbmNDManager.java
@@ -80,12 +80,12 @@ public class LgbmNDManager extends BaseNDManager {
             // output only NDArray
             return new LgbmNDArray(this, alternativeManager, (ByteBuffer) data, shape, dataType);
         } else if (data instanceof FloatBuffer && dataType == DataType.FLOAT32) {
-            ByteBuffer bb = ByteBuffer.allocateDirect(data.capacity() * 4);
+            ByteBuffer bb = allocateDirect(data.capacity() * 4);
             bb.asFloatBuffer().put((FloatBuffer) data);
             bb.rewind();
             return new LgbmNDArray(this, alternativeManager, bb, shape, dataType);
         } else if (data instanceof DoubleBuffer && dataType == DataType.FLOAT64) {
-            ByteBuffer bb = ByteBuffer.allocateDirect(data.capacity() * 8);
+            ByteBuffer bb = allocateDirect(data.capacity() * 8);
             bb.asDoubleBuffer().put((DoubleBuffer) data);
             bb.rewind();
             return new LgbmNDArray(this, alternativeManager, bb, shape, dataType);
diff --git a/engines/mxnet/mxnet-engine/src/main/java/ai/djl/mxnet/engine/MxNDArray.java b/engines/mxnet/mxnet-engine/src/main/java/ai/djl/mxnet/engine/MxNDArray.java
index 479a1a678..148be97e9 100644
--- a/engines/mxnet/mxnet-engine/src/main/java/ai/djl/mxnet/engine/MxNDArray.java
+++ b/engines/mxnet/mxnet-engine/src/main/java/ai/djl/mxnet/engine/MxNDArray.java
@@ -412,9 +412,10 @@ public class MxNDArray extends NativeResource<Pointer> implements LazyNDArray {
     /** {@inheritDoc} */
     @Override
     public boolean contentEquals(Number number) {
-        if (number == null) {
+        if (number == null || getDataType().isBoolean()) {
             return false;
         }
+
         try (NDArray result = eq(number)) {
             return result.all().getBoolean();
         }
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 de96b24f2..db91f276e 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
@@ -401,7 +401,7 @@ public class PtNDArray extends NativeResource<Long> implements NDArray {
     /** {@inheritDoc} */
     @Override
     public boolean contentEquals(Number number) {
-        return JniUtils.contentEqual(this, (PtNDArray) manager.create(number));
+        return contentEquals(manager.create(number));
     }
 
     /** {@inheritDoc} */
diff --git a/engines/tensorflow/tensorflow-engine/src/main/java/ai/djl/tensorflow/engine/TfNDArray.java b/engines/tensorflow/tensorflow-engine/src/main/java/ai/djl/tensorflow/engine/TfNDArray.java
index f19c754ac..7265cf534 100644
--- a/engines/tensorflow/tensorflow-engine/src/main/java/ai/djl/tensorflow/engine/TfNDArray.java
+++ b/engines/tensorflow/tensorflow-engine/src/main/java/ai/djl/tensorflow/engine/TfNDArray.java
@@ -311,7 +311,7 @@ public class TfNDArray extends NativeResource<TFE_TensorHandle> implements NDArr
     /** {@inheritDoc} */
     @Override
     public boolean contentEquals(Number number) {
-        if (number == null) {
+        if (number == null || getDataType().isBoolean()) {
             return false;
         }
         try (NDArray result = eq(number)) {


Test patch:
diff --git a/api/src/test/java/ai/djl/ndarray/NDUtilsTest.java b/api/src/test/java/ai/djl/ndarray/NDUtilsTest.java
new file mode 100644
index 000000000..2925f9343
--- /dev/null
+++ b/api/src/test/java/ai/djl/ndarray/NDUtilsTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2022 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.ndarray;
+
+import ai.djl.ndarray.types.Shape;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class NDUtilsTest {
+
+    @Test
+    public void testGetShape() {
+        Shape shape = new Shape(1, 2, 3);
+        Shape result = NDUtils.getShapeFromEmptyNDArrayForReductionOp(shape, 1);
+        Shape expected = new Shape(1, 3);
+        Assert.assertEquals(result, expected);
+
+        Shape empty = new Shape(0, 1);
+        Assert.assertThrows(() -> NDUtils.getShapeFromEmptyNDArrayForReductionOp(empty, 0));
+    }
+}
diff --git a/extensions/opencv/src/test/java/ai/djl/opencv/OpenCVImageFactoryTest.java b/extensions/opencv/src/test/java/ai/djl/opencv/OpenCVImageFactoryTest.java
index cb0d4dc52..eda79cb45 100644
--- a/extensions/opencv/src/test/java/ai/djl/opencv/OpenCVImageFactoryTest.java
+++ b/extensions/opencv/src/test/java/ai/djl/opencv/OpenCVImageFactoryTest.java
@@ -122,15 +122,8 @@ public class OpenCVImageFactoryTest {
             }
 
             Assert.assertThrows(
-                    IOException.class,
-                    () -> {
-                        factory.fromFile(Paths.get("nonexist.jpg"));
-                    });
-            Assert.assertThrows(
-                    IOException.class,
-                    () -> {
-                        factory.fromUrl("file:build.gradle");
-                    });
+                    IOException.class, () -> factory.fromFile(Paths.get("nonexist.jpg")));
+            Assert.assertThrows(IOException.class, () -> factory.fromUrl("file:build.gradle"));
         }
     }
 
diff --git a/extensions/sentencepiece/src/test/java/ai/djl/sentencepiece/SpTokenizerTest.java b/extensions/sentencepiece/src/test/java/ai/djl/sentencepiece/SpTokenizerTest.java
index 32f443d72..4821609ed 100644
--- a/extensions/sentencepiece/src/test/java/ai/djl/sentencepiece/SpTokenizerTest.java
+++ b/extensions/sentencepiece/src/test/java/ai/djl/sentencepiece/SpTokenizerTest.java
@@ -118,22 +118,14 @@ public class SpTokenizerTest {
     }
 
     @Test
-    public void testModelNotFound() throws IOException {
+    public void testModelNotFound() {
         TestRequirements.notWindows();
 
-        Assert.assertThrows(
-                () -> {
-                    new SpTokenizer(Paths.get("build/test/non-exists"));
-                });
+        Assert.assertThrows(() -> new SpTokenizer(Paths.get("build/test/non-exists")));
 
         Assert.assertThrows(
-                () -> {
-                    new SpTokenizer(Paths.get("build/test/sp_model"), "non-exists.model");
-                });
+                () -> new SpTokenizer(Paths.get("build/test/sp_model"), "non-exists.model"));
 
-        Assert.assertThrows(
-                () -> {
-                    new SpTokenizer(Paths.get("build/test/sp_model"), "non-exists");
-                });
+        Assert.assertThrows(() -> new SpTokenizer(Paths.get("build/test/sp_model"), "non-exists"));
     }
 }
diff --git a/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayElementArithmeticOpTest.java b/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayElementArithmeticOpTest.java
index 278943eb9..cb1d3b6ce 100644
--- a/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayElementArithmeticOpTest.java
+++ b/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayElementArithmeticOpTest.java
@@ -51,7 +51,6 @@ public class NDArrayElementArithmeticOpTest {
         } else {
             // other cases only apply to non inplace test
             // test NDArray with scalar
-            x1 = 10f;
             x2 = 5f;
             float y = arithmeticOp.apply(x1, x2);
             array1 = manager.create(new float[] {x1, x1});
@@ -168,6 +167,10 @@ public class NDArrayElementArithmeticOpTest {
             result = NDArrays.addi(lhs, 2);
             NDArray expected = manager.create(new float[] {3f, 4f, 5f, 6f});
             Assertions.assertInPlaceEquals(result, expected, lhs);
+            lhs = manager.create(new float[] {1f, 2f, 3f, 4f});
+            result = NDArrays.addi(2, lhs);
+            Assertions.assertInPlaceEquals(result, expected, lhs);
+
             testScalarCornerCase(manager, NDArrays::add, Float::sum, false);
             testScalarCornerCase(manager, NDArrays::addi, Float::sum, true);
         }
@@ -182,6 +185,9 @@ public class NDArrayElementArithmeticOpTest {
             Assert.assertNotEquals(
                     result, addend, "None in-place operation returned in-place result");
 
+            result = NDArrays.add(1, addend);
+            Assert.assertEquals(result, addendum);
+
             result = NDArrays.addi(addend, addendum);
             NDArray expected = manager.create(new float[] {3f, 5f, 7f, 9f});
             Assertions.assertInPlaceEquals(result, expected, addend);
@@ -192,6 +198,15 @@ public class NDArrayElementArithmeticOpTest {
                 manager.create(new float[] {2, 2, 2, 2}, new Shape(2, 2))
             };
 
+            Assert.assertThrows(() -> NDArrays.add(addend));
+
+            Assert.assertThrows(
+                    () ->
+                            NDArrays.add(
+                                    addend,
+                                    manager.ones(new Shape(2)),
+                                    manager.ones(new Shape(3))));
+
             NDArray addAll = NDArrays.add(toAddAll);
             Assert.assertNotEquals(
                     addAll, toAddAll[0], "None in-place operation returned in-place result");
@@ -307,11 +322,17 @@ public class NDArrayElementArithmeticOpTest {
         try (NDManager manager = NDManager.newBaseManager()) {
             NDArray multiplicand = manager.create(new float[] {6, 9, -12, 15, 0});
             NDArray result = NDArrays.mul(multiplicand, 3);
-            NDArray inPlaceResult = NDArrays.muli(multiplicand, 3);
             NDArray expected = manager.create(new float[] {18, 27, -36, 45, 0});
-            Assert.assertEquals(
-                    result, expected, "Scalar multiplication: Incorrect value in result ndarray");
+            Assert.assertEquals(result, expected);
+            result = NDArrays.mul(3, multiplicand);
+            Assert.assertEquals(result, expected);
+
+            NDArray inPlaceResult = NDArrays.muli(multiplicand, 3);
             Assertions.assertInPlaceEquals(inPlaceResult, expected, multiplicand);
+            multiplicand = manager.create(new float[] {6, 9, -12, 15, 0});
+            inPlaceResult = NDArrays.muli(3, multiplicand);
+            Assertions.assertInPlaceEquals(inPlaceResult, expected, multiplicand);
+
             testScalarCornerCase(manager, NDArrays::mul, (x, y) -> x * y, false);
             testScalarCornerCase(manager, NDArrays::muli, (x, y) -> x * y, true);
         }
@@ -430,7 +451,7 @@ public class NDArrayElementArithmeticOpTest {
             NDArray lhs = manager.create(new float[] {5, 10, -3, 4, 2, 7}, new Shape(2, 3));
             NDArray rhs = manager.create(new float[] {2, 9, 3}, new Shape(3, 1));
             NDArray expected = manager.create(new float[] {91, 47}, new Shape(2, 1));
-            Assert.assertEquals(lhs.matMul(rhs), expected);
+            Assert.assertEquals(NDArrays.matMul(lhs, rhs), expected);
             // 3D * 2D
             lhs = manager.arange(24f).reshape(2, 3, 4);
             rhs = manager.arange(12f).reshape(4, 3);
@@ -627,8 +648,8 @@ public class NDArrayElementArithmeticOpTest {
     public void testPowScalar() {
         try (NDManager manager = NDManager.newBaseManager()) {
             NDArray array = manager.create(new float[] {6, 0, -1, 5, 2}, new Shape(1, 5));
-            NDArray result = array.pow(2);
-            NDArray inPlaceResult = array.powi(2);
+            NDArray result = NDArrays.pow(array, 2);
+            NDArray inPlaceResult = NDArrays.powi(array, 2);
             NDArray expected = manager.create(new float[] {36, 0, 1, 25, 4}, new Shape(1, 5));
             Assertions.assertAlmostEquals(result, expected);
             Assertions.assertInPlaceAlmostEquals(inPlaceResult, expected, array);
diff --git a/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayElementComparisonOpTest.java b/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayElementComparisonOpTest.java
index dc6ffc874..6842cc5de 100644
--- a/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayElementComparisonOpTest.java
+++ b/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayElementComparisonOpTest.java
@@ -28,24 +28,36 @@ public class NDArrayElementComparisonOpTest {
         try (NDManager manager = NDManager.newBaseManager()) {
             NDArray array1 = manager.create(new float[] {1f, 2f});
             NDArray array2 = manager.create(new float[] {1f, 2f});
-            Assert.assertTrue(array1.contentEquals(array2));
+            Assert.assertTrue(NDArrays.shapeEquals(array1, array2));
+            Assert.assertTrue(NDArrays.contentEquals(array1, array2));
+            Assert.assertFalse(NDArrays.neq(array1, array2).getBoolean(0));
             array1 = manager.ones(new Shape(2, 3));
             array2 = manager.ones(new Shape(1, 3));
             Assert.assertFalse(array1.contentEquals(array2));
 
             // test scalar
+            Assert.assertFalse(NDArrays.contentEquals(null, 1));
+
             array1 = manager.create(5f);
             array2 = manager.create(5f);
             Assert.assertTrue(array1.contentEquals(array2));
+            Assert.assertTrue(NDArrays.contentEquals(array1, 5f));
+            Assert.assertTrue(NDArrays.eq(5f, array1).all().getBoolean());
+            Assert.assertFalse(NDArrays.neq(5f, array1).all().getBoolean());
+
             array1 = manager.create(3);
             array2 = manager.create(4);
             Assert.assertFalse(array1.contentEquals(array2));
 
             // different data type
-            array1 = manager.create(4f);
-            array2 = manager.create(4);
+            array1 = manager.create(1f);
+            array2 = manager.create(1d);
             Assert.assertFalse(array1.contentEquals(array2));
 
+            // boolean type
+            array1 = manager.create(true);
+            Assert.assertFalse(NDArrays.contentEquals(array1, 1));
+
             // test zero dim vs zero dim
             array1 = manager.create(new Shape(4, 0));
             array2 = manager.create(new Shape(4, 0));
@@ -171,6 +183,9 @@ public class NDArrayElementComparisonOpTest {
             NDArray result = NDArrays.gt(array, 2);
             NDArray expected = manager.create(new boolean[] {false, false, false, false, true});
             Assert.assertEquals(result, expected, "greater_scalar: Incorrect comparison");
+            result = NDArrays.gt(2, array);
+            Assert.assertTrue(result.getBoolean(0));
+
             array =
                     manager.create(
                             new float[] {2f, 3f, -5f, 2f, 5f, 10f, 20123f, -355f},
@@ -241,6 +256,9 @@ public class NDArrayElementComparisonOpTest {
             NDArray result = NDArrays.gte(array, 2);
             NDArray expected = manager.create(new boolean[] {false, true, true, true});
             Assert.assertEquals(result, expected, "greater_equals_scalar: Incorrect comparison");
+            result = NDArrays.gte(2, array);
+            Assert.assertTrue(result.getBoolean(0));
+
             array = manager.create(new float[] {3f, 2f, 2f, 4f, 5f, 3f}, new Shape(3, 2));
             result = NDArrays.gte(array, 3f);
             expected =
@@ -308,6 +326,9 @@ public class NDArrayElementComparisonOpTest {
             NDArray result = NDArrays.lt(array, 2);
             NDArray expected = manager.create(new boolean[] {true, false, false, false, false});
             Assert.assertEquals(result, expected, "lesser_scalar: Incorrect comparison");
+            result = NDArrays.lt(2, array);
+            Assert.assertFalse(result.getBoolean(0));
+
             array =
                     manager.create(
                             new float[] {2.2322f, 2.3222f, 2.3333f, 2.2222f}, new Shape(2, 2));
@@ -386,6 +407,9 @@ public class NDArrayElementComparisonOpTest {
                                 true, true, true, true, true, false, false, false, false, false
                             });
             Assert.assertEquals(result, expected);
+            result = NDArrays.lte(2, array);
+            Assert.assertFalse(result.getBoolean(0));
+
             array = manager.create(new float[] {0.1f, 0.2f, 0.3f, 0.4f}, new Shape(2, 2, 1));
             result = NDArrays.lte(array, 0.2f);
             expected = manager.create(new boolean[] {true, true, false, false}, new Shape(2, 2, 1));
@@ -446,33 +470,25 @@ public class NDArrayElementComparisonOpTest {
     public void testMaximumScalar() {
         try (NDManager manager = NDManager.newBaseManager()) {
             NDArray array = manager.arange(10.0f);
-            NDArray result = array.maximum(4.0f);
+            NDArray result = NDArrays.maximum(4f, array);
             NDArray expected = manager.create(new float[] {4f, 4f, 4f, 4f, 4f, 5f, 6f, 7f, 8f, 9f});
             Assert.assertEquals(result, expected);
-            result = NDArrays.maximum(array, 4f);
-            Assert.assertEquals(result, expected);
 
             array = manager.create(new float[] {0.1f, 0.2f, 0.3f, 0.4f}, new Shape(2, 2, 1));
-            result = array.maximum(0.2f);
+            result = NDArrays.maximum(0.2f, array);
             expected = manager.create(new float[] {0.2f, 0.2f, 0.3f, 0.4f}, new Shape(2, 2, 1));
             Assert.assertEquals(result, expected);
-            result = NDArrays.maximum(array, 0.2f);
-            Assert.assertEquals(result, expected);
 
             // test scalar
             array = manager.create(3.9999f);
-            result = array.maximum(4.0f);
+            result = NDArrays.maximum(4f, array);
             expected = manager.create(4f);
             Assert.assertEquals(result, expected);
-            result = NDArrays.maximum(array, 4f);
-            Assert.assertEquals(result, expected);
 
             // test zero-dim
             array = manager.create(new Shape(2, 0, 3, 0, 1, 0));
-            result = array.maximum(2f);
-            expected = manager.create(new Shape(2, 0, 3, 0, 1, 0));
-            Assert.assertEquals(result, expected);
             result = NDArrays.maximum(array, 2f);
+            expected = manager.create(new Shape(2, 0, 3, 0, 1, 0));
             Assert.assertEquals(result, expected);
         }
     }
@@ -482,47 +498,37 @@ public class NDArrayElementComparisonOpTest {
         try (NDManager manager = NDManager.newBaseManager()) {
             NDArray array1 = manager.create(new float[] {1f, 2f, 3f, 4f, 5f});
             NDArray array2 = manager.create(new float[] {5f, 4f, 3f, 2f, 1f});
-            NDArray result = array1.maximum(array2);
+            NDArray result = NDArrays.maximum(array1, array2);
             NDArray expected = manager.create(new float[] {5f, 4f, 3f, 4f, 5f});
             Assert.assertEquals(result, expected);
-            result = NDArrays.maximum(array1, array2);
-            Assert.assertEquals(result, expected);
 
             array1 = manager.arange(10.0f).reshape(new Shape(2, 5));
             array2 = manager.create(new float[] {4f, 5f}, new Shape(2, 1));
-            result = array1.maximum(array2);
+            result = NDArrays.maximum(array1, array2);
             expected =
                     manager.create(
                             new float[] {4f, 4f, 4f, 4f, 4f, 5f, 6f, 7f, 8f, 9f}, new Shape(2, 5));
             Assert.assertEquals(result, expected);
-            result = NDArrays.maximum(array1, array2);
-            Assert.assertEquals(result, expected);
 
             // test scalar with scalar
             array1 = manager.create(0f);
             array2 = manager.create(1f);
-            result = array1.maximum(array2);
-            expected = manager.create(1f);
-            Assert.assertEquals(result, expected);
             result = NDArrays.maximum(array1, array2);
+            expected = manager.create(1f);
             Assert.assertEquals(result, expected);
 
             // test NDArray with scalar
             array1 = manager.create(3f);
             array2 = manager.create(new float[] {3f, 3f, 3f, 2f}, new Shape(2, 2));
-            result = array1.maximum(array2);
-            expected = manager.ones(new Shape(2, 2)).mul(3);
-            Assert.assertEquals(result, expected);
             result = NDArrays.maximum(array1, array2);
+            expected = manager.ones(new Shape(2, 2)).mul(3);
             Assert.assertEquals(result, expected);
 
             // test zero-dim with zero-dim
             array1 = manager.create(new Shape(0, 0, 1));
             array2 = manager.create(new Shape(1, 0, 0));
-            result = array1.maximum(array2);
-            expected = manager.create(new Shape(0, 0, 0));
-            Assert.assertEquals(result, expected);
             result = NDArrays.maximum(array1, array2);
+            expected = manager.create(new Shape(0, 0, 0));
             Assert.assertEquals(result, expected);
         }
     }
@@ -531,33 +537,25 @@ public class NDArrayElementComparisonOpTest {
     public void testMinimumScalar() {
         try (NDManager manager = NDManager.newBaseManager()) {
             NDArray array = manager.arange(10.0f);
-            NDArray result = array.minimum(4f);
+            NDArray result = NDArrays.minimum(4f, array);
             NDArray expected = manager.create(new float[] {0f, 1f, 2f, 3f, 4f, 4f, 4f, 4f, 4f, 4f});
             Assert.assertEquals(result, expected);
-            result = NDArrays.minimum(array, 4f);
-            Assert.assertEquals(result, expected);
 
             array = manager.create(new float[] {0.1f, 0.2f, 0.3f, 0.4f}, new Shape(2, 2, 1));
-            result = array.minimum(0.2f);
-            expected = manager.create(new float[] {0.1f, 0.2f, 0.2f, 0.2f}, new Shape(2, 2, 1));
-            Assert.assertEquals(result, expected);
             result = NDArrays.minimum(array, 0.2f);
+            expected = manager.create(new float[] {0.1f, 0.2f, 0.2f, 0.2f}, new Shape(2, 2, 1));
             Assert.assertEquals(result, expected);
 
             // test scalar
             array = manager.create(3.9999f);
-            result = array.minimum(4f);
-            expected = manager.create(3.9999f);
-            Assert.assertEquals(result, expected);
             result = NDArrays.minimum(array, 4f);
+            expected = manager.create(3.9999f);
             Assert.assertEquals(result, expected);
 
             // test zero-dim
             array = manager.create(new Shape(1, 0));
-            result = array.minimum(2f);
-            expected = manager.create(new Shape(1, 0));
-            Assert.assertEquals(result, expected);
             result = NDArrays.minimum(array, 2f);
+            expected = manager.create(new Shape(1, 0));
             Assert.assertEquals(result, expected);
         }
     }
@@ -567,47 +565,37 @@ public class NDArrayElementComparisonOpTest {
         try (NDManager manager = NDManager.newBaseManager()) {
             NDArray array1 = manager.create(new float[] {1f, 2f, 3f, 4f, 5f});
             NDArray array2 = manager.create(new float[] {5f, 4f, 3f, 2f, 1f});
-            NDArray result = array1.minimum(array2);
+            NDArray result = NDArrays.minimum(array1, array2);
             NDArray expected = manager.create(new float[] {1f, 2f, 3f, 2f, 1f});
             Assert.assertEquals(result, expected);
-            result = NDArrays.minimum(array1, array2);
-            Assert.assertEquals(result, expected);
 
             array1 = manager.arange(10.0f).reshape(new Shape(2, 5));
             array2 = manager.create(new float[] {4f, 5f}, new Shape(2, 1));
-            result = array1.minimum(array2);
+            result = NDArrays.minimum(array1, array2);
             expected =
                     manager.create(
                             new float[] {0f, 1f, 2f, 3f, 4f, 5f, 5f, 5f, 5f, 5f}, new Shape(2, 5));
             Assert.assertEquals(result, expected);
-            result = NDArrays.minimum(array1, array2);
-            Assert.assertEquals(result, expected);
 
             // test scalar with scalar
             array1 = manager.create(0f);
             array2 = manager.create(1f);
-            result = array1.minimum(array2);
-            expected = manager.create(0f);
-            Assert.assertEquals(result, expected);
             result = NDArrays.minimum(array1, array2);
+            expected = manager.create(0f);
             Assert.assertEquals(result, expected);
 
             // test NDArray with scalar
             array1 = manager.create(3f);
             array2 = manager.create(new float[] {3f, 3f, 3f, 2f}, new Shape(2, 2));
-            result = array1.minimum(array2);
-            expected = manager.create(new float[] {3f, 3f, 3f, 2f}, new Shape(2, 2));
-            Assert.assertEquals(result, expected);
             result = NDArrays.minimum(array1, array2);
+            expected = manager.create(new float[] {3f, 3f, 3f, 2f}, new Shape(2, 2));
             Assert.assertEquals(result, expected);
 
             // test zero-dim with zero-dim
             array1 = manager.create(new Shape(0, 0, 1));
             array2 = manager.create(new Shape(1, 0, 0));
-            result = array1.minimum(array2);
-            expected = manager.create(new Shape(0, 0, 0));
-            Assert.assertEquals(result, expected);
             result = NDArrays.minimum(array1, array2);
+            expected = manager.create(new Shape(0, 0, 0));
             Assert.assertEquals(result, expected);
         }
     }
diff --git a/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayOtherOpTest.java b/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayOtherOpTest.java
index 814ec62f7..663044695 100644
--- a/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayOtherOpTest.java
+++ b/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayOtherOpTest.java
@@ -316,8 +316,12 @@ public class NDArrayOtherOpTest {
             NDArray array = manager.create(new float[][] {{1, 2, 3}, {4, 5, 6}});
             NDArray sequenceLength = manager.create(new float[] {1, 2});
             NDArray expected = manager.create(new float[][] {{1, 0, 0}, {4, 5, 0}});
-            Assert.assertEquals(array.sequenceMask(sequenceLength), expected);
-            Assert.assertEquals(NDArrays.sequenceMask(array, sequenceLength), expected);
+            NDArray result = NDArrays.sequenceMask(array, sequenceLength);
+            Assert.assertEquals(result, expected);
+
+            result = NDArrays.sequenceMask(array, sequenceLength, -1f);
+            expected = manager.create(new float[][] {{1, -1, -1}, {4, 5, -1}});
+            Assert.assertEquals(result, expected);
 
             // test zero dimension
             array = manager.create(new Shape(1, 0, 0));
@@ -841,7 +845,7 @@ public class NDArrayOtherOpTest {
             // test 1-D
             NDArray array = manager.create(new float[] {0f, 0.5f, -1f});
             NDArray expected = manager.create(new float[] {0f, 0.4769f, Float.NEGATIVE_INFINITY});
-            Assertions.assertAlmostEquals(array.erfinv(), expected);
+            Assertions.assertAlmostEquals(NDArrays.erfinv(array), expected);
             // test 3-D
             array = manager.linspace(-1.0f, 1.0f, 9).reshape(3, 1, 3);
             expected =
diff --git a/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayShapesManipulationOpTest.java b/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayShapesManipulationOpTest.java
index 50709beed..dae21cb79 100644
--- a/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayShapesManipulationOpTest.java
+++ b/integration/src/main/java/ai/djl/integration/tests/ndarray/NDArrayShapesManipulationOpTest.java
@@ -180,6 +180,8 @@ public class NDArrayShapesManipulationOpTest {
     @Test
     public void testStack() {
         try (NDManager manager = NDManager.newBaseManager()) {
+            Assert.assertThrows(() -> NDArrays.stack(new NDList()));
+
             NDArray array1 = manager.create(new float[] {1f, 2f});
             NDArray array2 = manager.create(new float[] {3f, 4f});
 
@@ -239,15 +241,14 @@ public class NDArrayShapesManipulationOpTest {
         try (NDManager manager = NDManager.newBaseManager()) {
             NDArray array1 = manager.create(new float[] {1f});
             NDArray array2 = manager.create(new float[] {2f});
+
             NDArray expected = manager.create(new float[] {1f, 2f});
-            Assert.assertEquals(NDArrays.concat(new NDList(array1, array2), 0), expected);
-            Assert.assertEquals(array1.concat(array2), expected);
+            Assert.assertEquals(NDArrays.concat(new NDList(array1, array2)), expected);
 
             array1 = manager.create(new float[] {1f, 2f, 3f, 4f}, new Shape(2, 2));
             array2 = manager.create(new float[] {5f, 6f, 7f, 8f}, new Shape(2, 2));
             expected = manager.create(new float[] {1f, 2f, 3f, 4f, 5f, 6f, 7, 8f}, new Shape(4, 2));
             Assert.assertEquals(NDArrays.concat(new NDList(array1, array2)), expected);
-            Assert.assertEquals(array1.concat(array2), expected);
             expected =
                     manager.create(new float[] {1f, 2f, 5f, 6f, 3f, 4f, 7f, 8f}, new Shape(2, 4));
             Assert.assertEquals(NDArrays.concat(new NDList(array1, array2), 1), expected);
@@ -258,10 +259,8 @@ public class NDArrayShapesManipulationOpTest {
             // zero-dim
             array1 = manager.create(new Shape(0, 1));
             expected = manager.create(new Shape(0, 1));
-            Assert.assertEquals(array1.concat(array1), expected);
             Assert.assertEquals(NDArrays.concat(new NDList(array1, array1)), expected);
             expected = manager.create(new Shape(0, 2));
-            Assert.assertEquals(array1.concat(array1, 1), expected);
             Assert.assertEquals(NDArrays.concat(new NDList(array1, array1), 1), expected);
 
             // scalar
@@ -271,8 +270,12 @@ public class NDArrayShapesManipulationOpTest {
 
             // one array
             array1 = manager.ones(new Shape(2, 2));
-            expected = manager.ones(new Shape(2, 2));
-            Assert.assertEquals(NDArrays.concat(new NDList(array1)), expected);
+            Assert.assertEquals(NDArrays.concat(new NDList(array1)), array1);
+
+            Assert.assertThrows(() -> NDArrays.concat(new NDList()));
+
+            NDList list = new NDList(manager.ones(new Shape(2)), manager.ones(new Shape(3, 1)));
+            Assert.assertThrows(() -> NDArrays.concat(list));
         }
     }