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> &parameter_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> &parameter_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> &parameter_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