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 package android.renderscript.cts; 18 19 import android.renderscript.*; 20 import java.lang.Float; 21 import java.lang.Math; 22 import java.util.Arrays; 23 import java.util.Random; 24 25 public class ReduceTest extends RSBaseCompute { 26 private ScriptC_reduce mScript; 27 28 @Override setUp()29 protected void setUp() throws Exception { 30 super.setUp(); 31 mScript = new ScriptC_reduce(mRS); 32 mScript.set_negInf(Float.NEGATIVE_INFINITY); 33 mScript.set_posInf(Float.POSITIVE_INFINITY); 34 mScript.invoke_setInfsHalf(RSUtils.FLOAT16_NEGATIVE_INFINITY, RSUtils.FLOAT16_POSITIVE_INFINITY); 35 } 36 37 /////////////////////////////////////////////////////////////////// 38 assertEquals(final float[] javaRslt, final float[] rsRslt)39 private void assertEquals(final float[] javaRslt, final float[] rsRslt) { 40 assertEquals("length", javaRslt.length, rsRslt.length); 41 for (int i = 0; i < javaRslt.length; ++i) 42 assertEquals(String.valueOf(i), javaRslt[i], rsRslt[i]); 43 } 44 assertEquals(final short[] javaRslt, final short[] rsRslt)45 private void assertEquals(final short[] javaRslt, final short[] rsRslt) { 46 assertEquals("length", javaRslt.length, rsRslt.length); 47 for (int i = 0; i < javaRslt.length; ++i) 48 assertEquals(String.valueOf(i), javaRslt[i], rsRslt[i]); 49 } 50 assertEquals(final Short2[] javaRslt, final Short2[] rsRslt)51 private void assertEquals(final Short2[] javaRslt, final Short2[] rsRslt) { 52 assertEquals("length", javaRslt.length, rsRslt.length); 53 for (int i = 0; i < javaRslt.length; ++i) 54 assertEquals(String.valueOf(i), javaRslt[i], rsRslt[i]); 55 } 56 assertEquals(final String msg, final Float2 javaRslt, final Float2 rsRslt)57 private void assertEquals(final String msg, final Float2 javaRslt, final Float2 rsRslt) { 58 assertEquals(msg + "(x)", javaRslt.x, rsRslt.x); 59 assertEquals(msg + "(y)", javaRslt.y, rsRslt.y); 60 } 61 assertEquals(final Float2 javaRslt, final Float2 rsRslt)62 private void assertEquals(final Float2 javaRslt, final Float2 rsRslt) { 63 assertEquals("", javaRslt, rsRslt); 64 } 65 assertEquals(final String msg, final Int2 javaRslt, final Int2 rsRslt)66 private void assertEquals(final String msg, final Int2 javaRslt, final Int2 rsRslt) { 67 assertEquals(msg + "(x)", javaRslt.x, rsRslt.x); 68 assertEquals(msg + "(y)", javaRslt.y, rsRslt.y); 69 } 70 assertEquals(final Int2 javaRslt, final Int2 rsRslt)71 private void assertEquals(final Int2 javaRslt, final Int2 rsRslt) { 72 assertEquals("", javaRslt, rsRslt); 73 } 74 assertEquals(final String msg, final Short2 javaRslt, final Short2 rsRslt)75 private void assertEquals(final String msg, final Short2 javaRslt, final Short2 rsRslt) { 76 assertEquals(msg + "(x)", javaRslt.x, rsRslt.x); 77 assertEquals(msg + "(y)", javaRslt.y, rsRslt.y); 78 } 79 assertEquals(final Short2 javaRslt, final Short2 rsRslt)80 private void assertEquals(final Short2 javaRslt, final Short2 rsRslt) { 81 assertEquals("", javaRslt, rsRslt); 82 } 83 84 // Create a zero-initialized Allocation. 85 // 1D: ylen == 0, zlen == 0 86 // 2D: ylen != 0, zlen == 0 87 // 3D: ylen != 0, zlen != 0 createInputAllocation(Element elt, int xlen, int ylen, int zlen)88 private Allocation createInputAllocation(Element elt, int xlen, int ylen, int zlen) { 89 assertTrue(xlen >= 1); 90 assertTrue((zlen==0) || (ylen >= 1)); 91 92 Allocation alloc; 93 94 if (zlen != 0) 95 alloc = Allocation.createTyped(mRS, Type.createXYZ(mRS, elt, xlen, ylen, zlen)); 96 else if (ylen != 0) 97 alloc = Allocation.createTyped(mRS, Type.createXY(mRS, elt, xlen, ylen)); 98 else 99 alloc = Allocation.createSized(mRS, elt, xlen); 100 if (elt.getVectorSize() == 3) 101 alloc.setAutoPadding(true); 102 103 byte[] init = new byte[alloc.getBytesSize()]; 104 Arrays.fill(init, (byte)0); 105 alloc.copyFromUnchecked(init); 106 return alloc; 107 } 108 109 // Create an arry of zero-initialized Allocations of various dimensions -- 110 // all possible 1D, 2D, and 3D Allocations where no dimension exceeds max. createInputAllocations(Element elt, int max)111 private Allocation[] createInputAllocations(Element elt, int max) { 112 // 1D Allocations: { 1..max } 113 // 2D Allocations: { 1..max }^2 114 // 3D Allocations: { 1..max }^3 115 final int numAllocs = max + max*max + max*max*max; 116 Allocation alloc[] = new Allocation[numAllocs]; 117 int count = 0; 118 for (int xlen = 1; xlen <= max; ++xlen) { 119 for (int ylen = 0; ylen <= max; ++ylen) { 120 final int zlim = ((ylen!=0) ? max : 0); 121 for (int zlen = 0; zlen <= zlim; ++zlen) 122 alloc[count++] = createInputAllocation(elt, xlen, ylen, zlen); 123 } 124 } 125 assertTrue(count == numAllocs); 126 return alloc; 127 } 128 createInputArrayByte(int len, int seed)129 private static byte[] createInputArrayByte(int len, int seed) { 130 byte[] array = new byte[len]; 131 (new Random(seed)).nextBytes(array); 132 return array; 133 } 134 createInputArrayHalf(int len, int seed)135 private static short[] createInputArrayHalf(int len, int seed) { 136 short[] array = new short[len]; 137 RSUtils.genRandomFloat16s(seed, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, array, 138 false); 139 return array; 140 } 141 createInputArrayFloat(int len, int seed)142 private static float[] createInputArrayFloat(int len, int seed) { 143 Random rand = new Random(seed); 144 float[] array = new float[len]; 145 for (int i = 0; i < len; ++i) 146 array[i] = rand.nextFloat(); 147 return array; 148 } 149 createInputArrayInt(int len, int seed)150 private static int[] createInputArrayInt(int len, int seed) { 151 Random rand = new Random(seed); 152 int[] array = new int[len]; 153 for (int i = 0; i < len; ++i) 154 array[i] = rand.nextInt(); 155 return array; 156 } 157 createInputArrayInt(int len, int seed, int eltRange)158 private static int[] createInputArrayInt(int len, int seed, int eltRange) { 159 Random rand = new Random(seed); 160 int[] array = new int[len]; 161 for (int i = 0; i < len; ++i) 162 array[i] = rand.nextInt(eltRange); 163 return array; 164 } 165 166 /////////////////////////////////////////////////////////////////// 167 addint(final int[] input)168 private int addint(final int[] input) { 169 int rslt = 0; 170 for (int idx = 0; idx < input.length; ++idx) 171 rslt += input[idx]; 172 return rslt; 173 } 174 testAddInt1D()175 public void testAddInt1D() { 176 final int[] input = createInputArrayInt(100000, 0, 1 << 13); 177 178 final int javaRslt = addint(input); 179 final int rsRslt = mScript.reduce_addint(input).get(); 180 181 assertEquals(javaRslt, rsRslt); 182 } 183 testAddInt2D()184 public void testAddInt2D() { 185 final int dimX = 450, dimY = 225; 186 187 final int[] inputArray = createInputArrayInt(dimX * dimY, 1, 1 << 13); 188 Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS)); 189 typeBuilder.setX(dimX).setY(dimY); 190 Allocation inputAllocation = Allocation.createTyped(mRS, typeBuilder.create()); 191 inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray); 192 193 final int javaRslt = addint(inputArray); 194 final int rsRslt = mScript.reduce_addint(inputAllocation).get(); 195 196 assertEquals(javaRslt, rsRslt); 197 } 198 199 /////////////////////////////////////////////////////////////////// 200 findMinAndMax(final float[] input)201 private Int2 findMinAndMax(final float[] input) { 202 float minVal = Float.POSITIVE_INFINITY; 203 int minIdx = -1; 204 float maxVal = Float.NEGATIVE_INFINITY; 205 int maxIdx = -1; 206 207 for (int idx = 0; idx < input.length; ++idx) { 208 if (input[idx] < minVal) { 209 minVal = input[idx]; 210 minIdx = idx; 211 } 212 if (input[idx] > maxVal) { 213 maxVal = input[idx]; 214 maxIdx = idx; 215 } 216 } 217 218 return new Int2(minIdx, maxIdx); 219 } 220 testFindMinAndMax()221 public void testFindMinAndMax() { 222 final float[] input = createInputArrayFloat(100000, 4); 223 224 final Int2 javaRslt = findMinAndMax(input); 225 final Int2 rsRslt = mScript.reduce_findMinAndMax(input).get(); 226 227 // Note that the Java and RenderScript algorithms are not 228 // guaranteed to find the same cells -- but they should 229 // find cells of the same value. 230 final Float2 javaVal = new Float2(input[javaRslt.x], input[javaRslt.y]); 231 final Float2 rsVal = new Float2(input[rsRslt.x], input[rsRslt.y]); 232 233 assertEquals(javaVal, rsVal); 234 } 235 236 /////////////////////////////////////////////////////////////////// 237 findMinAndMaxHalf(final short[] inputArray)238 private Short2 findMinAndMaxHalf(final short[] inputArray) { 239 Allocation inputAllocation = Allocation.createSized(mRS, Element.F16(mRS), inputArray.length); 240 inputAllocation.copyFrom(inputArray); 241 242 Allocation outputAllocation = Allocation.createSized(mRS, Element.F16_2(mRS), 1); 243 244 mScript.invoke_findMinAndMaxHalf(outputAllocation, inputAllocation); 245 246 short[] outputArray = new short[2]; 247 outputAllocation.copyTo(outputArray); 248 return new Short2(outputArray[0], outputArray[1]); 249 } 250 findMinAndMaxHalfIntoArray(final short[] inputArray)251 private short[] findMinAndMaxHalfIntoArray(final short[] inputArray) { 252 final Short2 vectorResult = findMinAndMaxHalf(inputArray); 253 final short[] arrayResult = new short[] { vectorResult.x, vectorResult.y }; 254 return arrayResult; 255 } 256 testFindMinAndMaxHalf()257 public void testFindMinAndMaxHalf() { 258 // fewer members in the array than there are distinct half values 259 final short[] input = createInputArrayHalf(1000, 23); 260 261 // test Short2 result 262 final Short2 javaRslt = findMinAndMaxHalf(input); 263 final Short2 rsRslt = mScript.reduce_findMinAndMaxHalf(input).get(); 264 assertEquals(javaRslt, rsRslt); 265 266 // test short[2] result 267 final short[] javaRsltIntoArray = findMinAndMaxHalfIntoArray(input); 268 final short[] rsRsltIntoArray = mScript.reduce_findMinAndMaxHalfIntoArray(input).get(); 269 assertEquals(javaRsltIntoArray, rsRsltIntoArray); 270 } 271 272 /////////////////////////////////////////////////////////////////// 273 274 // The input is a flattened representation of an array of 2-vector findMinAndMaxHalf2(final short[] inputArray)275 private Short2[] findMinAndMaxHalf2(final short[] inputArray) { 276 assertEquals(inputArray.length % 2, 0); 277 278 Allocation inputAllocation = Allocation.createSized(mRS, Element.F16_2(mRS), inputArray.length / 2); 279 inputAllocation.copyFrom(inputArray); 280 281 Allocation outputAllocation = Allocation.createSized(mRS, Element.F16_2(mRS), 2); 282 283 mScript.invoke_findMinAndMaxHalf2(outputAllocation, inputAllocation); 284 285 short[] outputArray = new short[4]; 286 outputAllocation.copyTo(outputArray); 287 return new Short2[] { new Short2(outputArray[0], outputArray[1]), 288 new Short2(outputArray[2], outputArray[3]) }; 289 } 290 testFindMinAndMaxHalf2()291 public void testFindMinAndMaxHalf2() { 292 // fewer members in the array than there are distinct half values 293 final short[] input = createInputArrayHalf(1000, 25); 294 295 final Short2[] javaRslt = findMinAndMaxHalf2(input); 296 final Short2[] rsRslt = mScript.reduce_findMinAndMaxHalf2(input).get(); 297 298 assertEquals(javaRslt, rsRslt); 299 } 300 301 /////////////////////////////////////////////////////////////////// 302 303 // Both the input and the result are linearized representations of 2x2 matrices. findMinMat(final float[] inputArray)304 private float[] findMinMat(final float[] inputArray) { 305 float[] result = new float[4]; 306 for (int i = 0; i < 4; ++i) 307 result[i] = Float.POSITIVE_INFINITY; 308 309 for (int i = 0; i < inputArray.length; ++i) 310 result[i % 4] = Math.min(result[i % 4], inputArray[i]); 311 312 return result; 313 } 314 testFindMinMat()315 public void testFindMinMat() { 316 final int length = 100000; 317 318 final float[] inputArray = createInputArrayFloat(4 * length, 24); 319 Allocation inputAllocation = Allocation.createSized(mRS, Element.MATRIX_2X2(mRS), length); 320 inputAllocation.copyFromUnchecked(inputArray); 321 322 final float[] javaRslt = findMinMat(inputArray); 323 final float[] rsRslt = mScript.reduce_findMinMat(inputAllocation).get(); 324 325 assertEquals(javaRslt, rsRslt); 326 } 327 328 /////////////////////////////////////////////////////////////////// 329 330 // Both the input and the result are linearized representations of 2x2 matrices. findMinAndMaxMat(final float[] inputArray)331 private float[] findMinAndMaxMat(final float[] inputArray) { 332 float[] result = new float[8]; 333 for (int i = 0; i < 4; ++i) { 334 result[i+0] = Float.POSITIVE_INFINITY; 335 result[i+4] = Float.NEGATIVE_INFINITY; 336 } 337 338 for (int i = 0; i < inputArray.length; ++i) { 339 result[0 + i % 4] = Math.min(result[0 + i % 4], inputArray[i]); 340 result[4 + i % 4] = Math.max(result[4 + i % 4], inputArray[i]); 341 } 342 343 return result; 344 } 345 testFindMinAndMaxMat()346 public void testFindMinAndMaxMat() { 347 final int length = 100000; 348 349 final float[] inputArray = createInputArrayFloat(4 * length, 26); 350 Allocation inputAllocation = Allocation.createSized(mRS, Element.MATRIX_2X2(mRS), length); 351 inputAllocation.copyFromUnchecked(inputArray); 352 353 final float[] javaRslt = findMinAndMaxMat(inputArray); 354 final float[] rsRslt = mScript.reduce_findMinAndMaxMat(inputAllocation).get(); 355 356 assertEquals(javaRslt, rsRslt); 357 } 358 359 /////////////////////////////////////////////////////////////////// 360 testFz()361 public void testFz() { 362 final int inputLen = 100000; 363 int[] input = createInputArrayInt(inputLen, 5); 364 // just in case we got unlucky 365 input[(new Random(6)).nextInt(inputLen)] = 0; 366 367 final int rsRslt = mScript.reduce_fz(input).get(); 368 369 assertEquals("input[" + rsRslt + "]", 0, input[rsRslt]); 370 } 371 372 /////////////////////////////////////////////////////////////////// 373 testFz2()374 public void testFz2() { 375 final int dimX = 225, dimY = 450; 376 final int inputLen = dimX * dimY; 377 378 int[] inputArray = createInputArrayInt(inputLen, 7); 379 // just in case we got unlucky 380 inputArray[(new Random(8)).nextInt(inputLen)] = 0; 381 382 Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS)); 383 typeBuilder.setX(dimX).setY(dimY); 384 Allocation inputAllocation = Allocation.createTyped(mRS, typeBuilder.create()); 385 inputAllocation.copy2DRangeFrom(0, 0, dimX, dimY, inputArray); 386 387 final Int2 rsRslt = mScript.reduce_fz2(inputAllocation).get(); 388 389 final int cellVal = inputArray[rsRslt.x + dimX * rsRslt.y]; 390 391 assertEquals("input[" + rsRslt.x + ", " + rsRslt.y + "]", 0, cellVal); 392 } 393 394 /////////////////////////////////////////////////////////////////// 395 testFz3()396 public void testFz3() { 397 final int dimX = 59, dimY = 48, dimZ = 37; 398 final int inputLen = dimX * dimY * dimZ; 399 400 int[] inputArray = createInputArrayInt(inputLen, 9); 401 // just in case we got unlucky 402 inputArray[(new Random(10)).nextInt(inputLen)] = 0; 403 404 Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS)); 405 typeBuilder.setX(dimX).setY(dimY).setZ(dimZ); 406 Allocation inputAllocation = Allocation.createTyped(mRS, typeBuilder.create()); 407 inputAllocation.copy3DRangeFrom(0, 0, 0, dimX, dimY, dimZ, inputArray); 408 409 final Int3 rsRslt = mScript.reduce_fz3(inputAllocation).get(); 410 411 final int cellVal = inputArray[rsRslt.x + dimX * rsRslt.y + dimX * dimY * rsRslt.z]; 412 413 assertEquals("input[" + rsRslt.x + ", " + rsRslt.y + ", " + rsRslt.z + "]", 0, cellVal); 414 } 415 416 /////////////////////////////////////////////////////////////////// 417 418 private static final int histogramBucketCount = 256; 419 histogram(final byte[] inputArray)420 private long[] histogram(final byte[] inputArray) { 421 Allocation inputAllocation = Allocation.createSized(mRS, Element.U8(mRS), inputArray.length); 422 inputAllocation.copyFrom(inputArray); 423 424 Allocation outputAllocation = Allocation.createSized(mRS, Element.U32(mRS), histogramBucketCount); 425 426 ScriptIntrinsicHistogram scriptHsg = ScriptIntrinsicHistogram.create(mRS, Element.U8(mRS)); 427 scriptHsg.setOutput(outputAllocation); 428 scriptHsg.forEach(inputAllocation); 429 430 int[] outputArrayMistyped = new int[histogramBucketCount]; 431 outputAllocation.copyTo(outputArrayMistyped); 432 433 long[] outputArray = new long[histogramBucketCount]; 434 for (int i = 0; i < histogramBucketCount; ++i) 435 outputArray[i] = outputArrayMistyped[i] & (long)0xffffffff; 436 return outputArray; 437 } 438 testHistogram()439 public void testHistogram() { 440 final byte[] inputArray = createInputArrayByte(100000, 11); 441 442 final long[] javaRslt = histogram(inputArray); 443 assertEquals("javaRslt unexpected length", histogramBucketCount, javaRslt.length); 444 final long[] rsRslt = mScript.reduce_histogram(inputArray).get(); 445 assertEquals("rsRslt unexpected length", histogramBucketCount, rsRslt.length); 446 447 for (int i = 0; i < histogramBucketCount; ++i) { 448 assertEquals("histogram[" + i + "]", javaRslt[i], rsRslt[i]); 449 } 450 } 451 452 //----------------------------------------------------------------- 453 mode(final byte[] inputArray)454 private Int2 mode(final byte[] inputArray) { 455 long[] hsg = histogram(inputArray); 456 457 int modeIdx = 0; 458 for (int i = 1; i < hsg.length; ++i) 459 if (hsg[i] > hsg[modeIdx]) modeIdx =i; 460 return new Int2(modeIdx, (int)hsg[modeIdx]); 461 } 462 testMode()463 public void testMode() { 464 final byte[] inputArray = createInputArrayByte(100000, 12); 465 466 final Int2 javaRslt = mode(inputArray); 467 final Int2 rsRslt = mScript.reduce_mode(inputArray).get(); 468 469 assertEquals(javaRslt, rsRslt); 470 } 471 472 /////////////////////////////////////////////////////////////////// 473 sumXor(final int[] input1, final int[] input2)474 private int sumXor(final int[] input1, final int[] input2) { 475 int sum = 0; 476 for (int idx = 0; idx < input1.length; ++idx) 477 sum += (input1[idx] ^ input2[idx]); 478 return sum; 479 } 480 testSumXor()481 public void testSumXor() { 482 final int[] input1 = createInputArrayInt(100000, 13, 1 << 13); 483 final int[] input2 = createInputArrayInt(100000, 14, 1 << 13); 484 485 final int javaRslt = sumXor(input1, input2); 486 final int rsRslt = mScript.reduce_sumxor(input1, input2).get(); 487 488 assertEquals(javaRslt, rsRslt); 489 } 490 testBadSumXorInputDimensionMismatch()491 public void testBadSumXorInputDimensionMismatch() { 492 Allocation[] inputs = createInputAllocations(Element.I32(mRS), 3); 493 494 // try all pairwise combinations of Allocations; we don't care 495 // about the result, only whether we correctly recognize 496 // whether or not the input Allocations have the same 497 // dimensions. 498 for (int i = 0; i < inputs.length; ++i) { 499 for (int j = 0; j < inputs.length; ++j) { 500 try { 501 mScript.reduce_sumxor(inputs[i], inputs[j]); 502 if (i != j) 503 fail("expected RSRuntimeException for dimension mismatch: inputs " + i + " and " + j); 504 } catch (RSRuntimeException e) { 505 if (i == j) 506 fail("did not expect RSRuntimeException for dimension match: inputs " + i); 507 } 508 } 509 } 510 } 511 testBadSumXorInputLengthMismatch()512 public void testBadSumXorInputLengthMismatch() { 513 final int[] input1 = createInputArrayInt(90000, 16, 1 << 13); 514 final int[] input2 = createInputArrayInt(100000, 17, 1 << 13); 515 516 // we don't care about the result, only whether we correctly recognize 517 // that the input arrays have different dimensions. 518 try { 519 mScript.reduce_sumxor(input1, input2); 520 fail("expected RSRuntimeException for mismatched array input lengths"); 521 } catch (RSRuntimeException e) { 522 } 523 } 524 testBadSumXorInputNull()525 public void testBadSumXorInputNull() { 526 final int[] input = createInputArrayInt(100000, 15, 1 << 13); 527 528 // we don't care about the result, only whether we correctly recognize 529 // that the input array is null. 530 531 try { 532 mScript.reduce_sumxor(input, null); 533 fail("expected RSIllegalArgumentException for null array input"); 534 } catch (RSIllegalArgumentException e) { 535 } 536 537 try { 538 mScript.reduce_sumxor(null, input); 539 fail("expected RSIllegalArgumentException for null array input"); 540 } catch (RSIllegalArgumentException e) { 541 } 542 } 543 testBadSumXorInputWrongType()544 public void testBadSumXorInputWrongType() { 545 Allocation inputI32 = Allocation.createSized(mRS, Element.I32(mRS), 1); 546 547 Allocation badInput[] = new Allocation[]{ 548 Allocation.createSized(mRS, Element.I16(mRS), 1), 549 Allocation.createSized(mRS, Element.I16_2(mRS), 1), 550 Allocation.createSized(mRS, Element.I32_2(mRS), 1), 551 Allocation.createSized(mRS, Element.U32(mRS), 1) 552 }; 553 554 // we don't care about the result, only whether we correctly recognize 555 // that the input Allocation has the wrong type. 556 557 for (int i = 0; i < badInput.length; ++i) { 558 try { 559 mScript.reduce_sumxor(inputI32, badInput[i]); 560 fail("badInput[" + i + "]: expected RSRuntimeException for wrong input data type"); 561 } catch (RSRuntimeException e) { 562 } 563 564 try { 565 mScript.reduce_sumxor(badInput[i], inputI32); 566 fail("badInput[" + i + "]: expected RSRuntimeException for wrong input data type"); 567 } catch (RSRuntimeException e) { 568 } 569 } 570 } 571 572 /////////////////////////////////////////////////////////////////// 573 sillySum(final byte[] input1, final float[] input2, final int[] input3)574 private long sillySum(final byte[] input1, final float[] input2, final int[] input3) { 575 // input3 is a flattened 3-vector 576 assertEquals(input1.length, input2.length); 577 assertEquals(input1.length * 3, input3.length); 578 579 long sum = 0; 580 for (int i = 0; i < input1.length; ++i) 581 sum += ((((input1[i] + (long)Math.ceil(Math.log(input2[i]))) + input3[3*i + 0]) + input3[3*i + 1]) + input3[3*i + 2]); 582 return sum; 583 } 584 testSillySum()585 public void testSillySum() { 586 final int length = 100000; 587 588 final byte[] input1 = createInputArrayByte(length, 16); 589 final float[] input2 = createInputArrayFloat(length, 17); 590 // input3 is a flattened 3-vector 591 final int[] input3 = createInputArrayInt(3 * length, 18); 592 593 final long javaRslt = sillySum(input1, input2, input3); 594 final long rsRslt = mScript.reduce_sillysum(input1, input2, input3).get(); 595 596 assertEquals(javaRslt, rsRslt); 597 } 598 testBadSillySumInputDimensionMismatch()599 public void testBadSillySumInputDimensionMismatch() { 600 Allocation[] allocs1 = createInputAllocations(Element.I8(mRS), 3); 601 Allocation[] allocs2 = createInputAllocations(Element.F32(mRS), 3); 602 Allocation[] allocs3 = createInputAllocations(Element.I32_3(mRS), 3); 603 604 // try all tuples of Allocations; we don't care about the 605 // result, only whether we correctly recognize whether or not 606 // the input Allocations have the same dimensions. 607 for (int i = 0; i < allocs1.length; ++i) { 608 for (int j = 0; j < allocs2.length; ++j) { 609 for (int k = 0; k < allocs3.length; ++k) { 610 final boolean expectException = !((i == j) && (j == k)); 611 try { 612 mScript.reduce_sillysum(allocs1[i], allocs2[j], allocs3[k]); 613 if (expectException) 614 fail("expected RSRuntimeException for dimension mismatch: inputs " + i + ", " + j + ", " + k); 615 } catch (RSRuntimeException e) { 616 if (!expectException) { 617 fail("did not expect RSRuntimeException for dimension match: inputs " + i); 618 } 619 } 620 } 621 } 622 } 623 } 624 testBadSillySumInputLengthMismatch()625 public void testBadSillySumInputLengthMismatch() { 626 final int[] lengths = new int[]{ 10, 100, 1000 }; 627 628 // try all pairwise combinations of lengths; we don't care 629 // about the result, only whether we correctly recognize 630 // whether or not the input Allocations have the same lengths. 631 for (int len1idx = 0; len1idx < lengths.length; ++len1idx) { 632 for (int len2idx = 0; len2idx < lengths.length; ++len2idx) { 633 for (int len3idx = 0; len3idx < lengths.length; ++len3idx) { 634 635 final byte[] input1 = createInputArrayByte(lengths[len1idx], 19); 636 final float[] input2 = createInputArrayFloat(lengths[len2idx], 20); 637 // input3 is a flattened 3-vector 638 final int[] input3 = createInputArrayInt(3 * lengths[len3idx], 21); 639 640 try { 641 mScript.reduce_sillysum(input1, input2, input3); 642 if ((len1idx != len2idx) || (len1idx != len3idx)) 643 fail("expected RSRuntimeException for dimension mismatch: inputs " + 644 len1idx + ", " + len2idx + ", " + len3idx); 645 } catch (RSRuntimeException e) { 646 if ((len1idx == len2idx) && (len1idx == len3idx)) 647 fail("did not expect RSRuntimeException for dimension match: inputs " + len1idx); 648 } 649 } 650 } 651 } 652 } 653 654 /////////////////////////////////////////////////////////////////// 655 656 private static final long[] oorrGoodResults = new long[]{0L, 1L, 0x7fff_ffff_ffff_ffffL}; 657 private static final long[] oorrBadResultHalfs = new long[]{0x4000_0000_0000_0000L, 0x4567_89ab_cdef_0123L}; 658 659 private static final int[] oorInput = createInputArrayInt(1, 22); 660 testBadOorrSca()661 public void testBadOorrSca() { 662 final int[] oorrBadPositions = new int[]{-1, 0}; 663 664 for (long goodResult : oorrGoodResults) { 665 mScript.set_oorrGoodResult(goodResult); 666 for (long badResultHalf : oorrBadResultHalfs) { 667 mScript.set_oorrBadResultHalf(badResultHalf); 668 for (int badPosition : oorrBadPositions) { 669 mScript.set_oorrBadPos(badPosition); 670 671 // we don't care about the result, only whether 672 // it's representible. note that no exception is 673 // thrown until "get()". 674 try { 675 mScript.reduce_oorrSca(oorInput).get(); 676 if (badPosition >= 0) 677 fail("expected RSRuntimeException for non-representible result; expected 2*" + badResultHalf); 678 } catch (RSRuntimeException e) { 679 if (badPosition < 0) 680 fail("did not expect RSRuntimeException for representible result; expected " + goodResult); 681 } 682 } 683 } 684 } 685 } 686 testBadOorrVec4()687 public void testBadOorrVec4() { 688 final int[] oorrBadPositions = new int[]{-1, 0, 1, 2, 3}; 689 690 for (long goodResult : oorrGoodResults) { 691 mScript.set_oorrGoodResult(goodResult); 692 for (long badResultHalf : oorrBadResultHalfs) { 693 mScript.set_oorrBadResultHalf(badResultHalf); 694 for (int badPosition : oorrBadPositions) { 695 mScript.set_oorrBadPos(badPosition); 696 697 // we don't care about the result, only whether 698 // it's representible. note that no exception is 699 // thrown until "get()". 700 try { 701 mScript.reduce_oorrVec4(oorInput).get(); 702 if (badPosition >= 0) 703 fail("expected RSRuntimeException for non-representible result; expected 2*" + badResultHalf 704 + " at position " + badPosition); 705 } catch (RSRuntimeException e) { 706 if (badPosition < 0) 707 fail("did not expect RSRuntimeException for representible result; expected " + goodResult); 708 } 709 } 710 } 711 } 712 } 713 testBadOorrArr9()714 public void testBadOorrArr9() { 715 final int[] oorrBadPositions = new int[]{-1, 0, 1, 2, 3, 4, 5, 6, 7, 8}; 716 717 for (long goodResult : oorrGoodResults) { 718 mScript.set_oorrGoodResult(goodResult); 719 for (long badResultHalf : oorrBadResultHalfs) { 720 mScript.set_oorrBadResultHalf(badResultHalf); 721 for (int badPosition : oorrBadPositions) { 722 mScript.set_oorrBadPos(badPosition); 723 724 // we don't care about the result, only whether 725 // it's representible. note that no exception is 726 // thrown until "get()". 727 try { 728 mScript.reduce_oorrArr9(oorInput).get(); 729 if (badPosition >= 0) 730 fail("expected RSRuntimeException for non-representible result; expected 2*" + badResultHalf 731 + " at position " + badPosition); 732 } catch (RSRuntimeException e) { 733 if (badPosition < 0) 734 fail("did not expect RSRuntimeException for representible result; expected " + goodResult); 735 } 736 } 737 } 738 } 739 } 740 testBadOorrArr9Vec4()741 public void testBadOorrArr9Vec4() { 742 for (long goodResult : oorrGoodResults) { 743 mScript.set_oorrGoodResult(goodResult); 744 for (long badResultHalf : oorrBadResultHalfs) { 745 mScript.set_oorrBadResultHalf(badResultHalf); 746 for (int badPosition = -1; badPosition < 36; ++badPosition) { 747 mScript.set_oorrBadPos(badPosition); 748 749 // we don't care about the result, only whether 750 // it's representible. note that no exception is 751 // thrown until "get()". 752 try { 753 mScript.reduce_oorrArr9Vec4(oorInput).get(); 754 if (badPosition >= 0) 755 fail("expected RSRuntimeException for non-representible result; expected 2*" + badResultHalf 756 + " at position " + badPosition); 757 } catch (RSRuntimeException e) { 758 if (badPosition < 0) 759 fail("did not expect RSRuntimeException for representible result; expected " + goodResult); 760 } 761 } 762 } 763 } 764 } 765 } 766