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