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