diff options
Diffstat (limited to 'src/utilities')
-rw-r--r-- | src/utilities/device_mapping.hpp | 51 | ||||
-rw-r--r-- | src/utilities/utilities.cpp | 63 | ||||
-rw-r--r-- | src/utilities/utilities.hpp | 21 |
3 files changed, 127 insertions, 8 deletions
diff --git a/src/utilities/device_mapping.hpp b/src/utilities/device_mapping.hpp new file mode 100644 index 00000000..7fdc04a0 --- /dev/null +++ b/src/utilities/device_mapping.hpp @@ -0,0 +1,51 @@ + +// ================================================================================================= +// This file is part of the CLBlast project. The project is licensed under Apache Version 2.0. This +// project loosely follows the Google C++ styleguide and uses a tab-size of two spaces and a max- +// width of 100 characters per line. +// +// Author(s): +// Cedric Nugteren <www.cedricnugteren.nl> +// +// This file describes the mappings of extracted names from OpenCL (device, board, vendor, etc.) to +// more commonly used names to match devices from different vendors and platforms properly. +// +// ================================================================================================= + +#ifndef CLBLAST_UTILITIES_DEVICE_MAPPING_H_ +#define CLBLAST_UTILITIES_DEVICE_MAPPING_H_ + +#include <string> +#include <unordered_map> + +namespace clblast { +// A special namespace to hold all the global constant variables +namespace device_mapping { + +// ================================================================================================= + +// Alternative names for some vendor names (top-level) +const std::unordered_map<std::string, std::string> kVendorNames { + { "Intel(R) Corporation", "Intel" }, + { "GenuineIntel", "Intel" }, + { "Advanced Micro Devices, Inc.", "AMD" }, + { "NVIDIA Corporation", "NVIDIA" }, +}; + +// Alternative names for some architectures (mid-level) +const std::unordered_map<std::string, std::string> kArchitectureNames { + {"gfx803", "Fiji"}, + {"gfx900", "Vega"}, +}; + +// Alternative names for some devices (low-level) +const std::unordered_map<std::string, std::string> kDeviceNames { + // Empty +}; + +// ================================================================================================= +} // namespace device_mapping +} // namespace clblast + +// CLBLAST_UTILITIES_DEVICE_MAPPING_H_ +#endif diff --git a/src/utilities/utilities.cpp b/src/utilities/utilities.cpp index 0cd00438..4b8d5a09 100644 --- a/src/utilities/utilities.cpp +++ b/src/utilities/utilities.cpp @@ -11,8 +11,6 @@ // // ================================================================================================= -#include "utilities/utilities.hpp" - #include <string> #include <vector> #include <chrono> @@ -20,6 +18,10 @@ #include <iomanip> #include <cmath> +#include "utilities/utilities.hpp" + +#include "utilities/device_mapping.hpp" + namespace clblast { // ================================================================================================= @@ -390,17 +392,62 @@ template <> Precision PrecisionValue<double2>() { return Precision::kComplexDoub template <> bool PrecisionSupported<float>(const Device &) { return true; } template <> bool PrecisionSupported<float2>(const Device &) { return true; } template <> bool PrecisionSupported<double>(const Device &device) { - auto extensions = device.Capabilities(); - return (extensions.find(kKhronosDoublePrecision) == std::string::npos) ? false : true; + return device.HasExtension(kKhronosDoublePrecision); } template <> bool PrecisionSupported<double2>(const Device &device) { - auto extensions = device.Capabilities(); - return (extensions.find(kKhronosDoublePrecision) == std::string::npos) ? false : true; + return device.HasExtension(kKhronosDoublePrecision); } template <> bool PrecisionSupported<half>(const Device &device) { - auto extensions = device.Capabilities(); if (device.Name() == "Mali-T628") { return true; } // supports fp16 but not cl_khr_fp16 officially - return (extensions.find(kKhronosHalfPrecision) == std::string::npos) ? false : true; + return device.HasExtension(kKhronosHalfPrecision); +} + +// ================================================================================================= + +// High-level info +std::string GetDeviceType(const Device& device) { + return device.Type(); +} +std::string GetDeviceVendor(const Device& device) { + auto device_vendor = device.Vendor(); + + for (auto &find_and_replace : device_mapping::kVendorNames) { // replacing to common names + if (device_vendor == find_and_replace.first) { device_vendor = find_and_replace.second; } + } + return device_vendor; +} + +// Mid-level info +std::string GetDeviceArchitecture(const Device& device) { + auto device_architecture = std::string{""}; + if (device.HasExtension(kKhronosAttributesNVIDIA)) { + device_architecture = device.NVIDIAComputeCapability(); + } + else if (device.HasExtension(kKhronosAttributesAMD)) { + device_architecture = device.Name(); // Name is architecture for AMD APP and AMD ROCm + } + // Note: no else - 'device_architecture' might be the empty string + + for (auto &find_and_replace : device_mapping::kArchitectureNames) { // replacing to common names + if (device_architecture == find_and_replace.first) { device_architecture = find_and_replace.second; } + } + return device_architecture; +} + +// Lowest-level +std::string GetDeviceName(const Device& device) { + auto device_name = std::string{""}; + if (device.HasExtension(kKhronosAttributesAMD)) { + device_name = device.AMDBoardName(); + } + else { + device_name = device.Name(); + } + + for (auto &find_and_replace : device_mapping::kDeviceNames) { // replacing to common names + if (device_name == find_and_replace.first) { device_name = find_and_replace.second; } + } + return device_name; } // ================================================================================================= diff --git a/src/utilities/utilities.hpp b/src/utilities/utilities.hpp index fae69b63..e45c606c 100644 --- a/src/utilities/utilities.hpp +++ b/src/utilities/utilities.hpp @@ -40,6 +40,8 @@ using double2 = std::complex<double>; // Khronos OpenCL extensions const std::string kKhronosHalfPrecision = "cl_khr_fp16"; const std::string kKhronosDoublePrecision = "cl_khr_fp64"; +const std::string kKhronosAttributesAMD = "cl_amd_device_attribute_query"; +const std::string kKhronosAttributesNVIDIA = "cl_nv_device_attribute_query"; // Catched an unknown error constexpr auto kUnknownError = -999; @@ -121,6 +123,17 @@ constexpr auto kBufScalar = "Scalar"; // ================================================================================================= +#ifdef VERBOSE +inline void log_debug(const std::string &log_string) { + printf("[DEBUG] %s\n", log_string.c_str()); +} +#else +inline void log_debug(const std::string&) { } +#endif + + +// ================================================================================================= + // Converts a regular or complex type to it's base type (e.g. float2 to float) template <typename T> struct BaseType { using Type = T; }; template <> struct BaseType<float2> { using Type = float; }; @@ -306,6 +319,14 @@ template <typename T> bool PrecisionSupported(const Device &device); // ================================================================================================= + +// Device information in a specific CLBlast form +std::string GetDeviceType(const Device& device); +std::string GetDeviceVendor(const Device& device); +std::string GetDeviceArchitecture(const Device& device); +std::string GetDeviceName(const Device& device); + +// ================================================================================================= } // namespace clblast // CLBLAST_UTILITIES_H_ |