1 /*========================== begin_copyright_notice ============================ 2 3 Copyright (C) 2017-2021 Intel Corporation 4 5 SPDX-License-Identifier: MIT 6 7 ============================= end_copyright_notice ===========================*/ 8 9 #ifndef _OPTION_H_ 10 #define _OPTION_H_ 11 12 #include <iostream> 13 #include <iomanip> 14 #include "visa_igc_common_header.h" 15 #include "VISAOptions.h" 16 #include "common.h" 17 #include <vector> 18 #include <unordered_map> 19 #include <algorithm> 20 21 #define MAX_OPTION_STR_LENGTH 256 22 #define MAX_LABEL_STR_LENGTH 256 23 24 enum Stepping { 25 Step_A = 0, 26 Step_B = 1, 27 Step_C = 2, 28 Step_D = 3, 29 Step_E = 4, 30 Step_F = 5, 31 Step_none = 6 32 }; 33 34 enum EntryType { 35 ET_UNINIT = 0, 36 ET_BOOL, 37 ET_INT32, 38 ET_2xINT32, 39 ET_INT64, 40 ET_CSTR, 41 ET_MAX 42 }; 43 44 union EntryValue { 45 bool boolean; 46 uint32_t int32; 47 uint64_t int64; 48 const char *cstr; 49 }; 50 51 struct VISAOptionsEntry { 52 EntryType type = ET_UNINIT; 53 EntryValue val; getTypeVISAOptionsEntry54 EntryType getType(void) const { return type; } dumpVISAOptionsEntry55 virtual void dump(void) const { std::cerr << "BASE"; } ~VISAOptionsEntryVISAOptionsEntry56 virtual ~VISAOptionsEntry() {} 57 }; 58 59 struct VISAOptionsEntryBool : VISAOptionsEntry { VISAOptionsEntryBoolVISAOptionsEntryBool60 VISAOptionsEntryBool(bool Val) { 61 val.boolean = Val; 62 type = ET_BOOL; 63 } dumpVISAOptionsEntryBool64 virtual void dump(void) const override { 65 std::cerr << std::left << std::setw(10) 66 << ((val.boolean) ? "true" : "false"); 67 } getValVISAOptionsEntryBool68 bool getVal(void) const { return val.boolean; } 69 }; 70 struct VISAOptionsEntryUint32 : VISAOptionsEntry { VISAOptionsEntryUint32VISAOptionsEntryUint3271 VISAOptionsEntryUint32(uint32_t Val) { 72 val.int32 = Val; 73 type = ET_INT32; 74 } dumpVISAOptionsEntryUint3275 virtual void dump(void) const override { 76 std::cerr << std::left << std::setw(10) << val.int32; 77 } getValVISAOptionsEntryUint3278 uint32_t getVal(void) const { return val.int32; } 79 }; 80 struct VISAOptionsEntryUint64 : VISAOptionsEntry { VISAOptionsEntryUint64VISAOptionsEntryUint6481 VISAOptionsEntryUint64(uint64_t Val) { 82 val.int64 = Val; 83 type = ET_INT64; 84 } dumpVISAOptionsEntryUint6485 virtual void dump(void) const override { 86 std::cerr << std::left << std::setw(10) << val.int64; 87 } getValVISAOptionsEntryUint6488 uint64_t getVal(void) const { return val.int64; } 89 }; 90 struct VISAOptionsEntryCstr : VISAOptionsEntry { VISAOptionsEntryCstrVISAOptionsEntryCstr91 VISAOptionsEntryCstr(const char *Val) { 92 val.cstr = Val; 93 type = ET_CSTR; 94 } dumpVISAOptionsEntryCstr95 virtual void dump(void) const override { 96 if (val.cstr) { 97 std::cerr << std::left << std::setw(10) << val.cstr; 98 } else { 99 std::cerr << std::left << std::setw(10) << "NULL"; 100 } 101 } getValVISAOptionsEntryCstr102 const char *getVal(void) const { return val.cstr; } 103 }; 104 105 106 class Options { 107 std::unordered_map<std::string, vISAOptions> argToOption; 108 const char *vISAOptionsToStr[vISA_NUM_OPTIONS]; 109 void initializeArgToOption(void); 110 void initialize_vISAOptionsToStr(void); 111 void initialize_m_vISAOptions(void); 112 113 public: 114 Options(); 115 get_vISAOptionsToStr(vISAOptions opt)116 const char *get_vISAOptionsToStr(vISAOptions opt) { 117 return vISAOptionsToStr[opt]; 118 } 119 bool parseOptions(int argc, const char *argv[]); 120 // This is to check whether an option of any type is set. 121 // It is useful for Cstr or Int arguments because getOption() will give us 122 // the value, not whether they are set or not. 123 bool isOptionSetByUser(vISAOptions option) const; 124 125 void getOption(vISAOptions option, bool &value) const; 126 bool getOption(vISAOptions option) const; 127 void getOption(vISAOptions option, const char*& buf) const; 128 const char *getOptionCstr(vISAOptions option) const; 129 uint32_t getuInt32Option(vISAOptions option) const; 130 uint64_t getuInt64Option(vISAOptions option) const; 131 setTarget(VISATarget tTarget)132 void setTarget(VISATarget tTarget) { target = tTarget;} getTarget()133 VISATarget getTarget() const { return target; } 134 135 // APIs used by vISA clients (explicitly setting options) 136 void setOption(vISAOptions option, bool val); 137 void setOption(vISAOptions option, uint32_t val); 138 void setOption(vISAOptions options, const char* str); 139 140 // APIs used by vISA itself to set options internally 141 void setOptionInternally(vISAOptions option, bool val); 142 void setOptionInternally(vISAOptions option, uint32_t val); 143 void setOptionInternally(vISAOptions options, const char* str); 144 145 static void showUsage(std::ostream& output); 146 147 std::stringstream& getUserArgString(); 148 std::string getFullArgString() const; 149 std::string getEncoderOutputFile() const; 150 GetStepping()151 Stepping GetStepping() const { return stepping; } 152 153 void getOptionsFromEV(); 154 155 void dump() const; 156 157 private: 158 void setGTPin(); 159 160 // This holds the data of a single vISAOptions entry 161 struct VISAOptionsLine { 162 // This is the "-fooBarOption" 163 const char *argStr; 164 // The TYPE 165 EntryType type; 166 // This holds the actual value 167 VISAOptionsEntry *value; 168 // This holds the default value 169 VISAOptionsEntry *defaultValue; 170 // The error message to show when argument is badly formed 171 const char *errorMsg; 172 // This is set to TRUE if this option is passed as an argument 173 bool argIsSet; 174 VISAOptionsLineVISAOptionsLine175 VISAOptionsLine(void) { 176 argStr = (const char *) nullptr; 177 type = ET_UNINIT; 178 value = nullptr; 179 defaultValue = nullptr; 180 errorMsg = nullptr; 181 argIsSet = false; 182 } 183 // Debug print dumpVISAOptionsLine184 void dump(void) const { 185 std::cerr << std::setw(30) << argStr 186 << " [" << argIsSet << "] "; 187 if (value) { 188 value->dump(); 189 } else { 190 std::cerr << std::left << std::setw(10) << "NULL"; 191 } 192 std::cerr << ", (default:"; 193 if (defaultValue) { 194 defaultValue->dump(); 195 } else { 196 std::cerr << std::left << std::setw(10) << "NULL"; 197 } 198 std::cerr << ")"; 199 } 200 }; 201 202 // gcc 4.9.3 does not support enum as unordered_map key without an explicit hash function 203 struct vISAOptionsHash 204 { operatorvISAOptionsHash205 size_t operator()(vISAOptions opt) const 206 { 207 return (size_t)opt; 208 } 209 }; 210 211 // The main structure where we hold the options, their "-argument string", 212 // their assigned values, their default values etc. 213 // It is a map from vISAOptions->VISAOptionsLine 214 class VISAOptionsDB { 215 private: 216 Options *options = nullptr; 217 std::unordered_map<vISAOptions, VISAOptionsLine, vISAOptionsHash> optionsMap; 218 // Check if KEY has already a value assigned to it 219 void freeIfAlreadySet(vISAOptions key, bool dontCheckNull = true) { 220 // If already set, free tha last one 221 auto it = optionsMap.find(key); 222 if (it != optionsMap.end()) { 223 if (dontCheckNull || it->second.value != nullptr) { 224 delete it->second.value; 225 } 226 } 227 } 228 public: 229 // Debug print all the options dump(void)230 void dump(void) const { 231 for (auto pair : optionsMap) { 232 const VISAOptionsLine &line = pair.second; 233 std::cerr << std::left << std::setw(34) 234 << options->get_vISAOptionsToStr(pair.first) 235 << ": "; 236 line.dump(); 237 std::cerr << std::endl; 238 } 239 } 240 // Debug print a single entry dump(vISAOptions key)241 void dump(vISAOptions key) const { 242 optionsMap.at(key).dump(); 243 } 244 // If the option is passed as a command line argument setArgSetByUser(vISAOptions key)245 void setArgSetByUser(vISAOptions key) { 246 optionsMap[key].argIsSet = true; 247 } 248 // Set the value of the option setBool(vISAOptions key,bool val)249 void setBool(vISAOptions key, bool val) { 250 freeIfAlreadySet(key); 251 optionsMap[key].value = new VISAOptionsEntryBool(val); 252 } setUint32(vISAOptions key,uint32_t val)253 void setUint32(vISAOptions key, uint32_t val) { 254 freeIfAlreadySet(key); 255 optionsMap[key].value = new VISAOptionsEntryUint32(val); 256 } setUint64(vISAOptions key,uint64_t val)257 void setUint64(vISAOptions key, uint64_t val) { 258 freeIfAlreadySet(key); 259 optionsMap[key].value = new VISAOptionsEntryUint64(val); 260 } setCstr(vISAOptions key,const char * val)261 void setCstr(vISAOptions key, const char *val) { 262 freeIfAlreadySet(key, false); 263 if (! val) { 264 optionsMap[key].value = nullptr; 265 } else { 266 MUST_BE_TRUE(strlen(val) < MAX_OPTION_STR_LENGTH, ERROR_OPTION); 267 // size_t strLen = std::min(strlen(val) + 1, 268 // (size_t)MAX_OPTION_STR_LENGTH); 269 // // Not sure why new space is allocated. 270 // // It is never freed. 271 // char *newBuf = (char *) malloc(strLen); 272 // strncpy_s(newBuf, strLen, val, strLen); 273 optionsMap[key].value = new VISAOptionsEntryCstr(val); 274 } 275 } 276 277 // Set the value of the option setDefaultBool(vISAOptions key,bool val)278 void setDefaultBool(vISAOptions key, bool val) { 279 optionsMap[key].defaultValue = new VISAOptionsEntryBool(val); 280 } setDefaultUint32(vISAOptions key,uint32_t val)281 void setDefaultUint32(vISAOptions key, uint32_t val) { 282 optionsMap[key].defaultValue = new VISAOptionsEntryUint32(val); 283 } setDefaultUint64(vISAOptions key,uint64_t val)284 void setDefaultUint64(vISAOptions key, uint64_t val) { 285 optionsMap[key].defaultValue = new VISAOptionsEntryUint64(val); 286 } setDefaultCstr(vISAOptions key,const char * val)287 void setDefaultCstr(vISAOptions key, const char *val) { 288 optionsMap[key].defaultValue = new VISAOptionsEntryCstr(val); 289 } 290 291 // Set the "-fooBarOption" setArgStr(vISAOptions key,const char * argStr)292 void setArgStr(vISAOptions key, const char *argStr) { 293 optionsMap[key].argStr = argStr; 294 } 295 296 // Set the TYPE setType(vISAOptions key,EntryType type)297 void setType(vISAOptions key, EntryType type) { 298 optionsMap[key].type = type; 299 } 300 301 // Set the error message setErrorMsg(vISAOptions key,const char * errorMsg)302 void setErrorMsg(vISAOptions key, const char *errorMsg) { 303 optionsMap[key].errorMsg = errorMsg; 304 } 305 306 // Get the argument string "-fooArg" getArgStr(vISAOptions key)307 const char *getArgStr(vISAOptions key) const { 308 auto it = optionsMap.find(key); 309 if (it != optionsMap.end()) { 310 const char *argStr = it->second.argStr; 311 return argStr; 312 } else { 313 return "UNDEFINED"; 314 } 315 } 316 317 // Get the type of KEY getType(vISAOptions key)318 EntryType getType(vISAOptions key) const { 319 assert(optionsMap.count(key)); 320 return optionsMap.at(key).type; 321 } 322 323 // Get the type of KEY getErrorMsg(vISAOptions key)324 const char *getErrorMsg(vISAOptions key) const { 325 assert(optionsMap.count(key)); 326 return optionsMap.at(key).errorMsg; 327 } 328 329 330 // Get the values getBool(vISAOptions key)331 bool getBool(vISAOptions key) const { 332 assert(optionsMap.count(key)); 333 const VISAOptionsEntry *value = optionsMap.at(key).value; 334 assert(value->getType() == ET_BOOL && "Bad Type"); 335 const VISAOptionsEntryBool *Bool 336 = static_cast<const VISAOptionsEntryBool *>(value); 337 assert(Bool && "Uninitialized?"); 338 return Bool->getVal(); 339 } getUint32(vISAOptions key)340 uint32_t getUint32(vISAOptions key) const { 341 assert(optionsMap.count(key)); 342 const VISAOptionsEntry *value = optionsMap.at(key).value; 343 assert(value->getType() == ET_INT32 && "Bad Type"); 344 const VISAOptionsEntryUint32 *Int32 345 = static_cast<const VISAOptionsEntryUint32 *>(value); 346 assert(Int32 && "Uninitialized?"); 347 return Int32->getVal(); 348 } getUint64(vISAOptions key)349 uint64_t getUint64(vISAOptions key) const { 350 assert(optionsMap.count(key)); 351 const VISAOptionsEntry *value = optionsMap.at(key).value; 352 assert(value->getType() == ET_INT64 && "Bad Type"); 353 const VISAOptionsEntryUint64 *Int64 354 = static_cast<const VISAOptionsEntryUint64 *>(value); 355 assert(Int64 && "Uninitialized?"); 356 return Int64->getVal(); 357 } getCstr(vISAOptions key)358 const char *getCstr(vISAOptions key) const { 359 assert(optionsMap.count(key)); 360 const VISAOptionsEntry *value = optionsMap.at(key).value; 361 if (! value) { 362 return nullptr; 363 } 364 assert(value->getType() == ET_CSTR && "Bad Type"); 365 const VISAOptionsEntryCstr *Cstr 366 = static_cast<const VISAOptionsEntryCstr *>(value); 367 // assert(Cstr && "Bad option type OR uninit"); 368 return Cstr->getVal(); 369 } 370 371 // TRUE if the options is passed as a cmd line argument isArgSetByUser(vISAOptions key)372 bool isArgSetByUser(vISAOptions key) const { 373 return optionsMap.at(key).argIsSet; 374 } 375 // Get defaults getDefaultBool(vISAOptions key)376 bool getDefaultBool(vISAOptions key) const { 377 assert(optionsMap.count(key)); 378 const VISAOptionsEntry *defValue = optionsMap.at(key).defaultValue; 379 assert(defValue->getType() == ET_BOOL && "Bad Type"); 380 const VISAOptionsEntryBool *Bool 381 = static_cast<const VISAOptionsEntryBool *>(defValue); 382 assert(Bool && "Uninitialized?"); 383 return Bool->getVal(); 384 } getDefaultUint32(vISAOptions key)385 uint32_t getDefaultUint32(vISAOptions key) const { 386 assert(optionsMap.count(key)); 387 const VISAOptionsEntry *defValue = optionsMap.at(key).defaultValue; 388 assert(defValue->getType() == ET_INT32 && "Bad Type"); 389 const VISAOptionsEntryUint32 *Int32 390 = static_cast<const VISAOptionsEntryUint32 *>(defValue); 391 assert(Int32 && "Uninitialized?"); 392 return Int32->getVal(); 393 } getDefaultUint64(vISAOptions key)394 uint64_t getDefaultUint64(vISAOptions key) const { 395 assert(optionsMap.count(key)); 396 const VISAOptionsEntry *defValue = optionsMap.at(key).defaultValue; 397 assert(defValue->getType() == ET_INT64 && "Bad Type"); 398 const VISAOptionsEntryUint64 *Int64 399 = static_cast<const VISAOptionsEntryUint64 *>(defValue); 400 assert(Int64 && "Uninitialized?"); 401 return Int64->getVal(); 402 } getDefaultCstr(vISAOptions key)403 const char *getDefaultCstr(vISAOptions key) const { 404 assert(optionsMap.count(key)); 405 const VISAOptionsEntry *defValue = optionsMap.at(key).defaultValue; 406 assert(defValue->getType() == ET_CSTR && "Bad Type"); 407 const VISAOptionsEntryCstr *Cstr 408 = static_cast<const VISAOptionsEntryCstr *>(defValue); 409 assert(Cstr && "Uninitialized?"); 410 return Cstr->getVal(); 411 } VISAOptionsDB()412 VISAOptionsDB() {} VISAOptionsDB(Options * opt)413 VISAOptionsDB(Options *opt) { 414 options = opt; 415 } 416 ~VISAOptionsDB(void)417 ~VISAOptionsDB(void) { 418 for (auto pair : optionsMap) { 419 auto *val = pair.second.value; 420 delete val; 421 auto *defVal = pair.second.defaultValue; 422 delete defVal; 423 424 } 425 } 426 }; 427 428 VISAOptionsDB m_vISAOptions; 429 430 VISATarget target; 431 432 // for debugging, store the options passed to command line/vISA builder 433 std::stringstream argString; 434 435 // legacy stepping setting for offline vISA compile. 436 // FE compilers should not use this and should instead program the appropriate WATable/vISA option flags instead. 437 Stepping stepping = Stepping::Step_none; 438 SetStepping(const char * str)439 int SetStepping(const char* str) { 440 441 int retVal = VISA_SUCCESS; 442 char upperchar = (char)std::toupper(*str); 443 444 switch (upperchar) 445 { 446 case 'A': 447 stepping = Step_A; 448 break; 449 case 'B': 450 stepping = Step_B; 451 break; 452 case 'C': 453 stepping = Step_C; 454 break; 455 case 'D': 456 stepping = Step_D; 457 break; 458 case 'E': 459 stepping = Step_E; 460 break; 461 case 'F': 462 stepping = Step_F; 463 break; 464 default: 465 // err msg? 466 break; 467 } 468 return retVal; 469 } 470 471 }; 472 473 #endif 474