[Test/android/snpe] Add android tests with snpe
authorYongjoo Ahn <yongjoo1.ahn@samsung.com>
Sun, 5 Jul 2020 07:24:21 +0000 (16:24 +0900)
committerMyungJoo Ham <myungjoo.ham@samsung.com>
Tue, 7 Jul 2020 00:31:38 +0000 (09:31 +0900)
- Add classification result test with inception_v3 model
- Add runtime checks

Signed-off-by: Yongjoo Ahn <yongjoo1.ahn@samsung.com>
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestCommon.java
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestPipeline.java
api/android/api/src/androidTest/java/org/nnsuite/nnstreamer/APITestSingleShot.java

index 59fa480..275b6f3 100644 (file)
@@ -123,6 +123,62 @@ public class APITestCommon {
     }
 
     /**
+     * Reads raw float image file (plastic_cup) and returns TensorsData instance.
+     */
+    public static TensorsData readRawImageDataSNPE() {
+        String root = Environment.getExternalStorageDirectory().getAbsolutePath();
+        File raw = new File(root + "/nnstreamer/snpe_data/plastic_cup.raw");
+
+        if (!raw.exists()) {
+            fail();
+        }
+
+        TensorsInfo info = new TensorsInfo();
+        info.addTensorInfo(NNStreamer.TensorType.FLOAT32, new int[]{3, 299, 299, 1});
+
+        int size = info.getTensorSize(0);
+        TensorsData data = TensorsData.allocate(info);
+
+        try {
+            byte[] content = Files.readAllBytes(raw.toPath());
+            if (content.length != size) {
+                fail();
+            }
+
+            ByteBuffer buffer = TensorsData.allocateByteBuffer(size);
+            buffer.put(content);
+
+            data.setTensorData(0, buffer);
+        } catch (Exception e) {
+            fail();
+        }
+
+        return data;
+    }
+
+    /**
+     * Gets the label index with max score, for SNPE image classification.
+     */
+    public static int getMaxScoreSNPE(ByteBuffer buffer) {
+        int index = -1;
+        float maxScore = -Float.MAX_VALUE;
+
+        if (isValidBuffer(buffer, 4004)) {
+            for (int i = 0; i < 1001; i++) {
+                /* convert to float */
+                float score = buffer.getFloat(i * 4);
+
+                if (score > maxScore) {
+                    maxScore = score;
+                    index = i;
+                }
+            }
+        }
+
+        return index;
+    }
+
+    /**
      * Gets the File object of tensorflow-lite model.
      * Note that, to invoke model in the storage, the permission READ_EXTERNAL_STORAGE is required.
      */
index 38288c5..3c882f3 100644 (file)
@@ -1656,4 +1656,100 @@ public class APITestPipeline {
             fail();
         }
     }
+
+    /**
+     * Run SNPE with inception model with given runtime.
+     */
+    private void runSNPEInception(String runtime) {
+        File model = APITestCommon.getSNPEModel();
+        String desc = "appsrc name=srcx ! " +
+                "other/tensor,dimension=(string)3:299:299:1,type=(string)float32,framerate=(fraction)0/1 ! " +
+                "tensor_filter framework=snpe model=" + model.getAbsolutePath() +
+                " custom=Runtime:" + runtime + " ! " +
+                "tensor_sink name=sinkx";
+
+        /* expected label is measuring_cup (648) */
+        final int expected_label = 648;
+        try (
+            Pipeline pipe = new Pipeline(desc)
+        ) {
+            /* register sink callback */
+            pipe.registerSinkCallback("sinkx", new Pipeline.NewDataCallback() {
+                @Override
+                public void onNewDataReceived(TensorsData data) {
+                    if (data == null || data.getTensorsCount() != 1) {
+                        mInvalidState = true;
+                        return;
+                    }
+
+                    ByteBuffer buffer = data.getTensorData(0);
+                    int labelIndex = APITestCommon.getMaxScoreSNPE(buffer);
+
+                    /* check label index (measuring cup) */
+                    if (labelIndex != expected_label) {
+                        mInvalidState = true;
+                    }
+
+                    mReceived++;
+                }
+            });
+
+            /* start pipeline */
+            pipe.start();
+
+            /* push input buffer */
+            TensorsData in = APITestCommon.readRawImageDataSNPE();
+            pipe.inputData("srcx", in);
+
+            /* sleep 1000 msec to invoke */
+            Thread.sleep(1000);
+
+            /* check received data from sink */
+            assertFalse(mInvalidState);
+            assertTrue(mReceived > 0);
+        } catch (Exception e) {
+            fail();
+        }
+    }
+
+    @Test
+    public void testSNPEClassificationResultCPU() {
+        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
+            /* cannot run the test */
+            return;
+        }
+
+        runSNPEInception("CPU");
+    }
+
+    @Test
+    public void testSNPEClassificationResultGPU() {
+        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
+            /* cannot run the test */
+            return;
+        }
+
+        runSNPEInception("GPU");
+    }
+
+    @Test
+    public void testSNPEClassificationResultDSP() {
+        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
+            /* cannot run the test */
+            return;
+        }
+
+        runSNPEInception("DSP");
+    }
+
+    @Test
+    public void testSNPEClassificationResultNPU() {
+        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
+            /* cannot run the test */
+            return;
+        }
+
+        runSNPEInception("NPU");
+    }
+
 }
index bf869d2..1f1d6d2 100644 (file)
@@ -814,4 +814,38 @@ public class APITestSingleShot {
             fail();
         }
     }
+
+    @Test
+    public void testSNPEClassificationResult() {
+        if (!NNStreamer.isAvailable(NNStreamer.NNFWType.SNPE)) {
+            /* cannot run the test */
+            return;
+        }
+
+        /* expected label is measuring_cup (648) */
+        final int expected_label = 648;
+
+        try {
+            File model = APITestCommon.getSNPEModel();
+
+            SingleShot single = new SingleShot(model, NNStreamer.NNFWType.SNPE);
+
+            /* let's ignore timeout (set 10 sec) */
+            single.setTimeout(10000);
+
+            /* single-shot invoke */
+            TensorsData in = APITestCommon.readRawImageDataSNPE();
+            TensorsData out = single.invoke(in);
+            int labelIndex = APITestCommon.getMaxScoreSNPE(out.getTensorData(0));
+
+            /* check label index (measuring cup) */
+            if (labelIndex != expected_label) {
+                fail();
+            }
+
+            single.close();
+        } catch (Exception e) {
+            fail();
+        }
+    }
 }