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