1 /* 2 * Copyright (C) 2011 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.RenderScript; 20 import android.renderscript.Allocation; 21 import android.renderscript.Element; 22 import android.renderscript.RSRuntimeException; 23 import android.util.Log; 24 25 /** 26 * Base RenderScript test class. This class provides a message handler and a 27 * convenient way to wait for compute scripts to complete their execution. 28 */ 29 public class RSBaseCompute extends RSBase { 30 RenderScript mRS; 31 protected int INPUTSIZE = 512; 32 33 @Override 34 protected void setUp() throws Exception { 35 super.setUp(); 36 mRS = RenderScript.create(mCtx); 37 mRS.setMessageHandler(mRsMessage); 38 } 39 40 @Override 41 protected void tearDown() throws Exception { 42 super.tearDown(); 43 } 44 45 public void checkArray(float[] ref, float[] out, int height, int refStride, 46 int outStride, float ulpCount) { 47 int minStride = refStride > outStride ? outStride : refStride; 48 for (int i = 0; i < height; i++) { 49 for (int j = 0; j < minStride; j++) { 50 int refIdx = i * refStride + j; 51 int outIdx = i * outStride + j; 52 float ulp = Math.ulp(ref[refIdx]) * ulpCount; 53 assertEquals("Incorrect value @ idx = " + i + " |", 54 ref[refIdx], 55 out[outIdx], 56 ulp); 57 } 58 } 59 } 60 61 public void checkArray(int[] ref, int[] out, int height, int refStride, 62 int outStride) { 63 int minStride = refStride > outStride ? outStride : refStride; 64 for (int i = 0; i < height; i++) { 65 for (int j = 0; j < minStride; j++) { 66 int refIdx = i * refStride + j; 67 int outIdx = i * outStride + j; 68 assertEquals("Incorrect value @ idx = " + i + " |", 69 ref[refIdx], 70 out[outIdx]); 71 } 72 } 73 } 74 75 // TODO Is there a better way to do this 76 protected Element getElement(RenderScript rs, Element.DataType dataType, int size) { 77 Element element = null; 78 if (size == 1) { 79 if (dataType == Element.DataType.FLOAT_64) { 80 element = Element.F64(rs); 81 } else if (dataType == Element.DataType.FLOAT_32) { 82 element = Element.F32(rs); 83 } else if (dataType == Element.DataType.SIGNED_64) { 84 element = Element.I64(rs); 85 } else if (dataType == Element.DataType.UNSIGNED_64) { 86 element = Element.U64(rs); 87 } else if (dataType == Element.DataType.SIGNED_32) { 88 element = Element.I32(rs); 89 } else if (dataType == Element.DataType.UNSIGNED_32) { 90 element = Element.U32(rs); 91 } else if (dataType == Element.DataType.SIGNED_16) { 92 element = Element.I16(rs); 93 } else if (dataType == Element.DataType.UNSIGNED_16) { 94 element = Element.U16(rs); 95 } else if (dataType == Element.DataType.SIGNED_8) { 96 element = Element.I8(rs); 97 } else if (dataType == Element.DataType.UNSIGNED_8) { 98 element = Element.U8(rs); 99 } else { 100 android.util.Log.e("RenderscriptCTS", "Don't know how to create allocation of type" + 101 dataType.toString()); 102 } 103 } else { 104 element = Element.createVector(rs, dataType, size); 105 } 106 return element; 107 } 108 109 protected Allocation createRandomAllocation(RenderScript rs, Element.DataType dataType, 110 int size, long seed, boolean includeExtremes) { 111 Element element = getElement(rs, dataType, size); 112 Allocation alloc = Allocation.createSized(rs, element, INPUTSIZE); 113 int width = (size == 3) ? 4 : size; 114 if (dataType == Element.DataType.FLOAT_64) { 115 double[] inArray = new double[INPUTSIZE * width]; 116 // TODO The ranges for float is too small. We need to accept a wider range of values. 117 double min = -4.0 * Math.PI; 118 double max = 4.0 * Math.PI; 119 RSUtils.genRandomDoubles(seed, min, max, inArray, includeExtremes); 120 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 121 } else if (dataType == Element.DataType.FLOAT_32) { 122 float[] inArray = new float[INPUTSIZE * width]; 123 // TODO The ranges for float is too small. We need to accept a wider range of values. 124 float min = -4.0f * (float) Math.PI; 125 float max = 4.0f * (float) Math.PI; 126 RSUtils.genRandomFloats(seed, min, max, inArray, includeExtremes); 127 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 128 } else if (dataType == Element.DataType.SIGNED_64) { 129 long[] inArray = new long[INPUTSIZE * width]; 130 RSUtils.genRandomLongs(seed, inArray, true, 63); 131 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 132 } else if (dataType == Element.DataType.UNSIGNED_64) { 133 long[] inArray = new long[INPUTSIZE * width]; 134 RSUtils.genRandomLongs(seed, inArray, false, 64); 135 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 136 } else if (dataType == Element.DataType.SIGNED_32) { 137 int[] inArray = new int[INPUTSIZE * width]; 138 RSUtils.genRandomInts(seed, inArray, true, 31); 139 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 140 } else if (dataType == Element.DataType.UNSIGNED_32) { 141 int[] inArray = new int[INPUTSIZE * width]; 142 RSUtils.genRandomInts(seed, inArray, false, 32); 143 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 144 } else if (dataType == Element.DataType.SIGNED_16) { 145 short[] inArray = new short[INPUTSIZE * width]; 146 RSUtils.genRandomShorts(seed, inArray, true, 15); 147 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 148 } else if (dataType == Element.DataType.UNSIGNED_16) { 149 short[] inArray = new short[INPUTSIZE * width]; 150 RSUtils.genRandomShorts(seed, inArray, false, 16); 151 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 152 } else if (dataType == Element.DataType.SIGNED_8) { 153 byte[] inArray = new byte[INPUTSIZE * width]; 154 RSUtils.genRandomBytes(seed, inArray, true, 7); 155 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 156 } else if (dataType == Element.DataType.UNSIGNED_8) { 157 byte[] inArray = new byte[INPUTSIZE * width]; 158 RSUtils.genRandomBytes(seed, inArray, true, 8); 159 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 160 } else { 161 android.util.Log.e("RenderscriptCTS", "Don't know how to create allocation of type" + 162 dataType.toString()); 163 } 164 return alloc; 165 } 166 167 protected Allocation createRandomFloatAllocation(RenderScript rs, Element.DataType dataType, 168 int size, long seed, double minValue, double maxValue) { 169 Element element = getElement(rs, dataType, size); 170 Allocation alloc = Allocation.createSized(rs, element, INPUTSIZE); 171 int width = (size == 3) ? 4 : size; 172 if (dataType == Element.DataType.FLOAT_64) { 173 double[] inArray = new double[INPUTSIZE * width]; 174 RSUtils.genRandomDoubles(seed, minValue, maxValue, inArray, false); 175 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 176 } else if (dataType == Element.DataType.FLOAT_32) { 177 float[] inArray = new float[INPUTSIZE * width]; 178 RSUtils.genRandomFloats(seed, (float) minValue, (float) maxValue, inArray, false); 179 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 180 } else { 181 android.util.Log.e("RenderscriptCTS", 182 "Don't know how to create a random float allocation for " + 183 dataType.toString()); 184 } 185 return alloc; 186 } 187 188 protected Allocation createRandomIntegerAllocation(RenderScript rs, Element.DataType dataType, 189 int size, long seed, boolean signed, int numberOfBits) { 190 Element element = getElement(rs, dataType, size); 191 Allocation alloc = Allocation.createSized(rs, element, INPUTSIZE); 192 int width = (size == 3) ? 4 : size; 193 if (dataType == Element.DataType.SIGNED_64 || 194 dataType == Element.DataType.UNSIGNED_64) { 195 long[] inArray = new long[INPUTSIZE * width]; 196 RSUtils.genRandomLongs(seed, inArray, signed, numberOfBits); 197 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 198 } else 199 if (dataType == Element.DataType.SIGNED_32 || 200 dataType == Element.DataType.UNSIGNED_32) { 201 int[] inArray = new int[INPUTSIZE * width]; 202 RSUtils.genRandomInts(seed, inArray, signed, numberOfBits); 203 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 204 } else if (dataType == Element.DataType.SIGNED_16 || 205 dataType == Element.DataType.UNSIGNED_16) { 206 short[] inArray = new short[INPUTSIZE * width]; 207 RSUtils.genRandomShorts(seed, inArray, signed, numberOfBits); 208 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 209 } else if (dataType == Element.DataType.SIGNED_8 || 210 dataType == Element.DataType.UNSIGNED_8) { 211 byte[] inArray = new byte[INPUTSIZE * width]; 212 RSUtils.genRandomBytes(seed, inArray, signed, numberOfBits); 213 alloc.copy1DRangeFrom(0, INPUTSIZE, inArray); 214 } else { 215 android.util.Log.e("RenderscriptCTS", 216 "Don't know how to create an integer allocation of type" + 217 dataType.toString()); 218 } 219 return alloc; 220 } 221 222 protected <T> void enforceOrdering(/*RenderScript rs,*/ Allocation minAlloc, Allocation maxAlloc) { 223 Element element = minAlloc.getElement(); 224 int stride = element.getVectorSize(); 225 if (stride == 3) { 226 stride = 4; 227 } 228 int size = INPUTSIZE * stride; 229 Element.DataType dataType = element.getDataType(); 230 if (dataType == Element.DataType.FLOAT_64) { 231 double[] minArray = new double[size]; 232 double[] maxArray = new double[size]; 233 minAlloc.copyTo(minArray); 234 maxAlloc.copyTo(maxArray); 235 for (int i = 0; i < size; i++) { 236 if (minArray[i] > maxArray[i]) { 237 double temp = minArray[i]; 238 minArray[i] = maxArray[i]; 239 maxArray[i] = temp; 240 } 241 } 242 minAlloc.copyFrom(minArray); 243 maxAlloc.copyFrom(maxArray); 244 } else 245 if (dataType == Element.DataType.FLOAT_32) { 246 float[] minArray = new float[size]; 247 float[] maxArray = new float[size]; 248 minAlloc.copyTo(minArray); 249 maxAlloc.copyTo(maxArray); 250 for (int i = 0; i < size; i++) { 251 if (minArray[i] > maxArray[i]) { 252 float temp = minArray[i]; 253 minArray[i] = maxArray[i]; 254 maxArray[i] = temp; 255 } 256 } 257 minAlloc.copyFrom(minArray); 258 maxAlloc.copyFrom(maxArray); 259 } else if (dataType == Element.DataType.SIGNED_64) { 260 long[] minArray = new long[size]; 261 long[] maxArray = new long[size]; 262 minAlloc.copyTo(minArray); 263 maxAlloc.copyTo(maxArray); 264 for (int i = 0; i < size; i++) { 265 if (minArray[i] > maxArray[i]) { 266 long temp = minArray[i]; 267 minArray[i] = maxArray[i]; 268 maxArray[i] = temp; 269 } 270 } 271 minAlloc.copyFrom(minArray); 272 maxAlloc.copyFrom(maxArray); 273 } else if (dataType == Element.DataType.UNSIGNED_64) { 274 long[] minArray = new long[size]; 275 long[] maxArray = new long[size]; 276 minAlloc.copyTo(minArray); 277 maxAlloc.copyTo(maxArray); 278 for (int i = 0; i < size; i++) { 279 if (RSUtils.compareUnsignedLong(minArray[i], maxArray[i]) > 0) { 280 long temp = minArray[i]; 281 minArray[i] = maxArray[i]; 282 maxArray[i] = temp; 283 } 284 } 285 minAlloc.copyFrom(minArray); 286 maxAlloc.copyFrom(maxArray); 287 } else if (dataType == Element.DataType.SIGNED_32) { 288 int[] minArray = new int[size]; 289 int[] maxArray = new int[size]; 290 minAlloc.copyTo(minArray); 291 maxAlloc.copyTo(maxArray); 292 for (int i = 0; i < size; i++) { 293 if (minArray[i] > maxArray[i]) { 294 int temp = minArray[i]; 295 minArray[i] = maxArray[i]; 296 maxArray[i] = temp; 297 } 298 } 299 minAlloc.copyFrom(minArray); 300 maxAlloc.copyFrom(maxArray); 301 } else if (dataType == Element.DataType.UNSIGNED_32) { 302 int[] minArray = new int[size]; 303 int[] maxArray = new int[size]; 304 minAlloc.copyTo(minArray); 305 maxAlloc.copyTo(maxArray); 306 for (int i = 0; i < size; i++) { 307 long min = minArray[i] &0xffffffffl; 308 long max = maxArray[i] &0xffffffffl; 309 if (min > max) { 310 minArray[i] = (int) max; 311 maxArray[i] = (int) min; 312 } 313 } 314 minAlloc.copyFrom(minArray); 315 maxAlloc.copyFrom(maxArray); 316 } else if (dataType == Element.DataType.SIGNED_16) { 317 short[] minArray = new short[size]; 318 short[] maxArray = new short[size]; 319 minAlloc.copyTo(minArray); 320 maxAlloc.copyTo(maxArray); 321 for (int i = 0; i < size; i++) { 322 if (minArray[i] > maxArray[i]) { 323 short temp = minArray[i]; 324 minArray[i] = maxArray[i]; 325 maxArray[i] = temp; 326 } 327 } 328 minAlloc.copyFrom(minArray); 329 maxAlloc.copyFrom(maxArray); 330 } else if (dataType == Element.DataType.UNSIGNED_16) { 331 short[] minArray = new short[size]; 332 short[] maxArray = new short[size]; 333 minAlloc.copyTo(minArray); 334 maxAlloc.copyTo(maxArray); 335 for (int i = 0; i < size; i++) { 336 int min = minArray[i] &0xffff; 337 int max = maxArray[i] &0xffff; 338 if (min > max) { 339 minArray[i] = (short) max; 340 maxArray[i] = (short) min; 341 } 342 } 343 minAlloc.copyFrom(minArray); 344 maxAlloc.copyFrom(maxArray); 345 } else if (dataType == Element.DataType.SIGNED_8) { 346 byte[] minArray = new byte[size]; 347 byte[] maxArray = new byte[size]; 348 minAlloc.copyTo(minArray); 349 maxAlloc.copyTo(maxArray); 350 for (int i = 0; i < size; i++) { 351 if (minArray[i] > maxArray[i]) { 352 byte temp = minArray[i]; 353 minArray[i] = maxArray[i]; 354 maxArray[i] = temp; 355 } 356 } 357 minAlloc.copyFrom(minArray); 358 maxAlloc.copyFrom(maxArray); 359 } else if (dataType == Element.DataType.UNSIGNED_8) { 360 byte[] minArray = new byte[size]; 361 byte[] maxArray = new byte[size]; 362 minAlloc.copyTo(minArray); 363 maxAlloc.copyTo(maxArray); 364 for (int i = 0; i < size; i++) { 365 int min = minArray[i] &0xff; 366 int max = maxArray[i] &0xff; 367 if (min > max) { 368 minArray[i] = (byte) max; 369 maxArray[i] = (byte) min; 370 } 371 } 372 minAlloc.copyFrom(minArray); 373 maxAlloc.copyFrom(maxArray); 374 } else { 375 android.util.Log.e("RenderscriptCTS", "Ordering not supported for " + 376 dataType.toString()); 377 } 378 } 379 380 public void forEach(int testId, Allocation mIn, Allocation mOut) throws RSRuntimeException { 381 // Intentionally empty... subclass will likely define only one, but not both 382 } 383 384 public void forEach(int testId, Allocation mIn) throws RSRuntimeException { 385 // Intentionally empty... subclass will likely define only one, but not both 386 } 387 388 protected void appendVariableToMessage(StringBuilder message, int value) { 389 message.append(String.format("%d {%x}", value, value)); 390 } 391 392 protected void appendVariableToMessage(StringBuilder message, float value) { 393 message.append(String.format("%14.8g {%8x} %15a", value, 394 Float.floatToRawIntBits(value), value)); 395 } 396 397 protected void appendVariableToMessage(StringBuilder message, double value) { 398 message.append(String.format("%24.8g {%16x} %31a", value, 399 Double.doubleToRawLongBits(value), value)); 400 } 401 402 protected void appendVariableToMessage(StringBuilder message, Target.Floaty value) { 403 message.append(value.toString()); 404 } 405 } 406