1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
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 #include "parseParameters.h"
17
18 #include "errorHelpers.h"
19 #include "testHarness.h"
20 #include "ThreadPool.h"
21
22 #include <iostream>
23 #include <sstream>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <string.h>
27
28 using namespace std;
29
30 #define DEFAULT_COMPILATION_PROGRAM "cl_offline_compiler"
31 #define DEFAULT_SPIRV_VALIDATOR "spirv-val"
32
33 CompilationMode gCompilationMode = kOnline;
34 CompilationCacheMode gCompilationCacheMode = kCacheModeCompileIfAbsent;
35 std::string gCompilationCachePath = ".";
36 std::string gCompilationProgram = DEFAULT_COMPILATION_PROGRAM;
37 bool gDisableSPIRVValidation = false;
38 std::string gSPIRVValidator = DEFAULT_SPIRV_VALIDATOR;
39
helpInfo()40 void helpInfo()
41 {
42 log_info(
43 R"(Common options:
44 -h, --help
45 This help
46 --compilation-mode <mode>
47 Specify a compilation mode. Mode can be:
48 online Use online compilation (default)
49 binary Use binary offline compilation
50 spir-v Use SPIR-V offline compilation
51
52 For offline compilation (binary and spir-v modes) only:
53 --compilation-cache-mode <cache-mode>
54 Specify a compilation caching mode:
55 compile-if-absent
56 Read from cache if already populated, or else perform
57 offline compilation (default)
58 force-read
59 Force reading from the cache
60 overwrite
61 Disable reading from the cache
62 dump-cl-files
63 Dumps the .cl and build .options files used by the test suite
64 --compilation-cache-path <path>
65 Path for offline compiler output and CL source
66 --compilation-program <prog>
67 Program to use for offline compilation, defaults to:
68 )" DEFAULT_COMPILATION_PROGRAM R"(
69
70 For spir-v mode only:
71 --disable-spirv-validation
72 Disable validation of SPIR-V using the SPIR-V validator
73 --spirv-validator
74 Path for SPIR-V validator, defaults to )" DEFAULT_SPIRV_VALIDATOR "\n"
75 "\n");
76 }
77
parseCustomParam(int argc,const char * argv[],const char * ignore)78 int parseCustomParam(int argc, const char *argv[], const char *ignore)
79 {
80 int delArg = 0;
81
82 for (int i = 1; i < argc; i++)
83 {
84 if (ignore != 0)
85 {
86 // skip parameters that require special/different treatment in
87 // application (generic interpretation and parameter removal will
88 // not be performed)
89 const char *ptr = strstr(ignore, argv[i]);
90 if (ptr != 0 && (ptr == ignore || ptr[-1] == ' ')
91 && // first on list or ' ' before
92 (ptr[strlen(argv[i])] == 0
93 || ptr[strlen(argv[i])] == ' ')) // last on list or ' ' after
94 continue;
95 }
96
97 delArg = 0;
98
99 if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
100 {
101 // Note: we don't increment delArg to delete this argument,
102 // to allow the caller's argument parsing routine to see the
103 // option and print its own help.
104 helpInfo();
105 }
106 else if (!strcmp(argv[i], "--compilation-mode"))
107 {
108 delArg++;
109 if ((i + 1) < argc)
110 {
111 delArg++;
112 const char *mode = argv[i + 1];
113
114 if (!strcmp(mode, "online"))
115 {
116 gCompilationMode = kOnline;
117 }
118 else if (!strcmp(mode, "binary"))
119 {
120 gCompilationMode = kBinary;
121 }
122 else if (!strcmp(mode, "spir-v"))
123 {
124 gCompilationMode = kSpir_v;
125 }
126 else
127 {
128 log_error("Compilation mode not recognized: %s\n", mode);
129 return -1;
130 }
131 log_info("Compilation mode specified: %s\n", mode);
132 }
133 else
134 {
135 log_error("Compilation mode parameters are incorrect. Usage:\n"
136 " --compilation-mode <online|binary|spir-v>\n");
137 return -1;
138 }
139 }
140 else if (!strcmp(argv[i], "--compilation-cache-mode"))
141 {
142 delArg++;
143 if ((i + 1) < argc)
144 {
145 delArg++;
146 const char *mode = argv[i + 1];
147
148 if (!strcmp(mode, "compile-if-absent"))
149 {
150 gCompilationCacheMode = kCacheModeCompileIfAbsent;
151 }
152 else if (!strcmp(mode, "force-read"))
153 {
154 gCompilationCacheMode = kCacheModeForceRead;
155 }
156 else if (!strcmp(mode, "overwrite"))
157 {
158 gCompilationCacheMode = kCacheModeOverwrite;
159 }
160 else if (!strcmp(mode, "dump-cl-files"))
161 {
162 gCompilationCacheMode = kCacheModeDumpCl;
163 }
164 else
165 {
166 log_error("Compilation cache mode not recognized: %s\n",
167 mode);
168 return -1;
169 }
170 log_info("Compilation cache mode specified: %s\n", mode);
171 }
172 else
173 {
174 log_error(
175 "Compilation cache mode parameters are incorrect. Usage:\n"
176 " --compilation-cache-mode "
177 "<compile-if-absent|force-read|overwrite>\n");
178 return -1;
179 }
180 }
181 else if (!strcmp(argv[i], "--compilation-cache-path"))
182 {
183 delArg++;
184 if ((i + 1) < argc)
185 {
186 delArg++;
187 gCompilationCachePath = argv[i + 1];
188 }
189 else
190 {
191 log_error("Path argument for --compilation-cache-path was not "
192 "specified.\n");
193 return -1;
194 }
195 }
196 else if (!strcmp(argv[i], "--compilation-program"))
197 {
198 delArg++;
199 if ((i + 1) < argc)
200 {
201 delArg++;
202 gCompilationProgram = argv[i + 1];
203 }
204 else
205 {
206 log_error("Program argument for --compilation-program was not "
207 "specified.\n");
208 return -1;
209 }
210 }
211 else if (!strcmp(argv[i], "--disable-spirv-validation"))
212 {
213 delArg++;
214 gDisableSPIRVValidation = true;
215 }
216 else if (!strcmp(argv[i], "--spirv-validator"))
217 {
218 delArg++;
219 if ((i + 1) < argc)
220 {
221 delArg++;
222 gSPIRVValidator = argv[i + 1];
223 }
224 else
225 {
226 log_error("Program argument for --spirv-validator was not "
227 "specified.\n");
228 return -1;
229 }
230 }
231
232 // cleaning parameters from argv tab
233 for (int j = i; j < argc - delArg; j++) argv[j] = argv[j + delArg];
234 argc -= delArg;
235 i -= delArg;
236 }
237
238 if ((gCompilationCacheMode == kCacheModeForceRead
239 || gCompilationCacheMode == kCacheModeOverwrite)
240 && gCompilationMode == kOnline)
241 {
242 log_error("Compilation cache mode can only be specified when using an "
243 "offline compilation mode.\n");
244 return -1;
245 }
246
247 return argc;
248 }
249
is_power_of_two(int number)250 bool is_power_of_two(int number) { return number && !(number & (number - 1)); }
251
parseWimpyReductionFactor(const char * & arg,int & wimpyReductionFactor)252 extern void parseWimpyReductionFactor(const char *&arg,
253 int &wimpyReductionFactor)
254 {
255 const char *arg_temp = strchr(&arg[1], ']');
256 if (arg_temp != 0)
257 {
258 int new_factor = atoi(&arg[1]);
259 arg = arg_temp; // Advance until ']'
260 if (is_power_of_two(new_factor))
261 {
262 log_info("\n Wimpy reduction factor changed from %d to %d \n",
263 wimpyReductionFactor, new_factor);
264 wimpyReductionFactor = new_factor;
265 }
266 else
267 {
268 log_info("\n WARNING: Incorrect wimpy reduction factor %d, must be "
269 "power of 2. The default value will be used.\n",
270 new_factor);
271 }
272 }
273 }
274