1 2 // ================================================================================================= 3 // This file is part of the CLBlast project. The project is licensed under Apache Version 2.0. This 4 // project loosely follows the Google C++ styleguide and uses a tab-size of two spaces and a max- 5 // width of 100 characters per line. 6 // 7 // Author(s): 8 // Cedric Nugteren <www.cedricnugteren.nl> 9 // 10 // This file implements the Database class, providing a static variable holding the actual database 11 // information. The class also provides utility functions to search the database and to access a 12 // found entry by parameter-key. The database itself is filled in the corresponding source-file and 13 // partially also by the database/xxxxx.h files, in which kernel-specific parameters are found. 14 // 15 // ================================================================================================= 16 17 #ifndef CLBLAST_DATABASE_H_ 18 #define CLBLAST_DATABASE_H_ 19 20 #include <string> 21 #include <vector> 22 #include <unordered_map> 23 24 #include "utilities/utilities.hpp" 25 #include "database/database_structure.hpp" 26 27 namespace clblast { 28 // ================================================================================================= 29 30 // See comment at top of file for a description of the class 31 class Database { 32 public: 33 34 // The OpenCL device vendors 35 static const std::string kDeviceVendorAll; 36 37 // The database consists of separate database entries, stored together in a vector 38 static const std::vector<database::DatabaseEntry> database; 39 40 // Database for a special case: Apple CPUs support limited number of threads 41 static const std::vector<database::DatabaseEntry> apple_cpu_fallback; 42 43 Database() = default; 44 45 // The constructor with a user-provided database overlay (potentially an empty vector) 46 explicit Database(const Device &device, const std::string &kernel_name, 47 const Precision precision, const std::vector<database::DatabaseEntry> &overlay); 48 49 // Accessor of values by key operator [](const std::string & key) const50 size_t operator[](const std::string &key) const { return parameters_->find(key)->second; } exists(const std::string & key) const51 bool exists(const std::string &key) const { return (parameters_->count(key) == 1); } 52 53 // Obtain a list of OpenCL pre-processor defines based on the parameters 54 std::string GetDefines() const; 55 56 // Retrieves the names of all the parameters 57 std::vector<std::string> GetParameterNames() const; 58 59 private: 60 // Search method functions, returning a set of parameters (possibly empty) 61 database::Parameters Search(const std::string &this_kernel, 62 const std::string &this_vendor, const std::string &this_type, 63 const std::string &this_device, const std::string &this_architecture, 64 const Precision this_precision, 65 const std::vector<database::DatabaseEntry> &db) const; 66 database::Parameters SearchDevice(const std::string &target_device, 67 const std::vector<database::DatabaseDevice> &devices, 68 const std::vector<std::string> ¶meter_names) const; 69 database::Parameters SearchArchitecture(const std::string &target_architecture, 70 const std::string &this_device, 71 const std::vector<database::DatabaseArchitecture> &architectures, 72 const std::vector<std::string> ¶meter_names) const; 73 database::Parameters SearchVendorAndType(const std::string &target_vendor, 74 const std::string &target_type, 75 const std::string &this_device, const std::string &this_architecture, 76 const std::vector<database::DatabaseVendor> &vendors, 77 const std::vector<std::string> ¶meter_names) const; 78 79 // Helper to convert from database format to proper types 80 std::string CharArrayToString(const database::Name char_array) const; 81 82 // Found parameters suitable for this device/kernel 83 std::shared_ptr<database::Parameters> parameters_; 84 }; 85 86 // ================================================================================================= 87 88 // Multiple databases together in a map 89 class Databases { 90 public: 91 Databases(const std::vector<std::string> & kernel_names)92 explicit Databases(const std::vector<std::string> &kernel_names): kernel_names_(kernel_names) { } 93 94 // Database accessor operator ()(const std::string & kernel_name)95 Database& operator()(const std::string &kernel_name) { return databases_[kernel_name]; } 96 97 // Retrieves a parameter from the database operator [](const std::string & key) const98 size_t operator[](const std::string &key) const { 99 for (const auto &kernel_name : kernel_names_) { 100 const auto &kernel_db = databases_.find(kernel_name)->second; 101 if (kernel_db.exists(key)) { return kernel_db[key]; } 102 } 103 throw RuntimeErrorCode(StatusCode::kDatabaseError); 104 } 105 106 private: 107 const std::vector<std::string> kernel_names_; 108 std::unordered_map<std::string, Database> databases_; 109 }; 110 111 // ================================================================================================= 112 } // namespace clblast 113 114 // CLBLAST_DATABASE_H_ 115 #endif 116