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