Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric009.java
41159 views
1
/*
2
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/*
25
* @test
26
* @key stress randomness
27
*
28
* @summary converted from VM testbase nsk/stress/numeric/numeric009.
29
* VM testbase keywords: [stress, slow, nonconcurrent, quick]
30
* VM testbase readme:
31
* DESCRIPTION
32
* This test calculates the product A*A for a square matrix A, and checks
33
* if such product is calculated correctly. Elements of the matrix A are
34
* initiated with integer numbers, so that A*A must be the same if calculated
35
* with double, float, long, or int precision. The test just checks, if
36
* double, float, long, and int variants of the product calculation result
37
* in the same A*A matrix.
38
* Calculation of the product A*A is iterated two times, because HotSpot
39
* releases 1.0 and 1.3 seem to do not adjust JVM for better performance
40
* in 1st iteration, while 2nd iteration usually runs much faster. I guess,
41
* that the 1st iteration is probably executed by HotSpot interpreter, and
42
* HotSpot compiler is probably involved to execute the 2nd iteration. So,
43
* the test apparently checks accuracy of A*A calculation in both compilation
44
* and interpretation modes.
45
* By the way, the test checks JVM performance. The test is treated failed
46
* due to poor performance, if 1st iteration is essentially slower than the
47
* 2nd iteration. The calculations algorithm is encoded as rather compact
48
* 3-levels cycle like:
49
* for (int line=0; line<N; line++)
50
* for (int column=0; column<N; column++) {
51
* float sum = 0;
52
* for (int k=0; k<N; k++)
53
* sum += A[line][k] * A[k][column];
54
* AA[line][column] = sum;
55
* }
56
* In this test, N=200, so that A is 200x200 matrix; and multiplication
57
* A[line][k]*A[k][column] is executed 200**3=8 millions times in each
58
* iteration of execution of this cycle. I believe, that this is HotSpot
59
* bug to do not adjust JVM for best performance during such a huge series
60
* of executions of the rather compact portion of program code.
61
* COMMENTS
62
* See the bug-report:
63
* #4242172 (P3/S5) 2.0: poor performance in matrix calculations
64
*
65
* @library /test/lib
66
* @run main/othervm nsk.stress.numeric.numeric009.numeric009 200 2
67
*/
68
69
package nsk.stress.numeric.numeric009;
70
71
import java.io.PrintStream;
72
import java.util.Random;
73
import jdk.test.lib.Utils;
74
75
/**
76
* This test calculates the product <code>A<sup>.</sup>A</code> for a square
77
* matrix <code>A</code>, and checks if such product is calculated correctly.
78
* Elements of the matrix <code>A</code> are initiated with integer numbers,
79
* so that <code>A<sup>.</sup>A</code> must be the same if calculated with
80
* <code>double</code>, <code>float</code>, <code>long</code>, or
81
* <code>int</code> precision. The test just checks, if <code>double</code>,
82
* <code>float</code>, <code>long</code>, and <code>int</code> variants of
83
* the product calculation result in the same <code>A<sup>.</sup>A</code>
84
* matrix.
85
* <p>
86
* <p>Calculation of the product <code>A<sup>.</sup>A</code> is iterated two
87
* times, because HotSpot releases 1.0 and 1.3 seem to do not adjust JVM for
88
* better performance in 1<sup>st</sup> iteration, while 2<sup>nd</sup>
89
* iteration usually runs much faster. I guess, that the 1<sup>st</sup> iteration
90
* is probably executed by HotSpot interpreter, and HotSpot compiler is probably
91
* involved to execute the 2<sup>nd</sup> iteration. So, the test apparently
92
* checks accuracy of <code>A<sup>.</sup>A</code> calculation in both compilation
93
* and interpretation modes.
94
* <p>
95
* <p>By the way, the test checks JVM performance. The test is treated failed
96
* due to poor performance, if 1<sup>st</sup> iteration is essentially slower
97
* than the 2<sup>nd</sup> iteration. The calculations algorithm is encoded
98
* as compact ``canonical'' 3-levels cycle like:
99
* <pre>
100
* for (int line=0; line&lt;N; line++)
101
* for (int column=0; column&lt;N; column++) {
102
* float sum = 0;
103
* for (int k=0; k&lt;N; k++)
104
* sum += A[line][k] * A[k][column];
105
* AA[line][column] = sum;
106
* }
107
* </pre>
108
* <p>
109
* In this test, <code>N</code>=200, so that <code>A</code> is 200x200 matrix;
110
* and multiplication <code>A[line][k]*A[k][column]</code> is executed
111
* 200<sup>3</sup>=8 millions times in each iteration of execution of this
112
* cycle. I believe, that this is HotSpot bug to do not adjust JVM for best
113
* performance during such a huge series of executions of the rather compact
114
* portion of program code.
115
* <p>
116
* <p>See the bug-report:
117
* <br>&nbsp;&nbsp;
118
* #4242172 (P3/S5) 2.0: poor performance in matrix calculations
119
*/
120
public class numeric009 {
121
private static final Random RNG = Utils.getRandomInstance();
122
/**
123
* When testing performance, 1st iteration is allowed to be 10% slower
124
* than 2nd iteration (<code>tolerance</code> is assigned to 10 now).
125
*/
126
public static double tolerance = 100; // 10;
127
128
/**
129
* Re-assign this value to <code>true</code> for better
130
* diagnostics.
131
*
132
* @see #print(Object)
133
* @see #println(Object)
134
*/
135
private static boolean verbose = false;
136
137
/**
138
* Stream to print execution trace and/or error messages.
139
* This stream usually equals to <code>System.out</code>
140
*/
141
private static PrintStream out = null;
142
143
/**
144
* Print error-message.
145
*
146
* @see #out
147
*/
148
private static void complain(Object x) {
149
out.println("# " + x);
150
}
151
152
/**
153
* Print to execution trace, if mode is <code>verbose</code>.
154
*
155
* @see #verbose
156
* @see #out
157
*/
158
private static void print(Object x) {
159
if (verbose)
160
out.print(x);
161
}
162
163
/**
164
* Print line to execution trace, if mode is <code>verbose</code>.
165
*
166
* @see #verbose
167
* @see #out
168
*/
169
private static void println(Object x) {
170
print(x + "\n");
171
}
172
173
/**
174
* Re-invoke <code>run(args,out)</code> in order to simulate
175
* JCK-like test interface.
176
*/
177
public static void main(String args[]) {
178
int exitCode = run(args, System.out);
179
System.exit(exitCode + 95);
180
// JCK-like exit status
181
}
182
183
/**
184
* Parse command-line parameters stored in <code>args[]</code> and run
185
* the test.
186
* <p>
187
* <p>Command-line parameters are:
188
* <br>&nbsp;&nbsp;
189
* <code>java numeric009 [-verbose] [-performance]
190
* [-tolerance:<i>percents</i>]
191
* <i>matrixSize</i> <i>iterations</i></code>
192
* <p>
193
* <p>Here:
194
* <br>&nbsp;&nbsp;<code>-verbose</code> -
195
* keyword alowing to print execution trace
196
* <br>&nbsp;&nbsp;<code>-performance</code> -
197
* keyword turning on performance testing
198
* <br>&nbsp;&nbsp;<code>-tolerance</code> -
199
* setup tolerance of performance checking
200
* <br>&nbsp;&nbsp;<code><i>percents</i></code> -
201
* 1<sup>st</sup> iteration is allowed to be
202
* <code><i>percents</i></code>% slower
203
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
204
* number of rows (and columns) in square matrix <code>A</code>
205
* <br>&nbsp;&nbsp;<code><i>iterations</i></code> -
206
* how many times to execute the test for stronger checking
207
*
208
* @param args strings array containing command-line parameters
209
* @param out the test log, usually <code>System.out</code>
210
*/
211
public static int run(String args[], PrintStream out) {
212
numeric009.out = out;
213
214
boolean testPerformance = false;
215
int numberOfCPU = 1;
216
217
// Parse parameters starting with "-" (like: "-verbose"):
218
219
int argsShift = 0;
220
for (; argsShift < args.length; argsShift++) {
221
String argument = args[argsShift];
222
223
if (!argument.startsWith("-"))
224
break;
225
226
if (argument.equals("-performance")) {
227
testPerformance = true;
228
continue;
229
}
230
231
if (argument.equals("-verbose")) {
232
verbose = true;
233
continue;
234
}
235
236
if (argument.startsWith("-tolerance:")) {
237
String percents =
238
argument.substring("-tolerance:".length(), argument.length());
239
tolerance = Integer.parseInt(percents);
240
if ((tolerance < 0) || (tolerance > 100)) {
241
complain("Tolerance should be 0 to 100%: " + argument);
242
return 2; // failure
243
}
244
continue;
245
}
246
247
complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
248
return 2; // failure
249
}
250
251
if (args.length != argsShift + 2) {
252
complain("Illegal arguments. Execute:");
253
complain(
254
" java numeric009 [-verbose] [-performance] " +
255
"[-tolerance:percents] matrixSize iterations");
256
return 2; // failure
257
}
258
259
int size = Integer.parseInt(args[argsShift]);
260
if ((size < 100) || (size > 10000)) {
261
complain("Matrix size should be 100 to 1000 lines & columns.");
262
return 2; // failure
263
}
264
265
int iterations = Integer.parseInt(args[argsShift + 1]);
266
if ((iterations < 1) || (iterations > 100)) {
267
complain("Iterations number should be 1 to 100.");
268
return 2; // failure
269
}
270
271
print("Preparing A[" + size + "," + size + "]:");
272
int[][] intA = newIntegerMatrix(size);
273
int[][] intAA = new int[size][size];
274
long[][] longA = newLongMatrix(intA);
275
long[][] longAA = new long[size][size];
276
double[][] doubleA = newDoubleMatrix(intA);
277
double[][] doubleAA = new double[size][size];
278
float[][] floatA = newFloatMatrix(intA);
279
float[][] floatAA = new float[size][size];
280
println(" done.");
281
282
println("Should try " + iterations + " iteration(s):");
283
println("==========================" +
284
((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
285
println("");
286
287
double overallTime = 0;
288
double firstTime = 0;
289
double lastTime = 0;
290
291
for (int i = 1; i <= iterations; i++) {
292
double seconds = elapsedTime(i,
293
intA, intAA, longA, longAA, floatA, floatAA, doubleA, doubleAA);
294
295
if (i == 1)
296
firstTime = seconds;
297
else
298
lastTime = seconds;
299
overallTime += seconds;
300
301
print("Checking accuracy:");
302
for (int line = 0; line < size; line++)
303
for (int column = 0; column < size; column++) {
304
if (intAA[line][column] != longAA[line][column]) {
305
println("");
306
complain("Test failed:");
307
complain("Integer and Long results differ at:");
308
complain(" line=" + line + ", column=" + column);
309
return 2; // FAILED
310
}
311
if (intAA[line][column] != floatAA[line][column]) {
312
println("");
313
complain("Test failed:");
314
complain("Integer and Float results differ at:");
315
complain(" line=" + line + ", column=" + column);
316
return 2; // FAILED
317
}
318
if (intAA[line][column] != doubleAA[line][column]) {
319
println("");
320
complain("Test failed:");
321
complain("Integer and Double results differ at:");
322
complain(" line=" + line + ", column=" + column);
323
return 2; // FAILED
324
}
325
}
326
println(" done.");
327
}
328
329
double averageTime = overallTime / iterations / 4;
330
double averagePerformance = size * size * (size + size) / averageTime / 1e6;
331
332
println("");
333
println("=======================" +
334
((iterations > 99) ? "==" : (iterations > 9) ? "=" : ""));
335
println("Overall iteration(s): " + iterations);
336
println("Overall elapsed time: " + overallTime + " seconds.");
337
println("Average elapsed time: " + averageTime + " seconds.");
338
println("Average performance: " + averagePerformance + " MFLOPS");
339
340
if (testPerformance) {
341
print("Checking performance: ");
342
if (firstTime > lastTime * (1 + tolerance / 100)) {
343
println("");
344
complain("Test failed:");
345
complain("1st iterartion is essentially slower:");
346
complain("Calculation time elapsed (seconds):");
347
complain(" 1-st iteration: " + firstTime);
348
complain(" last iteration: " + lastTime);
349
complain(" tolerance: " + tolerance + "%");
350
return 2; // FAILED
351
}
352
println("done.");
353
}
354
355
println("Test passed.");
356
return 0; // PASSED
357
}
358
359
/**
360
* Return time (in seconds) elapsed for calculation of matrix
361
* product <code>A*A</code> with <code>int</code>, <code>long</code>,
362
* <code>float</code>, and <code>double</code> representations.
363
*/
364
private static double elapsedTime(int i,
365
int[][] intA, int[][] intAA,
366
long[][] longA, long[][] longAA,
367
float[][] floatA, float[][] floatAA,
368
double[][] doubleA, double[][] doubleAA) {
369
370
int size = intA.length;
371
372
if (i > 1)
373
println("");
374
println("Iteration #" + i + ":");
375
376
print("Computing int, long, float, and double A*A:");
377
long mark1 = System.currentTimeMillis();
378
setSquare(intA, intAA);
379
setSquare(longA, longAA);
380
setSquare(floatA, floatAA);
381
setSquare(doubleA, doubleAA);
382
long mark2 = System.currentTimeMillis();
383
println(" done.");
384
385
double sec = (mark2 - mark1) / 1000.0;
386
double perf = size * size * (size + size) / (sec / 4);
387
println("Elapsed time: " + sec + " seconds");
388
println("Performance: " + perf / 1e6 + " MOPS");
389
390
return sec;
391
}
392
393
/**
394
* Compute <code>A*A</code> for the given square matrix <code>A</code>.
395
*/
396
private static void setSquare(int[][] A, int[][] AA) {
397
if (A.length != A[0].length)
398
throw new IllegalArgumentException(
399
"the argument matrix A should be square matrix");
400
if (AA.length != AA[0].length)
401
throw new IllegalArgumentException(
402
"the resulting matrix AA should be square matrix");
403
if (A.length != AA.length)
404
throw new IllegalArgumentException(
405
"the matrices A and AA should have equal size");
406
407
int size = A.length;
408
409
for (int line = 0; line < size; line++)
410
for (int column = 0; column < size; column++) {
411
int sum = 0;
412
for (int k = 0; k < size; k++)
413
sum += A[line][k] * A[k][line];
414
AA[line][column] = sum;
415
}
416
}
417
418
/**
419
* Compute <code>A*A</code> for the given square matrix <code>A</code>.
420
*/
421
private static void setSquare(long[][] A, long[][] AA) {
422
if (A.length != A[0].length)
423
throw new IllegalArgumentException(
424
"the argument matrix A should be square matrix");
425
if (AA.length != AA[0].length)
426
throw new IllegalArgumentException(
427
"the resulting matrix AA should be square matrix");
428
if (A.length != AA.length)
429
throw new IllegalArgumentException(
430
"the matrices A and AA should have equal size");
431
432
int size = A.length;
433
434
for (int line = 0; line < size; line++)
435
for (int column = 0; column < size; column++) {
436
long sum = 0;
437
for (int k = 0; k < size; k++)
438
sum += A[line][k] * A[k][line];
439
AA[line][column] = sum;
440
}
441
}
442
443
/**
444
* Compute <code>A*A</code> for the given square matrix <code>A</code>.
445
*/
446
private static void setSquare(float[][] A, float[][] AA) {
447
if (A.length != A[0].length)
448
throw new IllegalArgumentException(
449
"the argument matrix A should be square matrix");
450
if (AA.length != AA[0].length)
451
throw new IllegalArgumentException(
452
"the resulting matrix AA should be square matrix");
453
if (A.length != AA.length)
454
throw new IllegalArgumentException(
455
"the matrices A and AA should have equal size");
456
457
int size = A.length;
458
459
for (int line = 0; line < size; line++)
460
for (int column = 0; column < size; column++) {
461
float sum = 0;
462
for (int k = 0; k < size; k++)
463
sum += A[line][k] * A[k][line];
464
AA[line][column] = sum;
465
}
466
}
467
468
/**
469
* Compute <code>A*A</code> for the given square matrix <code>A</code>.
470
*/
471
private static void setSquare(double[][] A, double[][] AA) {
472
if (A.length != A[0].length)
473
throw new IllegalArgumentException(
474
"the argument matrix A should be square matrix");
475
if (AA.length != AA[0].length)
476
throw new IllegalArgumentException(
477
"the resulting matrix AA should be square matrix");
478
if (A.length != AA.length)
479
throw new IllegalArgumentException(
480
"the matrices A and AA should have equal size");
481
482
int size = A.length;
483
484
for (int line = 0; line < size; line++)
485
for (int column = 0; column < size; column++) {
486
double sum = 0;
487
for (int k = 0; k < size; k++)
488
sum += A[line][k] * A[k][line];
489
AA[line][column] = sum;
490
}
491
}
492
493
/**
494
* Generate new square matrix of the given <code>size</code>
495
* and with elements initiated with random numbers.
496
*/
497
private static int[][] newIntegerMatrix(int size) {
498
if ((size < 1) || (size > 1000))
499
throw new IllegalArgumentException(
500
"matrix size should be 1 to 1000");
501
502
int[][] A = new int[size][size];
503
504
for (int line = 0; line < size; line++)
505
for (int column = 0; column < size; column++)
506
A[line][column] =
507
Math.round((float) ((1 - 2 * RNG.nextDouble()) * size));
508
509
return A;
510
}
511
512
/**
513
* Generate new square matrix with <code>long</code> elements,
514
* and initiate them with the same values as in the given matrix
515
* <code>intA</code>.
516
*/
517
private static long[][] newLongMatrix(int[][] intA) {
518
if (intA.length != intA[0].length)
519
throw new IllegalArgumentException(
520
"need square argument matrix");
521
522
int size = intA.length;
523
long[][] longA = new long[size][size];
524
525
for (int line = 0; line < size; line++)
526
for (int column = 0; column < size; column++)
527
longA[line][column] = intA[line][column];
528
529
return longA;
530
}
531
532
/**
533
* Generate new square matrix with <code>double</code> elements,
534
* and initiate them with the same values as in the given matrix
535
* <code>intA</code>.
536
*/
537
private static double[][] newDoubleMatrix(int[][] intA) {
538
if (intA.length != intA[0].length)
539
throw new IllegalArgumentException(
540
"need square argument matrix");
541
542
int size = intA.length;
543
double[][] doubleA = new double[size][size];
544
545
for (int line = 0; line < size; line++)
546
for (int column = 0; column < size; column++)
547
doubleA[line][column] = intA[line][column];
548
549
return doubleA;
550
}
551
552
/**
553
* Generate new square matrix with <code>float</code> elements,
554
* and initiate them with the same values as in the given matrix
555
* <code>intA</code>.
556
*/
557
private static float[][] newFloatMatrix(int[][] intA) {
558
if (intA.length != intA[0].length)
559
throw new IllegalArgumentException(
560
"need square argument matrix");
561
562
int size = intA.length;
563
float[][] floatA = new float[size][size];
564
565
for (int line = 0; line < size; line++)
566
for (int column = 0; column < size; column++)
567
floatA[line][column] = intA[line][column];
568
569
return floatA;
570
}
571
572
}
573
574