[RenderScript] Utility functions to generate random Float16 Allocations.

http://b/23536224

The numbers are randomly generated in the range [MIN_NORMAL, 16.0].  To
include negative numbers, about half of the generated numbers are
negated.

Some special Float16 values are also substituted randomly.  Extreme
values are included when corresponding parameter is set.

Change-Id: I827bea2945387ccdac4704bb5ba1db978cab2d05
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
index 0ba8248..384e41c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
@@ -80,6 +80,8 @@
                 element = Element.F64(rs);
             } else if (dataType == Element.DataType.FLOAT_32) {
                 element = Element.F32(rs);
+            } else if (dataType == Element.DataType.FLOAT_16) {
+                element = Element.F16(rs);
             } else if (dataType == Element.DataType.SIGNED_64) {
                 element = Element.I64(rs);
             } else if (dataType == Element.DataType.UNSIGNED_64) {
@@ -125,6 +127,12 @@
             float max = 4.0f * (float) Math.PI;
             RSUtils.genRandomFloats(seed, min, max, inArray, includeExtremes);
             alloc.copy1DRangeFrom(0, INPUTSIZE, inArray);
+        } else if (dataType == Element.DataType.FLOAT_16) {
+            short[] inArray = new short[INPUTSIZE * width];
+            short min = 1024; // 0x0400 in hex, 2^-14, i.e. float16 MIN_NORMAL
+            short max = 19456; // 0x4c00 in hex, 16.0 in float16
+            RSUtils.genRandomFloat16s(seed, min, max, inArray, includeExtremes);
+            alloc.copyFrom(inArray);
         } else if (dataType == Element.DataType.SIGNED_64) {
             long[] inArray = new long[INPUTSIZE * width];
             RSUtils.genRandomLongs(seed, inArray, true, 63);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java b/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
index 6038d90..e7524a6 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSUtils.java
@@ -41,6 +41,23 @@
         -Math.PI * 2.0,
     };
 
+    // Constants E, PI etc. are set to their nearest representations in Float16.
+    private static final short[] sInterestingFloat16s = {
+        (short) 0x0, // zero
+        (short) 0x3c00, // one
+        (short) 0x4170, // E, 2.71875000000
+        (short) 0x4248, // PI, 3.14062500000
+        (short) 0x3e48, // PI / 2, 1.57031250000
+        (short) 0x4648, // PI * 2, 6.28125000000
+
+        (short) 0x8000, // negative zero
+        (short) 0xbc00, // negative one
+        (short) 0xc170, // -E, -2.71875000000
+        (short) 0xc248, // -PI, -3.14062500000
+        (short) 0xbe48, // -PI / 2, -1.57031250000
+        (short) 0xc648, // -PI * 2, -6.28125000000
+    };
+
     /**
      * Fills the array with random doubles.  Values will be between min (inclusive) and
      * max (inclusive).
@@ -143,6 +160,37 @@
         }
     }
 
+    public static void genRandomFloat16s(long seed, short min, short max, short array[],
+            boolean includeExtremes) {
+        Random r = new Random(seed);
+        short range = (short) (max - min + 1);
+        for (int i = 0; i < array.length; i ++) {
+            array[i] = (short) (min + r.nextInt(range));
+        }
+        array[r.nextInt(array.length)] = min;
+        array[r.nextInt(array.length)] = max;
+
+        // Negate approximately half of the elements.
+        for (int i = 0; i < array.length; i ++) {
+            if (r.nextBoolean()) {
+                array[i] = (short) (0x8000 | array[i]);
+            }
+        }
+
+        for (short s : sInterestingFloat16s) {
+            array[r.nextInt(array.length)] = s;
+        }
+        if (includeExtremes) {
+            array[r.nextInt(array.length)] = (short) 0x7c01; // NaN
+            array[r.nextInt(array.length)] = (short) 0x7c00; // POSITIVE_INFINITY
+            array[r.nextInt(array.length)] = (short) 0xfc00; // NEGATIVE_INFINITY
+            array[r.nextInt(array.length)] = (short) 0x0400; // MIN_NORMAL, 0.00006103516
+            array[r.nextInt(array.length)] = (short) 0x7bff; // MAX_VALUE, 65504
+            array[r.nextInt(array.length)] = (short) 0x8400; // -MIN_NORMAL, -0.00006103516
+            array[r.nextInt(array.length)] = (short) 0xfbff; // -MAX_VALUE, -65504
+        }
+    }
+
     /**
      * Fills the array with random ints.  Values will be between min (inclusive) and
      * max (inclusive).