diff --git a/ethminer/MinerAux.h b/ethminer/MinerAux.h index 7486d64f8..023d7a6f4 100644 --- a/ethminer/MinerAux.h +++ b/ethminer/MinerAux.h @@ -295,6 +295,7 @@ public: BOOST_THROW_EXCEPTION(BadArgument()); } } +#if ETH_ETHASHCU || !ETH_TRUE else if (arg == "--cuda-devices") { while (m_cudaDeviceCount < 16 && i + 1 < argc) { @@ -310,6 +311,7 @@ public: else if (arg == "--cuda-high-cpu") { m_cudaHighCPULoad = true; } +#endif else return false; return true; diff --git a/libethash-cu/ethash_cu_miner.cpp b/libethash-cu/ethash_cu_miner.cpp index a4aec1829..22cad1fd4 100644 --- a/libethash-cu/ethash_cu_miner.cpp +++ b/libethash-cu/ethash_cu_miner.cpp @@ -65,7 +65,7 @@ std::string ethash_cu_miner::platform_info(unsigned _deviceId) int runtime_version; int device_count; - device_count = get_num_devices(); + device_count = getNumDevices(); if (device_count == 0) return std::string(); @@ -99,7 +99,7 @@ std::string ethash_cu_miner::platform_info(unsigned _deviceId) } -int ethash_cu_miner::get_num_devices() +int ethash_cu_miner::getNumDevices() { int device_count; @@ -123,7 +123,7 @@ void ethash_cu_miner::finish() bool ethash_cu_miner::init(uint8_t const* _dag, uint64_t _dagSize, unsigned num_buffers, unsigned search_batch_size, unsigned workgroup_size, unsigned _deviceId, bool highcpu) { - int device_count = get_num_devices(); + int device_count = getNumDevices(); if (device_count == 0) return false; diff --git a/libethash-cu/ethash_cu_miner.h b/libethash-cu/ethash_cu_miner.h index 54e535850..54d33549c 100644 --- a/libethash-cu/ethash_cu_miner.h +++ b/libethash-cu/ethash_cu_miner.h @@ -1,6 +1,6 @@ #pragma once -#include +//#include #include #include @@ -24,8 +24,17 @@ public: bool init(uint8_t const* _dag, uint64_t _dagSize, unsigned num_buffers = 2, unsigned search_batch_size = 262144, unsigned workgroup_size = 64, unsigned _deviceId = 0, bool highcpu = false); static std::string platform_info(unsigned _deviceId = 0); - static int get_num_devices(); - + static int getNumDevices(); + static void listDevices(); + static bool configureGPU( + unsigned _platformId, + unsigned _localWorkSize, + unsigned _globalWorkSize, + unsigned _msPerBatch, + bool _allowCPU, + unsigned _extraGPUMemory, + uint64_t _currentBlock + ); void finish(); void hash(uint8_t* ret, uint8_t const* header, uint64_t nonce, unsigned count); diff --git a/libethcore/BasicAuthority.h b/libethcore/BasicAuthority.h index 8db47938b..77ae363c8 100644 --- a/libethcore/BasicAuthority.h +++ b/libethcore/BasicAuthority.h @@ -45,6 +45,7 @@ namespace eth * typename Solution * typename CPUMiner * typename GPUMiner + * typename CUDAMiner * and a few others. TODO */ class BasicAuthority diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp index 99fcc04cf..6026828dc 100644 --- a/libethcore/Ethash.cpp +++ b/libethcore/Ethash.cpp @@ -45,6 +45,7 @@ #include "EthashSealEngine.h" #include "EthashCPUMiner.h" #include "EthashGPUMiner.h" +#include "EthashCUDAMiner.h" using namespace std; using namespace std::chrono; diff --git a/libethcore/Ethash.h b/libethcore/Ethash.h index a0904fa62..e9b5dc827 100644 --- a/libethcore/Ethash.h +++ b/libethcore/Ethash.h @@ -33,6 +33,7 @@ #include "Sealer.h" class ethash_cl_miner; +class ethash_cu_miner; namespace dev { @@ -45,6 +46,7 @@ namespace eth class BlockInfo; class EthashCLHook; +class EthashCUHook; class Ethash { diff --git a/libethcore/EthashCUDAMiner.cpp b/libethcore/EthashCUDAMiner.cpp index 36ef206bb..d0e3c6ad9 100644 --- a/libethcore/EthashCUDAMiner.cpp +++ b/libethcore/EthashCUDAMiner.cpp @@ -1,25 +1,25 @@ /* - This file is part of cpp-ethereum. +This file is part of cpp-ethereum. - cpp-ethereum 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. +cpp-ethereum 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. - cpp-ethereum 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. +cpp-ethereum 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 cpp-ethereum. If not, see . +You should have received a copy of the GNU General Public License +along with cpp-ethereum. If not, see . +*/ +/** @file EthashCUDAMiner.cpp +* @author Gav Wood +* @date 2014 +* +* Determines the PoW algorithm. */ -/** @file EthashGPUMiner.cpp - * @author Gav Wood - * @date 2014 - * - * Determines the PoW algorithm. - */ #if ETH_ETHASHCU || !ETH_TRUE @@ -33,71 +33,71 @@ using namespace eth; namespace dev { -namespace eth -{ - -class EthashCUHook: public ethash_cu_miner::search_hook -{ -public: - EthashCUHook(EthashCUDAMiner* _owner): m_owner(_owner) {} - EthashCUHook(EthashCUHook const&) = delete; - - void abort() + namespace eth { + + class EthashCUHook : public ethash_cu_miner::search_hook { - UniqueGuard l(x_all); - if (m_aborted) - return; -// cdebug << "Attempting to abort"; + public: + EthashCUHook(EthashCUDAMiner* _owner) : m_owner(_owner) {} + EthashCUHook(EthashCUHook const&) = delete; - m_abort = true; - } - // m_abort is true so now searched()/found() will return true to abort the search. - // we hang around on this thread waiting for them to point out that they have aborted since - // otherwise we may end up deleting this object prior to searched()/found() being called. - m_aborted.wait(true); -// for (unsigned timeout = 0; timeout < 100 && !m_aborted; ++timeout) -// std::this_thread::sleep_for(chrono::milliseconds(30)); -// if (!m_aborted) -// cwarn << "Couldn't abort. Abandoning OpenCL process."; - } + void abort() + { + { + UniqueGuard l(x_all); + if (m_aborted) + return; + // cdebug << "Attempting to abort"; - void reset() - { - UniqueGuard l(x_all); - m_aborted = m_abort = false; - } + m_abort = true; + } + // m_abort is true so now searched()/found() will return true to abort the search. + // we hang around on this thread waiting for them to point out that they have aborted since + // otherwise we may end up deleting this object prior to searched()/found() being called. + m_aborted.wait(true); + // for (unsigned timeout = 0; timeout < 100 && !m_aborted; ++timeout) + // std::this_thread::sleep_for(chrono::milliseconds(30)); + // if (!m_aborted) + // cwarn << "Couldn't abort. Abandoning OpenCL process."; + } -protected: - virtual bool found(uint64_t const* _nonces, uint32_t _count) override - { -// dev::operator <<(std::cerr << "Found nonces: ", vector(_nonces, _nonces + _count)) << std::endl; - for (uint32_t i = 0; i < _count; ++i) - if (m_owner->report(_nonces[i])) - return (m_aborted = true); - return m_owner->shouldStop(); - } + void reset() + { + UniqueGuard l(x_all); + m_aborted = m_abort = false; + } - virtual bool searched(uint64_t _startNonce, uint32_t _count) override - { - UniqueGuard l(x_all); -// std::cerr << "Searched " << _count << " from " << _startNonce << std::endl; - m_owner->accumulateHashes(_count); - m_last = _startNonce + _count; - if (m_abort || m_owner->shouldStop()) - return (m_aborted = true); - return false; - } + protected: + virtual bool found(uint64_t const* _nonces, uint32_t _count) override + { + // dev::operator <<(std::cerr << "Found nonces: ", vector(_nonces, _nonces + _count)) << std::endl; + for (uint32_t i = 0; i < _count; ++i) + if (m_owner->report(_nonces[i])) + return (m_aborted = true); + return m_owner->shouldStop(); + } -private: - Mutex x_all; - uint64_t m_last; - bool m_abort = false; - Notified m_aborted = {true}; - EthashCUDAMiner* m_owner = nullptr; -}; + virtual bool searched(uint64_t _startNonce, uint32_t _count) override + { + UniqueGuard l(x_all); + // std::cerr << "Searched " << _count << " from " << _startNonce << std::endl; + m_owner->accumulateHashes(_count); + m_last = _startNonce + _count; + if (m_abort || m_owner->shouldStop()) + return (m_aborted = true); + return false; + } -} + private: + Mutex x_all; + uint64_t m_last; + bool m_abort = false; + Notified m_aborted = { true }; + EthashCUDAMiner* m_owner = nullptr; + }; + + } } unsigned EthashCUDAMiner::s_platformId = 0; @@ -105,9 +105,9 @@ unsigned EthashCUDAMiner::s_deviceId = 0; unsigned EthashCUDAMiner::s_numInstances = 0; EthashCUDAMiner::EthashCUDAMiner(ConstructionInfo const& _ci) : - GenericMiner(_ci), - Worker("cudaminer" + toString(index())), - m_hook(new EthashCUDAMiner(this)) +GenericMiner(_ci), +Worker("cudaminer" + toString(index())), +m_hook( new EthashCUHook(this)) { } @@ -123,7 +123,7 @@ bool EthashCUDAMiner::report(uint64_t _nonce) Nonce n = (Nonce)(u64)_nonce; EthashProofOfWork::Result r = EthashAux::eval(work().seedHash, work().headerHash, n); if (r.value < work().boundary) - return submitProof(Solution{n, r.mixHash}); + return submitProof(Solution{ n, r.mixHash }); return false; } @@ -170,11 +170,11 @@ void EthashCUDAMiner::workLoop() uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192); m_miner->search(w.headerHash.data(), upper64OfBoundary, *m_hook); } - catch (cl::Error const& _e) + catch (std::runtime_error const& _e) { delete m_miner; m_miner = nullptr; - cwarn << "Error GPU mining: " << _e.what() << "(" << _e.err() << ")"; + cwarn << "Error CUDA mining: " << _e.what(); } } @@ -186,17 +186,17 @@ void EthashCUDAMiner::pause() std::string EthashCUDAMiner::platformInfo() { - return ethash_cl_miner::platform_info(s_platformId, s_deviceId); + return ethash_cu_miner::platform_info(s_deviceId); } unsigned EthashCUDAMiner::getNumDevices() { - return ethash_cl_miner::getNumDevices(s_platformId); + return ethash_cu_miner::getNumDevices(); } void EthashCUDAMiner::listDevices() { - return ethash_cl_miner::listDevices(); + return ethash_cu_miner::listDevices(); } bool EthashCUDAMiner::configureGPU( @@ -208,7 +208,7 @@ bool EthashCUDAMiner::configureGPU( bool _allowCPU, unsigned _extraGPUMemory, uint64_t _currentBlock -) + ) { s_platformId = _platformId; s_deviceId = _deviceId; @@ -220,14 +220,14 @@ bool EthashCUDAMiner::configureGPU( } if (!ethash_cu_miner::configureGPU( - _platformId, - _localWorkSize, - _globalWorkSizeMultiplier * _localWorkSize, - _msPerBatch, - _allowCPU, - _extraGPUMemory, - _currentBlock) - ) + _platformId, + _localWorkSize, + _globalWorkSizeMultiplier * _localWorkSize, + _msPerBatch, + _allowCPU, + _extraGPUMemory, + _currentBlock) + ) { cout << "No GPU device with sufficient memory was found. Can't GPU mine. Remove the -G argument" << endl; return false; diff --git a/libethcore/EthashCUDAMiner.h b/libethcore/EthashCUDAMiner.h index 080c6ddcf..989e3c2a5 100644 --- a/libethcore/EthashCUDAMiner.h +++ b/libethcore/EthashCUDAMiner.h @@ -1,25 +1,25 @@ /* - This file is part of cpp-ethereum. +This file is part of cpp-ethereum. - cpp-ethereum 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. +cpp-ethereum 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. - cpp-ethereum 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. +cpp-ethereum 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 cpp-ethereum. If not, see . +You should have received a copy of the GNU General Public License +along with cpp-ethereum. If not, see . +*/ +/** @file EthashCUDAMiner.h +* @author Gav Wood +* @date 2014 +* +* Determines the PoW algorithm. */ -/** @file EthashGPUMiner.h - * @author Gav Wood - * @date 2014 - * - * Determines the PoW algorithm. - */ #pragma once #if ETH_ETHASHCU || !ETH_TRUE @@ -30,53 +30,53 @@ namespace dev { -namespace eth -{ - -class EthashCUDAMiner: public GenericMiner, Worker -{ - friend class dev::eth::EthashCLHook; - -public: - EthashCUDAMiner(ConstructionInfo const& _ci); - ~EthashCUDAMiner(); - - static unsigned instances() { return s_numInstances > 0 ? s_numInstances : 1; } - static std::string platformInfo(); - static unsigned getNumDevices(); - static void listDevices(); - static bool configureGPU( - unsigned _localWorkSize, - unsigned _globalWorkSizeMultiplier, - unsigned _msPerBatch, - unsigned _platformId, - unsigned _deviceId, - bool _allowCPU, - unsigned _extraGPUMemory, - uint64_t _currentBlock - ); - static void setNumInstances(unsigned _instances) { s_numInstances = std::min(_instances, getNumDevices()); } - -protected: - void kickOff() override; - void pause() override; - -private: - void workLoop() override; - bool report(uint64_t _nonce); - - using GenericMiner::accumulateHashes; - - EthashCLHook* m_hook = nullptr; - ethash_cl_miner* m_miner = nullptr; - - h256 m_minerSeed; ///< Last seed in m_miner - static unsigned s_platformId; - static unsigned s_deviceId; - static unsigned s_numInstances; -}; - -} + namespace eth + { + + class EthashCUDAMiner : public GenericMiner, Worker + { + friend class dev::eth::EthashCUHook; + + public: + EthashCUDAMiner(ConstructionInfo const& _ci); + ~EthashCUDAMiner(); + + static unsigned instances() { return s_numInstances > 0 ? s_numInstances : 1; } + static std::string platformInfo(); + static unsigned getNumDevices(); + static void listDevices(); + static bool configureGPU( + unsigned _localWorkSize, + unsigned _globalWorkSizeMultiplier, + unsigned _msPerBatch, + unsigned _platformId, + unsigned _deviceId, + bool _allowCPU, + unsigned _extraGPUMemory, + uint64_t _currentBlock + ); + static void setNumInstances(unsigned _instances) { s_numInstances = std::min(_instances, getNumDevices()); } + + protected: + void kickOff() override; + void pause() override; + + private: + void workLoop() override; + bool report(uint64_t _nonce); + + using GenericMiner::accumulateHashes; + + EthashCUHook* m_hook = nullptr; + ethash_cu_miner* m_miner = nullptr; + + h256 m_minerSeed; ///< Last seed in m_miner + static unsigned s_platformId; + static unsigned s_deviceId; + static unsigned s_numInstances; + }; + + } } #endif diff --git a/libethcore/EthashSealEngine.cpp b/libethcore/EthashSealEngine.cpp index 5eacfc713..064810d1b 100644 --- a/libethcore/EthashSealEngine.cpp +++ b/libethcore/EthashSealEngine.cpp @@ -24,6 +24,7 @@ #include "EthashSealEngine.h" #include "EthashCPUMiner.h" #include "EthashGPUMiner.h" +#include "EthashCUDAMiner.h" using namespace std; using namespace dev; using namespace eth; @@ -34,6 +35,9 @@ EthashSealEngine::EthashSealEngine() sealers["cpu"] = GenericFarm::SealerDescriptor{&EthashCPUMiner::instances, [](GenericMiner::ConstructionInfo ci){ return new EthashCPUMiner(ci); }}; #if ETH_ETHASHCL sealers["opencl"] = GenericFarm::SealerDescriptor{&EthashGPUMiner::instances, [](GenericMiner::ConstructionInfo ci){ return new EthashGPUMiner(ci); }}; +#endif +#if ETH_ETHASHCU + sealers["cuda"] = GenericFarm::SealerDescriptor{ &EthashCUDAMiner::instances, [](GenericMiner::ConstructionInfo ci){ return new EthashCUDAMiner(ci); } }; #endif m_farm.setSealers(sealers); } @@ -44,6 +48,9 @@ strings EthashSealEngine::sealers() const "cpu" #if ETH_ETHASHCL , "opencl" +#endif +#if ETH_ETHASHCU + , "cuda" #endif }; }