Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/numeric/numeric002.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/numeric002.
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 of the type
33
* float[][]. Elements of the matrix A are initiated with random numbers,
34
* so that optimizing compiler could not eliminate any essential portion
35
* of calculations.
36
* That product A*A is calculated twice: in a single thread, and in N
37
* separate threads, where NxN is the size of square matrix A. When executing
38
* in N threads, each thread calculate distinct row of the resulting matrix.
39
* The test checks if the resulting product A*A is the same when calculated
40
* in single thread and in N threads.
41
* By the way, the test checks JVM performance. The test is treated failed
42
* due to poor performance, if single-thread calculation is essentially
43
* slower than N-threads calculation (surely, the number of CPUs installed
44
* on the platform executing the test is taken into account for performance
45
* testing). Note, that HotSpot may fail to adjust itself for better
46
* performance in single-thread calculation.
47
* COMMENTS
48
* The bug was filed referencing to the same numeric algorithm,
49
* which is used by this test:
50
* 4242172 (P3/S5) 2.0: poor performance in matrix calculations
51
*
52
* @library /test/lib
53
* @run main/othervm nsk.stress.numeric.numeric002.numeric002 300 300
54
*/
55
56
package nsk.stress.numeric.numeric002;
57
58
import java.io.PrintStream;
59
import java.util.Random;
60
import jdk.test.lib.Utils;
61
62
/**
63
* This test calculates the product <b>A</b><sup>.</sup><b>A</b> for
64
* a square matrix <b>A</b> of the type <code>float[][]</code>.
65
* Elements of the matrix <b>A</b> are initiated with random numbers,
66
* so that optimizing compiler could not eliminate any essential portion
67
* of calculations.
68
* <p>
69
* <p>That product <b>A</b><sup>.</sup><b>A</b> is calculated twice: in
70
* a single thread, and in <i>N</i> separate threads, where <i>N</i>x<i>N</i>
71
* is the size of square matrix <b>A</b>. When executing in <i>N</i> threads,
72
* each thread calculate distinct row of the resulting matrix. The test checks
73
* if the resulting product <b>A</b><sup>.</sup><b>A</b> is the same when
74
* calculated in single thread and in <i>N</i> threads.
75
* <p>
76
* <p>By the way, the test checks JVM performance. The test is treated failed
77
* due to poor performance, if single-thread calculation is essentially
78
* slower than <i>N</i>-threads calculation (surely, the number of CPUs
79
* installed on the platform executing the test is taken into account for
80
* performance testing). Note, that HotSpot may fail to adjust itself for
81
* better performance in single-thread calculation.
82
* <p>
83
* <p>See the bug-report:
84
* <br>&nbsp;&nbsp;
85
* 4242172 (P3/S5) 2.0: poor performance in matrix calculations
86
*/
87
public class numeric002 {
88
private static final Random RNG = Utils.getRandomInstance();
89
/**
90
* When testing performance, single thread calculation is allowed to
91
* be 10% slower than multi-threads calculation (<code>TOLERANCE</code>
92
* is assigned to 10 now).
93
*/
94
public static final double TOLERANCE = 100; // 10;
95
96
/**
97
* Re-assign this value to <code>true</code> for better
98
* diagnostics.
99
*/
100
private static boolean verbose = false;
101
102
private static PrintStream out = null;
103
104
/**
105
* Print error-message to the <code>out<code>.
106
*/
107
private static void complain(Object x) {
108
out.println("# " + x);
109
}
110
111
private static void print(Object x) {
112
if (verbose)
113
out.print(x);
114
}
115
116
private static void println(Object x) {
117
print(x + "\n");
118
}
119
120
/**
121
* Re-invoke <code>run(args,out)</code> in order to simulate
122
* JCK-like test interface.
123
*/
124
public static void main(String args[]) {
125
int exitCode = run(args, System.out);
126
System.exit(exitCode + 95);
127
// JCK-like exit status
128
}
129
130
/**
131
* Parse command-line parameters stored in <code>args[]</code> and run
132
* the test.
133
* <p>
134
* <p>Command-line parameters are:
135
* <br>&nbsp;&nbsp;
136
* <code>java numeric002 [-verbose] [-performance] [-CPU:<i>number</i>]
137
* <i>matrixSize</i> [<i>threads</i>]</code>
138
* <p>
139
* <p>Here:
140
* <br>&nbsp;&nbsp;<code>-verbose</code> -
141
* keyword, which alows to print execution trace
142
* <br>&nbsp;&nbsp;<code>-performance</code> -
143
* keyword, which alows performance testing
144
* <br>&nbsp;&nbsp;<code><i>number</i></code> -
145
* number of CPU installed on the computer just executing the test
146
* <br>&nbsp;&nbsp;<code><i>matrixSize</i></code> -
147
* number of rows (and columns) in square matrix to be tested
148
* <br>&nbsp;&nbsp;<code><i>threads</i></code> -
149
* for multi-thread calculation
150
* (default: <code><i>matrixSize</i></code>)
151
*
152
* @param args strings array containing command-line parameters
153
* @param out the test log, usually <code>System.out</code>
154
*/
155
public static int run(String args[], PrintStream out) {
156
numeric002.out = out;
157
158
boolean testPerformance = false;
159
int numberOfCPU = 1;
160
161
int argsShift = 0;
162
for (; argsShift < args.length; argsShift++) {
163
String argument = args[argsShift];
164
165
if (!argument.startsWith("-"))
166
break;
167
168
if (argument.equals("-performance")) {
169
testPerformance = true;
170
continue;
171
}
172
173
if (argument.equals("-verbose")) {
174
verbose = true;
175
continue;
176
}
177
178
if (argument.startsWith("-CPU:")) {
179
String value =
180
argument.substring("-CPU:".length(), argument.length());
181
numberOfCPU = Integer.parseInt(value);
182
183
if (numberOfCPU < 1) {
184
complain("Illegal number of CPU: " + argument);
185
return 2; // failure
186
}
187
continue;
188
}
189
190
complain("Cannot recognize argument: args[" + argsShift + "]: " + argument);
191
return 2; // failure
192
}
193
194
if ((args.length < argsShift + 1) || (args.length > argsShift + 2)) {
195
complain("Illegal argument(s). Execute:");
196
complain(
197
" java numeric002 [-verbose] [-performance] [-CPU:number] " +
198
"matrixSize [threads]");
199
return 2; // failure
200
}
201
202
int size = Integer.parseInt(args[argsShift]);
203
if ((size < 100) || (size > 10000)) {
204
complain("Matrix size should be 100 to 1000 lines & columns.");
205
return 2; // failure
206
}
207
208
int threads = size;
209
if (args.length >= argsShift + 2)
210
threads = Integer.parseInt(args[argsShift + 1]);
211
if ((threads < 1) || (threads > size)) {
212
complain("Threads number should be 1 to matrix size.");
213
return 2; // failure
214
}
215
if ((size % threads) != 0) {
216
complain("Threads number should evenly divide matrix size.");
217
return 2; // failure
218
}
219
220
print("Preparing A[" + size + "," + size + "]:");
221
SquareMatrix A = new SquareMatrix(size);
222
SquareMatrix A1 = new SquareMatrix(size);
223
SquareMatrix Am = new SquareMatrix(size);
224
println(" done.");
225
226
double singleThread = elapsedTime(out, A, A1, size, 1);
227
double multiThreads = elapsedTime(out, A, Am, size, threads);
228
229
if (!A1.isConsistent) {
230
complain("Failed to execute 1-thread calculation.");
231
return 2; // test FAILED
232
}
233
if (!Am.isConsistent) {
234
complain("Failed to execute " + threads + "-threads calculation.");
235
if (testPerformance) {
236
complain("I.e.: VM failed to execute " + threads + " threads,");
237
complain("and this looks like a performance bug.");
238
return 2; // test FAILED
239
} else {
240
complain("This looks strange, but this is not a bug.");
241
complain("The test is thought passed.");
242
return 0; // test PASSED
243
}
244
}
245
246
print("Checking accuracy:");
247
for (int line = 0; line < size; line++)
248
for (int column = 0; column < size; column++)
249
if (A1.value[line][column] != Am.value[line][column]) {
250
println("");
251
complain("Test failed:");
252
complain("Different results by single- and multi-threads:");
253
complain(" line=" + line + ", column=" + column);
254
complain("A1.value[line][column]=" + A1.value[line][column]);
255
complain("Am.value[line][column]=" + Am.value[line][column]);
256
return 2; // FAILED
257
}
258
println(" done.");
259
260
if (testPerformance) {
261
print("Checking performance: ");
262
double elapsed1 = singleThread;
263
double elapsedM = multiThreads * numberOfCPU;
264
if (elapsed1 > elapsedM * (1 + TOLERANCE / 100)) {
265
println("");
266
complain("Test failed:");
267
complain("Single-thread calculation is essentially slower:");
268
complain("Calculation time elapsed (seconds):");
269
complain(" single thread: " + singleThread);
270
complain(" multi-threads: " + multiThreads);
271
complain(" number of CPU: " + numberOfCPU);
272
complain(" tolerance: " + TOLERANCE + "%");
273
return 2; // FAILED
274
}
275
println("done.");
276
}
277
278
println("Test passed.");
279
return 0; // PASSED
280
}
281
282
private static double elapsedTime(PrintStream out,
283
SquareMatrix A, SquareMatrix AA, int size, int threads) {
284
285
print("Computing A*A with " + threads + " thread(s):");
286
long mark1 = System.currentTimeMillis();
287
AA.setSquareOf(A, threads);
288
long mark2 = System.currentTimeMillis();
289
println(" done.");
290
291
double sec = (mark2 - mark1) / 1000.0;
292
double perf = size * size * (size + size) / sec;
293
println("Elapsed time: " + sec + " seconds");
294
println("Performance: " + perf / 1e6 + " MFLOPS");
295
296
return sec;
297
}
298
299
/**
300
* This class computes <code>A*A</code> for square matrix <code>A</code>.
301
*/
302
private static class SquareMatrix {
303
volatile float value[][];
304
boolean isConsistent = false;
305
306
/**
307
* New square matrix with random elements.
308
*/
309
public SquareMatrix(int size) {
310
value = new float[size][size];
311
for (int line = 0; line < size; line++)
312
for (int column = 0; column < size; column++)
313
value[line][column] = (float) (RNG.nextDouble() * size);
314
isConsistent = true;
315
}
316
317
/**
318
* Update <code>value[][]</code> of <code>this</code> matrix.
319
*
320
* @param threads Split computation into the given number of threads.
321
*/
322
public void setSquareOf(SquareMatrix A, int threads) {
323
if (this.value.length != A.value.length)
324
throw new IllegalArgumentException(
325
"this.value.length != A.value.length");
326
327
int size = value.length;
328
if ((size % threads) != 0)
329
throw new IllegalArgumentException("size%threads != 0");
330
int bunch = size / threads;
331
332
Thread task[] = new Thread[threads];
333
for (int t = 0; t < threads; t++) {
334
int line0 = bunch * t;
335
MatrixComputer computer =
336
new MatrixComputer(value, A.value, line0, bunch);
337
task[t] = computer;
338
}
339
340
for (int t = 0; t < threads; t++)
341
task[t].start();
342
343
isConsistent = true;
344
for (int t = 0; t < threads; t++) {
345
if (task[t].isAlive())
346
try {
347
task[t].join();
348
} catch (InterruptedException exception) {
349
throw new RuntimeException(exception.toString());
350
}
351
if (!((MatrixComputer) (task[t])).threadExecuted) {
352
complain("Thread #" + t + " was not actually executed.");
353
isConsistent = false;
354
}
355
}
356
}
357
358
/**
359
* Thread to compute a bunch of lines of matrix square.
360
*/
361
private static class MatrixComputer extends Thread {
362
private float result[][];
363
private float source[][];
364
private int line0;
365
private int bunch;
366
367
/**
368
* Register a task for matrix multiplication.
369
*/
370
public MatrixComputer(
371
float result[][], float source[][], int line0, int bunch) {
372
373
this.result = result; // reference to resulting matrix value
374
this.source = source; // reference to matrix to be squared
375
this.line0 = line0; // compute lines from line0 to ...
376
this.bunch = bunch; // number of resulting lines to compute
377
}
378
379
/**
380
* Do execute the task just registered for <code>this</code> thread.
381
*/
382
public void run() {
383
int line1 = line0 + bunch;
384
int size = result.length;
385
for (int line = line0; line < line1; line++)
386
for (int column = 0; column < size; column++) {
387
float sum = 0;
388
for (int i = 0; i < size; i++)
389
sum += source[line][i] * source[i][column];
390
result[line][column] = sum;
391
}
392
threadExecuted = true;
393
}
394
395
/**
396
* Method <code>run()</code> sets this flag on is actually
397
* finishes to execute.
398
*/
399
boolean threadExecuted = false;
400
}
401
402
}
403
404
}
405
406