Home | History | Annotate | Download | only in unittest
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /* This is a much simpler version of UT_reduce.java that
     18  * exercises pragmas after the functions (backward reference),
     19  * whereas the other test case exercises the pragmas before the
     20  * functions (forward reference).
     21  */
     22 
     23 package com.android.rs.unittest;
     24 
     25 import android.content.Context;
     26 import android.renderscript.Allocation;
     27 import android.renderscript.Element;
     28 import android.renderscript.Float2;
     29 import android.renderscript.Int2;
     30 import android.renderscript.Int3;
     31 import android.renderscript.RenderScript;
     32 import android.renderscript.ScriptIntrinsicHistogram;
     33 import android.renderscript.Type;
     34 import android.util.Log;
     35 
     36 import java.util.Random;
     37 
     38 public class UT_reduce_backward extends UnitTest {
     39     private static final String TAG = "reduce_backward";
     40 
     41     public UT_reduce_backward(Context ctx) {
     42         super("reduce_backward", ctx);
     43     }
     44 
     45     private byte[] createInputArrayByte(int len, int seed) {
     46         byte[] array = new byte[len];
     47         (new Random(seed)).nextBytes(array);
     48         return array;
     49     }
     50 
     51     private float[] createInputArrayFloat(int len, int seed) {
     52         Random rand = new Random(seed);
     53         float[] array = new float[len];
     54         for (int i = 0; i < len; ++i)
     55             array[i] = rand.nextFloat();
     56         return array;
     57     }
     58 
     59     private int[] createInputArrayInt(int len, int seed) {
     60         Random rand = new Random(seed);
     61         int[] array = new int[len];
     62         for (int i = 0; i < len; ++i)
     63             array[i] = rand.nextInt();
     64         return array;
     65     }
     66 
     67     private int[] createInputArrayInt(int len, int seed, int eltRange) {
     68         Random rand = new Random(seed);
     69         int[] array = new int[len];
     70         for (int i = 0; i < len; ++i)
     71             array[i] = rand.nextInt(eltRange);
     72         return array;
     73     }
     74 
     75     private <T extends Number> boolean result(String testName, T javaRslt, T rsRslt) {
     76         final boolean success = javaRslt.equals(rsRslt);
     77         Log.i(TAG,
     78                 testName + ": java " + javaRslt + ", rs " + rsRslt + ": " +
     79                         (success ? "PASSED" : "FAILED"));
     80         return success;
     81     }
     82 
     83     private boolean result(String testName, Float2 javaRslt, Float2 rsRslt) {
     84         final boolean success = (javaRslt.x == rsRslt.x) && (javaRslt.y == rsRslt.y);
     85         Log.i(TAG,
     86                 testName +
     87                         ": java (" + javaRslt.x + ", " + javaRslt.y + ")" +
     88                         ", rs (" + rsRslt.x + ", " + rsRslt.y + ")" +
     89                         ": " + (success ? "PASSED" : "FAILED"));
     90         return success;
     91     }
     92 
     93     private boolean result(String testName, Int2 javaRslt, Int2 rsRslt) {
     94         final boolean success = (javaRslt.x == rsRslt.x) && (javaRslt.y == rsRslt.y);
     95         Log.i(TAG,
     96                 testName +
     97                         ": java (" + javaRslt.x + ", " + javaRslt.y + ")" +
     98                         ", rs (" + rsRslt.x + ", " + rsRslt.y + ")" +
     99                         ": " + (success ? "PASSED" : "FAILED"));
    100         return success;
    101     }
    102 
    103     ///////////////////////////////////////////////////////////////////
    104 
    105     private int addint(int[] input) {
    106         int rslt = 0;
    107         for (int idx = 0; idx < input.length; ++idx)
    108             rslt += input[idx];
    109         return rslt;
    110     }
    111 
    112     private boolean addint1D(RenderScript RS, ScriptC_reduce_backward s) {
    113         final int[] input = createInputArrayInt(100000, 0, 1 << 13);
    114 
    115         final int javaRslt = addint(input);
    116         final int rsRslt = s.reduce_addint(input).get();
    117 
    118         return result("addint1D", javaRslt, rsRslt);
    119     }
    120 
    121     private boolean addint2D(RenderScript RS, ScriptC_reduce_backward s) {
    122         final int dimX = 450, dimY = 225;
    123 
    124         final int[] inputArray = createInputArrayInt(dimX * dimY, 1, 1 << 13);
    125         Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
    126         typeBuilder.setX(dimX).setY(dimY);
    127         Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
    128         inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray);
    129 
    130         final int javaRslt = addint(inputArray);
    131         final int rsRslt = s.reduce_addint(inputAllocation).get();
    132 
    133         return result("addint2D", javaRslt, rsRslt);
    134     }
    135 
    136     ///////////////////////////////////////////////////////////////////
    137 
    138     private Int2 findMinAndMax(float[] input) {
    139         float minVal = Float.POSITIVE_INFINITY;
    140         int minIdx = -1;
    141         float maxVal = Float.NEGATIVE_INFINITY;
    142         int maxIdx = -1;
    143 
    144         for (int idx = 0; idx < input.length; ++idx) {
    145             if (input[idx] < minVal) {
    146                 minVal = input[idx];
    147                 minIdx = idx;
    148             }
    149             if (input[idx] > maxVal) {
    150                 maxVal = input[idx];
    151                 maxIdx = idx;
    152             }
    153         }
    154 
    155         return new Int2(minIdx, maxIdx);
    156     }
    157 
    158     private boolean findMinAndMax(RenderScript RS, ScriptC_reduce_backward s) {
    159         final float[] input = createInputArrayFloat(100000, 4);
    160 
    161         final Int2 javaRslt = findMinAndMax(input);
    162         final Int2 rsRslt = s.reduce_findMinAndMax(input).get();
    163 
    164         // Note that the Java and RenderScript algorithms are not
    165         // guaranteed to find the same cells -- but they should
    166         // find cells of the same value.
    167         final Float2 javaVal = new Float2(input[javaRslt.x], input[javaRslt.y]);
    168         final Float2 rsVal = new Float2(input[rsRslt.x], input[rsRslt.y]);
    169 
    170         return result("findMinAndMax", javaVal, rsVal);
    171     }
    172 
    173     ///////////////////////////////////////////////////////////////////
    174 
    175     private boolean fz(RenderScript RS, ScriptC_reduce_backward s) {
    176         final int inputLen = 100000;
    177         int[] input = createInputArrayInt(inputLen, 5);
    178         // just in case we got unlucky
    179         input[(new Random(6)).nextInt(inputLen)] = 0;
    180 
    181         final int rsRslt = s.reduce_fz(input).get();
    182 
    183         final boolean success = (input[rsRslt] == 0);
    184         Log.i(TAG,
    185                 "fz: input[" + rsRslt + "] == " + input[rsRslt] + ": " +
    186                         (success ? "PASSED" : "FAILED"));
    187         return success;
    188     }
    189 
    190     ///////////////////////////////////////////////////////////////////
    191 
    192     private boolean fz2(RenderScript RS, ScriptC_reduce_backward s) {
    193         final int dimX = 225, dimY = 450;
    194         final int inputLen = dimX * dimY;
    195 
    196         int[] inputArray = createInputArrayInt(inputLen, 7);
    197         // just in case we got unlucky
    198         inputArray[(new Random(8)).nextInt(inputLen)] = 0;
    199 
    200         Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
    201         typeBuilder.setX(dimX).setY(dimY);
    202         Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
    203         inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray);
    204 
    205         final Int2 rsRslt = s.reduce_fz2(inputAllocation).get();
    206 
    207         final int cellVal = inputArray[rsRslt.x + dimX * rsRslt.y];
    208         final boolean success = (cellVal == 0);
    209         Log.i(TAG,
    210                 "fz2: input[" + rsRslt.x + ", " + rsRslt.y + "] == " + cellVal + ": " +
    211                         (success ? "PASSED" : "FAILED"));
    212         return success;
    213     }
    214 
    215     ///////////////////////////////////////////////////////////////////
    216 
    217     private boolean fz3(RenderScript RS, ScriptC_reduce_backward s) {
    218         final int dimX = 59, dimY = 48, dimZ = 37;
    219         final int inputLen = dimX * dimY * dimZ;
    220 
    221         int[] inputArray = createInputArrayInt(inputLen, 9);
    222         // just in case we got unlucky
    223         inputArray[(new Random(10)).nextInt(inputLen)] = 0;
    224 
    225         Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
    226         typeBuilder.setX(dimX).setY(dimY).setZ(dimZ);
    227         Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
    228         inputAllocation.copy3DRangeFrom(0, 0, 0, dimX, dimY, dimZ, inputArray);
    229 
    230         final Int3 rsRslt = s.reduce_fz3(inputAllocation).get();
    231 
    232         final int cellVal = inputArray[rsRslt.x + dimX * rsRslt.y + dimX * dimY * rsRslt.z];
    233         final boolean success = (cellVal == 0);
    234         Log.i(TAG,
    235                 "fz3: input[" + rsRslt.x + ", " + rsRslt.y + ", " + rsRslt.z + "] == " + cellVal + ": " +
    236                         (success ? "PASSED" : "FAILED"));
    237         return success;
    238     }
    239 
    240     ///////////////////////////////////////////////////////////////////
    241 
    242     private static final int histogramBucketCount = 256;
    243 
    244     private long[] histogram(RenderScript RS, final byte[] inputArray) {
    245         Allocation inputAllocation = Allocation.createSized(RS, Element.U8(RS), inputArray.length);
    246         inputAllocation.copyFrom(inputArray);
    247 
    248         Allocation outputAllocation = Allocation.createSized(RS, Element.U32(RS), histogramBucketCount);
    249 
    250         ScriptIntrinsicHistogram scriptHsg = ScriptIntrinsicHistogram.create(RS, Element.U8(RS));
    251         scriptHsg.setOutput(outputAllocation);
    252         scriptHsg.forEach(inputAllocation);
    253 
    254         int[] outputArrayMistyped = new int[histogramBucketCount];
    255         outputAllocation.copyTo(outputArrayMistyped);
    256 
    257         long[] outputArray = new long[histogramBucketCount];
    258         for (int i = 0; i < histogramBucketCount; ++i)
    259             outputArray[i] = outputArrayMistyped[i] & (long) 0xffffffff;
    260         return outputArray;
    261     }
    262 
    263     private boolean histogram(RenderScript RS, ScriptC_reduce_backward s) {
    264         final byte[] inputArray = createInputArrayByte(100000, 11);
    265 
    266         final long[] javaRslt = histogram(RS, inputArray);
    267         _RS_ASSERT("javaRslt unexpected length: " + javaRslt.length, javaRslt.length == histogramBucketCount);
    268         final long[] rsRslt = s.reduce_histogram(inputArray).get();
    269         _RS_ASSERT("rsRslt unexpected length: " + rsRslt.length, rsRslt.length == histogramBucketCount);
    270 
    271         for (int i = 0; i < histogramBucketCount; ++i) {
    272             if (javaRslt[i] != rsRslt[i]) {
    273                 Log.i(TAG,
    274                         "histogram[" + i + "]: java " + javaRslt[i] + ", rs " + rsRslt[i] + ": FAILED");
    275                 return false;
    276             }
    277         }
    278 
    279         Log.i(TAG, "histogram: PASSED");
    280         return true;
    281     }
    282 
    283     //-----------------------------------------------------------------
    284 
    285     private Int2 mode(RenderScript RS, final byte[] inputArray) {
    286         long[] hsg = histogram(RS, inputArray);
    287 
    288         int modeIdx = 0;
    289         for (int i = 1; i < hsg.length; ++i)
    290             if (hsg[i] > hsg[modeIdx]) modeIdx = i;
    291         return new Int2(modeIdx, (int) hsg[modeIdx]);
    292     }
    293 
    294     private boolean mode(RenderScript RS, ScriptC_reduce_backward s) {
    295         final byte[] inputArray = createInputArrayByte(100000, 12);
    296 
    297         final Int2 javaRslt = mode(RS, inputArray);
    298         final Int2 rsRslt = s.reduce_mode(inputArray).get();
    299 
    300         return result("mode", javaRslt, rsRslt);
    301     }
    302 
    303     ///////////////////////////////////////////////////////////////////
    304 
    305     public void run() {
    306         RenderScript pRS = createRenderScript(false);
    307         ScriptC_reduce_backward s = new ScriptC_reduce_backward(pRS);
    308         s.set_negInf(Float.NEGATIVE_INFINITY);
    309         s.set_posInf(Float.POSITIVE_INFINITY);
    310 
    311         boolean pass = true;
    312         pass &= addint1D(pRS, s);
    313         pass &= addint2D(pRS, s);
    314         pass &= findMinAndMax(pRS, s);
    315         pass &= fz(pRS, s);
    316         pass &= fz2(pRS, s);
    317         pass &= fz3(pRS, s);
    318         pass &= histogram(pRS, s);
    319         pass &= mode(pRS, s);
    320 
    321         pRS.finish();
    322         pRS.destroy();
    323 
    324         Log.i(TAG, pass ? "PASSED" : "FAILED");
    325         if (pass)
    326             passTest();
    327         else
    328             failTest();
    329     }
    330 }
    331