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