Browse Source

Merge pull request #2154 from LefterisJP/opencl_query_gpu_only

OpenCL Query Only GPU devices
cl-refactor
Gav Wood 10 years ago
parent
commit
9c25eb9fd0
  1. 96
      ethminer/MinerAux.h
  2. 34
      libethash-cl/ethash_cl_miner.cpp
  3. 6
      libethash-cl/ethash_cl_miner.h
  4. 2
      libethash-cl/ethash_cl_miner_kernel.cl
  5. 6
      libethcore/Ethash.cpp
  6. 9
      libethcore/Ethash.h

96
ethminer/MinerAux.h

@ -97,11 +97,11 @@ public:
if ((arg == "-F" || arg == "--farm") && i + 1 < argc) if ((arg == "-F" || arg == "--farm") && i + 1 < argc)
{ {
mode = OperationMode::Farm; mode = OperationMode::Farm;
farmURL = argv[++i]; m_farmURL = argv[++i];
} }
else if (arg == "--farm-recheck" && i + 1 < argc) else if (arg == "--farm-recheck" && i + 1 < argc)
try { try {
farmRecheckPeriod = stol(argv[++i]); m_farmRecheckPeriod = stol(argv[++i]);
} }
catch (...) catch (...)
{ {
@ -110,7 +110,7 @@ public:
} }
else if (arg == "--opencl-platform" && i + 1 < argc) else if (arg == "--opencl-platform" && i + 1 < argc)
try { try {
openclPlatform = stol(argv[++i]); m_openclPlatform = stol(argv[++i]);
} }
catch (...) catch (...)
{ {
@ -119,8 +119,8 @@ public:
} }
else if (arg == "--opencl-device" && i + 1 < argc) else if (arg == "--opencl-device" && i + 1 < argc)
try { try {
openclDevice = stol(argv[++i]); m_openclDevice = stol(argv[++i]);
miningThreads = 1; m_miningThreads = 1;
} }
catch (...) catch (...)
{ {
@ -128,17 +128,16 @@ public:
throw BadArgument(); throw BadArgument();
} }
else if (arg == "--list-devices") else if (arg == "--list-devices")
{ m_shouldListDevices = true;
ProofOfWork::GPUMiner::listDevices(); else if (arg == "--allow-opencl-cpu")
exit(0); m_clAllowCPU = true;
}
else if (arg == "--phone-home" && i + 1 < argc) else if (arg == "--phone-home" && i + 1 < argc)
{ {
string m = argv[++i]; string m = argv[++i];
if (isTrue(m)) if (isTrue(m))
phoneHome = true; m_phoneHome = true;
else if (isFalse(m)) else if (isFalse(m))
phoneHome = false; m_phoneHome = false;
else else
{ {
cerr << "Bad " << arg << " option: " << m << endl; cerr << "Bad " << arg << " option: " << m << endl;
@ -147,7 +146,7 @@ public:
} }
else if (arg == "--benchmark-warmup" && i + 1 < argc) else if (arg == "--benchmark-warmup" && i + 1 < argc)
try { try {
benchmarkWarmup = stol(argv[++i]); m_benchmarkWarmup = stol(argv[++i]);
} }
catch (...) catch (...)
{ {
@ -156,7 +155,7 @@ public:
} }
else if (arg == "--benchmark-trial" && i + 1 < argc) else if (arg == "--benchmark-trial" && i + 1 < argc)
try { try {
benchmarkTrial = stol(argv[++i]); m_benchmarkTrial = stol(argv[++i]);
} }
catch (...) catch (...)
{ {
@ -165,7 +164,7 @@ public:
} }
else if (arg == "--benchmark-trials" && i + 1 < argc) else if (arg == "--benchmark-trials" && i + 1 < argc)
try { try {
benchmarkTrials = stol(argv[++i]); m_benchmarkTrials = stol(argv[++i]);
} }
catch (...) catch (...)
{ {
@ -175,21 +174,10 @@ public:
else if (arg == "-C" || arg == "--cpu") else if (arg == "-C" || arg == "--cpu")
m_minerType = MinerType::CPU; m_minerType = MinerType::CPU;
else if (arg == "-G" || arg == "--opencl") else if (arg == "-G" || arg == "--opencl")
{ m_minerType = MinerType::GPU;
if (!ProofOfWork::GPUMiner::configureGPU())
{
cout << "No GPU device with sufficient memory was found. Defaulting to CPU" << endl;
m_minerType = MinerType::CPU;
}
else
{
m_minerType = MinerType::GPU;
miningThreads = 1;
}
}
else if (arg == "--no-precompute") else if (arg == "--no-precompute")
{ {
precompute = false; m_precompute = false;
} }
else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc) else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc)
{ {
@ -197,7 +185,7 @@ public:
mode = OperationMode::DAGInit; mode = OperationMode::DAGInit;
try try
{ {
initDAG = stol(m); m_initDAG = stol(m);
} }
catch (...) catch (...)
{ {
@ -247,7 +235,7 @@ public:
else if ((arg == "-t" || arg == "--mining-threads") && i + 1 < argc) else if ((arg == "-t" || arg == "--mining-threads") && i + 1 < argc)
{ {
try { try {
miningThreads = stol(argv[++i]); m_miningThreads = stol(argv[++i]);
} }
catch (...) catch (...)
{ {
@ -262,20 +250,29 @@ public:
void execute() void execute()
{ {
if (m_shouldListDevices)
{
ProofOfWork::GPUMiner::listDevices();
exit(0);
}
if (m_minerType == MinerType::CPU) if (m_minerType == MinerType::CPU)
ProofOfWork::CPUMiner::setNumInstances(miningThreads); ProofOfWork::CPUMiner::setNumInstances(m_miningThreads);
else if (m_minerType == MinerType::GPU) else if (m_minerType == MinerType::GPU)
{ {
ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform); ProofOfWork::GPUMiner::setNumInstances(m_miningThreads);
ProofOfWork::GPUMiner::setDefaultDevice(openclDevice); if (!ProofOfWork::GPUMiner::configureGPU(m_openclPlatform, m_openclDevice, m_clAllowCPU))
ProofOfWork::GPUMiner::setNumInstances(miningThreads); {
cout << "No GPU device with sufficient memory was found. Can't GPU mine. Remove the -G argument" << endl;
exit(1);
}
} }
if (mode == OperationMode::DAGInit) if (mode == OperationMode::DAGInit)
doInitDAG(initDAG); doInitDAG(m_initDAG);
else if (mode == OperationMode::Benchmark) else if (mode == OperationMode::Benchmark)
doBenchmark(m_minerType, phoneHome, benchmarkWarmup, benchmarkTrial, benchmarkTrials); doBenchmark(m_minerType, m_phoneHome, m_benchmarkWarmup, m_benchmarkTrial, m_benchmarkTrials);
else if (mode == OperationMode::Farm) else if (mode == OperationMode::Farm)
doFarm(m_minerType, farmURL, farmRecheckPeriod); doFarm(m_minerType, m_farmURL, m_farmRecheckPeriod);
} }
static void streamHelp(ostream& _out) static void streamHelp(ostream& _out)
@ -441,7 +438,7 @@ private:
cnote << "Grabbing DAG for" << newSeedHash; cnote << "Grabbing DAG for" << newSeedHash;
if (!(dag = EthashAux::full(newSeedHash, true, [&](unsigned _pc){ cout << "\rCreating DAG. " << _pc << "% done..." << flush; return 0; }))) if (!(dag = EthashAux::full(newSeedHash, true, [&](unsigned _pc){ cout << "\rCreating DAG. " << _pc << "% done..." << flush; return 0; })))
BOOST_THROW_EXCEPTION(DAGCreationFailure()); BOOST_THROW_EXCEPTION(DAGCreationFailure());
if (precompute) if (m_precompute)
EthashAux::computeFull(sha3(newSeedHash), true); EthashAux::computeFull(sha3(newSeedHash), true);
if (hh != current.headerHash) if (hh != current.headerHash)
{ {
@ -490,22 +487,23 @@ private:
/// Mining options /// Mining options
MinerType m_minerType = MinerType::CPU; MinerType m_minerType = MinerType::CPU;
unsigned openclPlatform = 0; unsigned m_openclPlatform = 0;
unsigned openclDevice = 0; unsigned m_openclDevice = 0;
unsigned miningThreads = UINT_MAX; unsigned m_miningThreads = UINT_MAX;
unsigned dagChunks = 1; bool m_shouldListDevices = false;
bool m_clAllowCPU = false;
/// DAG initialisation param. /// DAG initialisation param.
unsigned initDAG = 0; unsigned m_initDAG = 0;
/// Benchmarking params /// Benchmarking params
bool phoneHome = true; bool m_phoneHome = true;
unsigned benchmarkWarmup = 3; unsigned m_benchmarkWarmup = 3;
unsigned benchmarkTrial = 3; unsigned m_benchmarkTrial = 3;
unsigned benchmarkTrials = 5; unsigned m_benchmarkTrials = 5;
/// Farm params /// Farm params
string farmURL = "http://127.0.0.1:8545"; string m_farmURL = "http://127.0.0.1:8545";
unsigned farmRecheckPeriod = 500; unsigned m_farmRecheckPeriod = 500;
bool precompute = true; bool m_precompute = true;
}; };

34
libethash-cl/ethash_cl_miner.cpp

@ -51,6 +51,8 @@ using namespace std;
// TODO: If at any point we can use libdevcore in here then we should switch to using a LogChannel // TODO: If at any point we can use libdevcore in here then we should switch to using a LogChannel
#define ETHCL_LOG(_contents) cout << "[OPENCL]:" << _contents << endl #define ETHCL_LOG(_contents) cout << "[OPENCL]:" << _contents << endl
// Types of OpenCL devices we are interested in
#define ETHCL_QUERIED_DEVICE_TYPES (CL_DEVICE_TYPE_GPU | CL_DEVICE_TYPE_ACCELERATOR)
static void addDefinition(string& _source, char const* _id, unsigned _value) static void addDefinition(string& _source, char const* _id, unsigned _value)
{ {
@ -82,9 +84,8 @@ string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _deviceId)
} }
// get GPU device of the selected platform // get GPU device of the selected platform
vector<cl::Device> devices;
unsigned platform_num = min<unsigned>(_platformId, platforms.size() - 1); unsigned platform_num = min<unsigned>(_platformId, platforms.size() - 1);
platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices); vector<cl::Device> devices = getDevices(platforms, _platformId);
if (devices.empty()) if (devices.empty())
{ {
ETHCL_LOG("No OpenCL devices found."); ETHCL_LOG("No OpenCL devices found.");
@ -99,6 +100,17 @@ string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _deviceId)
return "{ \"platform\": \"" + platforms[platform_num].getInfo<CL_PLATFORM_NAME>() + "\", \"device\": \"" + device.getInfo<CL_DEVICE_NAME>() + "\", \"version\": \"" + device_version + "\" }"; return "{ \"platform\": \"" + platforms[platform_num].getInfo<CL_PLATFORM_NAME>() + "\", \"device\": \"" + device.getInfo<CL_DEVICE_NAME>() + "\", \"version\": \"" + device_version + "\" }";
} }
std::vector<cl::Device> ethash_cl_miner::getDevices(std::vector<cl::Platform> const& _platforms, unsigned _platformId)
{
vector<cl::Device> devices;
unsigned platform_num = min<unsigned>(_platformId, _platforms.size() - 1);
_platforms[platform_num].getDevices(
s_allowCPU ? CL_DEVICE_TYPE_ALL : ETHCL_QUERIED_DEVICE_TYPES,
&devices
);
return devices;
}
unsigned ethash_cl_miner::getNumPlatforms() unsigned ethash_cl_miner::getNumPlatforms()
{ {
vector<cl::Platform> platforms; vector<cl::Platform> platforms;
@ -116,9 +128,7 @@ unsigned ethash_cl_miner::getNumDevices(unsigned _platformId)
return 0; return 0;
} }
vector<cl::Device> devices; vector<cl::Device> devices = getDevices(platforms, _platformId);
unsigned platform_num = min<unsigned>(_platformId, platforms.size() - 1);
platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices);
if (devices.empty()) if (devices.empty())
{ {
ETHCL_LOG("No OpenCL devices found."); ETHCL_LOG("No OpenCL devices found.");
@ -127,8 +137,9 @@ unsigned ethash_cl_miner::getNumDevices(unsigned _platformId)
return devices.size(); return devices.size();
} }
bool ethash_cl_miner::configureGPU() bool ethash_cl_miner::configureGPU(bool _allowCPU)
{ {
s_allowCPU = _allowCPU;
return searchForAllDevices([](cl::Device const _device) -> bool return searchForAllDevices([](cl::Device const _device) -> bool
{ {
cl_ulong result; cl_ulong result;
@ -152,6 +163,8 @@ bool ethash_cl_miner::configureGPU()
); );
} }
bool ethash_cl_miner::s_allowCPU = false;
bool ethash_cl_miner::searchForAllDevices(function<bool(cl::Device const&)> _callback) bool ethash_cl_miner::searchForAllDevices(function<bool(cl::Device const&)> _callback)
{ {
vector<cl::Platform> platforms; vector<cl::Platform> platforms;
@ -175,8 +188,7 @@ bool ethash_cl_miner::searchForAllDevices(unsigned _platformId, function<bool(cl
if (_platformId >= platforms.size()) if (_platformId >= platforms.size())
return false; return false;
vector<cl::Device> devices; vector<cl::Device> devices = getDevices(platforms, _platformId);
platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices);
for (cl::Device const& device: devices) for (cl::Device const& device: devices)
if (_callback(device)) if (_callback(device))
return true; return true;
@ -204,8 +216,7 @@ void ethash_cl_miner::doForAllDevices(unsigned _platformId, function<void(cl::De
if (_platformId >= platforms.size()) if (_platformId >= platforms.size())
return; return;
vector<cl::Device> devices; vector<cl::Device> devices = getDevices(platforms, _platformId);
platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices);
for (cl::Device const& device: devices) for (cl::Device const& device: devices)
_callback(device); _callback(device);
} }
@ -253,8 +264,7 @@ bool ethash_cl_miner::init(
ETHCL_LOG("Using platform: " << platforms[_platformId].getInfo<CL_PLATFORM_NAME>().c_str()); ETHCL_LOG("Using platform: " << platforms[_platformId].getInfo<CL_PLATFORM_NAME>().c_str());
// get GPU device of the default platform // get GPU device of the default platform
vector<cl::Device> devices; vector<cl::Device> devices = getDevices(platforms, _platformId);
platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices);
if (devices.empty()) if (devices.empty())
{ {
ETHCL_LOG("No OpenCL devices found."); ETHCL_LOG("No OpenCL devices found.");

6
libethash-cl/ethash_cl_miner.h

@ -40,7 +40,7 @@ public:
static unsigned getNumDevices(unsigned _platformId = 0); static unsigned getNumDevices(unsigned _platformId = 0);
static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0); static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0);
static void listDevices(); static void listDevices();
static bool configureGPU(); static bool configureGPU(bool _allowCPU);
bool init( bool init(
uint8_t const* _dag, uint8_t const* _dag,
@ -56,6 +56,9 @@ public:
void search_chunk(uint8_t const* header, uint64_t target, search_hook& hook); void search_chunk(uint8_t const* header, uint64_t target, search_hook& hook);
private: private:
static std::vector<cl::Device> getDevices(std::vector<cl::Platform> const& _platforms, unsigned _platformId);
enum { c_max_search_results = 63, c_num_buffers = 2, c_hash_batch_size = 1024, c_search_batch_size = 1024*256 }; enum { c_max_search_results = 63, c_num_buffers = 2, c_hash_batch_size = 1024, c_search_batch_size = 1024*256 };
cl::Context m_context; cl::Context m_context;
@ -70,4 +73,5 @@ private:
unsigned m_workgroup_size; unsigned m_workgroup_size;
bool m_opencl_1_1; bool m_opencl_1_1;
static bool s_allowCPU;
}; };

2
libethash-cl/ethash_cl_miner_kernel.cl

@ -585,4 +585,4 @@ __kernel void ethash_search_chunks(
uint slot = min(convert_uint(MAX_OUTPUTS), convert_uint(atomic_inc(&g_output[0]) + 1)); uint slot = min(convert_uint(MAX_OUTPUTS), convert_uint(atomic_inc(&g_output[0]) + 1));
g_output[slot] = gid; g_output[slot] = gid;
} }
} }

6
libethcore/Ethash.cpp

@ -381,9 +381,11 @@ void Ethash::GPUMiner::listDevices()
return ethash_cl_miner::listDevices(); return ethash_cl_miner::listDevices();
} }
bool Ethash::GPUMiner::configureGPU() bool Ethash::GPUMiner::configureGPU(unsigned _platformId, unsigned _deviceId, bool _allowCPU)
{ {
return ethash_cl_miner::configureGPU(); s_platformId = _platformId;
s_deviceId = _deviceId;
return ethash_cl_miner::configureGPU(_allowCPU);
} }
#endif #endif

9
libethcore/Ethash.h

@ -87,11 +87,8 @@ public:
static unsigned instances() { return s_numInstances > 0 ? s_numInstances : std::thread::hardware_concurrency(); } static unsigned instances() { return s_numInstances > 0 ? s_numInstances : std::thread::hardware_concurrency(); }
static std::string platformInfo(); static std::string platformInfo();
static void setDefaultPlatform(unsigned) {}
static void setDagChunks(unsigned) {}
static void setDefaultDevice(unsigned) {}
static void listDevices() {} static void listDevices() {}
static bool configureGPU() { return false; } static bool configureGPU(unsigned, unsigned, bool) { return false; }
static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, std::thread::hardware_concurrency()); } static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, std::thread::hardware_concurrency()); }
protected: protected:
void kickOff() override void kickOff() override
@ -120,9 +117,7 @@ public:
static std::string platformInfo(); static std::string platformInfo();
static unsigned getNumDevices(); static unsigned getNumDevices();
static void listDevices(); static void listDevices();
static bool configureGPU(); static bool configureGPU(unsigned _platformId, unsigned _deviceId, bool _allowCPU);
static void setDefaultPlatform(unsigned _id) { s_platformId = _id; }
static void setDefaultDevice(unsigned _id) { s_deviceId = _id; }
static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, getNumDevices()); } static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, getNumDevices()); }
protected: protected:

Loading…
Cancel
Save