diff --git a/ethminer/MinerAux.h b/ethminer/MinerAux.h index 476c810c2..aac68f1a7 100644 --- a/ethminer/MinerAux.h +++ b/ethminer/MinerAux.h @@ -132,6 +132,8 @@ public: ProofOfWork::GPUMiner::listDevices(); exit(0); } + else if (arg == "--allow-opencl-cpu") + ProofOfWork::GPUMiner::allowCPU(); else if (arg == "--phone-home" && i + 1 < argc) { string m = argv[++i]; diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index 1a5eaddc3..054985a38 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/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 #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) { @@ -82,9 +84,8 @@ string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _deviceId) } // get GPU device of the selected platform - vector devices; unsigned platform_num = min(_platformId, platforms.size() - 1); - platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices); + vector devices = getDevices(platforms, _platformId); if (devices.empty()) { 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() + "\", \"device\": \"" + device.getInfo() + "\", \"version\": \"" + device_version + "\" }"; } +std::vector ethash_cl_miner::getDevices(std::vector const& _platforms, unsigned _platformId) +{ + vector devices; + unsigned platform_num = min(_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() { vector platforms; @@ -116,9 +128,7 @@ unsigned ethash_cl_miner::getNumDevices(unsigned _platformId) return 0; } - vector devices; - unsigned platform_num = min(_platformId, platforms.size() - 1); - platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices); + vector devices = getDevices(platforms, _platformId); if (devices.empty()) { ETHCL_LOG("No OpenCL devices found."); @@ -152,6 +162,13 @@ bool ethash_cl_miner::configureGPU() ); } +bool ethash_cl_miner::s_allowCPU = false; + +void ethash_cl_miner::allowCPU() +{ + s_allowCPU = true; +} + bool ethash_cl_miner::searchForAllDevices(function _callback) { vector platforms; @@ -175,8 +192,7 @@ bool ethash_cl_miner::searchForAllDevices(unsigned _platformId, function= platforms.size()) return false; - vector devices; - platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices); + vector devices = getDevices(platforms, _platformId); for (cl::Device const& device: devices) if (_callback(device)) return true; @@ -204,8 +220,7 @@ void ethash_cl_miner::doForAllDevices(unsigned _platformId, function= platforms.size()) return; - vector devices; - platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices); + vector devices = getDevices(platforms, _platformId); for (cl::Device const& device: devices) _callback(device); } @@ -253,8 +268,7 @@ bool ethash_cl_miner::init( ETHCL_LOG("Using platform: " << platforms[_platformId].getInfo().c_str()); // get GPU device of the default platform - vector devices; - platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices); + vector devices = getDevices(platforms, _platformId); if (devices.empty()) { ETHCL_LOG("No OpenCL devices found."); diff --git a/libethash-cl/ethash_cl_miner.h b/libethash-cl/ethash_cl_miner.h index 4c986053a..dc3f7eca0 100644 --- a/libethash-cl/ethash_cl_miner.h +++ b/libethash-cl/ethash_cl_miner.h @@ -41,6 +41,7 @@ public: static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0); static void listDevices(); static bool configureGPU(); + static void allowCPU(); bool init( uint8_t const* _dag, @@ -56,6 +57,9 @@ public: void search_chunk(uint8_t const* header, uint64_t target, search_hook& hook); private: + + static std::vector getDevices(std::vector 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 }; cl::Context m_context; @@ -70,4 +74,5 @@ private: unsigned m_workgroup_size; bool m_opencl_1_1; + static bool s_allowCPU; }; diff --git a/libethash-cl/ethash_cl_miner_kernel.cl b/libethash-cl/ethash_cl_miner_kernel.cl index 8567bb164..46c94f241 100644 --- a/libethash-cl/ethash_cl_miner_kernel.cl +++ b/libethash-cl/ethash_cl_miner_kernel.cl @@ -275,8 +275,6 @@ uint inner_loop_chunks(uint4 init, uint thread_id, __local uint* share, __global return fnv_reduce(mix); } - - uint inner_loop(uint4 init, uint thread_id, __local uint* share, __global hash128_t const* g_dag, uint isolate) { uint4 mix = init; @@ -585,4 +583,4 @@ __kernel void ethash_search_chunks( uint slot = min(convert_uint(MAX_OUTPUTS), convert_uint(atomic_inc(&g_output[0]) + 1)); g_output[slot] = gid; } -} \ No newline at end of file +} diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp index 9ac4474ba..09ecfe1a3 100644 --- a/libethcore/Ethash.cpp +++ b/libethcore/Ethash.cpp @@ -366,6 +366,11 @@ void Ethash::GPUMiner::pause() stopWorking(); } +void Ethash::GPUMiner::allowCPU() +{ + return ethash_cl_miner::allowCPU(); +} + std::string Ethash::GPUMiner::platformInfo() { return ethash_cl_miner::platform_info(s_platformId, s_deviceId); diff --git a/libethcore/Ethash.h b/libethcore/Ethash.h index 49a8ae006..91ca5f8fd 100644 --- a/libethcore/Ethash.h +++ b/libethcore/Ethash.h @@ -92,6 +92,7 @@ public: static void setDefaultDevice(unsigned) {} static void listDevices() {} static bool configureGPU() { return false; } + static void allowCPU() {} static void setNumInstances(unsigned _instances) { s_numInstances = std::min(_instances, std::thread::hardware_concurrency()); } protected: void kickOff() override @@ -121,6 +122,7 @@ public: static unsigned getNumDevices(); static void listDevices(); static bool configureGPU(); + static void 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(_instances, getNumDevices()); }