|
|
@ -78,30 +78,28 @@ ethash_cl_miner::~ethash_cl_miner() |
|
|
|
finish(); |
|
|
|
} |
|
|
|
|
|
|
|
// Quite ugly. Saves us a lot of typing on these static functions
|
|
|
|
// since we can't keep the platforms vector in the class (static class/functions)
|
|
|
|
//
|
|
|
|
// LTODO: With a bit of general refactoring this could go away and platforms
|
|
|
|
// be queried only once and kept in the class.
|
|
|
|
#define ETHASHCL_GET_PLATFORMS(platforms_, failStmt_) \ |
|
|
|
do { \ |
|
|
|
try \ |
|
|
|
{ \ |
|
|
|
cl::Platform::get(&platforms_); \ |
|
|
|
} \ |
|
|
|
catch (cl::Error const& err) \ |
|
|
|
{ \ |
|
|
|
int errCode = err.err(); \ |
|
|
|
if (errCode == CL_PLATFORM_NOT_FOUND_KHR) \ |
|
|
|
ETHCL_LOG("No OpenCL platforms found"); \ |
|
|
|
failStmt_; \ |
|
|
|
} \ |
|
|
|
} while(0) |
|
|
|
std::vector<cl::Platform> ethash_cl_miner::getPlatforms() |
|
|
|
{ |
|
|
|
vector<cl::Platform> platforms; |
|
|
|
try |
|
|
|
{ |
|
|
|
cl::Platform::get(&platforms); |
|
|
|
} |
|
|
|
catch(cl::Error const& err) |
|
|
|
{ |
|
|
|
if (err.err() == CL_PLATFORM_NOT_FOUND_KHR) |
|
|
|
ETHCL_LOG("No OpenCL platforms found"); |
|
|
|
else |
|
|
|
throw err; |
|
|
|
} |
|
|
|
return platforms; |
|
|
|
} |
|
|
|
|
|
|
|
string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _deviceId) |
|
|
|
{ |
|
|
|
vector<cl::Platform> platforms; |
|
|
|
ETHASHCL_GET_PLATFORMS(platforms, return string()); |
|
|
|
vector<cl::Platform> platforms = getPlatforms(); |
|
|
|
if (platforms.empty()) |
|
|
|
return string(); |
|
|
|
// get GPU device of the selected platform
|
|
|
|
unsigned platform_num = min<unsigned>(_platformId, platforms.size() - 1); |
|
|
|
vector<cl::Device> devices = getDevices(platforms, _platformId); |
|
|
@ -123,24 +121,35 @@ std::vector<cl::Device> ethash_cl_miner::getDevices(std::vector<cl::Platform> co |
|
|
|
{ |
|
|
|
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 |
|
|
|
); |
|
|
|
try |
|
|
|
{ |
|
|
|
_platforms[platform_num].getDevices( |
|
|
|
s_allowCPU ? CL_DEVICE_TYPE_ALL : ETHCL_QUERIED_DEVICE_TYPES, |
|
|
|
&devices |
|
|
|
); |
|
|
|
} |
|
|
|
catch (cl::Error const& err) |
|
|
|
{ |
|
|
|
// if simply no devices found return empty vector
|
|
|
|
if (err.err() != CL_DEVICE_NOT_FOUND) |
|
|
|
throw err; |
|
|
|
} |
|
|
|
return devices; |
|
|
|
} |
|
|
|
|
|
|
|
unsigned ethash_cl_miner::getNumPlatforms() |
|
|
|
{ |
|
|
|
vector<cl::Platform> platforms; |
|
|
|
ETHASHCL_GET_PLATFORMS(platforms, return 0); |
|
|
|
vector<cl::Platform> platforms = getPlatforms(); |
|
|
|
if (platforms.empty()) |
|
|
|
return 0; |
|
|
|
return platforms.size(); |
|
|
|
} |
|
|
|
|
|
|
|
unsigned ethash_cl_miner::getNumDevices(unsigned _platformId) |
|
|
|
{ |
|
|
|
vector<cl::Platform> platforms; |
|
|
|
ETHASHCL_GET_PLATFORMS(platforms, return 0); |
|
|
|
vector<cl::Platform> platforms = getPlatforms(); |
|
|
|
if (platforms.empty()) |
|
|
|
return 0; |
|
|
|
|
|
|
|
vector<cl::Device> devices = getDevices(platforms, _platformId); |
|
|
|
if (devices.empty()) |
|
|
@ -200,8 +209,9 @@ unsigned ethash_cl_miner::s_initialGlobalWorkSize = ethash_cl_miner::c_defaultGl |
|
|
|
|
|
|
|
bool ethash_cl_miner::searchForAllDevices(function<bool(cl::Device const&)> _callback) |
|
|
|
{ |
|
|
|
vector<cl::Platform> platforms; |
|
|
|
ETHASHCL_GET_PLATFORMS(platforms, return false); |
|
|
|
vector<cl::Platform> platforms = getPlatforms(); |
|
|
|
if (platforms.empty()) |
|
|
|
return false; |
|
|
|
for (unsigned i = 0; i < platforms.size(); ++i) |
|
|
|
if (searchForAllDevices(i, _callback)) |
|
|
|
return true; |
|
|
@ -211,8 +221,9 @@ bool ethash_cl_miner::searchForAllDevices(function<bool(cl::Device const&)> _cal |
|
|
|
|
|
|
|
bool ethash_cl_miner::searchForAllDevices(unsigned _platformId, function<bool(cl::Device const&)> _callback) |
|
|
|
{ |
|
|
|
vector<cl::Platform> platforms; |
|
|
|
ETHASHCL_GET_PLATFORMS(platforms, return false); |
|
|
|
vector<cl::Platform> platforms = getPlatforms(); |
|
|
|
if (platforms.empty()) |
|
|
|
return false; |
|
|
|
if (_platformId >= platforms.size()) |
|
|
|
return false; |
|
|
|
|
|
|
@ -226,16 +237,18 @@ bool ethash_cl_miner::searchForAllDevices(unsigned _platformId, function<bool(cl |
|
|
|
|
|
|
|
void ethash_cl_miner::doForAllDevices(function<void(cl::Device const&)> _callback) |
|
|
|
{ |
|
|
|
vector<cl::Platform> platforms; |
|
|
|
ETHASHCL_GET_PLATFORMS(platforms, return); |
|
|
|
vector<cl::Platform> platforms = getPlatforms(); |
|
|
|
if (platforms.empty()) |
|
|
|
return; |
|
|
|
for (unsigned i = 0; i < platforms.size(); ++i) |
|
|
|
doForAllDevices(i, _callback); |
|
|
|
} |
|
|
|
|
|
|
|
void ethash_cl_miner::doForAllDevices(unsigned _platformId, function<void(cl::Device const&)> _callback) |
|
|
|
{ |
|
|
|
vector<cl::Platform> platforms; |
|
|
|
ETHASHCL_GET_PLATFORMS(platforms, return); |
|
|
|
vector<cl::Platform> platforms = getPlatforms(); |
|
|
|
if (platforms.empty()) |
|
|
|
return; |
|
|
|
if (_platformId >= platforms.size()) |
|
|
|
return; |
|
|
|
|
|
|
@ -273,8 +286,9 @@ bool ethash_cl_miner::init( |
|
|
|
// get all platforms
|
|
|
|
try |
|
|
|
{ |
|
|
|
vector<cl::Platform> platforms; |
|
|
|
ETHASHCL_GET_PLATFORMS(platforms, return false); |
|
|
|
vector<cl::Platform> platforms = getPlatforms(); |
|
|
|
if (platforms.empty()) |
|
|
|
return false; |
|
|
|
|
|
|
|
// use selected platform
|
|
|
|
_platformId = min<unsigned>(_platformId, platforms.size() - 1); |
|
|
|