UT_reduce.java revision 89e35a551ee4b0bfcb3ede10da3b027dba1da7ef
127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi/*
227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Copyright (C) 2016 The Android Open Source Project
327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Licensed under the Apache License, Version 2.0 (the "License");
527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * you may not use this file except in compliance with the License.
627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * You may obtain a copy of the License at
727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *      http://www.apache.org/licenses/LICENSE-2.0
927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi *
1027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * Unless required by applicable law or agreed to in writing, software
1127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * distributed under the License is distributed on an "AS IS" BASIS,
1227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * See the License for the specific language governing permissions and
1427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * limitations under the License.
1527ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi */
1627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
1727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi/* Same as UT_reduce_backward.java, except this test case exercises
1827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * pragmas before the functions (forward reference), and the other
1927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * test case exercises the pragmas after the functions (backward
2027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi * reference).
2127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi */
2241b3d3be18b54e72a44813cbdd180aae7e77b444Glenn Kasten
2327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshipackage com.android.rs.test_compat;
2427ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
258635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dongimport android.content.Context;
2627ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiimport android.content.res.Resources;
27ecba7488c5cceaacef95836b1b476433451e7761Ying Wangimport android.support.v8.renderscript.*;
285e0067b486c3862316aa1f293cf9690c0cf54bdaJeff Brownimport android.util.Log;
295e0067b486c3862316aa1f293cf9690c0cf54bdaJeff Brownimport java.lang.Float;
3027ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshiimport java.util.Random;
3127ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshipublic class UT_reduce extends UnitTest {
3327ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    private static final String TAG = "reduce";
34559bf2836f5da25b75bfb229fec0d20d540ee426James Dong
35559bf2836f5da25b75bfb229fec0d20d540ee426James Dong    protected UT_reduce(RSTestCore rstc, Resources res, Context ctx) {
36559bf2836f5da25b75bfb229fec0d20d540ee426James Dong        super(rstc, "reduce", ctx);
3727ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    }
3827ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi
3927ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi    private byte[] createInputArrayByte(int len, int seed) {
400335b70c6cdbe96650d4bed817f9233cd8db1c6dJean-Baptiste Queru        byte[] array = new byte[len];
410335b70c6cdbe96650d4bed817f9233cd8db1c6dJean-Baptiste Queru        (new Random(seed)).nextBytes(array);
4227ed8ad2db653f6ac07dcf8bcc05e2409c8bb024aimitakeshi        return array;
43    }
44
45    private float[] createInputArrayFloat(int len, int seed) {
46        Random rand = new Random(seed);
47        float[] array = new float[len];
48        for (int i = 0; i < len; ++i)
49            array[i] = rand.nextFloat();
50        return array;
51    }
52
53    private int[] createInputArrayInt(int len, int seed) {
54        Random rand = new Random(seed);
55        int[] array = new int[len];
56        for (int i = 0; i < len; ++i)
57            array[i] = rand.nextInt();
58        return array;
59    }
60
61    private int[] createInputArrayInt(int len, int seed, int eltRange) {
62        Random rand = new Random(seed);
63        int[] array = new int[len];
64        for (int i = 0; i < len; ++i)
65            array[i] = rand.nextInt(eltRange);
66        return array;
67    }
68
69    private <T extends Number> boolean result(String testName, T javaRslt, T rsRslt) {
70        final boolean success = javaRslt.equals(rsRslt);
71        Log.i(TAG,
72                testName + ": java " + javaRslt + ", rs " + rsRslt + ": " +
73                (success ? "PASSED" : "FAILED"));
74        return success;
75    }
76
77    private boolean result(String testName, Int2 javaRslt, Int2 rsRslt) {
78        final boolean success = (javaRslt.x == rsRslt.x) && (javaRslt.y == rsRslt.y);
79        Log.i(TAG,
80                testName +
81                ": java (" + javaRslt.x + ", " + javaRslt.y + ")" +
82                ", rs (" + rsRslt.x + ", " + rsRslt.y + ")" +
83                ": " + (success ? "PASSED" : "FAILED"));
84        return success;
85    }
86
87    ///////////////////////////////////////////////////////////////////
88
89    private int addint(int[] input) {
90        int rslt = 0;
91        for (int idx = 0; idx < input.length; ++idx)
92            rslt += input[idx];
93        return rslt;
94    }
95
96    private boolean addint1D(RenderScript RS, ScriptC_reduce s) {
97        final int[] input = createInputArrayInt(100000, 0, 1 << 13);
98
99        final int javaRslt = addint(input);
100        final int rsRslt = s.reduce_addint(input).get();
101
102        return result("addint1D", javaRslt, rsRslt);
103    }
104
105    private boolean addint2D(RenderScript RS, ScriptC_reduce s) {
106        final int dimX = 450, dimY = 225;
107
108        final int[] inputArray = createInputArrayInt(dimX * dimY, 1, 1 << 13);
109        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
110        typeBuilder.setX(dimX).setY(dimY);
111        Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
112        inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray);
113
114        final int javaRslt = addint(inputArray);
115        final int rsRslt = s.reduce_addint(inputAllocation).get();
116
117        return result("addint2D", javaRslt, rsRslt);
118    }
119
120    ///////////////////////////////////////////////////////////////////
121
122    private Int2 findMinAndMax(float[] input) {
123        float minVal = Float.POSITIVE_INFINITY;
124        int minIdx = -1;
125        float maxVal = Float.NEGATIVE_INFINITY;
126        int maxIdx = -1;
127
128        for (int idx = 0; idx < input.length; ++idx) {
129            if (input[idx] < minVal) {
130                minVal = input[idx];
131                minIdx = idx;
132            }
133            if (input[idx] > maxVal) {
134                maxVal = input[idx];
135                maxIdx = idx;
136            }
137        }
138
139        return new Int2(minIdx, maxIdx);
140    }
141
142    private boolean findMinAndMax(RenderScript RS, ScriptC_reduce s) {
143        final float[] input = createInputArrayFloat(100000, 4);
144
145        final Int2 javaRslt = findMinAndMax(input);
146        final Int2 rsRslt = s.reduce_findMinAndMax(input).get();
147
148        return result("findMinAndMax", javaRslt, rsRslt);
149    }
150
151    ///////////////////////////////////////////////////////////////////
152
153    private boolean fz(RenderScript RS, ScriptC_reduce s) {
154        final int inputLen = 100000;
155        int[] input = createInputArrayInt(inputLen, 5);
156        // just in case we got unlucky
157        input[(new Random(6)).nextInt(inputLen)] = 0;
158
159        final int rsRslt = s.reduce_fz(input).get();
160
161        final boolean success = (input[rsRslt] == 0);
162        Log.i(TAG,
163                "fz: input[" + rsRslt + "] == " + input[rsRslt] + ": " +
164                (success ? "PASSED" : "FAILED"));
165        return success;
166    }
167
168    ///////////////////////////////////////////////////////////////////
169
170    private boolean fz2(RenderScript RS, ScriptC_reduce s) {
171        final int dimX = 225, dimY = 450;
172        final int inputLen = dimX * dimY;
173
174        int[] inputArray = createInputArrayInt(inputLen, 7);
175        // just in case we got unlucky
176        inputArray[(new Random(8)).nextInt(inputLen)] = 0;
177
178        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
179        typeBuilder.setX(dimX).setY(dimY);
180        Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
181        inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray);
182
183        final Int2 rsRslt = s.reduce_fz2(inputAllocation).get();
184
185        final int cellVal = inputArray[rsRslt.x + dimX * rsRslt.y];
186        final boolean success = (cellVal == 0);
187        Log.i(TAG,
188                "fz2: input[" + rsRslt.x + ", " + rsRslt.y + "] == " + cellVal + ": " +
189                (success ? "PASSED" : "FAILED"));
190        return success;
191    }
192
193    ///////////////////////////////////////////////////////////////////
194
195    private boolean fz3(RenderScript RS, ScriptC_reduce s) {
196        final int dimX = 59, dimY = 48, dimZ = 37;
197        final int inputLen = dimX * dimY * dimZ;
198
199        int[] inputArray = createInputArrayInt(inputLen, 9);
200        // just in case we got unlucky
201        inputArray[(new Random(10)).nextInt(inputLen)] = 0;
202
203        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
204        typeBuilder.setX(dimX).setY(dimY).setZ(dimZ);
205        Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
206        inputAllocation.copy3DRangeFrom(0, 0, 0, dimX, dimY, dimZ, inputArray);
207
208        final Int3 rsRslt = s.reduce_fz3(inputAllocation).get();
209
210        final int cellVal = inputArray[rsRslt.x + dimX * rsRslt.y + dimX * dimY * rsRslt.z];
211        final boolean success = (cellVal == 0);
212        Log.i(TAG,
213                "fz3: input[" + rsRslt.x + ", " + rsRslt.y + ", " + rsRslt.z + "] == " + cellVal + ": " +
214                (success ? "PASSED" : "FAILED"));
215        return success;
216    }
217
218    ///////////////////////////////////////////////////////////////////
219
220    private static final int histogramBucketCount = 256;
221
222    private long[] histogram(RenderScript RS, final byte[] inputArray) {
223        Allocation inputAllocation = Allocation.createSized(RS, Element.U8(RS), inputArray.length);
224        inputAllocation.copyFrom(inputArray);
225
226        Allocation outputAllocation = Allocation.createSized(RS, Element.U32(RS), histogramBucketCount);
227
228        ScriptIntrinsicHistogram scriptHsg = ScriptIntrinsicHistogram.create(RS, Element.U8(RS));
229        scriptHsg.setOutput(outputAllocation);
230        scriptHsg.forEach(inputAllocation);
231
232        int[] outputArrayMistyped = new int[histogramBucketCount];
233        outputAllocation.copyTo(outputArrayMistyped);
234
235        long[] outputArray = new long[histogramBucketCount];
236        for (int i = 0; i < histogramBucketCount; ++i)
237            outputArray[i] = outputArrayMistyped[i] & (long)0xffffffff;
238        return outputArray;
239    }
240
241    private boolean histogram(RenderScript RS, ScriptC_reduce s) {
242        final byte[] inputArray = createInputArrayByte(100000, 11);
243
244        final long[] javaRslt = histogram(RS, inputArray);
245        _RS_ASSERT("javaRslt unexpected length: " + javaRslt.length, javaRslt.length == histogramBucketCount);
246        final long[] rsRslt = s.reduce_histogram(inputArray).get();
247        _RS_ASSERT("rsRslt unexpected length: " + rsRslt.length, rsRslt.length == histogramBucketCount);
248
249        for (int i = 0; i < histogramBucketCount; ++i) {
250            if (javaRslt[i] != rsRslt[i]) {
251                Log.i(TAG,
252                        "histogram[" + i + "]: java " + javaRslt[i] + ", rs " + rsRslt[i] + ": FAILED");
253                return false;
254            }
255        }
256
257        Log.i(TAG, "histogram: PASSED");
258        return true;
259    }
260
261    //-----------------------------------------------------------------
262
263    private Int2 mode(RenderScript RS, final byte[] inputArray) {
264        long[] hsg = histogram(RS, inputArray);
265
266        int modeIdx = 0;
267        for (int i = 1; i < hsg.length; ++i)
268            if (hsg[i] > hsg[modeIdx]) modeIdx =i;
269        return new Int2(modeIdx, (int)hsg[modeIdx]);
270    }
271
272    private boolean mode(RenderScript RS, ScriptC_reduce s) {
273        final byte[] inputArray = createInputArrayByte(100000, 12);
274
275        final Int2 javaRslt = mode(RS, inputArray);
276        final Int2 rsRslt = s.reduce_mode(inputArray).get();
277
278        return result("mode", javaRslt, rsRslt);
279    }
280
281    ///////////////////////////////////////////////////////////////////
282
283    public void run() {
284        RenderScript pRS = RenderScript.create(mCtx);
285        ScriptC_reduce s = new ScriptC_reduce(pRS);
286        s.set_negInf(Float.NEGATIVE_INFINITY);
287        s.set_posInf(Float.POSITIVE_INFINITY);
288
289        boolean pass = true;
290        pass &= addint1D(pRS, s);
291        pass &= addint2D(pRS, s);
292        pass &= findMinAndMax(pRS, s);
293        pass &= fz(pRS, s);
294        pass &= fz2(pRS, s);
295        pass &= fz3(pRS, s);
296        pass &= histogram(pRS, s);
297        pass &= mode(pRS, s);
298
299        pRS.finish();
300        pRS.destroy();
301
302        Log.i(TAG, pass ? "PASSED" : "FAILED");
303        if (pass)
304            passTest();
305        else
306            failTest();
307    }
308}
309