1 /* vim: set ft=java:
2 * Copyright (c) 2024, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 import static java.lang.IO.print;
27 import static java.lang.IO.println;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30
31 class Config {
32 boolean headless = false;
33 boolean verbose = false;
34 boolean startOnFirstThread = false;
35 boolean justShowCommandline = false;
36 boolean runSuite = false;
37 String backendName = null;
38 Script.JarFile backendJar = null;
39 String testName = null;
40 String examplePackageName = null;
41 String testMainClassName = null;
42 Script.JarFile exampleJar = null;
43 List<Script.ClassPathEntryProvider> classpath = new ArrayList<>();
44 List<String> vmargs = new ArrayList<>();
45 List<String> appargs = new ArrayList<>();
46
47 Config(Script.BuildDir buildDir, String[] args) {
48
49 var testJARFile = buildDir.jarFile("hat-tests-1.0.jar");
50 if (testJARFile.exists()) {
51 testMainClassName = "hat.test.engine.HATTestEngine";
52 exampleJar = testJARFile;
53 if (exampleJar.exists()) {
54 classpath.add(exampleJar);
55 } else {
56 System.err.println("Cannot find example jar at " + testMainClassName);
57 }
58 }
59
60 classpath.add(buildDir.jarFile("hat-tests-1.0.jar"));
61 classpath.add(buildDir.jarFile("hat-core-1.0.jar"));
62 classpath.add(buildDir.jarFile("hat-example-shared-1.0.jar"));
63
64 for (int arg = 0; arg < args.length; arg++) {
65
66 if (args[arg].equals("suite")) {
67 runSuite = true;
68 } else if (args[arg].startsWith("ffi-")) {
69 backendName = args[arg];
70 backendJar = buildDir.jarFile("hat-backend-" + backendName + "-1.0.jar");
71 classpath.add(buildDir.jarFile("hat-backend-ffi-shared-1.0.jar"));
72 classpath.add(backendJar);
73 } else if (args[arg].startsWith("java-")) {
74 backendName = args[arg];
75 backendJar = buildDir.jarFile("hat-backend-" + backendName + "-1.0.jar");
76 classpath.add(backendJar);
77 } else {
78 switch (args[arg]) {
79 case "headless" -> headless = true;
80 case "verbose" -> verbose = true;
81 case "justShowCommandLine" -> justShowCommandline = true;
82 case "startOnFirstThread" -> startOnFirstThread = true;
83 default -> {
84 this.appargs.add(args[arg]);
85 }
86 }
87 }
88 }
89 }
90 }
91
92 class Stats {
93 int passed = 0;
94 int failed = 0;
95 int unsupported = 0;
96 public void incrementPassed(int val) {
97 this.passed += val;
98 }
99 public void incrementFailed(int fail) {
100 this.failed += fail;
101 }
102 public void incrementUnsupported(int unsupporeted) {
103 this.unsupported += unsupporeted;
104 }
105
106 public int getPassed() {
107 return passed;
108 }
109 public int getFailed() {
110 return failed;
111 }
112 public int getUnsupported() {
113 return unsupported;
114 }
115
116 @Override
117 public String toString() {
118 return String.format("Global passed: %d, failed: %d, unsupported: %d, pass-rate: %.2f%%",
119 passed, failed, unsupported, ((float)(passed * 100 / (passed + failed + unsupported))));
120 }
121 }
122
123 void main(String[] argv) {
124 var usage = """
125 usage:
126 java @hat/test [backend] class
127 backend : opencl|cuda
128
129 examples:
130 java @hat/test suite ffi-opencl
131 java @hat/test ffi-opencl class#method
132 java @hat/test suite ffi-cuda
133 java @hat/test ffi-cuda class#method
134 """;
135
136 var hatDir = Script.DirEntry.current();
137 var buildDir = hatDir.existingBuildDir("build");
138
139 Config config = new Config(buildDir, argv);
140
141 if (config.classpath.isEmpty()) {
142 println("Classpath is empty!");
143 } else if (config.backendJar == null || !config.backendJar.exists()) {
144 println("No backend !");
145 } else if (!config.exampleJar.exists()) {
146 println("No example !");
147 } else {
148 var extraction_opencl_jar = buildDir.jarFile("hat-extraction-opencl-1.0.jar");
149 var extraction_opengl_jar = buildDir.jarFile("hat-extraction-opengl-1.0.jar");
150 var wrap_shared_jar = buildDir.jarFile("hat-wrap-shared-1.0.jar");
151 var wrap_opencl_jar = buildDir.jarFile("hat-wrap-opencl-1.0.jar");
152 var wrap_opengl_jar = buildDir.jarFile("hat-wrap-opengl-1.0.jar");
153 switch (config.backendName) {
154 default -> {
155 }
156 }
157 }
158
159 // Remove the previous report file:
160 Path file = Paths.get("test_report.txt");
161 try {
162 Files.deleteIfExists(file);
163 } catch (IOException e) {
164 e.printStackTrace();
165 }
166
167 if (config.runSuite) {
168
169 String[] suite = new String[] {
170 "hat.test.TestMatMul",
171 "hat.test.TestArrays",
172 "hat.test.TestMandel",
173 "hat.test.TestLocal",
174 "hat.test.TestReductions",
175 "hat.test.TestPrivate",
176 "hat.test.TestParenthesis",
177 "hat.test.TestConstants",
178 "hat.test.TestBlackscholes",
179 "hat.test.TestNbody",
180 "hat.test.TestArrayView",
181 "hat.test.TestVectorTypes",
182 "hat.test.TestF16Type",
183 "hat.test.TestFloat2"
184 };
185
186 // Test the whole suite
187 for (String testClass : suite) {
188 Script.java(java -> java
189 .enable_preview()
190 .verbose(true)
191 .enable_native_access("ALL-UNNAMED")
192 .library_path(buildDir)
193 .when(config.headless, Script.JavaBuilder::headless)
194 .when(config.startOnFirstThread, Script.JavaBuilder::start_on_first_thread)
195 .class_path(config.classpath)
196 .vmargs(config.vmargs)
197 .main_class(config.testMainClassName)
198 .args(testClass)
199 .justShowCommandline(config.justShowCommandline));
200 }
201
202 // Final report
203 String regex = "passed: (\\d+), failed: (\\d+), unsupported: (\\d+)";
204 Pattern pattern = Pattern.compile(regex);
205 Stats stats = new Stats();
206
207 System.out.println("\n\n************************************************");
208 System.out.println(" HAT Test Report ");
209 System.out.println("************************************************");
210 try {
211 List<String> lines = Files.readAllLines(file);
212 for (String line : lines) {
213 System.out.println(line);
214
215 Matcher matcher = pattern.matcher(line);
216 if (matcher.find()) {
217 int passed = Integer.parseInt(matcher.group(1));
218 int fail = Integer.parseInt(matcher.group(2));
219 int unsupported = Integer.parseInt(matcher.group(3));
220 stats.incrementPassed(passed);
221 stats.incrementFailed(fail);
222 stats.incrementUnsupported(unsupported);
223 }
224 }
225 } catch (IOException e) {
226 e.printStackTrace();
227 }
228 System.out.println(stats);
229
230 } else {
231 // A single command for a specific class/method
232 Script.java(java -> java
233 .enable_preview()
234 .verbose(true)
235 .enable_native_access("ALL-UNNAMED")
236 .library_path(buildDir)
237 .when(config.headless, Script.JavaBuilder::headless)
238 .when(config.startOnFirstThread, Script.JavaBuilder::start_on_first_thread)
239 .class_path(config.classpath)
240 .vmargs(config.vmargs)
241 .main_class(config.testMainClassName)
242 .args(config.appargs)
243 .justShowCommandline(config.justShowCommandline));
244 }
245
246 }