16c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross/*
26c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross * Copyright (C) 2016 The Android Open Source Project
36c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross *
46c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross * Licensed under the Apache License, Version 2.0 (the "License");
56c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross * you may not use this file except in compliance with the License.
66c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross * You may obtain a copy of the License at
76c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross *
86c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross *      http://www.apache.org/licenses/LICENSE-2.0
96c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross *
106c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross * Unless required by applicable law or agreed to in writing, software
116c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross * distributed under the License is distributed on an "AS IS" BASIS,
126c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross * See the License for the specific language governing permissions and
146c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross * limitations under the License.
156c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross */
166c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
173fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross/* UT_reduce_backward.java is a much simpler version of this test
183fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross * case that exercises pragmas after the functions (backward
193fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross * reference), whereas this test case exercises the pragmas before
203fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross * the functions (forward reference).
2123966203d0b4d4a7da90d521349dbb77d7283261David Gross */
2223966203d0b4d4a7da90d521349dbb77d7283261David Gross
236c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Grosspackage com.android.rs.test;
246c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
256c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Grossimport android.content.Context;
26c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.Allocation;
27c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.Element;
28c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.Float2;
29c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.Int2;
30c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.Int3;
31c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.RenderScript;
32c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.ScriptIntrinsicHistogram;
33c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.Type;
346c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Grossimport android.util.Log;
3533709e1da5e801ca331642c25a61847ced8539e8Miao Wang
363fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Grossimport java.util.ArrayList;
3735dbc8c20814997a00e06d7798a5633c37706978David Grossimport java.util.Arrays;
386c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Grossimport java.util.Random;
3933709e1da5e801ca331642c25a61847ced8539e8Miao Wang
40c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport static junit.framework.Assert.assertEquals;
41c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport static junit.framework.Assert.assertTrue;
426c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
436c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Grosspublic class UT_reduce extends UnitTest {
446c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    private static final String TAG = "reduce";
456c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
4633709e1da5e801ca331642c25a61847ced8539e8Miao Wang    protected UT_reduce(RSTestCore rstc, Context ctx) {
476c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        super(rstc, "reduce", ctx);
486c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
496c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
5035dbc8c20814997a00e06d7798a5633c37706978David Gross    private static class timing {
5135dbc8c20814997a00e06d7798a5633c37706978David Gross        timing(long myJavaStart, long myJavaEnd, long myRsStart,
5235dbc8c20814997a00e06d7798a5633c37706978David Gross               long myCopyStart, long myKernelStart, long myRsEnd,
5335dbc8c20814997a00e06d7798a5633c37706978David Gross               Allocation... myInputs) {
5435dbc8c20814997a00e06d7798a5633c37706978David Gross            javaStart = myJavaStart;
5535dbc8c20814997a00e06d7798a5633c37706978David Gross            javaEnd = myJavaEnd;
5635dbc8c20814997a00e06d7798a5633c37706978David Gross            rsStart = myRsStart;
5735dbc8c20814997a00e06d7798a5633c37706978David Gross            copyStart = myCopyStart;
5835dbc8c20814997a00e06d7798a5633c37706978David Gross            kernelStart = myKernelStart;
5935dbc8c20814997a00e06d7798a5633c37706978David Gross            rsEnd = myRsEnd;
6035dbc8c20814997a00e06d7798a5633c37706978David Gross
6135dbc8c20814997a00e06d7798a5633c37706978David Gross            inputBytes = 0;
6235dbc8c20814997a00e06d7798a5633c37706978David Gross            for (Allocation input : myInputs)
6335dbc8c20814997a00e06d7798a5633c37706978David Gross                inputBytes += input.getBytesSize();
6435dbc8c20814997a00e06d7798a5633c37706978David Gross
6535dbc8c20814997a00e06d7798a5633c37706978David Gross            inputCells = (myInputs.length > 0) ? myInputs[0].getType().getCount() : 0;
6635dbc8c20814997a00e06d7798a5633c37706978David Gross        }
6735dbc8c20814997a00e06d7798a5633c37706978David Gross
6835dbc8c20814997a00e06d7798a5633c37706978David Gross        timing(long myInputCells) {
6935dbc8c20814997a00e06d7798a5633c37706978David Gross            inputCells = myInputCells;
7035dbc8c20814997a00e06d7798a5633c37706978David Gross        }
7135dbc8c20814997a00e06d7798a5633c37706978David Gross
7235dbc8c20814997a00e06d7798a5633c37706978David Gross        private long javaStart = -1;
7335dbc8c20814997a00e06d7798a5633c37706978David Gross        private long javaEnd = -1;
7435dbc8c20814997a00e06d7798a5633c37706978David Gross        private long rsStart = -1;
7535dbc8c20814997a00e06d7798a5633c37706978David Gross        private long copyStart = -1;
7635dbc8c20814997a00e06d7798a5633c37706978David Gross        private long kernelStart = -1;
7735dbc8c20814997a00e06d7798a5633c37706978David Gross        private long rsEnd = -1;
7835dbc8c20814997a00e06d7798a5633c37706978David Gross        private long inputBytes = -1;
7935dbc8c20814997a00e06d7798a5633c37706978David Gross        private long inputCells = -1;
8035dbc8c20814997a00e06d7798a5633c37706978David Gross
81c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        public long javaTime() {
82c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            return javaEnd - javaStart;
83c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        }
84c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang
85c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        public long rsTime() {
86c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            return rsEnd - rsStart;
87c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        }
88c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang
89c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        public long kernelTime() {
90c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            return rsEnd - kernelStart;
91c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        }
92c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang
93c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        public long overheadTime() {
94c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            return kernelStart - rsStart;
95c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        }
96c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang
97c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        public long allocationTime() {
98c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            return copyStart - rsStart;
99c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        }
100c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang
101c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        public long copyTime() {
102c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            return kernelStart - copyStart;
103c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        }
10435dbc8c20814997a00e06d7798a5633c37706978David Gross
10535dbc8c20814997a00e06d7798a5633c37706978David Gross        public static String string(long myJavaStart, long myJavaEnd, long myRsStart,
10635dbc8c20814997a00e06d7798a5633c37706978David Gross                                    long myCopyStart, long myKernelStart, long myRsEnd,
10735dbc8c20814997a00e06d7798a5633c37706978David Gross                                    Allocation... myInputs) {
10835dbc8c20814997a00e06d7798a5633c37706978David Gross            return (new timing(myJavaStart, myJavaEnd, myRsStart,
109c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    myCopyStart, myKernelStart, myRsEnd, myInputs)).string();
11035dbc8c20814997a00e06d7798a5633c37706978David Gross        }
11135dbc8c20814997a00e06d7798a5633c37706978David Gross
11235dbc8c20814997a00e06d7798a5633c37706978David Gross        public static String string(long myInputCells) {
11335dbc8c20814997a00e06d7798a5633c37706978David Gross            return (new timing(myInputCells)).string();
11435dbc8c20814997a00e06d7798a5633c37706978David Gross        }
11535dbc8c20814997a00e06d7798a5633c37706978David Gross
11635dbc8c20814997a00e06d7798a5633c37706978David Gross        public String string() {
11735dbc8c20814997a00e06d7798a5633c37706978David Gross            String result;
11835dbc8c20814997a00e06d7798a5633c37706978David Gross            if (javaStart >= 0) {
11935dbc8c20814997a00e06d7798a5633c37706978David Gross                result = "(java " + javaTime() + "ms, rs " + rsTime() + "ms = overhead " +
120c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        overheadTime() + "ms (alloc " + allocationTime() + "ms + copy " +
121c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        copyTime() + "ms) + kernel+get() " + kernelTime() + "ms)";
12235dbc8c20814997a00e06d7798a5633c37706978David Gross                if (inputCells > 0)
12335dbc8c20814997a00e06d7798a5633c37706978David Gross                    result += " ";
12435dbc8c20814997a00e06d7798a5633c37706978David Gross            } else {
12535dbc8c20814997a00e06d7798a5633c37706978David Gross                result = "";
12635dbc8c20814997a00e06d7798a5633c37706978David Gross            }
12735dbc8c20814997a00e06d7798a5633c37706978David Gross            if (inputCells > 0) {
12835dbc8c20814997a00e06d7798a5633c37706978David Gross                result += "(" + fmt.format(inputCells) + " cells";
12935dbc8c20814997a00e06d7798a5633c37706978David Gross                if (inputBytes > 0)
13035dbc8c20814997a00e06d7798a5633c37706978David Gross                    result += ", " + fmt.format(inputBytes) + " bytes";
13135dbc8c20814997a00e06d7798a5633c37706978David Gross                result += ")";
13235dbc8c20814997a00e06d7798a5633c37706978David Gross            }
13335dbc8c20814997a00e06d7798a5633c37706978David Gross            return result;
13435dbc8c20814997a00e06d7798a5633c37706978David Gross        }
13535dbc8c20814997a00e06d7798a5633c37706978David Gross
13635dbc8c20814997a00e06d7798a5633c37706978David Gross        private static java.text.DecimalFormat fmt;
137c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang
13835dbc8c20814997a00e06d7798a5633c37706978David Gross        static {
13935dbc8c20814997a00e06d7798a5633c37706978David Gross            fmt = new java.text.DecimalFormat("###,###");
14035dbc8c20814997a00e06d7798a5633c37706978David Gross        }
141c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang    }
14235dbc8c20814997a00e06d7798a5633c37706978David Gross
1436c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    private byte[] createInputArrayByte(int len, int seed) {
1446c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        byte[] array = new byte[len];
1456c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        (new Random(seed)).nextBytes(array);
1466c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        return array;
1476c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
1486c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
1496ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    private float[] createInputArrayFloat(int len, Random rand) {
1506ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        float[] array = new float[len];
1516ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        for (int i = 0; i < len; ++i) {
1526ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross            final float val = rand.nextFloat();
1536ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross            array[i] = rand.nextBoolean() ? val : -val;
1546ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        }
1556ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        return array;
1566ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    }
1576ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
1586c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    private float[] createInputArrayFloat(int len, int seed) {
1596ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        return createInputArrayFloat(len, new Random(seed));
1606ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    }
1616ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
1626ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    private float[] createInputArrayFloatWithInfs(int len, int infs, int seed) {
1636c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Random rand = new Random(seed);
1646ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        float[] array = createInputArrayFloat(len, rand);
1656ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        for (int i = 0; i < infs; ++i)
1666ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross            array[rand.nextInt(len)] = (rand.nextBoolean() ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY);
1676c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        return array;
1686c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
1696c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
1706c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    private int[] createInputArrayInt(int len, int seed) {
1716c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Random rand = new Random(seed);
1726c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        int[] array = new int[len];
1736c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        for (int i = 0; i < len; ++i)
1746c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross            array[i] = rand.nextInt();
1756c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        return array;
1766c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
1776c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
1786c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    private int[] createInputArrayInt(int len, int seed, int eltRange) {
1796c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Random rand = new Random(seed);
1806c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        int[] array = new int[len];
1816c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        for (int i = 0; i < len; ++i)
1826c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross            array[i] = rand.nextInt(eltRange);
1836c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        return array;
1846c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
1856c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
186ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    private long[] intArrayToLong(final int[] input) {
187ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        final long[] output = new long[input.length];
188ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
189ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        for (int i = 0; i < input.length; ++i)
190ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross            output[i] = input[i];
191ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
192ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        return output;
193ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    }
194ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
19535dbc8c20814997a00e06d7798a5633c37706978David Gross    private <T extends Number> boolean result(String testName, final timing t,
1966ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                                              T javaResult, T rsResult) {
1976ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final boolean success = javaResult.equals(rsResult);
19835dbc8c20814997a00e06d7798a5633c37706978David Gross        String status = (success ? "PASSED" : "FAILED");
19935dbc8c20814997a00e06d7798a5633c37706978David Gross        if (success && (t != null))
20035dbc8c20814997a00e06d7798a5633c37706978David Gross            status += " " + t.string();
2016ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        Log.i(TAG, testName + ": java " + javaResult + ", rs " + rsResult + ": " + status);
20235dbc8c20814997a00e06d7798a5633c37706978David Gross        return success;
20335dbc8c20814997a00e06d7798a5633c37706978David Gross    }
20435dbc8c20814997a00e06d7798a5633c37706978David Gross
20535dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean result(String testName, final timing t,
2066ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                           final float[] javaResult, final float[] rsResult) {
2076ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        if (javaResult.length != rsResult.length) {
2086ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross            Log.i(TAG, testName + ": java length " + javaResult.length +
209c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    ", rs length " + rsResult.length + ": FAILED");
210140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross            return false;
211140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        }
2126ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        for (int i = 0; i < javaResult.length; ++i) {
2136ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross            if (javaResult[i] != rsResult[i]) {
2146ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                Log.i(TAG, testName + "[" + i + "]: java " + javaResult[i] +
215c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        ", rs " + rsResult[i] + ": FAILED");
216140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross                return false;
217140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross            }
218140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        }
219140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        String status = "PASSED";
220140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        if (t != null)
221140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross            status += " " + t.string();
222140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        Log.i(TAG, testName + ": " + status);
223140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        return true;
224140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    }
225140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
226140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    private boolean result(String testName, final timing t,
2276ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                           final long[] javaResult, final long[] rsResult) {
2286ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        if (javaResult.length != rsResult.length) {
2296ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross            Log.i(TAG, testName + ": java length " + javaResult.length +
230c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    ", rs length " + rsResult.length + ": FAILED");
23135dbc8c20814997a00e06d7798a5633c37706978David Gross            return false;
23235dbc8c20814997a00e06d7798a5633c37706978David Gross        }
2336ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        for (int i = 0; i < javaResult.length; ++i) {
2346ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross            if (javaResult[i] != rsResult[i]) {
2356ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                Log.i(TAG, testName + "[" + i + "]: java " + javaResult[i] +
236c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        ", rs " + rsResult[i] + ": FAILED");
23735dbc8c20814997a00e06d7798a5633c37706978David Gross                return false;
23835dbc8c20814997a00e06d7798a5633c37706978David Gross            }
23935dbc8c20814997a00e06d7798a5633c37706978David Gross        }
24035dbc8c20814997a00e06d7798a5633c37706978David Gross        String status = "PASSED";
24135dbc8c20814997a00e06d7798a5633c37706978David Gross        if (t != null)
24235dbc8c20814997a00e06d7798a5633c37706978David Gross            status += " " + t.string();
24335dbc8c20814997a00e06d7798a5633c37706978David Gross        Log.i(TAG, testName + ": " + status);
24435dbc8c20814997a00e06d7798a5633c37706978David Gross        return true;
24535dbc8c20814997a00e06d7798a5633c37706978David Gross    }
24635dbc8c20814997a00e06d7798a5633c37706978David Gross
247ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    private boolean result(String testName, final timing t,
2486ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                           final int[] javaResult, final int[] rsResult) {
2496ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        return result(testName, t, intArrayToLong(javaResult), intArrayToLong(rsResult));
250ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    }
251ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
2526ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    private boolean result(String testName, final timing t, Int2 javaResult, Int2 rsResult) {
2536ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final boolean success = (javaResult.x == rsResult.x) && (javaResult.y == rsResult.y);
25435dbc8c20814997a00e06d7798a5633c37706978David Gross        String status = (success ? "PASSED" : "FAILED");
25535dbc8c20814997a00e06d7798a5633c37706978David Gross        if (success && (t != null))
25635dbc8c20814997a00e06d7798a5633c37706978David Gross            status += " " + t.string();
2576c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Log.i(TAG,
25835dbc8c20814997a00e06d7798a5633c37706978David Gross                testName +
259c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        ": java (" + javaResult.x + ", " + javaResult.y + ")" +
260c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        ", rs (" + rsResult.x + ", " + rsResult.y + ")" +
261c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        ": " + status);
2626c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        return success;
2636c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
2646c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
2656ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    private boolean result(String testName, final timing t, Float2 javaResult, Float2 rsResult) {
2666ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final boolean success = (javaResult.x == rsResult.x) && (javaResult.y == rsResult.y);
26735dbc8c20814997a00e06d7798a5633c37706978David Gross        String status = (success ? "PASSED" : "FAILED");
26835dbc8c20814997a00e06d7798a5633c37706978David Gross        if (success && (t != null))
26935dbc8c20814997a00e06d7798a5633c37706978David Gross            status += " " + t.string();
2706c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Log.i(TAG,
2716c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross                testName +
272c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        ": java (" + javaResult.x + ", " + javaResult.y + ")" +
273c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        ", rs (" + rsResult.x + ", " + rsResult.y + ")" +
274c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        ": " + status);
2756c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        return success;
2766c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
2776c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
2786c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    ///////////////////////////////////////////////////////////////////
2796c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
2806c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    private int addint(int[] input) {
2816ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        int result = 0;
2826c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        for (int idx = 0; idx < input.length; ++idx)
2836ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross            result += input[idx];
2846ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        return result;
2856c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
2866c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
28735dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean addint1D_array(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
28835dbc8c20814997a00e06d7798a5633c37706978David Gross        final int[] input = createInputArrayInt(size[0], seed, Integer.MAX_VALUE / size[0]);
2896c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
2906ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int javaResult = addint(input);
2916ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int rsResult = s.reduce_addint(input).get();
2926c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
2936ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        return result("addint1D_array", new timing(size[0]), javaResult, rsResult);
2946c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
2956c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
29635dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean addint1D(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
29735dbc8c20814997a00e06d7798a5633c37706978David Gross        final int[] inputArray = createInputArrayInt(size[0], seed, Integer.MAX_VALUE / size[0]);
2986c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
29935dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeStart = java.lang.System.currentTimeMillis();
3006ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int javaResult = addint(inputArray);
30135dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeEnd = java.lang.System.currentTimeMillis();
30235dbc8c20814997a00e06d7798a5633c37706978David Gross
30335dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeStart = java.lang.System.currentTimeMillis();
30435dbc8c20814997a00e06d7798a5633c37706978David Gross
30535dbc8c20814997a00e06d7798a5633c37706978David Gross        Allocation inputAllocation = Allocation.createSized(RS, Element.I32(RS), inputArray.length);
30635dbc8c20814997a00e06d7798a5633c37706978David Gross
30735dbc8c20814997a00e06d7798a5633c37706978David Gross        final long copyTimeStart = java.lang.System.currentTimeMillis();
30835dbc8c20814997a00e06d7798a5633c37706978David Gross
30935dbc8c20814997a00e06d7798a5633c37706978David Gross        inputAllocation.copyFrom(inputArray);
31035dbc8c20814997a00e06d7798a5633c37706978David Gross
31135dbc8c20814997a00e06d7798a5633c37706978David Gross        final long kernelTimeStart = java.lang.System.currentTimeMillis();
3126ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int rsResult = s.reduce_addint(inputAllocation).get();
31335dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeEnd = java.lang.System.currentTimeMillis();
3146c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
3153fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final boolean success =
3163fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                result("addint1D",
3173fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                        new timing(javaTimeStart, javaTimeEnd, rsTimeStart,
318c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                                copyTimeStart, kernelTimeStart, rsTimeEnd, inputAllocation),
3196ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                        javaResult, rsResult);
3203fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocation.destroy();
3213fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        return success;
3226c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
3236c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
32435dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean addint2D(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
32535dbc8c20814997a00e06d7798a5633c37706978David Gross        final int dimX = size[0];
32635dbc8c20814997a00e06d7798a5633c37706978David Gross        final int dimY = size[1];
3276c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
32835dbc8c20814997a00e06d7798a5633c37706978David Gross        final int[] inputArray = createInputArrayInt(dimX * dimY, seed, Integer.MAX_VALUE / (dimX * dimY));
3296c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
33035dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeStart = java.lang.System.currentTimeMillis();
3316ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int javaResult = addint(inputArray);
33235dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeEnd = java.lang.System.currentTimeMillis();
33335dbc8c20814997a00e06d7798a5633c37706978David Gross
33435dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeStart = java.lang.System.currentTimeMillis();
3356c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
33635dbc8c20814997a00e06d7798a5633c37706978David Gross        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
33735dbc8c20814997a00e06d7798a5633c37706978David Gross        typeBuilder.setX(dimX).setY(dimY);
33835dbc8c20814997a00e06d7798a5633c37706978David Gross        Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
3396c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
34035dbc8c20814997a00e06d7798a5633c37706978David Gross        final long copyTimeStart = java.lang.System.currentTimeMillis();
3416c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
34235dbc8c20814997a00e06d7798a5633c37706978David Gross        inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray);
34335dbc8c20814997a00e06d7798a5633c37706978David Gross
34435dbc8c20814997a00e06d7798a5633c37706978David Gross        final long kernelTimeStart = java.lang.System.currentTimeMillis();
3456ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int rsResult = s.reduce_addint(inputAllocation).get();
34635dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeEnd = java.lang.System.currentTimeMillis();
34735dbc8c20814997a00e06d7798a5633c37706978David Gross
3483fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final boolean success =
3493fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                result("addint2D",
3503fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                        new timing(javaTimeStart, javaTimeEnd, rsTimeStart,
351c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                                copyTimeStart, kernelTimeStart, rsTimeEnd, inputAllocation),
3526ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                        javaResult, rsResult);
3533fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocation.destroy();
3543fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        return success;
3553fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    }
3563fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
3573fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    private boolean addint3D(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
3583fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int dimX = size[0];
3593fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int dimY = size[1];
3603fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int dimZ = size[2];
3613fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
3623fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int[] inputArray = createInputArrayInt(dimX * dimY * dimZ, seed, Integer.MAX_VALUE / (dimX * dimY * dimZ));
3633fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
3643fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final long javaTimeStart = java.lang.System.currentTimeMillis();
3656ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int javaResult = addint(inputArray);
3663fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final long javaTimeEnd = java.lang.System.currentTimeMillis();
3673fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
3683fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final long rsTimeStart = java.lang.System.currentTimeMillis();
3693fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
3703fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
3713fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        typeBuilder.setX(dimX).setY(dimY).setZ(dimZ);
3723fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
3733fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
3743fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final long copyTimeStart = java.lang.System.currentTimeMillis();
3753fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
3763fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocation.copy3DRangeFrom(0, 0, 0, dimX, dimY, dimZ, inputArray);
3773fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
3783fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final long kernelTimeStart = java.lang.System.currentTimeMillis();
3796ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int rsResult = s.reduce_addint(inputAllocation).get();
3803fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final long rsTimeEnd = java.lang.System.currentTimeMillis();
3813fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
3823fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final boolean success =
3833fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                result("addint3D",
3843fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                        new timing(javaTimeStart, javaTimeEnd, rsTimeStart,
385c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                                copyTimeStart, kernelTimeStart, rsTimeEnd, inputAllocation),
3866ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                        javaResult, rsResult);
3873fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocation.destroy();
3883fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        return success;
3896c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
3906c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
391ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    //-----------------------------------------------------------------
392ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
393cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross    private boolean patternInterleavedReduce(RenderScript RS, ScriptC_reduce s) {
394cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        // Run two reduce operations without forcing completion between them.
395cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        // We want to ensure that the driver can handle this, and that
396cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        // temporary Allocations created to run the reduce operations survive
397cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        // until get().
398cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
399cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        boolean pass = true;
400cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
401cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        final int inputSize = (1 << 18);
402cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
403cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        final int[] input1 = createInputArrayInt(123, Integer.MAX_VALUE / inputSize);
404cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        final int[] input2 = createInputArrayInt(456, Integer.MAX_VALUE / inputSize);
405cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
4066ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int javaResult1 = addint(input1);
4076ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int javaResult2 = addint(input2);
408cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
4096ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final ScriptC_reduce.result_int rsResultFuture1 = s.reduce_addint(input1);
4106ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final ScriptC_reduce.result_int rsResultFuture2 = s.reduce_addint(input2);
411cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
412cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        pass &= result("patternInterleavedReduce (1)", new timing(inputSize),
4136ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                javaResult1, rsResultFuture1.get());
414cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        pass &= result("patternInterleavedReduce (2)", new timing(inputSize),
4156ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                javaResult2, rsResultFuture2.get());
416cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
417cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        return pass;
418cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross    }
419cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
420ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    //-----------------------------------------------------------------
421ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
422ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    private int[] sillySumIntoDecArray(final int[] input) {
423ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        final int resultScalar = addint(input);
424ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        final int[] result = new int[4];
425ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        for (int i = 0; i < 4; ++i)
426c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            result[i] = resultScalar / (i + 1);
427ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        return result;
428ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    }
429ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
430ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    private int[] sillySumIntoIncArray(final int[] input) {
431ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        final int resultScalar = addint(input);
432ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        final int[] result = new int[4];
433ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        for (int i = 0; i < 4; ++i)
434c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            result[i] = resultScalar / (4 - i);
435ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        return result;
436ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    }
437ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
438ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    private boolean patternDuplicateAnonymousResult(RenderScript RS, ScriptC_reduce s) {
439ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        // Ensure that we can have two kernels with the same anonymous result type.
440ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
441ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        boolean pass = true;
442ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
443ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        final int inputSize = 1000;
444ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        final int[] input = createInputArrayInt(149, Integer.MAX_VALUE / inputSize);
445ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
4466ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int[] javaResultDec = sillySumIntoDecArray(input);
4476ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int[] rsResultDec = s.reduce_sillySumIntoDecArray(input).get();
448ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        pass &= result("patternDuplicateAnonymousResult (Dec)", new timing(inputSize),
4496ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                javaResultDec, rsResultDec);
450ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
4516ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int[] javaResultInc = sillySumIntoIncArray(input);
4526ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int[] rsResultInc = s.reduce_sillySumIntoIncArray(input).get();
453ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        pass &= result("patternDuplicateAnonymousResult (Inc)", new timing(inputSize),
4546ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                javaResultInc, rsResultInc);
455ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
456ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        return pass;
457ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    }
458ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
4596c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    ///////////////////////////////////////////////////////////////////
4606c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
4616ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    private float findMinAbs(float[] input) {
4626ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        float accum = input[0];
4636ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        for (int idx = 1; idx < input.length; ++idx) {
4646ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross            final float val = input[idx];
4656ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross            if (Math.abs(val) < Math.abs(accum))
4666ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                accum = val;
4676ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        }
4686ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        return accum;
4696ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    }
4706ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
4716ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    static interface ReduceFindMinAbs {
4726ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        float run(Allocation input);
473c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang    }
4746ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
4756ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    private boolean findMinAbs(RenderScript RS, float[] inputArray, String testName, ReduceFindMinAbs reduction) {
4766ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long javaTimeStart = java.lang.System.currentTimeMillis();
4776ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final float javaResult = findMinAbs(inputArray);
4786ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long javaTimeEnd = java.lang.System.currentTimeMillis();
4796ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
4806ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long rsTimeStart = java.lang.System.currentTimeMillis();
4816ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
4826ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        Allocation inputAllocation = Allocation.createSized(RS, Element.F32(RS), inputArray.length);
4836ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
4846ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long copyTimeStart = java.lang.System.currentTimeMillis();
4856ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
4866ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        inputAllocation.copyFrom(inputArray);
4876ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
4886ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long kernelTimeStart = java.lang.System.currentTimeMillis();
4896ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final float rsResult = reduction.run(inputAllocation);
4906ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long rsTimeEnd = java.lang.System.currentTimeMillis();
4916ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
4926ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        // Note that the Java and RenderScript algorithms are not
4936ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        // guaranteed to find the same results -- but the results
4946ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        // should have the same absolute value.
4956ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
4966ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final boolean success =
4976ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                result(testName,
4986ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                        new timing(javaTimeStart, javaTimeEnd, rsTimeStart,
499c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                                copyTimeStart, kernelTimeStart, rsTimeEnd, inputAllocation),
5006ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                        Math.abs(javaResult), Math.abs(rsResult));
5016ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        inputAllocation.destroy();
5026ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        return success;
5036ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    }
5046ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
5056ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    private boolean findMinAbsBool(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
5066ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        return findMinAbs(RS, createInputArrayFloat(size[0], seed), "findMinAbsBool",
5076ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                (Allocation input) -> s.reduce_findMinAbsBool(input).get());
5086ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    }
5096ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
5106ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    private boolean findMinAbsBoolInf(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
511c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        return findMinAbs(RS, createInputArrayFloatWithInfs(size[0], 1 + size[0] / 1000, seed), "findMinAbsBoolInf",
5126ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                (Allocation input) -> s.reduce_findMinAbsBool(input).get());
5136ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    }
5146ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
5156ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    private boolean findMinAbsNaN(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
5166ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        return findMinAbs(RS, createInputArrayFloat(size[0], seed), "findMinAbsNaN",
5176ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                (Allocation input) -> s.reduce_findMinAbsNaN(input).get());
5186ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    }
5196ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
5206ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    private boolean findMinAbsNaNInf(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
521c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        return findMinAbs(RS, createInputArrayFloatWithInfs(size[0], 1 + size[0] / 1000, seed), "findMinAbsNaNInf",
5226ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                (Allocation input) -> s.reduce_findMinAbsNaN(input).get());
5236ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    }
5246ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
5256ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross    ///////////////////////////////////////////////////////////////////
5266ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross
5276c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    private Int2 findMinAndMax(float[] input) {
5286c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        float minVal = Float.POSITIVE_INFINITY;
5296c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        int minIdx = -1;
5306c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        float maxVal = Float.NEGATIVE_INFINITY;
5316c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        int maxIdx = -1;
5326c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
5336c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        for (int idx = 0; idx < input.length; ++idx) {
5342e2237911682e25612c9a3755910cfc33402840dDavid Gross            if ((minIdx < 0) || (input[idx] < minVal)) {
5356c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross                minVal = input[idx];
5366c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross                minIdx = idx;
5376c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross            }
5382e2237911682e25612c9a3755910cfc33402840dDavid Gross            if ((maxIdx < 0) || (input[idx] > maxVal)) {
5396c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross                maxVal = input[idx];
5406c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross                maxIdx = idx;
5416c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross            }
5426c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        }
5436c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
5446c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        return new Int2(minIdx, maxIdx);
5456c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
5466c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
54735dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean findMinAndMax_array(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
54835dbc8c20814997a00e06d7798a5633c37706978David Gross        final float[] input = createInputArrayFloat(size[0], seed);
5496c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
5506ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Int2 javaResult = findMinAndMax(input);
5516ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Int2 rsResult = s.reduce_findMinAndMax(input).get();
5526c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
55335dbc8c20814997a00e06d7798a5633c37706978David Gross        // Note that the Java and RenderScript algorithms are not
55435dbc8c20814997a00e06d7798a5633c37706978David Gross        // guaranteed to find the same cells -- but they should
55535dbc8c20814997a00e06d7798a5633c37706978David Gross        // find cells of the same value.
5566ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Float2 javaVal = new Float2(input[javaResult.x], input[javaResult.y]);
5576ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Float2 rsVal = new Float2(input[rsResult.x], input[rsResult.y]);
55835dbc8c20814997a00e06d7798a5633c37706978David Gross
55935dbc8c20814997a00e06d7798a5633c37706978David Gross        return result("findMinAndMax_array", new timing(size[0]), javaVal, rsVal);
56035dbc8c20814997a00e06d7798a5633c37706978David Gross    }
56135dbc8c20814997a00e06d7798a5633c37706978David Gross
56235dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean findMinAndMax(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
56335dbc8c20814997a00e06d7798a5633c37706978David Gross        final float[] inputArray = createInputArrayFloat(size[0], seed);
56435dbc8c20814997a00e06d7798a5633c37706978David Gross
56535dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeStart = java.lang.System.currentTimeMillis();
5666ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Int2 javaResult = findMinAndMax(inputArray);
56735dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeEnd = java.lang.System.currentTimeMillis();
56835dbc8c20814997a00e06d7798a5633c37706978David Gross
56935dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeStart = java.lang.System.currentTimeMillis();
57035dbc8c20814997a00e06d7798a5633c37706978David Gross
57135dbc8c20814997a00e06d7798a5633c37706978David Gross        Allocation inputAllocation = Allocation.createSized(RS, Element.F32(RS), inputArray.length);
57235dbc8c20814997a00e06d7798a5633c37706978David Gross
57335dbc8c20814997a00e06d7798a5633c37706978David Gross        final long copyTimeStart = java.lang.System.currentTimeMillis();
57435dbc8c20814997a00e06d7798a5633c37706978David Gross
57535dbc8c20814997a00e06d7798a5633c37706978David Gross        inputAllocation.copyFrom(inputArray);
57635dbc8c20814997a00e06d7798a5633c37706978David Gross
57735dbc8c20814997a00e06d7798a5633c37706978David Gross        final long kernelTimeStart = java.lang.System.currentTimeMillis();
5786ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Int2 rsResult = s.reduce_findMinAndMax(inputAllocation).get();
57935dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeEnd = java.lang.System.currentTimeMillis();
58035dbc8c20814997a00e06d7798a5633c37706978David Gross
58135dbc8c20814997a00e06d7798a5633c37706978David Gross        // Note that the Java and RenderScript algorithms are not
58235dbc8c20814997a00e06d7798a5633c37706978David Gross        // guaranteed to find the same cells -- but they should
58335dbc8c20814997a00e06d7798a5633c37706978David Gross        // find cells of the same value.
5846ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Float2 javaVal = new Float2(inputArray[javaResult.x], inputArray[javaResult.y]);
5856ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Float2 rsVal = new Float2(inputArray[rsResult.x], inputArray[rsResult.y]);
58635dbc8c20814997a00e06d7798a5633c37706978David Gross
5873fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final boolean success =
5883fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                result("findMinAndMax",
5893fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                        new timing(javaTimeStart, javaTimeEnd, rsTimeStart,
590c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                                copyTimeStart, kernelTimeStart, rsTimeEnd, inputAllocation),
5913fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                        javaVal, rsVal);
5923fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocation.destroy();
5933fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        return success;
5946c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
5956c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
5962e2237911682e25612c9a3755910cfc33402840dDavid Gross    //-----------------------------------------------------------------
5972e2237911682e25612c9a3755910cfc33402840dDavid Gross
5982e2237911682e25612c9a3755910cfc33402840dDavid Gross    private boolean patternFindMinAndMaxInf(RenderScript RS, ScriptC_reduce s) {
5992e2237911682e25612c9a3755910cfc33402840dDavid Gross        // Run this kernel on an input consisting solely of a single infinity.
6002e2237911682e25612c9a3755910cfc33402840dDavid Gross
6012e2237911682e25612c9a3755910cfc33402840dDavid Gross        final float[] input = new float[1];
6022e2237911682e25612c9a3755910cfc33402840dDavid Gross        input[0] = Float.POSITIVE_INFINITY;
6032e2237911682e25612c9a3755910cfc33402840dDavid Gross
6042e2237911682e25612c9a3755910cfc33402840dDavid Gross        final Int2 javaResult = findMinAndMax(input);
6052e2237911682e25612c9a3755910cfc33402840dDavid Gross        final Int2 rsResult = s.reduce_findMinAndMax(input).get();
6062e2237911682e25612c9a3755910cfc33402840dDavid Gross
6072e2237911682e25612c9a3755910cfc33402840dDavid Gross        // Note that the Java and RenderScript algorithms are not
6082e2237911682e25612c9a3755910cfc33402840dDavid Gross        // guaranteed to find the same cells -- but they should
6092e2237911682e25612c9a3755910cfc33402840dDavid Gross        // find cells of the same value.
6102e2237911682e25612c9a3755910cfc33402840dDavid Gross        final Float2 javaVal = new Float2(input[javaResult.x], input[javaResult.y]);
6112e2237911682e25612c9a3755910cfc33402840dDavid Gross        final Float2 rsVal = new Float2(input[rsResult.x], input[rsResult.y]);
6122e2237911682e25612c9a3755910cfc33402840dDavid Gross
6132e2237911682e25612c9a3755910cfc33402840dDavid Gross        return result("patternFindMinAndMaxInf", new timing(1), javaVal, rsVal);
6142e2237911682e25612c9a3755910cfc33402840dDavid Gross    }
6152e2237911682e25612c9a3755910cfc33402840dDavid Gross
6166c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    ///////////////////////////////////////////////////////////////////
6176c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
618140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    // Both the input and the result are linearized representations of matSize*matSize matrices.
619140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    private float[] findMinMat(final float[] inputArray, final int matSize) {
620c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        final int matSizeSquared = matSize * matSize;
621140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
622140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        float[] result = new float[matSizeSquared];
623140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        for (int i = 0; i < matSizeSquared; ++i)
624140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross            result[i] = Float.POSITIVE_INFINITY;
625140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
626140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        for (int i = 0; i < inputArray.length; ++i)
627140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross            result[i % matSizeSquared] = Math.min(result[i % matSizeSquared], inputArray[i]);
628140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
629140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        return result;
630140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    }
631140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
632140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    static interface ReduceFindMinMat {
633140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        float[] run(Allocation input);
634c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang    }
635140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
636140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    private boolean findMinMat(RenderScript RS, int seed, int[] inputSize,
637c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                               int matSize, Element matElement, ReduceFindMinMat reduction) {
638140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        final int length = inputSize[0];
639c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        final int matSizeSquared = matSize * matSize;
640140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
641140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        final float[] inputArray = createInputArrayFloat(matSizeSquared * length, seed);
642140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
643140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        final long javaTimeStart = java.lang.System.currentTimeMillis();
6446ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final float[] javaResult = findMinMat(inputArray, matSize);
645140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        final long javaTimeEnd = java.lang.System.currentTimeMillis();
646140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
647140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        final long rsTimeStart = java.lang.System.currentTimeMillis();
648140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
649140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        Allocation inputAllocation = Allocation.createSized(RS, matElement, length);
650140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
651140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        final long copyTimeStart = java.lang.System.currentTimeMillis();
652140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
653140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        inputAllocation.copyFromUnchecked(inputArray);
654140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
655140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        final long kernelTimeStart = java.lang.System.currentTimeMillis();
6566ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final float[] rsResult = reduction.run(inputAllocation);
657140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        final long rsTimeEnd = java.lang.System.currentTimeMillis();
658140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
659140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        final boolean success =
660140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross                result("findMinMat" + matSize,
661140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross                        new timing(javaTimeStart, javaTimeEnd, rsTimeStart,
662c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                                copyTimeStart, kernelTimeStart, rsTimeEnd, inputAllocation),
6636ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                        javaResult, rsResult);
664140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        inputAllocation.destroy();
665140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        return success;
666140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    }
667140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
668140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    private boolean findMinMat2(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
669140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        return findMinMat(RS, seed, size, 2, Element.MATRIX_2X2(RS),
670140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross                (Allocation input) -> s.reduce_findMinMat2(input).get());
671140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    }
672140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
673140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    private boolean findMinMat4(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
674140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross        return findMinMat(RS, seed, size, 4, Element.MATRIX_4X4(RS),
675140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross                (Allocation input) -> s.reduce_findMinMat4(input).get());
676140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    }
677140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
678140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross    ///////////////////////////////////////////////////////////////////
679140077ca807941f50e254ebd773cabd1ff5f81eeDavid Gross
68035dbc8c20814997a00e06d7798a5633c37706978David Gross    private int fz(final int[] input) {
68135dbc8c20814997a00e06d7798a5633c37706978David Gross        for (int i = 0; i < input.length; ++i)
68235dbc8c20814997a00e06d7798a5633c37706978David Gross            if (input[i] == 0)
68335dbc8c20814997a00e06d7798a5633c37706978David Gross                return i;
68435dbc8c20814997a00e06d7798a5633c37706978David Gross        return -1;
68535dbc8c20814997a00e06d7798a5633c37706978David Gross    }
68635dbc8c20814997a00e06d7798a5633c37706978David Gross
68735dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean fz_array(RenderScript RS, ScriptC_reduce s, int seed, int size[]) {
68835dbc8c20814997a00e06d7798a5633c37706978David Gross        final int inputLen = size[0];
689c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        int[] input = createInputArrayInt(inputLen, seed + 0);
6906c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        // just in case we got unlucky
691c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        input[(new Random(seed + 1)).nextInt(inputLen)] = 0;
6926c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
6936ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int rsResult = s.reduce_fz(input).get();
6946c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
6956ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final boolean success = (input[rsResult] == 0);
6966c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Log.i(TAG,
6976ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                "fz_array: input[" + rsResult + "] == " + input[rsResult] + ": " +
698c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        (success ? "PASSED " + timing.string(size[0]) : "FAILED"));
69935dbc8c20814997a00e06d7798a5633c37706978David Gross        return success;
70035dbc8c20814997a00e06d7798a5633c37706978David Gross    }
70135dbc8c20814997a00e06d7798a5633c37706978David Gross
70235dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean fz(RenderScript RS, ScriptC_reduce s, int seed, int size[]) {
70335dbc8c20814997a00e06d7798a5633c37706978David Gross        final int inputLen = size[0];
704c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        int[] inputArray = createInputArrayInt(inputLen, seed + 0);
70535dbc8c20814997a00e06d7798a5633c37706978David Gross        // just in case we got unlucky
706c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        inputArray[(new Random(seed + 1)).nextInt(inputLen)] = 0;
70735dbc8c20814997a00e06d7798a5633c37706978David Gross
70835dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeStart = java.lang.System.currentTimeMillis();
7096ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int javaResult = fz(inputArray);
71035dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeEnd = java.lang.System.currentTimeMillis();
71135dbc8c20814997a00e06d7798a5633c37706978David Gross
71235dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeStart = java.lang.System.currentTimeMillis();
71335dbc8c20814997a00e06d7798a5633c37706978David Gross
71435dbc8c20814997a00e06d7798a5633c37706978David Gross        Allocation inputAllocation = Allocation.createSized(RS, Element.I32(RS), inputArray.length);
71535dbc8c20814997a00e06d7798a5633c37706978David Gross
71635dbc8c20814997a00e06d7798a5633c37706978David Gross        final long copyTimeStart = java.lang.System.currentTimeMillis();
71735dbc8c20814997a00e06d7798a5633c37706978David Gross
71835dbc8c20814997a00e06d7798a5633c37706978David Gross        inputAllocation.copyFrom(inputArray);
71935dbc8c20814997a00e06d7798a5633c37706978David Gross
72035dbc8c20814997a00e06d7798a5633c37706978David Gross        final long kernelTimeStart = java.lang.System.currentTimeMillis();
7216ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int rsResult = s.reduce_fz(inputAllocation).get();
72235dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeEnd = java.lang.System.currentTimeMillis();
72335dbc8c20814997a00e06d7798a5633c37706978David Gross
7246ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final boolean success = (inputArray[rsResult] == 0);
72535dbc8c20814997a00e06d7798a5633c37706978David Gross        String status = (success ? "PASSED" : "FAILED");
72635dbc8c20814997a00e06d7798a5633c37706978David Gross        if (success)
72735dbc8c20814997a00e06d7798a5633c37706978David Gross            status += " " + timing.string(javaTimeStart, javaTimeEnd, rsTimeStart,
728c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    copyTimeStart, kernelTimeStart, rsTimeEnd, inputAllocation);
72935dbc8c20814997a00e06d7798a5633c37706978David Gross        Log.i(TAG,
7306ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                "fz: java input[" + javaResult + "] == " + inputArray[javaResult] +
731c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        ", rs input[" + rsResult + "] == " + inputArray[javaResult] + ": " + status);
7323fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocation.destroy();
7336c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        return success;
7346c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
7356c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
7366c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    ///////////////////////////////////////////////////////////////////
7376c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
73835dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean fz2(RenderScript RS, ScriptC_reduce s, int seed, int size[]) {
73935dbc8c20814997a00e06d7798a5633c37706978David Gross        final int dimX = size[0], dimY = size[1];
7406c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        final int inputLen = dimX * dimY;
7416c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
742c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        int[] inputArray = createInputArrayInt(inputLen, seed + 0);
7436c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        // just in case we got unlucky
744c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        inputArray[(new Random(seed + 1)).nextInt(inputLen)] = 0;
74535dbc8c20814997a00e06d7798a5633c37706978David Gross
74635dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeStart = java.lang.System.currentTimeMillis();
7476ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int javaResultLinear = fz(inputArray);
74835dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeEnd = java.lang.System.currentTimeMillis();
74935dbc8c20814997a00e06d7798a5633c37706978David Gross
7506ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Int2 javaResult = new Int2(javaResultLinear % dimX, javaResultLinear / dimX);
7516ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int javaCellVal = inputArray[javaResult.x + dimX * javaResult.y];
75235dbc8c20814997a00e06d7798a5633c37706978David Gross
75335dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeStart = java.lang.System.currentTimeMillis();
7546c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
7556c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
7566c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        typeBuilder.setX(dimX).setY(dimY);
7576c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
75835dbc8c20814997a00e06d7798a5633c37706978David Gross
75935dbc8c20814997a00e06d7798a5633c37706978David Gross        final long copyTimeStart = java.lang.System.currentTimeMillis();
76035dbc8c20814997a00e06d7798a5633c37706978David Gross
7616c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray);
7626c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
76335dbc8c20814997a00e06d7798a5633c37706978David Gross        final long kernelTimeStart = java.lang.System.currentTimeMillis();
7646ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Int2 rsResult = s.reduce_fz2(inputAllocation).get();
76535dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeEnd = java.lang.System.currentTimeMillis();
76635dbc8c20814997a00e06d7798a5633c37706978David Gross
7676ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int rsCellVal = inputArray[rsResult.x + dimX * rsResult.y];
76835dbc8c20814997a00e06d7798a5633c37706978David Gross        final boolean success = (rsCellVal == 0);
76935dbc8c20814997a00e06d7798a5633c37706978David Gross        String status = (success ? "PASSED" : "FAILED");
77035dbc8c20814997a00e06d7798a5633c37706978David Gross        if (success)
77135dbc8c20814997a00e06d7798a5633c37706978David Gross            status += " " + timing.string(javaTimeStart, javaTimeEnd, rsTimeStart,
772c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    copyTimeStart, kernelTimeStart, rsTimeEnd, inputAllocation);
7736c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Log.i(TAG,
7746ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                "fz2: java input[" + javaResult.x + ", " + javaResult.y + "] == " + javaCellVal +
775c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        ", rs input[" + rsResult.x + ", " + rsResult.y + "] == " + rsCellVal + ": " + status);
7763fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocation.destroy();
7776c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        return success;
7786c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
7796c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
7806c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    ///////////////////////////////////////////////////////////////////
7816c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
78235dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean fz3(RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
78335dbc8c20814997a00e06d7798a5633c37706978David Gross        final int dimX = size[0], dimY = size[1], dimZ = size[2];
7846c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        final int inputLen = dimX * dimY * dimZ;
7856c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
786c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        int[] inputArray = createInputArrayInt(inputLen, seed + 0);
7876c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        // just in case we got unlucky
788c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        inputArray[(new Random(seed + 1)).nextInt(inputLen)] = 0;
78935dbc8c20814997a00e06d7798a5633c37706978David Gross
79035dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeStart = java.lang.System.currentTimeMillis();
7916ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int javaResultLinear = fz(inputArray);
79235dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeEnd = java.lang.System.currentTimeMillis();
79335dbc8c20814997a00e06d7798a5633c37706978David Gross
7946ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Int3 javaResult = new Int3(
795c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                javaResultLinear % dimX,
796c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                (javaResultLinear / dimX) % dimY,
797c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                javaResultLinear / (dimX * dimY));
7986ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int javaCellVal = inputArray[javaResult.x + dimX * javaResult.y + dimX * dimY * javaResult.z];
79935dbc8c20814997a00e06d7798a5633c37706978David Gross
80035dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeStart = java.lang.System.currentTimeMillis();
8016c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
8026c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS));
8036c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        typeBuilder.setX(dimX).setY(dimY).setZ(dimZ);
8046c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Allocation inputAllocation = Allocation.createTyped(RS, typeBuilder.create());
80535dbc8c20814997a00e06d7798a5633c37706978David Gross
80635dbc8c20814997a00e06d7798a5633c37706978David Gross        final long copyTimeStart = java.lang.System.currentTimeMillis();
80735dbc8c20814997a00e06d7798a5633c37706978David Gross
8086c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        inputAllocation.copy3DRangeFrom(0, 0, 0, dimX, dimY, dimZ, inputArray);
8096c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
81035dbc8c20814997a00e06d7798a5633c37706978David Gross        final long kernelTimeStart = java.lang.System.currentTimeMillis();
8116ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Int3 rsResult = s.reduce_fz3(inputAllocation).get();
81235dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeEnd = java.lang.System.currentTimeMillis();
81335dbc8c20814997a00e06d7798a5633c37706978David Gross
8146ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final int rsCellVal = inputArray[rsResult.x + dimX * rsResult.y + dimX * dimY * rsResult.z];
81535dbc8c20814997a00e06d7798a5633c37706978David Gross        final boolean success = (rsCellVal == 0);
81635dbc8c20814997a00e06d7798a5633c37706978David Gross        String status = (success ? "PASSED" : "FAILED");
81735dbc8c20814997a00e06d7798a5633c37706978David Gross        if (success)
81835dbc8c20814997a00e06d7798a5633c37706978David Gross            status += " " + timing.string(javaTimeStart, javaTimeEnd, rsTimeStart,
819c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    copyTimeStart, kernelTimeStart, rsTimeEnd, inputAllocation);
8206c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Log.i(TAG,
8216ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                "fz3: java input[" + javaResult.x + ", " + javaResult.y + ", " + javaResult.z + "] == " + javaCellVal +
822c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        ", rs input[" + rsResult.x + ", " + rsResult.y + ", " + rsResult.z + "] == " + rsCellVal + ": " + status);
8233fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocation.destroy();
8246c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        return success;
8256c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
8266c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
8276c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    ///////////////////////////////////////////////////////////////////
8286c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
8296c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    private static final int histogramBucketCount = 256;
8306c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
8316c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    private long[] histogram(RenderScript RS, final byte[] inputArray) {
8326c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Allocation inputAllocation = Allocation.createSized(RS, Element.U8(RS), inputArray.length);
8336c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        inputAllocation.copyFrom(inputArray);
8346c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
8356c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Allocation outputAllocation = Allocation.createSized(RS, Element.U32(RS), histogramBucketCount);
8366c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
8376c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        ScriptIntrinsicHistogram scriptHsg = ScriptIntrinsicHistogram.create(RS, Element.U8(RS));
8386c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        scriptHsg.setOutput(outputAllocation);
8396c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        scriptHsg.forEach(inputAllocation);
8406c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
8416c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        int[] outputArrayMistyped = new int[histogramBucketCount];
8426c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        outputAllocation.copyTo(outputArrayMistyped);
8436c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
8446c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        long[] outputArray = new long[histogramBucketCount];
8456c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        for (int i = 0; i < histogramBucketCount; ++i)
846c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            outputArray[i] = outputArrayMistyped[i] & (long) 0xffffffff;
8473fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
8483fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocation.destroy();
8493fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        outputAllocation.destroy();
8503fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
8511c3a11a3287d971458a021d16a54e16b37f391f9Yang Ni        scriptHsg.destroy();
8526c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        return outputArray;
8536c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
8546c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
85535dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean histogram_array(RenderScript RS, ScriptC_reduce s, int seed, int size[]) {
85635dbc8c20814997a00e06d7798a5633c37706978David Gross        final byte[] inputArray = createInputArrayByte(size[0], seed);
8576c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
8586ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long[] javaResult = histogram(RS, inputArray);
8596ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        assertEquals("javaResult length", histogramBucketCount, javaResult.length);
8606ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long[] rsResult = s.reduce_histogram(inputArray).get();
8616ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        assertEquals("rsResult length", histogramBucketCount, rsResult.length);
8626c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
8636ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        return result("histogram_array", new timing(size[0]), javaResult, rsResult);
86435dbc8c20814997a00e06d7798a5633c37706978David Gross    }
8656c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
86635dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean histogram(RenderScript RS, ScriptC_reduce s, int seed, int size[]) {
86735dbc8c20814997a00e06d7798a5633c37706978David Gross        final byte[] inputArray = createInputArrayByte(size[0], seed);
86835dbc8c20814997a00e06d7798a5633c37706978David Gross
86935dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeStart = java.lang.System.currentTimeMillis();
8706ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long[] javaResult = histogram(RS, inputArray);
87135dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeEnd = java.lang.System.currentTimeMillis();
8726ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        assertEquals("javaResult length", histogramBucketCount, javaResult.length);
87335dbc8c20814997a00e06d7798a5633c37706978David Gross
87435dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeStart = java.lang.System.currentTimeMillis();
87535dbc8c20814997a00e06d7798a5633c37706978David Gross
87635dbc8c20814997a00e06d7798a5633c37706978David Gross        Allocation inputAllocation = Allocation.createSized(RS, Element.U8(RS), inputArray.length);
87735dbc8c20814997a00e06d7798a5633c37706978David Gross
87835dbc8c20814997a00e06d7798a5633c37706978David Gross        final long copyTimeStart = java.lang.System.currentTimeMillis();
87935dbc8c20814997a00e06d7798a5633c37706978David Gross
88035dbc8c20814997a00e06d7798a5633c37706978David Gross        inputAllocation.copyFrom(inputArray);
88135dbc8c20814997a00e06d7798a5633c37706978David Gross
88235dbc8c20814997a00e06d7798a5633c37706978David Gross        final long kernelTimeStart = java.lang.System.currentTimeMillis();
8836ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long[] rsResult = s.reduce_histogram(inputAllocation).get();
88435dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeEnd = java.lang.System.currentTimeMillis();
8856ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        assertEquals("rsResult length", histogramBucketCount, rsResult.length);
88635dbc8c20814997a00e06d7798a5633c37706978David Gross
88735dbc8c20814997a00e06d7798a5633c37706978David Gross        // NOTE: The "java time" is actually for the RenderScript histogram intrinsic
8883fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final boolean success =
8893fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                result("histogram",
8903fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                        new timing(javaTimeStart, javaTimeEnd, rsTimeStart,
891c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                                copyTimeStart, kernelTimeStart, rsTimeEnd, inputAllocation),
8926ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                        javaResult, rsResult);
8933fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocation.destroy();
8943fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        return success;
8956c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
8966c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
897ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross    //-----------------------------------------------------------------
898ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross
899cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross    private boolean patternRedundantGet(RenderScript RS, ScriptC_reduce s) {
900cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        // Ensure that get() can be called multiple times on the same
901cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        // result, and returns the same object each time.
902cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
903cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        boolean pass = true;
904cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
905cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        final int inputLength = 1 << 18;
906cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        final byte[] inputArray = createInputArrayByte(inputLength, 789);
907cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
9086ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long[] javaResult = histogram(RS, inputArray);
9096ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        assertEquals("javaResult length", histogramBucketCount, javaResult.length);
910cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
9116ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final ScriptC_reduce.resultArray256_uint rsResultFuture = s.reduce_histogram(inputArray);
9126ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long[] rsResult1 = rsResultFuture.get();
9136ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        assertEquals("rsResult1 length", histogramBucketCount, rsResult1.length);
9146ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        pass &= result("patternRedundantGet (1)", new timing(inputLength), javaResult, rsResult1);
915cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
9166ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long[] rsResult2 = rsResultFuture.get();
9176ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        pass &= result("patternRedundantGet (2)", new timing(inputLength), javaResult, rsResult2);
918cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
9196ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final boolean success = (rsResult1 == rsResult2);
920cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        Log.i(TAG, "patternRedundantGet (object equality): " + (success ? "PASSED" : "FAILED"));
921cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        pass &= success;
922cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
923cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        return pass;
924cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross    }
925cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
9266c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    //-----------------------------------------------------------------
9276c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
9286c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    private Int2 mode(RenderScript RS, final byte[] inputArray) {
9296c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        long[] hsg = histogram(RS, inputArray);
9306c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
9316c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        int modeIdx = 0;
9326c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        for (int i = 1; i < hsg.length; ++i)
933c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            if (hsg[i] > hsg[modeIdx]) modeIdx = i;
934c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        return new Int2(modeIdx, (int) hsg[modeIdx]);
9356c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
9366c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
93735dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean mode_array(RenderScript RS, ScriptC_reduce s, int seed, int size[]) {
93835dbc8c20814997a00e06d7798a5633c37706978David Gross        final byte[] inputArray = createInputArrayByte(size[0], seed);
9396c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
9406ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Int2 javaResult = mode(RS, inputArray);
9416ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final Int2 rsResult = s.reduce_mode(inputArray).get();
9426c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
9436ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        return result("mode", new timing(size[0]), javaResult, rsResult);
94435dbc8c20814997a00e06d7798a5633c37706978David Gross    }
94535dbc8c20814997a00e06d7798a5633c37706978David Gross
94635dbc8c20814997a00e06d7798a5633c37706978David Gross    ///////////////////////////////////////////////////////////////////
94735dbc8c20814997a00e06d7798a5633c37706978David Gross
94835dbc8c20814997a00e06d7798a5633c37706978David Gross    private long sumgcd(final int in1[], final int in2[]) {
9493fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        assertEquals("sumgcd input lengths", in1.length, in2.length);
95035dbc8c20814997a00e06d7798a5633c37706978David Gross
95135dbc8c20814997a00e06d7798a5633c37706978David Gross        long sum = 0;
95235dbc8c20814997a00e06d7798a5633c37706978David Gross        for (int i = 0; i < in1.length; ++i) {
95335dbc8c20814997a00e06d7798a5633c37706978David Gross            int a = in1[i], b = in2[i];
95435dbc8c20814997a00e06d7798a5633c37706978David Gross
95535dbc8c20814997a00e06d7798a5633c37706978David Gross            while (b != 0) {
95635dbc8c20814997a00e06d7798a5633c37706978David Gross                final int aNew = b;
95735dbc8c20814997a00e06d7798a5633c37706978David Gross                final int bNew = a % b;
95835dbc8c20814997a00e06d7798a5633c37706978David Gross
95935dbc8c20814997a00e06d7798a5633c37706978David Gross                a = aNew;
96035dbc8c20814997a00e06d7798a5633c37706978David Gross                b = bNew;
96135dbc8c20814997a00e06d7798a5633c37706978David Gross            }
96235dbc8c20814997a00e06d7798a5633c37706978David Gross
96335dbc8c20814997a00e06d7798a5633c37706978David Gross            sum += a;
96435dbc8c20814997a00e06d7798a5633c37706978David Gross        }
96535dbc8c20814997a00e06d7798a5633c37706978David Gross        return sum;
96635dbc8c20814997a00e06d7798a5633c37706978David Gross    }
96735dbc8c20814997a00e06d7798a5633c37706978David Gross
96835dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean sumgcd(RenderScript RS, ScriptC_reduce s, int seed, int size[]) {
96935dbc8c20814997a00e06d7798a5633c37706978David Gross        final int len = size[0];
97035dbc8c20814997a00e06d7798a5633c37706978David Gross
971c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        final int[] inputArrayA = createInputArrayInt(len, seed + 0);
972c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        final int[] inputArrayB = createInputArrayInt(len, seed + 1);
97335dbc8c20814997a00e06d7798a5633c37706978David Gross
97435dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeStart = java.lang.System.currentTimeMillis();
9756ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long javaResult = sumgcd(inputArrayA, inputArrayB);
97635dbc8c20814997a00e06d7798a5633c37706978David Gross        final long javaTimeEnd = java.lang.System.currentTimeMillis();
97735dbc8c20814997a00e06d7798a5633c37706978David Gross
97835dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeStart = java.lang.System.currentTimeMillis();
97935dbc8c20814997a00e06d7798a5633c37706978David Gross
98035dbc8c20814997a00e06d7798a5633c37706978David Gross        Allocation inputAllocationA = Allocation.createSized(RS, Element.I32(RS), len);
98135dbc8c20814997a00e06d7798a5633c37706978David Gross        Allocation inputAllocationB = Allocation.createSized(RS, Element.I32(RS), len);
98235dbc8c20814997a00e06d7798a5633c37706978David Gross
98335dbc8c20814997a00e06d7798a5633c37706978David Gross        final long copyTimeStart = java.lang.System.currentTimeMillis();
98435dbc8c20814997a00e06d7798a5633c37706978David Gross
98535dbc8c20814997a00e06d7798a5633c37706978David Gross        inputAllocationA.copyFrom(inputArrayA);
98635dbc8c20814997a00e06d7798a5633c37706978David Gross        inputAllocationB.copyFrom(inputArrayB);
98735dbc8c20814997a00e06d7798a5633c37706978David Gross
98835dbc8c20814997a00e06d7798a5633c37706978David Gross        final long kernelTimeStart = java.lang.System.currentTimeMillis();
9896ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross        final long rsResult = s.reduce_sumgcd(inputAllocationA, inputAllocationB).get();
99035dbc8c20814997a00e06d7798a5633c37706978David Gross        final long rsTimeEnd = java.lang.System.currentTimeMillis();
99135dbc8c20814997a00e06d7798a5633c37706978David Gross
9923fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final boolean success =
9933fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                result("sumgcd",
9943fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                        new timing(javaTimeStart, javaTimeEnd, rsTimeStart, copyTimeStart, kernelTimeStart, rsTimeEnd,
995c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                                inputAllocationA, inputAllocationB),
9966ddc0c73cb13ee070f3a7d65e4cc51980fe863abDavid Gross                        javaResult, rsResult);
9973fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocationA.destroy();
9983fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        inputAllocationB.destroy();
9993fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        return success;
10006c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
10016c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
10026c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    ///////////////////////////////////////////////////////////////////
10036c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
10043fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // Return an array of sparse integer values from 0 to maxVal inclusive.
10053fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // The array consists of all values k*sparseness (k a nonnegative integer)
10063fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // that are less than maxVal, and maxVal itself.  For example, if maxVal
10073fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // is 20 and sparseness is 6, then the result is { 0, 6, 12, 18, 20 };
10083fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // and if maxVal is 20 and sparseness is 10, then the result is { 0, 10, 20 }.
10093fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    //
10103fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // The elements of the array are sorted in increasing order.
10113fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    //
10123fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // maxVal     -- must be nonnegative
10133fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // sparseness -- must be positive
10143fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    private static int[] computeSizePoints(int maxVal, int sparseness) {
10153fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        assertTrue((maxVal >= 0) && (sparseness > 0));
10163fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
10173fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final boolean maxValIsExtra = ((maxVal % sparseness) != 0);
1018c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        int[] result = new int[1 + maxVal / sparseness + (maxValIsExtra ? 1 : 0)];
10193fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
10203fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        for (int i = 0; i * sparseness <= maxVal; ++i)
10213fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            result[i] = i * sparseness;
10223fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        if (maxValIsExtra)
10233fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            result[result.length - 1] = maxVal;
10243fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
10253fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        return result;
10263fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    }
10273fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
10283fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    private static final int maxSeedsPerTest = 10;
102935dbc8c20814997a00e06d7798a5633c37706978David Gross
103035dbc8c20814997a00e06d7798a5633c37706978David Gross    static interface Test {
103135dbc8c20814997a00e06d7798a5633c37706978David Gross        // A test execution is characterized by two properties: A seed
103235dbc8c20814997a00e06d7798a5633c37706978David Gross        // and a size.
103335dbc8c20814997a00e06d7798a5633c37706978David Gross        //
103435dbc8c20814997a00e06d7798a5633c37706978David Gross        // The seed is used for generating pseudorandom input data.
103535dbc8c20814997a00e06d7798a5633c37706978David Gross        // Ideally, we use different seeds for different tests and for
103635dbc8c20814997a00e06d7798a5633c37706978David Gross        // different executions of the same test at different sizes.
103735dbc8c20814997a00e06d7798a5633c37706978David Gross        // A test with multiple blocks of input data (i.e., for a
103835dbc8c20814997a00e06d7798a5633c37706978David Gross        // reduction with multiple inputs) may want multiple seeds; it
103935dbc8c20814997a00e06d7798a5633c37706978David Gross        // may use the seeds seed..seed+maxSeedsPerTest-1.
104035dbc8c20814997a00e06d7798a5633c37706978David Gross        //
104135dbc8c20814997a00e06d7798a5633c37706978David Gross        // The size indicates the amount of input data.  It is the number
104235dbc8c20814997a00e06d7798a5633c37706978David Gross        // of cells in a particular dimension of the iteration space.
104335dbc8c20814997a00e06d7798a5633c37706978David Gross        boolean run(RenderScript RS, ScriptC_reduce s, int seed, int[] size);
1044c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang    }
104535dbc8c20814997a00e06d7798a5633c37706978David Gross
104635dbc8c20814997a00e06d7798a5633c37706978David Gross    static class TestDescription {
10473fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        public TestDescription(String myTestName, Test myTest, int mySeed, int[] myDefSize,
10483fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                               int myLog2MaxSize, int mySparseness) {
1049c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            testName = myTestName;
1050c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            test = myTest;
1051c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            seed = mySeed;
1052c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            defSize = myDefSize;
1053c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            log2MaxSize = myLog2MaxSize;
1054c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            sparseness = mySparseness;
1055c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        }
10563fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
10573fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        public TestDescription(String myTestName, Test myTest, int mySeed, int[] myDefSize, int myLog2MaxSize) {
1058c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            testName = myTestName;
1059c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            test = myTest;
1060c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            seed = mySeed;
1061c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            defSize = myDefSize;
106235dbc8c20814997a00e06d7798a5633c37706978David Gross            log2MaxSize = myLog2MaxSize;
1063c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            sparseness = 1;
1064c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        }
106535dbc8c20814997a00e06d7798a5633c37706978David Gross
106635dbc8c20814997a00e06d7798a5633c37706978David Gross        public TestDescription(String myTestName, Test myTest, int mySeed, int[] myDefSize) {
1067c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            testName = myTestName;
1068c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            test = myTest;
1069c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            seed = mySeed;
1070c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            defSize = myDefSize;
10713fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            log2MaxSize = -1;
1072c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            sparseness = 1;
1073c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        }
107435dbc8c20814997a00e06d7798a5633c37706978David Gross
107535dbc8c20814997a00e06d7798a5633c37706978David Gross        public final String testName;
107635dbc8c20814997a00e06d7798a5633c37706978David Gross
107735dbc8c20814997a00e06d7798a5633c37706978David Gross        public final Test test;
107835dbc8c20814997a00e06d7798a5633c37706978David Gross
107935dbc8c20814997a00e06d7798a5633c37706978David Gross        // When executing the test, scale this up by maxSeedsPerTest.
108035dbc8c20814997a00e06d7798a5633c37706978David Gross        public final int seed;
108135dbc8c20814997a00e06d7798a5633c37706978David Gross
108235dbc8c20814997a00e06d7798a5633c37706978David Gross        // If we're only going to run the test once, what size should
10833fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // we use?  The length of the array is the number of
10843fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // dimensions of the input data.
108535dbc8c20814997a00e06d7798a5633c37706978David Gross        public final int[] defSize;
108635dbc8c20814997a00e06d7798a5633c37706978David Gross
108735dbc8c20814997a00e06d7798a5633c37706978David Gross        // If we're going to run the test over a range of sizes, what
10883fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // is the maximum size to use?  (This constrains the number of
10893fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // cells of the input data, not the number of cells ALONG A
10903fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // PARTICULAR DIMENSION of the input data.)
10913fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        public final int log2MaxSize;
10923fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
10933fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // If we're going to run the test "exhaustively" over a range
10943fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // of sizes, what is the size of a step through the range?
10953fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        //
10963fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // For 1D, must be 1.
10973fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        public final int sparseness;
1098c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang    }
109935dbc8c20814997a00e06d7798a5633c37706978David Gross
110035dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean run(TestDescription td, RenderScript RS, ScriptC_reduce s, int seed, int[] size) {
110135dbc8c20814997a00e06d7798a5633c37706978David Gross        String arrayContent = "";
110235dbc8c20814997a00e06d7798a5633c37706978David Gross        for (int i = 0; i < size.length; ++i) {
110335dbc8c20814997a00e06d7798a5633c37706978David Gross            if (i != 0)
110435dbc8c20814997a00e06d7798a5633c37706978David Gross                arrayContent += ", ";
110535dbc8c20814997a00e06d7798a5633c37706978David Gross            arrayContent += size[i];
110635dbc8c20814997a00e06d7798a5633c37706978David Gross        }
110735dbc8c20814997a00e06d7798a5633c37706978David Gross        Log.i(TAG, "Running " + td.testName + "(seed = " + seed + ", size[] = {" + arrayContent + "})");
110835dbc8c20814997a00e06d7798a5633c37706978David Gross        return td.test.run(RS, s, seed, size);
110935dbc8c20814997a00e06d7798a5633c37706978David Gross    }
111035dbc8c20814997a00e06d7798a5633c37706978David Gross
111135dbc8c20814997a00e06d7798a5633c37706978David Gross    private final TestDescription[] correctnessTests = {
1112c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            // alloc and array variants of the same test will use the same
1113c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            // seed, in case results need to be compared.
1114c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang
1115c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("addint1D", this::addint1D, 0, new int[]{100000}, 20),
1116c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("addint1D_array", this::addint1D_array, 0, new int[]{100000}, 20),
1117c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("addint2D", this::addint2D, 1, new int[]{450, 225}, 20, 5),
1118c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("addint3D", this::addint3D, 2, new int[]{37, 48, 49}, 20, 7),
1119c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang
1120c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            // Bool and NaN variants of the same test will use the same
1121c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            // seed, in case results need to be compared.
1122c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("findMinAbsBool", this::findMinAbsBool, 3, new int[]{100000}, 20),
1123c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("findMinAbsNaN", this::findMinAbsNaN, 3, new int[]{100000}, 20),
1124c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("findMinAbsBoolInf", this::findMinAbsBoolInf, 4, new int[]{100000}, 20),
1125c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("findMinAbsNaNInf", this::findMinAbsNaNInf, 4, new int[]{100000}, 20),
1126c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang
1127c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("findMinAndMax", this::findMinAndMax, 5, new int[]{100000}, 20),
1128c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("findMinAndMax_array", this::findMinAndMax_array, 5, new int[]{100000}, 20),
1129c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("findMinMat2", this::findMinMat2, 6, new int[]{25000}, 17),
1130c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("findMinMat4", this::findMinMat4, 7, new int[]{10000}, 15),
1131c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("fz", this::fz, 8, new int[]{100000}, 20),
1132c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("fz_array", this::fz_array, 8, new int[]{100000}, 20),
1133c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("fz2", this::fz2, 9, new int[]{225, 450}, 20, 5),
1134c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("fz3", this::fz3, 10, new int[]{59, 48, 37}, 20, 7),
1135c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("histogram", this::histogram, 11, new int[]{100000}, 20),
1136c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("histogram_array", this::histogram_array, 11, new int[]{100000}, 20),
1137c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            // might want to add: new TestDescription("mode", this::mode, 12, new int[]{100000}, 20),
1138c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("mode_array", this::mode_array, 12, new int[]{100000}, 20),
1139c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("sumgcd", this::sumgcd, 13, new int[]{1 << 16}, 20)
114035dbc8c20814997a00e06d7798a5633c37706978David Gross    };
114135dbc8c20814997a00e06d7798a5633c37706978David Gross
114235dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean runCorrectnessQuick(RenderScript RS, ScriptC_reduce s) {
114335dbc8c20814997a00e06d7798a5633c37706978David Gross        boolean pass = true;
114435dbc8c20814997a00e06d7798a5633c37706978David Gross
114535dbc8c20814997a00e06d7798a5633c37706978David Gross        for (TestDescription td : correctnessTests) {
114635dbc8c20814997a00e06d7798a5633c37706978David Gross            pass &= run(td, RS, s, maxSeedsPerTest * td.seed, td.defSize);
114735dbc8c20814997a00e06d7798a5633c37706978David Gross        }
114835dbc8c20814997a00e06d7798a5633c37706978David Gross
114935dbc8c20814997a00e06d7798a5633c37706978David Gross        return pass;
115035dbc8c20814997a00e06d7798a5633c37706978David Gross    }
115135dbc8c20814997a00e06d7798a5633c37706978David Gross
11523fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // NOTE: Each test execution gets maxSeedsPerTest, and there are
11533fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // up to 3 + 5*log2MaxSize test executions in the full (as opposed
11543fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // to quick) correctness run of a particular test description, and
11553fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // we need an additional seed for pseudorandom size generation.
11563fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // Assuming log2MaxSize does not exceed 32, then it should be
11573fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // sufficient to reserve 1 + (3+5*32)*maxSeedsPerTest seeds per
11583fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // TestDescription.
11593fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    //
11603fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // See runCorrectness1D().
1161c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang    private static final int seedsPerTestDescriptionCorrectness1D = 1 + (3 + 5 * 32) * maxSeedsPerTest;
11623fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
11633fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // NOTE: Each test execution gets maxSeedsPerTest, and there are
11643fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // about 11*((log2MaxSize+1)**2) test executions in the full (as
11653fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // opposed to quick) correctness run of a particular test
11663fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // description, and we need a seed for pseudorandom size
11673fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // generation.  Assuming log2MaxSize does not exceed 32, then it
11683fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // should be sufficient to reserve 1 + 11*1089*maxSeedsPerTest
11693fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // seeds per TestDescription.
11703fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    //
11713fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // See runCorrectness2D().
1172c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang    private static final int seedsPerTestDescriptionCorrectness2D = 1 + (11 * 1089) * maxSeedsPerTest;
11733fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
11743fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // NOTE: Each test execution gets maxSeedsPerTest, and there are
11753fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // about 27*((log2MaxSize+1)**3) + 6*((log2MaxSize+1)**2) test
11763fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // executions in the full (as opposed to quick) correctness run of
11773fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // a particular test description, and we need a seed for (c).
11783fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // Assuming log2MaxSize does not exceed 32, then it should
11793fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // be sufficient to reserve 1 + (27*(33**3) + 6*(33**2))*maxSeedsPerTest
11803fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // seeds per TestDescription, which can be simplified upwards to
11813fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // 1 + (28*(33**3))*maxSeedsPerTest seeds per TestDescription.
1182c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang    private static final int seedsPerTestDescriptionCorrectness3D = 1 + (28 * 35937) * maxSeedsPerTest;
11833fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
11843fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // Each test execution gets a certain number of seeds, and a full
11853fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // (as opposed to quick) correctness run of a particular
11863fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // TestDescription consists of some number of executions (each of
11873fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // which needs up to maxSeedsPerTest) and may require some
11883fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    // additional seeds.
11893fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    private static final int seedsPerTestDescriptionCorrectness =
11903fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            Math.max(seedsPerTestDescriptionCorrectness1D,
1191c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    Math.max(seedsPerTestDescriptionCorrectness2D,
1192c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                            seedsPerTestDescriptionCorrectness3D));
11933fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
119435dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean runCorrectness(RenderScript RS, ScriptC_reduce s) {
119535dbc8c20814997a00e06d7798a5633c37706978David Gross        boolean pass = true;
119635dbc8c20814997a00e06d7798a5633c37706978David Gross
119735dbc8c20814997a00e06d7798a5633c37706978David Gross        for (TestDescription td : correctnessTests) {
11983fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            switch (td.defSize.length) {
11993fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                case 1:
12003fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    pass &= runCorrectness1D(td, RS, s);
12013fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    break;
12023fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                case 2:
12033fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    pass &= runCorrectness2D(td, RS, s);
12043fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    break;
12053fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                case 3:
12063fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    pass &= runCorrectness3D(td, RS, s);
12073fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    break;
12083fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                default:
12093fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    assertTrue("unexpected defSize.length " + td.defSize.length, false);
12103fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    pass &= false;
12113fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    break;
12123fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            }
12133fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        }
12143fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12153fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        return pass;
12163fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    }
12173fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12183fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    private boolean runCorrectness1D(TestDescription td, RenderScript RS, ScriptC_reduce s) {
12193fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        assertEquals(1, td.sparseness);
12203fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int log2MaxSize = td.log2MaxSize;
12213fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        assertTrue(log2MaxSize >= 0);
12223fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12233fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        boolean pass = true;
12243fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12253fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // We will execute the test with the following sizes:
12263fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // (a) Each power of 2 from zero (2**0) up to log2MaxSize (2**log2MaxSize)
12273fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // (b) Each size from (a) +/-1
12283fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // (c) 2 random sizes between each pair of adjacent points in (a)
12293fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        int[] testSizes = new int[
12303fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            /* a */ (1 + log2MaxSize) +
1231c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            /* b */ 2 * (1 + log2MaxSize) +
1232c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            /* c */ 2 * log2MaxSize];
12333fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // See seedsPerTestDescriptionCorrectness1D
12343fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12353fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int seedForPickingTestSizes = td.seed * seedsPerTestDescriptionCorrectness;
12363fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12373fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        int nextTestIdx = 0;
12383fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12393fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // Fill in (a) and (b)
12403fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        for (int i = 0; i <= log2MaxSize; ++i) {
12413fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            final int pwrOf2 = 1 << i;
12423fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            testSizes[nextTestIdx++] = pwrOf2;      /* a */
12433fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            testSizes[nextTestIdx++] = pwrOf2 - 1;  /* b */
12443fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            testSizes[nextTestIdx++] = pwrOf2 + 1;  /* b */
12453fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        }
124635dbc8c20814997a00e06d7798a5633c37706978David Gross
12473fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // Fill in (c)
12483fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        Random r = new Random(seedForPickingTestSizes);
12493fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        for (int i = 0; i < log2MaxSize; ++i) {
12503fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            final int lo = (1 << i) + 1;
12513fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            final int hi = 1 << (i + 1);
12523fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12533fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            if (lo < hi) {
12543fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                for (int j = 0; j < 2; ++j) {
12553fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    testSizes[nextTestIdx++] = r.nextInt(hi - lo) + lo;
125635dbc8c20814997a00e06d7798a5633c37706978David Gross                }
12573fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            }
12583fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        }
125935dbc8c20814997a00e06d7798a5633c37706978David Gross
12603fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        Arrays.sort(testSizes);
126135dbc8c20814997a00e06d7798a5633c37706978David Gross
12623fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        int[] lastTestSizeArg = new int[]{-1};
12633fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        for (int i = 0; i < testSizes.length; ++i) {
12643fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            if ((testSizes[i] > 0) && (testSizes[i] != lastTestSizeArg[0])) {
12653fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                lastTestSizeArg[0] = testSizes[i];
1266c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                final int seedForTestExecution = seedForPickingTestSizes + 1 + i * maxSeedsPerTest;
12673fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                pass &= run(td, RS, s, seedForTestExecution, lastTestSizeArg);
12683fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            }
12693fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        }
12703fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12713fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        return pass;
12723fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    }
12733fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12743fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    private boolean runCorrectness2D(TestDescription td, RenderScript RS, ScriptC_reduce s) {
12753fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int log2MaxSize = td.log2MaxSize, maxSize = 1 << log2MaxSize, sparseness = td.sparseness;
12763fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        assertTrue((log2MaxSize >= 0) && (sparseness >= 1));
12773fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12783fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        boolean pass = true;
12793fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12803fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int[] sizePoints = computeSizePoints(log2MaxSize, sparseness);
12813fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12823fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // We will execute the test with the following sizes:
12833fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // (a) Each dimension at a power of 2 from sizePoints[]
12843fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        ///    such that the sum of the exponents does not exceed
12853fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        //     log2MaxSize
12863fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // (b) Each size from (a) with one or both dimensions +/-1,
12873fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        //     except where this would exceed 2**log2MaxSize
12883fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // (c) Approximately 2*(sizePoints.length**2) random sizes
12893fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        ArrayList<int[]> testSizesList = new ArrayList<int[]>();
12903fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // See seedsPerTestDescriptionCorrectness2D
12913fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12923fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int seedForPickingTestSizes = td.seed * seedsPerTestDescriptionCorrectness;
12933fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
12943fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // Fill in (a) and (b)
12953fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        for (int i : sizePoints) {
12963fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            final int iPwrOf2 = 1 << i;
12973fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            for (int iDelta = -1; iDelta <= 1; ++iDelta) {
12983fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                final int iSize = iPwrOf2 + iDelta;
12993fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                for (int j : sizePoints) {
13003fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    final int jPwrOf2 = 1 << j;
13013fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    for (int jDelta = -1; jDelta <= 1; ++jDelta) {
13023fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                        final int jSize = jPwrOf2 + jDelta;
1303c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        if ((long) iSize * (long) jSize <= maxSize)
13043fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                            testSizesList.add(new int[]{iSize, jSize});
130535dbc8c20814997a00e06d7798a5633c37706978David Gross                    }
130635dbc8c20814997a00e06d7798a5633c37706978David Gross                }
13073fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            }
13083fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        }
13093fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
13103fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // Fill in (c)
13113fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        Random r = new Random(seedForPickingTestSizes);
13123fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        for (int i : sizePoints) {
13133fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            for (int j : sizePoints) {
13143fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                final int size0 = 1 + r.nextInt(1 << i);
13153fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                final int size1 = 1 + r.nextInt(maxSize / size0);
131635dbc8c20814997a00e06d7798a5633c37706978David Gross
13173fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                testSizesList.add(new int[]{size0, size1});
13183fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                testSizesList.add(new int[]{size1, size0});
13193fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            }
13203fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        }
13213fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
13223fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        int[][] testSizes = testSizesList.toArray(new int[0][]);
13233fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        Arrays.sort(testSizes,
13243fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                (a, b) -> {
1325c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    final int comp0 = ((Integer) a[0]).compareTo(b[0]);
1326c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    return (comp0 != 0 ? comp0 : ((Integer) a[1]).compareTo(b[1]));
13273fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                });
13283fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
13293fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        int[] lastTestSizeArg = null;
13303fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        for (int i = 0; i < testSizes.length; ++i) {
13313fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            if ((testSizes[i][0] <= 0) || (testSizes[i][1] <= 0))
13323fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                continue;
13333fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            if ((lastTestSizeArg != null) &&
1334c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    (testSizes[i][0] == lastTestSizeArg[0]) &&
1335c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    (testSizes[i][1] == lastTestSizeArg[1]))
13363fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                continue;
13373fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            lastTestSizeArg = testSizes[i];
1338c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            final int seedForTestExecution = seedForPickingTestSizes + 1 + i * maxSeedsPerTest;
13393fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            pass &= run(td, RS, s, seedForTestExecution, lastTestSizeArg);
13403fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        }
13413fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
13423fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        return pass;
13433fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    }
13443fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
13453fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross    private boolean runCorrectness3D(TestDescription td, RenderScript RS, ScriptC_reduce s) {
13463fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int log2MaxSize = td.log2MaxSize, maxSize = 1 << log2MaxSize, sparseness = td.sparseness;
13473fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        assertTrue((log2MaxSize >= 0) && (sparseness >= 1));
134835dbc8c20814997a00e06d7798a5633c37706978David Gross
13493fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        boolean pass = true;
13503fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
13513fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int[] sizePoints = computeSizePoints(log2MaxSize, sparseness);
13523fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
13533fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // We will execute the test with the following sizes:
13543fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // (a) Each dimension at a power of 2 from sizePoints[]
13553fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        ///    such that the sum of the exponents does not exceed
13563fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        //     log2MaxSize
13573fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // (b) Each size from (a) with one or both dimensions +/-1,
13583fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        //     except where this would exceed 2**log2MaxSize
13593fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // (c) Approximately 6*(sizePoints.length**2) random sizes
13603fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        ArrayList<int[]> testSizesList = new ArrayList<int[]>();
13613fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // See seedsPerTestDescriptionCorrectness3D
13623fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
13633fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        final int seedForPickingTestSizes = td.seed * seedsPerTestDescriptionCorrectness;
13643fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
13653fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // Fill in (a) and (b)
13663fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        for (int i : sizePoints) {
13673fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            final int iPwrOf2 = 1 << i;
13683fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            for (int iDelta = -1; iDelta <= 1; ++iDelta) {
13693fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                final int iSize = iPwrOf2 + iDelta;
13703fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                for (int j : sizePoints) {
13713fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    final int jPwrOf2 = 1 << j;
13723fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    for (int jDelta = -1; jDelta <= 1; ++jDelta) {
13733fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                        final int jSize = jPwrOf2 + jDelta;
13743fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                        for (int k : sizePoints) {
13753fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                            final int kPwrOf2 = 1 << k;
13763fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                            for (int kDelta = -1; kDelta <= 1; ++kDelta) {
13773fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                                final int kSize = kPwrOf2 + kDelta;
1378c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                                if ((long) iSize * (long) jSize * (long) kSize <= maxSize)
13793fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                                    testSizesList.add(new int[]{iSize, jSize, kSize});
13803fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                            }
13813fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                        }
138235dbc8c20814997a00e06d7798a5633c37706978David Gross                    }
138335dbc8c20814997a00e06d7798a5633c37706978David Gross                }
138435dbc8c20814997a00e06d7798a5633c37706978David Gross            }
13853fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        }
13863fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
13873fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        // Fill in (c)
13883fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        Random r = new Random(seedForPickingTestSizes);
13893fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        for (int i : sizePoints) {
13903fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            for (int j : sizePoints) {
13913fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                final int size0 = 1 + r.nextInt(1 << i);
13923fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                final int size1 = 1 + r.nextInt(Math.min(1 << j, maxSize / size0));
1393c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                final int size2 = 1 + r.nextInt(maxSize / (size0 * size1));
13943fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
13953fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                testSizesList.add(new int[]{size0, size1, size2});
13963fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                testSizesList.add(new int[]{size0, size2, size1});
13973fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                testSizesList.add(new int[]{size1, size0, size2});
13983fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                testSizesList.add(new int[]{size1, size2, size0});
13993fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                testSizesList.add(new int[]{size2, size0, size1});
14003fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                testSizesList.add(new int[]{size2, size1, size0});
14013fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            }
14023fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        }
14033fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
14043fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        int[][] testSizes = testSizesList.toArray(new int[0][]);
14053fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        Arrays.sort(testSizes,
14063fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                (a, b) -> {
1407c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    int comp = ((Integer) a[0]).compareTo(b[0]);
14083fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    if (comp == 0)
1409c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        comp = ((Integer) a[1]).compareTo(b[1]);
14103fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    if (comp == 0)
1411c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        comp = ((Integer) a[2]).compareTo(b[2]);
14123fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                    return comp;
14133fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                });
14143fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
14153fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        int[] lastTestSizeArg = null;
14163fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross        for (int i = 0; i < testSizes.length; ++i) {
14173fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            if ((testSizes[i][0] <= 0) || (testSizes[i][1] <= 0) || (testSizes[i][2] <= 0))
14183fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                continue;
14193fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            if ((lastTestSizeArg != null) &&
1420c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    (testSizes[i][0] == lastTestSizeArg[0]) &&
1421c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    (testSizes[i][1] == lastTestSizeArg[1]) &&
1422c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    (testSizes[i][2] == lastTestSizeArg[2]))
14233fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross                continue;
1424e770ef6fbf928cbbd2a33a6e720d728380518743David Gross
1425e770ef6fbf928cbbd2a33a6e720d728380518743David Gross            // Apply Z-dimension limiting.
1426e770ef6fbf928cbbd2a33a6e720d728380518743David Gross            //
1427e770ef6fbf928cbbd2a33a6e720d728380518743David Gross            // The Z dimension is always handled specially by GPU
1428e770ef6fbf928cbbd2a33a6e720d728380518743David Gross            // drivers, and a high value for this dimension can have
1429e770ef6fbf928cbbd2a33a6e720d728380518743David Gross            // serious performance implications.  For example, Cuda
1430e770ef6fbf928cbbd2a33a6e720d728380518743David Gross            // and OpenCL encourage Z to be the smallest dimension.
1431e770ef6fbf928cbbd2a33a6e720d728380518743David Gross            if (testSizes[i][2] > 1024)
1432e770ef6fbf928cbbd2a33a6e720d728380518743David Gross                continue;
1433e770ef6fbf928cbbd2a33a6e720d728380518743David Gross
14343fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            lastTestSizeArg = testSizes[i];
1435c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            final int seedForTestExecution = seedForPickingTestSizes + 1 + i * maxSeedsPerTest;
14363fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross            pass &= run(td, RS, s, seedForTestExecution, lastTestSizeArg);
143735dbc8c20814997a00e06d7798a5633c37706978David Gross        }
143835dbc8c20814997a00e06d7798a5633c37706978David Gross
143935dbc8c20814997a00e06d7798a5633c37706978David Gross        return pass;
144035dbc8c20814997a00e06d7798a5633c37706978David Gross    }
144135dbc8c20814997a00e06d7798a5633c37706978David Gross
144235dbc8c20814997a00e06d7798a5633c37706978David Gross    private final TestDescription[] performanceTests = {
1443c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("addint1D", this::addint1D, 0, new int[]{100000 << 10}),
1444c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("addint2D", this::addint2D, 1, new int[]{450 << 5, 225 << 5}),
1445c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("addint3D", this::addint3D, 2, new int[]{37 << 3, 48 << 3, 49 << 3}),
1446c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("findMinAndMax", this::findMinAndMax, 3, new int[]{100000 << 9}),
1447c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("fz", this::fz, 4, new int[]{100000 << 10}),
1448c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("fz2", this::fz2, 5, new int[]{225 << 5, 450 << 5}),
1449c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("fz3", this::fz3, 6, new int[]{59 << 3, 48 << 3, 37 << 3}),
1450c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("histogram", this::histogram, 7, new int[]{100000 << 10}),
1451c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            // might want to add: new TestDescription("mode", this::mode, 8, new int[]{100000}),
1452c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            new TestDescription("sumgcd", this::sumgcd, 9, new int[]{1 << 21})
145335dbc8c20814997a00e06d7798a5633c37706978David Gross    };
145435dbc8c20814997a00e06d7798a5633c37706978David Gross
145535dbc8c20814997a00e06d7798a5633c37706978David Gross    private boolean runPerformanceQuick(RenderScript RS, ScriptC_reduce s) {
145635dbc8c20814997a00e06d7798a5633c37706978David Gross        boolean pass = true;
145735dbc8c20814997a00e06d7798a5633c37706978David Gross
145835dbc8c20814997a00e06d7798a5633c37706978David Gross        for (TestDescription td : performanceTests) {
145935dbc8c20814997a00e06d7798a5633c37706978David Gross            pass &= run(td, RS, s, maxSeedsPerTest * td.seed, td.defSize);
146035dbc8c20814997a00e06d7798a5633c37706978David Gross        }
146135dbc8c20814997a00e06d7798a5633c37706978David Gross
146235dbc8c20814997a00e06d7798a5633c37706978David Gross        return pass;
146335dbc8c20814997a00e06d7798a5633c37706978David Gross    }
146435dbc8c20814997a00e06d7798a5633c37706978David Gross
1465cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross    private boolean runCorrectnessPatterns(RenderScript RS, ScriptC_reduce s) {
1466cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        // Test some very specific usage patterns.
1467cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        boolean pass = true;
1468cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
1469ce873f06a45cb94154c6330cc588439b883a5c1aDavid Gross        pass &= patternDuplicateAnonymousResult(RS, s);
14702e2237911682e25612c9a3755910cfc33402840dDavid Gross        pass &= patternFindMinAndMaxInf(RS, s);
1471cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        pass &= patternInterleavedReduce(RS, s);
1472cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        pass &= patternRedundantGet(RS, s);
1473cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross
1474cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        return pass;
1475cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross    }
147635dbc8c20814997a00e06d7798a5633c37706978David Gross
14776c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    public void run() {
14786c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        RenderScript pRS = RenderScript.create(mCtx);
14796c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        ScriptC_reduce s = new ScriptC_reduce(pRS);
14806c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        s.set_negInf(Float.NEGATIVE_INFINITY);
14816c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        s.set_posInf(Float.POSITIVE_INFINITY);
14826c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
14836c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        boolean pass = true;
148435dbc8c20814997a00e06d7798a5633c37706978David Gross
1485cb74dabc7a8df4c5840c6d8edf06162c581ae6edDavid Gross        pass &= runCorrectnessPatterns(pRS, s);
148635dbc8c20814997a00e06d7798a5633c37706978David Gross        pass &= runCorrectnessQuick(pRS, s);
148735dbc8c20814997a00e06d7798a5633c37706978David Gross        pass &= runCorrectness(pRS, s);
148835dbc8c20814997a00e06d7798a5633c37706978David Gross        // pass &= runPerformanceQuick(pRS, s);
14896c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
14906c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        pRS.finish();
14911c3a11a3287d971458a021d16a54e16b37f391f9Yang Ni        s.destroy();
14926c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        pRS.destroy();
14936c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross
14946c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        Log.i(TAG, pass ? "PASSED" : "FAILED");
14956c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        if (pass)
14966c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross            passTest();
14976c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross        else
14986c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross            failTest();
14996c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross    }
15006c1876bbef1b2c89975dce91230a168bd2d2ce4cDavid Gross}
15013fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross
15023fff3e7ae6fc85cf9a5954287724fc9d6454942dDavid Gross// TODO: Add machinery for easily running fuller (i.e., non-sparse) testing.
1503