mirror of
https://github.com/xmrig/xmrig.git
synced 2025-03-12 09:37:35 +00:00
Merge branch 'evo' into beta
This commit is contained in:
commit
5519e97e6e
79 changed files with 3700 additions and 158 deletions
|
@ -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.
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ 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_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)
|
||||
|
||||
|
|
24
README.md
24
README.md
|
@ -9,17 +9,15 @@
|
|||
[](https://github.com/xmrig/xmrig/stargazers)
|
||||
[](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).
|
||||
|
||||
<img src="doc/screenshot.png" width="808" >
|
||||
|
||||
#### 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
|
||||
|
@ -29,6 +27,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
|
||||
```
|
||||
|
@ -77,13 +76,20 @@ 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)
|
||||
--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:
|
||||
|
|
2
doc/build/CMAKE_OPTIONS.md
vendored
2
doc/build/CMAKE_OPTIONS.md
vendored
|
@ -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
|
||||
|
||||
|
|
25
src/App.cpp
25
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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}"
|
||||
)
|
||||
|
|
|
@ -27,10 +27,15 @@
|
|||
#define XMRIG_TAGS_H
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
const char *backend_tag(uint32_t backend);
|
||||
const char *cpu_tag();
|
||||
const char *net_tag();
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_OPENCL
|
||||
|
@ -38,6 +43,12 @@ const char *ocl_tag();
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_CUDA
|
||||
const char *cuda_tag();
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef XMRIG_ALGO_RANDOMX
|
||||
const char *rx_tag();
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,11 @@
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_CUDA
|
||||
# include "backend/cuda/CudaThreads.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
|
@ -167,4 +172,8 @@ template class Threads<CpuThreads>;
|
|||
template class Threads<OclThreads>;
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_FEATURE_CUDA
|
||||
template class Threads<CudaThreads>;
|
||||
#endif
|
||||
|
||||
} // namespace xmrig
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#define XMRIG_WORKERJOB_H
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
#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());
|
||||
}
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_CUDA
|
||||
# include "backend/cuda/CudaWorker.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
|
@ -217,4 +222,16 @@ template class Workers<OclLaunchData>;
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_CUDA
|
||||
template<>
|
||||
xmrig::IWorker *xmrig::Workers<CudaLaunchData>::create(Thread<CudaLaunchData> *handle)
|
||||
{
|
||||
return new CudaWorker(handle->id(), handle->config());
|
||||
}
|
||||
|
||||
|
||||
template class Workers<CudaLaunchData>;
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
|
|
@ -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<OclLaunchData>;
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_CUDA
|
||||
template<>
|
||||
IWorker *Workers<CudaLaunchData>::create(Thread<CudaLaunchData> *handle);
|
||||
extern template class Workers<CudaLaunchData>;
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
@ -210,6 +211,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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -303,7 +303,7 @@ void xmrig::CpuWorker<N>::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) {
|
||||
|
|
519
src/backend/cuda/CudaBackend.cpp
Normal file
519
src/backend/cuda/CudaBackend.cpp
Normal file
|
@ -0,0 +1,519 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
|
||||
#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 "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"
|
||||
#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
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_NVML
|
||||
#include "backend/cuda/wrappers/NvmlLib.h"
|
||||
|
||||
namespace xmrig { static const char *kNvmlLabel = "NVML"; }
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
extern template class Threads<CudaThreads>;
|
||||
|
||||
|
||||
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 *label, const char *reason)
|
||||
{
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") RED_BOLD("disabled") "%s", label, 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
|
||||
{
|
||||
public:
|
||||
inline CudaBackendPrivate(Controller *controller) :
|
||||
controller(controller)
|
||||
{
|
||||
init(controller->config()->cuda());
|
||||
}
|
||||
|
||||
|
||||
void init(const CudaConfig &cuda)
|
||||
{
|
||||
if (!cuda.isEnabled()) {
|
||||
return printDisabled(kLabel, "");
|
||||
}
|
||||
|
||||
if (!CudaLib::init(cuda.loader())) {
|
||||
return printDisabled(kLabel, RED_S " (failed to load CUDA plugin)");
|
||||
}
|
||||
|
||||
runtimeVersion = CudaLib::runtimeVersion();
|
||||
driverVersion = CudaLib::driverVersion();
|
||||
|
||||
if (!runtimeVersion || !driverVersion || !CudaLib::deviceCount()) {
|
||||
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"), 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())) {
|
||||
NvmlLib::assign(devices);
|
||||
|
||||
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)");
|
||||
}
|
||||
}
|
||||
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",
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void start(const Job &)
|
||||
{
|
||||
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
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
# 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;
|
||||
std::vector<CudaDevice> devices;
|
||||
std::vector<CudaLaunchData> threads;
|
||||
String profileName;
|
||||
uint32_t driverVersion = 0;
|
||||
uint32_t runtimeVersion = 0;
|
||||
Workers<CudaLaunchData> workers;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
const char *xmrig::cuda_tag()
|
||||
{
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
xmrig::CudaBackend::CudaBackend(Controller *controller) :
|
||||
d_ptr(new CudaBackendPrivate(controller))
|
||||
{
|
||||
d_ptr->workers.setBackend(this);
|
||||
}
|
||||
|
||||
|
||||
xmrig::CudaBackend::~CudaBackend()
|
||||
{
|
||||
delete d_ptr;
|
||||
|
||||
CudaLib::close();
|
||||
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
NvmlLib::close();
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CudaBackend::isEnabled() const
|
||||
{
|
||||
return d_ptr->controller->config()->cuda().isEnabled() && CudaLib::isInitialized() && !d_ptr->devices.empty();;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CudaBackend::isEnabled(const Algorithm &algorithm) const
|
||||
{
|
||||
return !d_ptr->controller->config()->cuda().threads().get(algorithm).isEmpty();
|
||||
}
|
||||
|
||||
|
||||
const xmrig::Hashrate *xmrig::CudaBackend::hashrate() const
|
||||
{
|
||||
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::execCommand(char command)
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
if (command == 'e' || command == 'E') {
|
||||
d_ptr->printHealth();
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
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 auto &data : d_ptr->threads) {
|
||||
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),
|
||||
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++;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
auto seconds = d_ptr->controller->config()->healthPrintTime();
|
||||
if (seconds && ticks && (ticks % (seconds * 2)) == 0) {
|
||||
d_ptr->printHealth();
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
#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);
|
||||
|
||||
Value versions(kObjectType);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CudaBackend::handleRequest(IApiRequest &)
|
||||
{
|
||||
}
|
||||
#endif
|
80
src/backend/cuda/CudaBackend.h
Normal file
80
src/backend/cuda/CudaBackend.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CUDABACKEND_H
|
||||
#define XMRIG_CUDABACKEND_H
|
||||
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
#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 execCommand(char command) 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 */
|
186
src/backend/cuda/CudaConfig.cpp
Normal file
186
src/backend/cuda/CudaConfig.cpp
Normal file
|
@ -0,0 +1,186 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#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"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static bool generated = false;
|
||||
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<CudaThreads>;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
std::vector<xmrig::CudaLaunchData> xmrig::CudaConfig::get(const Miner *miner, const Algorithm &algorithm, const std::vector<CudaDevice> &devices) const
|
||||
{
|
||||
std::vector<CudaLaunchData> 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()) {
|
||||
m_enabled = Json::getBool(value, kEnabled, m_enabled);
|
||||
m_loader = Json::getString(value, kLoader);
|
||||
|
||||
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();
|
||||
}
|
||||
else if (value.IsBool()) {
|
||||
m_enabled = value.GetBool();
|
||||
|
||||
generate();
|
||||
}
|
||||
else {
|
||||
m_shouldSave = true;
|
||||
|
||||
generate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CudaConfig::generate()
|
||||
{
|
||||
if (generated) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isEnabled() || m_threads.has("*")) {
|
||||
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<Algorithm::CN>(m_threads, devices);
|
||||
count += xmrig::generate<Algorithm::CN_LITE>(m_threads, devices);
|
||||
count += xmrig::generate<Algorithm::CN_HEAVY>(m_threads, devices);
|
||||
count += xmrig::generate<Algorithm::CN_PICO>(m_threads, devices);
|
||||
count += xmrig::generate<Algorithm::RANDOM_X>(m_threads, devices);
|
||||
|
||||
generated = true;
|
||||
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));
|
||||
}
|
||||
}
|
86
src/backend/cuda/CudaConfig.h
Normal file
86
src/backend/cuda/CudaConfig.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CUDACONFIG_H
|
||||
#define XMRIG_CUDACONFIG_H
|
||||
|
||||
|
||||
#include "backend/cuda/CudaLaunchData.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;
|
||||
std::vector<CudaLaunchData> get(const Miner *miner, const Algorithm &algorithm, const std::vector<CudaDevice> &devices) const;
|
||||
void read(const rapidjson::Value &value);
|
||||
|
||||
inline bool isEnabled() const { return m_enabled; }
|
||||
inline bool isShouldSave() const { return m_shouldSave; }
|
||||
inline const String &loader() const { return m_loader; }
|
||||
inline const Threads<CudaThreads> &threads() const { return m_threads; }
|
||||
inline int32_t bfactor() const { return m_bfactor; }
|
||||
inline int32_t bsleep() const { return m_bsleep; }
|
||||
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
inline bool isNvmlEnabled() const { return m_nvml; }
|
||||
inline const String &nvmlLoader() const { return m_nvmlLoader; }
|
||||
# endif
|
||||
|
||||
private:
|
||||
void generate();
|
||||
void setDevicesHint(const char *devicesHint);
|
||||
|
||||
bool m_enabled = false;
|
||||
bool m_shouldSave = false;
|
||||
std::vector<uint32_t> m_devicesHint;
|
||||
String m_loader;
|
||||
Threads<CudaThreads> 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
|
||||
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
bool m_nvml = true;
|
||||
String m_nvmlLoader;
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CUDACONFIG_H */
|
137
src/backend/cuda/CudaConfig_gen.h
Normal file
137
src/backend/cuda/CudaConfig_gen.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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 <algorithm>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static inline size_t generate(const char *key, Threads<CudaThreads> &threads, const Algorithm &algorithm, const std::vector<CudaDevice> &devices)
|
||||
{
|
||||
if (threads.isExist(algorithm) || threads.has(key)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return threads.move(key, CudaThreads(devices, algorithm));
|
||||
}
|
||||
|
||||
|
||||
template<Algorithm::Family FAMILY>
|
||||
static inline size_t generate(Threads<CudaThreads> &, const std::vector<CudaDevice> &) { return 0; }
|
||||
|
||||
|
||||
template<>
|
||||
size_t inline generate<Algorithm::CN>(Threads<CudaThreads> &threads, const std::vector<CudaDevice> &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<Algorithm::CN_LITE>(Threads<CudaThreads> &threads, const std::vector<CudaDevice> &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<Algorithm::CN_HEAVY>(Threads<CudaThreads> &threads, const std::vector<CudaDevice> &devices)
|
||||
{
|
||||
return generate("cn-heavy", threads, Algorithm::CN_HEAVY_0, devices);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_ALGO_CN_PICO
|
||||
template<>
|
||||
size_t inline generate<Algorithm::CN_PICO>(Threads<CudaThreads> &threads, const std::vector<CudaDevice> &devices)
|
||||
{
|
||||
return generate("cn-pico", threads, Algorithm::CN_PICO_0, devices);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_ALGO_RANDOMX
|
||||
template<>
|
||||
size_t inline generate<Algorithm::RANDOM_X>(Threads<CudaThreads> &threads, const std::vector<CudaDevice> &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 */
|
||||
|
||||
|
||||
#endif /* XMRIG_CUDACONFIG_GEN_H */
|
51
src/backend/cuda/CudaLaunchData.cpp
Normal file
51
src/backend/cuda/CudaLaunchData.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#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.family() == algorithm.family() &&
|
||||
other.algorithm.l3() == algorithm.l3() &&
|
||||
other.thread == thread);
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::CudaLaunchData::tag()
|
||||
{
|
||||
return cuda_tag();
|
||||
}
|
66
src/backend/cuda/CudaLaunchData.h
Normal file
66
src/backend/cuda/CudaLaunchData.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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 */
|
99
src/backend/cuda/CudaThread.cpp
Normal file
99
src/backend/cuda/CudaThread.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "backend/cuda/CudaThread.h"
|
||||
#include "backend/cuda/wrappers/CudaLib.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
|
||||
rapidjson::Value xmrig::CudaThread::toJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
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;
|
||||
}
|
79
src/backend/cuda/CudaThread.h
Normal file
79
src/backend/cuda/CudaThread.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CUDATHREAD_H
|
||||
#define XMRIG_CUDATHREAD_H
|
||||
|
||||
|
||||
using nvid_ctx = struct nvid_ctx;
|
||||
|
||||
|
||||
#include "crypto/common/Algorithm.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class CudaThread
|
||||
{
|
||||
public:
|
||||
CudaThread() = delete;
|
||||
CudaThread(const rapidjson::Value &value);
|
||||
CudaThread(uint32_t index, nvid_ctx *ctx);
|
||||
|
||||
inline bool isValid() const { return m_blocks > 0 && m_threads > 0; }
|
||||
inline int32_t bfactor() const { return static_cast<int32_t>(m_bfactor); }
|
||||
inline int32_t blocks() const { return m_blocks; }
|
||||
inline int32_t bsleep() const { return static_cast<int32_t>(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); }
|
||||
|
||||
bool isEqual(const CudaThread &other) const;
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CUDATHREAD_H */
|
79
src/backend/cuda/CudaThreads.cpp
Normal file
79
src/backend/cuda/CudaThreads.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "backend/cuda/CudaThreads.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::CudaThreads::CudaThreads(const std::vector<CudaDevice> &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()) {
|
||||
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;
|
||||
}
|
66
src/backend/cuda/CudaThreads.h
Normal file
66
src/backend/cuda/CudaThreads.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CUDATHREADS_H
|
||||
#define XMRIG_CUDATHREADS_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "backend/cuda/CudaThread.h"
|
||||
#include "backend/cuda/wrappers/CudaDevice.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class CudaThreads
|
||||
{
|
||||
public:
|
||||
CudaThreads() = default;
|
||||
CudaThreads(const rapidjson::Value &value);
|
||||
CudaThreads(const std::vector<CudaDevice> &devices, const Algorithm &algorithm);
|
||||
|
||||
inline bool isEmpty() const { return m_data.empty(); }
|
||||
inline const std::vector<CudaThread> &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<CudaThread> m_data;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_CUDATHREADS_H */
|
171
src/backend/cuda/CudaWorker.cpp
Normal file
171
src/backend/cuda/CudaWorker.cpp
Normal file
|
@ -0,0 +1,171 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#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"
|
||||
#include "crypto/common/Nonce.h"
|
||||
#include "net/JobResults.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_ALGO_RANDOMX
|
||||
# include "backend/cuda/runners/CudaRxRunner.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include <cassert>
|
||||
#include <thread>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static constexpr uint32_t kReserveCount = 32768;
|
||||
std::atomic<bool> CudaWorker::ready;
|
||||
|
||||
|
||||
static inline bool isReady() { return !Nonce::isPaused() && CudaWorker::ready; }
|
||||
static inline uint32_t roundSize(uint32_t intensity) { return kReserveCount / intensity + 1; }
|
||||
|
||||
|
||||
} // 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CudaWorker::selfTest()
|
||||
{
|
||||
return m_runner != nullptr;
|
||||
}
|
||||
|
||||
|
||||
size_t xmrig::CudaWorker::intensity() const
|
||||
{
|
||||
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())) {
|
||||
uint32_t foundNonce[10] = { 0 };
|
||||
uint32_t foundCount = 0;
|
||||
|
||||
if (!m_runner->run(*m_job.nonce(), &foundCount, foundNonce)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (foundCount) {
|
||||
JobResults::submit(m_job.currentJob(), foundNonce, foundCount);
|
||||
}
|
||||
|
||||
const size_t batch_size = intensity();
|
||||
m_job.nextRound(roundSize(batch_size), batch_size);
|
||||
|
||||
storeStats();
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
if (!consumeJob()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CudaWorker::consumeJob()
|
||||
{
|
||||
if (Nonce::sequence(Nonce::CUDA) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t batch_size = intensity();
|
||||
m_job.add(m_miner->job(), roundSize(batch_size) * batch_size, Nonce::CUDA);
|
||||
|
||||
return m_runner->set(m_job.currentJob(), m_job.blob());;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CudaWorker::storeStats()
|
||||
{
|
||||
if (!isReady()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_count += intensity();
|
||||
|
||||
Worker::storeStats();
|
||||
}
|
73
src/backend/cuda/CudaWorker.h
Normal file
73
src/backend/cuda/CudaWorker.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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 ICudaRunner;
|
||||
|
||||
|
||||
class CudaWorker : public Worker
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(CudaWorker)
|
||||
|
||||
CudaWorker(size_t id, const CudaLaunchData &data);
|
||||
|
||||
~CudaWorker() override;
|
||||
|
||||
static std::atomic<bool> 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;
|
||||
ICudaRunner *m_runner = nullptr;
|
||||
WorkerJob<1> m_job;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_CUDAWORKER_H */
|
53
src/backend/cuda/cuda.cmake
Normal file
53
src/backend/cuda/cuda.cmake
Normal file
|
@ -0,0 +1,53 @@
|
|||
if (WITH_CUDA)
|
||||
add_definitions(/DXMRIG_FEATURE_CUDA)
|
||||
|
||||
set(HEADERS_BACKEND_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/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
|
||||
)
|
||||
|
||||
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/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
|
||||
)
|
||||
|
||||
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/NvmlHealth.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 "")
|
||||
endif()
|
71
src/backend/cuda/interfaces/ICudaRunner.h
Normal file
71
src/backend/cuda/interfaces/ICudaRunner.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ICUDARUNNER_H
|
||||
#define XMRIG_ICUDARUNNER_H
|
||||
|
||||
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
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
|
83
src/backend/cuda/runners/CudaBaseRunner.cpp
Normal file
83
src/backend/cuda/runners/CudaBaseRunner.cpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "backend/cuda/runners/CudaBaseRunner.h"
|
||||
#include "backend/cuda/wrappers/CudaLib.h"
|
||||
#include "backend/cuda/CudaLaunchData.h"
|
||||
#include "backend/common/Tags.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/net/stratum/Job.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 callWrapper(CudaLib::deviceInit(m_ctx));
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CudaBaseRunner::set(const Job &job, uint8_t *blob)
|
||||
{
|
||||
m_height = job.height();
|
||||
m_target = job.target();
|
||||
|
||||
return callWrapper(CudaLib::setJob(m_ctx, blob, job.size(), job.algorithm()));
|
||||
}
|
||||
|
||||
|
||||
size_t xmrig::CudaBaseRunner::intensity() const
|
||||
{
|
||||
return m_data.thread.threads() * m_data.thread.blocks();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CudaBaseRunner::callWrapper(bool result) const
|
||||
{
|
||||
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;
|
||||
}
|
68
src/backend/cuda/runners/CudaBaseRunner.h
Normal file
68
src/backend/cuda/runners/CudaBaseRunner.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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:
|
||||
bool callWrapper(bool result) const;
|
||||
|
||||
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
|
38
src/backend/cuda/runners/CudaCnRunner.cpp
Normal file
38
src/backend/cuda/runners/CudaCnRunner.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#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 callWrapper(CudaLib::cnHash(m_ctx, startNonce, m_height, m_target, rescount, resnonce));
|
||||
}
|
48
src/backend/cuda/runners/CudaCnRunner.h
Normal file
48
src/backend/cuda/runners/CudaCnRunner.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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
|
65
src/backend/cuda/runners/CudaRxRunner.cpp
Normal file
65
src/backend/cuda/runners/CudaRxRunner.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
m_intensity -= m_intensity % 32;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CudaRxRunner::run(uint32_t startNonce, uint32_t *rescount, uint32_t *resnonce)
|
||||
{
|
||||
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;
|
||||
}
|
55
src/backend/cuda/runners/CudaRxRunner.h
Normal file
55
src/backend/cuda/runners/CudaRxRunner.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CUDARXRUNNER_H
|
||||
#define XMRIG_CUDARXRUNNER_H
|
||||
|
||||
|
||||
#include "backend/cuda/runners/CudaBaseRunner.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class CudaRxRunner : public CudaBaseRunner
|
||||
{
|
||||
public:
|
||||
CudaRxRunner(size_t index, const CudaLaunchData &data);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif // XMRIG_CUDARXRUNNER_H
|
152
src/backend/cuda/wrappers/CudaDevice.cpp
Normal file
152
src/backend/cuda/wrappers/CudaDevice.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#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"
|
||||
|
||||
#ifdef XMRIG_FEATURE_NVML
|
||||
# include "backend/cuda/wrappers/NvmlLib.h"
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
xmrig::CudaDevice::CudaDevice(uint32_t index, int32_t bfactor, int32_t bsleep) :
|
||||
m_index(index)
|
||||
{
|
||||
auto ctx = CudaLib::alloc(index, bfactor, bsleep);
|
||||
if (CudaLib::deviceInfo(ctx, 0, 0, Algorithm::INVALID) != 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
|
||||
{
|
||||
if (CudaLib::deviceInfo(m_ctx, -1, -1, algorithm) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
threads.add(CudaThread(m_index, m_ctx));
|
||||
}
|
||||
|
||||
|
||||
#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<uint64_t>(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
|
94
src/backend/cuda/wrappers/CudaDevice.h
Normal file
94
src/backend/cuda/wrappers/CudaDevice.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
using nvmlDevice_t = struct nvmlDevice_st *;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Algorithm;
|
||||
class CudaThreads;
|
||||
|
||||
|
||||
class CudaDevice
|
||||
{
|
||||
public:
|
||||
CudaDevice() = delete;
|
||||
CudaDevice(const CudaDevice &other) = delete;
|
||||
CudaDevice(CudaDevice &&other) noexcept;
|
||||
CudaDevice(uint32_t index, int32_t bfactor, int32_t bsleep);
|
||||
~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 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;
|
||||
# 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;
|
||||
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
nvmlDevice_t m_nvmlDevice = nullptr;
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_CUDADEVICE_H */
|
316
src/backend/cuda/wrappers/CudaLib.cpp
Normal file
316
src/backend/cuda/wrappers/CudaLib.cpp
Normal file
|
@ -0,0 +1,316 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdexcept>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "backend/cuda/wrappers/CudaLib.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
enum Version : uint32_t
|
||||
{
|
||||
ApiVersion,
|
||||
DriverVersion,
|
||||
RuntimeVersion
|
||||
};
|
||||
|
||||
|
||||
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 *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";
|
||||
|
||||
|
||||
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 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);
|
||||
|
||||
|
||||
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 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;
|
||||
|
||||
|
||||
#define DLSYM(x) if (uv_dlsym(&cudaLib, k##x, reinterpret_cast<void**>(&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() noexcept
|
||||
{
|
||||
return uv_dlerror(&cudaLib);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CudaLib::close()
|
||||
{
|
||||
uv_dlclose(&cudaLib);
|
||||
}
|
||||
|
||||
|
||||
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::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);
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::CudaLib::deviceName(nvid_ctx *ctx) noexcept
|
||||
{
|
||||
return pDeviceName(ctx);
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::CudaLib::lastError(nvid_ctx *ctx) noexcept
|
||||
{
|
||||
return pLastError(ctx);
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::CudaLib::pluginVersion() noexcept
|
||||
{
|
||||
return pPluginVersion();
|
||||
}
|
||||
|
||||
|
||||
int xmrig::CudaLib::deviceInfo(nvid_ctx *ctx, int32_t blocks, int32_t threads, const Algorithm &algorithm) noexcept
|
||||
{
|
||||
return pDeviceInfo(ctx, blocks, threads, algorithm);
|
||||
}
|
||||
|
||||
|
||||
int32_t xmrig::CudaLib::deviceInt(nvid_ctx *ctx, DeviceProperty property) noexcept
|
||||
{
|
||||
return pDeviceInt(ctx, property);
|
||||
}
|
||||
|
||||
|
||||
nvid_ctx *xmrig::CudaLib::alloc(uint32_t id, int32_t bfactor, int32_t bsleep) noexcept
|
||||
{
|
||||
return pAlloc(id, bfactor, bsleep);
|
||||
}
|
||||
|
||||
|
||||
std::string xmrig::CudaLib::version(uint32_t version)
|
||||
{
|
||||
return std::to_string(version / 1000) + "." + std::to_string((version % 1000) / 10);
|
||||
}
|
||||
|
||||
|
||||
std::vector<xmrig::CudaDevice> xmrig::CudaLib::devices(int32_t bfactor, int32_t bsleep) noexcept
|
||||
{
|
||||
const uint32_t count = deviceCount();
|
||||
if (!count) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<CudaDevice> out;
|
||||
out.reserve(count);
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
CudaDevice device(i, bfactor, bsleep);
|
||||
if (device.isValid()) {
|
||||
out.emplace_back(std::move(device));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
uint32_t xmrig::CudaLib::runtimeVersion() noexcept
|
||||
{
|
||||
return pVersion(RuntimeVersion);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CudaLib::load()
|
||||
{
|
||||
if (uv_dlsym(&cudaLib, kVersion, reinterpret_cast<void**>(&pVersion)) == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pVersion(ApiVersion) != 1u) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
DLSYM(Alloc);
|
||||
DLSYM(CnHash);
|
||||
DLSYM(DeviceCount);
|
||||
DLSYM(DeviceInfo);
|
||||
DLSYM(DeviceInit);
|
||||
DLSYM(DeviceInt);
|
||||
DLSYM(DeviceName);
|
||||
DLSYM(DeviceUint);
|
||||
DLSYM(DeviceUlong);
|
||||
DLSYM(Init);
|
||||
DLSYM(LastError);
|
||||
DLSYM(PluginVersion);
|
||||
DLSYM(Release);
|
||||
DLSYM(RxHash);
|
||||
DLSYM(RxPrepare);
|
||||
DLSYM(SetJob);
|
||||
DLSYM(Version);
|
||||
} catch (std::exception &ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pInit();
|
||||
|
||||
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 "libxmrig-cuda.so";
|
||||
# endif
|
||||
}
|
107
src/backend/cuda/wrappers/CudaLib.h
Normal file
107
src/backend/cuda/wrappers/CudaLib.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_CUDALIB_H
|
||||
#define XMRIG_CUDALIB_H
|
||||
|
||||
|
||||
using nvid_ctx = struct nvid_ctx;
|
||||
|
||||
|
||||
#include "backend/cuda/wrappers/CudaDevice.h"
|
||||
#include "base/tools/String.h"
|
||||
#include "crypto/common/Algorithm.h"
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
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() noexcept;
|
||||
static void close();
|
||||
|
||||
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 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;
|
||||
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;
|
||||
static nvid_ctx *alloc(uint32_t id, int32_t bfactor, int32_t bsleep) noexcept;
|
||||
static std::string version(uint32_t version);
|
||||
static std::vector<CudaDevice> 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;
|
||||
static uint32_t runtimeVersion() noexcept;
|
||||
static uint64_t deviceUlong(nvid_ctx *ctx, DeviceProperty property) 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 */
|
43
src/backend/cuda/wrappers/NvmlHealth.h
Normal file
43
src/backend/cuda/wrappers/NvmlHealth.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_NVMLHEALTH_H
|
||||
#define XMRIG_NVMLHEALTH_H
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
|
||||
struct NvmlHealth
|
||||
{
|
||||
std::vector<uint32_t> fanSpeed;
|
||||
uint32_t clock = 0;
|
||||
uint32_t memClock = 0;
|
||||
uint32_t power = 0;
|
||||
uint32_t temperature = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* XMRIG_NVMLHEALTH_H */
|
227
src/backend/cuda/wrappers/NvmlLib.cpp
Normal file
227
src/backend/cuda/wrappers/NvmlLib.cpp
Normal file
|
@ -0,0 +1,227 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdexcept>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#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 *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";
|
||||
static const char *kNvmlSystemGetNVMLVersion = "nvmlSystemGetNVMLVersion";
|
||||
static const char *kSymbolNotFound = "symbol not found";
|
||||
|
||||
|
||||
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<void**>(&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::assign(std::vector<CudaDevice> &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()) {
|
||||
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(NvmlDeviceGetClockInfo);
|
||||
DLSYM(NvmlDeviceGetCount);
|
||||
DLSYM(NvmlDeviceGetFanSpeed);
|
||||
DLSYM(NvmlDeviceGetHandleByIndex);
|
||||
DLSYM(NvmlDeviceGetPciInfo);
|
||||
DLSYM(NvmlDeviceGetPowerUsage);
|
||||
DLSYM(NvmlDeviceGetTemperature);
|
||||
DLSYM(NvmlInit);
|
||||
DLSYM(NvmlShutdown);
|
||||
DLSYM(NvmlSystemGetDriverVersion);
|
||||
DLSYM(NvmlSystemGetNVMLVersion);
|
||||
} catch (std::exception &ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uv_dlsym(&nvmlLib, kNvmlDeviceGetFanSpeed_v2, reinterpret_cast<void**>(&pNvmlDeviceGetFanSpeed_v2));
|
||||
|
||||
if (pNvmlInit() != NVML_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pNvmlSystemGetDriverVersion(m_driverVersion, sizeof(m_driverVersion));
|
||||
pNvmlSystemGetNVMLVersion(m_nvmlVersion, sizeof(m_nvmlVersion));
|
||||
|
||||
return true;
|
||||
}
|
66
src/backend/cuda/wrappers/NvmlLib.h
Normal file
66
src/backend/cuda/wrappers/NvmlLib.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_NVMLLIB_H
|
||||
#define XMRIG_NVMLLIB_H
|
||||
|
||||
|
||||
#include "backend/cuda/wrappers/CudaDevice.h"
|
||||
#include "backend/cuda/wrappers/NvmlHealth.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class NvmlLib
|
||||
{
|
||||
public:
|
||||
static bool init(const char *fileName = nullptr);
|
||||
static const char *lastError() noexcept;
|
||||
static void close();
|
||||
|
||||
static bool assign(std::vector<CudaDevice> &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; }
|
||||
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 */
|
55
src/backend/cuda/wrappers/nvml_lite.h
Normal file
55
src/backend/cuda/wrappers/nvml_lite.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_NVML_LITE_H
|
||||
#define XMRIG_NVML_LITE_H
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
#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 */
|
|
@ -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(),
|
||||
|
@ -167,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
|
||||
);
|
||||
|
||||
|
@ -284,7 +286,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,
|
||||
|
@ -309,7 +311,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);
|
||||
}
|
||||
|
@ -318,7 +320,7 @@ void xmrig::OclBackend::setJob(const Job &job)
|
|||
return stop();
|
||||
}
|
||||
|
||||
std::vector<OclLaunchData> threads = cl.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->platform, d_ptr->devices, tag);
|
||||
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;
|
||||
}
|
||||
|
@ -408,7 +410,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);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
|
||||
#include "backend/common/interfaces/IBackend.h"
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
@ -43,17 +44,15 @@ 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:
|
||||
inline void execCommand(char) override {}
|
||||
|
||||
bool isEnabled() const override;
|
||||
bool isEnabled(const Algorithm &algorithm) const override;
|
||||
const Hashrate *hashrate() const override;
|
||||
|
|
|
@ -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,10 +114,10 @@ rapidjson::Value xmrig::OclConfig::toJSON(rapidjson::Document &doc) const
|
|||
}
|
||||
|
||||
|
||||
std::vector<xmrig::OclLaunchData> xmrig::OclConfig::get(const Miner *miner, const Algorithm &algorithm, const OclPlatform &platform, const std::vector<OclDevice> &devices, const char *tag) const
|
||||
std::vector<xmrig::OclLaunchData> xmrig::OclConfig::get(const Miner *miner, const Algorithm &algorithm, const OclPlatform &platform, const std::vector<OclDevice> &devices) const
|
||||
{
|
||||
std::vector<OclLaunchData> out;
|
||||
const OclThreads &threads = m_threads.get(algorithm);
|
||||
const auto &threads = m_threads.get(algorithm);
|
||||
|
||||
if (threads.isEmpty()) {
|
||||
return out;
|
||||
|
@ -124,9 +125,9 @@ std::vector<xmrig::OclLaunchData> 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"), tag, thread.index());
|
||||
LOG_INFO("%s" YELLOW(" skip non-existing device with index ") YELLOW_BOLD("%u"), ocl_tag(), thread.index());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
|
||||
OclPlatform platform() const;
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
std::vector<OclLaunchData> get(const Miner *miner, const Algorithm &algorithm, const OclPlatform &platform, const std::vector<OclDevice> &devices, const char *tag) const;
|
||||
std::vector<OclLaunchData> get(const Miner *miner, const Algorithm &algorithm, const OclPlatform &platform, const std::vector<OclDevice> &devices) const;
|
||||
void read(const rapidjson::Value &value);
|
||||
|
||||
inline bool isCacheEnabled() const { return m_cache; }
|
||||
|
|
|
@ -46,7 +46,7 @@ xmrig::OclThreads::OclThreads(const rapidjson::Value &value)
|
|||
|
||||
xmrig::OclThreads::OclThreads(const std::vector<OclDevice> &devices, const Algorithm &algorithm)
|
||||
{
|
||||
for (const OclDevice &device : devices) {
|
||||
for (const auto &device : devices) {
|
||||
device.generate(algorithm, *this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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<bool> ready;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -26,14 +26,13 @@
|
|||
#define XMRIG_OCLDEVICE_H
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
#include "backend/common/misc/PciTopology.h"
|
||||
#include "backend/opencl/wrappers/OclVendor.h"
|
||||
#include "base/tools/String.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
|
||||
using cl_device_id = struct _cl_device_id *;
|
||||
using cl_platform_id = struct _cl_platform_id *;
|
||||
|
|
|
@ -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<void**>(&p##x)) == -1) { return false; }
|
||||
#define DLSYM(x) if (uv_dlsym(&oclLib, k##x, reinterpret_cast<void**>(&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<void**>(&pCreateCommandQueueWithProperties));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -134,6 +134,10 @@ public:
|
|||
CudaLaunchKey = 1204,
|
||||
CudaAffinityKey = 1205,
|
||||
CudaMaxUsageKey = 1206,
|
||||
CudaKey = 1207,
|
||||
CudaLoaderKey = 1208,
|
||||
NvmlKey = 1209,
|
||||
HealthPrintTimeKey = 1210,
|
||||
};
|
||||
|
||||
virtual ~IConfig() = default;
|
||||
|
|
|
@ -212,9 +212,9 @@ 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());
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend);
|
||||
# endif
|
||||
|
||||
return send(doc);
|
||||
|
|
|
@ -117,9 +117,9 @@ 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());
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend);
|
||||
# endif
|
||||
|
||||
send(HTTP_POST, kJsonRPC, doc);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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<uint32_t*>(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<uint32_t*>(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;
|
||||
|
@ -117,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
|
||||
};
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
|
||||
|
||||
#include "base/net/stratum/Pool.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;
|
||||
|
|
|
@ -38,6 +38,13 @@
|
|||
"cn/0": false,
|
||||
"cn-lite/0": false
|
||||
},
|
||||
"cuda": {
|
||||
"enabled": false,
|
||||
"loader": null,
|
||||
"nvml": true,
|
||||
"cn/0": false,
|
||||
"cn-lite/0": false
|
||||
},
|
||||
"donate-level": 5,
|
||||
"donate-over-proxy": 1,
|
||||
"log-file": null,
|
||||
|
@ -59,9 +66,10 @@
|
|||
}
|
||||
],
|
||||
"print-time": 60,
|
||||
"health-print-time": 60,
|
||||
"retries": 5,
|
||||
"retry-pause": 5,
|
||||
"syslog": false,
|
||||
"user-agent": null,
|
||||
"watch": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -318,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;
|
||||
|
@ -383,7 +421,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
|
||||
|
@ -456,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);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
const Algorithms &algorithms() const;
|
||||
const std::vector<IBackend *> &backends() const;
|
||||
Job job() const;
|
||||
void execCommand(char command);
|
||||
void pause();
|
||||
void printHashrate(bool details);
|
||||
void setEnabled(bool enabled);
|
||||
|
|
|
@ -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,15 @@ static const char *kRandomX = "randomx";
|
|||
static const char *kOcl = "opencl";
|
||||
#endif
|
||||
|
||||
#ifdef XMRIG_FEATURE_CUDA
|
||||
static const char *kCuda = "cuda";
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(XMRIG_FEATURE_NVML)
|
||||
static const char *kHealthPrintTime = "health-print-time";
|
||||
#endif
|
||||
|
||||
|
||||
class ConfigPrivate
|
||||
{
|
||||
|
@ -73,6 +87,14 @@ public:
|
|||
# ifdef XMRIG_FEATURE_OPENCL
|
||||
OclConfig cl;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_CUDA
|
||||
CudaConfig cuda;
|
||||
# endif
|
||||
|
||||
# if defined(XMRIG_FEATURE_NVML)
|
||||
uint32_t healthPrintTime = 60;
|
||||
# endif
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -104,6 +126,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
|
||||
{
|
||||
|
@ -112,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()) {
|
||||
|
@ -124,6 +162,12 @@ bool xmrig::Config::isShouldSave() const
|
|||
}
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_CUDA
|
||||
if (cuda().isShouldSave()) {
|
||||
return true;
|
||||
}
|
||||
# endif
|
||||
|
||||
return (m_upgrade || cpu().isShouldSave());
|
||||
}
|
||||
|
||||
|
@ -146,6 +190,14 @@ 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
|
||||
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
d_ptr->healthPrintTime = reader.getUint(kHealthPrintTime, d_ptr->healthPrintTime);
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -178,14 +230,21 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
|
|||
doc.AddMember(StringRef(kOcl), cl().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);
|
||||
# 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);
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -39,9 +39,10 @@ namespace xmrig {
|
|||
|
||||
|
||||
class ConfigPrivate;
|
||||
class CudaConfig;
|
||||
class IThread;
|
||||
class RxConfig;
|
||||
class OclConfig;
|
||||
class RxConfig;
|
||||
|
||||
|
||||
class Config : public BaseConfig
|
||||
|
@ -58,10 +59,18 @@ public:
|
|||
const OclConfig &cl() const;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_CUDA
|
||||
const CudaConfig &cuda() const;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
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;
|
||||
|
|
|
@ -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,22 @@ 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
|
||||
|
||||
# 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<uint64_t>(strtol(arg, nullptr, 10)));
|
||||
# endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -72,6 +72,13 @@ R"===(
|
|||
"cn/0": false,
|
||||
"cn-lite/0": false
|
||||
},
|
||||
"cuda": {
|
||||
"enabled": false,
|
||||
"loader": null,
|
||||
"nvml": true,
|
||||
"cn/0": false,
|
||||
"cn-lite/0": false
|
||||
},
|
||||
"donate-level": 5,
|
||||
"donate-over-proxy": 1,
|
||||
"log-file": null,
|
||||
|
@ -93,6 +100,7 @@ R"===(
|
|||
}
|
||||
],
|
||||
"print-time": 60,
|
||||
"health-print-time": 60,
|
||||
"retries": 5,
|
||||
"retry-pause": 5,
|
||||
"syslog": false,
|
||||
|
|
|
@ -103,6 +103,14 @@ 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
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
{ "no-nvml", 0, nullptr, IConfig::NvmlKey },
|
||||
{ "health-print-time", 1, nullptr, IConfig::HealthPrintTimeKey },
|
||||
# endif
|
||||
{ nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
|
|
|
@ -103,11 +103,20 @@ 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
|
||||
# ifdef XMRIG_FEATURE_NVML
|
||||
u += " --no-nvml disable NVML (NVIDIA Management Library) support\n";
|
||||
# endif
|
||||
|
||||
u += "\nLogging:\n";
|
||||
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
|
@ -116,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";
|
||||
|
|
|
@ -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<uint32_t>(((memory() - 1) / 16) * 16); }
|
||||
|
||||
inline static size_t memory(Algorithm::Id algo)
|
||||
{
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace xmrig {
|
|||
class Nonce
|
||||
{
|
||||
public:
|
||||
enum Backend {
|
||||
enum Backend : uint32_t {
|
||||
CPU,
|
||||
OPENCL,
|
||||
CUDA,
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <memory>
|
||||
|
||||
|
||||
#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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue