173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross/*
273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross * Copyright (C) 2016 The Android Open Source Project
373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross *
473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross * Licensed under the Apache License, Version 2.0 (the "License");
573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross * you may not use this file except in compliance with the License.
673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross * You may obtain a copy of the License at
773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross *
873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross *      http://www.apache.org/licenses/LICENSE-2.0
973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross *
1073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross * Unless required by applicable law or agreed to in writing, software
1173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross * distributed under the License is distributed on an "AS IS" BASIS,
1273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross * See the License for the specific language governing permissions and
1473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross * limitations under the License.
1573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross */
1673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
17d41c224c3e1e31e29d225e51b994d689022cfd07David Gross/* This is a much simpler version of UT_reduce.java that
18d41c224c3e1e31e29d225e51b994d689022cfd07David Gross * exercises pragmas after the functions (backward reference),
19d41c224c3e1e31e29d225e51b994d689022cfd07David Gross * whereas the other test case exercises the pragmas before the
20d41c224c3e1e31e29d225e51b994d689022cfd07David Gross * functions (forward reference).
2173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross */
2273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
2373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Grosspackage com.android.rs.test;
2473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
2573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Grossimport android.content.Context;
2673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Grossimport android.content.res.Resources;
2773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Grossimport android.renderscript.*;
2873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Grossimport android.util.Log;
2973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Grossimport java.lang.Float;
3073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Grossimport java.util.Random;
3173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
3273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Grosspublic class UT_reduce_backward extends UnitTest {
3373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private static final String TAG = "reduce_backward";
3473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
3573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    protected UT_reduce_backward(RSTestCore rstc, Resources res, Context ctx) {
3673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        super(rstc, "reduce_backward", ctx);
3773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
3873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
3973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private byte[] createInputArrayByte(int len, int seed) {
4073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        byte[] array = new byte[len];
4173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        (new Random(seed)).nextBytes(array);
4273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return array;
4373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
4473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
4573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private float[] createInputArrayFloat(int len, int seed) {
4673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Random rand = new Random(seed);
4773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        float[] array = new float[len];
4873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        for (int i = 0; i < len; ++i)
4973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            array[i] = rand.nextFloat();
5073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return array;
5173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
5273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
5373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private int[] createInputArrayInt(int len, int seed) {
5473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Random rand = new Random(seed);
5573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        int[] array = new int[len];
5673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        for (int i = 0; i < len; ++i)
5773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            array[i] = rand.nextInt();
5873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return array;
5973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
6073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
6173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private int[] createInputArrayInt(int len, int seed, int eltRange) {
6273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Random rand = new Random(seed);
6373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        int[] array = new int[len];
6473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        for (int i = 0; i < len; ++i)
6573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            array[i] = rand.nextInt(eltRange);
6673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return array;
6773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
6873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
6973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private <T extends Number> boolean result(String testName, T javaRslt, T rsRslt) {
7073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final boolean success = javaRslt.equals(rsRslt);
7173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Log.i(TAG,
7273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                testName + ": java " + javaRslt + ", rs " + rsRslt + ": " +
7373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                (success ? "PASSED" : "FAILED"));
7473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return success;
7573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
7673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
77d41c224c3e1e31e29d225e51b994d689022cfd07David Gross    private boolean result(String testName, Float2 javaRslt, Float2 rsRslt) {
78d41c224c3e1e31e29d225e51b994d689022cfd07David Gross        final boolean success = (javaRslt.x == rsRslt.x) && (javaRslt.y == rsRslt.y);
79d41c224c3e1e31e29d225e51b994d689022cfd07David Gross        Log.i(TAG,
80d41c224c3e1e31e29d225e51b994d689022cfd07David Gross                testName +
81d41c224c3e1e31e29d225e51b994d689022cfd07David Gross                ": java (" + javaRslt.x + ", " + javaRslt.y + ")" +
82d41c224c3e1e31e29d225e51b994d689022cfd07David Gross                ", rs (" + rsRslt.x + ", " + rsRslt.y + ")" +
83d41c224c3e1e31e29d225e51b994d689022cfd07David Gross                ": " + (success ? "PASSED" : "FAILED"));
84d41c224c3e1e31e29d225e51b994d689022cfd07David Gross        return success;
85d41c224c3e1e31e29d225e51b994d689022cfd07David Gross    }
86d41c224c3e1e31e29d225e51b994d689022cfd07David Gross
8773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private boolean result(String testName, Int2 javaRslt, Int2 rsRslt) {
8873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final boolean success = (javaRslt.x == rsRslt.x) && (javaRslt.y == rsRslt.y);
8973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Log.i(TAG,
9073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                testName +
9173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                ": java (" + javaRslt.x + ", " + javaRslt.y + ")" +
9273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                ", rs (" + rsRslt.x + ", " + rsRslt.y + ")" +
9373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                ": " + (success ? "PASSED" : "FAILED"));
9473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return success;
9573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
9673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
9773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    ///////////////////////////////////////////////////////////////////
9873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
9973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private int addint(int[] input) {
10073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        int rslt = 0;
10173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        for (int idx = 0; idx < input.length; ++idx)
10273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            rslt += input[idx];
10373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return rslt;
10473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
10573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
10673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private boolean addint1D(RenderScript RS, ScriptC_reduce_backward s) {
10773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int[] input = createInputArrayInt(100000, 0, 1 << 13);
10873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
10973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int javaRslt = addint(input);
11073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int rsRslt = s.reduce_addint(input).get();
11173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
11273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return result("addint1D", javaRslt, rsRslt);
11373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
11473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
11573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private boolean addint2D(RenderScript RS, ScriptC_reduce_backward s) {
11673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int dimX = 450, dimY = 225;
11773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
11873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int[] inputArray = createInputArrayInt(dimX * dimY, 1, 1 << 13);
11973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
12073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        typeBuilder.setX(dimX).setY(dimY);
12173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
12273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray);
12373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
12473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int javaRslt = addint(inputArray);
12573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int rsRslt = s.reduce_addint(inputAllocation).get();
12673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
12773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return result("addint2D", javaRslt, rsRslt);
12873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
12973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
13073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    ///////////////////////////////////////////////////////////////////
13173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
13273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private Int2 findMinAndMax(float[] input) {
13373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        float minVal = Float.POSITIVE_INFINITY;
13473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        int minIdx = -1;
13573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        float maxVal = Float.NEGATIVE_INFINITY;
13673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        int maxIdx = -1;
13773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
13873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        for (int idx = 0; idx < input.length; ++idx) {
13973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            if (input[idx] < minVal) {
14073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                minVal = input[idx];
14173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                minIdx = idx;
14273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            }
14373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            if (input[idx] > maxVal) {
14473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                maxVal = input[idx];
14573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                maxIdx = idx;
14673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            }
14773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        }
14873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
14973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return new Int2(minIdx, maxIdx);
15073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
15173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
15273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private boolean findMinAndMax(RenderScript RS, ScriptC_reduce_backward s) {
15373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final float[] input = createInputArrayFloat(100000, 4);
15473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
15573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final Int2 javaRslt = findMinAndMax(input);
15673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final Int2 rsRslt = s.reduce_findMinAndMax(input).get();
15773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
158d41c224c3e1e31e29d225e51b994d689022cfd07David Gross        // Note that the Java and RenderScript algorithms are not
159d41c224c3e1e31e29d225e51b994d689022cfd07David Gross        // guaranteed to find the same cells -- but they should
160d41c224c3e1e31e29d225e51b994d689022cfd07David Gross        // find cells of the same value.
161d41c224c3e1e31e29d225e51b994d689022cfd07David Gross        final Float2 javaVal = new Float2(input[javaRslt.x], input[javaRslt.y]);
162d41c224c3e1e31e29d225e51b994d689022cfd07David Gross        final Float2 rsVal = new Float2(input[rsRslt.x], input[rsRslt.y]);
163d41c224c3e1e31e29d225e51b994d689022cfd07David Gross
164d41c224c3e1e31e29d225e51b994d689022cfd07David Gross        return result("findMinAndMax", javaVal, rsVal);
16573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
16673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
16773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    ///////////////////////////////////////////////////////////////////
16873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
16973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private boolean fz(RenderScript RS, ScriptC_reduce_backward s) {
17073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int inputLen = 100000;
17173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        int[] input = createInputArrayInt(inputLen, 5);
17273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        // just in case we got unlucky
17373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        input[(new Random(6)).nextInt(inputLen)] = 0;
17473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
17573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int rsRslt = s.reduce_fz(input).get();
17673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
17773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final boolean success = (input[rsRslt] == 0);
17873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Log.i(TAG,
17973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                "fz: input[" + rsRslt + "] == " + input[rsRslt] + ": " +
18073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                (success ? "PASSED" : "FAILED"));
18173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return success;
18273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
18373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
18473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    ///////////////////////////////////////////////////////////////////
18573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
18673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private boolean fz2(RenderScript RS, ScriptC_reduce_backward s) {
18773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int dimX = 225, dimY = 450;
18873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int inputLen = dimX * dimY;
18973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
19073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        int[] inputArray = createInputArrayInt(inputLen, 7);
19173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        // just in case we got unlucky
19273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        inputArray[(new Random(8)).nextInt(inputLen)] = 0;
19373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
19473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
19573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        typeBuilder.setX(dimX).setY(dimY);
19673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
19773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray);
19873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
19973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final Int2 rsRslt = s.reduce_fz2(inputAllocation).get();
20073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
20173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int cellVal = inputArray[rsRslt.x + dimX * rsRslt.y];
20273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final boolean success = (cellVal == 0);
20373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Log.i(TAG,
20473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                "fz2: input[" + rsRslt.x + ", " + rsRslt.y + "] == " + cellVal + ": " +
20573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                (success ? "PASSED" : "FAILED"));
20673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return success;
20773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
20873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
20973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    ///////////////////////////////////////////////////////////////////
21073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
21173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private boolean fz3(RenderScript RS, ScriptC_reduce_backward s) {
21273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int dimX = 59, dimY = 48, dimZ = 37;
21373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int inputLen = dimX * dimY * dimZ;
21473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
21573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        int[] inputArray = createInputArrayInt(inputLen, 9);
21673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        // just in case we got unlucky
21773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        inputArray[(new Random(10)).nextInt(inputLen)] = 0;
21873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
21973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
22073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        typeBuilder.setX(dimX).setY(dimY).setZ(dimZ);
22173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
22273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        inputAllocation.copy3DRangeFrom(0, 0, 0, dimX, dimY, dimZ, inputArray);
22373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
22473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final Int3 rsRslt = s.reduce_fz3(inputAllocation).get();
22573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
22673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final int cellVal = inputArray[rsRslt.x + dimX * rsRslt.y + dimX * dimY * rsRslt.z];
22773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final boolean success = (cellVal == 0);
22873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Log.i(TAG,
22973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                "fz3: input[" + rsRslt.x + ", " + rsRslt.y + ", " + rsRslt.z + "] == " + cellVal + ": " +
23073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                (success ? "PASSED" : "FAILED"));
23173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return success;
23273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
23373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
23473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    ///////////////////////////////////////////////////////////////////
23573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
23673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private static final int histogramBucketCount = 256;
23773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
23873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private long[] histogram(RenderScript RS, final byte[] inputArray) {
23973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Allocation inputAllocation = Allocation.createSized(RS, Element.U8(RS), inputArray.length);
24073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        inputAllocation.copyFrom(inputArray);
24173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
24273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Allocation outputAllocation = Allocation.createSized(RS, Element.U32(RS), histogramBucketCount);
24373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
24473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        ScriptIntrinsicHistogram scriptHsg = ScriptIntrinsicHistogram.create(RS, Element.U8(RS));
24573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        scriptHsg.setOutput(outputAllocation);
24673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        scriptHsg.forEach(inputAllocation);
24773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
24873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        int[] outputArrayMistyped = new int[histogramBucketCount];
24973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        outputAllocation.copyTo(outputArrayMistyped);
25073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
25173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        long[] outputArray = new long[histogramBucketCount];
25273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        for (int i = 0; i < histogramBucketCount; ++i)
25373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            outputArray[i] = outputArrayMistyped[i] & (long)0xffffffff;
25473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return outputArray;
25573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
25673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
25773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private boolean histogram(RenderScript RS, ScriptC_reduce_backward s) {
25873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final byte[] inputArray = createInputArrayByte(100000, 11);
25973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
26073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final long[] javaRslt = histogram(RS, inputArray);
26173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        _RS_ASSERT("javaRslt unexpected length: " + javaRslt.length, javaRslt.length == histogramBucketCount);
26273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final long[] rsRslt = s.reduce_histogram(inputArray).get();
26373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        _RS_ASSERT("rsRslt unexpected length: " + rsRslt.length, rsRslt.length == histogramBucketCount);
26473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
26573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        for (int i = 0; i < histogramBucketCount; ++i) {
26673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            if (javaRslt[i] != rsRslt[i]) {
26773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                Log.i(TAG,
26873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                        "histogram[" + i + "]: java " + javaRslt[i] + ", rs " + rsRslt[i] + ": FAILED");
26973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross                return false;
27073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            }
27173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        }
27273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
27373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Log.i(TAG, "histogram: PASSED");
27473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return true;
27573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
27673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
27773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    //-----------------------------------------------------------------
27873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
27973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private Int2 mode(RenderScript RS, final byte[] inputArray) {
28073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        long[] hsg = histogram(RS, inputArray);
28173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
28273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        int modeIdx = 0;
28373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        for (int i = 1; i < hsg.length; ++i)
28473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            if (hsg[i] > hsg[modeIdx]) modeIdx =i;
28573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return new Int2(modeIdx, (int)hsg[modeIdx]);
28673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
28773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
28873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    private boolean mode(RenderScript RS, ScriptC_reduce_backward s) {
28973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final byte[] inputArray = createInputArrayByte(100000, 12);
29073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
29173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final Int2 javaRslt = mode(RS, inputArray);
29273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        final Int2 rsRslt = s.reduce_mode(inputArray).get();
29373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
29473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        return result("mode", javaRslt, rsRslt);
29573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
29673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
29773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    ///////////////////////////////////////////////////////////////////
29873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
29973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    public void run() {
30073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        RenderScript pRS = RenderScript.create(mCtx);
30173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        ScriptC_reduce_backward s = new ScriptC_reduce_backward(pRS);
30273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        s.set_negInf(Float.NEGATIVE_INFINITY);
30373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        s.set_posInf(Float.POSITIVE_INFINITY);
30473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
30573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        boolean pass = true;
30673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        pass &= addint1D(pRS, s);
30773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        pass &= addint2D(pRS, s);
30873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        pass &= findMinAndMax(pRS, s);
30973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        pass &= fz(pRS, s);
31073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        pass &= fz2(pRS, s);
31173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        pass &= fz3(pRS, s);
31273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        pass &= histogram(pRS, s);
31373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        pass &= mode(pRS, s);
31473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
31573a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        pRS.finish();
31673a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        pRS.destroy();
31773a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross
31873a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        Log.i(TAG, pass ? "PASSED" : "FAILED");
31973a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        if (pass)
32073a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            passTest();
32173a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross        else
32273a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross            failTest();
32373a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross    }
32473a422b2f32f947ce1b1366a6c78ddec58a4c1eaDavid Gross}
325