From 0fc215c457664b85251c7feb211daf9511943a75 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 23 Oct 2019 16:37:56 +0700 Subject: [PATCH 01/27] Added initial CUDA backend stub. --- CMakeLists.txt | 1 + src/backend/backend.cmake | 3 + src/backend/common/Tags.h | 6 + src/backend/common/Threads.cpp | 9 ++ src/backend/cuda/CudaBackend.cpp | 217 ++++++++++++++++++++++++++++++ src/backend/cuda/CudaBackend.h | 79 +++++++++++ src/backend/cuda/CudaConfig.cpp | 115 ++++++++++++++++ src/backend/cuda/CudaConfig.h | 62 +++++++++ src/backend/cuda/CudaConfig_gen.h | 42 ++++++ src/backend/cuda/CudaThread.cpp | 63 +++++++++ src/backend/cuda/CudaThread.h | 62 +++++++++ src/backend/cuda/CudaThreads.cpp | 71 ++++++++++ src/backend/cuda/CudaThreads.h | 64 +++++++++ src/backend/cuda/cuda.cmake | 23 ++++ src/backend/opencl/OclBackend.h | 9 +- src/core/Miner.cpp | 10 ++ src/core/config/Config.cpp | 35 +++++ src/core/config/Config.h | 7 +- 18 files changed, 871 insertions(+), 7 deletions(-) create mode 100644 src/backend/cuda/CudaBackend.cpp create mode 100644 src/backend/cuda/CudaBackend.h create mode 100644 src/backend/cuda/CudaConfig.cpp create mode 100644 src/backend/cuda/CudaConfig.h create mode 100644 src/backend/cuda/CudaConfig_gen.h create mode 100644 src/backend/cuda/CudaThread.cpp create mode 100644 src/backend/cuda/CudaThread.h create mode 100644 src/backend/cuda/CudaThreads.cpp create mode 100644 src/backend/cuda/CudaThreads.h create mode 100644 src/backend/cuda/cuda.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 90abfd42..1a195f6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ option(WITH_TLS "Enable OpenSSL support" ON) option(WITH_ASM "Enable ASM PoW implementations" ON) option(WITH_EMBEDDED_CONFIG "Enable internal embedded JSON config" OFF) option(WITH_OPENCL "Enable OpenCL backend" ON) +option(WITH_CUDA "Enable CUDA backend" ON) option(WITH_STRICT_CACHE "Enable strict checks for OpenCL cache" ON) option(WITH_INTERLEAVE_DEBUG_LOG "Enable debug log for threads interleave" OFF) diff --git a/src/backend/backend.cmake b/src/backend/backend.cmake index 14f0ab9c..6bf6c3b2 100644 --- a/src/backend/backend.cmake +++ b/src/backend/backend.cmake @@ -1,5 +1,6 @@ include (src/backend/cpu/cpu.cmake) include (src/backend/opencl/opencl.cmake) +include (src/backend/cuda/cuda.cmake) include (src/backend/common/common.cmake) @@ -7,10 +8,12 @@ set(HEADERS_BACKEND "${HEADERS_BACKEND_COMMON}" "${HEADERS_BACKEND_CPU}" "${HEADERS_BACKEND_OPENCL}" + "${HEADERS_BACKEND_CUDA}" ) set(SOURCES_BACKEND "${SOURCES_BACKEND_COMMON}" "${SOURCES_BACKEND_CPU}" "${SOURCES_BACKEND_OPENCL}" + "${SOURCES_BACKEND_CUDA}" ) diff --git a/src/backend/common/Tags.h b/src/backend/common/Tags.h index 16022e33..54de3760 100644 --- a/src/backend/common/Tags.h +++ b/src/backend/common/Tags.h @@ -38,6 +38,12 @@ const char *ocl_tag(); #endif +#ifdef XMRIG_FEATURE_CUDA +const char *cuda_tag(); +#endif + + + #ifdef XMRIG_ALGO_RANDOMX const char *rx_tag(); #endif diff --git a/src/backend/common/Threads.cpp b/src/backend/common/Threads.cpp index bb9e440f..f85e18f3 100644 --- a/src/backend/common/Threads.cpp +++ b/src/backend/common/Threads.cpp @@ -34,6 +34,11 @@ #endif +#ifdef XMRIG_FEATURE_CUDA +# include "backend/cuda/CudaThreads.h" +#endif + + namespace xmrig { @@ -167,4 +172,8 @@ template class Threads; template class Threads; #endif +#ifdef XMRIG_FEATURE_CUDA +template class Threads; +#endif + } // namespace xmrig diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp new file mode 100644 index 00000000..784d21eb --- /dev/null +++ b/src/backend/cuda/CudaBackend.cpp @@ -0,0 +1,217 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include + + +#include "backend/cuda/CudaBackend.h" +#include "backend/common/Hashrate.h" +#include "backend/common/interfaces/IWorker.h" +#include "backend/common/Tags.h" +#include "backend/common/Workers.h" +#include "base/io/log/Log.h" +#include "base/net/stratum/Job.h" +#include "base/tools/Chrono.h" +#include "base/tools/String.h" +#include "core/config/Config.h" +#include "core/Controller.h" +#include "rapidjson/document.h" + + +#ifdef XMRIG_FEATURE_API +# include "base/api/interfaces/IApiRequest.h" +#endif + + +namespace xmrig { + + +extern template class Threads; + + +constexpr const size_t oneMiB = 1024u * 1024u; +static const char *tag = MAGENTA_BG_BOLD(WHITE_BOLD_S " nv "); +static const String kType = "cuda"; +static std::mutex mutex; + + + +class CudaBackendPrivate +{ +public: + inline CudaBackendPrivate(Controller *controller) : + controller(controller) + { + } + + + void init(const OclConfig &cl) + { + } + + + inline void start(const Job &job) + { + } + + + Algorithm algo; + Controller *controller; + String profileName; +}; + + +} // namespace xmrig + + +const char *xmrig::cuda_tag() +{ + return tag; +} + + +xmrig::CudaBackend::CudaBackend(Controller *controller) : + d_ptr(new CudaBackendPrivate(controller)) +{ +} + + +xmrig::CudaBackend::~CudaBackend() +{ + delete d_ptr; +} + + +bool xmrig::CudaBackend::isEnabled() const +{ + return false; +} + + +bool xmrig::CudaBackend::isEnabled(const Algorithm &algorithm) const +{ + return false; +} + + +const xmrig::Hashrate *xmrig::CudaBackend::hashrate() const +{ + return nullptr; +// return d_ptr->workers.hashrate(); +} + + +const xmrig::String &xmrig::CudaBackend::profileName() const +{ + return d_ptr->profileName; +} + + +const xmrig::String &xmrig::CudaBackend::type() const +{ + return kType; +} + + +void xmrig::CudaBackend::prepare(const Job &) +{ +} + + +void xmrig::CudaBackend::printHashrate(bool details) +{ + if (!details || !hashrate()) { + return; + } + + char num[8 * 3] = { 0 }; + + Log::print(WHITE_BOLD_S "| CUDA # | AFFINITY | 10s H/s | 60s H/s | 15m H/s |"); + +// size_t i = 0; +// for (const OclLaunchData &data : d_ptr->threads) { +// Log::print("| %8zu | %8" PRId64 " | %7s | %7s | %7s |" CYAN_BOLD(" #%u") YELLOW(" %s") " %s", +// i, +// data.affinity, +// Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval), num, sizeof num / 3), +// Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval), num + 8, sizeof num / 3), +// Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3), +// data.device.index(), +// data.device.topology().toString().data(), +// data.device.printableName().data() +// ); + +// i++; +// } + + Log::print(WHITE_BOLD_S "| - | - | %7s | %7s | %7s |", + Hashrate::format(hashrate()->calc(Hashrate::ShortInterval), num, sizeof num / 3), + Hashrate::format(hashrate()->calc(Hashrate::MediumInterval), num + 8, sizeof num / 3), + Hashrate::format(hashrate()->calc(Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3) + ); +} + + +void xmrig::CudaBackend::setJob(const Job &job) +{ +} + + +void xmrig::CudaBackend::start(IWorker *worker, bool ready) +{ +} + + +void xmrig::CudaBackend::stop() +{ +} + + +void xmrig::CudaBackend::tick(uint64_t ticks) +{ +} + + +#ifdef XMRIG_FEATURE_API +rapidjson::Value xmrig::CudaBackend::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value out(kObjectType); + out.AddMember("type", type().toJSON(), allocator); + out.AddMember("enabled", isEnabled(), allocator); + out.AddMember("algo", d_ptr->algo.toJSON(), allocator); + out.AddMember("profile", profileName().toJSON(), allocator); + + return out; +} + + +void xmrig::CudaBackend::handleRequest(IApiRequest &) +{ +} +#endif diff --git a/src/backend/cuda/CudaBackend.h b/src/backend/cuda/CudaBackend.h new file mode 100644 index 00000000..0d2a2395 --- /dev/null +++ b/src/backend/cuda/CudaBackend.h @@ -0,0 +1,79 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CUDABACKEND_H +#define XMRIG_CUDABACKEND_H + + +#include + + +#include "backend/common/interfaces/IBackend.h" +#include "base/tools/Object.h" + + +namespace xmrig { + + +class Controller; +class CudaBackendPrivate; +class Miner; + + +class CudaBackend : public IBackend +{ +public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(CudaBackend) + + CudaBackend(Controller *controller); + + ~CudaBackend() override; + +protected: + bool isEnabled() const override; + bool isEnabled(const Algorithm &algorithm) const override; + const Hashrate *hashrate() const override; + const String &profileName() const override; + const String &type() const override; + void prepare(const Job &nextJob) override; + void printHashrate(bool details) override; + void setJob(const Job &job) override; + void start(IWorker *worker, bool ready) override; + void stop() override; + void tick(uint64_t ticks) override; + +# ifdef XMRIG_FEATURE_API + rapidjson::Value toJSON(rapidjson::Document &doc) const override; + void handleRequest(IApiRequest &request) override; +# endif + +private: + CudaBackendPrivate *d_ptr; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CUDABACKEND_H */ diff --git a/src/backend/cuda/CudaConfig.cpp b/src/backend/cuda/CudaConfig.cpp new file mode 100644 index 00000000..792131de --- /dev/null +++ b/src/backend/cuda/CudaConfig.cpp @@ -0,0 +1,115 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cuda/CudaConfig.h" +#include "backend/cuda/CudaConfig_gen.h" +#include "base/io/json/Json.h" +#include "base/io/log/Log.h" +#include "rapidjson/document.h" + + +namespace xmrig { + + +static const char *kDevicesHint = "devices-hint"; +static const char *kEnabled = "enabled"; + + +extern template class Threads; + + +} + + +rapidjson::Value xmrig::CudaConfig::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value obj(kObjectType); + + obj.AddMember(StringRef(kEnabled), m_enabled, allocator); + + m_threads.toJSON(obj, doc); + + return obj; +} + + +void xmrig::CudaConfig::read(const rapidjson::Value &value) +{ + if (value.IsObject()) { + m_enabled = Json::getBool(value, kEnabled, m_enabled); + + setDevicesHint(Json::getString(value, kDevicesHint)); + + m_threads.read(value); + + generate(); + } + else if (value.IsBool()) { + m_enabled = value.GetBool(); + + generate(); + } + else { + m_shouldSave = true; + + generate(); + } +} + + +void xmrig::CudaConfig::generate() +{ + if (!isEnabled() || m_threads.has("*")) { + return; + } + + size_t count = 0; + +// count += xmrig::generate(m_threads, devices); +// count += xmrig::generate(m_threads, devices); +// count += xmrig::generate(m_threads, devices); +// count += xmrig::generate(m_threads, devices); +// count += xmrig::generate(m_threads, devices); + + m_shouldSave = count > 0; +} + + +void xmrig::CudaConfig::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)); + } +} diff --git a/src/backend/cuda/CudaConfig.h b/src/backend/cuda/CudaConfig.h new file mode 100644 index 00000000..6feaa130 --- /dev/null +++ b/src/backend/cuda/CudaConfig.h @@ -0,0 +1,62 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CUDACONFIG_H +#define XMRIG_CUDACONFIG_H + + +#include "backend/common/Threads.h" +#include "backend/cuda/CudaThreads.h" + + +namespace xmrig { + + +class CudaConfig +{ +public: + CudaConfig() = default; + + rapidjson::Value toJSON(rapidjson::Document &doc) const; + void read(const rapidjson::Value &value); + + inline bool isEnabled() const { return m_enabled; } + inline bool isShouldSave() const { return m_shouldSave; } + inline const Threads &threads() const { return m_threads; } + +private: + void generate(); + void setDevicesHint(const char *devicesHint); + + bool m_enabled = false; + bool m_shouldSave = false; + std::vector m_devicesHint; + Threads m_threads; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CUDACONFIG_H */ diff --git a/src/backend/cuda/CudaConfig_gen.h b/src/backend/cuda/CudaConfig_gen.h new file mode 100644 index 00000000..757635ee --- /dev/null +++ b/src/backend/cuda/CudaConfig_gen.h @@ -0,0 +1,42 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_OCLCONFIG_GEN_H +#define XMRIG_OCLCONFIG_GEN_H + + +#include "backend/common/Threads.h" +#include "backend/cuda/CudaThreads.h" + + +#include + + +namespace xmrig { + + +} /* namespace xmrig */ + + +#endif /* XMRIG_OCLCONFIG_GEN_H */ diff --git a/src/backend/cuda/CudaThread.cpp b/src/backend/cuda/CudaThread.cpp new file mode 100644 index 00000000..9dc77c4f --- /dev/null +++ b/src/backend/cuda/CudaThread.cpp @@ -0,0 +1,63 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cuda/CudaThread.h" + +#include "base/io/json/Json.h" +#include "rapidjson/document.h" + + +#include + + +namespace xmrig { + + +} // namespace xmrig + + +xmrig::CudaThread::CudaThread(const rapidjson::Value &value) +{ + if (!value.IsObject()) { + return; + } +} + + +bool xmrig::CudaThread::isEqual(const CudaThread &other) const +{ + return false; +} + + +rapidjson::Value xmrig::CudaThread::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value out(kObjectType); + + return out; +} diff --git a/src/backend/cuda/CudaThread.h b/src/backend/cuda/CudaThread.h new file mode 100644 index 00000000..ececf3ad --- /dev/null +++ b/src/backend/cuda/CudaThread.h @@ -0,0 +1,62 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CUDATHREAD_H +#define XMRIG_CUDATHREAD_H + + +#include "crypto/common/Algorithm.h" +#include "rapidjson/fwd.h" + + +#include +#include + + +namespace xmrig { + + +class CudaThread +{ +public: + CudaThread() = delete; + + CudaThread(const rapidjson::Value &value); + + inline bool isValid() const { return false; } + + inline bool operator!=(const CudaThread &other) const { return !isEqual(other); } + inline bool operator==(const CudaThread &other) const { return isEqual(other); } + + bool isEqual(const CudaThread &other) const; + rapidjson::Value toJSON(rapidjson::Document &doc) const; + +private: +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CUDATHREAD_H */ diff --git a/src/backend/cuda/CudaThreads.cpp b/src/backend/cuda/CudaThreads.cpp new file mode 100644 index 00000000..9c8b1531 --- /dev/null +++ b/src/backend/cuda/CudaThreads.cpp @@ -0,0 +1,71 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cuda/CudaThreads.h" +#include "base/io/json/Json.h" +#include "rapidjson/document.h" + + +#include + + +xmrig::CudaThreads::CudaThreads(const rapidjson::Value &value) +{ + if (value.IsArray()) { + for (auto &v : value.GetArray()) { + CudaThread thread(v); + if (thread.isValid()) { + add(std::move(thread)); + } + } + } +} + + +bool xmrig::CudaThreads::isEqual(const CudaThreads &other) const +{ + if (isEmpty() && other.isEmpty()) { + return true; + } + + return count() == other.count() && std::equal(m_data.begin(), m_data.end(), other.m_data.begin()); +} + + +rapidjson::Value xmrig::CudaThreads::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value out(kArrayType); + + out.SetArray(); + + for (const CudaThread &thread : m_data) { + out.PushBack(thread.toJSON(doc), allocator); + } + + return out; +} diff --git a/src/backend/cuda/CudaThreads.h b/src/backend/cuda/CudaThreads.h new file mode 100644 index 00000000..3c762722 --- /dev/null +++ b/src/backend/cuda/CudaThreads.h @@ -0,0 +1,64 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CUDATHREADS_H +#define XMRIG_CUDATHREADS_H + + +#include + + +#include "backend/cuda/CudaThread.h" + + +namespace xmrig { + + +class CudaThreads +{ +public: + CudaThreads() = default; + CudaThreads(const rapidjson::Value &value); + + inline bool isEmpty() const { return m_data.empty(); } + inline const std::vector &data() const { return m_data; } + inline size_t count() const { return m_data.size(); } + inline void add(CudaThread &&thread) { m_data.push_back(thread); } + inline void reserve(size_t capacity) { m_data.reserve(capacity); } + + inline bool operator!=(const CudaThreads &other) const { return !isEqual(other); } + inline bool operator==(const CudaThreads &other) const { return isEqual(other); } + + bool isEqual(const CudaThreads &other) const; + rapidjson::Value toJSON(rapidjson::Document &doc) const; + +private: + std::vector m_data; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CUDATHREADS_H */ diff --git a/src/backend/cuda/cuda.cmake b/src/backend/cuda/cuda.cmake new file mode 100644 index 00000000..f8840c38 --- /dev/null +++ b/src/backend/cuda/cuda.cmake @@ -0,0 +1,23 @@ +if (WITH_CUDA) + add_definitions(/DXMRIG_FEATURE_CUDA) + + set(HEADERS_BACKEND_CUDA + src/backend/cuda/CudaBackend.h + src/backend/cuda/CudaConfig.h + src/backend/cuda/CudaConfig_gen.h + src/backend/cuda/CudaThread.h + src/backend/cuda/CudaThreads.h + ) + + set(SOURCES_BACKEND_CUDA + src/backend/cuda/CudaBackend.cpp + src/backend/cuda/CudaConfig.cpp + src/backend/cuda/CudaThread.cpp + src/backend/cuda/CudaThreads.cpp + ) +else() + remove_definitions(/DXMRIG_FEATURE_CUDA) + + set(HEADERS_BACKEND_CUDA "") + set(SOURCES_BACKEND_CUDA "") +endif() diff --git a/src/backend/opencl/OclBackend.h b/src/backend/opencl/OclBackend.h index ade560ba..57f5db38 100644 --- a/src/backend/opencl/OclBackend.h +++ b/src/backend/opencl/OclBackend.h @@ -30,6 +30,7 @@ #include "backend/common/interfaces/IBackend.h" +#include "base/tools/Object.h" namespace xmrig { @@ -43,16 +44,12 @@ class Miner; class OclBackend : public IBackend { public: - OclBackend() = delete; - OclBackend(const OclBackend &other) = delete; + XMRIG_DISABLE_COPY_MOVE_DEFAULT(OclBackend) + OclBackend(Controller *controller); - OclBackend(OclBackend &&other) = delete; ~OclBackend() override; - OclBackend &operator=(const OclBackend &other) = delete; - OclBackend &operator=(OclBackend &&other) = delete; - protected: bool isEnabled() const override; bool isEnabled(const Algorithm &algorithm) const override; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 49b548e9..0caf298f 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -56,6 +56,11 @@ #endif +#ifdef XMRIG_FEATURE_CUDA +# include "backend/cuda/CudaBackend.h" +#endif + + #ifdef XMRIG_ALGO_RANDOMX # include "crypto/rx/RxConfig.h" #endif @@ -270,12 +275,17 @@ xmrig::Miner::Miner(Controller *controller) d_ptr->timer = new Timer(this); + d_ptr->backends.reserve(3); d_ptr->backends.push_back(new CpuBackend(controller)); # ifdef XMRIG_FEATURE_OPENCL d_ptr->backends.push_back(new OclBackend(controller)); # endif +# ifdef XMRIG_FEATURE_CUDA + d_ptr->backends.push_back(new CudaBackend(controller)); +# endif + d_ptr->rebuild(); } diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 7ef7197f..4fd88b90 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -48,6 +48,11 @@ #endif +#ifdef XMRIG_FEATURE_CUDA +# include "backend/cuda/CudaConfig.h" +#endif + + namespace xmrig { static const char *kCPU = "cpu"; @@ -60,6 +65,10 @@ static const char *kRandomX = "randomx"; static const char *kOcl = "opencl"; #endif +#ifdef XMRIG_FEATURE_CUDA +static const char *kCuda = "cuda"; +#endif + class ConfigPrivate { @@ -73,6 +82,10 @@ public: # ifdef XMRIG_FEATURE_OPENCL OclConfig cl; # endif + +# ifdef XMRIG_FEATURE_CUDA + CudaConfig cuda; +# endif }; } @@ -104,6 +117,14 @@ const xmrig::OclConfig &xmrig::Config::cl() const #endif +#ifdef XMRIG_FEATURE_CUDA +const xmrig::CudaConfig &xmrig::Config::cuda() const +{ + return d_ptr->cuda; +} +#endif + + #ifdef XMRIG_ALGO_RANDOMX const xmrig::RxConfig &xmrig::Config::rx() const { @@ -124,6 +145,12 @@ bool xmrig::Config::isShouldSave() const } # endif +# ifdef XMRIG_FEATURE_CUDA + if (cuda().isShouldSave()) { + return true; + } +# endif + return (m_upgrade || cpu().isShouldSave()); } @@ -146,6 +173,10 @@ bool xmrig::Config::read(const IJsonReader &reader, const char *fileName) d_ptr->cl.read(reader.getValue(kOcl)); # endif +# ifdef XMRIG_FEATURE_CUDA + d_ptr->cuda.read(reader.getValue(kCuda)); +# endif + return true; } @@ -178,6 +209,10 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember(StringRef(kOcl), cl().toJSON(doc), allocator); # endif +# ifdef XMRIG_FEATURE_CUDA + doc.AddMember(StringRef(kCuda), cuda().toJSON(doc), allocator); +# endif + doc.AddMember("donate-level", m_pools.donateLevel(), allocator); doc.AddMember("donate-over-proxy", m_pools.proxyDonate(), allocator); doc.AddMember("log-file", m_logFile.toJSON(), allocator); diff --git a/src/core/config/Config.h b/src/core/config/Config.h index 22deb2c2..8becc0b8 100644 --- a/src/core/config/Config.h +++ b/src/core/config/Config.h @@ -39,9 +39,10 @@ namespace xmrig { class ConfigPrivate; +class CudaConfig; class IThread; -class RxConfig; class OclConfig; +class RxConfig; class Config : public BaseConfig @@ -58,6 +59,10 @@ public: const OclConfig &cl() const; # endif +# ifdef XMRIG_FEATURE_CUDA + const CudaConfig &cuda() const; +# endif + # ifdef XMRIG_ALGO_RANDOMX const RxConfig &rx() const; # endif From ec717f27b5c520d8d36e8d87ae85004026b8a2f9 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 25 Oct 2019 16:46:49 +0700 Subject: [PATCH 02/27] Added CudaLib stub. --- src/backend/cuda/CudaBackend.cpp | 34 ++++- src/backend/cuda/CudaConfig.cpp | 3 + src/backend/cuda/CudaConfig.h | 2 + src/backend/cuda/cuda.cmake | 4 +- src/backend/cuda/wrappers/CudaLib.cpp | 174 +++++++++++++++++++++++++ src/backend/cuda/wrappers/CudaLib.h | 72 ++++++++++ src/backend/opencl/wrappers/OclLib.cpp | 73 ++++++----- src/crypto/cn/CnAlgo.h | 2 +- 8 files changed, 326 insertions(+), 38 deletions(-) create mode 100644 src/backend/cuda/wrappers/CudaLib.cpp create mode 100644 src/backend/cuda/wrappers/CudaLib.h diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index 784d21eb..853d37e9 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -32,6 +32,9 @@ #include "backend/common/interfaces/IWorker.h" #include "backend/common/Tags.h" #include "backend/common/Workers.h" +#include "backend/cuda/CudaConfig.h" +#include "backend/cuda/CudaThreads.h" +#include "backend/cuda/wrappers/CudaLib.h" #include "base/io/log/Log.h" #include "base/net/stratum/Job.h" #include "base/tools/Chrono.h" @@ -49,7 +52,7 @@ namespace xmrig { -extern template class Threads; +extern template class Threads; constexpr const size_t oneMiB = 1024u * 1024u; @@ -59,17 +62,42 @@ static std::mutex mutex; +static void printDisabled(const char *reason) +{ + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") RED_BOLD("disabled") "%s", "CUDA", reason); +} + + + class CudaBackendPrivate { public: inline CudaBackendPrivate(Controller *controller) : controller(controller) { + init(controller->config()->cuda()); } - void init(const OclConfig &cl) + void init(const CudaConfig &cuda) { + if (!cuda.isEnabled()) { + return printDisabled(""); + } + + if (!CudaLib::init(cuda.loader())) { + return printDisabled(RED_S " (failed to load CUDA plugin)"); + } + + if (!CudaLib::runtimeVersion() || !CudaLib::driverVersion() || !CudaLib::deviceCount()) { + return printDisabled(RED_S " (no devices)"); + } + + const uint32_t runtimeVersion = CudaLib::runtimeVersion(); + const uint32_t driverVersion = CudaLib::driverVersion(); + + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%u.%u") "/" WHITE_BOLD("%u.%u") BLACK_BOLD("/%s"), "CUDA", + runtimeVersion / 1000, runtimeVersion % 100, driverVersion / 1000, driverVersion % 100, CudaLib::pluginVersion()); } @@ -102,6 +130,8 @@ xmrig::CudaBackend::CudaBackend(Controller *controller) : xmrig::CudaBackend::~CudaBackend() { delete d_ptr; + + CudaLib::close(); } diff --git a/src/backend/cuda/CudaConfig.cpp b/src/backend/cuda/CudaConfig.cpp index 792131de..ee400822 100644 --- a/src/backend/cuda/CudaConfig.cpp +++ b/src/backend/cuda/CudaConfig.cpp @@ -35,6 +35,7 @@ namespace xmrig { static const char *kDevicesHint = "devices-hint"; static const char *kEnabled = "enabled"; +static const char *kLoader = "loader"; extern template class Threads; @@ -51,6 +52,7 @@ rapidjson::Value xmrig::CudaConfig::toJSON(rapidjson::Document &doc) const Value obj(kObjectType); obj.AddMember(StringRef(kEnabled), m_enabled, allocator); + obj.AddMember(StringRef(kLoader), m_loader.toJSON(), allocator); m_threads.toJSON(obj, doc); @@ -62,6 +64,7 @@ void xmrig::CudaConfig::read(const rapidjson::Value &value) { if (value.IsObject()) { m_enabled = Json::getBool(value, kEnabled, m_enabled); + m_loader = Json::getString(value, kLoader); setDevicesHint(Json::getString(value, kDevicesHint)); diff --git a/src/backend/cuda/CudaConfig.h b/src/backend/cuda/CudaConfig.h index 6feaa130..16c06e60 100644 --- a/src/backend/cuda/CudaConfig.h +++ b/src/backend/cuda/CudaConfig.h @@ -43,6 +43,7 @@ public: 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; } private: @@ -52,6 +53,7 @@ private: bool m_enabled = false; bool m_shouldSave = false; std::vector m_devicesHint; + String m_loader; Threads m_threads; }; diff --git a/src/backend/cuda/cuda.cmake b/src/backend/cuda/cuda.cmake index f8840c38..983e18a9 100644 --- a/src/backend/cuda/cuda.cmake +++ b/src/backend/cuda/cuda.cmake @@ -3,10 +3,11 @@ if (WITH_CUDA) set(HEADERS_BACKEND_CUDA src/backend/cuda/CudaBackend.h - src/backend/cuda/CudaConfig.h src/backend/cuda/CudaConfig_gen.h + src/backend/cuda/CudaConfig.h src/backend/cuda/CudaThread.h src/backend/cuda/CudaThreads.h + src/backend/cuda/wrappers/CudaLib.h ) set(SOURCES_BACKEND_CUDA @@ -14,6 +15,7 @@ if (WITH_CUDA) src/backend/cuda/CudaConfig.cpp src/backend/cuda/CudaThread.cpp src/backend/cuda/CudaThreads.cpp + src/backend/cuda/wrappers/CudaLib.cpp ) else() remove_definitions(/DXMRIG_FEATURE_CUDA) diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp new file mode 100644 index 00000000..1d075408 --- /dev/null +++ b/src/backend/cuda/wrappers/CudaLib.cpp @@ -0,0 +1,174 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include + + +#include "backend/cuda/wrappers/CudaLib.h" +#include "base/io/log/Log.h" + + +namespace xmrig { + + +enum Version : uint32_t +{ + ApiVersion, + DriverVersion, + RuntimeVersion +}; + + +static uv_lib_t cudaLib; + + +static const char *kAlloc = "alloc"; +static const char *kDeviceCount = "deviceCount"; +static const char *kPluginVersion = "pluginVersion"; +static const char *kRelease = "release"; +static const char *kSymbolNotFound = "symbol not found"; +static const char *kVersion = "version"; + + +using alloc_t = nvid_ctx * (*)(size_t, int, int, int, int, int); +using deviceCount_t = size_t (*)(); +using pluginVersion_t = const char * (*)(); +using release_t = void (*)(nvid_ctx *); +using version_t = uint32_t (*)(Version); + + +static alloc_t pAlloc = nullptr; +static deviceCount_t pDeviceCount = nullptr; +static pluginVersion_t pPluginVersion = nullptr; +static release_t pRelease = nullptr; +static version_t pVersion = nullptr; + + +#define DLSYM(x) if (uv_dlsym(&cudaLib, k##x, reinterpret_cast(&p##x)) == -1) { throw std::runtime_error(kSymbolNotFound); } + + +bool CudaLib::m_initialized = false; +bool CudaLib::m_ready = false; +String CudaLib::m_loader; + + +} // namespace xmrig + + +bool xmrig::CudaLib::init(const char *fileName) +{ + if (!m_initialized) { + m_loader = fileName == nullptr ? defaultLoader() : fileName; + m_ready = uv_dlopen(m_loader, &cudaLib) == 0 && load(); + m_initialized = true; + } + + return m_ready; +} + + +const char *xmrig::CudaLib::lastError() +{ + return uv_dlerror(&cudaLib); +} + + +void xmrig::CudaLib::close() +{ + uv_dlclose(&cudaLib); +} + + +const char *xmrig::CudaLib::pluginVersion() noexcept +{ + return pPluginVersion(); +} + + +nvid_ctx *xmrig::CudaLib::alloc(size_t id, int blocks, int threads, int bfactor, int bsleep, const Algorithm &algorithm) noexcept +{ + return pAlloc(id, blocks, threads, bfactor, bsleep, algorithm); +} + + +size_t xmrig::CudaLib::deviceCount() noexcept +{ + return pDeviceCount(); +} + + +uint32_t xmrig::CudaLib::driverVersion() noexcept +{ + return pVersion(DriverVersion); +} + + +uint32_t xmrig::CudaLib::runtimeVersion() noexcept +{ + return pVersion(RuntimeVersion); +} + + +void xmrig::CudaLib::release(nvid_ctx *ctx) noexcept +{ + pRelease(ctx); +} + + +bool xmrig::CudaLib::load() +{ + if (uv_dlsym(&cudaLib, kVersion, reinterpret_cast(&pVersion)) == -1) { + return false; + } + + if (pVersion(ApiVersion) != 1u) { + return false; + } + + try { + DLSYM(Alloc); + DLSYM(DeviceCount); + DLSYM(PluginVersion); + DLSYM(Release); + DLSYM(Version); + } catch (std::exception &ex) { + return false; + } + + return true; +} + + +const char *xmrig::CudaLib::defaultLoader() +{ +# if defined(__APPLE__) + return "/System/Library/Frameworks/OpenCL.framework/OpenCL"; // FIXME +# elif defined(_WIN32) + return "xmrig-cuda.dll"; +# else + return "xmrig-cuda.so"; +# endif +} diff --git a/src/backend/cuda/wrappers/CudaLib.h b/src/backend/cuda/wrappers/CudaLib.h new file mode 100644 index 00000000..d82447e1 --- /dev/null +++ b/src/backend/cuda/wrappers/CudaLib.h @@ -0,0 +1,72 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CUDALIB_H +#define XMRIG_CUDALIB_H + + +#include + + +#include "base/tools/String.h" +#include "crypto/common/Algorithm.h" + + +using nvid_ctx = struct nvid_ctx; + + +namespace xmrig { + + +class CudaLib +{ +public: + static bool init(const char *fileName = nullptr); + static const char *lastError(); + static void close(); + + static inline bool isInitialized() { return m_initialized; } + static inline const String &loader() { return m_loader; } + + static const char *pluginVersion() noexcept; + static nvid_ctx *alloc(size_t id, int blocks, int threads, int bfactor, int bsleep, const Algorithm &algorithm) noexcept; + static size_t deviceCount() noexcept; + static uint32_t driverVersion() noexcept; + static uint32_t runtimeVersion() noexcept; + static void release(nvid_ctx *ctx) noexcept; + +private: + static bool load(); + static const char *defaultLoader(); + + static bool m_initialized; + static bool m_ready; + static String m_loader; +}; + + +} // namespace xmrig + + +#endif /* XMRIG_CUDALIB_H */ diff --git a/src/backend/opencl/wrappers/OclLib.cpp b/src/backend/opencl/wrappers/OclLib.cpp index 1b530bae..f156ed3d 100644 --- a/src/backend/opencl/wrappers/OclLib.cpp +++ b/src/backend/opencl/wrappers/OclLib.cpp @@ -77,6 +77,7 @@ static const char *kRetainMemObject = "clRetainMemObject"; static const char *kRetainProgram = "clRetainProgram"; static const char *kSetKernelArg = "clSetKernelArg"; static const char *kSetMemObjectDestructorCallback = "clSetMemObjectDestructorCallback"; +static const char *kSymbolNotFound = "symbol not found"; static const char *kUnloadPlatformCompiler = "clUnloadPlatformCompiler"; @@ -156,7 +157,7 @@ static setKernelArg_t pSetKernelArg = nu static setMemObjectDestructorCallback_t pSetMemObjectDestructorCallback = nullptr; static unloadPlatformCompiler_t pUnloadPlatformCompiler = nullptr; -#define DLSYM(x) if (uv_dlsym(&oclLib, k##x, reinterpret_cast(&p##x)) == -1) { return false; } +#define DLSYM(x) if (uv_dlsym(&oclLib, k##x, reinterpret_cast(&p##x)) == -1) { throw std::runtime_error(kSymbolNotFound); } namespace xmrig { @@ -210,39 +211,43 @@ void xmrig::OclLib::close() bool xmrig::OclLib::load() { - DLSYM(CreateCommandQueue); - DLSYM(CreateContext); - DLSYM(BuildProgram); - DLSYM(EnqueueNDRangeKernel); - DLSYM(EnqueueReadBuffer); - DLSYM(EnqueueWriteBuffer); - DLSYM(Finish); - DLSYM(GetDeviceIDs); - DLSYM(GetDeviceInfo); - DLSYM(GetPlatformInfo); - DLSYM(GetPlatformIDs); - DLSYM(GetProgramBuildInfo); - DLSYM(GetProgramInfo); - DLSYM(SetKernelArg); - DLSYM(CreateKernel); - DLSYM(CreateBuffer); - DLSYM(CreateProgramWithBinary); - DLSYM(CreateProgramWithSource); - DLSYM(ReleaseMemObject); - DLSYM(ReleaseProgram); - DLSYM(ReleaseKernel); - DLSYM(ReleaseCommandQueue); - DLSYM(ReleaseContext); - DLSYM(GetKernelInfo); - DLSYM(GetCommandQueueInfo); - DLSYM(GetMemObjectInfo); - DLSYM(GetContextInfo); - DLSYM(ReleaseDevice); - DLSYM(UnloadPlatformCompiler); - DLSYM(SetMemObjectDestructorCallback); - DLSYM(CreateSubBuffer); - DLSYM(RetainProgram); - DLSYM(RetainMemObject); + try { + DLSYM(CreateCommandQueue); + DLSYM(CreateContext); + DLSYM(BuildProgram); + DLSYM(EnqueueNDRangeKernel); + DLSYM(EnqueueReadBuffer); + DLSYM(EnqueueWriteBuffer); + DLSYM(Finish); + DLSYM(GetDeviceIDs); + DLSYM(GetDeviceInfo); + DLSYM(GetPlatformInfo); + DLSYM(GetPlatformIDs); + DLSYM(GetProgramBuildInfo); + DLSYM(GetProgramInfo); + DLSYM(SetKernelArg); + DLSYM(CreateKernel); + DLSYM(CreateBuffer); + DLSYM(CreateProgramWithBinary); + DLSYM(CreateProgramWithSource); + DLSYM(ReleaseMemObject); + DLSYM(ReleaseProgram); + DLSYM(ReleaseKernel); + DLSYM(ReleaseCommandQueue); + DLSYM(ReleaseContext); + DLSYM(GetKernelInfo); + DLSYM(GetCommandQueueInfo); + DLSYM(GetMemObjectInfo); + DLSYM(GetContextInfo); + DLSYM(ReleaseDevice); + DLSYM(UnloadPlatformCompiler); + DLSYM(SetMemObjectDestructorCallback); + DLSYM(CreateSubBuffer); + DLSYM(RetainProgram); + DLSYM(RetainMemObject); + } catch (std::exception &ex) { + return false; + } # if defined(CL_VERSION_2_0) uv_dlsym(&oclLib, kCreateCommandQueueWithProperties, reinterpret_cast(&pCreateCommandQueueWithProperties)); diff --git a/src/crypto/cn/CnAlgo.h b/src/crypto/cn/CnAlgo.h index 296c52b7..b6a76089 100644 --- a/src/crypto/cn/CnAlgo.h +++ b/src/crypto/cn/CnAlgo.h @@ -49,7 +49,7 @@ public: constexpr inline bool isR() const { return ALGO == Algorithm::CN_R; } constexpr inline size_t memory() const { static_assert(ALGO > Algorithm::INVALID && ALGO < Algorithm::RX_0, "invalid CRYPTONIGHT algorithm"); return CN_MEMORY; } constexpr inline uint32_t iterations() const { static_assert(ALGO > Algorithm::INVALID && ALGO < Algorithm::RX_0, "invalid CRYPTONIGHT algorithm"); return CN_ITER; } - constexpr inline uint32_t mask() const { return ((memory() - 1) / 16) * 16; } + constexpr inline uint32_t mask() const { return static_cast(((memory() - 1) / 16) * 16); } inline static size_t memory(Algorithm::Id algo) { From 77d5b73724944a06995324759c45d3dcc2a095e8 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 26 Oct 2019 00:49:59 +0700 Subject: [PATCH 03/27] Added CudaDevice class. --- src/backend/cuda/CudaBackend.cpp | 27 +++++- src/backend/cuda/cuda.cmake | 2 + src/backend/cuda/wrappers/CudaDevice.cpp | 115 +++++++++++++++++++++++ src/backend/cuda/wrappers/CudaDevice.h | 83 ++++++++++++++++ src/backend/cuda/wrappers/CudaLib.cpp | 77 ++++++++++++++- src/backend/cuda/wrappers/CudaLib.h | 33 ++++++- src/backend/opencl/OclBackend.cpp | 3 +- src/backend/opencl/wrappers/OclDevice.h | 5 +- 8 files changed, 331 insertions(+), 14 deletions(-) create mode 100644 src/backend/cuda/wrappers/CudaDevice.cpp create mode 100644 src/backend/cuda/wrappers/CudaDevice.h diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index 853d37e9..a7c315ec 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -34,6 +34,7 @@ #include "backend/common/Workers.h" #include "backend/cuda/CudaConfig.h" #include "backend/cuda/CudaThreads.h" +#include "backend/cuda/wrappers/CudaDevice.h" #include "backend/cuda/wrappers/CudaLib.h" #include "base/io/log/Log.h" #include "base/net/stratum/Job.h" @@ -89,15 +90,32 @@ public: return printDisabled(RED_S " (failed to load CUDA plugin)"); } - if (!CudaLib::runtimeVersion() || !CudaLib::driverVersion() || !CudaLib::deviceCount()) { - return printDisabled(RED_S " (no devices)"); - } - const uint32_t runtimeVersion = CudaLib::runtimeVersion(); const uint32_t driverVersion = CudaLib::driverVersion(); + if (!runtimeVersion || !driverVersion || !CudaLib::deviceCount()) { + return printDisabled(RED_S " (no devices)"); + } + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%u.%u") "/" WHITE_BOLD("%u.%u") BLACK_BOLD("/%s"), "CUDA", runtimeVersion / 1000, runtimeVersion % 100, driverVersion / 1000, driverVersion % 100, CudaLib::pluginVersion()); + + devices = CudaLib::devices(); + + for (const CudaDevice &device : devices) { + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu") YELLOW(" %s") GREEN_BOLD(" %s ") WHITE_BOLD("%u/%u MHz") " smx:" WHITE_BOLD("%u") " arch:" WHITE_BOLD("%u%u") " mem:" CYAN("%zu/%zu") " MB", + "CUDA GPU", + device.index(), + device.topology().toString().data(), + device.name().data(), + device.clock(), + device.memoryClock(), + device.smx(), + device.computeCapability(true), + device.computeCapability(false), + device.freeMemSize() / oneMiB, + device.globalMemSize() / oneMiB); + } } @@ -108,6 +126,7 @@ public: Algorithm algo; Controller *controller; + std::vector devices; String profileName; }; diff --git a/src/backend/cuda/cuda.cmake b/src/backend/cuda/cuda.cmake index 983e18a9..4cbe9c0d 100644 --- a/src/backend/cuda/cuda.cmake +++ b/src/backend/cuda/cuda.cmake @@ -7,6 +7,7 @@ if (WITH_CUDA) src/backend/cuda/CudaConfig.h src/backend/cuda/CudaThread.h src/backend/cuda/CudaThreads.h + src/backend/cuda/wrappers/CudaDevice.h src/backend/cuda/wrappers/CudaLib.h ) @@ -15,6 +16,7 @@ if (WITH_CUDA) src/backend/cuda/CudaConfig.cpp src/backend/cuda/CudaThread.cpp src/backend/cuda/CudaThreads.cpp + src/backend/cuda/wrappers/CudaDevice.cpp src/backend/cuda/wrappers/CudaLib.cpp ) else() diff --git a/src/backend/cuda/wrappers/CudaDevice.cpp b/src/backend/cuda/wrappers/CudaDevice.cpp new file mode 100644 index 00000000..03646eae --- /dev/null +++ b/src/backend/cuda/wrappers/CudaDevice.cpp @@ -0,0 +1,115 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cuda/wrappers/CudaDevice.h" +#include "backend/cuda/CudaThreads.h" +#include "backend/cuda/wrappers/CudaLib.h" +#include "base/io/log/Log.h" +#include "crypto/common/Algorithm.h" +#include "rapidjson/document.h" + + +#include + + + +xmrig::CudaDevice::CudaDevice(uint32_t index) : + m_index(index) +{ + auto ctx = CudaLib::alloc(index, 0, 0, 0, 0, Algorithm::INVALID); + if (CudaLib::deviceInfo(ctx) != 0) { + CudaLib::release(ctx); + + return; + } + + m_ctx = ctx; + m_name = CudaLib::deviceName(ctx); + m_topology = PciTopology(CudaLib::deviceUint(ctx, CudaLib::DevicePciBusID), CudaLib::deviceUint(ctx, CudaLib::DevicePciDeviceID), 0); +} + + +xmrig::CudaDevice::CudaDevice(CudaDevice &&other) noexcept : + m_index(other.m_index), + m_ctx(other.m_ctx), + m_topology(other.m_topology), + m_name(std::move(other.m_name)) +{ + other.m_ctx = nullptr; +} + + +xmrig::CudaDevice::~CudaDevice() +{ + CudaLib::release(m_ctx); +} + + +size_t xmrig::CudaDevice::freeMemSize() const +{ + return CudaLib::deviceUlong(m_ctx, CudaLib::DeviceMemoryFree); +} + + +size_t xmrig::CudaDevice::globalMemSize() const +{ + return CudaLib::deviceUlong(m_ctx, CudaLib::DeviceMemoryTotal); +} + + +uint32_t xmrig::CudaDevice::clock() const +{ + return CudaLib::deviceUint(m_ctx, CudaLib::DeviceClockRate) / 1000; +} + + +uint32_t xmrig::CudaDevice::computeCapability(bool major) const +{ + return CudaLib::deviceUint(m_ctx, major ? CudaLib::DeviceArchMajor : CudaLib::DeviceArchMinor); +} + + +uint32_t xmrig::CudaDevice::memoryClock() const +{ + return CudaLib::deviceUint(m_ctx, CudaLib::DeviceMemoryClockRate) / 1000; +} + + +uint32_t xmrig::CudaDevice::smx() const +{ + return CudaLib::deviceUint(m_ctx, CudaLib::DeviceSmx); +} + + +void xmrig::CudaDevice::generate(const Algorithm &algorithm, CudaThreads &threads) const +{ +} + + +#ifdef XMRIG_FEATURE_API +void xmrig::CudaDevice::toJSON(rapidjson::Value &out, rapidjson::Document &doc) const +{ +} +#endif diff --git a/src/backend/cuda/wrappers/CudaDevice.h b/src/backend/cuda/wrappers/CudaDevice.h new file mode 100644 index 00000000..c0df83c8 --- /dev/null +++ b/src/backend/cuda/wrappers/CudaDevice.h @@ -0,0 +1,83 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CUDADEVICE_H +#define XMRIG_CUDADEVICE_H + + +#include "backend/common/misc/PciTopology.h" +#include "base/tools/String.h" + + +using nvid_ctx = struct nvid_ctx; + + +namespace xmrig { + + +class Algorithm; +class CudaThreads; + + +class CudaDevice +{ +public: + CudaDevice() = delete; + CudaDevice(const CudaDevice &other) = delete; + CudaDevice(CudaDevice &&other) noexcept; + CudaDevice(uint32_t index); + ~CudaDevice(); + + size_t freeMemSize() const; + size_t globalMemSize() const; + uint32_t clock() const; + uint32_t computeCapability(bool major = true) const; + uint32_t memoryClock() const; + uint32_t smx() const; + void generate(const Algorithm &algorithm, CudaThreads &threads) const; + + inline bool isValid() const { return m_ctx != nullptr; } + inline const PciTopology &topology() const { return m_topology; } + inline const String &name() const { return m_name; } + inline uint32_t index() const { return m_index; } + +# ifdef XMRIG_FEATURE_API + void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const; +# endif + + CudaDevice &operator=(const CudaDevice &other) = delete; + CudaDevice &operator=(CudaDevice &&other) = delete; + +private: + const uint32_t m_index = 0; + nvid_ctx *m_ctx = nullptr; + PciTopology m_topology; + String m_name; +}; + + +} // namespace xmrig + + +#endif /* XMRIG_CUDADEVICE_H */ diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp index 1d075408..a8ca5601 100644 --- a/src/backend/cuda/wrappers/CudaLib.cpp +++ b/src/backend/cuda/wrappers/CudaLib.cpp @@ -47,14 +47,24 @@ static uv_lib_t cudaLib; static const char *kAlloc = "alloc"; static const char *kDeviceCount = "deviceCount"; +static const char *kDeviceInfo = "deviceInfo"; +static const char *kDeviceInt = "deviceInt"; +static const char *kDeviceName = "deviceName"; +static const char *kDeviceUint = "deviceUint"; +static const char *kDeviceUlong = "deviceUlong"; static const char *kPluginVersion = "pluginVersion"; static const char *kRelease = "release"; static const char *kSymbolNotFound = "symbol not found"; static const char *kVersion = "version"; -using alloc_t = nvid_ctx * (*)(size_t, int, int, int, int, int); -using deviceCount_t = size_t (*)(); +using alloc_t = nvid_ctx * (*)(size_t, int32_t, int32_t, int32_t, int32_t, int32_t); +using deviceCount_t = uint32_t (*)(); +using deviceInfo_t = int32_t (*)(nvid_ctx *); +using deviceInt_t = int32_t (*)(nvid_ctx *, CudaLib::DeviceProperty); +using deviceName_t = const char * (*)(nvid_ctx *); +using deviceUint_t = uint32_t (*)(nvid_ctx *, CudaLib::DeviceProperty); +using deviceUlong_t = uint64_t (*)(nvid_ctx *, CudaLib::DeviceProperty); using pluginVersion_t = const char * (*)(); using release_t = void (*)(nvid_ctx *); using version_t = uint32_t (*)(Version); @@ -62,6 +72,11 @@ using version_t = uint32_t (*)(Version); static alloc_t pAlloc = nullptr; static deviceCount_t pDeviceCount = nullptr; +static deviceInfo_t pDeviceInfo = nullptr; +static deviceInt_t pDeviceInt = nullptr; +static deviceName_t pDeviceName = nullptr; +static deviceUint_t pDeviceUint = nullptr; +static deviceUlong_t pDeviceUlong = nullptr; static pluginVersion_t pPluginVersion = nullptr; static release_t pRelease = nullptr; static version_t pVersion = nullptr; @@ -102,24 +117,69 @@ void xmrig::CudaLib::close() } +const char *xmrig::CudaLib::deviceName(nvid_ctx *ctx) noexcept +{ + return pDeviceName(ctx); +} + + const char *xmrig::CudaLib::pluginVersion() noexcept { return pPluginVersion(); } +int xmrig::CudaLib::deviceInfo(nvid_ctx *ctx) noexcept +{ + return pDeviceInfo(ctx); +} + + +int32_t xmrig::CudaLib::deviceInt(nvid_ctx *ctx, DeviceProperty property) noexcept +{ + return pDeviceInt(ctx, property); +} + + nvid_ctx *xmrig::CudaLib::alloc(size_t id, int blocks, int threads, int bfactor, int bsleep, const Algorithm &algorithm) noexcept { return pAlloc(id, blocks, threads, bfactor, bsleep, algorithm); } -size_t xmrig::CudaLib::deviceCount() noexcept +std::vector xmrig::CudaLib::devices() noexcept +{ + const uint32_t count = deviceCount(); + if (!count) { + return {}; + } + + std::vector out; + out.reserve(count); + + for (uint32_t i = 0; i < count; ++i) { + CudaDevice device(i); + if (device.isValid()) { + out.emplace_back(std::move(device)); + } + } + + return out; +} + + +uint32_t xmrig::CudaLib::deviceCount() noexcept { return pDeviceCount(); } +uint32_t xmrig::CudaLib::deviceUint(nvid_ctx *ctx, DeviceProperty property) noexcept +{ + return pDeviceUint(ctx, property); +} + + uint32_t xmrig::CudaLib::driverVersion() noexcept { return pVersion(DriverVersion); @@ -132,6 +192,12 @@ uint32_t xmrig::CudaLib::runtimeVersion() noexcept } +uint64_t xmrig::CudaLib::deviceUlong(nvid_ctx *ctx, DeviceProperty property) noexcept +{ + return pDeviceUlong(ctx, property); +} + + void xmrig::CudaLib::release(nvid_ctx *ctx) noexcept { pRelease(ctx); @@ -151,6 +217,11 @@ bool xmrig::CudaLib::load() try { DLSYM(Alloc); DLSYM(DeviceCount); + DLSYM(DeviceInfo); + DLSYM(DeviceInt); + DLSYM(DeviceName); + DLSYM(DeviceUint); + DLSYM(DeviceUlong); DLSYM(PluginVersion); DLSYM(Release); DLSYM(Version); diff --git a/src/backend/cuda/wrappers/CudaLib.h b/src/backend/cuda/wrappers/CudaLib.h index d82447e1..e479102b 100644 --- a/src/backend/cuda/wrappers/CudaLib.h +++ b/src/backend/cuda/wrappers/CudaLib.h @@ -26,14 +26,15 @@ #define XMRIG_CUDALIB_H -#include +using nvid_ctx = struct nvid_ctx; +#include "backend/cuda/wrappers/CudaDevice.h" #include "base/tools/String.h" #include "crypto/common/Algorithm.h" -using nvid_ctx = struct nvid_ctx; +#include namespace xmrig { @@ -42,6 +43,26 @@ namespace xmrig { class CudaLib { public: + enum DeviceProperty : uint32_t + { + DeviceId, + DeviceAlgorithm, + DeviceArchMajor, + DeviceArchMinor, + DeviceSmx, + DeviceBlocks, + DeviceThreads, + DeviceBFactor, + DeviceBSleep, + DeviceClockRate, + DeviceMemoryClockRate, + DeviceMemoryTotal, + DeviceMemoryFree, + DevicePciBusID, + DevicePciDeviceID, + DevicePciDomainID + }; + static bool init(const char *fileName = nullptr); static const char *lastError(); static void close(); @@ -49,11 +70,17 @@ public: static inline bool isInitialized() { return m_initialized; } static inline const String &loader() { return m_loader; } + static const char *deviceName(nvid_ctx *ctx) noexcept; static const char *pluginVersion() noexcept; + static int deviceInfo(nvid_ctx *ctx) noexcept; + static int32_t deviceInt(nvid_ctx *ctx, DeviceProperty property) noexcept; static nvid_ctx *alloc(size_t id, int blocks, int threads, int bfactor, int bsleep, const Algorithm &algorithm) noexcept; - static size_t deviceCount() noexcept; + static std::vector devices() noexcept; + static uint32_t deviceCount() noexcept; + static uint32_t deviceUint(nvid_ctx *ctx, DeviceProperty property) noexcept; static uint32_t driverVersion() noexcept; static uint32_t runtimeVersion() noexcept; + static uint64_t deviceUlong(nvid_ctx *ctx, DeviceProperty property) noexcept; static void release(nvid_ctx *ctx) noexcept; private: diff --git a/src/backend/opencl/OclBackend.cpp b/src/backend/opencl/OclBackend.cpp index 5b078006..e0c197d8 100644 --- a/src/backend/opencl/OclBackend.cpp +++ b/src/backend/opencl/OclBackend.cpp @@ -153,7 +153,8 @@ public: Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu ") WHITE_BOLD("%s") "/" WHITE_BOLD("%s"), "OPENCL", platform.index(), platform.name().data(), platform.version().data()); for (const OclDevice &device : devices) { - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu") YELLOW(" %s") " %s " WHITE_BOLD("%uMHz") " cu:" WHITE_BOLD("%u") " mem:" CYAN("%zu/%zu") " MB", "OPENCL GPU", + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu") YELLOW(" %s") " %s " WHITE_BOLD("%u MHz") " cu:" WHITE_BOLD("%u") " mem:" CYAN("%zu/%zu") " MB", + "OPENCL GPU", device.index(), device.topology().toString().data(), device.printableName().data(), diff --git a/src/backend/opencl/wrappers/OclDevice.h b/src/backend/opencl/wrappers/OclDevice.h index 04577d90..7d081618 100644 --- a/src/backend/opencl/wrappers/OclDevice.h +++ b/src/backend/opencl/wrappers/OclDevice.h @@ -26,14 +26,13 @@ #define XMRIG_OCLDEVICE_H -#include - - #include "backend/common/misc/PciTopology.h" #include "backend/opencl/wrappers/OclVendor.h" #include "base/tools/String.h" #include +#include + using cl_device_id = struct _cl_device_id *; using cl_platform_id = struct _cl_platform_id *; From d4a302499689036dd7b9d413bbad8a3f707d8a61 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 26 Oct 2019 03:12:55 +0700 Subject: [PATCH 04/27] Implemented CUDA config generation. --- src/backend/cuda/CudaBackend.cpp | 10 +++- src/backend/cuda/CudaConfig.cpp | 24 ++++++-- src/backend/cuda/CudaConfig.h | 14 ++++- src/backend/cuda/CudaConfig_gen.h | 76 +++++++++++++++++++++++- src/backend/cuda/CudaThread.cpp | 40 ++++++++++++- src/backend/cuda/CudaThread.h | 29 +++++++-- src/backend/cuda/CudaThreads.cpp | 8 +++ src/backend/cuda/CudaThreads.h | 2 + src/backend/cuda/wrappers/CudaDevice.cpp | 12 ++-- src/backend/cuda/wrappers/CudaDevice.h | 2 +- src/backend/cuda/wrappers/CudaLib.cpp | 16 ++--- src/backend/cuda/wrappers/CudaLib.h | 6 +- src/backend/opencl/OclBackend.cpp | 2 +- src/backend/opencl/OclConfig.cpp | 5 +- src/backend/opencl/OclConfig.h | 2 +- src/backend/opencl/OclThreads.cpp | 2 +- 16 files changed, 208 insertions(+), 42 deletions(-) diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index a7c315ec..1a4f9294 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -97,10 +97,14 @@ public: return printDisabled(RED_S " (no devices)"); } + if (!devices.empty()) { + return; + } + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%u.%u") "/" WHITE_BOLD("%u.%u") BLACK_BOLD("/%s"), "CUDA", runtimeVersion / 1000, runtimeVersion % 100, driverVersion / 1000, driverVersion % 100, CudaLib::pluginVersion()); - devices = CudaLib::devices(); + devices = CudaLib::devices(cuda.bfactor(), cuda.bsleep()); for (const CudaDevice &device : devices) { Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu") YELLOW(" %s") GREEN_BOLD(" %s ") WHITE_BOLD("%u/%u MHz") " smx:" WHITE_BOLD("%u") " arch:" WHITE_BOLD("%u%u") " mem:" CYAN("%zu/%zu") " MB", @@ -156,13 +160,13 @@ xmrig::CudaBackend::~CudaBackend() bool xmrig::CudaBackend::isEnabled() const { - return false; + return d_ptr->controller->config()->cuda().isEnabled() && CudaLib::isInitialized() && !d_ptr->devices.empty();; } bool xmrig::CudaBackend::isEnabled(const Algorithm &algorithm) const { - return false; + return !d_ptr->controller->config()->cuda().threads().get(algorithm).isEmpty(); } diff --git a/src/backend/cuda/CudaConfig.cpp b/src/backend/cuda/CudaConfig.cpp index ee400822..084fb702 100644 --- a/src/backend/cuda/CudaConfig.cpp +++ b/src/backend/cuda/CudaConfig.cpp @@ -25,6 +25,7 @@ #include "backend/cuda/CudaConfig.h" #include "backend/cuda/CudaConfig_gen.h" +#include "backend/cuda/wrappers/CudaLib.h" #include "base/io/json/Json.h" #include "base/io/log/Log.h" #include "rapidjson/document.h" @@ -91,13 +92,26 @@ void xmrig::CudaConfig::generate() return; } + if (!CudaLib::init(loader())) { + return; + } + + if (!CudaLib::runtimeVersion() || !CudaLib::driverVersion() || !CudaLib::deviceCount()) { + return; + } + + const auto devices = CudaLib::devices(bfactor(), bsleep()); + if (devices.empty()) { + return; + } + size_t count = 0; -// count += xmrig::generate(m_threads, devices); -// count += xmrig::generate(m_threads, devices); -// count += xmrig::generate(m_threads, devices); -// count += xmrig::generate(m_threads, devices); -// count += xmrig::generate(m_threads, devices); + count += xmrig::generate(m_threads, devices); + count += xmrig::generate(m_threads, devices); + count += xmrig::generate(m_threads, devices); + count += xmrig::generate(m_threads, devices); + count += xmrig::generate(m_threads, devices); m_shouldSave = count > 0; } diff --git a/src/backend/cuda/CudaConfig.h b/src/backend/cuda/CudaConfig.h index 16c06e60..5c392d2c 100644 --- a/src/backend/cuda/CudaConfig.h +++ b/src/backend/cuda/CudaConfig.h @@ -45,16 +45,26 @@ public: 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; } private: void generate(); void setDevicesHint(const char *devicesHint); - bool m_enabled = false; - bool m_shouldSave = false; + bool m_enabled = false; + bool m_shouldSave = false; std::vector m_devicesHint; String m_loader; Threads m_threads; + +# ifdef _WIN32 + int32_t m_bfactor = 6; + int32_t m_bsleep = 25; +# else + int32_t m_bfactor = 0; + int32_t m_bsleep = 0; +# endif }; diff --git a/src/backend/cuda/CudaConfig_gen.h b/src/backend/cuda/CudaConfig_gen.h index 757635ee..d7c913f5 100644 --- a/src/backend/cuda/CudaConfig_gen.h +++ b/src/backend/cuda/CudaConfig_gen.h @@ -22,12 +22,13 @@ * along with this program. If not, see . */ -#ifndef XMRIG_OCLCONFIG_GEN_H -#define XMRIG_OCLCONFIG_GEN_H +#ifndef XMRIG_CUDACONFIG_GEN_H +#define XMRIG_CUDACONFIG_GEN_H #include "backend/common/Threads.h" #include "backend/cuda/CudaThreads.h" +#include "backend/cuda/wrappers/CudaDevice.h" #include @@ -36,7 +37,76 @@ namespace xmrig { +static inline size_t generate(const char *key, Threads &threads, const Algorithm &algorithm, const std::vector &devices) +{ + if (threads.isExist(algorithm) || threads.has(key)) { + return 0; + } + + return threads.move(key, CudaThreads(devices, algorithm)); +} + + +template +static inline size_t generate(Threads &, const std::vector &) { return 0; } + + +template<> +size_t inline generate(Threads &threads, const std::vector &devices) +{ + size_t count = 0; + + count += generate("cn", threads, Algorithm::CN_1, devices); + count += generate("cn/2", threads, Algorithm::CN_2, devices); + + if (!threads.isExist(Algorithm::CN_0)) { + threads.disable(Algorithm::CN_0); + count++; + } + +# ifdef XMRIG_ALGO_CN_GPU + count += generate("cn/gpu", threads, Algorithm::CN_GPU, devices); +# endif + + return count; +} + + +#ifdef XMRIG_ALGO_CN_LITE +template<> +size_t inline generate(Threads &threads, const std::vector &devices) +{ + size_t count = generate("cn-lite", threads, Algorithm::CN_LITE_1, devices); + + if (!threads.isExist(Algorithm::CN_LITE_0)) { + threads.disable(Algorithm::CN_LITE_0); + ++count; + } + + return count; +} +#endif + + +#ifdef XMRIG_ALGO_CN_HEAVY +template<> +size_t inline generate(Threads &threads, const std::vector &devices) +{ + return generate("cn-heavy", threads, Algorithm::CN_HEAVY_0, devices); +} +#endif + + +#ifdef XMRIG_ALGO_CN_PICO +template<> +size_t inline generate(Threads &threads, const std::vector &devices) +{ + return generate("cn-pico", threads, Algorithm::CN_PICO_0, devices); +} +#endif + + } /* namespace xmrig */ -#endif /* XMRIG_OCLCONFIG_GEN_H */ +#endif /* XMRIG_CUDACONFIG_GEN_H */ diff --git a/src/backend/cuda/CudaThread.cpp b/src/backend/cuda/CudaThread.cpp index 9dc77c4f..3100b662 100644 --- a/src/backend/cuda/CudaThread.cpp +++ b/src/backend/cuda/CudaThread.cpp @@ -24,7 +24,7 @@ #include "backend/cuda/CudaThread.h" - +#include "backend/cuda/wrappers/CudaLib.h" #include "base/io/json/Json.h" #include "rapidjson/document.h" @@ -34,6 +34,12 @@ namespace xmrig { +static const char *kAffinity = "affinity"; +static const char *kBFactor = "bfactor"; +static const char *kBlocks = "blocks"; +static const char *kBSleep = "bsleep"; +static const char *kIndex = "index"; +static const char *kThreads = "threads"; } // namespace xmrig @@ -43,12 +49,35 @@ xmrig::CudaThread::CudaThread(const rapidjson::Value &value) if (!value.IsObject()) { return; } + + m_index = Json::getUint(value, kIndex); + m_threads = Json::getInt(value, kThreads); + m_blocks = Json::getInt(value, kBlocks); + m_bfactor = std::min(Json::getUint(value, kBFactor, m_bfactor), 12u); + m_bsleep = Json::getUint(value, kBSleep, m_bsleep); + m_affinity = Json::getUint64(value, kAffinity, m_affinity); +} + + +xmrig::CudaThread::CudaThread(uint32_t index, nvid_ctx *ctx) : + m_blocks(CudaLib::deviceInt(ctx, CudaLib::DeviceBlocks)), + m_threads(CudaLib::deviceInt(ctx, CudaLib::DeviceThreads)), + m_index(index), + m_bfactor(CudaLib::deviceUint(ctx, CudaLib::DeviceBFactor)), + m_bsleep(CudaLib::deviceUint(ctx, CudaLib::DeviceBSleep)) +{ + } bool xmrig::CudaThread::isEqual(const CudaThread &other) const { - return false; + return m_blocks == other.m_blocks && + m_threads == other.m_threads && + m_affinity == other.m_affinity && + m_index == other.m_index && + m_bfactor == other.m_bfactor && + m_bsleep == other.m_bsleep; } @@ -59,5 +88,12 @@ rapidjson::Value xmrig::CudaThread::toJSON(rapidjson::Document &doc) const Value out(kObjectType); + out.AddMember(StringRef(kIndex), index(), allocator); + out.AddMember(StringRef(kThreads), threads(), allocator); + out.AddMember(StringRef(kBlocks), blocks(), allocator); + out.AddMember(StringRef(kBFactor), bfactor(), allocator); + out.AddMember(StringRef(kBSleep), bsleep(), allocator); + out.AddMember(StringRef(kAffinity), affinity(), allocator); + return out; } diff --git a/src/backend/cuda/CudaThread.h b/src/backend/cuda/CudaThread.h index ececf3ad..f6523d95 100644 --- a/src/backend/cuda/CudaThread.h +++ b/src/backend/cuda/CudaThread.h @@ -26,14 +26,13 @@ #define XMRIG_CUDATHREAD_H +using nvid_ctx = struct nvid_ctx; + + #include "crypto/common/Algorithm.h" #include "rapidjson/fwd.h" -#include -#include - - namespace xmrig { @@ -41,10 +40,16 @@ class CudaThread { public: CudaThread() = delete; - CudaThread(const rapidjson::Value &value); + CudaThread(uint32_t index, nvid_ctx *ctx); - inline bool isValid() const { return false; } + inline bool isValid() const { return m_blocks > 0 && m_threads > 0; } + inline int32_t bfactor() const { return static_cast(m_bfactor); } + inline int32_t blocks() const { return m_blocks; } + inline int32_t bsleep() const { return static_cast(m_bsleep); } + inline int32_t threads() const { return m_threads; } + inline int64_t affinity() const { return m_affinity; } + inline uint32_t index() const { return m_index; } inline bool operator!=(const CudaThread &other) const { return !isEqual(other); } inline bool operator==(const CudaThread &other) const { return isEqual(other); } @@ -53,6 +58,18 @@ public: rapidjson::Value toJSON(rapidjson::Document &doc) const; private: + int32_t m_blocks = 0; + int32_t m_threads = 0; + int64_t m_affinity = -1; + uint32_t m_index = 0; + +# ifdef _WIN32 + uint32_t m_bfactor = 6; + uint32_t m_bsleep = 25; +# else + uint32_t m_bfactor = 0; + uint32_t m_bsleep = 0; +# endif }; diff --git a/src/backend/cuda/CudaThreads.cpp b/src/backend/cuda/CudaThreads.cpp index 9c8b1531..5ff4cb24 100644 --- a/src/backend/cuda/CudaThreads.cpp +++ b/src/backend/cuda/CudaThreads.cpp @@ -44,6 +44,14 @@ xmrig::CudaThreads::CudaThreads(const rapidjson::Value &value) } +xmrig::CudaThreads::CudaThreads(const std::vector &devices, const Algorithm &algorithm) +{ + for (const auto &device : devices) { + device.generate(algorithm, *this); + } +} + + bool xmrig::CudaThreads::isEqual(const CudaThreads &other) const { if (isEmpty() && other.isEmpty()) { diff --git a/src/backend/cuda/CudaThreads.h b/src/backend/cuda/CudaThreads.h index 3c762722..5f174d8e 100644 --- a/src/backend/cuda/CudaThreads.h +++ b/src/backend/cuda/CudaThreads.h @@ -30,6 +30,7 @@ #include "backend/cuda/CudaThread.h" +#include "backend/cuda/wrappers/CudaDevice.h" namespace xmrig { @@ -40,6 +41,7 @@ class CudaThreads public: CudaThreads() = default; CudaThreads(const rapidjson::Value &value); + CudaThreads(const std::vector &devices, const Algorithm &algorithm); inline bool isEmpty() const { return m_data.empty(); } inline const std::vector &data() const { return m_data; } diff --git a/src/backend/cuda/wrappers/CudaDevice.cpp b/src/backend/cuda/wrappers/CudaDevice.cpp index 03646eae..7eb947fc 100644 --- a/src/backend/cuda/wrappers/CudaDevice.cpp +++ b/src/backend/cuda/wrappers/CudaDevice.cpp @@ -34,12 +34,11 @@ #include - -xmrig::CudaDevice::CudaDevice(uint32_t index) : +xmrig::CudaDevice::CudaDevice(uint32_t index, int32_t bfactor, int32_t bsleep) : m_index(index) { - auto ctx = CudaLib::alloc(index, 0, 0, 0, 0, Algorithm::INVALID); - if (CudaLib::deviceInfo(ctx) != 0) { + auto ctx = CudaLib::alloc(index, bfactor, bsleep); + if (CudaLib::deviceInfo(ctx, 0, 0, Algorithm::INVALID) != 0) { CudaLib::release(ctx); return; @@ -105,6 +104,11 @@ uint32_t xmrig::CudaDevice::smx() const void xmrig::CudaDevice::generate(const Algorithm &algorithm, CudaThreads &threads) const { + if (CudaLib::deviceInfo(m_ctx, -1, -1, algorithm) != 0) { + return; + } + + threads.add(CudaThread(m_index, m_ctx)); } diff --git a/src/backend/cuda/wrappers/CudaDevice.h b/src/backend/cuda/wrappers/CudaDevice.h index c0df83c8..40b8ee11 100644 --- a/src/backend/cuda/wrappers/CudaDevice.h +++ b/src/backend/cuda/wrappers/CudaDevice.h @@ -46,7 +46,7 @@ public: CudaDevice() = delete; CudaDevice(const CudaDevice &other) = delete; CudaDevice(CudaDevice &&other) noexcept; - CudaDevice(uint32_t index); + CudaDevice(uint32_t index, int32_t bfactor, int32_t bsleep); ~CudaDevice(); size_t freeMemSize() const; diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp index a8ca5601..58ce66bb 100644 --- a/src/backend/cuda/wrappers/CudaLib.cpp +++ b/src/backend/cuda/wrappers/CudaLib.cpp @@ -58,9 +58,9 @@ static const char *kSymbolNotFound = "symbol not found"; static const char *kVersion = "version"; -using alloc_t = nvid_ctx * (*)(size_t, int32_t, int32_t, int32_t, int32_t, int32_t); +using alloc_t = nvid_ctx * (*)(uint32_t, int32_t, int32_t); using deviceCount_t = uint32_t (*)(); -using deviceInfo_t = int32_t (*)(nvid_ctx *); +using deviceInfo_t = int32_t (*)(nvid_ctx *, int32_t, int32_t, int32_t); using deviceInt_t = int32_t (*)(nvid_ctx *, CudaLib::DeviceProperty); using deviceName_t = const char * (*)(nvid_ctx *); using deviceUint_t = uint32_t (*)(nvid_ctx *, CudaLib::DeviceProperty); @@ -129,9 +129,9 @@ const char *xmrig::CudaLib::pluginVersion() noexcept } -int xmrig::CudaLib::deviceInfo(nvid_ctx *ctx) noexcept +int xmrig::CudaLib::deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads, const Algorithm &algorithm) noexcept { - return pDeviceInfo(ctx); + return pDeviceInfo(ctx, blocks, threads, algorithm); } @@ -141,13 +141,13 @@ int32_t xmrig::CudaLib::deviceInt(nvid_ctx *ctx, DeviceProperty property) noexce } -nvid_ctx *xmrig::CudaLib::alloc(size_t id, int blocks, int threads, int bfactor, int bsleep, const Algorithm &algorithm) noexcept +nvid_ctx *xmrig::CudaLib::alloc(uint32_t id, int32_t bfactor, int32_t bsleep) noexcept { - return pAlloc(id, blocks, threads, bfactor, bsleep, algorithm); + return pAlloc(id, bfactor, bsleep); } -std::vector xmrig::CudaLib::devices() noexcept +std::vector xmrig::CudaLib::devices(int32_t bfactor, int32_t bsleep) noexcept { const uint32_t count = deviceCount(); if (!count) { @@ -158,7 +158,7 @@ std::vector xmrig::CudaLib::devices() noexcept out.reserve(count); for (uint32_t i = 0; i < count; ++i) { - CudaDevice device(i); + 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 e479102b..253a15a4 100644 --- a/src/backend/cuda/wrappers/CudaLib.h +++ b/src/backend/cuda/wrappers/CudaLib.h @@ -72,10 +72,10 @@ public: static const char *deviceName(nvid_ctx *ctx) noexcept; static const char *pluginVersion() noexcept; - static int deviceInfo(nvid_ctx *ctx) noexcept; + static int deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads, const Algorithm &algorithm) noexcept; static int32_t deviceInt(nvid_ctx *ctx, DeviceProperty property) noexcept; - static nvid_ctx *alloc(size_t id, int blocks, int threads, int bfactor, int bsleep, const Algorithm &algorithm) noexcept; - static std::vector devices() noexcept; + static nvid_ctx *alloc(uint32_t id, int32_t bfactor, int32_t bsleep) noexcept; + static std::vector devices(int32_t bfactor, int32_t bsleep) 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/backend/opencl/OclBackend.cpp b/src/backend/opencl/OclBackend.cpp index e0c197d8..91c1eb6c 100644 --- a/src/backend/opencl/OclBackend.cpp +++ b/src/backend/opencl/OclBackend.cpp @@ -319,7 +319,7 @@ void xmrig::OclBackend::setJob(const Job &job) return stop(); } - std::vector threads = cl.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->platform, d_ptr->devices, tag); + std::vector threads = cl.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->platform, d_ptr->devices); if (!d_ptr->threads.empty() && d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) { return; } diff --git a/src/backend/opencl/OclConfig.cpp b/src/backend/opencl/OclConfig.cpp index 71a669d6..21cccabf 100644 --- a/src/backend/opencl/OclConfig.cpp +++ b/src/backend/opencl/OclConfig.cpp @@ -24,6 +24,7 @@ #include "backend/opencl/OclConfig.h" +#include "backend/common/Tags.h" #include "backend/opencl/OclConfig_gen.h" #include "backend/opencl/wrappers/OclLib.h" #include "base/io/json/Json.h" @@ -113,7 +114,7 @@ rapidjson::Value xmrig::OclConfig::toJSON(rapidjson::Document &doc) const } -std::vector xmrig::OclConfig::get(const Miner *miner, const Algorithm &algorithm, const OclPlatform &platform, const std::vector &devices, const char *tag) const +std::vector xmrig::OclConfig::get(const Miner *miner, const Algorithm &algorithm, const OclPlatform &platform, const std::vector &devices) const { std::vector out; const OclThreads &threads = m_threads.get(algorithm); @@ -126,7 +127,7 @@ std::vector xmrig::OclConfig::get(const Miner *miner, cons for (const OclThread &thread : threads.data()) { if (thread.index() >= devices.size()) { - LOG_INFO("%s" YELLOW(" skip non-existing device with index ") YELLOW_BOLD("%u"), tag, thread.index()); + LOG_INFO("%s" YELLOW(" skip non-existing device with index ") YELLOW_BOLD("%u"), ocl_tag(), thread.index()); continue; } diff --git a/src/backend/opencl/OclConfig.h b/src/backend/opencl/OclConfig.h index 9dd5ad1d..8e2db042 100644 --- a/src/backend/opencl/OclConfig.h +++ b/src/backend/opencl/OclConfig.h @@ -42,7 +42,7 @@ public: OclPlatform platform() const; rapidjson::Value toJSON(rapidjson::Document &doc) const; - std::vector get(const Miner *miner, const Algorithm &algorithm, const OclPlatform &platform, const std::vector &devices, const char *tag) const; + std::vector get(const Miner *miner, const Algorithm &algorithm, const OclPlatform &platform, const std::vector &devices) const; void read(const rapidjson::Value &value); inline bool isCacheEnabled() const { return m_cache; } diff --git a/src/backend/opencl/OclThreads.cpp b/src/backend/opencl/OclThreads.cpp index 167ccfc0..3e53a5f5 100644 --- a/src/backend/opencl/OclThreads.cpp +++ b/src/backend/opencl/OclThreads.cpp @@ -46,7 +46,7 @@ xmrig::OclThreads::OclThreads(const rapidjson::Value &value) xmrig::OclThreads::OclThreads(const std::vector &devices, const Algorithm &algorithm) { - for (const OclDevice &device : devices) { + for (const auto &device : devices) { device.generate(algorithm, *this); } } From bb2cc0deb796d2a7f52ee871be143a7385ce0537 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 26 Oct 2019 17:37:54 +0700 Subject: [PATCH 05/27] Added CudaWorker and CudaLaunchData. --- src/backend/common/Workers.cpp | 17 +++ src/backend/common/Workers.h | 12 ++ src/backend/cuda/CudaBackend.cpp | 164 +++++++++++++++++++++++++--- src/backend/cuda/CudaConfig.cpp | 25 +++++ src/backend/cuda/CudaConfig.h | 2 + src/backend/cuda/CudaLaunchData.cpp | 50 +++++++++ src/backend/cuda/CudaLaunchData.h | 66 +++++++++++ src/backend/cuda/CudaWorker.cpp | 164 ++++++++++++++++++++++++++++ src/backend/cuda/CudaWorker.h | 70 ++++++++++++ src/backend/cuda/cuda.cmake | 4 + src/backend/opencl/OclBackend.cpp | 6 +- src/backend/opencl/OclConfig.cpp | 4 +- src/backend/opencl/OclWorker.h | 9 +- src/base/io/log/Log.h | 2 + 14 files changed, 567 insertions(+), 28 deletions(-) create mode 100644 src/backend/cuda/CudaLaunchData.cpp create mode 100644 src/backend/cuda/CudaLaunchData.h create mode 100644 src/backend/cuda/CudaWorker.cpp create mode 100644 src/backend/cuda/CudaWorker.h diff --git a/src/backend/common/Workers.cpp b/src/backend/common/Workers.cpp index 9fb6859e..319f2804 100644 --- a/src/backend/common/Workers.cpp +++ b/src/backend/common/Workers.cpp @@ -37,6 +37,11 @@ #endif +#ifdef XMRIG_FEATURE_CUDA +# include "backend/cuda/CudaWorker.h" +#endif + + namespace xmrig { @@ -217,4 +222,16 @@ template class Workers; #endif +#ifdef XMRIG_FEATURE_CUDA +template<> +xmrig::IWorker *xmrig::Workers::create(Thread *handle) +{ + return new CudaWorker(handle->id(), handle->config()); +} + + +template class Workers; +#endif + + } // namespace xmrig diff --git a/src/backend/common/Workers.h b/src/backend/common/Workers.h index 2688a1e3..637a33c9 100644 --- a/src/backend/common/Workers.h +++ b/src/backend/common/Workers.h @@ -37,6 +37,11 @@ #endif +#ifdef XMRIG_FEATURE_CUDA +# include "backend/cuda/CudaLaunchData.h" +#endif + + namespace xmrig { @@ -80,6 +85,13 @@ extern template class Workers; #endif +#ifdef XMRIG_FEATURE_CUDA +template<> +IWorker *Workers::create(Thread *handle); +extern template class Workers; +#endif + + } // namespace xmrig diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index 1a4f9294..9043299c 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -34,6 +34,7 @@ #include "backend/common/Workers.h" #include "backend/cuda/CudaConfig.h" #include "backend/cuda/CudaThreads.h" +#include "backend/cuda/CudaWorker.h" #include "backend/cuda/wrappers/CudaDevice.h" #include "backend/cuda/wrappers/CudaLib.h" #include "base/io/log/Log.h" @@ -57,7 +58,7 @@ extern template class Threads; constexpr const size_t oneMiB = 1024u * 1024u; -static const char *tag = MAGENTA_BG_BOLD(WHITE_BOLD_S " nv "); +static const char *tag = GREEN_BG_BOLD(WHITE_BOLD_S " nv "); static const String kType = "cuda"; static std::mutex mutex; @@ -69,6 +70,51 @@ static void printDisabled(const char *reason) } +struct CudaLaunchStatus +{ +public: + inline size_t threads() const { return m_threads; } + + inline bool started(bool ready) + { + ready ? m_started++ : m_errors++; + + return (m_started + m_errors) == m_threads; + } + + inline void start(size_t threads) + { + m_started = 0; + m_errors = 0; + m_threads = threads; + m_ts = Chrono::steadyMSecs(); + CudaWorker::ready = false; + } + + inline void print() const + { + if (m_started == 0) { + LOG_ERR("%s " RED_BOLD("disabled") YELLOW(" (failed to start threads)"), tag); + + return; + } + + LOG_INFO("%s" GREEN_BOLD(" READY") " threads " "%s%zu/%zu" BLACK_BOLD(" (%" PRIu64 " ms)"), + tag, + m_errors == 0 ? CYAN_BOLD_S : YELLOW_BOLD_S, + m_started, + m_threads, + Chrono::steadyMSecs() - m_ts + ); + } + +private: + size_t m_errors = 0; + size_t m_started = 0; + size_t m_threads = 0; + uint64_t m_ts = 0; +}; + class CudaBackendPrivate { @@ -125,13 +171,46 @@ public: inline void start(const Job &job) { + LOG_INFO("%s use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), + tag, + profileName.data(), + threads.size(), + algo.l3() / 1024 + ); + + Log::print(WHITE_BOLD("| # | GPU | BUS ID | I | T | B | BF | BS | MEM | NAME")); + + size_t i = 0; + for (const auto &data : threads) { + Log::print("|" CYAN_BOLD("%3zu") " |" CYAN_BOLD("%4u") " |" YELLOW(" %7s") " |" CYAN_BOLD("%5d") " |" CYAN_BOLD("%4d") " |" + CYAN_BOLD("%4d") " |" CYAN_BOLD("%3d") " |" CYAN_BOLD("%4d") " |" CYAN("%5zu") " | " GREEN("%s"), + i, + data.thread.index(), + data.device.topology().toString().data(), + data.thread.threads() * data.thread.blocks(), + data.thread.threads(), + data.thread.blocks(), + data.thread.bfactor(), + data.thread.bsleep(), + (data.thread.threads() * data.thread.blocks()) * algo.l3() / oneMiB, + data.device.name().data() + ); + + i++; + } + + status.start(threads.size()); + workers.start(threads); } Algorithm algo; Controller *controller; + CudaLaunchStatus status; std::vector devices; + std::vector threads; String profileName; + Workers workers; }; @@ -147,6 +226,7 @@ const char *xmrig::cuda_tag() xmrig::CudaBackend::CudaBackend(Controller *controller) : d_ptr(new CudaBackendPrivate(controller)) { + d_ptr->workers.setBackend(this); } @@ -172,8 +252,7 @@ bool xmrig::CudaBackend::isEnabled(const Algorithm &algorithm) const const xmrig::Hashrate *xmrig::CudaBackend::hashrate() const { - return nullptr; -// return d_ptr->workers.hashrate(); + return d_ptr->workers.hashrate(); } @@ -204,21 +283,21 @@ void xmrig::CudaBackend::printHashrate(bool details) Log::print(WHITE_BOLD_S "| CUDA # | AFFINITY | 10s H/s | 60s H/s | 15m H/s |"); -// size_t i = 0; -// for (const OclLaunchData &data : d_ptr->threads) { -// Log::print("| %8zu | %8" PRId64 " | %7s | %7s | %7s |" CYAN_BOLD(" #%u") YELLOW(" %s") " %s", -// i, -// data.affinity, -// Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval), num, sizeof num / 3), -// Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval), num + 8, sizeof num / 3), -// Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3), -// data.device.index(), -// data.device.topology().toString().data(), -// data.device.printableName().data() -// ); + size_t i = 0; + for (const auto &data : d_ptr->threads) { + Log::print("| %8zu | %8" PRId64 " | %7s | %7s | %7s |" CYAN_BOLD(" #%u") YELLOW(" %s") " %s", + i, + data.thread.affinity(), + Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval), num, sizeof num / 3), + Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval), num + 8, sizeof num / 3), + Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3), + data.device.index(), + data.device.topology().toString().data(), + data.device.name().data() + ); -// i++; -// } + i++; + } Log::print(WHITE_BOLD_S "| - | - | %7s | %7s | %7s |", Hashrate::format(hashrate()->calc(Hashrate::ShortInterval), num, sizeof num / 3), @@ -230,21 +309,72 @@ void xmrig::CudaBackend::printHashrate(bool details) void xmrig::CudaBackend::setJob(const Job &job) { + const auto &cuda = d_ptr->controller->config()->cuda(); + if (cuda.isEnabled()) { + d_ptr->init(cuda); + } + + if (!isEnabled()) { + return stop(); + } + + auto threads = cuda.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->devices); + if (!d_ptr->threads.empty() && d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) { + return; + } + + d_ptr->algo = job.algorithm(); + d_ptr->profileName = cuda.threads().profileName(job.algorithm()); + + if (d_ptr->profileName.isNull() || threads.empty()) { + LOG_WARN("%s " RED_BOLD("disabled") YELLOW(" (no suitable configuration found)"), tag); + + return stop(); + } + + stop(); + + d_ptr->threads = std::move(threads); + d_ptr->start(job); } void xmrig::CudaBackend::start(IWorker *worker, bool ready) { + mutex.lock(); + + if (d_ptr->status.started(ready)) { + d_ptr->status.print(); + + CudaWorker::ready = true; + } + + mutex.unlock(); + + if (ready) { + worker->start(); + } } void xmrig::CudaBackend::stop() { + if (d_ptr->threads.empty()) { + return; + } + + const uint64_t ts = Chrono::steadyMSecs(); + + d_ptr->workers.stop(); + d_ptr->threads.clear(); + + LOG_INFO("%s" YELLOW(" stopped") BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts); } void xmrig::CudaBackend::tick(uint64_t ticks) { + d_ptr->workers.tick(ticks); } diff --git a/src/backend/cuda/CudaConfig.cpp b/src/backend/cuda/CudaConfig.cpp index 084fb702..67cee3a2 100644 --- a/src/backend/cuda/CudaConfig.cpp +++ b/src/backend/cuda/CudaConfig.cpp @@ -24,6 +24,7 @@ #include "backend/cuda/CudaConfig.h" +#include "backend/common/Tags.h" #include "backend/cuda/CudaConfig_gen.h" #include "backend/cuda/wrappers/CudaLib.h" #include "base/io/json/Json.h" @@ -61,6 +62,30 @@ 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 +{ + std::vector out; + const auto &threads = m_threads.get(algorithm); + + if (threads.isEmpty()) { + return out; + } + + out.reserve(threads.count() * 2); + + for (const auto &thread : threads.data()) { + if (thread.index() >= devices.size()) { + 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()]); + } + + return out; +} + + void xmrig::CudaConfig::read(const rapidjson::Value &value) { if (value.IsObject()) { diff --git a/src/backend/cuda/CudaConfig.h b/src/backend/cuda/CudaConfig.h index 5c392d2c..4367d826 100644 --- a/src/backend/cuda/CudaConfig.h +++ b/src/backend/cuda/CudaConfig.h @@ -26,6 +26,7 @@ #define XMRIG_CUDACONFIG_H +#include "backend/cuda/CudaLaunchData.h" #include "backend/common/Threads.h" #include "backend/cuda/CudaThreads.h" @@ -39,6 +40,7 @@ public: CudaConfig() = default; rapidjson::Value toJSON(rapidjson::Document &doc) const; + 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; } diff --git a/src/backend/cuda/CudaLaunchData.cpp b/src/backend/cuda/CudaLaunchData.cpp new file mode 100644 index 00000000..b19c42e7 --- /dev/null +++ b/src/backend/cuda/CudaLaunchData.cpp @@ -0,0 +1,50 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cuda/CudaLaunchData.h" +#include "backend/common/Tags.h" + + +xmrig::CudaLaunchData::CudaLaunchData(const Miner *miner, const Algorithm &algorithm, const CudaThread &thread, const CudaDevice &device) : + algorithm(algorithm), + miner(miner), + device(device), + thread(thread) +{ +} + + +bool xmrig::CudaLaunchData::isEqual(const CudaLaunchData &other) const +{ + return (other.algorithm == algorithm && + other.thread == thread); +} + + +const char *xmrig::CudaLaunchData::tag() +{ + return cuda_tag(); +} diff --git a/src/backend/cuda/CudaLaunchData.h b/src/backend/cuda/CudaLaunchData.h new file mode 100644 index 00000000..33173ffb --- /dev/null +++ b/src/backend/cuda/CudaLaunchData.h @@ -0,0 +1,66 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CUDALAUNCHDATA_H +#define XMRIG_CUDALAUNCHDATA_H + + +#include "backend/cuda/CudaThread.h" +#include "crypto/common/Algorithm.h" +#include "crypto/common/Nonce.h" + + +namespace xmrig { + + +class CudaDevice; +class Miner; + + +class CudaLaunchData +{ +public: + CudaLaunchData(const Miner *miner, const Algorithm &algorithm, const CudaThread &thread, const CudaDevice &device); + + bool isEqual(const CudaLaunchData &other) const; + + inline constexpr static Nonce::Backend backend() { return Nonce::CUDA; } + + inline bool operator!=(const CudaLaunchData &other) const { return !isEqual(other); } + inline bool operator==(const CudaLaunchData &other) const { return isEqual(other); } + + static const char *tag(); + + const Algorithm algorithm; + const Miner *miner; + const CudaDevice &device; + const CudaThread thread; +}; + + +} // namespace xmrig + + +#endif /* XMRIG_OCLLAUNCHDATA_H */ diff --git a/src/backend/cuda/CudaWorker.cpp b/src/backend/cuda/CudaWorker.cpp new file mode 100644 index 00000000..98765fb3 --- /dev/null +++ b/src/backend/cuda/CudaWorker.cpp @@ -0,0 +1,164 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cuda/CudaWorker.h" +#include "backend/common/Tags.h" +#include "base/io/log/Log.h" +#include "base/tools/Chrono.h" +#include "core/Miner.h" +#include "crypto/common/Nonce.h" +#include "net/JobResults.h" + + +#include +#include + + +namespace xmrig { + + +static constexpr uint32_t kReserveCount = 32768; +std::atomic CudaWorker::ready; + + +static inline bool isReady() { return !Nonce::isPaused() && CudaWorker::ready; } +static inline uint32_t roundSize(uint32_t intensity) { return kReserveCount / intensity + 1; } + + +static inline void printError(size_t id, const char *error) +{ + LOG_ERR("%s" RED_S " thread " RED_BOLD("#%zu") RED_S " failed with error " RED_BOLD("%s"), cuda_tag(), id, error); +} + + +} // namespace xmrig + + + +xmrig::CudaWorker::CudaWorker(size_t id, const CudaLaunchData &data) : + Worker(id, data.thread.affinity(), -1), + m_algorithm(data.algorithm), + m_miner(data.miner), + m_intensity(data.thread.threads() * data.thread.blocks()) +{ +} + + +xmrig::CudaWorker::~CudaWorker() +{ +// delete m_runner; +} + + +bool xmrig::CudaWorker::selfTest() +{ + return false; // FIXME +} + + +size_t xmrig::CudaWorker::intensity() const +{ + return 0; // FIXME; +// return m_runner ? m_runner->intensity() : 0; +} + + +void xmrig::CudaWorker::start() +{ + while (Nonce::sequence(Nonce::CUDA) > 0) { + if (!isReady()) { + do { + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + while (!isReady() && Nonce::sequence(Nonce::CUDA) > 0); + + if (Nonce::sequence(Nonce::CUDA) == 0) { + break; + } + + if (!consumeJob()) { + return; + } + } + + while (!Nonce::isOutdated(Nonce::CUDA, m_job.sequence())) { +// try { +// m_runner->run(*m_job.nonce(), results); +// } +// catch (std::exception &ex) { +// printError(id(), ex.what()); + +// return; +// } + +// if (results[0xFF] > 0) { +// JobResults::submit(m_job.currentJob(), results, results[0xFF]); +// } + + m_job.nextRound(roundSize(m_intensity), m_intensity); + + storeStats(); + std::this_thread::yield(); + } + + if (!consumeJob()) { + return; + } + } +} + + +bool xmrig::CudaWorker::consumeJob() +{ + if (Nonce::sequence(Nonce::CUDA) == 0) { + return false; + } + + m_job.add(m_miner->job(), Nonce::sequence(Nonce::CUDA), roundSize(m_intensity) * m_intensity); + +// try { +// m_runner->set(m_job.currentJob(), m_job.blob()); +// } +// catch (std::exception &ex) { +// printError(id(), ex.what()); + +// return false; +// } + + return true; +} + + +void xmrig::CudaWorker::storeStats() +{ + if (!isReady()) { + return; + } + + m_count += m_intensity; + + Worker::storeStats(); +} diff --git a/src/backend/cuda/CudaWorker.h b/src/backend/cuda/CudaWorker.h new file mode 100644 index 00000000..0ba71e86 --- /dev/null +++ b/src/backend/cuda/CudaWorker.h @@ -0,0 +1,70 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CUDAWORKER_H +#define XMRIG_CUDAWORKER_H + + +#include "backend/common/Worker.h" +#include "backend/common/WorkerJob.h" +#include "backend/cuda/CudaLaunchData.h" +#include "base/tools/Object.h" +#include "net/JobResult.h" + + +namespace xmrig { + + +class CudaWorker : public Worker +{ +public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(CudaWorker) + + CudaWorker(size_t id, const CudaLaunchData &data); + + ~CudaWorker() override; + + static std::atomic ready; + +protected: + bool selfTest() override; + size_t intensity() const override; + void start() override; + +private: + bool consumeJob(); + void storeStats(); + + const Algorithm m_algorithm; + const Miner *m_miner; + const uint32_t m_intensity; + WorkerJob<1> m_job; +}; + + +} // namespace xmrig + + +#endif /* XMRIG_CUDAWORKER_H */ diff --git a/src/backend/cuda/cuda.cmake b/src/backend/cuda/cuda.cmake index 4cbe9c0d..93348964 100644 --- a/src/backend/cuda/cuda.cmake +++ b/src/backend/cuda/cuda.cmake @@ -5,8 +5,10 @@ if (WITH_CUDA) src/backend/cuda/CudaBackend.h src/backend/cuda/CudaConfig_gen.h src/backend/cuda/CudaConfig.h + src/backend/cuda/CudaLaunchData.h src/backend/cuda/CudaThread.h src/backend/cuda/CudaThreads.h + src/backend/cuda/CudaWorker.h src/backend/cuda/wrappers/CudaDevice.h src/backend/cuda/wrappers/CudaLib.h ) @@ -14,8 +16,10 @@ if (WITH_CUDA) set(SOURCES_BACKEND_CUDA src/backend/cuda/CudaBackend.cpp src/backend/cuda/CudaConfig.cpp + src/backend/cuda/CudaLaunchData.cpp src/backend/cuda/CudaThread.cpp src/backend/cuda/CudaThreads.cpp + src/backend/cuda/CudaWorker.cpp src/backend/cuda/wrappers/CudaDevice.cpp src/backend/cuda/wrappers/CudaLib.cpp ) diff --git a/src/backend/opencl/OclBackend.cpp b/src/backend/opencl/OclBackend.cpp index 91c1eb6c..8aadc926 100644 --- a/src/backend/opencl/OclBackend.cpp +++ b/src/backend/opencl/OclBackend.cpp @@ -285,7 +285,7 @@ void xmrig::OclBackend::printHashrate(bool details) Log::print(WHITE_BOLD_S "| OPENCL # | AFFINITY | 10s H/s | 60s H/s | 15m H/s |"); size_t i = 0; - for (const OclLaunchData &data : d_ptr->threads) { + for (const auto &data : d_ptr->threads) { Log::print("| %8zu | %8" PRId64 " | %7s | %7s | %7s |" CYAN_BOLD(" #%u") YELLOW(" %s") " %s", i, data.affinity, @@ -310,7 +310,7 @@ void xmrig::OclBackend::printHashrate(bool details) void xmrig::OclBackend::setJob(const Job &job) { - const OclConfig &cl = d_ptr->controller->config()->cl(); + const auto &cl = d_ptr->controller->config()->cl(); if (cl.isEnabled()) { d_ptr->init(cl); } @@ -319,7 +319,7 @@ void xmrig::OclBackend::setJob(const Job &job) return stop(); } - std::vector threads = cl.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->platform, d_ptr->devices); + auto threads = cl.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->platform, d_ptr->devices); if (!d_ptr->threads.empty() && d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) { return; } diff --git a/src/backend/opencl/OclConfig.cpp b/src/backend/opencl/OclConfig.cpp index 21cccabf..ec01adaf 100644 --- a/src/backend/opencl/OclConfig.cpp +++ b/src/backend/opencl/OclConfig.cpp @@ -117,7 +117,7 @@ rapidjson::Value xmrig::OclConfig::toJSON(rapidjson::Document &doc) const std::vector xmrig::OclConfig::get(const Miner *miner, const Algorithm &algorithm, const OclPlatform &platform, const std::vector &devices) const { std::vector out; - const OclThreads &threads = m_threads.get(algorithm); + const auto &threads = m_threads.get(algorithm); if (threads.isEmpty()) { return out; @@ -125,7 +125,7 @@ std::vector xmrig::OclConfig::get(const Miner *miner, cons out.reserve(threads.count() * 2); - for (const OclThread &thread : threads.data()) { + for (const auto &thread : threads.data()) { if (thread.index() >= devices.size()) { LOG_INFO("%s" YELLOW(" skip non-existing device with index ") YELLOW_BOLD("%u"), ocl_tag(), thread.index()); continue; diff --git a/src/backend/opencl/OclWorker.h b/src/backend/opencl/OclWorker.h index 76cb63db..01803f70 100644 --- a/src/backend/opencl/OclWorker.h +++ b/src/backend/opencl/OclWorker.h @@ -30,6 +30,7 @@ #include "backend/common/Worker.h" #include "backend/common/WorkerJob.h" #include "backend/opencl/OclLaunchData.h" +#include "base/tools/Object.h" #include "net/JobResult.h" @@ -42,16 +43,12 @@ class IOclRunner; class OclWorker : public Worker { public: - OclWorker() = delete; - OclWorker(const OclWorker &other) = delete; - OclWorker(OclWorker &&other) = delete; + XMRIG_DISABLE_COPY_MOVE_DEFAULT(OclWorker) + OclWorker(size_t id, const OclLaunchData &data); ~OclWorker() override; - OclWorker &operator=(const OclWorker &other) = delete; - OclWorker &operator=(OclWorker &&other) = delete; - static std::atomic ready; protected: diff --git a/src/base/io/log/Log.h b/src/base/io/log/Log.h index 3517b61d..cfd3c3a3 100644 --- a/src/base/io/log/Log.h +++ b/src/base/io/log/Log.h @@ -82,6 +82,7 @@ private: #define WHITE_S CSI "0;37m" // another name for LT.GRAY #define WHITE_BOLD_S CSI "1;37m" // actually white +#define GREEN_BG_BOLD_S CSI "42;1m" #define BLUE_BG_S CSI "44m" #define BLUE_BG_BOLD_S CSI "44;1m" #define MAGENTA_BG_S CSI "45m" @@ -107,6 +108,7 @@ private: #define WHITE(x) WHITE_S x CLEAR #define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR +#define GREEN_BG_BOLD(x) GREEN_BG_BOLD_S x CLEAR #define BLUE_BG(x) BLUE_BG_S x CLEAR #define BLUE_BG_BOLD(x) BLUE_BG_BOLD_S x CLEAR #define MAGENTA_BG(x) MAGENTA_BG_S x CLEAR From 7cb9b923479862e862844289599cbeb49413ba97 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Sat, 26 Oct 2019 13:32:30 +0200 Subject: [PATCH 06/27] Fix VS2019 compilation --- src/base/net/stratum/Pool.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index eb2fe506..59b70b11 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "base/net/stratum/Pool.h" From c9f7cbae09744278e03c909e51afbd06c93046f9 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 27 Oct 2019 17:53:00 +0700 Subject: [PATCH 07/27] Implemented cryptonight mining. --- src/backend/cuda/CudaLaunchData.cpp | 5 +- src/backend/cuda/CudaWorker.cpp | 60 +++++++++------- src/backend/cuda/CudaWorker.h | 4 ++ src/backend/cuda/cuda.cmake | 7 ++ src/backend/cuda/interfaces/ICudaRunner.h | 71 ++++++++++++++++++ src/backend/cuda/runners/CudaBaseRunner.cpp | 76 ++++++++++++++++++++ src/backend/cuda/runners/CudaBaseRunner.h | 66 +++++++++++++++++ src/backend/cuda/runners/CudaCnRunner.cpp | 38 ++++++++++ src/backend/cuda/runners/CudaCnRunner.h | 48 +++++++++++++ src/backend/cuda/runners/CudaRxRunner.cpp | 42 +++++++++++ src/backend/cuda/runners/CudaRxRunner.h | 53 ++++++++++++++ src/backend/cuda/wrappers/CudaLib.cpp | 36 ++++++++++ src/backend/cuda/wrappers/CudaLib.h | 3 + src/backend/opencl/runners/OclBaseRunner.cpp | 2 +- src/backend/opencl/runners/OclBaseRunner.h | 4 +- 15 files changed, 486 insertions(+), 29 deletions(-) create mode 100644 src/backend/cuda/interfaces/ICudaRunner.h create mode 100644 src/backend/cuda/runners/CudaBaseRunner.cpp create mode 100644 src/backend/cuda/runners/CudaBaseRunner.h create mode 100644 src/backend/cuda/runners/CudaCnRunner.cpp create mode 100644 src/backend/cuda/runners/CudaCnRunner.h create mode 100644 src/backend/cuda/runners/CudaRxRunner.cpp create mode 100644 src/backend/cuda/runners/CudaRxRunner.h diff --git a/src/backend/cuda/CudaLaunchData.cpp b/src/backend/cuda/CudaLaunchData.cpp index b19c42e7..11cf70c8 100644 --- a/src/backend/cuda/CudaLaunchData.cpp +++ b/src/backend/cuda/CudaLaunchData.cpp @@ -39,8 +39,9 @@ xmrig::CudaLaunchData::CudaLaunchData(const Miner *miner, const Algorithm &algor bool xmrig::CudaLaunchData::isEqual(const CudaLaunchData &other) const { - return (other.algorithm == algorithm && - other.thread == thread); + return (other.algorithm.family() == algorithm.family() && + other.algorithm.l3() == algorithm.l3() && + other.thread == thread); } diff --git a/src/backend/cuda/CudaWorker.cpp b/src/backend/cuda/CudaWorker.cpp index 98765fb3..1f262574 100644 --- a/src/backend/cuda/CudaWorker.cpp +++ b/src/backend/cuda/CudaWorker.cpp @@ -26,6 +26,7 @@ #include "backend/cuda/CudaWorker.h" #include "backend/common/Tags.h" +#include "backend/cuda/runners/CudaCnRunner.h" #include "base/io/log/Log.h" #include "base/tools/Chrono.h" #include "core/Miner.h" @@ -33,6 +34,11 @@ #include "net/JobResults.h" +#ifdef XMRIG_ALGO_RANDOMX +# include "backend/cuda/runners/CudaRxRunner.h" +#endif + + #include #include @@ -64,25 +70,42 @@ xmrig::CudaWorker::CudaWorker(size_t id, const CudaLaunchData &data) : m_miner(data.miner), m_intensity(data.thread.threads() * data.thread.blocks()) { + switch (m_algorithm.family()) { + case Algorithm::RANDOM_X: +# ifdef XMRIG_ALGO_RANDOMX + m_runner = new CudaRxRunner(id, data); +# endif + break; + + case Algorithm::ARGON2: + break; + + default: + m_runner = new CudaCnRunner(id, data); + break; + } + + if (!m_runner || !m_runner->init()) { + return; + } } xmrig::CudaWorker::~CudaWorker() { -// delete m_runner; + delete m_runner; } bool xmrig::CudaWorker::selfTest() { - return false; // FIXME + return m_runner != nullptr; } size_t xmrig::CudaWorker::intensity() const { - return 0; // FIXME; -// return m_runner ? m_runner->intensity() : 0; + return m_runner ? m_runner->intensity() : 0; } @@ -105,18 +128,16 @@ void xmrig::CudaWorker::start() } while (!Nonce::isOutdated(Nonce::CUDA, m_job.sequence())) { -// try { -// m_runner->run(*m_job.nonce(), results); -// } -// catch (std::exception &ex) { -// printError(id(), ex.what()); + uint32_t foundNonce[10] = { 0 }; + uint32_t foundCount = 0; -// return; -// } + if (!m_runner->run(*m_job.nonce(), &foundCount, foundNonce)) { + return; + } -// if (results[0xFF] > 0) { -// JobResults::submit(m_job.currentJob(), results, results[0xFF]); -// } + if (foundCount) { + JobResults::submit(m_job.currentJob(), foundNonce, foundCount); + } m_job.nextRound(roundSize(m_intensity), m_intensity); @@ -139,16 +160,7 @@ bool xmrig::CudaWorker::consumeJob() m_job.add(m_miner->job(), Nonce::sequence(Nonce::CUDA), roundSize(m_intensity) * m_intensity); -// try { -// m_runner->set(m_job.currentJob(), m_job.blob()); -// } -// catch (std::exception &ex) { -// printError(id(), ex.what()); - -// return false; -// } - - return true; + return m_runner->set(m_job.currentJob(), m_job.blob());; } diff --git a/src/backend/cuda/CudaWorker.h b/src/backend/cuda/CudaWorker.h index 0ba71e86..4fb006ba 100644 --- a/src/backend/cuda/CudaWorker.h +++ b/src/backend/cuda/CudaWorker.h @@ -37,6 +37,9 @@ namespace xmrig { +class ICudaRunner; + + class CudaWorker : public Worker { public: @@ -60,6 +63,7 @@ private: const Algorithm m_algorithm; const Miner *m_miner; const uint32_t m_intensity; + ICudaRunner *m_runner = nullptr; WorkerJob<1> m_job; }; diff --git a/src/backend/cuda/cuda.cmake b/src/backend/cuda/cuda.cmake index 93348964..764acd0f 100644 --- a/src/backend/cuda/cuda.cmake +++ b/src/backend/cuda/cuda.cmake @@ -9,6 +9,10 @@ if (WITH_CUDA) src/backend/cuda/CudaThread.h src/backend/cuda/CudaThreads.h src/backend/cuda/CudaWorker.h + src/backend/cuda/interfaces/ICudaRunner.h + src/backend/cuda/runners/CudaBaseRunner.h + src/backend/cuda/runners/CudaCnRunner.h + src/backend/cuda/runners/CudaRxRunner.h src/backend/cuda/wrappers/CudaDevice.h src/backend/cuda/wrappers/CudaLib.h ) @@ -20,6 +24,9 @@ if (WITH_CUDA) src/backend/cuda/CudaThread.cpp src/backend/cuda/CudaThreads.cpp src/backend/cuda/CudaWorker.cpp + src/backend/cuda/runners/CudaBaseRunner.cpp + src/backend/cuda/runners/CudaCnRunner.cpp + src/backend/cuda/runners/CudaRxRunner.cpp src/backend/cuda/wrappers/CudaDevice.cpp src/backend/cuda/wrappers/CudaLib.cpp ) diff --git a/src/backend/cuda/interfaces/ICudaRunner.h b/src/backend/cuda/interfaces/ICudaRunner.h new file mode 100644 index 00000000..b5772c89 --- /dev/null +++ b/src/backend/cuda/interfaces/ICudaRunner.h @@ -0,0 +1,71 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_ICUDARUNNER_H +#define XMRIG_ICUDARUNNER_H + + +#include "base/tools/Object.h" + + +#include + + +namespace xmrig { + + +class Job; + + +class ICudaRunner +{ +public: + XMRIG_DISABLE_COPY_MOVE(ICudaRunner) + + ICudaRunner() = default; + virtual ~ICudaRunner() = default; + +// virtual cl_context ctx() const = 0; +// virtual const Algorithm &algorithm() const = 0; +// virtual const char *buildOptions() const = 0; +// virtual const char *deviceKey() const = 0; +// virtual const char *source() const = 0; +// virtual const OclLaunchData &data() const = 0; + virtual size_t intensity() const = 0; +// virtual size_t threadId() const = 0; +// virtual uint32_t deviceIndex() const = 0; +// virtual void build() = 0; + virtual bool init() = 0; + virtual bool run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce) = 0; + virtual bool set(const Job &job, uint8_t *blob) = 0; + +protected: +// virtual size_t bufferSize() const = 0; +}; + + +} /* namespace xmrig */ + + +#endif // XMRIG_ICUDARUNNER_H diff --git a/src/backend/cuda/runners/CudaBaseRunner.cpp b/src/backend/cuda/runners/CudaBaseRunner.cpp new file mode 100644 index 00000000..9428b16c --- /dev/null +++ b/src/backend/cuda/runners/CudaBaseRunner.cpp @@ -0,0 +1,76 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cuda/runners/CudaBaseRunner.h" +#include "backend/cuda/wrappers/CudaLib.h" +#include "backend/cuda/CudaLaunchData.h" +//#include "backend/opencl/cl/OclSource.h" +//#include "backend/opencl/OclCache.h" +//#include "backend/opencl/OclLaunchData.h" +//#include "backend/opencl/runners/tools/OclSharedState.h" +//#include "backend/opencl/wrappers/OclError.h" +//#include "backend/opencl/wrappers/OclLib.h" +#include "base/io/log/Log.h" +#include "base/net/stratum/Job.h" +//#include "crypto/common/VirtualMemory.h" + + +xmrig::CudaBaseRunner::CudaBaseRunner(size_t id, const CudaLaunchData &data) : + m_data(data), + m_threadId(id) +{ +} + + +xmrig::CudaBaseRunner::~CudaBaseRunner() +{ + CudaLib::release(m_ctx); +} + + +bool xmrig::CudaBaseRunner::init() +{ + m_ctx = CudaLib::alloc(m_data.thread.index(), m_data.thread.bfactor(), m_data.thread.bsleep()); + if (CudaLib::deviceInfo(m_ctx, m_data.thread.blocks(), m_data.thread.threads(), m_data.algorithm) != 0) { + return false; + } + + return CudaLib::deviceInit(m_ctx); +} + + +bool xmrig::CudaBaseRunner::set(const Job &job, uint8_t *blob) +{ + m_height = job.height(); + m_target = job.target(); + + return CudaLib::setJob(m_ctx, blob, job.size(), job.algorithm()); +} + + +size_t xmrig::CudaBaseRunner::intensity() const +{ + return m_data.thread.threads() * m_data.thread.blocks(); +} diff --git a/src/backend/cuda/runners/CudaBaseRunner.h b/src/backend/cuda/runners/CudaBaseRunner.h new file mode 100644 index 00000000..7bdc7bea --- /dev/null +++ b/src/backend/cuda/runners/CudaBaseRunner.h @@ -0,0 +1,66 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CUDABASERUNNER_H +#define XMRIG_CUDABASERUNNER_H + + +#include "backend/cuda/interfaces/ICudaRunner.h" + + +using nvid_ctx = struct nvid_ctx; + + +namespace xmrig { + + +class CudaLaunchData; + + +class CudaBaseRunner : public ICudaRunner +{ +public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(CudaBaseRunner) + + CudaBaseRunner(size_t id, const CudaLaunchData &data); + ~CudaBaseRunner() override; + +protected: + bool init() override; + bool set(const Job &job, uint8_t *blob) override; + size_t intensity() const override; + +protected: + const CudaLaunchData &m_data; + const size_t m_threadId; + nvid_ctx *m_ctx = nullptr; + uint64_t m_height = 0; + uint64_t m_target = 0; +}; + + +} /* namespace xmrig */ + + +#endif // XMRIG_CUDABASERUNNER_H diff --git a/src/backend/cuda/runners/CudaCnRunner.cpp b/src/backend/cuda/runners/CudaCnRunner.cpp new file mode 100644 index 00000000..f75f0995 --- /dev/null +++ b/src/backend/cuda/runners/CudaCnRunner.cpp @@ -0,0 +1,38 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cuda/runners/CudaCnRunner.h" +#include "backend/cuda/wrappers/CudaLib.h" + + +xmrig::CudaCnRunner::CudaCnRunner(size_t index, const CudaLaunchData &data) : CudaBaseRunner(index, data) +{ +} + + +bool xmrig::CudaCnRunner::run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce) +{ + return CudaLib::cnHash(m_ctx, startNonce, m_height, m_target, rescount, resnonce); +} diff --git a/src/backend/cuda/runners/CudaCnRunner.h b/src/backend/cuda/runners/CudaCnRunner.h new file mode 100644 index 00000000..e563435b --- /dev/null +++ b/src/backend/cuda/runners/CudaCnRunner.h @@ -0,0 +1,48 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CUDACNRUNNER_H +#define XMRIG_CUDACNRUNNER_H + + +#include "backend/cuda/runners/CudaBaseRunner.h" + + +namespace xmrig { + + +class CudaCnRunner : public CudaBaseRunner +{ +public: + CudaCnRunner(size_t index, const CudaLaunchData &data); + +protected: + bool run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce) override; +}; + + +} /* namespace xmrig */ + + +#endif // XMRIG_CUDACNRUNNER_H diff --git a/src/backend/cuda/runners/CudaRxRunner.cpp b/src/backend/cuda/runners/CudaRxRunner.cpp new file mode 100644 index 00000000..92b2d9f9 --- /dev/null +++ b/src/backend/cuda/runners/CudaRxRunner.cpp @@ -0,0 +1,42 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cuda/runners/CudaRxRunner.h" + + +xmrig::CudaRxRunner::CudaRxRunner(size_t index, const CudaLaunchData &data) : CudaBaseRunner(index, data) +{ +} + + +xmrig::CudaRxRunner::~CudaRxRunner() +{ +} + + +bool xmrig::CudaRxRunner::run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce) +{ + return false; +} diff --git a/src/backend/cuda/runners/CudaRxRunner.h b/src/backend/cuda/runners/CudaRxRunner.h new file mode 100644 index 00000000..8aba75f5 --- /dev/null +++ b/src/backend/cuda/runners/CudaRxRunner.h @@ -0,0 +1,53 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CUDARXRUNNER_H +#define XMRIG_CUDARXRUNNER_H + + +#include "backend/cuda/runners/CudaBaseRunner.h" + + +namespace xmrig { + + +class CudaRxRunner : public CudaBaseRunner +{ +public: + XMRIG_DISABLE_COPY_MOVE_DEFAULT(CudaRxRunner) + + CudaRxRunner(size_t index, const CudaLaunchData &data); + ~CudaRxRunner() override; + +protected: + bool run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce) override; + +private: +}; + + +} /* namespace xmrig */ + + +#endif // XMRIG_CUDARXRUNNER_H diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp index 58ce66bb..d0c720ee 100644 --- a/src/backend/cuda/wrappers/CudaLib.cpp +++ b/src/backend/cuda/wrappers/CudaLib.cpp @@ -46,39 +46,51 @@ static uv_lib_t cudaLib; static const char *kAlloc = "alloc"; +static const char *kCnHash = "cnHash"; static const char *kDeviceCount = "deviceCount"; static const char *kDeviceInfo = "deviceInfo"; +static const char *kDeviceInit = "deviceInit"; static const char *kDeviceInt = "deviceInt"; static const char *kDeviceName = "deviceName"; static const char *kDeviceUint = "deviceUint"; static const char *kDeviceUlong = "deviceUlong"; +static const char *kInit = "init"; static const char *kPluginVersion = "pluginVersion"; static const char *kRelease = "release"; +static const char *kSetJob = "setJob"; static const char *kSymbolNotFound = "symbol not found"; static const char *kVersion = "version"; using alloc_t = nvid_ctx * (*)(uint32_t, int32_t, int32_t); +using cnHash_t = bool (*)(nvid_ctx *, uint32_t, uint64_t, uint64_t, uint32_t *, uint32_t *); using deviceCount_t = uint32_t (*)(); using deviceInfo_t = int32_t (*)(nvid_ctx *, int32_t, int32_t, int32_t); +using deviceInit_t = bool (*)(nvid_ctx *); using deviceInt_t = int32_t (*)(nvid_ctx *, CudaLib::DeviceProperty); using deviceName_t = const char * (*)(nvid_ctx *); using deviceUint_t = uint32_t (*)(nvid_ctx *, CudaLib::DeviceProperty); using deviceUlong_t = uint64_t (*)(nvid_ctx *, CudaLib::DeviceProperty); +using init_t = void (*)(); using pluginVersion_t = const char * (*)(); using release_t = void (*)(nvid_ctx *); +using setJob_t = bool (*)(nvid_ctx *, const void *, size_t, int32_t); using version_t = uint32_t (*)(Version); static alloc_t pAlloc = nullptr; +static cnHash_t pCnHash = nullptr; static deviceCount_t pDeviceCount = nullptr; static deviceInfo_t pDeviceInfo = nullptr; +static deviceInit_t pDeviceInit = nullptr; static deviceInt_t pDeviceInt = nullptr; static deviceName_t pDeviceName = nullptr; static deviceUint_t pDeviceUint = nullptr; static deviceUlong_t pDeviceUlong = nullptr; +static init_t pInit = nullptr; static pluginVersion_t pPluginVersion = nullptr; static release_t pRelease = nullptr; +static setJob_t pSetJob = nullptr; static version_t pVersion = nullptr; @@ -117,6 +129,24 @@ void xmrig::CudaLib::close() } +bool xmrig::CudaLib::cnHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t height, uint64_t target, uint32_t *rescount, uint32_t *resnonce) +{ + return pCnHash(ctx, startNonce, height, target, rescount, resnonce); +} + + +bool xmrig::CudaLib::deviceInit(nvid_ctx *ctx) noexcept +{ + return pDeviceInit(ctx); +} + + +bool xmrig::CudaLib::setJob(nvid_ctx *ctx, const void *data, size_t size, const Algorithm &algorithm) noexcept +{ + return pSetJob(ctx, data, size, algorithm); +} + + const char *xmrig::CudaLib::deviceName(nvid_ctx *ctx) noexcept { return pDeviceName(ctx); @@ -216,19 +246,25 @@ bool xmrig::CudaLib::load() try { DLSYM(Alloc); + DLSYM(CnHash); DLSYM(DeviceCount); DLSYM(DeviceInfo); + DLSYM(DeviceInit); DLSYM(DeviceInt); DLSYM(DeviceName); DLSYM(DeviceUint); DLSYM(DeviceUlong); + DLSYM(Init); DLSYM(PluginVersion); DLSYM(Release); + DLSYM(SetJob); DLSYM(Version); } catch (std::exception &ex) { return false; } + pInit(); + return true; } diff --git a/src/backend/cuda/wrappers/CudaLib.h b/src/backend/cuda/wrappers/CudaLib.h index 253a15a4..5aafeaea 100644 --- a/src/backend/cuda/wrappers/CudaLib.h +++ b/src/backend/cuda/wrappers/CudaLib.h @@ -70,6 +70,9 @@ public: static inline bool isInitialized() { return m_initialized; } static inline const String &loader() { return m_loader; } + static bool cnHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t height, uint64_t target, uint32_t *rescount, uint32_t *resnonce); + static bool deviceInit(nvid_ctx *ctx) noexcept; + static bool setJob(nvid_ctx *ctx, const void *data, size_t size, const Algorithm &algorithm) noexcept; static const char *deviceName(nvid_ctx *ctx) noexcept; static const char *pluginVersion() noexcept; static int deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads, const Algorithm &algorithm) noexcept; diff --git a/src/backend/opencl/runners/OclBaseRunner.cpp b/src/backend/opencl/runners/OclBaseRunner.cpp index d8497e94..2e75d9b6 100644 --- a/src/backend/opencl/runners/OclBaseRunner.cpp +++ b/src/backend/opencl/runners/OclBaseRunner.cpp @@ -39,8 +39,8 @@ constexpr size_t oneGiB = 1024 * 1024 * 1024; xmrig::OclBaseRunner::OclBaseRunner(size_t id, const OclLaunchData &data) : - m_algorithm(data.algorithm), m_ctx(data.ctx), + m_algorithm(data.algorithm), m_source(OclSource::get(data.algorithm)), m_data(data), m_align(OclLib::getUint(data.device.id(), CL_DEVICE_MEM_BASE_ADDR_ALIGN)), diff --git a/src/backend/opencl/runners/OclBaseRunner.h b/src/backend/opencl/runners/OclBaseRunner.h index 558d6807..6abbb2b7 100644 --- a/src/backend/opencl/runners/OclBaseRunner.h +++ b/src/backend/opencl/runners/OclBaseRunner.h @@ -70,21 +70,21 @@ protected: void enqueueWriteBuffer(cl_mem buffer, cl_bool blocking_write, size_t offset, size_t size, const void *ptr); void finalize(uint32_t *hashOutput); - Algorithm m_algorithm; cl_command_queue m_queue = nullptr; cl_context m_ctx; cl_mem m_buffer = nullptr; cl_mem m_input = nullptr; cl_mem m_output = nullptr; cl_program m_program = nullptr; + const Algorithm m_algorithm; const char *m_source; const OclLaunchData &m_data; const size_t m_align; const size_t m_threadId; + const uint32_t m_intensity; size_t m_offset = 0; std::string m_deviceKey; std::string m_options; - uint32_t m_intensity; }; From 0e224abb0aac15a791978c27a667c7aefbf91eb0 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 27 Oct 2019 19:51:21 +0700 Subject: [PATCH 08/27] Improved error handling. --- src/backend/cuda/CudaWorker.cpp | 6 ---- src/backend/cuda/runners/CudaBaseRunner.cpp | 32 +++++++++++++++------ src/backend/cuda/runners/CudaBaseRunner.h | 2 ++ src/backend/cuda/runners/CudaCnRunner.cpp | 8 +++++- src/backend/cuda/wrappers/CudaLib.cpp | 12 +++++++- src/backend/cuda/wrappers/CudaLib.h | 3 +- 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/src/backend/cuda/CudaWorker.cpp b/src/backend/cuda/CudaWorker.cpp index 1f262574..28a3a7bf 100644 --- a/src/backend/cuda/CudaWorker.cpp +++ b/src/backend/cuda/CudaWorker.cpp @@ -54,12 +54,6 @@ static inline bool isReady() { return !Nonce::isPaused() static inline uint32_t roundSize(uint32_t intensity) { return kReserveCount / intensity + 1; } -static inline void printError(size_t id, const char *error) -{ - LOG_ERR("%s" RED_S " thread " RED_BOLD("#%zu") RED_S " failed with error " RED_BOLD("%s"), cuda_tag(), id, error); -} - - } // namespace xmrig diff --git a/src/backend/cuda/runners/CudaBaseRunner.cpp b/src/backend/cuda/runners/CudaBaseRunner.cpp index 9428b16c..191b9e39 100644 --- a/src/backend/cuda/runners/CudaBaseRunner.cpp +++ b/src/backend/cuda/runners/CudaBaseRunner.cpp @@ -26,15 +26,9 @@ #include "backend/cuda/runners/CudaBaseRunner.h" #include "backend/cuda/wrappers/CudaLib.h" #include "backend/cuda/CudaLaunchData.h" -//#include "backend/opencl/cl/OclSource.h" -//#include "backend/opencl/OclCache.h" -//#include "backend/opencl/OclLaunchData.h" -//#include "backend/opencl/runners/tools/OclSharedState.h" -//#include "backend/opencl/wrappers/OclError.h" -//#include "backend/opencl/wrappers/OclLib.h" +#include "backend/common/Tags.h" #include "base/io/log/Log.h" #include "base/net/stratum/Job.h" -//#include "crypto/common/VirtualMemory.h" xmrig::CudaBaseRunner::CudaBaseRunner(size_t id, const CudaLaunchData &data) : @@ -57,7 +51,13 @@ bool xmrig::CudaBaseRunner::init() return false; } - return CudaLib::deviceInit(m_ctx); + if (!CudaLib::deviceInit(m_ctx)) { + printError(CudaLib::lastError(m_ctx)); + + return false; + } + + return true; } @@ -66,7 +66,13 @@ bool xmrig::CudaBaseRunner::set(const Job &job, uint8_t *blob) m_height = job.height(); m_target = job.target(); - return CudaLib::setJob(m_ctx, blob, job.size(), job.algorithm()); + if (!CudaLib::setJob(m_ctx, blob, job.size(), job.algorithm())) { + printError(CudaLib::lastError(m_ctx)); + + return false; + } + + return true; } @@ -74,3 +80,11 @@ size_t xmrig::CudaBaseRunner::intensity() const { return m_data.thread.threads() * m_data.thread.blocks(); } + + +void xmrig::CudaBaseRunner::printError(const char *error) const +{ + if (error) { + LOG_ERR("%s" RED_S " thread " RED_BOLD("#%zu") RED_S " failed with error " RED_BOLD("%s"), cuda_tag(), m_threadId, error); + } +} diff --git a/src/backend/cuda/runners/CudaBaseRunner.h b/src/backend/cuda/runners/CudaBaseRunner.h index 7bdc7bea..4ac04d4d 100644 --- a/src/backend/cuda/runners/CudaBaseRunner.h +++ b/src/backend/cuda/runners/CudaBaseRunner.h @@ -52,6 +52,8 @@ protected: size_t intensity() const override; protected: + void printError(const char *error) const; + const CudaLaunchData &m_data; const size_t m_threadId; nvid_ctx *m_ctx = nullptr; diff --git a/src/backend/cuda/runners/CudaCnRunner.cpp b/src/backend/cuda/runners/CudaCnRunner.cpp index f75f0995..c4852972 100644 --- a/src/backend/cuda/runners/CudaCnRunner.cpp +++ b/src/backend/cuda/runners/CudaCnRunner.cpp @@ -34,5 +34,11 @@ xmrig::CudaCnRunner::CudaCnRunner(size_t index, const CudaLaunchData &data) : Cu bool xmrig::CudaCnRunner::run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce) { - return CudaLib::cnHash(m_ctx, startNonce, m_height, m_target, rescount, resnonce); + if (!CudaLib::cnHash(m_ctx, startNonce, m_height, m_target, rescount, resnonce)) { + printError(CudaLib::lastError(m_ctx)); + + return false; + } + + return true; } diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp index d0c720ee..f89d1de1 100644 --- a/src/backend/cuda/wrappers/CudaLib.cpp +++ b/src/backend/cuda/wrappers/CudaLib.cpp @@ -55,6 +55,7 @@ static const char *kDeviceName = "deviceName"; static const char *kDeviceUint = "deviceUint"; static const char *kDeviceUlong = "deviceUlong"; static const char *kInit = "init"; +static const char *kLastError = "lastError"; static const char *kPluginVersion = "pluginVersion"; static const char *kRelease = "release"; static const char *kSetJob = "setJob"; @@ -72,6 +73,7 @@ using deviceName_t = const char * (*)(nvid_ using deviceUint_t = uint32_t (*)(nvid_ctx *, CudaLib::DeviceProperty); using deviceUlong_t = uint64_t (*)(nvid_ctx *, CudaLib::DeviceProperty); using init_t = void (*)(); +using lastError_t = const char * (*)(nvid_ctx *); using pluginVersion_t = const char * (*)(); using release_t = void (*)(nvid_ctx *); using setJob_t = bool (*)(nvid_ctx *, const void *, size_t, int32_t); @@ -88,6 +90,7 @@ static deviceName_t pDeviceName = nullptr; static deviceUint_t pDeviceUint = nullptr; static deviceUlong_t pDeviceUlong = nullptr; static init_t pInit = nullptr; +static lastError_t pLastError = nullptr; static pluginVersion_t pPluginVersion = nullptr; static release_t pRelease = nullptr; static setJob_t pSetJob = nullptr; @@ -117,7 +120,7 @@ bool xmrig::CudaLib::init(const char *fileName) } -const char *xmrig::CudaLib::lastError() +const char *xmrig::CudaLib::lastError() noexcept { return uv_dlerror(&cudaLib); } @@ -153,6 +156,12 @@ const char *xmrig::CudaLib::deviceName(nvid_ctx *ctx) noexcept } +const char *xmrig::CudaLib::lastError(nvid_ctx *ctx) noexcept +{ + return pLastError(ctx); +} + + const char *xmrig::CudaLib::pluginVersion() noexcept { return pPluginVersion(); @@ -255,6 +264,7 @@ bool xmrig::CudaLib::load() DLSYM(DeviceUint); DLSYM(DeviceUlong); DLSYM(Init); + DLSYM(LastError); DLSYM(PluginVersion); DLSYM(Release); DLSYM(SetJob); diff --git a/src/backend/cuda/wrappers/CudaLib.h b/src/backend/cuda/wrappers/CudaLib.h index 5aafeaea..926fca56 100644 --- a/src/backend/cuda/wrappers/CudaLib.h +++ b/src/backend/cuda/wrappers/CudaLib.h @@ -64,7 +64,7 @@ public: }; static bool init(const char *fileName = nullptr); - static const char *lastError(); + static const char *lastError() noexcept; static void close(); static inline bool isInitialized() { return m_initialized; } @@ -74,6 +74,7 @@ public: static bool deviceInit(nvid_ctx *ctx) noexcept; static bool setJob(nvid_ctx *ctx, const void *data, size_t size, const Algorithm &algorithm) noexcept; static const char *deviceName(nvid_ctx *ctx) noexcept; + static const char *lastError(nvid_ctx *ctx) noexcept; static const char *pluginVersion() noexcept; static int deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads, const Algorithm &algorithm) noexcept; static int32_t deviceInt(nvid_ctx *ctx, DeviceProperty property) noexcept; From 7889634b40ed9c0f5a9faed8bd151461258c0a73 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 28 Oct 2019 01:18:08 +0700 Subject: [PATCH 09/27] Added RandomX support. --- src/backend/cuda/CudaConfig_gen.h | 25 +++++++++++++++++ src/backend/cuda/CudaWorker.cpp | 11 ++++---- src/backend/cuda/CudaWorker.h | 1 - src/backend/cuda/runners/CudaBaseRunner.cpp | 27 +++++++----------- src/backend/cuda/runners/CudaBaseRunner.h | 2 +- src/backend/cuda/runners/CudaCnRunner.cpp | 8 +----- src/backend/cuda/runners/CudaRxRunner.cpp | 31 ++++++++++++++++++--- src/backend/cuda/runners/CudaRxRunner.h | 8 ++++-- src/backend/cuda/wrappers/CudaLib.cpp | 20 +++++++++++++ src/backend/cuda/wrappers/CudaLib.h | 2 ++ 10 files changed, 97 insertions(+), 38 deletions(-) diff --git a/src/backend/cuda/CudaConfig_gen.h b/src/backend/cuda/CudaConfig_gen.h index d7c913f5..87e35dc4 100644 --- a/src/backend/cuda/CudaConfig_gen.h +++ b/src/backend/cuda/CudaConfig_gen.h @@ -106,6 +106,31 @@ size_t inline generate(Threads &threads, const #endif +#ifdef XMRIG_ALGO_RANDOMX +template<> +size_t inline generate(Threads &threads, const std::vector &devices) +{ + size_t count = 0; + + auto rx = CudaThreads(devices, Algorithm::RX_0); + auto wow = CudaThreads(devices, Algorithm::RX_WOW); + auto arq = CudaThreads(devices, Algorithm::RX_ARQ); + + if (!threads.isExist(Algorithm::RX_WOW) && wow != rx) { + count += threads.move("rx/wow", std::move(wow)); + } + + if (!threads.isExist(Algorithm::RX_ARQ) && arq != rx) { + count += threads.move("rx/arq", std::move(arq)); + } + + count += threads.move("rx", std::move(rx)); + + return count; +} +#endif + + } /* namespace xmrig */ diff --git a/src/backend/cuda/CudaWorker.cpp b/src/backend/cuda/CudaWorker.cpp index 28a3a7bf..5e5ad413 100644 --- a/src/backend/cuda/CudaWorker.cpp +++ b/src/backend/cuda/CudaWorker.cpp @@ -61,8 +61,7 @@ static inline uint32_t roundSize(uint32_t intensity) { return kReserveCount / in xmrig::CudaWorker::CudaWorker(size_t id, const CudaLaunchData &data) : Worker(id, data.thread.affinity(), -1), m_algorithm(data.algorithm), - m_miner(data.miner), - m_intensity(data.thread.threads() * data.thread.blocks()) + m_miner(data.miner) { switch (m_algorithm.family()) { case Algorithm::RANDOM_X: @@ -133,7 +132,8 @@ void xmrig::CudaWorker::start() JobResults::submit(m_job.currentJob(), foundNonce, foundCount); } - m_job.nextRound(roundSize(m_intensity), m_intensity); + const size_t batch_size = intensity(); + m_job.nextRound(roundSize(batch_size), batch_size); storeStats(); std::this_thread::yield(); @@ -152,7 +152,8 @@ bool xmrig::CudaWorker::consumeJob() return false; } - m_job.add(m_miner->job(), Nonce::sequence(Nonce::CUDA), roundSize(m_intensity) * m_intensity); + const size_t batch_size = intensity(); + m_job.add(m_miner->job(), Nonce::sequence(Nonce::CUDA), roundSize(batch_size) * batch_size); return m_runner->set(m_job.currentJob(), m_job.blob());; } @@ -164,7 +165,7 @@ void xmrig::CudaWorker::storeStats() return; } - m_count += m_intensity; + m_count += intensity(); Worker::storeStats(); } diff --git a/src/backend/cuda/CudaWorker.h b/src/backend/cuda/CudaWorker.h index 4fb006ba..f717ca50 100644 --- a/src/backend/cuda/CudaWorker.h +++ b/src/backend/cuda/CudaWorker.h @@ -62,7 +62,6 @@ private: const Algorithm m_algorithm; const Miner *m_miner; - const uint32_t m_intensity; ICudaRunner *m_runner = nullptr; WorkerJob<1> m_job; }; diff --git a/src/backend/cuda/runners/CudaBaseRunner.cpp b/src/backend/cuda/runners/CudaBaseRunner.cpp index 191b9e39..032d50c9 100644 --- a/src/backend/cuda/runners/CudaBaseRunner.cpp +++ b/src/backend/cuda/runners/CudaBaseRunner.cpp @@ -51,13 +51,7 @@ bool xmrig::CudaBaseRunner::init() return false; } - if (!CudaLib::deviceInit(m_ctx)) { - printError(CudaLib::lastError(m_ctx)); - - return false; - } - - return true; + return callWrapper(CudaLib::deviceInit(m_ctx)); } @@ -66,13 +60,7 @@ bool xmrig::CudaBaseRunner::set(const Job &job, uint8_t *blob) m_height = job.height(); m_target = job.target(); - if (!CudaLib::setJob(m_ctx, blob, job.size(), job.algorithm())) { - printError(CudaLib::lastError(m_ctx)); - - return false; - } - - return true; + return callWrapper(CudaLib::setJob(m_ctx, blob, job.size(), job.algorithm())); } @@ -82,9 +70,14 @@ size_t xmrig::CudaBaseRunner::intensity() const } -void xmrig::CudaBaseRunner::printError(const char *error) const +bool xmrig::CudaBaseRunner::callWrapper(bool result) const { - if (error) { - LOG_ERR("%s" RED_S " thread " RED_BOLD("#%zu") RED_S " failed with error " RED_BOLD("%s"), cuda_tag(), m_threadId, error); + if (!result) { + const char *error = CudaLib::lastError(m_ctx); + if (error) { + LOG_ERR("%s" RED_S " thread " RED_BOLD("#%zu") RED_S " failed with error " RED_BOLD("%s"), cuda_tag(), m_threadId, error); + } } + + return result; } diff --git a/src/backend/cuda/runners/CudaBaseRunner.h b/src/backend/cuda/runners/CudaBaseRunner.h index 4ac04d4d..c0e1aef0 100644 --- a/src/backend/cuda/runners/CudaBaseRunner.h +++ b/src/backend/cuda/runners/CudaBaseRunner.h @@ -52,7 +52,7 @@ protected: size_t intensity() const override; protected: - void printError(const char *error) const; + bool callWrapper(bool result) const; const CudaLaunchData &m_data; const size_t m_threadId; diff --git a/src/backend/cuda/runners/CudaCnRunner.cpp b/src/backend/cuda/runners/CudaCnRunner.cpp index c4852972..4d79efe3 100644 --- a/src/backend/cuda/runners/CudaCnRunner.cpp +++ b/src/backend/cuda/runners/CudaCnRunner.cpp @@ -34,11 +34,5 @@ xmrig::CudaCnRunner::CudaCnRunner(size_t index, const CudaLaunchData &data) : Cu bool xmrig::CudaCnRunner::run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce) { - if (!CudaLib::cnHash(m_ctx, startNonce, m_height, m_target, rescount, resnonce)) { - printError(CudaLib::lastError(m_ctx)); - - return false; - } - - return true; + return callWrapper(CudaLib::cnHash(m_ctx, startNonce, m_height, m_target, rescount, resnonce)); } diff --git a/src/backend/cuda/runners/CudaRxRunner.cpp b/src/backend/cuda/runners/CudaRxRunner.cpp index 92b2d9f9..83bf21ff 100644 --- a/src/backend/cuda/runners/CudaRxRunner.cpp +++ b/src/backend/cuda/runners/CudaRxRunner.cpp @@ -24,19 +24,42 @@ #include "backend/cuda/runners/CudaRxRunner.h" +#include "backend/cuda/CudaLaunchData.h" +#include "backend/cuda/wrappers/CudaLib.h" +#include "base/net/stratum/Job.h" +#include "crypto/rx/Rx.h" +#include "crypto/rx/RxDataset.h" xmrig::CudaRxRunner::CudaRxRunner(size_t index, const CudaLaunchData &data) : CudaBaseRunner(index, data) { -} + m_intensity = m_data.thread.threads() * m_data.thread.blocks(); + const size_t scratchpads_size = m_intensity * m_data.algorithm.l3(); + const size_t num_scratchpads = scratchpads_size / m_data.algorithm.l3(); + if (m_intensity > num_scratchpads) { + m_intensity = num_scratchpads; + } -xmrig::CudaRxRunner::~CudaRxRunner() -{ + m_intensity -= m_intensity % 32; } bool xmrig::CudaRxRunner::run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce) { - return false; + return callWrapper(CudaLib::rxHash(m_ctx, startNonce, m_target, rescount, resnonce)); +} + + +bool xmrig::CudaRxRunner::set(const Job &job, uint8_t *blob) +{ + const bool rc = CudaBaseRunner::set(job, blob); + if (!rc || m_ready) { + return rc; + } + + auto dataset = Rx::dataset(job, 0); + m_ready = callWrapper(CudaLib::rxPrepare(m_ctx, dataset->raw(), dataset->size(false), m_intensity)); + + return m_ready; } diff --git a/src/backend/cuda/runners/CudaRxRunner.h b/src/backend/cuda/runners/CudaRxRunner.h index 8aba75f5..06ed1b90 100644 --- a/src/backend/cuda/runners/CudaRxRunner.h +++ b/src/backend/cuda/runners/CudaRxRunner.h @@ -35,15 +35,17 @@ namespace xmrig { class CudaRxRunner : public CudaBaseRunner { public: - XMRIG_DISABLE_COPY_MOVE_DEFAULT(CudaRxRunner) - CudaRxRunner(size_t index, const CudaLaunchData &data); - ~CudaRxRunner() override; protected: + inline size_t intensity() const override { return m_intensity; } + bool run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce) override; + bool set(const Job &job, uint8_t *blob) override; private: + bool m_ready = false; + size_t m_intensity = 0; }; diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp index f89d1de1..4f8376e3 100644 --- a/src/backend/cuda/wrappers/CudaLib.cpp +++ b/src/backend/cuda/wrappers/CudaLib.cpp @@ -58,6 +58,8 @@ static const char *kInit = "init"; static const char *kLastError = "lastError"; static const char *kPluginVersion = "pluginVersion"; static const char *kRelease = "release"; +static const char *kRxHash = "rxHash"; +static const char *kRxPrepare = "rxPrepare"; static const char *kSetJob = "setJob"; static const char *kSymbolNotFound = "symbol not found"; static const char *kVersion = "version"; @@ -76,6 +78,8 @@ using init_t = void (*)(); using lastError_t = const char * (*)(nvid_ctx *); using pluginVersion_t = const char * (*)(); using release_t = void (*)(nvid_ctx *); +using rxHash_t = bool (*)(nvid_ctx *, uint32_t, uint64_t, uint32_t *, uint32_t *); +using rxPrepare_t = bool (*)(nvid_ctx *, const void *, size_t, uint32_t); using setJob_t = bool (*)(nvid_ctx *, const void *, size_t, int32_t); using version_t = uint32_t (*)(Version); @@ -93,6 +97,8 @@ static init_t pInit = nullptr; static lastError_t pLastError = nullptr; static pluginVersion_t pPluginVersion = nullptr; static release_t pRelease = nullptr; +static rxHash_t pRxHash = nullptr; +static rxPrepare_t pRxPrepare = nullptr; static setJob_t pSetJob = nullptr; static version_t pVersion = nullptr; @@ -144,6 +150,18 @@ bool xmrig::CudaLib::deviceInit(nvid_ctx *ctx) noexcept } +bool xmrig::CudaLib::rxHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t target, uint32_t *rescount, uint32_t *resnonce) noexcept +{ + return pRxHash(ctx, startNonce, target, rescount, resnonce); +} + + +bool xmrig::CudaLib::rxPrepare(nvid_ctx *ctx, const void *dataset, size_t datasetSize, uint32_t batchSize) noexcept +{ + return pRxPrepare(ctx, dataset, datasetSize, batchSize); +} + + bool xmrig::CudaLib::setJob(nvid_ctx *ctx, const void *data, size_t size, const Algorithm &algorithm) noexcept { return pSetJob(ctx, data, size, algorithm); @@ -267,6 +285,8 @@ bool xmrig::CudaLib::load() DLSYM(LastError); DLSYM(PluginVersion); DLSYM(Release); + DLSYM(RxHash); + DLSYM(RxPrepare); DLSYM(SetJob); DLSYM(Version); } catch (std::exception &ex) { diff --git a/src/backend/cuda/wrappers/CudaLib.h b/src/backend/cuda/wrappers/CudaLib.h index 926fca56..b1215640 100644 --- a/src/backend/cuda/wrappers/CudaLib.h +++ b/src/backend/cuda/wrappers/CudaLib.h @@ -72,6 +72,8 @@ public: static bool cnHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t height, uint64_t target, uint32_t *rescount, uint32_t *resnonce); static bool deviceInit(nvid_ctx *ctx) noexcept; + static bool rxHash(nvid_ctx *ctx, uint32_t startNonce, uint64_t target, uint32_t *rescount, uint32_t *resnonce) noexcept; + static bool rxPrepare(nvid_ctx *ctx, const void *dataset, size_t datasetSize, uint32_t batchSize) noexcept; static bool setJob(nvid_ctx *ctx, const void *data, size_t size, const Algorithm &algorithm) noexcept; static const char *deviceName(nvid_ctx *ctx) noexcept; static const char *lastError(nvid_ctx *ctx) noexcept; From 99fe304c1f56329fa29f93ba4e1d133ffe914ffd Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 28 Oct 2019 01:47:55 +0700 Subject: [PATCH 10/27] Don't generate CUDA config on fly. --- src/backend/cuda/CudaConfig.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/backend/cuda/CudaConfig.cpp b/src/backend/cuda/CudaConfig.cpp index 67cee3a2..19817c65 100644 --- a/src/backend/cuda/CudaConfig.cpp +++ b/src/backend/cuda/CudaConfig.cpp @@ -35,6 +35,7 @@ namespace xmrig { +static bool generated = false; static const char *kDevicesHint = "devices-hint"; static const char *kEnabled = "enabled"; static const char *kLoader = "loader"; @@ -113,6 +114,10 @@ void xmrig::CudaConfig::read(const rapidjson::Value &value) void xmrig::CudaConfig::generate() { + if (generated) { + return; + } + if (!isEnabled() || m_threads.has("*")) { return; } @@ -138,6 +143,7 @@ void xmrig::CudaConfig::generate() count += xmrig::generate(m_threads, devices); count += xmrig::generate(m_threads, devices); + generated = true; m_shouldSave = count > 0; } From 8cd265c38ccf65f7f9044920c1cbd04ea3694bbd Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 28 Oct 2019 13:18:00 +0700 Subject: [PATCH 11/27] Added CUDA threads to API. --- src/backend/cuda/CudaBackend.cpp | 25 ++++++++++++++++++++++-- src/backend/cuda/wrappers/CudaDevice.cpp | 10 ++++++++++ src/backend/cuda/wrappers/CudaDevice.h | 1 + src/backend/opencl/OclBackend.cpp | 2 +- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index 9043299c..903c096f 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -169,7 +169,7 @@ public: } - inline void start(const Job &job) + inline void start(const Job &) { LOG_INFO("%s use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), tag, @@ -285,7 +285,7 @@ void xmrig::CudaBackend::printHashrate(bool details) size_t i = 0; for (const auto &data : d_ptr->threads) { - Log::print("| %8zu | %8" PRId64 " | %7s | %7s | %7s |" CYAN_BOLD(" #%u") YELLOW(" %s") " %s", + Log::print("| %8zu | %8" PRId64 " | %7s | %7s | %7s |" CYAN_BOLD(" #%u") YELLOW(" %s") GREEN(" %s"), i, data.thread.affinity(), Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval), num, sizeof num / 3), @@ -390,6 +390,27 @@ rapidjson::Value xmrig::CudaBackend::toJSON(rapidjson::Document &doc) const out.AddMember("algo", d_ptr->algo.toJSON(), allocator); out.AddMember("profile", profileName().toJSON(), allocator); + if (d_ptr->threads.empty() || !hashrate()) { + return out; + } + + out.AddMember("hashrate", hashrate()->toJSON(doc), allocator); + + Value threads(kArrayType); + + size_t i = 0; + for (const auto &data : d_ptr->threads) { + Value thread = data.thread.toJSON(doc); + thread.AddMember("hashrate", hashrate()->toJSON(i, doc), allocator); + + data.device.toJSON(thread, doc); + + i++; + threads.PushBack(thread, allocator); + } + + out.AddMember("threads", threads, allocator); + return out; } diff --git a/src/backend/cuda/wrappers/CudaDevice.cpp b/src/backend/cuda/wrappers/CudaDevice.cpp index 7eb947fc..740a063c 100644 --- a/src/backend/cuda/wrappers/CudaDevice.cpp +++ b/src/backend/cuda/wrappers/CudaDevice.cpp @@ -115,5 +115,15 @@ void xmrig::CudaDevice::generate(const Algorithm &algorithm, CudaThreads &thread #ifdef XMRIG_FEATURE_API void xmrig::CudaDevice::toJSON(rapidjson::Value &out, rapidjson::Document &doc) const { + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + out.AddMember("name", name().toJSON(doc), allocator); + out.AddMember("bus_id", topology().toString().toJSON(doc), allocator); + out.AddMember("smx", smx(), allocator); + out.AddMember("arch", arch(), allocator); + out.AddMember("global_mem", static_cast(globalMemSize()), allocator); + out.AddMember("clock", clock(), allocator); + out.AddMember("memory_clock", memoryClock(), allocator); } #endif diff --git a/src/backend/cuda/wrappers/CudaDevice.h b/src/backend/cuda/wrappers/CudaDevice.h index 40b8ee11..07866c82 100644 --- a/src/backend/cuda/wrappers/CudaDevice.h +++ b/src/backend/cuda/wrappers/CudaDevice.h @@ -60,6 +60,7 @@ public: inline bool isValid() const { return m_ctx != nullptr; } inline const PciTopology &topology() const { return m_topology; } inline const String &name() const { return m_name; } + inline uint32_t arch() const { return (computeCapability(true) * 10) + computeCapability(false); } inline uint32_t index() const { return m_index; } # ifdef XMRIG_FEATURE_API diff --git a/src/backend/opencl/OclBackend.cpp b/src/backend/opencl/OclBackend.cpp index 8aadc926..c9fef1f9 100644 --- a/src/backend/opencl/OclBackend.cpp +++ b/src/backend/opencl/OclBackend.cpp @@ -409,7 +409,7 @@ rapidjson::Value xmrig::OclBackend::toJSON(rapidjson::Document &doc) const Value threads(kArrayType); size_t i = 0; - for (const OclLaunchData &data : d_ptr->threads) { + for (const auto &data : d_ptr->threads) { Value thread = data.thread.toJSON(doc); thread.AddMember("affinity", data.affinity, allocator); thread.AddMember("hashrate", hashrate()->toJSON(i, doc), allocator); From 58174e5e91c0d7de265f7ccb8d5c46b9ed949a3c Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 28 Oct 2019 13:30:03 +0700 Subject: [PATCH 12/27] v4.5.0-evo --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index dab33f9d..ea5c458c 100644 --- a/src/version.h +++ b/src/version.h @@ -28,14 +28,14 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "4.4.0-beta" +#define APP_VERSION "4.5.0-evo" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com" #define APP_KIND "miner" #define APP_VER_MAJOR 4 -#define APP_VER_MINOR 4 +#define APP_VER_MINOR 5 #define APP_VER_PATCH 0 #ifdef _MSC_VER From 80fd0f9fab9a0fe8bd099d9ad1f50fe0ca3e150a Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 28 Oct 2019 14:54:24 +0700 Subject: [PATCH 13/27] Fix CUDA plugin name for Linux. --- src/backend/cuda/wrappers/CudaLib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp index 4f8376e3..10b7fab0 100644 --- a/src/backend/cuda/wrappers/CudaLib.cpp +++ b/src/backend/cuda/wrappers/CudaLib.cpp @@ -306,6 +306,6 @@ const char *xmrig::CudaLib::defaultLoader() # elif defined(_WIN32) return "xmrig-cuda.dll"; # else - return "xmrig-cuda.so"; + return "libxmrig-cuda.so"; # endif } From 9dfa38f1e791c20e2d09ee9aa6798f5f57d149b9 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 29 Oct 2019 00:42:49 +0700 Subject: [PATCH 14/27] Added command line options --cuda and --cuda-loader. --- README.md | 7 ++++++- src/base/kernel/interfaces/IConfig.h | 2 ++ src/config.json | 6 +++++- src/core/config/ConfigTransform.cpp | 12 ++++++++++++ src/core/config/Config_default.h | 4 ++++ src/core/config/Config_platform.h | 4 ++++ src/core/config/usage.h | 8 +++++++- 7 files changed, 40 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e520a505..cffb28c7 100644 --- a/README.md +++ b/README.md @@ -77,11 +77,16 @@ OpenCL backend: --opencl enable OpenCL mining backend --opencl-devices=N list of OpenCL devices to use --opencl-platform=N OpenCL platform index or name - --opencl-loader=N path to OpenCL-ICD-Loader (OpenCL.dll or libOpenCL.so) + --opencl-loader=PATH path to OpenCL-ICD-Loader (OpenCL.dll or libOpenCL.so) --opencl-no-cache disable OpenCL cache --print-platforms print available OpenCL platforms and exit +CUDA backend: + --cuda enable CUDA mining backend + --cuda-loader=PATH path to CUDA plugin (xmrig-cuda.dll or libxmrig-cuda.so) + Logging: + -S, --syslog use system log for output messages -l, --log-file=FILE log all output to a file --print-time=N print hashrate report every N seconds --no-color disable colored output diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index 9f8d9618..ccee47c6 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -134,6 +134,8 @@ public: CudaLaunchKey = 1204, CudaAffinityKey = 1205, CudaMaxUsageKey = 1206, + CudaKey = 1207, + CudaLoaderKey = 1208 }; virtual ~IConfig() = default; diff --git a/src/config.json b/src/config.json index cb027a27..9c6d459e 100644 --- a/src/config.json +++ b/src/config.json @@ -38,6 +38,10 @@ "cn/0": false, "cn-lite/0": false }, + "cuda": { + "enabled": false, + "loader": null, + }, "donate-level": 5, "donate-over-proxy": 1, "log-file": null, @@ -64,4 +68,4 @@ "syslog": false, "user-agent": null, "watch": true -} \ No newline at end of file +} diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp index ad323212..51f594e8 100644 --- a/src/core/config/ConfigTransform.cpp +++ b/src/core/config/ConfigTransform.cpp @@ -47,6 +47,10 @@ static const char *kRandomX = "randomx"; static const char *kOcl = "opencl"; #endif +#ifdef XMRIG_FEATURE_CUDA +static const char *kCuda = "cuda"; +#endif + static inline uint64_t intensity(uint64_t av) { @@ -181,6 +185,14 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const return set(doc, kOcl, "platform", arg); # endif +# ifdef XMRIG_FEATURE_CUDA + case IConfig::CudaKey: /* --cuda */ + return set(doc, kCuda, "enabled", true); + + case IConfig::CudaLoaderKey: /* --cuda-loader */ + return set(doc, kCuda, "loader", arg); +# endif + default: break; } diff --git a/src/core/config/Config_default.h b/src/core/config/Config_default.h index 8a284758..e7d39299 100644 --- a/src/core/config/Config_default.h +++ b/src/core/config/Config_default.h @@ -72,6 +72,10 @@ R"===( "cn/0": false, "cn-lite/0": false }, + "cuda": { + "enabled": false, + "loader": null, + }, "donate-level": 5, "donate-over-proxy": 1, "log-file": null, diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index a61f1a91..371e58fa 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -103,6 +103,10 @@ static const option options[] = { { "opencl-platform", 1, nullptr, IConfig::OclPlatformKey }, { "opencl-loader", 1, nullptr, IConfig::OclLoaderKey }, { "opencl-no-cache", 0, nullptr, IConfig::OclCacheKey }, +# endif +# ifdef XMRIG_FEATURE_CUDA + { "cuda", 0, nullptr, IConfig::CudaKey }, + { "cuda-loader", 1, nullptr, IConfig::CudaLoaderKey }, # endif { nullptr, 0, nullptr, 0 } }; diff --git a/src/core/config/usage.h b/src/core/config/usage.h index f5928fe9..c95526f7 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -103,11 +103,17 @@ static inline const std::string &usage() u += " --opencl enable OpenCL mining backend\n"; u += " --opencl-devices=N list of OpenCL devices to use\n"; u += " --opencl-platform=N OpenCL platform index or name\n"; - u += " --opencl-loader=N path to OpenCL-ICD-Loader (OpenCL.dll or libOpenCL.so)\n"; + u += " --opencl-loader=PATH path to OpenCL-ICD-Loader (OpenCL.dll or libOpenCL.so)\n"; u += " --opencl-no-cache disable OpenCL cache\n"; u += " --print-platforms print available OpenCL platforms and exit\n"; # endif +# ifdef XMRIG_FEATURE_CUDA + 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"; +# endif + u += "\nLogging:\n"; # ifdef HAVE_SYSLOG_H From b1eac17d60c4b8434b077ed540129347a17f4ff4 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 29 Oct 2019 14:25:40 +0700 Subject: [PATCH 15/27] Added version information to API. --- src/backend/cuda/CudaBackend.cpp | 16 ++++++++++++---- src/backend/cuda/wrappers/CudaLib.cpp | 6 ++++++ src/backend/cuda/wrappers/CudaLib.h | 2 ++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index 903c096f..2a2f8ea1 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -136,8 +136,8 @@ public: return printDisabled(RED_S " (failed to load CUDA plugin)"); } - const uint32_t runtimeVersion = CudaLib::runtimeVersion(); - const uint32_t driverVersion = CudaLib::driverVersion(); + runtimeVersion = CudaLib::runtimeVersion(); + driverVersion = CudaLib::driverVersion(); if (!runtimeVersion || !driverVersion || !CudaLib::deviceCount()) { return printDisabled(RED_S " (no devices)"); @@ -147,8 +147,8 @@ public: return; } - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%u.%u") "/" WHITE_BOLD("%u.%u") BLACK_BOLD("/%s"), "CUDA", - runtimeVersion / 1000, runtimeVersion % 100, driverVersion / 1000, driverVersion % 100, CudaLib::pluginVersion()); + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") "/" WHITE_BOLD("%s") BLACK_BOLD("/%s"), "CUDA", + CudaLib::version(runtimeVersion).c_str(), CudaLib::version(driverVersion).c_str(), CudaLib::pluginVersion()); devices = CudaLib::devices(cuda.bfactor(), cuda.bsleep()); @@ -210,6 +210,8 @@ public: std::vector devices; std::vector threads; String profileName; + uint32_t driverVersion = 0; + uint32_t runtimeVersion = 0; Workers workers; }; @@ -390,6 +392,12 @@ rapidjson::Value xmrig::CudaBackend::toJSON(rapidjson::Document &doc) const out.AddMember("algo", d_ptr->algo.toJSON(), allocator); out.AddMember("profile", profileName().toJSON(), allocator); + Value versions(kObjectType); + versions.AddMember("runtime", Value(CudaLib::version(d_ptr->runtimeVersion).c_str(), allocator), allocator); + versions.AddMember("driver", Value(CudaLib::version(d_ptr->driverVersion).c_str(), allocator), allocator); + versions.AddMember("plugin", String(CudaLib::pluginVersion()).toJSON(doc), allocator); + out.AddMember("versions", versions, allocator); + if (d_ptr->threads.empty() || !hashrate()) { return out; } diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp index 10b7fab0..5f3018d3 100644 --- a/src/backend/cuda/wrappers/CudaLib.cpp +++ b/src/backend/cuda/wrappers/CudaLib.cpp @@ -204,6 +204,12 @@ nvid_ctx *xmrig::CudaLib::alloc(uint32_t id, int32_t bfactor, int32_t bsleep) no } +std::string xmrig::CudaLib::version(uint32_t version) +{ + return std::to_string(version / 1000) + "." + std::to_string((version % 1000) / 10); +} + + std::vector xmrig::CudaLib::devices(int32_t bfactor, int32_t bsleep) noexcept { const uint32_t count = deviceCount(); diff --git a/src/backend/cuda/wrappers/CudaLib.h b/src/backend/cuda/wrappers/CudaLib.h index b1215640..7fb1c1eb 100644 --- a/src/backend/cuda/wrappers/CudaLib.h +++ b/src/backend/cuda/wrappers/CudaLib.h @@ -35,6 +35,7 @@ using nvid_ctx = struct nvid_ctx; #include +#include namespace xmrig { @@ -81,6 +82,7 @@ public: static int deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads, const Algorithm &algorithm) noexcept; 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 uint32_t deviceCount() noexcept; static uint32_t deviceUint(nvid_ctx *ctx, DeviceProperty property) noexcept; From 23ebcfb2db0dda39c5e2fe41019520e72d089db9 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 29 Oct 2019 15:43:13 +0700 Subject: [PATCH 16/27] Display backend for shares. --- src/backend/common/Tags.h | 5 +++ src/backend/common/WorkerJob.h | 18 ++++++----- src/backend/cpu/CpuBackend.cpp | 18 +++++++++++ src/backend/cpu/CpuWorker.cpp | 2 +- src/backend/cuda/CudaWorker.cpp | 2 +- src/backend/opencl/OclWorker.cpp | 2 +- src/base/net/stratum/Client.cpp | 2 +- src/base/net/stratum/DaemonClient.cpp | 2 +- src/base/net/stratum/Job.cpp | 32 +++++++++++++++++++ src/base/net/stratum/Job.h | 11 ++++++- src/base/net/stratum/SubmitResult.h | 4 ++- src/crypto/common/Nonce.h | 2 +- src/net/JobResult.h | 8 +++-- src/net/Network.cpp | 45 ++++++++++++++++++--------- 14 files changed, 121 insertions(+), 32 deletions(-) diff --git a/src/backend/common/Tags.h b/src/backend/common/Tags.h index 54de3760..9141eb72 100644 --- a/src/backend/common/Tags.h +++ b/src/backend/common/Tags.h @@ -27,10 +27,15 @@ #define XMRIG_TAGS_H +#include + + namespace xmrig { +const char *backend_tag(uint32_t backend); const char *cpu_tag(); +const char *net_tag(); #ifdef XMRIG_FEATURE_OPENCL diff --git a/src/backend/common/WorkerJob.h b/src/backend/common/WorkerJob.h index 6e31a701..2ea41476 100644 --- a/src/backend/common/WorkerJob.h +++ b/src/backend/common/WorkerJob.h @@ -26,7 +26,7 @@ #define XMRIG_WORKERJOB_H -#include +#include #include "base/net/stratum/Job.h" @@ -47,9 +47,9 @@ public: inline uint8_t index() const { return m_index; } - inline void add(const Job &job, uint64_t sequence, uint32_t reserveCount) + inline void add(const Job &job, uint32_t reserveCount, Nonce::Backend backend) { - m_sequence = sequence; + m_sequence = Nonce::sequence(backend); if (currentJob() == job) { return; @@ -60,7 +60,7 @@ public: return; } - save(job, reserveCount); + save(job, reserveCount, backend); } @@ -82,13 +82,15 @@ public: private: - inline void save(const Job &job, uint32_t reserveCount) + inline void save(const Job &job, uint32_t reserveCount, Nonce::Backend backend) { m_index = job.index(); const size_t size = job.size(); m_jobs[index()] = job; m_rounds[index()] = 0; + m_jobs[index()].setBackend(backend); + for (size_t i = 0; i < N; ++i) { memcpy(m_blobs[index()] + (i * size), job.blob(), size); *nonce(i) = Nonce::next(index(), *nonce(i), reserveCount, job.isNicehash()); @@ -96,7 +98,7 @@ private: } - alignas(16) uint8_t m_blobs[2][Job::kMaxBlobSize * N]; + alignas(16) uint8_t m_blobs[2][Job::kMaxBlobSize * N]{}; Job m_jobs[2]; uint32_t m_rounds[2] = { 0, 0 }; uint64_t m_sequence = 0; @@ -126,12 +128,14 @@ inline void xmrig::WorkerJob<1>::nextRound(uint32_t rounds, uint32_t roundSize) template<> -inline void xmrig::WorkerJob<1>::save(const Job &job, uint32_t reserveCount) +inline void xmrig::WorkerJob<1>::save(const Job &job, uint32_t reserveCount, Nonce::Backend backend) { m_index = job.index(); m_jobs[index()] = job; m_rounds[index()] = 0; + m_jobs[index()].setBackend(backend); + memcpy(blob(), job.blob(), job.size()); *nonce() = Nonce::next(index(), *nonce(), reserveCount, currentJob().isNicehash()); } diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index 78b71e25..12cd34e5 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -210,6 +210,24 @@ public: } // namespace xmrig +const char *xmrig::backend_tag(uint32_t backend) +{ +# ifdef XMRIG_FEATURE_OPENCL + if (backend == Nonce::OPENCL) { + return ocl_tag(); + } +# endif + +# ifdef XMRIG_FEATURE_CUDA + if (backend == Nonce::CUDA) { + return cuda_tag(); + } +# endif + + return tag; +} + + const char *xmrig::cpu_tag() { return tag; diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index d6e917fb..f64882ba 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -303,7 +303,7 @@ void xmrig::CpuWorker::consumeJob() return; } - m_job.add(m_miner->job(), Nonce::sequence(Nonce::CPU), kReserveCount); + m_job.add(m_miner->job(), kReserveCount, Nonce::CPU); # ifdef XMRIG_ALGO_RANDOMX if (m_job.currentJob().algorithm().family() == Algorithm::RANDOM_X) { diff --git a/src/backend/cuda/CudaWorker.cpp b/src/backend/cuda/CudaWorker.cpp index 5e5ad413..b280e294 100644 --- a/src/backend/cuda/CudaWorker.cpp +++ b/src/backend/cuda/CudaWorker.cpp @@ -153,7 +153,7 @@ bool xmrig::CudaWorker::consumeJob() } const size_t batch_size = intensity(); - m_job.add(m_miner->job(), Nonce::sequence(Nonce::CUDA), roundSize(batch_size) * batch_size); + m_job.add(m_miner->job(), roundSize(batch_size) * batch_size, Nonce::CUDA); return m_runner->set(m_job.currentJob(), m_job.blob());; } diff --git a/src/backend/opencl/OclWorker.cpp b/src/backend/opencl/OclWorker.cpp index f79bc59b..83b83dae 100644 --- a/src/backend/opencl/OclWorker.cpp +++ b/src/backend/opencl/OclWorker.cpp @@ -206,7 +206,7 @@ bool xmrig::OclWorker::consumeJob() return false; } - m_job.add(m_miner->job(), Nonce::sequence(Nonce::OPENCL), roundSize(m_intensity) * m_intensity); + m_job.add(m_miner->job(), roundSize(m_intensity) * m_intensity, Nonce::OPENCL); try { m_runner->set(m_job.currentJob(), m_job.blob()); diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 3619e4e9..fed87092 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -214,7 +214,7 @@ int64_t xmrig::Client::submit(const JobResult &result) # ifdef XMRIG_PROXY_PROJECT m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id); # else - m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff()); + m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend); # endif return send(doc); diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 0870dc1d..7fa1a4a9 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -119,7 +119,7 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result) # ifdef XMRIG_PROXY_PROJECT m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id); # else - m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff()); + m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend); # endif send(HTTP_POST, kJsonRPC, doc); diff --git a/src/base/net/stratum/Job.cpp b/src/base/net/stratum/Job.cpp index ef1b03b5..1de1c19b 100644 --- a/src/base/net/stratum/Job.cpp +++ b/src/base/net/stratum/Job.cpp @@ -157,6 +157,7 @@ void xmrig::Job::copy(const Job &other) m_size = other.m_size; m_clientId = other.m_clientId; m_id = other.m_id; + m_backend = other.m_backend; m_diff = other.m_diff; m_height = other.m_height; m_target = other.m_target; @@ -174,3 +175,34 @@ void xmrig::Job::copy(const Job &other) memcpy(m_rawTarget, other.m_rawTarget, sizeof(m_rawTarget)); # endif } + + +void xmrig::Job::move(Job &&other) +{ + m_algorithm = other.m_algorithm; + m_nicehash = other.m_nicehash; + m_size = other.m_size; + m_clientId = std::move(other.m_clientId); + m_id = std::move(other.m_id); + m_backend = other.m_backend; + m_diff = other.m_diff; + m_height = other.m_height; + m_target = other.m_target; + m_index = other.m_index; + m_seed = std::move(other.m_seed); + m_extraNonce = std::move(other.m_extraNonce); + m_poolWallet = std::move(other.m_poolWallet); + + memcpy(m_blob, other.m_blob, sizeof(m_blob)); + + other.m_size = 0; + other.m_diff = 0; + other.m_algorithm = Algorithm::INVALID; + +# ifdef XMRIG_PROXY_PROJECT + m_rawSeedHash = std::move(other.m_rawSeedHash); + + memcpy(m_rawBlob, other.m_rawBlob, sizeof(m_rawBlob)); + memcpy(m_rawTarget, other.m_rawTarget, sizeof(m_rawTarget)); +# endif +} diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index 3c4c4724..09a42355 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -50,6 +50,10 @@ public: Job() = default; Job(bool nicehash, const Algorithm &algorithm, const String &clientId); + + inline Job(const Job &other) { copy(other); } + inline Job(Job &&other) noexcept { move(std::move(other)); } + ~Job() = default; bool isEqual(const Job &other) const; @@ -71,6 +75,7 @@ public: inline const uint8_t *blob() const { return m_blob; } inline size_t size() const { return m_size; } inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } + inline uint32_t backend() const { return m_backend; } inline uint64_t diff() const { return m_diff; } inline uint64_t height() const { return m_height; } inline uint64_t target() const { return m_target; } @@ -79,6 +84,7 @@ public: inline void reset() { m_size = 0; m_diff = 0; } inline void setAlgorithm(const Algorithm::Id id) { m_algorithm = id; } inline void setAlgorithm(const char *algo) { m_algorithm = algo; } + inline void setBackend(uint32_t backend) { m_backend = backend; } inline void setClientId(const String &id) { m_clientId = id; } inline void setExtraNonce(const String &extraNonce) { m_extraNonce = extraNonce; } inline void setHeight(uint64_t height) { m_height = height; } @@ -95,12 +101,14 @@ public: static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast(blob + 39); } static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; } - inline bool operator==(const Job &other) const { return isEqual(other); } inline bool operator!=(const Job &other) const { return !isEqual(other); } + inline bool operator==(const Job &other) const { return isEqual(other); } inline Job &operator=(const Job &other) { copy(other); return *this; } + inline Job &operator=(Job &&other) noexcept { move(std::move(other)); return *this; } private: void copy(const Job &other); + void move(Job &&other); Algorithm m_algorithm; bool m_nicehash = false; @@ -110,6 +118,7 @@ private: String m_extraNonce; String m_id; String m_poolWallet; + uint32_t m_backend = 0; uint64_t m_diff = 0; uint64_t m_height = 0; uint64_t m_target = 0; diff --git a/src/base/net/stratum/SubmitResult.h b/src/base/net/stratum/SubmitResult.h index 1b49acb4..a180f6fa 100644 --- a/src/base/net/stratum/SubmitResult.h +++ b/src/base/net/stratum/SubmitResult.h @@ -37,9 +37,10 @@ class SubmitResult public: SubmitResult() = default; - inline SubmitResult(int64_t seq, uint64_t diff, uint64_t actualDiff, int64_t reqId = 0) : + inline SubmitResult(int64_t seq, uint64_t diff, uint64_t actualDiff, int64_t reqId, uint32_t backend) : reqId(reqId), seq(seq), + backend(backend), actualDiff(actualDiff), diff(diff), m_start(Chrono::steadyMSecs()) @@ -49,6 +50,7 @@ public: int64_t reqId = 0; int64_t seq = 0; + uint32_t backend = 0; uint64_t actualDiff = 0; uint64_t diff = 0; uint64_t elapsed = 0; diff --git a/src/crypto/common/Nonce.h b/src/crypto/common/Nonce.h index 401139fd..7335663d 100644 --- a/src/crypto/common/Nonce.h +++ b/src/crypto/common/Nonce.h @@ -35,7 +35,7 @@ namespace xmrig { class Nonce { public: - enum Backend { + enum Backend : uint32_t { CPU, OPENCL, CUDA, diff --git a/src/net/JobResult.h b/src/net/JobResult.h index 87bf3be9..a44a639b 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -47,6 +47,7 @@ public: algorithm(job.algorithm()), clientId(job.clientId()), jobId(job.id()), + backend(job.backend()), nonce(nonce), diff(job.diff()), index(job.index()) @@ -61,9 +62,10 @@ public: const Algorithm algorithm; const String clientId; const String jobId; - const uint32_t nonce = 0; - const uint64_t diff = 0; - const uint8_t index = 0; + const uint32_t backend; + const uint32_t nonce; + const uint64_t diff; + const uint8_t index; private: uint8_t m_result[32] = { 0 }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 2fb40c6c..8c832934 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -34,6 +34,7 @@ #include +#include "backend/common/Tags.h" #include "base/io/log/Log.h" #include "base/net/stratum/Client.h" #include "base/net/stratum/SubmitResult.h" @@ -55,6 +56,22 @@ #endif +namespace xmrig { + + +static const char *tag = BLUE_BG_BOLD(WHITE_BOLD_S " net "); + + +} // namespace xmrig + + + +const char *xmrig::net_tag() +{ + return tag; +} + + xmrig::Network::Network(Controller *controller) : m_controller(controller), m_donate(nullptr), @@ -97,19 +114,19 @@ void xmrig::Network::connect() void xmrig::Network::onActive(IStrategy *strategy, IClient *client) { if (m_donate && m_donate == strategy) { - LOG_NOTICE("dev donate started"); + LOG_NOTICE("%s " WHITE_BOLD("dev donate started"), tag); return; } m_state.onActive(client); const char *tlsVersion = client->tlsVersion(); - LOG_INFO(WHITE_BOLD("use %s ") CYAN_BOLD("%s:%d ") GREEN_BOLD("%s") " " BLACK_BOLD("%s"), - client->mode(), client->pool().host().data(), client->pool().port(), tlsVersion ? tlsVersion : "", client->ip().data()); + LOG_INFO("%s " WHITE_BOLD("use %s ") CYAN_BOLD("%s:%d ") GREEN_BOLD("%s") " " BLACK_BOLD("%s"), + tag, client->mode(), client->pool().host().data(), client->pool().port(), tlsVersion ? tlsVersion : "", client->ip().data()); const char *fingerprint = client->tlsFingerprint(); if (fingerprint != nullptr) { - LOG_INFO(BLACK_BOLD("fingerprint (SHA-256): \"%s\""), fingerprint); + LOG_INFO("%s " BLACK_BOLD("fingerprint (SHA-256): \"%s\""), tag, fingerprint); } } @@ -178,12 +195,12 @@ void xmrig::Network::onLogin(IStrategy *, IClient *client, rapidjson::Document & void xmrig::Network::onPause(IStrategy *strategy) { if (m_donate && m_donate == strategy) { - LOG_NOTICE("dev donate finished"); + LOG_NOTICE("%s " WHITE_BOLD("dev donate finished"), tag); m_strategy->resume(); } if (!m_strategy->isActive()) { - LOG_ERR("no active pools, stop mining"); + LOG_ERR("%s " RED("no active pools, stop mining"), tag); m_state.stop(); return m_controller->miner()->pause(); @@ -196,12 +213,12 @@ void xmrig::Network::onResultAccepted(IStrategy *, IClient *, const SubmitResult m_state.add(result, error); if (error) { - LOG_INFO(RED_BOLD("rejected") " (%" PRId64 "/%" PRId64 ") diff " WHITE_BOLD("%" PRIu64) " " RED("\"%s\"") " " BLACK_BOLD("(%" PRIu64 " ms)"), - m_state.accepted, m_state.rejected, result.diff, error, result.elapsed); + LOG_INFO("%s " RED_BOLD("rejected") " (%" PRId64 "/%" PRId64 ") diff " WHITE_BOLD("%" PRIu64) " " RED("\"%s\"") " " BLACK_BOLD("(%" PRIu64 " ms)"), + backend_tag(result.backend), m_state.accepted, m_state.rejected, result.diff, error, result.elapsed); } else { - LOG_INFO(GREEN_BOLD("accepted") " (%" PRId64 "/%" PRId64 ") diff " WHITE_BOLD("%" PRIu64) " " BLACK_BOLD("(%" PRIu64 " ms)"), - m_state.accepted, m_state.rejected, result.diff, result.elapsed); + LOG_INFO("%s " GREEN_BOLD("accepted") " (%" PRId64 "/%" PRId64 ") diff " WHITE_BOLD("%" PRIu64) " " BLACK_BOLD("(%" PRIu64 " ms)"), + backend_tag(result.backend), m_state.accepted, m_state.rejected, result.diff, result.elapsed); } } @@ -232,12 +249,12 @@ void xmrig::Network::onRequest(IApiRequest &request) void xmrig::Network::setJob(IClient *client, const Job &job, bool donate) { if (job.height()) { - LOG_INFO(MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%" PRIu64) " algo " WHITE_BOLD("%s") " height " WHITE_BOLD("%" PRIu64), - client->pool().host().data(), client->pool().port(), job.diff(), job.algorithm().shortName(), job.height()); + LOG_INFO("%s " MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%" PRIu64) " algo " WHITE_BOLD("%s") " height " WHITE_BOLD("%" PRIu64), + tag, client->pool().host().data(), client->pool().port(), job.diff(), job.algorithm().shortName(), job.height()); } else { - LOG_INFO(MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%" PRIu64) " algo " WHITE_BOLD("%s"), - client->pool().host().data(), client->pool().port(), job.diff(), job.algorithm().shortName()); + LOG_INFO("%s " MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%" PRIu64) " algo " WHITE_BOLD("%s"), + tag, client->pool().host().data(), client->pool().port(), job.diff(), job.algorithm().shortName()); } if (!donate && m_donate) { From 3bdf7111cef4d59ec21b1872f81f4527b9050722 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 29 Oct 2019 17:18:46 +0700 Subject: [PATCH 17/27] Fixed singular form for threads. --- src/backend/cpu/CpuBackend.cpp | 3 ++- src/backend/cuda/CudaBackend.cpp | 3 ++- src/backend/opencl/OclBackend.cpp | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index 12cd34e5..ddee6768 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -146,10 +146,11 @@ public: inline void start() { - LOG_INFO("%s use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), + LOG_INFO("%s use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" thread%s)") " scratchpad " CYAN_BOLD("%zu KB"), tag, profileName.data(), threads.size(), + threads.size() > 1 ? "s" : "", algo.l3() / 1024 ); diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index 2a2f8ea1..db0d512e 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -171,10 +171,11 @@ public: inline void start(const Job &) { - LOG_INFO("%s use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), + LOG_INFO("%s use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" thread%s)") " scratchpad " CYAN_BOLD("%zu KB"), tag, profileName.data(), threads.size(), + threads.size() > 1 ? "s" : "", algo.l3() / 1024 ); diff --git a/src/backend/opencl/OclBackend.cpp b/src/backend/opencl/OclBackend.cpp index c9fef1f9..bbf60443 100644 --- a/src/backend/opencl/OclBackend.cpp +++ b/src/backend/opencl/OclBackend.cpp @@ -168,10 +168,11 @@ public: inline void start(const Job &job) { - LOG_INFO("%s use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), + LOG_INFO("%s use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" thread%s)") " scratchpad " CYAN_BOLD("%zu KB"), tag, profileName.data(), threads.size(), + threads.size() > 1 ? "s" : "", algo.l3() / 1024 ); From 9d580693db49f788f10ff35174ad7c7aee8326df Mon Sep 17 00:00:00 2001 From: xmrig Date: Tue, 29 Oct 2019 17:26:03 +0700 Subject: [PATCH 18/27] Update CMAKE_OPTIONS.md --- doc/build/CMAKE_OPTIONS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/build/CMAKE_OPTIONS.md b/doc/build/CMAKE_OPTIONS.md index 8cb66eec..fad15f50 100644 --- a/doc/build/CMAKE_OPTIONS.md +++ b/doc/build/CMAKE_OPTIONS.md @@ -21,6 +21,8 @@ This feature add external dependency to libhwloc (1.10.0+) (except MSVC builds). * **`-DWITH_TLS=OFF`** disable SSL/TLS support (secure connections to pool). This feature add external dependency to OpenSSL. * **`-DWITH_ASM=OFF`** disable assembly optimizations for modern CryptoNight algorithms. * **`-DWITH_EMBEDDED_CONFIG=ON`** Enable [embedded](https://github.com/xmrig/xmrig/issues/957) config support. +* **`-DWITH_OPENCL=OFF`** Disable OpenCL backend. +* **`-DWITH_CUDA=OFF`** Disable CUDA backend. ## Debug options From 175a7b06b7795061d0fc79289aae90955b0ba5c8 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 30 Oct 2019 15:33:06 +0700 Subject: [PATCH 19/27] Added initial NVML stub. --- CMakeLists.txt | 1 + src/backend/cuda/CudaBackend.cpp | 55 +++++++++-- src/backend/cuda/CudaConfig.cpp | 23 +++++ src/backend/cuda/CudaConfig.h | 10 ++ src/backend/cuda/cuda.cmake | 14 +++ src/backend/cuda/wrappers/CudaLib.cpp | 1 - src/backend/cuda/wrappers/NvmlLib.cpp | 136 ++++++++++++++++++++++++++ src/backend/cuda/wrappers/NvmlLib.h | 62 ++++++++++++ src/backend/cuda/wrappers/nvml_lite.h | 38 +++++++ src/crypto/common/Nonce.cpp | 12 +-- 10 files changed, 335 insertions(+), 17 deletions(-) create mode 100644 src/backend/cuda/wrappers/NvmlLib.cpp create mode 100644 src/backend/cuda/wrappers/NvmlLib.h create mode 100644 src/backend/cuda/wrappers/nvml_lite.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a195f6e..849c1257 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ option(WITH_ASM "Enable ASM PoW implementations" ON) option(WITH_EMBEDDED_CONFIG "Enable internal embedded JSON config" OFF) option(WITH_OPENCL "Enable OpenCL backend" ON) option(WITH_CUDA "Enable CUDA backend" ON) +option(WITH_NVML "Enable NVML (NVIDIA Management Library) support (only if CUDA backend enabled)" ON) option(WITH_STRICT_CACHE "Enable strict checks for OpenCL cache" ON) option(WITH_INTERLEAVE_DEBUG_LOG "Enable debug log for threads interleave" OFF) diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index db0d512e..a8cfa688 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -51,6 +51,13 @@ #endif +#ifdef XMRIG_FEATURE_NVML +#include "backend/cuda/wrappers/NvmlLib.h" + +namespace xmrig { static const char *kNvmlLabel = "NVML"; } +#endif + + namespace xmrig { @@ -58,15 +65,16 @@ extern template class Threads; constexpr const size_t oneMiB = 1024u * 1024u; +static const char *kLabel = "CUDA"; static const char *tag = GREEN_BG_BOLD(WHITE_BOLD_S " nv "); static const String kType = "cuda"; static std::mutex mutex; -static void printDisabled(const char *reason) +static void printDisabled(const char *label, const char *reason) { - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") RED_BOLD("disabled") "%s", "CUDA", reason); + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") RED_BOLD("disabled") "%s", label, reason); } @@ -129,29 +137,44 @@ public: void init(const CudaConfig &cuda) { if (!cuda.isEnabled()) { - return printDisabled(""); + return printDisabled(kLabel, ""); } if (!CudaLib::init(cuda.loader())) { - return printDisabled(RED_S " (failed to load CUDA plugin)"); + return printDisabled(kLabel, RED_S " (failed to load CUDA plugin)"); } runtimeVersion = CudaLib::runtimeVersion(); driverVersion = CudaLib::driverVersion(); if (!runtimeVersion || !driverVersion || !CudaLib::deviceCount()) { - return printDisabled(RED_S " (no devices)"); + return printDisabled(kLabel, RED_S " (no devices)"); } if (!devices.empty()) { return; } - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") "/" WHITE_BOLD("%s") BLACK_BOLD("/%s"), "CUDA", + 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())) { + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") "/" GREEN_BOLD("%s"), kNvmlLabel, + NvmlLib::version(), NvmlLib::driverVersion()); + } + else { + printDisabled(kLabel, RED_S " (failed to load NVML)"); + } + } + else { + printDisabled(kNvmlLabel, ""); + } +# endif + for (const CudaDevice &device : devices) { Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu") YELLOW(" %s") GREEN_BOLD(" %s ") WHITE_BOLD("%u/%u MHz") " smx:" WHITE_BOLD("%u") " arch:" WHITE_BOLD("%u%u") " mem:" CYAN("%zu/%zu") " MB", "CUDA GPU", @@ -238,6 +261,10 @@ xmrig::CudaBackend::~CudaBackend() delete d_ptr; CudaLib::close(); + +# ifdef XMRIG_FEATURE_NVML + NvmlLib::close(); +# endif } @@ -394,10 +421,18 @@ rapidjson::Value xmrig::CudaBackend::toJSON(rapidjson::Document &doc) const out.AddMember("profile", profileName().toJSON(), allocator); Value versions(kObjectType); - versions.AddMember("runtime", Value(CudaLib::version(d_ptr->runtimeVersion).c_str(), allocator), allocator); - versions.AddMember("driver", Value(CudaLib::version(d_ptr->driverVersion).c_str(), allocator), allocator); - versions.AddMember("plugin", String(CudaLib::pluginVersion()).toJSON(doc), allocator); - out.AddMember("versions", versions, allocator); + versions.AddMember("cuda-runtime", Value(CudaLib::version(d_ptr->runtimeVersion).c_str(), allocator), allocator); + versions.AddMember("cuda-driver", Value(CudaLib::version(d_ptr->driverVersion).c_str(), allocator), allocator); + versions.AddMember("plugin", String(CudaLib::pluginVersion()).toJSON(doc), allocator); + +# ifdef XMRIG_FEATURE_NVML + if (NvmlLib::isReady()) { + versions.AddMember("nvml", StringRef(NvmlLib::version()), allocator); + versions.AddMember("driver", StringRef(NvmlLib::driverVersion()), allocator); + } +# endif + + out.AddMember("versions", versions, allocator); if (d_ptr->threads.empty() || !hashrate()) { return out; diff --git a/src/backend/cuda/CudaConfig.cpp b/src/backend/cuda/CudaConfig.cpp index 19817c65..49a28d11 100644 --- a/src/backend/cuda/CudaConfig.cpp +++ b/src/backend/cuda/CudaConfig.cpp @@ -40,6 +40,10 @@ static const char *kDevicesHint = "devices-hint"; static const char *kEnabled = "enabled"; static const char *kLoader = "loader"; +#ifdef XMRIG_FEATURE_NVML +static const char *kNvml = "nvml"; +#endif + extern template class Threads; @@ -57,6 +61,15 @@ rapidjson::Value xmrig::CudaConfig::toJSON(rapidjson::Document &doc) const obj.AddMember(StringRef(kEnabled), m_enabled, allocator); obj.AddMember(StringRef(kLoader), m_loader.toJSON(), allocator); +# ifdef XMRIG_FEATURE_NVML + if (m_nvmlLoader.isNull()) { + obj.AddMember(StringRef(kNvml), m_nvml, allocator); + } + else { + obj.AddMember(StringRef(kNvml), m_nvmlLoader.toJSON(), allocator); + } +# endif + m_threads.toJSON(obj, doc); return obj; @@ -95,6 +108,16 @@ void xmrig::CudaConfig::read(const rapidjson::Value &value) setDevicesHint(Json::getString(value, kDevicesHint)); +# ifdef XMRIG_FEATURE_NVML + auto &nvml = Json::getValue(value, kNvml); + if (nvml.IsString()) { + m_nvmlLoader = nvml.GetString(); + } + else if (nvml.IsBool()) { + m_nvml = nvml.GetBool(); + } +# endif + m_threads.read(value); generate(); diff --git a/src/backend/cuda/CudaConfig.h b/src/backend/cuda/CudaConfig.h index 4367d826..77be3dd4 100644 --- a/src/backend/cuda/CudaConfig.h +++ b/src/backend/cuda/CudaConfig.h @@ -50,6 +50,11 @@ public: 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; } +# endif + private: void generate(); void setDevicesHint(const char *devicesHint); @@ -67,6 +72,11 @@ private: int32_t m_bfactor = 0; int32_t m_bsleep = 0; # endif + +# ifdef XMRIG_FEATURE_NVML + bool m_nvml = true; + String m_nvmlLoader; +# endif }; diff --git a/src/backend/cuda/cuda.cmake b/src/backend/cuda/cuda.cmake index 764acd0f..a5dd27b8 100644 --- a/src/backend/cuda/cuda.cmake +++ b/src/backend/cuda/cuda.cmake @@ -30,8 +30,22 @@ if (WITH_CUDA) src/backend/cuda/wrappers/CudaDevice.cpp src/backend/cuda/wrappers/CudaLib.cpp ) + + if (WITH_NVML AND NOT APPLE) + add_definitions(/DXMRIG_FEATURE_NVML) + + list(APPEND HEADERS_BACKEND_CUDA + src/backend/cuda/wrappers/nvml_lite.h + src/backend/cuda/wrappers/NvmlLib.h + ) + + list(APPEND SOURCES_BACKEND_CUDA src/backend/cuda/wrappers/NvmlLib.cpp) + else() + remove_definitions(/DXMRIG_FEATURE_NVML) + endif() else() remove_definitions(/DXMRIG_FEATURE_CUDA) + remove_definitions(/DXMRIG_FEATURE_NVML) set(HEADERS_BACKEND_CUDA "") set(SOURCES_BACKEND_CUDA "") diff --git a/src/backend/cuda/wrappers/CudaLib.cpp b/src/backend/cuda/wrappers/CudaLib.cpp index 5f3018d3..7264d67d 100644 --- a/src/backend/cuda/wrappers/CudaLib.cpp +++ b/src/backend/cuda/wrappers/CudaLib.cpp @@ -28,7 +28,6 @@ #include "backend/cuda/wrappers/CudaLib.h" -#include "base/io/log/Log.h" namespace xmrig { diff --git a/src/backend/cuda/wrappers/NvmlLib.cpp b/src/backend/cuda/wrappers/NvmlLib.cpp new file mode 100644 index 00000000..2eb731cc --- /dev/null +++ b/src/backend/cuda/wrappers/NvmlLib.cpp @@ -0,0 +1,136 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include + + +#include "backend/cuda/wrappers/NvmlLib.h" +#include "backend/cuda/wrappers/nvml_lite.h" +#include "base/io/log/Log.h" + + + +namespace xmrig { + + +static uv_lib_t nvmlLib; + + +static const char *kNvmlInit = "nvmlInit_v2"; +static const char *kNvmlShutdown = "nvmlShutdown"; +static const char *kNvmlSystemGetDriverVersion = "nvmlSystemGetDriverVersion"; +static const char *kNvmlSystemGetNVMLVersion = "nvmlSystemGetNVMLVersion"; +static const char *kSymbolNotFound = "symbol not found"; + + +static nvmlReturn_t (*pNvmlInit)() = nullptr; +static nvmlReturn_t (*pNvmlShutdown)() = nullptr; +static nvmlReturn_t (*pNvmlSystemGetDriverVersion)(char *version, unsigned int length) = nullptr; +static nvmlReturn_t (*pNvmlSystemGetNVMLVersion)(char *version, unsigned int length) = nullptr; + + +#define DLSYM(x) if (uv_dlsym(&nvmlLib, k##x, reinterpret_cast(&p##x)) == -1) { throw std::runtime_error(kSymbolNotFound); } + + +bool NvmlLib::m_initialized = false; +bool NvmlLib::m_ready = false; +char NvmlLib::m_driverVersion[80] = { 0 }; +char NvmlLib::m_nvmlVersion[80] = { 0 }; +String NvmlLib::m_loader; + + +} // namespace xmrig + + +bool xmrig::NvmlLib::init(const char *fileName) +{ + if (!m_initialized) { + m_loader = fileName; + m_ready = dlopen() && load(); + m_initialized = true; + } + + return m_ready; +} + + +const char *xmrig::NvmlLib::lastError() noexcept +{ + return uv_dlerror(&nvmlLib); +} + + +void xmrig::NvmlLib::close() +{ + if (m_ready) { + pNvmlShutdown(); + } + + uv_dlclose(&nvmlLib); +} + + +bool xmrig::NvmlLib::dlopen() +{ + if (!m_loader.isNull()) { + return uv_dlopen(m_loader, &nvmlLib) == 0; + } + +# ifdef _WIN32 + if (uv_dlopen("nvml.dll", &nvmlLib) == 0) { + return true; + } + + char path[MAX_PATH] = { 0 }; + ExpandEnvironmentStringsA("%PROGRAMFILES%\\NVIDIA Corporation\\NVSMI\\nvml.dll", path, sizeof(path)); + + return uv_dlopen(path, &nvmlLib) == 0; +# else + return uv_dlopen("libnvidia-ml.so", &nvmlLib) == 0; +# endif +} + + +bool xmrig::NvmlLib::load() +{ + try { + DLSYM(NvmlInit); + DLSYM(NvmlShutdown); + DLSYM(NvmlSystemGetDriverVersion); + DLSYM(NvmlSystemGetNVMLVersion); + } catch (std::exception &ex) { + return false; + } + + if (pNvmlInit() != NVML_SUCCESS) { + return false; + } + + pNvmlSystemGetDriverVersion(m_driverVersion, sizeof(m_driverVersion)); + pNvmlSystemGetNVMLVersion(m_nvmlVersion, sizeof(m_nvmlVersion)); + + return true; +} diff --git a/src/backend/cuda/wrappers/NvmlLib.h b/src/backend/cuda/wrappers/NvmlLib.h new file mode 100644 index 00000000..395858f5 --- /dev/null +++ b/src/backend/cuda/wrappers/NvmlLib.h @@ -0,0 +1,62 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_NVMLLIB_H +#define XMRIG_NVMLLIB_H + + +#include "base/tools/String.h" + + +namespace xmrig { + + +class NvmlLib +{ +public: + static bool init(const char *fileName = nullptr); + static const char *lastError() noexcept; + static void close(); + + static inline bool isInitialized() noexcept { return m_initialized; } + static inline bool isReady() noexcept { return m_ready; } + static inline const char *driverVersion() noexcept { return m_driverVersion; } + static inline const char *version() noexcept { return m_nvmlVersion; } + +private: + static bool dlopen(); + static bool load(); + + static bool m_initialized; + static bool m_ready; + static char m_driverVersion[80]; + static char m_nvmlVersion[80]; + static String m_loader; +}; + + +} // namespace xmrig + + +#endif /* XMRIG_NVMLLIB_H */ diff --git a/src/backend/cuda/wrappers/nvml_lite.h b/src/backend/cuda/wrappers/nvml_lite.h new file mode 100644 index 00000000..1de6e657 --- /dev/null +++ b/src/backend/cuda/wrappers/nvml_lite.h @@ -0,0 +1,38 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_NVML_LITE_H +#define XMRIG_NVML_LITE_H + + +#include + + +#define NVML_SUCCESS 0 + + +using nvmlReturn_t = uint32_t; + + +#endif /* XMRIG_NVML_LITE_H */ diff --git a/src/crypto/common/Nonce.cpp b/src/crypto/common/Nonce.cpp index e79cb310..897045ca 100644 --- a/src/crypto/common/Nonce.cpp +++ b/src/crypto/common/Nonce.cpp @@ -48,8 +48,8 @@ xmrig::Nonce::Nonce() { m_paused = true; - for (int i = 0; i < MAX; ++i) { - m_sequence[i] = 1; + for (auto &i : m_sequence) { + i = 1; } } @@ -85,15 +85,15 @@ void xmrig::Nonce::stop() { pause(false); - for (int i = 0; i < MAX; ++i) { - m_sequence[i] = 0; + for (auto &i : m_sequence) { + i = 0; } } void xmrig::Nonce::touch() { - for (int i = 0; i < MAX; ++i) { - m_sequence[i]++; + for (auto &i : m_sequence) { + i++; } } From 83f437f9793e3aa7b5cd8e3a702ce49aa9a7ab6d Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 30 Oct 2019 20:26:21 +0700 Subject: [PATCH 20/27] Implemented NvmlLib. --- src/backend/cuda/CudaBackend.cpp | 2 + src/backend/cuda/cuda.cmake | 1 + src/backend/cuda/wrappers/CudaDevice.cpp | 23 ++++++ src/backend/cuda/wrappers/CudaDevice.h | 22 ++++-- src/backend/cuda/wrappers/NvmlHealth.h | 43 ++++++++++ src/backend/cuda/wrappers/NvmlLib.cpp | 99 +++++++++++++++++++++++- src/backend/cuda/wrappers/NvmlLib.h | 6 +- src/backend/cuda/wrappers/nvml_lite.h | 19 ++++- 8 files changed, 203 insertions(+), 12 deletions(-) create mode 100644 src/backend/cuda/wrappers/NvmlHealth.h diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index a8cfa688..6abd79b5 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -163,6 +163,8 @@ public: # ifdef XMRIG_FEATURE_NVML if (cuda.isNvmlEnabled()) { if (NvmlLib::init(cuda.nvmlLoader())) { + NvmlLib::assign(devices); + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") "/" GREEN_BOLD("%s"), kNvmlLabel, NvmlLib::version(), NvmlLib::driverVersion()); } diff --git a/src/backend/cuda/cuda.cmake b/src/backend/cuda/cuda.cmake index a5dd27b8..58ba3f5a 100644 --- a/src/backend/cuda/cuda.cmake +++ b/src/backend/cuda/cuda.cmake @@ -36,6 +36,7 @@ if (WITH_CUDA) list(APPEND HEADERS_BACKEND_CUDA src/backend/cuda/wrappers/nvml_lite.h + src/backend/cuda/wrappers/NvmlHealth.h src/backend/cuda/wrappers/NvmlLib.h ) diff --git a/src/backend/cuda/wrappers/CudaDevice.cpp b/src/backend/cuda/wrappers/CudaDevice.cpp index 740a063c..efacc800 100644 --- a/src/backend/cuda/wrappers/CudaDevice.cpp +++ b/src/backend/cuda/wrappers/CudaDevice.cpp @@ -30,6 +30,9 @@ #include "crypto/common/Algorithm.h" #include "rapidjson/document.h" +#ifdef XMRIG_FEATURE_NVML +# include "backend/cuda/wrappers/NvmlLib.h" +#endif #include @@ -125,5 +128,25 @@ void xmrig::CudaDevice::toJSON(rapidjson::Value &out, rapidjson::Document &doc) out.AddMember("global_mem", static_cast(globalMemSize()), allocator); out.AddMember("clock", clock(), allocator); out.AddMember("memory_clock", memoryClock(), allocator); + +# ifdef XMRIG_FEATURE_NVML + if (m_nvmlDevice) { + auto data = NvmlLib::health(m_nvmlDevice); + + Value health(kObjectType); + health.AddMember("temperature", data.temperature, allocator); + health.AddMember("power", data.power, allocator); + health.AddMember("clock", data.clock, allocator); + health.AddMember("mem_clock", data.memClock, allocator); + + Value fanSpeed(kArrayType); + for (auto speed : data.fanSpeed) { + fanSpeed.PushBack(speed, allocator); + } + health.AddMember("fan_speed", fanSpeed, allocator); + + out.AddMember("health", health, allocator); + } +# endif } #endif diff --git a/src/backend/cuda/wrappers/CudaDevice.h b/src/backend/cuda/wrappers/CudaDevice.h index 07866c82..8c624c85 100644 --- a/src/backend/cuda/wrappers/CudaDevice.h +++ b/src/backend/cuda/wrappers/CudaDevice.h @@ -30,7 +30,8 @@ #include "base/tools/String.h" -using nvid_ctx = struct nvid_ctx; +using nvid_ctx = struct nvid_ctx; +using nvmlDevice_t = struct nvmlDevice_st *; namespace xmrig { @@ -57,11 +58,16 @@ public: uint32_t smx() const; void generate(const Algorithm &algorithm, CudaThreads &threads) const; - inline bool isValid() const { return m_ctx != nullptr; } - inline const PciTopology &topology() const { return m_topology; } - inline const String &name() const { return m_name; } - inline uint32_t arch() const { return (computeCapability(true) * 10) + computeCapability(false); } - inline uint32_t index() const { return m_index; } + inline bool isValid() const { return m_ctx != nullptr; } + inline const PciTopology &topology() const { return m_topology; } + inline const String &name() const { return m_name; } + inline uint32_t arch() const { return (computeCapability(true) * 10) + computeCapability(false); } + inline uint32_t index() const { return m_index; } + +# ifdef XMRIG_FEATURE_NVML + inline nvmlDevice_t nvmlDevice() const { return m_nvmlDevice; } + inline void setNvmlDevice(nvmlDevice_t device) { m_nvmlDevice = device; } +# endif # ifdef XMRIG_FEATURE_API void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const; @@ -75,6 +81,10 @@ private: nvid_ctx *m_ctx = nullptr; PciTopology m_topology; String m_name; + +# ifdef XMRIG_FEATURE_NVML + nvmlDevice_t m_nvmlDevice = nullptr; +# endif }; diff --git a/src/backend/cuda/wrappers/NvmlHealth.h b/src/backend/cuda/wrappers/NvmlHealth.h new file mode 100644 index 00000000..58c1d3eb --- /dev/null +++ b/src/backend/cuda/wrappers/NvmlHealth.h @@ -0,0 +1,43 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_NVMLHEALTH_H +#define XMRIG_NVMLHEALTH_H + + +#include +#include + + +struct NvmlHealth +{ + std::vector fanSpeed; + uint32_t clock = 0; + uint32_t memClock = 0; + uint32_t power = 0; + uint32_t temperature = 0; +}; + + +#endif /* XMRIG_NVMLHEALTH_H */ diff --git a/src/backend/cuda/wrappers/NvmlLib.cpp b/src/backend/cuda/wrappers/NvmlLib.cpp index 2eb731cc..cb05bdc1 100644 --- a/src/backend/cuda/wrappers/NvmlLib.cpp +++ b/src/backend/cuda/wrappers/NvmlLib.cpp @@ -39,6 +39,14 @@ namespace xmrig { static uv_lib_t nvmlLib; +static const char *kNvmlDeviceGetClockInfo = "nvmlDeviceGetClockInfo"; +static const char *kNvmlDeviceGetCount = "nvmlDeviceGetCount_v2"; +static const char *kNvmlDeviceGetFanSpeed = "nvmlDeviceGetFanSpeed"; +static const char *kNvmlDeviceGetFanSpeed_v2 = "nvmlDeviceGetFanSpeed_v2"; +static const char *kNvmlDeviceGetHandleByIndex = "nvmlDeviceGetHandleByIndex_v2"; +static const char *kNvmlDeviceGetPciInfo = "nvmlDeviceGetPciInfo_v2"; +static const char *kNvmlDeviceGetPowerUsage = "nvmlDeviceGetPowerUsage"; +static const char *kNvmlDeviceGetTemperature = "nvmlDeviceGetTemperature"; static const char *kNvmlInit = "nvmlInit_v2"; static const char *kNvmlShutdown = "nvmlShutdown"; static const char *kNvmlSystemGetDriverVersion = "nvmlSystemGetDriverVersion"; @@ -46,10 +54,18 @@ static const char *kNvmlSystemGetNVMLVersion = "nvmlSyste static const char *kSymbolNotFound = "symbol not found"; -static nvmlReturn_t (*pNvmlInit)() = nullptr; -static nvmlReturn_t (*pNvmlShutdown)() = nullptr; -static nvmlReturn_t (*pNvmlSystemGetDriverVersion)(char *version, unsigned int length) = nullptr; -static nvmlReturn_t (*pNvmlSystemGetNVMLVersion)(char *version, unsigned int length) = nullptr; +static nvmlReturn_t (*pNvmlDeviceGetClockInfo)(nvmlDevice_t device, uint32_t type, uint32_t *clock) = nullptr; +static nvmlReturn_t (*pNvmlDeviceGetCount)(uint32_t *deviceCount) = nullptr; +static nvmlReturn_t (*pNvmlDeviceGetFanSpeed_v2)(nvmlDevice_t device, uint32_t fan, uint32_t *speed) = nullptr; +static nvmlReturn_t (*pNvmlDeviceGetFanSpeed)(nvmlDevice_t device, uint32_t *speed) = nullptr; +static nvmlReturn_t (*pNvmlDeviceGetHandleByIndex)(uint32_t index, nvmlDevice_t *device) = nullptr; +static nvmlReturn_t (*pNvmlDeviceGetPciInfo)(nvmlDevice_t device, nvmlPciInfo_t *pci) = nullptr; +static nvmlReturn_t (*pNvmlDeviceGetPowerUsage)(nvmlDevice_t device, uint32_t *power) = nullptr; +static nvmlReturn_t (*pNvmlDeviceGetTemperature)(nvmlDevice_t device, uint32_t sensorType, uint32_t *temp) = nullptr; +static nvmlReturn_t (*pNvmlInit)() = nullptr; +static nvmlReturn_t (*pNvmlShutdown)() = nullptr; +static nvmlReturn_t (*pNvmlSystemGetDriverVersion)(char *version, uint32_t length) = nullptr; +static nvmlReturn_t (*pNvmlSystemGetNVMLVersion)(char *version, uint32_t length) = nullptr; #define DLSYM(x) if (uv_dlsym(&nvmlLib, k##x, reinterpret_cast(&p##x)) == -1) { throw std::runtime_error(kSymbolNotFound); } @@ -93,6 +109,72 @@ void xmrig::NvmlLib::close() } +bool xmrig::NvmlLib::assign(std::vector &devices) +{ + uint32_t count = 0; + if (pNvmlDeviceGetCount(&count) != NVML_SUCCESS) { + return false; + } + + for (uint32_t i = 0; i < count; i++) { + nvmlDevice_t nvmlDevice; + if (pNvmlDeviceGetHandleByIndex(i, &nvmlDevice) != NVML_SUCCESS) { + continue; + } + + nvmlPciInfo_t pci; + if (pNvmlDeviceGetPciInfo(nvmlDevice, &pci) != NVML_SUCCESS) { + continue; + } + + for (auto &device : devices) { + if (device.topology().bus() == pci.bus && device.topology().device() == pci.device) { + device.setNvmlDevice(nvmlDevice); + } + } + } + + return true; +} + + +NvmlHealth xmrig::NvmlLib::health(nvmlDevice_t device) +{ + if (!device) { + return {}; + } + + NvmlHealth health; + pNvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &health.temperature); + pNvmlDeviceGetPowerUsage(device, &health.power); + pNvmlDeviceGetClockInfo(device, NVML_CLOCK_SM, &health.clock); + pNvmlDeviceGetClockInfo(device, NVML_CLOCK_MEM, &health.memClock); + + if (health.power) { + health.power /= 1000; + } + + uint32_t speed = 0; + + if (pNvmlDeviceGetFanSpeed_v2) { + uint32_t i = 0; + + while (pNvmlDeviceGetFanSpeed_v2(device, i, &speed) == NVML_SUCCESS) { + health.fanSpeed.push_back(speed); + ++i; + } + + } + else { + pNvmlDeviceGetFanSpeed(device, &speed); + + health.fanSpeed.push_back(speed); + } + + return health; +} + + bool xmrig::NvmlLib::dlopen() { if (!m_loader.isNull()) { @@ -117,6 +199,13 @@ bool xmrig::NvmlLib::dlopen() bool xmrig::NvmlLib::load() { try { + DLSYM(NvmlDeviceGetClockInfo); + DLSYM(NvmlDeviceGetCount); + DLSYM(NvmlDeviceGetFanSpeed); + DLSYM(NvmlDeviceGetHandleByIndex); + DLSYM(NvmlDeviceGetPciInfo); + DLSYM(NvmlDeviceGetPowerUsage); + DLSYM(NvmlDeviceGetTemperature); DLSYM(NvmlInit); DLSYM(NvmlShutdown); DLSYM(NvmlSystemGetDriverVersion); @@ -125,6 +214,8 @@ bool xmrig::NvmlLib::load() return false; } + uv_dlsym(&nvmlLib, kNvmlDeviceGetFanSpeed_v2, reinterpret_cast(&pNvmlDeviceGetFanSpeed_v2)); + if (pNvmlInit() != NVML_SUCCESS) { return false; } diff --git a/src/backend/cuda/wrappers/NvmlLib.h b/src/backend/cuda/wrappers/NvmlLib.h index 395858f5..85b80d0c 100644 --- a/src/backend/cuda/wrappers/NvmlLib.h +++ b/src/backend/cuda/wrappers/NvmlLib.h @@ -26,7 +26,8 @@ #define XMRIG_NVMLLIB_H -#include "base/tools/String.h" +#include "backend/cuda/wrappers/CudaDevice.h" +#include "backend/cuda/wrappers/NvmlHealth.h" namespace xmrig { @@ -39,6 +40,9 @@ public: static const char *lastError() noexcept; static void close(); + static bool assign(std::vector &devices); + static NvmlHealth health(nvmlDevice_t device); + static inline bool isInitialized() noexcept { return m_initialized; } static inline bool isReady() noexcept { return m_ready; } static inline const char *driverVersion() noexcept { return m_driverVersion; } diff --git a/src/backend/cuda/wrappers/nvml_lite.h b/src/backend/cuda/wrappers/nvml_lite.h index 1de6e657..4472847c 100644 --- a/src/backend/cuda/wrappers/nvml_lite.h +++ b/src/backend/cuda/wrappers/nvml_lite.h @@ -29,10 +29,27 @@ #include -#define NVML_SUCCESS 0 +#define NVML_SUCCESS 0 +#define NVML_TEMPERATURE_GPU 0 +#define NVML_CLOCK_SM 1 +#define NVML_CLOCK_MEM 2 using nvmlReturn_t = uint32_t; +using nvmlDevice_t = struct nvmlDevice_st *; + + +struct nvmlPciInfo_t +{ + char busIdLegacy[16]{}; + unsigned int domain = 0; + unsigned int bus = 0; + unsigned int device = 0; + unsigned int pciDeviceId = 0; + unsigned int pciSubSystemId = 0; + + char busId[32]{}; +}; #endif /* XMRIG_NVML_LITE_H */ From f110b5000bcc26d2780fceaf57058b3dae7ab99b Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 30 Oct 2019 22:40:09 +0700 Subject: [PATCH 21/27] Fixed switching from non RandomX algorithm to RandomX. --- src/core/Miner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 0caf298f..762539c1 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -393,7 +393,7 @@ void xmrig::Miner::setJob(const Job &job, bool donate) } # ifdef XMRIG_ALGO_RANDOMX - if (d_ptr->algorithm.family() == Algorithm::RANDOM_X && job.algorithm().family() == Algorithm::RANDOM_X && !Rx::isReady(job)) { + if (job.algorithm().family() == Algorithm::RANDOM_X && !Rx::isReady(job)) { stop(); } # endif From 1cb4d73fe3f1a39da46a6353d4e619b2acd0d956 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 1 Nov 2019 00:09:28 +0700 Subject: [PATCH 22/27] Added manual (e key) health reports. --- src/App.cpp | 25 ++---------- src/Summary.cpp | 6 +-- src/backend/common/interfaces/IBackend.h | 1 + src/backend/cpu/CpuBackend.h | 2 + src/backend/cuda/CudaBackend.cpp | 49 +++++++++++++++++++++++- src/backend/cuda/CudaBackend.h | 1 + src/backend/opencl/OclBackend.h | 2 + src/core/Miner.cpp | 28 ++++++++++++++ src/core/Miner.h | 1 + 9 files changed, 89 insertions(+), 26 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index 7db2ace2..04b05451 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -98,29 +98,12 @@ int xmrig::App::exec() void xmrig::App::onConsoleCommand(char command) { - switch (command) { - case 'h': - case 'H': - m_controller->miner()->printHashrate(true); - break; - - case 'p': - case 'P': - m_controller->miner()->setEnabled(false); - break; - - case 'r': - case 'R': - m_controller->miner()->setEnabled(true); - break; - - case 3: + if (command == 3) { LOG_WARN("Ctrl+C received, exiting"); close(); - break; - - default: - break; + } + else { + m_controller->miner()->execCommand(command); } } diff --git a/src/Summary.cpp b/src/Summary.cpp index 2b8939a7..2055e972 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -126,9 +126,9 @@ static void print_threads(Config *config) static void print_commands(Config *) { if (Log::colors) { - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BOLD("h") WHITE_BOLD("ashrate, ") - MAGENTA_BOLD("p") WHITE_BOLD("ause, ") - MAGENTA_BOLD("r") WHITE_BOLD("esume")); + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BG(WHITE_BOLD_S "h") WHITE_BOLD("ashrate, ") + MAGENTA_BG(WHITE_BOLD_S "p") WHITE_BOLD("ause, ") + MAGENTA_BG(WHITE_BOLD_S "r") WHITE_BOLD("esume")); } else { Log::print(" * COMMANDS 'h' hashrate, 'p' pause, 'r' resume"); diff --git a/src/backend/common/interfaces/IBackend.h b/src/backend/common/interfaces/IBackend.h index f9073229..c6e05bcf 100644 --- a/src/backend/common/interfaces/IBackend.h +++ b/src/backend/common/interfaces/IBackend.h @@ -53,6 +53,7 @@ public: virtual const Hashrate *hashrate() const = 0; virtual const String &profileName() const = 0; virtual const String &type() const = 0; + virtual void execCommand(char command) = 0; virtual void prepare(const Job &nextJob) = 0; virtual void printHashrate(bool details) = 0; virtual void setJob(const Job &job) = 0; diff --git a/src/backend/cpu/CpuBackend.h b/src/backend/cpu/CpuBackend.h index d5d9fbf6..d0e2267a 100644 --- a/src/backend/cpu/CpuBackend.h +++ b/src/backend/cpu/CpuBackend.h @@ -50,6 +50,8 @@ public: ~CpuBackend() override; protected: + inline void execCommand(char) override {} + bool isEnabled() const override; bool isEnabled(const Algorithm &algorithm) const override; const Hashrate *hashrate() const override; diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index 6abd79b5..6bc0d81c 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -165,8 +165,11 @@ public: if (NvmlLib::init(cuda.nvmlLoader())) { NvmlLib::assign(devices); - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") "/" GREEN_BOLD("%s"), kNvmlLabel, - NvmlLib::version(), NvmlLib::driverVersion()); + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") "/" GREEN_BOLD("%s") " press " MAGENTA_BG(WHITE_BOLD_S "e") " for health report", + kNvmlLabel, + NvmlLib::version(), + NvmlLib::driverVersion() + ); } else { printDisabled(kLabel, RED_S " (failed to load NVML)"); @@ -230,6 +233,38 @@ public: } +# ifdef XMRIG_FEATURE_NVML + void printHealth() + { + for (const auto &device : devices) { + const auto health = NvmlLib::health(device.nvmlDevice()); + + std::string clocks; + if (health.clock && health.memClock) { + clocks += " " + std::to_string(health.clock) + "/" + std::to_string(health.memClock) + " MHz"; + } + + std::string fans; + if (!health.fanSpeed.empty()) { + for (uint32_t i = 0; i < health.fanSpeed.size(); ++i) { + fans += " fan" + std::to_string(i) + ":" CYAN_BOLD_S + std::to_string(health.fanSpeed[i]) + "%" CLEAR; + } + } + + LOG_INFO(CYAN_BOLD("#%u") YELLOW(" %s") MAGENTA_BOLD("%4uW") CSI "1;%um %2uC" CLEAR WHITE_BOLD("%s") "%s", + device.index(), + device.topology().toString().data(), + health.power, + health.temperature < 60 ? 32 : (health.temperature > 85 ? 31 : 33), + health.temperature, + clocks.c_str(), + fans.c_str() + ); + } + } +# endif + + Algorithm algo; Controller *controller; CudaLaunchStatus status; @@ -300,6 +335,16 @@ const xmrig::String &xmrig::CudaBackend::type() const } +void xmrig::CudaBackend::execCommand(char command) +{ +# ifdef XMRIG_FEATURE_NVML + if (command == 'e' || command == 'E') { + d_ptr->printHealth(); + } +# endif +} + + void xmrig::CudaBackend::prepare(const Job &) { } diff --git a/src/backend/cuda/CudaBackend.h b/src/backend/cuda/CudaBackend.h index 0d2a2395..cf0bb621 100644 --- a/src/backend/cuda/CudaBackend.h +++ b/src/backend/cuda/CudaBackend.h @@ -56,6 +56,7 @@ protected: const Hashrate *hashrate() const override; const String &profileName() const override; const String &type() const override; + void execCommand(char command) override; void prepare(const Job &nextJob) override; void printHashrate(bool details) override; void setJob(const Job &job) override; diff --git a/src/backend/opencl/OclBackend.h b/src/backend/opencl/OclBackend.h index 57f5db38..59bea0aa 100644 --- a/src/backend/opencl/OclBackend.h +++ b/src/backend/opencl/OclBackend.h @@ -51,6 +51,8 @@ public: ~OclBackend() override; protected: + inline void execCommand(char) override {} + bool isEnabled() const override; bool isEnabled(const Algorithm &algorithm) const override; const Hashrate *hashrate() const override; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 762539c1..a28ccbbf 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -328,6 +328,34 @@ xmrig::Job xmrig::Miner::job() const } +void xmrig::Miner::execCommand(char command) +{ + switch (command) { + case 'h': + case 'H': + printHashrate(true); + break; + + case 'p': + case 'P': + setEnabled(false); + break; + + case 'r': + case 'R': + setEnabled(true); + break; + + default: + break; + } + + for (auto backend : d_ptr->backends) { + backend->execCommand(command); + } +} + + void xmrig::Miner::pause() { d_ptr->active = false; diff --git a/src/core/Miner.h b/src/core/Miner.h index 6f4149c3..f40e37f6 100644 --- a/src/core/Miner.h +++ b/src/core/Miner.h @@ -59,6 +59,7 @@ public: const Algorithms &algorithms() const; const std::vector &backends() const; Job job() const; + void execCommand(char command); void pause(); void printHashrate(bool details); void setEnabled(bool enabled); From 26ed6254dc88158e62cfe88a215d5e880749b481 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 1 Nov 2019 04:08:52 +0700 Subject: [PATCH 23/27] Added "health-print-time" option. --- README.md | 2 ++ src/backend/cuda/CudaBackend.cpp | 7 +++++ src/base/kernel/interfaces/IConfig.h | 4 ++- src/config.json | 4 +++ src/core/Miner.cpp | 3 +- src/core/config/Config.cpp | 44 +++++++++++++++++++++------- src/core/config/Config.h | 4 +++ src/core/config/ConfigTransform.cpp | 8 +++++ src/core/config/Config_default.h | 4 +++ src/core/config/Config_platform.h | 4 +++ src/core/config/usage.h | 6 ++++ 11 files changed, 78 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index cffb28c7..fa2e814a 100644 --- a/README.md +++ b/README.md @@ -84,11 +84,13 @@ OpenCL backend: CUDA backend: --cuda enable CUDA mining backend --cuda-loader=PATH path to CUDA plugin (xmrig-cuda.dll or libxmrig-cuda.so) + --no-nvml disable NVML (NVIDIA Management Library) support Logging: -S, --syslog use system log for output messages -l, --log-file=FILE log all output to a file --print-time=N print hashrate report every N seconds + --health-print-time=N print health report every N seconds --no-color disable colored output Misc: diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index 6bc0d81c..feb1dd93 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -452,6 +452,13 @@ void xmrig::CudaBackend::stop() void xmrig::CudaBackend::tick(uint64_t ticks) { d_ptr->workers.tick(ticks); + +# ifdef XMRIG_FEATURE_NVML + auto seconds = d_ptr->controller->config()->healthPrintTime(); + if (seconds && ticks && (ticks % (seconds * 2)) == 0) { + d_ptr->printHealth(); + } +# endif } diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index ccee47c6..7167e0bb 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -135,7 +135,9 @@ public: CudaAffinityKey = 1205, CudaMaxUsageKey = 1206, CudaKey = 1207, - CudaLoaderKey = 1208 + CudaLoaderKey = 1208, + NvmlKey = 1209, + HealthPrintTimeKey = 1210, }; virtual ~IConfig() = default; diff --git a/src/config.json b/src/config.json index 9c6d459e..fbc60474 100644 --- a/src/config.json +++ b/src/config.json @@ -41,6 +41,9 @@ "cuda": { "enabled": false, "loader": null, + "nvml": true, + "cn/0": false, + "cn-lite/0": false }, "donate-level": 5, "donate-over-proxy": 1, @@ -63,6 +66,7 @@ } ], "print-time": 60, + "health-print-time": 60, "retries": 5, "retry-pause": 5, "syslog": false, diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index a28ccbbf..20ff3fd7 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -494,7 +494,8 @@ void xmrig::Miner::onTimer(const Timer *) d_ptr->maxHashrate[d_ptr->algorithm] = std::max(d_ptr->maxHashrate[d_ptr->algorithm], maxHashrate); - if ((d_ptr->ticks % (d_ptr->controller->config()->printTime() * 2)) == 0) { + auto seconds = d_ptr->controller->config()->printTime(); + if (seconds && (d_ptr->ticks % (seconds * 2)) == 0) { printHashrate(false); } diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 4fd88b90..a445961f 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -70,6 +70,11 @@ static const char *kCuda = "cuda"; #endif +#if defined(XMRIG_FEATURE_NVML) +static const char *kHealthPrintTime = "health-print-time"; +#endif + + class ConfigPrivate { public: @@ -86,6 +91,10 @@ public: # ifdef XMRIG_FEATURE_CUDA CudaConfig cuda; # endif + +# if defined(XMRIG_FEATURE_NVML) + uint32_t healthPrintTime = 60; +# endif }; } @@ -133,6 +142,14 @@ const xmrig::RxConfig &xmrig::Config::rx() const #endif +#if defined(XMRIG_FEATURE_NVML) +uint32_t xmrig::Config::healthPrintTime() const +{ + return d_ptr->healthPrintTime; +} +#endif + + bool xmrig::Config::isShouldSave() const { if (!isAutoSave()) { @@ -177,6 +194,10 @@ bool xmrig::Config::read(const IJsonReader &reader, const char *fileName) d_ptr->cuda.read(reader.getValue(kCuda)); # endif +# ifdef XMRIG_FEATURE_NVML + d_ptr->healthPrintTime = reader.getUint(kHealthPrintTime, d_ptr->healthPrintTime); +# endif + return true; } @@ -213,14 +234,17 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember(StringRef(kCuda), cuda().toJSON(doc), allocator); # endif - doc.AddMember("donate-level", m_pools.donateLevel(), allocator); - doc.AddMember("donate-over-proxy", m_pools.proxyDonate(), allocator); - doc.AddMember("log-file", m_logFile.toJSON(), allocator); - doc.AddMember("pools", m_pools.toJSON(doc), allocator); - doc.AddMember("print-time", printTime(), allocator); - doc.AddMember("retries", m_pools.retries(), allocator); - doc.AddMember("retry-pause", m_pools.retryPause(), allocator); - doc.AddMember("syslog", isSyslog(), allocator); - doc.AddMember("user-agent", m_userAgent.toJSON(), allocator); - doc.AddMember("watch", m_watch, allocator); + doc.AddMember("donate-level", m_pools.donateLevel(), allocator); + doc.AddMember("donate-over-proxy", m_pools.proxyDonate(), allocator); + doc.AddMember("log-file", m_logFile.toJSON(), allocator); + doc.AddMember("pools", m_pools.toJSON(doc), allocator); + doc.AddMember("print-time", printTime(), allocator); +# if defined(XMRIG_FEATURE_NVML) + doc.AddMember(StringRef(kHealthPrintTime), healthPrintTime(), allocator); +# endif + doc.AddMember("retries", m_pools.retries(), allocator); + doc.AddMember("retry-pause", m_pools.retryPause(), allocator); + doc.AddMember("syslog", isSyslog(), allocator); + doc.AddMember("user-agent", m_userAgent.toJSON(), allocator); + doc.AddMember("watch", m_watch, allocator); } diff --git a/src/core/config/Config.h b/src/core/config/Config.h index 8becc0b8..5eb91eca 100644 --- a/src/core/config/Config.h +++ b/src/core/config/Config.h @@ -67,6 +67,10 @@ public: const RxConfig &rx() const; # endif +# if defined(XMRIG_FEATURE_NVML) + uint32_t healthPrintTime() const; +# endif + bool isShouldSave() const; bool read(const IJsonReader &reader, const char *fileName) override; void getJSON(rapidjson::Document &doc) const override; diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp index 51f594e8..ffd3fbd8 100644 --- a/src/core/config/ConfigTransform.cpp +++ b/src/core/config/ConfigTransform.cpp @@ -193,6 +193,14 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const return set(doc, kCuda, "loader", arg); # endif +# ifdef XMRIG_FEATURE_NVML + case IConfig::NvmlKey: /* --no-nvml */ + return set(doc, kCuda, "nvml", false); + + case IConfig::HealthPrintTimeKey: /* --health-print-time */ + return set(doc, "health-print-time", static_cast(strtol(arg, nullptr, 10))); +# endif + default: break; } diff --git a/src/core/config/Config_default.h b/src/core/config/Config_default.h index e7d39299..afd3638b 100644 --- a/src/core/config/Config_default.h +++ b/src/core/config/Config_default.h @@ -75,6 +75,9 @@ R"===( "cuda": { "enabled": false, "loader": null, + "nvml": true, + "cn/0": false, + "cn-lite/0": false }, "donate-level": 5, "donate-over-proxy": 1, @@ -97,6 +100,7 @@ R"===( } ], "print-time": 60, + "health-print-time": 60, "retries": 5, "retry-pause": 5, "syslog": false, diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index 371e58fa..3309beba 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -107,6 +107,10 @@ static const option options[] = { # ifdef XMRIG_FEATURE_CUDA { "cuda", 0, nullptr, IConfig::CudaKey }, { "cuda-loader", 1, nullptr, IConfig::CudaLoaderKey }, +# endif +# ifdef XMRIG_FEATURE_NVML + { "no-nvml", 0, nullptr, IConfig::NvmlKey }, + { "health-print-time", 1, nullptr, IConfig::HealthPrintTimeKey }, # endif { nullptr, 0, nullptr, 0 } }; diff --git a/src/core/config/usage.h b/src/core/config/usage.h index c95526f7..d9ef2316 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -113,6 +113,9 @@ static inline const std::string &usage() u += " --cuda enable CUDA mining backend\n"; u += " --cuda-loader=PATH path to CUDA plugin (xmrig-cuda.dll or libxmrig-cuda.so)\n"; # endif +# ifdef XMRIG_FEATURE_NVML + u += " --no-nvml disable NVML (NVIDIA Management Library) support\n"; +# endif u += "\nLogging:\n"; @@ -122,6 +125,9 @@ static inline const std::string &usage() u += " -l, --log-file=FILE log all output to a file\n"; u += " --print-time=N print hashrate report every N seconds\n"; +# ifdef XMRIG_FEATURE_NVML + u += " --health-print-time=N print health report every N seconds\n"; +# endif u += " --no-color disable colored output\n"; u += "\nMisc:\n"; From 9d679462ed149e82cfd6c1898e823c49e4f7e9b8 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 1 Nov 2019 21:51:03 +0700 Subject: [PATCH 24/27] Sync changes with proxy. --- src/base/net/stratum/Client.cpp | 2 +- src/base/net/stratum/DaemonClient.cpp | 2 +- src/base/net/stratum/Job.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index fed87092..9729f3fb 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -212,7 +212,7 @@ int64_t xmrig::Client::submit(const JobResult &result) JsonRequest::create(doc, m_sequence, "submit", params); # ifdef XMRIG_PROXY_PROJECT - m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id); + m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id, 0); # else m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend); # endif diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 7fa1a4a9..09f2a7f9 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -117,7 +117,7 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result) JsonRequest::create(doc, m_sequence, "submitblock", params); # ifdef XMRIG_PROXY_PROJECT - m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id); + m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id, 0); # else m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend); # endif diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index 09a42355..9e1f3bc9 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -126,8 +126,8 @@ private: uint8_t m_index = 0; # ifdef XMRIG_PROXY_PROJECT - char m_rawBlob[kMaxBlobSize * 2 + 8]; - char m_rawTarget[24]; + char m_rawBlob[kMaxBlobSize * 2 + 8]{}; + char m_rawTarget[24]{}; String m_rawSeedHash; # endif }; From b1e23b46ddaa93381084e892aecd7f70ede69fab Mon Sep 17 00:00:00 2001 From: xmrig Date: Sat, 2 Nov 2019 04:03:03 +0700 Subject: [PATCH 25/27] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fa2e814a..5630698d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,12 @@ [![GitHub stars](https://img.shields.io/github/stars/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/stargazers) [![GitHub forks](https://img.shields.io/github/forks/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/network) -XMRig High performance, open source, cross platform RandomX, CryptoNight and Argon2 CPU/GPU miner, with official support for Windows +XMRig High performance, open source, cross platform RandomX, CryptoNight and Argon2 CPU/GPU miner, with official support for Windows. + +## Mining backends +- **CPU** (x64/x86/ARM) +- **OpenCL** for AMD GPUs. +- **CUDA** for NVIDIA GPUs via external [CUDA plugin](https://github.com/xmrig/xmrig-cuda). @@ -29,6 +34,7 @@ XMRig High performance, open source, cross platform RandomX, CryptoNight and Arg The preferred way to configure the miner is the [JSON config file](src/config.json) as it is more flexible and human friendly. The command line interface does not cover all features, such as mining profiles for different algorithms. Important options can be changed during runtime without miner restart by editing the config file or executing API calls. * **[xmrig.com/wizard](https://xmrig.com/wizard)** helps you create initial configuration for the miner. +* **[workers.xmrig.info](http://workers.xmrig.info)** helps manage your miners via HTTP API. ### Command line options ``` From 239aecb0bb8585acdc3e408fc7b76abd04b0318e Mon Sep 17 00:00:00 2001 From: xmrig Date: Sat, 2 Nov 2019 04:08:07 +0700 Subject: [PATCH 26/27] Update README.md --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index 5630698d..ac978393 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,6 @@ XMRig High performance, open source, cross platform RandomX, CryptoNight and Arg -#### Table of contents -* [Download](#download) -* [Usage](#usage) -* [Build](https://github.com/xmrig/xmrig/wiki/Build) -* [Donations](#donations) -* [Contacts](#contacts) - ## Download * Binary releases: https://github.com/xmrig/xmrig/releases * Git tree: https://github.com/xmrig/xmrig.git From 4c4a674a4be37cdc9860eef0b025eb66e8a95be4 Mon Sep 17 00:00:00 2001 From: xmrig Date: Sat, 2 Nov 2019 04:22:57 +0700 Subject: [PATCH 27/27] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b380d75b..feba3b05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# v4.5.0-beta +- Added NVIDIA CUDA support via external [CUDA plugun](https://github.com/xmrig/xmrig-cuda). XMRig now is unified 3 in 1 miner. + # v4.4.0-beta - [#1068](https://github.com/xmrig/xmrig/pull/1068) Added support for `self-select` stratum protocol extension. - [#1240](https://github.com/xmrig/xmrig/pull/1240) Sync with the latest RandomX code. @@ -6,7 +9,6 @@ - [#1247](https://github.com/xmrig/xmrig/pull/1247) Fixed ARM64 RandomX code alignment. - [#1248](https://github.com/xmrig/xmrig/pull/1248) Fixed RandomX code cache cleanup on iOS/Darwin. - # v4.3.1-beta - Fixed regression in v4.3.0, miner didn't create `cn` mining profile with default config example.