From d6f05557710472ca4afdb9ec2536d5ba6274a392 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 24 Sep 2019 23:01:03 +0700 Subject: [PATCH] Added command line option --opencl-devices (hint mode) --- src/backend/opencl/OclConfig.cpp | 40 +++++++++++++++++++++++++++-- src/backend/opencl/OclConfig.h | 2 ++ src/backend/opencl/OclThread.cpp | 4 +++ src/base/io/json/Json.cpp | 21 +++++++++++++++ src/core/config/ConfigTransform.cpp | 4 +++ 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/backend/opencl/OclConfig.cpp b/src/backend/opencl/OclConfig.cpp index cec10b359..7424dba7a 100644 --- a/src/backend/opencl/OclConfig.cpp +++ b/src/backend/opencl/OclConfig.cpp @@ -30,12 +30,16 @@ #include "rapidjson/document.h" +#include + + namespace xmrig { static const char *kAMD = "AMD"; static const char *kCache = "cache"; static const char *kCn = "cn"; static const char *kCn2 = "cn/2"; +static const char *kDevicesHint = "devices-hint"; static const char *kEnabled = "enabled"; static const char *kINTEL = "INTEL"; static const char *kLoader = "loader"; @@ -90,6 +94,22 @@ static size_t generate(const char *key, Threads &threads, const Algo } +static inline std::vector filterDevices(const std::vector &devices, const std::vector &hints) +{ + std::vector out; + out.reserve(std::min(devices.size(), hints.size())); + + for (const auto &device : devices) { + auto it = std::find(hints.begin(), hints.end(), device.index()); + if (it != hints.end()) { + out.emplace_back(device); + } + } + + return out; +} + + } @@ -214,6 +234,7 @@ void xmrig::OclConfig::read(const rapidjson::Value &value) m_loader = Json::getString(value, kLoader); setPlatform(Json::getValue(value, kPlatform)); + setDevicesHint(Json::getString(value, kDevicesHint)); m_threads.read(value); @@ -234,7 +255,7 @@ void xmrig::OclConfig::read(const rapidjson::Value &value) void xmrig::OclConfig::generate() { - if (!isEnabled()) { + if (!isEnabled() || m_threads.has("*")) { return; } @@ -242,7 +263,7 @@ void xmrig::OclConfig::generate() return; } - const auto devices = platform().devices(); + const auto devices = m_devicesHint.empty() ? platform().devices() : filterDevices(platform().devices(), m_devicesHint); if (devices.empty()) { return; } @@ -287,6 +308,21 @@ void xmrig::OclConfig::generate() } +void xmrig::OclConfig::setDevicesHint(const char *devicesHint) +{ + if (devicesHint == nullptr) { + return; + } + + const auto indexes = String(devicesHint).split(','); + m_devicesHint.reserve(indexes.size()); + + for (const auto &index : indexes) { + m_devicesHint.push_back(strtoul(index, nullptr, 10)); + } +} + + void xmrig::OclConfig::setPlatform(const rapidjson::Value &platform) { if (platform.IsString()) { diff --git a/src/backend/opencl/OclConfig.h b/src/backend/opencl/OclConfig.h index 72546342e..9dd5ad1da 100644 --- a/src/backend/opencl/OclConfig.h +++ b/src/backend/opencl/OclConfig.h @@ -53,11 +53,13 @@ public: private: void generate(); + void setDevicesHint(const char *devicesHint); void setPlatform(const rapidjson::Value &platform); bool m_cache = true; bool m_enabled = false; bool m_shouldSave = false; + std::vector m_devicesHint; String m_loader; String m_platformVendor; Threads m_threads; diff --git a/src/backend/opencl/OclThread.cpp b/src/backend/opencl/OclThread.cpp index 02ef5f3b2..8ca4574f7 100644 --- a/src/backend/opencl/OclThread.cpp +++ b/src/backend/opencl/OclThread.cpp @@ -52,6 +52,10 @@ static const char* kDatasetHost = "dataset_host"; xmrig::OclThread::OclThread(const rapidjson::Value &value) { + if (!value.IsObject()) { + return; + } + m_index = Json::getUint(value, kIndex); m_worksize = std::max(std::min(Json::getUint(value, kWorksize), 128u), 1u); m_unrollFactor = std::max(std::min(Json::getUint(value, kUnroll, m_unrollFactor), 128u), 1u); diff --git a/src/base/io/json/Json.cpp b/src/base/io/json/Json.cpp index 07986c4af..03d4c65ab 100644 --- a/src/base/io/json/Json.cpp +++ b/src/base/io/json/Json.cpp @@ -27,6 +27,9 @@ #include "rapidjson/document.h" +#include + + namespace xmrig { static const rapidjson::Value kNullValue; @@ -36,6 +39,8 @@ static const rapidjson::Value kNullValue; bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue) { + assert(obj.IsObject()); + auto i = obj.FindMember(key); if (i != obj.MemberEnd() && i->value.IsBool()) { return i->value.GetBool(); @@ -47,6 +52,8 @@ bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool def const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key, const char *defaultValue) { + assert(obj.IsObject()); + auto i = obj.FindMember(key); if (i != obj.MemberEnd() && i->value.IsString()) { return i->value.GetString(); @@ -58,6 +65,8 @@ const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key, const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const char *key) { + assert(obj.IsObject()); + auto i = obj.FindMember(key); if (i != obj.MemberEnd() && i->value.IsArray()) { return i->value; @@ -69,6 +78,8 @@ const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, const char *key) { + assert(obj.IsObject()); + auto i = obj.FindMember(key); if (i != obj.MemberEnd() && i->value.IsObject()) { return i->value; @@ -80,6 +91,8 @@ const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, cons const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const char *key) { + assert(obj.IsObject()); + auto i = obj.FindMember(key); if (i != obj.MemberEnd()) { return i->value; @@ -91,6 +104,8 @@ const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue) { + assert(obj.IsObject()); + auto i = obj.FindMember(key); if (i != obj.MemberEnd() && i->value.IsInt()) { return i->value.GetInt(); @@ -102,6 +117,8 @@ int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaul int64_t xmrig::Json::getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue) { + assert(obj.IsObject()); + auto i = obj.FindMember(key); if (i != obj.MemberEnd() && i->value.IsInt64()) { return i->value.GetInt64(); @@ -113,6 +130,8 @@ int64_t xmrig::Json::getInt64(const rapidjson::Value &obj, const char *key, int6 uint64_t xmrig::Json::getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue) { + assert(obj.IsObject()); + auto i = obj.FindMember(key); if (i != obj.MemberEnd() && i->value.IsUint64()) { return i->value.GetUint64(); @@ -124,6 +143,8 @@ uint64_t xmrig::Json::getUint64(const rapidjson::Value &obj, const char *key, ui unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsigned defaultValue) { + assert(obj.IsObject()); + auto i = obj.FindMember(key); if (i != obj.MemberEnd() && i->value.IsUint()) { return i->value.GetUint(); diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp index 58f6aa64a..e7bd383fe 100644 --- a/src/core/config/ConfigTransform.cpp +++ b/src/core/config/ConfigTransform.cpp @@ -162,6 +162,10 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const case IConfig::OclLoaderKey: /* --opencl-loader */ return set(doc, kOcl, "loader", arg); + case IConfig::OclDevicesKey: /* --opencl-devices */ + m_opencl = true; + return set(doc, kOcl, "devices-hint", arg); + case IConfig::OclPlatformKey: /* --opencl-platform */ if (strlen(arg) < 3) { return set(doc, kOcl, "platform", static_cast(strtol(arg, nullptr, 10)));