From ed4cfd55aced32a99bbf9bc7184f1007f7ec9f57 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 13 Nov 2019 00:40:22 +0700 Subject: [PATCH] #1274 Added --cuda-devices command line option. --- README.md | 3 ++- src/backend/cuda/CudaBackend.cpp | 9 ++++++--- src/backend/cuda/CudaConfig.cpp | 19 +++++++++++++++---- src/backend/cuda/CudaConfig.h | 17 +++++++++-------- src/backend/cuda/wrappers/CudaLib.cpp | 24 +++++++++++++++++++----- src/backend/cuda/wrappers/CudaLib.h | 2 +- src/base/io/json/Json.cpp | 2 +- src/core/config/ConfigTransform.cpp | 6 +++++- src/core/config/Config_platform.h | 1 + src/core/config/usage.h | 3 ++- 10 files changed, 61 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index ac978393..cf286f86 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ API: OpenCL backend: --opencl enable OpenCL mining backend - --opencl-devices=N list of OpenCL devices to use + --opencl-devices=N comma separated list of OpenCL devices to use --opencl-platform=N OpenCL platform index or name --opencl-loader=PATH path to OpenCL-ICD-Loader (OpenCL.dll or libOpenCL.so) --opencl-no-cache disable OpenCL cache @@ -83,6 +83,7 @@ OpenCL backend: CUDA backend: --cuda enable CUDA mining backend --cuda-loader=PATH path to CUDA plugin (xmrig-cuda.dll or libxmrig-cuda.so) + --cuda-devices=N comma separated list of CUDA devices to use --no-nvml disable NVML (NVIDIA Management Library) support Logging: diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index 812ee270..b351df75 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -155,11 +155,14 @@ public: return; } + devices = CudaLib::devices(cuda.bfactor(), cuda.bsleep(), cuda.devicesHint()); + if (devices.empty()) { + return printDisabled(kLabel, RED_S " (no devices)"); + } + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") "/" WHITE_BOLD("%s") BLACK_BOLD("/%s"), kLabel, CudaLib::version(runtimeVersion).c_str(), CudaLib::version(driverVersion).c_str(), CudaLib::pluginVersion()); - devices = CudaLib::devices(cuda.bfactor(), cuda.bsleep()); - # ifdef XMRIG_FEATURE_NVML if (cuda.isNvmlEnabled()) { if (NvmlLib::init(cuda.nvmlLoader())) { @@ -172,7 +175,7 @@ public: ); } else { - printDisabled(kLabel, RED_S " (failed to load NVML)"); + printDisabled(kNvmlLabel, RED_S " (failed to load NVML)"); } } else { diff --git a/src/backend/cuda/CudaConfig.cpp b/src/backend/cuda/CudaConfig.cpp index 49a28d11..8f26c14c 100644 --- a/src/backend/cuda/CudaConfig.cpp +++ b/src/backend/cuda/CudaConfig.cpp @@ -78,6 +78,16 @@ rapidjson::Value xmrig::CudaConfig::toJSON(rapidjson::Document &doc) const std::vector xmrig::CudaConfig::get(const Miner *miner, const Algorithm &algorithm, const std::vector &devices) const { + auto deviceIndex = [&devices](uint32_t index) -> int { + for (uint32_t i = 0; i < devices.size(); ++i) { + if (devices[i].index() == index) { + return i; + } + } + + return -1; + }; + std::vector out; const auto &threads = m_threads.get(algorithm); @@ -85,15 +95,16 @@ std::vector xmrig::CudaConfig::get(const Miner *miner, co return out; } - out.reserve(threads.count() * 2); + out.reserve(threads.count()); for (const auto &thread : threads.data()) { - if (thread.index() >= devices.size()) { + const int index = deviceIndex(thread.index()); + if (index == -1) { LOG_INFO("%s" YELLOW(" skip non-existing device with index ") YELLOW_BOLD("%u"), cuda_tag(), thread.index()); continue; } - out.emplace_back(miner, algorithm, thread, devices[thread.index()]); + out.emplace_back(miner, algorithm, thread, devices[static_cast(index)]); } return out; @@ -153,7 +164,7 @@ void xmrig::CudaConfig::generate() return; } - const auto devices = CudaLib::devices(bfactor(), bsleep()); + const auto devices = CudaLib::devices(bfactor(), bsleep(), m_devicesHint); if (devices.empty()) { return; } diff --git a/src/backend/cuda/CudaConfig.h b/src/backend/cuda/CudaConfig.h index 77be3dd4..3f3957e6 100644 --- a/src/backend/cuda/CudaConfig.h +++ b/src/backend/cuda/CudaConfig.h @@ -43,16 +43,17 @@ public: std::vector get(const Miner *miner, const Algorithm &algorithm, const std::vector &devices) const; void read(const rapidjson::Value &value); - inline bool isEnabled() const { return m_enabled; } - inline bool isShouldSave() const { return m_shouldSave; } - inline const String &loader() const { return m_loader; } - inline const Threads &threads() const { return m_threads; } - inline int32_t bfactor() const { return m_bfactor; } - inline int32_t bsleep() const { return m_bsleep; } + inline bool isEnabled() const { return m_enabled; } + inline bool isShouldSave() const { return m_shouldSave; } + inline const std::vector &devicesHint() const { return m_devicesHint; } + inline const String &loader() const { return m_loader; } + inline const Threads &threads() const { return m_threads; } + inline int32_t bfactor() const { return m_bfactor; } + inline int32_t bsleep() const { return m_bsleep; } # ifdef XMRIG_FEATURE_NVML - inline bool isNvmlEnabled() const { return m_nvml; } - inline const String &nvmlLoader() const { return m_nvmlLoader; } + inline bool isNvmlEnabled() const { return m_nvml; } + inline const String &nvmlLoader() const { return m_nvmlLoader; } # endif private: diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp index 8d22fefb..37924457 100644 --- a/src/backend/cuda/wrappers/CudaLib.cpp +++ b/src/backend/cuda/wrappers/CudaLib.cpp @@ -209,7 +209,7 @@ std::string xmrig::CudaLib::version(uint32_t version) } -std::vector xmrig::CudaLib::devices(int32_t bfactor, int32_t bsleep) noexcept +std::vector xmrig::CudaLib::devices(int32_t bfactor, int32_t bsleep, const std::vector &hints) noexcept { const uint32_t count = deviceCount(); if (!count) { @@ -219,10 +219,24 @@ std::vector xmrig::CudaLib::devices(int32_t bfactor, int32_t std::vector out; out.reserve(count); - for (uint32_t i = 0; i < count; ++i) { - CudaDevice device(i, bfactor, bsleep); - if (device.isValid()) { - out.emplace_back(std::move(device)); + if (hints.empty()) { + for (uint32_t i = 0; i < count; ++i) { + CudaDevice device(i, bfactor, bsleep); + if (device.isValid()) { + out.emplace_back(std::move(device)); + } + } + } + else { + for (const uint32_t i : hints) { + if (i >= count) { + continue; + } + + CudaDevice device(i, bfactor, bsleep); + if (device.isValid()) { + out.emplace_back(std::move(device)); + } } } diff --git a/src/backend/cuda/wrappers/CudaLib.h b/src/backend/cuda/wrappers/CudaLib.h index f18ed350..4874112f 100644 --- a/src/backend/cuda/wrappers/CudaLib.h +++ b/src/backend/cuda/wrappers/CudaLib.h @@ -85,7 +85,7 @@ public: static int32_t deviceInt(nvid_ctx *ctx, DeviceProperty property) noexcept; static nvid_ctx *alloc(uint32_t id, int32_t bfactor, int32_t bsleep) noexcept; static std::string version(uint32_t version); - static std::vector devices(int32_t bfactor, int32_t bsleep) noexcept; + static std::vector devices(int32_t bfactor, int32_t bsleep, const std::vector &hints) noexcept; static uint32_t deviceCount() noexcept; static uint32_t deviceUint(nvid_ctx *ctx, DeviceProperty property) noexcept; static uint32_t driverVersion() noexcept; diff --git a/src/base/io/json/Json.cpp b/src/base/io/json/Json.cpp index 03d4c65a..9a578293 100644 --- a/src/base/io/json/Json.cpp +++ b/src/base/io/json/Json.cpp @@ -50,7 +50,7 @@ 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) +const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key, const char *defaultValue) { assert(obj.IsObject()); diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp index ffd3fbd8..4ece6186 100644 --- a/src/core/config/ConfigTransform.cpp +++ b/src/core/config/ConfigTransform.cpp @@ -187,10 +187,14 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const # ifdef XMRIG_FEATURE_CUDA case IConfig::CudaKey: /* --cuda */ - return set(doc, kCuda, "enabled", true); + return set(doc, kCuda, kEnabled, true); case IConfig::CudaLoaderKey: /* --cuda-loader */ return set(doc, kCuda, "loader", arg); + + case IConfig::CudaDevicesKey: /* --cuda-devices */ + set(doc, kCuda, kEnabled, true); + return set(doc, kCuda, "devices-hint", arg); # endif # ifdef XMRIG_FEATURE_NVML diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index 3309beba..6ab03267 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -107,6 +107,7 @@ static const option options[] = { # ifdef XMRIG_FEATURE_CUDA { "cuda", 0, nullptr, IConfig::CudaKey }, { "cuda-loader", 1, nullptr, IConfig::CudaLoaderKey }, + { "cuda-devices", 1, nullptr, IConfig::CudaDevicesKey }, # endif # ifdef XMRIG_FEATURE_NVML { "no-nvml", 0, nullptr, IConfig::NvmlKey }, diff --git a/src/core/config/usage.h b/src/core/config/usage.h index d9ef2316..bcc3abd1 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -101,7 +101,7 @@ static inline const std::string &usage() # ifdef XMRIG_FEATURE_OPENCL u += "\nOpenCL backend:\n"; u += " --opencl enable OpenCL mining backend\n"; - u += " --opencl-devices=N list of OpenCL devices to use\n"; + u += " --opencl-devices=N comma separated list of OpenCL devices to use\n"; u += " --opencl-platform=N OpenCL platform index or name\n"; u += " --opencl-loader=PATH path to OpenCL-ICD-Loader (OpenCL.dll or libOpenCL.so)\n"; u += " --opencl-no-cache disable OpenCL cache\n"; @@ -112,6 +112,7 @@ static inline const std::string &usage() u += "\nCUDA backend:\n"; u += " --cuda enable CUDA mining backend\n"; u += " --cuda-loader=PATH path to CUDA plugin (xmrig-cuda.dll or libxmrig-cuda.so)\n"; + u += " --cuda-devices=N comma separated list of CUDA devices to use\n"; # endif # ifdef XMRIG_FEATURE_NVML u += " --no-nvml disable NVML (NVIDIA Management Library) support\n";