From cf123b7d8826571d56bfcb295b8727847dc2ca37 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 24 Aug 2019 14:58:50 +0700 Subject: [PATCH] Added OclContext class. --- src/backend/opencl/OclBackend.cpp | 25 ++++------ src/backend/opencl/OclLaunchData.h | 4 ++ src/backend/opencl/opencl.cmake | 2 + src/backend/opencl/wrappers/OclContext.cpp | 58 ++++++++++++++++++++++ src/backend/opencl/wrappers/OclContext.h | 58 ++++++++++++++++++++++ src/backend/opencl/wrappers/OclDevice.cpp | 17 +++++++ src/backend/opencl/wrappers/OclDevice.h | 1 + src/backend/opencl/wrappers/OclLib.cpp | 11 +++- src/backend/opencl/wrappers/OclLib.h | 1 + 9 files changed, 161 insertions(+), 16 deletions(-) create mode 100644 src/backend/opencl/wrappers/OclContext.cpp create mode 100644 src/backend/opencl/wrappers/OclContext.h diff --git a/src/backend/opencl/OclBackend.cpp b/src/backend/opencl/OclBackend.cpp index acb0b627..30b942bd 100644 --- a/src/backend/opencl/OclBackend.cpp +++ b/src/backend/opencl/OclBackend.cpp @@ -32,6 +32,7 @@ #include "backend/opencl/OclBackend.h" #include "backend/opencl/OclConfig.h" #include "backend/opencl/OclLaunchData.h" +#include "backend/opencl/wrappers/OclContext.h" #include "backend/opencl/wrappers/OclLib.h" #include "base/io/log/Log.h" #include "base/net/stratum/Job.h" @@ -119,27 +120,14 @@ 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) { - const String topo = device.hasTopology() ? device.topology().toString() : "n/a"; - const size_t size = device.board().size() + device.name().size() + 64; - char *name = new char[size](); - - if (device.board() == device.name()) { - snprintf(name, size, GREEN_BOLD(" %s"), device.name().data()); - } - else { - snprintf(name, size, GREEN_BOLD(" %s") " (" CYAN_BOLD("%s") ")", device.board().data(), device.name().data()); - } - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu") YELLOW(" %s") "%s " WHITE_BOLD("%uMHz") " cu:" WHITE_BOLD("%u") " mem:" CYAN("%1.2f/%1.2f") " GB", "OPENCL GPU", device.index(), - topo.data(), - name, + device.hasTopology() ? device.topology().toString().data() : "n/a", + device.printableName().data(), device.clock(), device.computeUnits(), static_cast(device.freeMem()) / oneGiB, static_cast(device.globalMem()) / oneGiB); - - delete [] name; } } @@ -166,6 +154,7 @@ public: Algorithm algo; Controller *controller; LaunchStatus status; + OclContext context; OclPlatform platform; std::mutex mutex; std::vector devices; @@ -275,6 +264,12 @@ void xmrig::OclBackend::setJob(const Job &job) return stop(); } + if (!d_ptr->context.init(d_ptr->devices, threads)) { + LOG_WARN("%s " RED_BOLD("disabled") YELLOW(" (OpenCL context unavailable)"), tag); + + return stop(); + } + d_ptr->threads = std::move(threads); d_ptr->start(); } diff --git a/src/backend/opencl/OclLaunchData.h b/src/backend/opencl/OclLaunchData.h index 474d6eba..b8bde5be 100644 --- a/src/backend/opencl/OclLaunchData.h +++ b/src/backend/opencl/OclLaunchData.h @@ -33,6 +33,9 @@ #include "crypto/common/Nonce.h" +typedef struct _cl_context *cl_context; + + namespace xmrig { @@ -52,6 +55,7 @@ public: inline bool operator!=(const OclLaunchData &other) const { return !isEqual(other); } inline bool operator==(const OclLaunchData &other) const { return isEqual(other); } + cl_context ctx = nullptr; const Algorithm algorithm; const bool cache; const Miner *miner; diff --git a/src/backend/opencl/opencl.cmake b/src/backend/opencl/opencl.cmake index 5d64d191..ec5f26aa 100644 --- a/src/backend/opencl/opencl.cmake +++ b/src/backend/opencl/opencl.cmake @@ -10,6 +10,7 @@ if (WITH_OPENCL) src/backend/opencl/OclLaunchData.h src/backend/opencl/OclThread.h src/backend/opencl/OclThreads.h + src/backend/opencl/wrappers/OclContext.h src/backend/opencl/wrappers/OclDevice.h src/backend/opencl/wrappers/OclError.h src/backend/opencl/wrappers/OclLib.h @@ -24,6 +25,7 @@ if (WITH_OPENCL) src/backend/opencl/OclLaunchData.cpp src/backend/opencl/OclThread.cpp src/backend/opencl/OclThreads.cpp + src/backend/opencl/wrappers/OclContext.cpp src/backend/opencl/wrappers/OclDevice.cpp src/backend/opencl/wrappers/OclError.cpp src/backend/opencl/wrappers/OclLib.cpp diff --git a/src/backend/opencl/wrappers/OclContext.cpp b/src/backend/opencl/wrappers/OclContext.cpp new file mode 100644 index 00000000..8f283c78 --- /dev/null +++ b/src/backend/opencl/wrappers/OclContext.cpp @@ -0,0 +1,58 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/opencl/wrappers/OclLib.h" +#include "backend/opencl/wrappers/OclContext.h" + + +xmrig::OclContext::~OclContext() +{ + if (m_ctx) { + OclLib::releaseContext(m_ctx); + } +} + + +bool xmrig::OclContext::init(const std::vector &devices, std::vector &threads) +{ + if (!m_ctx) { + std::vector ids(devices.size()); + for (size_t i = 0; i < devices.size(); ++i) { + ids[i] = devices[i].id(); + } + + m_ctx = OclLib::createContext(ids); + } + + if (!m_ctx) { + return false; + } + + for (OclLaunchData &data : threads) { + data.ctx = m_ctx; + } + + return true; +} diff --git a/src/backend/opencl/wrappers/OclContext.h b/src/backend/opencl/wrappers/OclContext.h new file mode 100644 index 00000000..6902e805 --- /dev/null +++ b/src/backend/opencl/wrappers/OclContext.h @@ -0,0 +1,58 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_OCLCONTEXT_H +#define XMRIG_OCLCONTEXT_H + + +#include "backend/opencl/OclLaunchData.h" +#include "backend/opencl/wrappers/OclDevice.h" + + +typedef struct _cl_context *cl_context; + + +namespace xmrig { + + +class OclContext +{ +public: + OclContext() = default; + ~OclContext(); + + bool init(const std::vector &devices, std::vector &threads); + + inline bool isValid() const { return m_ctx != nullptr; } + inline cl_context ctx() const { return m_ctx; } + +private: + cl_context m_ctx = nullptr; +}; + + +} // namespace xmrig + + +#endif /* XMRIG_OCLCONTEXT_H */ diff --git a/src/backend/opencl/wrappers/OclDevice.cpp b/src/backend/opencl/wrappers/OclDevice.cpp index c3908244..67f99fde 100644 --- a/src/backend/opencl/wrappers/OclDevice.cpp +++ b/src/backend/opencl/wrappers/OclDevice.cpp @@ -29,6 +29,7 @@ #include "backend/opencl/OclThreads.h" #include "backend/opencl/wrappers/OclDevice.h" #include "backend/opencl/wrappers/OclLib.h" +#include "base/io/log/Log.h" #include "crypto/cn/CnAlgo.h" #include "crypto/common/Algorithm.h" #include "rapidjson/document.h" @@ -151,6 +152,22 @@ size_t xmrig::OclDevice::globalMem() const } +xmrig::String xmrig::OclDevice::printableName() const +{ + const size_t size = m_board.size() + m_name.size() + 64; + char *buf = new char[size](); + + if (m_board.isNull()) { + snprintf(buf, size, GREEN_BOLD(" %s"), m_name.data()); + } + else { + snprintf(buf, size, GREEN_BOLD(" %s") " (" CYAN_BOLD("%s") ")", m_board.data(), m_name.data()); + } + + return buf; +} + + uint32_t xmrig::OclDevice::clock() const { return OclLib::getDeviceUint(id(), CL_DEVICE_MAX_CLOCK_FREQUENCY); diff --git a/src/backend/opencl/wrappers/OclDevice.h b/src/backend/opencl/wrappers/OclDevice.h index fcedac85..25d574c8 100644 --- a/src/backend/opencl/wrappers/OclDevice.h +++ b/src/backend/opencl/wrappers/OclDevice.h @@ -64,6 +64,7 @@ public: size_t freeMem() const; size_t globalMem() const; + String printableName() const; uint32_t clock() const; void generate(const Algorithm &algorithm, OclThreads &threads) const; diff --git a/src/backend/opencl/wrappers/OclLib.cpp b/src/backend/opencl/wrappers/OclLib.cpp index 6cc01ff9..1fe56e07 100644 --- a/src/backend/opencl/wrappers/OclLib.cpp +++ b/src/backend/opencl/wrappers/OclLib.cpp @@ -33,7 +33,7 @@ static uv_lib_t oclLib; -static const char *kErrorTemplate = "Error %s when calling %s."; +static const char *kErrorTemplate = MAGENTA_BG_BOLD(WHITE_BOLD_S " ocl ") RED(" error ") RED_BOLD("%s") RED(" when calling ") RED_BOLD("%s"); static const char *kBuildProgram = "clBuildProgram"; static const char *kCreateBuffer = "clCreateBuffer"; @@ -235,12 +235,21 @@ cl_context xmrig::OclLib::createContext(const cl_context_properties *properties, auto result = pCreateContext(properties, num_devices, devices, pfn_notify, user_data, errcode_ret); if (*errcode_ret != CL_SUCCESS) { LOG_ERR(kErrorTemplate, OclError::toString(*errcode_ret), kCreateContext); + + return nullptr; } return result; } +cl_context xmrig::OclLib::createContext(const std::vector &ids) +{ + cl_int ret; + return OclLib::createContext(nullptr, static_cast(ids.size()), ids.data(), nullptr, nullptr, &ret); +} + + cl_int xmrig::OclLib::buildProgram(cl_program program, cl_uint num_devices, const cl_device_id *device_list, const char *options, void (CL_CALLBACK *pfn_notify)(cl_program program, void *user_data), void *user_data) { assert(pBuildProgram != nullptr); diff --git a/src/backend/opencl/wrappers/OclLib.h b/src/backend/opencl/wrappers/OclLib.h index f82fe42f..00b43705 100644 --- a/src/backend/opencl/wrappers/OclLib.h +++ b/src/backend/opencl/wrappers/OclLib.h @@ -48,6 +48,7 @@ public: static cl_command_queue createCommandQueue(cl_context context, cl_device_id device, cl_int *errcode_ret); static cl_context createContext(const cl_context_properties *properties, cl_uint num_devices, const cl_device_id *devices, void (CL_CALLBACK *pfn_notify)(const char *, const void *, size_t, void *), void *user_data, cl_int *errcode_ret); + static cl_context createContext(const std::vector &ids); static cl_int buildProgram(cl_program program, cl_uint num_devices, const cl_device_id *device_list, const char *options = nullptr, void (CL_CALLBACK *pfn_notify)(cl_program program, void *user_data) = nullptr, void *user_data = nullptr); static cl_int enqueueNDRangeKernel(cl_command_queue command_queue, cl_kernel kernel, cl_uint work_dim, const size_t *global_work_offset, const size_t *global_work_size, const size_t *local_work_size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event); static cl_int enqueueReadBuffer(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, size_t offset, size_t size, void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event);