Added platform option.
This commit is contained in:
parent
476e5dcb18
commit
166a68244e
9 changed files with 194 additions and 26 deletions
|
@ -32,6 +32,7 @@
|
||||||
#include "backend/opencl/OclBackend.h"
|
#include "backend/opencl/OclBackend.h"
|
||||||
#include "backend/opencl/OclConfig.h"
|
#include "backend/opencl/OclConfig.h"
|
||||||
#include "backend/opencl/OclLaunchData.h"
|
#include "backend/opencl/OclLaunchData.h"
|
||||||
|
#include "backend/opencl/wrappers/OclLib.h"
|
||||||
#include "base/io/log/Log.h"
|
#include "base/io/log/Log.h"
|
||||||
#include "base/net/stratum/Job.h"
|
#include "base/net/stratum/Job.h"
|
||||||
#include "base/tools/Chrono.h"
|
#include "base/tools/Chrono.h"
|
||||||
|
@ -52,7 +53,7 @@ namespace xmrig {
|
||||||
extern template class Threads<OclThreads>;
|
extern template class Threads<OclThreads>;
|
||||||
|
|
||||||
|
|
||||||
static const char *tag = MAGENTA_BG_BOLD(" ocl ");
|
static const char *tag = MAGENTA_BG_BOLD(WHITE_BOLD_S " ocl ");
|
||||||
static const String kType = "opencl";
|
static const String kType = "opencl";
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,6 +90,30 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool init(const OclConfig &cl)
|
||||||
|
{
|
||||||
|
if (!OclLib::init(cl.loader())) {
|
||||||
|
LOG_ERR("%s" RED_S " failed to load OpenCL runtime (%s): " RED_BOLD_S "\"%s\"", tag, OclLib::loader().data(), OclLib::lastError());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!platform.isValid()) {
|
||||||
|
platform = cl.platform();
|
||||||
|
|
||||||
|
if (!platform.isValid()) {
|
||||||
|
LOG_ERR("%s" RED_S " selected OpenCL platform NOT found.", tag);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO("%s use platform " WHITE_BOLD("%s") "/" WHITE_BOLD("%s"), tag, platform.name().data(), platform.version().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void start()
|
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(" threads)") " scratchpad " CYAN_BOLD("%zu KB"),
|
||||||
|
@ -123,6 +148,7 @@ public:
|
||||||
Algorithm algo;
|
Algorithm algo;
|
||||||
Controller *controller;
|
Controller *controller;
|
||||||
LaunchStatus status;
|
LaunchStatus status;
|
||||||
|
OclPlatform platform;
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
std::vector<OclLaunchData> threads;
|
std::vector<OclLaunchData> threads;
|
||||||
String profileName;
|
String profileName;
|
||||||
|
@ -143,6 +169,8 @@ xmrig::OclBackend::OclBackend(Controller *controller) :
|
||||||
xmrig::OclBackend::~OclBackend()
|
xmrig::OclBackend::~OclBackend()
|
||||||
{
|
{
|
||||||
delete d_ptr;
|
delete d_ptr;
|
||||||
|
|
||||||
|
OclLib::close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,6 +241,9 @@ void xmrig::OclBackend::setJob(const Job &job)
|
||||||
}
|
}
|
||||||
|
|
||||||
const OclConfig &cl = d_ptr->controller->config()->cl();
|
const OclConfig &cl = d_ptr->controller->config()->cl();
|
||||||
|
if (!d_ptr->init(cl)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<OclLaunchData> threads = cl.get(d_ptr->controller->miner(), job.algorithm());
|
std::vector<OclLaunchData> threads = cl.get(d_ptr->controller->miner(), job.algorithm());
|
||||||
// if (d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) {
|
// if (d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) {
|
||||||
|
@ -272,16 +303,13 @@ rapidjson::Value xmrig::OclBackend::toJSON(rapidjson::Document &doc) const
|
||||||
{
|
{
|
||||||
using namespace rapidjson;
|
using namespace rapidjson;
|
||||||
auto &allocator = doc.GetAllocator();
|
auto &allocator = doc.GetAllocator();
|
||||||
const CpuConfig &cpu = d_ptr->controller->config()->cpu();
|
|
||||||
|
|
||||||
Value out(kObjectType);
|
Value out(kObjectType);
|
||||||
out.AddMember("type", type().toJSON(), allocator);
|
out.AddMember("type", type().toJSON(), allocator);
|
||||||
out.AddMember("enabled", isEnabled(), allocator);
|
out.AddMember("enabled", isEnabled(), allocator);
|
||||||
out.AddMember("algo", d_ptr->algo.toJSON(), allocator);
|
out.AddMember("algo", d_ptr->algo.toJSON(), allocator);
|
||||||
out.AddMember("profile", profileName().toJSON(), allocator);
|
out.AddMember("profile", profileName().toJSON(), allocator);
|
||||||
out.AddMember("hw-aes", cpu.isHwAES(), allocator);
|
out.AddMember("platform", d_ptr->platform.toJSON(doc), allocator);
|
||||||
out.AddMember("priority", cpu.priority(), allocator);
|
|
||||||
out.AddMember("memory", static_cast<uint64_t>(d_ptr->algo.isValid() ? (d_ptr->ways() * d_ptr->algo.l3()) : 0), allocator);
|
|
||||||
|
|
||||||
if (d_ptr->threads.empty() || !hashrate()) {
|
if (d_ptr->threads.empty() || !hashrate()) {
|
||||||
return out;
|
return out;
|
||||||
|
|
|
@ -30,7 +30,13 @@
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
static const char *kCache = "cache";
|
||||||
static const char *kEnabled = "enabled";
|
static const char *kEnabled = "enabled";
|
||||||
|
static const char *kLoader = "loader";
|
||||||
|
static const char *kPlatform = "platform";
|
||||||
|
static const char *kAMD = "AMD";
|
||||||
|
static const char *kNVIDIA = "NVIDIA";
|
||||||
|
static const char *kINTEL = "INTEL";
|
||||||
|
|
||||||
|
|
||||||
extern template class Threads<OclThreads>;
|
extern template class Threads<OclThreads>;
|
||||||
|
@ -38,11 +44,51 @@ extern template class Threads<OclThreads>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
xmrig::OclConfig::OclConfig()
|
xmrig::OclConfig::OclConfig() :
|
||||||
|
m_platformVendor(kAMD)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::OclPlatform xmrig::OclConfig::platform() const
|
||||||
|
{
|
||||||
|
const auto platforms = OclPlatform::get();
|
||||||
|
if (platforms.empty()) {
|
||||||
|
return OclPlatform();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_platformVendor.isEmpty()) {
|
||||||
|
String search;
|
||||||
|
String vendor = m_platformVendor;
|
||||||
|
vendor.toUpper();
|
||||||
|
|
||||||
|
if (vendor == kAMD) {
|
||||||
|
search = "Advanced Micro Devices";
|
||||||
|
}
|
||||||
|
else if (vendor == kNVIDIA) {
|
||||||
|
search = kNVIDIA;
|
||||||
|
}
|
||||||
|
else if (vendor == kINTEL) {
|
||||||
|
search = "Intel";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
search = m_platformVendor;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &platform : platforms) {
|
||||||
|
if (platform.vendor().contains(search)) {
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_platformIndex < platforms.size()) {
|
||||||
|
return platforms[m_platformIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
return OclPlatform();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
rapidjson::Value xmrig::OclConfig::toJSON(rapidjson::Document &doc) const
|
rapidjson::Value xmrig::OclConfig::toJSON(rapidjson::Document &doc) const
|
||||||
{
|
{
|
||||||
using namespace rapidjson;
|
using namespace rapidjson;
|
||||||
|
@ -51,6 +97,9 @@ rapidjson::Value xmrig::OclConfig::toJSON(rapidjson::Document &doc) const
|
||||||
Value obj(kObjectType);
|
Value obj(kObjectType);
|
||||||
|
|
||||||
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
|
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
|
||||||
|
obj.AddMember(StringRef(kCache), m_cache, allocator);
|
||||||
|
obj.AddMember(StringRef(kLoader), m_loader.toJSON(), allocator);
|
||||||
|
obj.AddMember(StringRef(kPlatform), m_platformVendor.isEmpty() ? Value(m_platformIndex) : m_platformVendor.toJSON(), allocator);
|
||||||
|
|
||||||
m_threads.toJSON(obj, doc);
|
m_threads.toJSON(obj, doc);
|
||||||
|
|
||||||
|
@ -70,6 +119,10 @@ void xmrig::OclConfig::read(const rapidjson::Value &value)
|
||||||
{
|
{
|
||||||
if (value.IsObject()) {
|
if (value.IsObject()) {
|
||||||
m_enabled = Json::getBool(value, kEnabled, m_enabled);
|
m_enabled = Json::getBool(value, kEnabled, m_enabled);
|
||||||
|
m_cache = Json::getBool(value, kCache, m_cache);
|
||||||
|
m_loader = Json::getString(value, kLoader);
|
||||||
|
|
||||||
|
setPlatform(Json::getValue(value, kPlatform));
|
||||||
|
|
||||||
if (!m_threads.read(value)) {
|
if (!m_threads.read(value)) {
|
||||||
generate();
|
generate();
|
||||||
|
@ -88,3 +141,15 @@ void xmrig::OclConfig::generate()
|
||||||
{
|
{
|
||||||
m_shouldSave = true;
|
m_shouldSave = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::OclConfig::setPlatform(const rapidjson::Value &platform)
|
||||||
|
{
|
||||||
|
if (platform.IsString()) {
|
||||||
|
m_platformVendor = platform.GetString();
|
||||||
|
}
|
||||||
|
else if (platform.IsUint()) {
|
||||||
|
m_platformVendor = nullptr;
|
||||||
|
m_platformIndex = platform.GetUint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "backend/common/Threads.h"
|
#include "backend/common/Threads.h"
|
||||||
#include "backend/opencl/OclLaunchData.h"
|
#include "backend/opencl/OclLaunchData.h"
|
||||||
#include "backend/opencl/OclThreads.h"
|
#include "backend/opencl/OclThreads.h"
|
||||||
|
#include "backend/opencl/wrappers/OclPlatform.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
@ -39,20 +40,28 @@ class OclConfig
|
||||||
public:
|
public:
|
||||||
OclConfig();
|
OclConfig();
|
||||||
|
|
||||||
|
OclPlatform platform() const;
|
||||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||||
std::vector<OclLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
|
std::vector<OclLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
|
||||||
void read(const rapidjson::Value &value);
|
void read(const rapidjson::Value &value);
|
||||||
|
|
||||||
|
inline bool isCacheEnabled() const { return m_cache; }
|
||||||
inline bool isEnabled() const { return m_enabled; }
|
inline bool isEnabled() const { return m_enabled; }
|
||||||
inline bool isShouldSave() const { return m_shouldSave; }
|
inline bool isShouldSave() const { return m_shouldSave; }
|
||||||
|
inline const String &loader() const { return m_loader; }
|
||||||
inline const Threads<OclThreads> &threads() const { return m_threads; }
|
inline const Threads<OclThreads> &threads() const { return m_threads; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void generate();
|
void generate();
|
||||||
|
void setPlatform(const rapidjson::Value &platform);
|
||||||
|
|
||||||
|
bool m_cache = true;
|
||||||
bool m_enabled = true;
|
bool m_enabled = true;
|
||||||
bool m_shouldSave = false;
|
bool m_shouldSave = false;
|
||||||
|
String m_loader;
|
||||||
|
String m_platformVendor;
|
||||||
Threads<OclThreads> m_threads;
|
Threads<OclThreads> m_threads;
|
||||||
|
uint32_t m_platformIndex = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -123,26 +123,36 @@ static setKernelArg_t pSetKernelArg = nu
|
||||||
#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) { return false; }
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
bool OclLib::m_initialized = false;
|
||||||
|
bool OclLib::m_ready = false;
|
||||||
|
String OclLib::m_loader;
|
||||||
|
|
||||||
|
} // namespace xmrig
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::OclLib::init(const char *fileName)
|
bool xmrig::OclLib::init(const char *fileName)
|
||||||
{
|
{
|
||||||
if (uv_dlopen(fileName == nullptr ? defaultLoader() : fileName, &oclLib) == -1 || !load()) {
|
if (!m_initialized) {
|
||||||
LOG_ERR("Failed to load OpenCL runtime: %s", uv_dlerror(&oclLib));
|
m_loader = fileName == nullptr ? defaultLoader() : fileName;
|
||||||
return false;
|
m_ready = uv_dlopen(m_loader, &oclLib) == 0 && load();
|
||||||
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return m_ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *xmrig::OclLib::defaultLoader()
|
const char *xmrig::OclLib::lastError()
|
||||||
{
|
{
|
||||||
# if defined(__APPLE__)
|
return uv_dlerror(&oclLib);
|
||||||
return "/System/Library/Frameworks/OpenCL.framework/OpenCL";
|
}
|
||||||
# elif defined(_WIN32)
|
|
||||||
return "OpenCL.dll";
|
|
||||||
# else
|
void xmrig::OclLib::close()
|
||||||
return "libOpenCL.so";
|
{
|
||||||
# endif
|
uv_dlclose(&oclLib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -181,6 +191,18 @@ bool xmrig::OclLib::load()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *xmrig::OclLib::defaultLoader()
|
||||||
|
{
|
||||||
|
# if defined(__APPLE__)
|
||||||
|
return "/System/Library/Frameworks/OpenCL.framework/OpenCL";
|
||||||
|
# elif defined(_WIN32)
|
||||||
|
return "OpenCL.dll";
|
||||||
|
# else
|
||||||
|
return "libOpenCL.so";
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cl_command_queue xmrig::OclLib::createCommandQueue(cl_context context, cl_device_id device, cl_int *errcode_ret)
|
cl_command_queue xmrig::OclLib::createCommandQueue(cl_context context, cl_device_id device, cl_int *errcode_ret)
|
||||||
{
|
{
|
||||||
cl_command_queue result;
|
cl_command_queue result;
|
||||||
|
|
|
@ -40,7 +40,10 @@ class OclLib
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static bool init(const char *fileName = nullptr);
|
static bool init(const char *fileName = nullptr);
|
||||||
static const char *defaultLoader();
|
static const char *lastError();
|
||||||
|
static void close();
|
||||||
|
|
||||||
|
static inline const String &loader() { return m_loader; }
|
||||||
|
|
||||||
static cl_command_queue createCommandQueue(cl_context context, cl_device_id device, cl_int *errcode_ret);
|
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 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);
|
||||||
|
@ -76,6 +79,11 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool load();
|
static bool load();
|
||||||
|
static const char *defaultLoader();
|
||||||
|
|
||||||
|
static bool m_initialized;
|
||||||
|
static bool m_ready;
|
||||||
|
static String m_loader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include "backend/opencl/wrappers/OclLib.h"
|
#include "backend/opencl/wrappers/OclLib.h"
|
||||||
#include "backend/opencl/wrappers/OclPlatform.h"
|
#include "backend/opencl/wrappers/OclPlatform.h"
|
||||||
|
#include "rapidjson/document.h"
|
||||||
|
|
||||||
|
|
||||||
std::vector<xmrig::OclPlatform> xmrig::OclPlatform::get()
|
std::vector<xmrig::OclPlatform> xmrig::OclPlatform::get()
|
||||||
|
@ -65,6 +63,27 @@ void xmrig::OclPlatform::print()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rapidjson::Value xmrig::OclPlatform::toJSON(rapidjson::Document &doc) const
|
||||||
|
{
|
||||||
|
using namespace rapidjson;
|
||||||
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
|
if (!isValid()) {
|
||||||
|
return Value(kNullType);
|
||||||
|
}
|
||||||
|
|
||||||
|
Value out(kObjectType);
|
||||||
|
out.AddMember("index", index(), allocator);
|
||||||
|
out.AddMember("profile", profile().toJSON(doc), allocator);
|
||||||
|
out.AddMember("version", version().toJSON(doc), allocator);
|
||||||
|
out.AddMember("name", name().toJSON(doc), allocator);
|
||||||
|
out.AddMember("vendor", vendor().toJSON(doc), allocator);
|
||||||
|
out.AddMember("extensions", extensions().toJSON(doc), allocator);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
xmrig::String xmrig::OclPlatform::extensions() const
|
xmrig::String xmrig::OclPlatform::extensions() const
|
||||||
{
|
{
|
||||||
return OclLib::getPlatformInfo(id(), CL_PLATFORM_EXTENSIONS);
|
return OclLib::getPlatformInfo(id(), CL_PLATFORM_EXTENSIONS);
|
||||||
|
|
|
@ -47,9 +47,11 @@ public:
|
||||||
static std::vector<OclPlatform> get();
|
static std::vector<OclPlatform> get();
|
||||||
static void print();
|
static void print();
|
||||||
|
|
||||||
|
inline bool isValid() const { return m_id != nullptr; }
|
||||||
inline cl_platform_id id() const { return m_id; }
|
inline cl_platform_id id() const { return m_id; }
|
||||||
inline size_t index() const { return m_index; }
|
inline size_t index() const { return m_index; }
|
||||||
|
|
||||||
|
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||||
String extensions() const;
|
String extensions() const;
|
||||||
String name() const;
|
String name() const;
|
||||||
String profile() const;
|
String profile() const;
|
||||||
|
|
|
@ -146,6 +146,20 @@ xmrig::String &xmrig::String::toLower()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::String &xmrig::String::toUpper()
|
||||||
|
{
|
||||||
|
if (isNull() || isEmpty()) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size(); ++i) {
|
||||||
|
m_data[i] = static_cast<char>(toupper(m_data[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
xmrig::String xmrig::String::join(const std::vector<xmrig::String> &vec, char sep)
|
xmrig::String xmrig::String::join(const std::vector<xmrig::String> &vec, char sep)
|
||||||
{
|
{
|
||||||
if (vec.empty()) {
|
if (vec.empty()) {
|
||||||
|
|
|
@ -87,6 +87,7 @@ public:
|
||||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||||
std::vector<xmrig::String> split(char sep) const;
|
std::vector<xmrig::String> split(char sep) const;
|
||||||
String &toLower();
|
String &toLower();
|
||||||
|
String &toUpper();
|
||||||
|
|
||||||
static String join(const std::vector<xmrig::String> &vec, char sep);
|
static String join(const std::vector<xmrig::String> &vec, char sep);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue