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 // Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
18 
19 package android.renderscript.cts;
20 
21 import android.renderscript.Allocation;
22 import android.renderscript.RSRuntimeException;
23 import android.renderscript.Element;
24 import android.renderscript.cts.Target;
25 
26 import java.util.Arrays;
27 
28 public class TestFma extends RSBaseCompute {
29 
30     private ScriptC_TestFma script;
31     private ScriptC_TestFmaRelaxed scriptRelaxed;
32 
33     @Override
setUp()34     protected void setUp() throws Exception {
35         super.setUp();
36         script = new ScriptC_TestFma(mRS);
37         scriptRelaxed = new ScriptC_TestFmaRelaxed(mRS);
38     }
39 
40     public class ArgumentsFloatFloatFloatFloat {
41         public float inMultiplicand1;
42         public float inMultiplicand2;
43         public float inOffset;
44         public Target.Floaty out;
45     }
46 
checkFmaFloatFloatFloatFloat()47     private void checkFmaFloatFloatFloatFloat() {
48         Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x85c419bel, false);
49         Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x85c419bfl, false);
50         Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9d441b0el, false);
51         try {
52             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
53             script.set_gAllocInMultiplicand2(inMultiplicand2);
54             script.set_gAllocInOffset(inOffset);
55             script.forEach_testFmaFloatFloatFloatFloat(inMultiplicand1, out);
56             verifyResultsFmaFloatFloatFloatFloat(inMultiplicand1, inMultiplicand2, inOffset, out, false);
57         } catch (Exception e) {
58             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloatFloatFloatFloat: " + e.toString());
59         }
60         try {
61             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
62             scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
63             scriptRelaxed.set_gAllocInOffset(inOffset);
64             scriptRelaxed.forEach_testFmaFloatFloatFloatFloat(inMultiplicand1, out);
65             verifyResultsFmaFloatFloatFloatFloat(inMultiplicand1, inMultiplicand2, inOffset, out, true);
66         } catch (Exception e) {
67             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloatFloatFloatFloat: " + e.toString());
68         }
69     }
70 
verifyResultsFmaFloatFloatFloatFloat(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed)71     private void verifyResultsFmaFloatFloatFloatFloat(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
72         float[] arrayInMultiplicand1 = new float[INPUTSIZE * 1];
73         Arrays.fill(arrayInMultiplicand1, (float) 42);
74         inMultiplicand1.copyTo(arrayInMultiplicand1);
75         float[] arrayInMultiplicand2 = new float[INPUTSIZE * 1];
76         Arrays.fill(arrayInMultiplicand2, (float) 42);
77         inMultiplicand2.copyTo(arrayInMultiplicand2);
78         float[] arrayInOffset = new float[INPUTSIZE * 1];
79         Arrays.fill(arrayInOffset, (float) 42);
80         inOffset.copyTo(arrayInOffset);
81         float[] arrayOut = new float[INPUTSIZE * 1];
82         Arrays.fill(arrayOut, (float) 42);
83         out.copyTo(arrayOut);
84         StringBuilder message = new StringBuilder();
85         boolean errorFound = false;
86         for (int i = 0; i < INPUTSIZE; i++) {
87             for (int j = 0; j < 1 ; j++) {
88                 // Extract the inputs.
89                 ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
90                 args.inMultiplicand1 = arrayInMultiplicand1[i];
91                 args.inMultiplicand2 = arrayInMultiplicand2[i];
92                 args.inOffset = arrayInOffset[i];
93                 // Figure out what the outputs should have been.
94                 Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
95                 CoreMathVerifier.computeFma(args, target);
96                 // Validate the outputs.
97                 boolean valid = true;
98                 if (!args.out.couldBe(arrayOut[i * 1 + j])) {
99                     valid = false;
100                 }
101                 if (!valid) {
102                     if (!errorFound) {
103                         errorFound = true;
104                         message.append("Input inMultiplicand1: ");
105                         appendVariableToMessage(message, args.inMultiplicand1);
106                         message.append("\n");
107                         message.append("Input inMultiplicand2: ");
108                         appendVariableToMessage(message, args.inMultiplicand2);
109                         message.append("\n");
110                         message.append("Input inOffset: ");
111                         appendVariableToMessage(message, args.inOffset);
112                         message.append("\n");
113                         message.append("Expected output out: ");
114                         appendVariableToMessage(message, args.out);
115                         message.append("\n");
116                         message.append("Actual   output out: ");
117                         appendVariableToMessage(message, arrayOut[i * 1 + j]);
118                         if (!args.out.couldBe(arrayOut[i * 1 + j])) {
119                             message.append(" FAIL");
120                         }
121                         message.append("\n");
122                         message.append("Errors at");
123                     }
124                     message.append(" [");
125                     message.append(Integer.toString(i));
126                     message.append(", ");
127                     message.append(Integer.toString(j));
128                     message.append("]");
129                 }
130             }
131         }
132         assertFalse("Incorrect output for checkFmaFloatFloatFloatFloat" +
133                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
134     }
135 
checkFmaFloat2Float2Float2Float2()136     private void checkFmaFloat2Float2Float2Float2() {
137         Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdda15056l, false);
138         Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdda15057l, false);
139         Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8aeda396l, false);
140         try {
141             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
142             script.set_gAllocInMultiplicand2(inMultiplicand2);
143             script.set_gAllocInOffset(inOffset);
144             script.forEach_testFmaFloat2Float2Float2Float2(inMultiplicand1, out);
145             verifyResultsFmaFloat2Float2Float2Float2(inMultiplicand1, inMultiplicand2, inOffset, out, false);
146         } catch (Exception e) {
147             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat2Float2Float2Float2: " + e.toString());
148         }
149         try {
150             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
151             scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
152             scriptRelaxed.set_gAllocInOffset(inOffset);
153             scriptRelaxed.forEach_testFmaFloat2Float2Float2Float2(inMultiplicand1, out);
154             verifyResultsFmaFloat2Float2Float2Float2(inMultiplicand1, inMultiplicand2, inOffset, out, true);
155         } catch (Exception e) {
156             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat2Float2Float2Float2: " + e.toString());
157         }
158     }
159 
verifyResultsFmaFloat2Float2Float2Float2(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed)160     private void verifyResultsFmaFloat2Float2Float2Float2(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
161         float[] arrayInMultiplicand1 = new float[INPUTSIZE * 2];
162         Arrays.fill(arrayInMultiplicand1, (float) 42);
163         inMultiplicand1.copyTo(arrayInMultiplicand1);
164         float[] arrayInMultiplicand2 = new float[INPUTSIZE * 2];
165         Arrays.fill(arrayInMultiplicand2, (float) 42);
166         inMultiplicand2.copyTo(arrayInMultiplicand2);
167         float[] arrayInOffset = new float[INPUTSIZE * 2];
168         Arrays.fill(arrayInOffset, (float) 42);
169         inOffset.copyTo(arrayInOffset);
170         float[] arrayOut = new float[INPUTSIZE * 2];
171         Arrays.fill(arrayOut, (float) 42);
172         out.copyTo(arrayOut);
173         StringBuilder message = new StringBuilder();
174         boolean errorFound = false;
175         for (int i = 0; i < INPUTSIZE; i++) {
176             for (int j = 0; j < 2 ; j++) {
177                 // Extract the inputs.
178                 ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
179                 args.inMultiplicand1 = arrayInMultiplicand1[i * 2 + j];
180                 args.inMultiplicand2 = arrayInMultiplicand2[i * 2 + j];
181                 args.inOffset = arrayInOffset[i * 2 + j];
182                 // Figure out what the outputs should have been.
183                 Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
184                 CoreMathVerifier.computeFma(args, target);
185                 // Validate the outputs.
186                 boolean valid = true;
187                 if (!args.out.couldBe(arrayOut[i * 2 + j])) {
188                     valid = false;
189                 }
190                 if (!valid) {
191                     if (!errorFound) {
192                         errorFound = true;
193                         message.append("Input inMultiplicand1: ");
194                         appendVariableToMessage(message, args.inMultiplicand1);
195                         message.append("\n");
196                         message.append("Input inMultiplicand2: ");
197                         appendVariableToMessage(message, args.inMultiplicand2);
198                         message.append("\n");
199                         message.append("Input inOffset: ");
200                         appendVariableToMessage(message, args.inOffset);
201                         message.append("\n");
202                         message.append("Expected output out: ");
203                         appendVariableToMessage(message, args.out);
204                         message.append("\n");
205                         message.append("Actual   output out: ");
206                         appendVariableToMessage(message, arrayOut[i * 2 + j]);
207                         if (!args.out.couldBe(arrayOut[i * 2 + j])) {
208                             message.append(" FAIL");
209                         }
210                         message.append("\n");
211                         message.append("Errors at");
212                     }
213                     message.append(" [");
214                     message.append(Integer.toString(i));
215                     message.append(", ");
216                     message.append(Integer.toString(j));
217                     message.append("]");
218                 }
219             }
220         }
221         assertFalse("Incorrect output for checkFmaFloat2Float2Float2Float2" +
222                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
223     }
224 
checkFmaFloat3Float3Float3Float3()225     private void checkFmaFloat3Float3Float3Float3() {
226         Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x349697b2l, false);
227         Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x349697b3l, false);
228         Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x54d5ec8al, false);
229         try {
230             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
231             script.set_gAllocInMultiplicand2(inMultiplicand2);
232             script.set_gAllocInOffset(inOffset);
233             script.forEach_testFmaFloat3Float3Float3Float3(inMultiplicand1, out);
234             verifyResultsFmaFloat3Float3Float3Float3(inMultiplicand1, inMultiplicand2, inOffset, out, false);
235         } catch (Exception e) {
236             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat3Float3Float3Float3: " + e.toString());
237         }
238         try {
239             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
240             scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
241             scriptRelaxed.set_gAllocInOffset(inOffset);
242             scriptRelaxed.forEach_testFmaFloat3Float3Float3Float3(inMultiplicand1, out);
243             verifyResultsFmaFloat3Float3Float3Float3(inMultiplicand1, inMultiplicand2, inOffset, out, true);
244         } catch (Exception e) {
245             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat3Float3Float3Float3: " + e.toString());
246         }
247     }
248 
verifyResultsFmaFloat3Float3Float3Float3(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed)249     private void verifyResultsFmaFloat3Float3Float3Float3(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
250         float[] arrayInMultiplicand1 = new float[INPUTSIZE * 4];
251         Arrays.fill(arrayInMultiplicand1, (float) 42);
252         inMultiplicand1.copyTo(arrayInMultiplicand1);
253         float[] arrayInMultiplicand2 = new float[INPUTSIZE * 4];
254         Arrays.fill(arrayInMultiplicand2, (float) 42);
255         inMultiplicand2.copyTo(arrayInMultiplicand2);
256         float[] arrayInOffset = new float[INPUTSIZE * 4];
257         Arrays.fill(arrayInOffset, (float) 42);
258         inOffset.copyTo(arrayInOffset);
259         float[] arrayOut = new float[INPUTSIZE * 4];
260         Arrays.fill(arrayOut, (float) 42);
261         out.copyTo(arrayOut);
262         StringBuilder message = new StringBuilder();
263         boolean errorFound = false;
264         for (int i = 0; i < INPUTSIZE; i++) {
265             for (int j = 0; j < 3 ; j++) {
266                 // Extract the inputs.
267                 ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
268                 args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
269                 args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
270                 args.inOffset = arrayInOffset[i * 4 + j];
271                 // Figure out what the outputs should have been.
272                 Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
273                 CoreMathVerifier.computeFma(args, target);
274                 // Validate the outputs.
275                 boolean valid = true;
276                 if (!args.out.couldBe(arrayOut[i * 4 + j])) {
277                     valid = false;
278                 }
279                 if (!valid) {
280                     if (!errorFound) {
281                         errorFound = true;
282                         message.append("Input inMultiplicand1: ");
283                         appendVariableToMessage(message, args.inMultiplicand1);
284                         message.append("\n");
285                         message.append("Input inMultiplicand2: ");
286                         appendVariableToMessage(message, args.inMultiplicand2);
287                         message.append("\n");
288                         message.append("Input inOffset: ");
289                         appendVariableToMessage(message, args.inOffset);
290                         message.append("\n");
291                         message.append("Expected output out: ");
292                         appendVariableToMessage(message, args.out);
293                         message.append("\n");
294                         message.append("Actual   output out: ");
295                         appendVariableToMessage(message, arrayOut[i * 4 + j]);
296                         if (!args.out.couldBe(arrayOut[i * 4 + j])) {
297                             message.append(" FAIL");
298                         }
299                         message.append("\n");
300                         message.append("Errors at");
301                     }
302                     message.append(" [");
303                     message.append(Integer.toString(i));
304                     message.append(", ");
305                     message.append(Integer.toString(j));
306                     message.append("]");
307                 }
308             }
309         }
310         assertFalse("Incorrect output for checkFmaFloat3Float3Float3Float3" +
311                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
312     }
313 
checkFmaFloat4Float4Float4Float4()314     private void checkFmaFloat4Float4Float4Float4() {
315         Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8b8bdf0el, false);
316         Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8b8bdf0fl, false);
317         Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1ebe357el, false);
318         try {
319             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
320             script.set_gAllocInMultiplicand2(inMultiplicand2);
321             script.set_gAllocInOffset(inOffset);
322             script.forEach_testFmaFloat4Float4Float4Float4(inMultiplicand1, out);
323             verifyResultsFmaFloat4Float4Float4Float4(inMultiplicand1, inMultiplicand2, inOffset, out, false);
324         } catch (Exception e) {
325             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat4Float4Float4Float4: " + e.toString());
326         }
327         try {
328             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
329             scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
330             scriptRelaxed.set_gAllocInOffset(inOffset);
331             scriptRelaxed.forEach_testFmaFloat4Float4Float4Float4(inMultiplicand1, out);
332             verifyResultsFmaFloat4Float4Float4Float4(inMultiplicand1, inMultiplicand2, inOffset, out, true);
333         } catch (Exception e) {
334             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat4Float4Float4Float4: " + e.toString());
335         }
336     }
337 
verifyResultsFmaFloat4Float4Float4Float4(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed)338     private void verifyResultsFmaFloat4Float4Float4Float4(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
339         float[] arrayInMultiplicand1 = new float[INPUTSIZE * 4];
340         Arrays.fill(arrayInMultiplicand1, (float) 42);
341         inMultiplicand1.copyTo(arrayInMultiplicand1);
342         float[] arrayInMultiplicand2 = new float[INPUTSIZE * 4];
343         Arrays.fill(arrayInMultiplicand2, (float) 42);
344         inMultiplicand2.copyTo(arrayInMultiplicand2);
345         float[] arrayInOffset = new float[INPUTSIZE * 4];
346         Arrays.fill(arrayInOffset, (float) 42);
347         inOffset.copyTo(arrayInOffset);
348         float[] arrayOut = new float[INPUTSIZE * 4];
349         Arrays.fill(arrayOut, (float) 42);
350         out.copyTo(arrayOut);
351         StringBuilder message = new StringBuilder();
352         boolean errorFound = false;
353         for (int i = 0; i < INPUTSIZE; i++) {
354             for (int j = 0; j < 4 ; j++) {
355                 // Extract the inputs.
356                 ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
357                 args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
358                 args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
359                 args.inOffset = arrayInOffset[i * 4 + j];
360                 // Figure out what the outputs should have been.
361                 Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.FLOAT, relaxed);
362                 CoreMathVerifier.computeFma(args, target);
363                 // Validate the outputs.
364                 boolean valid = true;
365                 if (!args.out.couldBe(arrayOut[i * 4 + j])) {
366                     valid = false;
367                 }
368                 if (!valid) {
369                     if (!errorFound) {
370                         errorFound = true;
371                         message.append("Input inMultiplicand1: ");
372                         appendVariableToMessage(message, args.inMultiplicand1);
373                         message.append("\n");
374                         message.append("Input inMultiplicand2: ");
375                         appendVariableToMessage(message, args.inMultiplicand2);
376                         message.append("\n");
377                         message.append("Input inOffset: ");
378                         appendVariableToMessage(message, args.inOffset);
379                         message.append("\n");
380                         message.append("Expected output out: ");
381                         appendVariableToMessage(message, args.out);
382                         message.append("\n");
383                         message.append("Actual   output out: ");
384                         appendVariableToMessage(message, arrayOut[i * 4 + j]);
385                         if (!args.out.couldBe(arrayOut[i * 4 + j])) {
386                             message.append(" FAIL");
387                         }
388                         message.append("\n");
389                         message.append("Errors at");
390                     }
391                     message.append(" [");
392                     message.append(Integer.toString(i));
393                     message.append(", ");
394                     message.append(Integer.toString(j));
395                     message.append("]");
396                 }
397             }
398         }
399         assertFalse("Incorrect output for checkFmaFloat4Float4Float4Float4" +
400                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
401     }
402 
403     public class ArgumentsHalfHalfHalfHalf {
404         public short inMultiplicand1;
405         public double inMultiplicand1Double;
406         public short inMultiplicand2;
407         public double inMultiplicand2Double;
408         public short inOffset;
409         public double inOffsetDouble;
410         public Target.Floaty out;
411     }
412 
checkFmaHalfHalfHalfHalf()413     private void checkFmaHalfHalfHalfHalf() {
414         Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xd7c6a182l, false);
415         Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0xd7c6a183l, false);
416         Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 1, 0x663f87al, false);
417         try {
418             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
419             script.set_gAllocInMultiplicand2(inMultiplicand2);
420             script.set_gAllocInOffset(inOffset);
421             script.forEach_testFmaHalfHalfHalfHalf(inMultiplicand1, out);
422             verifyResultsFmaHalfHalfHalfHalf(inMultiplicand1, inMultiplicand2, inOffset, out, false);
423         } catch (Exception e) {
424             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalfHalfHalfHalf: " + e.toString());
425         }
426         try {
427             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 1), INPUTSIZE);
428             scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
429             scriptRelaxed.set_gAllocInOffset(inOffset);
430             scriptRelaxed.forEach_testFmaHalfHalfHalfHalf(inMultiplicand1, out);
431             verifyResultsFmaHalfHalfHalfHalf(inMultiplicand1, inMultiplicand2, inOffset, out, true);
432         } catch (Exception e) {
433             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalfHalfHalfHalf: " + e.toString());
434         }
435     }
436 
verifyResultsFmaHalfHalfHalfHalf(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed)437     private void verifyResultsFmaHalfHalfHalfHalf(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
438         short[] arrayInMultiplicand1 = new short[INPUTSIZE * 1];
439         Arrays.fill(arrayInMultiplicand1, (short) 42);
440         inMultiplicand1.copyTo(arrayInMultiplicand1);
441         short[] arrayInMultiplicand2 = new short[INPUTSIZE * 1];
442         Arrays.fill(arrayInMultiplicand2, (short) 42);
443         inMultiplicand2.copyTo(arrayInMultiplicand2);
444         short[] arrayInOffset = new short[INPUTSIZE * 1];
445         Arrays.fill(arrayInOffset, (short) 42);
446         inOffset.copyTo(arrayInOffset);
447         short[] arrayOut = new short[INPUTSIZE * 1];
448         Arrays.fill(arrayOut, (short) 42);
449         out.copyTo(arrayOut);
450         StringBuilder message = new StringBuilder();
451         boolean errorFound = false;
452         for (int i = 0; i < INPUTSIZE; i++) {
453             for (int j = 0; j < 1 ; j++) {
454                 // Extract the inputs.
455                 ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
456                 args.inMultiplicand1 = arrayInMultiplicand1[i];
457                 args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
458                 args.inMultiplicand2 = arrayInMultiplicand2[i];
459                 args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
460                 args.inOffset = arrayInOffset[i];
461                 args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
462                 // Figure out what the outputs should have been.
463                 Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
464                 CoreMathVerifier.computeFma(args, target);
465                 // Validate the outputs.
466                 boolean valid = true;
467                 if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
468                     valid = false;
469                 }
470                 if (!valid) {
471                     if (!errorFound) {
472                         errorFound = true;
473                         message.append("Input inMultiplicand1: ");
474                         appendVariableToMessage(message, args.inMultiplicand1);
475                         message.append("\n");
476                         message.append("Input inMultiplicand2: ");
477                         appendVariableToMessage(message, args.inMultiplicand2);
478                         message.append("\n");
479                         message.append("Input inOffset: ");
480                         appendVariableToMessage(message, args.inOffset);
481                         message.append("\n");
482                         message.append("Expected output out: ");
483                         appendVariableToMessage(message, args.out);
484                         message.append("\n");
485                         message.append("Actual   output out: ");
486                         appendVariableToMessage(message, arrayOut[i * 1 + j]);
487                         message.append("\n");
488                         message.append("Actual   output out (in double): ");
489                         appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]));
490                         if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 1 + j]))) {
491                             message.append(" FAIL");
492                         }
493                         message.append("\n");
494                         message.append("Errors at");
495                     }
496                     message.append(" [");
497                     message.append(Integer.toString(i));
498                     message.append(", ");
499                     message.append(Integer.toString(j));
500                     message.append("]");
501                 }
502             }
503         }
504         assertFalse("Incorrect output for checkFmaHalfHalfHalfHalf" +
505                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
506     }
507 
checkFmaHalf2Half2Half2Half2()508     private void checkFmaHalf2Half2Half2Half2() {
509         Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2f0bb556l, false);
510         Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0x2f0bb557l, false);
511         Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 2, 0xb6e9fa96l, false);
512         try {
513             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
514             script.set_gAllocInMultiplicand2(inMultiplicand2);
515             script.set_gAllocInOffset(inOffset);
516             script.forEach_testFmaHalf2Half2Half2Half2(inMultiplicand1, out);
517             verifyResultsFmaHalf2Half2Half2Half2(inMultiplicand1, inMultiplicand2, inOffset, out, false);
518         } catch (Exception e) {
519             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf2Half2Half2Half2: " + e.toString());
520         }
521         try {
522             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 2), INPUTSIZE);
523             scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
524             scriptRelaxed.set_gAllocInOffset(inOffset);
525             scriptRelaxed.forEach_testFmaHalf2Half2Half2Half2(inMultiplicand1, out);
526             verifyResultsFmaHalf2Half2Half2Half2(inMultiplicand1, inMultiplicand2, inOffset, out, true);
527         } catch (Exception e) {
528             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf2Half2Half2Half2: " + e.toString());
529         }
530     }
531 
verifyResultsFmaHalf2Half2Half2Half2(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed)532     private void verifyResultsFmaHalf2Half2Half2Half2(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
533         short[] arrayInMultiplicand1 = new short[INPUTSIZE * 2];
534         Arrays.fill(arrayInMultiplicand1, (short) 42);
535         inMultiplicand1.copyTo(arrayInMultiplicand1);
536         short[] arrayInMultiplicand2 = new short[INPUTSIZE * 2];
537         Arrays.fill(arrayInMultiplicand2, (short) 42);
538         inMultiplicand2.copyTo(arrayInMultiplicand2);
539         short[] arrayInOffset = new short[INPUTSIZE * 2];
540         Arrays.fill(arrayInOffset, (short) 42);
541         inOffset.copyTo(arrayInOffset);
542         short[] arrayOut = new short[INPUTSIZE * 2];
543         Arrays.fill(arrayOut, (short) 42);
544         out.copyTo(arrayOut);
545         StringBuilder message = new StringBuilder();
546         boolean errorFound = false;
547         for (int i = 0; i < INPUTSIZE; i++) {
548             for (int j = 0; j < 2 ; j++) {
549                 // Extract the inputs.
550                 ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
551                 args.inMultiplicand1 = arrayInMultiplicand1[i * 2 + j];
552                 args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
553                 args.inMultiplicand2 = arrayInMultiplicand2[i * 2 + j];
554                 args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
555                 args.inOffset = arrayInOffset[i * 2 + j];
556                 args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
557                 // Figure out what the outputs should have been.
558                 Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
559                 CoreMathVerifier.computeFma(args, target);
560                 // Validate the outputs.
561                 boolean valid = true;
562                 if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
563                     valid = false;
564                 }
565                 if (!valid) {
566                     if (!errorFound) {
567                         errorFound = true;
568                         message.append("Input inMultiplicand1: ");
569                         appendVariableToMessage(message, args.inMultiplicand1);
570                         message.append("\n");
571                         message.append("Input inMultiplicand2: ");
572                         appendVariableToMessage(message, args.inMultiplicand2);
573                         message.append("\n");
574                         message.append("Input inOffset: ");
575                         appendVariableToMessage(message, args.inOffset);
576                         message.append("\n");
577                         message.append("Expected output out: ");
578                         appendVariableToMessage(message, args.out);
579                         message.append("\n");
580                         message.append("Actual   output out: ");
581                         appendVariableToMessage(message, arrayOut[i * 2 + j]);
582                         message.append("\n");
583                         message.append("Actual   output out (in double): ");
584                         appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]));
585                         if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 2 + j]))) {
586                             message.append(" FAIL");
587                         }
588                         message.append("\n");
589                         message.append("Errors at");
590                     }
591                     message.append(" [");
592                     message.append(Integer.toString(i));
593                     message.append(", ");
594                     message.append(Integer.toString(j));
595                     message.append("]");
596                 }
597             }
598         }
599         assertFalse("Incorrect output for checkFmaHalf2Half2Half2Half2" +
600                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
601     }
602 
checkFmaHalf3Half3Half3Half3()603     private void checkFmaHalf3Half3Half3Half3() {
604         Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x1a5f3c9el, false);
605         Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x1a5f3c9fl, false);
606         Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 3, 0x1b05aael, false);
607         try {
608             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
609             script.set_gAllocInMultiplicand2(inMultiplicand2);
610             script.set_gAllocInOffset(inOffset);
611             script.forEach_testFmaHalf3Half3Half3Half3(inMultiplicand1, out);
612             verifyResultsFmaHalf3Half3Half3Half3(inMultiplicand1, inMultiplicand2, inOffset, out, false);
613         } catch (Exception e) {
614             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf3Half3Half3Half3: " + e.toString());
615         }
616         try {
617             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 3), INPUTSIZE);
618             scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
619             scriptRelaxed.set_gAllocInOffset(inOffset);
620             scriptRelaxed.forEach_testFmaHalf3Half3Half3Half3(inMultiplicand1, out);
621             verifyResultsFmaHalf3Half3Half3Half3(inMultiplicand1, inMultiplicand2, inOffset, out, true);
622         } catch (Exception e) {
623             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf3Half3Half3Half3: " + e.toString());
624         }
625     }
626 
verifyResultsFmaHalf3Half3Half3Half3(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed)627     private void verifyResultsFmaHalf3Half3Half3Half3(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
628         short[] arrayInMultiplicand1 = new short[INPUTSIZE * 4];
629         Arrays.fill(arrayInMultiplicand1, (short) 42);
630         inMultiplicand1.copyTo(arrayInMultiplicand1);
631         short[] arrayInMultiplicand2 = new short[INPUTSIZE * 4];
632         Arrays.fill(arrayInMultiplicand2, (short) 42);
633         inMultiplicand2.copyTo(arrayInMultiplicand2);
634         short[] arrayInOffset = new short[INPUTSIZE * 4];
635         Arrays.fill(arrayInOffset, (short) 42);
636         inOffset.copyTo(arrayInOffset);
637         short[] arrayOut = new short[INPUTSIZE * 4];
638         Arrays.fill(arrayOut, (short) 42);
639         out.copyTo(arrayOut);
640         StringBuilder message = new StringBuilder();
641         boolean errorFound = false;
642         for (int i = 0; i < INPUTSIZE; i++) {
643             for (int j = 0; j < 3 ; j++) {
644                 // Extract the inputs.
645                 ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
646                 args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
647                 args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
648                 args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
649                 args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
650                 args.inOffset = arrayInOffset[i * 4 + j];
651                 args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
652                 // Figure out what the outputs should have been.
653                 Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
654                 CoreMathVerifier.computeFma(args, target);
655                 // Validate the outputs.
656                 boolean valid = true;
657                 if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
658                     valid = false;
659                 }
660                 if (!valid) {
661                     if (!errorFound) {
662                         errorFound = true;
663                         message.append("Input inMultiplicand1: ");
664                         appendVariableToMessage(message, args.inMultiplicand1);
665                         message.append("\n");
666                         message.append("Input inMultiplicand2: ");
667                         appendVariableToMessage(message, args.inMultiplicand2);
668                         message.append("\n");
669                         message.append("Input inOffset: ");
670                         appendVariableToMessage(message, args.inOffset);
671                         message.append("\n");
672                         message.append("Expected output out: ");
673                         appendVariableToMessage(message, args.out);
674                         message.append("\n");
675                         message.append("Actual   output out: ");
676                         appendVariableToMessage(message, arrayOut[i * 4 + j]);
677                         message.append("\n");
678                         message.append("Actual   output out (in double): ");
679                         appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
680                         if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
681                             message.append(" FAIL");
682                         }
683                         message.append("\n");
684                         message.append("Errors at");
685                     }
686                     message.append(" [");
687                     message.append(Integer.toString(i));
688                     message.append(", ");
689                     message.append(Integer.toString(j));
690                     message.append("]");
691                 }
692             }
693         }
694         assertFalse("Incorrect output for checkFmaHalf3Half3Half3Half3" +
695                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
696     }
697 
checkFmaHalf4Half4Half4Half4()698     private void checkFmaHalf4Half4Half4Half4() {
699         Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x5b2c3e6l, false);
700         Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x5b2c3e7l, false);
701         Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_16, 4, 0x4c76bac6l, false);
702         try {
703             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
704             script.set_gAllocInMultiplicand2(inMultiplicand2);
705             script.set_gAllocInOffset(inOffset);
706             script.forEach_testFmaHalf4Half4Half4Half4(inMultiplicand1, out);
707             verifyResultsFmaHalf4Half4Half4Half4(inMultiplicand1, inMultiplicand2, inOffset, out, false);
708         } catch (Exception e) {
709             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf4Half4Half4Half4: " + e.toString());
710         }
711         try {
712             Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_16, 4), INPUTSIZE);
713             scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
714             scriptRelaxed.set_gAllocInOffset(inOffset);
715             scriptRelaxed.forEach_testFmaHalf4Half4Half4Half4(inMultiplicand1, out);
716             verifyResultsFmaHalf4Half4Half4Half4(inMultiplicand1, inMultiplicand2, inOffset, out, true);
717         } catch (Exception e) {
718             throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaHalf4Half4Half4Half4: " + e.toString());
719         }
720     }
721 
verifyResultsFmaHalf4Half4Half4Half4(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed)722     private void verifyResultsFmaHalf4Half4Half4Half4(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
723         short[] arrayInMultiplicand1 = new short[INPUTSIZE * 4];
724         Arrays.fill(arrayInMultiplicand1, (short) 42);
725         inMultiplicand1.copyTo(arrayInMultiplicand1);
726         short[] arrayInMultiplicand2 = new short[INPUTSIZE * 4];
727         Arrays.fill(arrayInMultiplicand2, (short) 42);
728         inMultiplicand2.copyTo(arrayInMultiplicand2);
729         short[] arrayInOffset = new short[INPUTSIZE * 4];
730         Arrays.fill(arrayInOffset, (short) 42);
731         inOffset.copyTo(arrayInOffset);
732         short[] arrayOut = new short[INPUTSIZE * 4];
733         Arrays.fill(arrayOut, (short) 42);
734         out.copyTo(arrayOut);
735         StringBuilder message = new StringBuilder();
736         boolean errorFound = false;
737         for (int i = 0; i < INPUTSIZE; i++) {
738             for (int j = 0; j < 4 ; j++) {
739                 // Extract the inputs.
740                 ArgumentsHalfHalfHalfHalf args = new ArgumentsHalfHalfHalfHalf();
741                 args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
742                 args.inMultiplicand1Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand1);
743                 args.inMultiplicand2 = arrayInMultiplicand2[i * 4 + j];
744                 args.inMultiplicand2Double = Float16Utils.convertFloat16ToDouble(args.inMultiplicand2);
745                 args.inOffset = arrayInOffset[i * 4 + j];
746                 args.inOffsetDouble = Float16Utils.convertFloat16ToDouble(args.inOffset);
747                 // Figure out what the outputs should have been.
748                 Target target = new Target(Target.FunctionType.NORMAL, Target.ReturnType.HALF, relaxed);
749                 CoreMathVerifier.computeFma(args, target);
750                 // Validate the outputs.
751                 boolean valid = true;
752                 if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
753                     valid = false;
754                 }
755                 if (!valid) {
756                     if (!errorFound) {
757                         errorFound = true;
758                         message.append("Input inMultiplicand1: ");
759                         appendVariableToMessage(message, args.inMultiplicand1);
760                         message.append("\n");
761                         message.append("Input inMultiplicand2: ");
762                         appendVariableToMessage(message, args.inMultiplicand2);
763                         message.append("\n");
764                         message.append("Input inOffset: ");
765                         appendVariableToMessage(message, args.inOffset);
766                         message.append("\n");
767                         message.append("Expected output out: ");
768                         appendVariableToMessage(message, args.out);
769                         message.append("\n");
770                         message.append("Actual   output out: ");
771                         appendVariableToMessage(message, arrayOut[i * 4 + j]);
772                         message.append("\n");
773                         message.append("Actual   output out (in double): ");
774                         appendVariableToMessage(message, Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]));
775                         if (!args.out.couldBe(Float16Utils.convertFloat16ToDouble(arrayOut[i * 4 + j]))) {
776                             message.append(" FAIL");
777                         }
778                         message.append("\n");
779                         message.append("Errors at");
780                     }
781                     message.append(" [");
782                     message.append(Integer.toString(i));
783                     message.append(", ");
784                     message.append(Integer.toString(j));
785                     message.append("]");
786                 }
787             }
788         }
789         assertFalse("Incorrect output for checkFmaHalf4Half4Half4Half4" +
790                 (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
791     }
792 
testFma()793     public void testFma() {
794         checkFmaFloatFloatFloatFloat();
795         checkFmaFloat2Float2Float2Float2();
796         checkFmaFloat3Float3Float3Float3();
797         checkFmaFloat4Float4Float4Float4();
798         checkFmaHalfHalfHalfHalf();
799         checkFmaHalf2Half2Half2Half2();
800         checkFmaHalf3Half3Half3Half3();
801         checkFmaHalf4Half4Half4Half4();
802     }
803 }
804