├── CODEOWNERS ├── ethminer ├── ethminer.rc ├── ethminer.ico ├── CMakeLists.txt └── DBusInt.h ├── libethash-cuda ├── cuda_helper.h ├── fnv.cuh ├── ethash_cuda_miner_kernel_globals.h ├── CMakeLists.txt ├── CUDAMiner.h ├── ethash_cuda_miner_kernel.h ├── dagger_shuffled.cuh └── ethash_cuda_miner_kernel.cu ├── libethash-cl ├── kernels │ ├── bin │ │ ├── ethash_tonga_lws64.bin │ │ ├── ethash_baffin_lws128.bin │ │ ├── ethash_baffin_lws256.bin │ │ ├── ethash_baffin_lws64.bin │ │ ├── ethash_gfx900_lws128.bin │ │ ├── ethash_gfx900_lws256.bin │ │ ├── ethash_gfx900_lws64.bin │ │ ├── ethash_gfx901_lws128.bin │ │ ├── ethash_gfx901_lws256.bin │ │ ├── ethash_gfx901_lws64.bin │ │ ├── ethash_gfx906_lws128.bin │ │ ├── ethash_gfx906_lws256.bin │ │ ├── ethash_gfx906_lws64.bin │ │ ├── ethash_tonga_lws128.bin │ │ ├── ethash_tonga_lws256.bin │ │ ├── ethash_ellesmere_lws128.bin │ │ ├── ethash_ellesmere_lws256.bin │ │ ├── ethash_ellesmere_lws64.bin │ │ ├── ethash_tonga_lws64_exit.bin │ │ ├── ethash_baffin_lws128_exit.bin │ │ ├── ethash_baffin_lws256_exit.bin │ │ ├── ethash_baffin_lws64_exit.bin │ │ ├── ethash_gfx900_lws128_exit.bin │ │ ├── ethash_gfx900_lws256_exit.bin │ │ ├── ethash_gfx900_lws64_exit.bin │ │ ├── ethash_gfx901_lws128_exit.bin │ │ ├── ethash_gfx901_lws256_exit.bin │ │ ├── ethash_gfx901_lws64_exit.bin │ │ ├── ethash_gfx906_lws128_exit.bin │ │ ├── ethash_gfx906_lws256_exit.bin │ │ ├── ethash_gfx906_lws64_exit.bin │ │ ├── ethash_tonga_lws128_exit.bin │ │ ├── ethash_tonga_lws256_exit.bin │ │ ├── ethash_ellesmere_lws128_exit.bin │ │ ├── ethash_ellesmere_lws256_exit.bin │ │ └── ethash_ellesmere_lws64_exit.bin │ ├── CMakeLists.txt │ ├── README.md │ ├── isa │ │ ├── GCN_ethash.isa │ │ └── GCN_ethash_globaldata.isa │ └── Makefile ├── CMakeLists.txt ├── CLMiner.h └── bin2h.cmake ├── BuildInfo.h.in ├── .gitattributes ├── libapicore ├── CMakeLists.txt └── ApiServer.h ├── .gitmodules ├── libdevcore ├── CMakeLists.txt ├── FixedHash.cpp ├── Common.h ├── Guards.h ├── Worker.h ├── Exceptions.h ├── Terminal.h ├── Log.cpp ├── Log.h ├── Worker.cpp ├── CommonData.cpp ├── vector_ref.h └── CommonData.h ├── .clang-tidy ├── libethash-cpu ├── CMakeLists.txt └── CPUMiner.h ├── libethcore ├── CMakeLists.txt ├── EthashAux.cpp ├── EthashAux.h ├── Miner.cpp └── Farm.h ├── libhwmon ├── wraphelper.h ├── CMakeLists.txt ├── wraphelper.cpp ├── wrapamdsysfs.h ├── wrapnvml.h ├── wrapadl.h ├── wrapnvml.cpp ├── wrapadl.cpp └── wrapamdsysfs.cpp ├── circle.yml ├── cmake ├── Hunter │ └── config.cmake ├── EthCheckCXXFlags.cmake └── EthCompilerSettings.cmake ├── .bumpversion.cfg ├── libpoolprotocols ├── CMakeLists.txt ├── testing │ ├── SimulateClient.h │ └── SimulateClient.cpp ├── getwork │ └── EthGetworkClient.h ├── PoolManager.h ├── PoolURI.h ├── PoolClient.h └── stratum │ └── EthStratumClient.h ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── .gitignore ├── .clang-format ├── scripts ├── install-cuda-ubuntu1604.sh └── install_cmake.sh ├── appveyor.yml ├── CHANGELOG.md ├── .travis.yml ├── CMakeLists.txt └── docs └── BUILD.md /CODEOWNERS: -------------------------------------------------------------------------------- 1 | ethminer/DBusInt.h @MRZA-MRZA 2 | -------------------------------------------------------------------------------- /ethminer/ethminer.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "ethminer.ico" 2 | -------------------------------------------------------------------------------- /ethminer/ethminer.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/ethminer/ethminer.ico -------------------------------------------------------------------------------- /libethash-cuda/cuda_helper.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cuda/cuda_helper.h -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_tonga_lws64.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_tonga_lws64.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_baffin_lws128.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_baffin_lws128.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_baffin_lws256.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_baffin_lws256.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_baffin_lws64.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_baffin_lws64.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx900_lws128.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx900_lws128.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx900_lws256.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx900_lws256.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx900_lws64.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx900_lws64.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx901_lws128.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx901_lws128.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx901_lws256.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx901_lws256.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx901_lws64.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx901_lws64.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx906_lws128.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx906_lws128.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx906_lws256.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx906_lws256.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx906_lws64.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx906_lws64.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_tonga_lws128.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_tonga_lws128.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_tonga_lws256.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_tonga_lws256.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_ellesmere_lws128.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_ellesmere_lws128.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_ellesmere_lws256.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_ellesmere_lws256.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_ellesmere_lws64.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_ellesmere_lws64.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_tonga_lws64_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_tonga_lws64_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_baffin_lws128_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_baffin_lws128_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_baffin_lws256_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_baffin_lws256_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_baffin_lws64_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_baffin_lws64_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx900_lws128_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx900_lws128_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx900_lws256_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx900_lws256_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx900_lws64_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx900_lws64_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx901_lws128_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx901_lws128_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx901_lws256_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx901_lws256_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx901_lws64_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx901_lws64_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx906_lws128_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx906_lws128_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx906_lws256_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx906_lws256_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_gfx906_lws64_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_gfx906_lws64_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_tonga_lws128_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_tonga_lws128_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_tonga_lws256_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_tonga_lws256_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(GNUInstallDirs) 2 | file (GLOB BINS "bin/*.bin") 3 | install(FILES ${BINS} DESTINATION ${CMAKE_INSTALL_BINDIR}/kernels) 4 | -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_ellesmere_lws128_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_ellesmere_lws128_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_ellesmere_lws256_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_ellesmere_lws256_exit.bin -------------------------------------------------------------------------------- /libethash-cl/kernels/bin/ethash_ellesmere_lws64_exit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gyf304/ethminer-m1/HEAD/libethash-cl/kernels/bin/ethash_ellesmere_lws64_exit.bin -------------------------------------------------------------------------------- /BuildInfo.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define ETH_PROJECT_VERSION "@PROJECT_VERSION@" 4 | #define ETH_BUILD_TYPE "@ETH_BUILD_TYPE@" 5 | #define ETH_BUILD_PLATFORM "@ETH_BUILD_PLATFORM@" 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Declare files that will always have LF line endings on checkout. 2 | *.bash text eol=lf 3 | *.cpp text eol=lf 4 | *.h text eol=lf 5 | *.py text eol=lf 6 | *.sh text eol=lf 7 | -------------------------------------------------------------------------------- /libapicore/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCES 2 | ApiServer.h ApiServer.cpp 3 | ) 4 | 5 | add_library(apicore ${SOURCES}) 6 | target_link_libraries(apicore PRIVATE ethcore devcore ethminer-buildinfo Boost::filesystem) 7 | target_include_directories(apicore PRIVATE ..) 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "cmake/Hunter/disabled-mode"] 2 | path = cmake/Hunter/disabled-mode 3 | url = https://github.com/hunter-packages/disabled-mode 4 | [submodule "cmake/cable"] 5 | path = cmake/cable 6 | url = https://github.com/ethereum/cable 7 | branch = master 8 | -------------------------------------------------------------------------------- /libdevcore/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB HEADERS "*.h") 2 | file(GLOB SOURCES "*.cpp") 3 | 4 | find_package(Threads) 5 | 6 | add_library(devcore ${SOURCES} ${HEADERS}) 7 | target_link_libraries(devcore PUBLIC Boost::boost Boost::system) 8 | target_link_libraries(devcore PRIVATE Threads::Threads) 9 | 10 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: 'clang-diagnostic-*,clang-analyzer-*,modernize-*,bugprone-*,readability-*,-readability-implicit-bool-conversion,performance-*' 3 | WarningsAsErrors: '' 4 | HeaderFilterRegex: 'ethminer/.*' 5 | CheckOptions: 6 | - key: readability-braces-around-statements.ShortStatementLines 7 | value: '3' 8 | ... 9 | -------------------------------------------------------------------------------- /libethash-cpu/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB sources "*.cpp") 2 | file(GLOB headers "*.h") 3 | 4 | add_library(ethash-cpu ${sources} ${headers}) 5 | #target_link_libraries(ethash-cpu ethcore ethash::ethash Boost::fiber Boost::thread) 6 | target_link_libraries(ethash-cpu ethcore ethash::ethash Boost::thread) 7 | target_include_directories(ethash-cpu PRIVATE .. ${CMAKE_CURRENT_BINARY_DIR}) 8 | -------------------------------------------------------------------------------- /libethash-cuda/fnv.cuh: -------------------------------------------------------------------------------- 1 | #define FNV_PRIME 0x01000193 2 | 3 | #define fnv(x, y) ((x)*FNV_PRIME ^ (y)) 4 | 5 | DEV_INLINE uint4 fnv4(uint4 a, uint4 b) 6 | { 7 | uint4 c; 8 | c.x = a.x * FNV_PRIME ^ b.x; 9 | c.y = a.y * FNV_PRIME ^ b.y; 10 | c.z = a.z * FNV_PRIME ^ b.z; 11 | c.w = a.w * FNV_PRIME ^ b.w; 12 | return c; 13 | } 14 | 15 | DEV_INLINE uint32_t fnv_reduce(uint4 v) 16 | { 17 | return fnv(fnv(fnv(v.x, v.y), v.z), v.w); 18 | } 19 | -------------------------------------------------------------------------------- /libethcore/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCES 2 | EthashAux.h EthashAux.cpp 3 | Farm.cpp Farm.h 4 | Miner.h Miner.cpp 5 | ) 6 | 7 | include_directories(BEFORE ..) 8 | 9 | add_library(ethcore ${SOURCES}) 10 | target_link_libraries(ethcore PUBLIC devcore ethash::ethash PRIVATE hwmon) 11 | 12 | if(ETHASHCL) 13 | target_link_libraries(ethcore PRIVATE ethash-cl) 14 | endif() 15 | if(ETHASHCUDA) 16 | target_link_libraries(ethcore PUBLIC ethash-cuda) 17 | endif() 18 | if(ETHASHCPU) 19 | target_link_libraries(ethcore PUBLIC ethash-cpu) 20 | endif() 21 | -------------------------------------------------------------------------------- /libhwmon/wraphelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Wrappers to emulate dlopen() on other systems like Windows 3 | */ 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | #if defined(_WIN32) 10 | #include 11 | void* wrap_dlopen(const char* filename); 12 | void* wrap_dlsym(void* h, const char* sym); 13 | int wrap_dlclose(void* h); 14 | #else 15 | /* assume we can use dlopen itself... */ 16 | #include 17 | void* wrap_dlopen(const char* filename); 18 | void* wrap_dlsym(void* h, const char* sym); 19 | int wrap_dlclose(void* h); 20 | #endif 21 | -------------------------------------------------------------------------------- /libethash-cuda/ethash_cuda_miner_kernel_globals.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | __constant__ uint32_t d_dag_size; 4 | __constant__ hash128_t* d_dag; 5 | __constant__ uint32_t d_light_size; 6 | __constant__ hash64_t* d_light; 7 | __constant__ hash32_t d_header; 8 | __constant__ uint64_t d_target; 9 | 10 | #if (__CUDACC_VER_MAJOR__ > 8) 11 | #define SHFL(x, y, z) __shfl_sync(0xFFFFFFFF, (x), (y), (z)) 12 | #else 13 | #define SHFL(x, y, z) __shfl((x), (y), (z)) 14 | #endif 15 | 16 | #if (__CUDA_ARCH__ >= 320) 17 | #define LDG(x) __ldg(&(x)) 18 | #else 19 | #define LDG(x) (x) 20 | #endif 21 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: nvidia/cuda:9.2-devel-ubuntu18.04 6 | steps: 7 | - run: apt-get update && apt-get install -qy git cmake mesa-common-dev libidn11-dev python3-requests python3-git 8 | 9 | - checkout 10 | - run: git submodule update --init --recursive 11 | 12 | - run: cmake -DHUNTER_JOBS_NUMBER=4 -DETHASHCUDA=ON -DAPICORE=ON -H. -Bbuild 13 | - run: cmake --build build -- -j4 14 | - store_artifacts: 15 | path: build/ethminer/ethminer 16 | destination: ethminer 17 | -------------------------------------------------------------------------------- /cmake/Hunter/config.cmake: -------------------------------------------------------------------------------- 1 | hunter_config(CURL VERSION ${HUNTER_CURL_VERSION} CMAKE_ARGS HTTP_ONLY=ON CMAKE_USE_OPENSSL=OFF CMAKE_USE_LIBSSH2=OFF CURL_CA_PATH=none) 2 | hunter_config( 3 | Boost 4 | URL "https://dl.bintray.com/boostorg/release/1.75.0/source/boost_1_75_0.tar.gz" 5 | SHA1 "68be4a43b73c66370c8d3fd94723b3913217ce1b" 6 | ) 7 | 8 | hunter_config( 9 | OpenSSL 10 | URL "https://www.openssl.org/source/openssl-1.1.1j.tar.gz" 11 | SHA1 "04c340b086828eecff9df06dceff196790bb9268" 12 | CMAKE_ARGS configure_architectures=${CMAKE_SYSTEM_PROCESSOR} 13 | ) 14 | -------------------------------------------------------------------------------- /libhwmon/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCES 2 | wraphelper.cpp wraphelper.h 3 | wrapnvml.h wrapnvml.cpp 4 | wrapadl.h wrapadl.cpp 5 | wrapamdsysfs.h wrapamdsysfs.cpp 6 | ) 7 | 8 | add_library(hwmon ${SOURCES}) 9 | set(HWMON_LINK_LIBRARIES devcore) 10 | 11 | if (UNIX) 12 | list(APPEND HWMON_LINK_LIBRARIES dl) 13 | endif () 14 | 15 | target_link_libraries(hwmon ${HWMON_LINK_LIBRARIES}) 16 | target_include_directories(hwmon PRIVATE ..) 17 | 18 | if (ETHASHCUDA) 19 | find_package(CUDA REQUIRED) 20 | target_include_directories(hwmon PUBLIC ${CUDA_INCLUDE_DIRS}) 21 | endif() 22 | -------------------------------------------------------------------------------- /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 0.19.0 3 | tag = True 4 | sign_tags = True 5 | tag_message = ethminer {new_version} 6 | commit = True 7 | message = ethminer {new_version} 8 | 9 | Bump version: {current_version} → {new_version} 10 | parse = (?P\d+)\.(?P\d+)\.(?P\d+)(-(?Prc|alpha)\.(?P\d+))? 11 | serialize = 12 | {major}.{minor}.{patch}-{prerel}.{prerelver} 13 | {major}.{minor}.{patch} 14 | 15 | [bumpversion:part:prerel] 16 | optional_value = rel 17 | values = 18 | alpha 19 | rc 20 | rel 21 | 22 | [bumpversion:file:CMakeLists.txt] 23 | -------------------------------------------------------------------------------- /libpoolprotocols/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCES 2 | PoolURI.cpp PoolURI.h 3 | PoolClient.h 4 | PoolManager.h PoolManager.cpp 5 | testing/SimulateClient.h testing/SimulateClient.cpp 6 | stratum/EthStratumClient.h stratum/EthStratumClient.cpp 7 | getwork/EthGetworkClient.h getwork/EthGetworkClient.cpp 8 | ) 9 | 10 | hunter_add_package(OpenSSL) 11 | find_package(OpenSSL REQUIRED) 12 | 13 | add_library(poolprotocols ${SOURCES}) 14 | target_link_libraries(poolprotocols PRIVATE devcore ethminer-buildinfo ethash::ethash Boost::system jsoncpp_lib_static OpenSSL::SSL OpenSSL::Crypto) 15 | target_include_directories(poolprotocols PRIVATE ..) 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | --- 5 | 6 | **Is your feature request related to a problem? Please describe.** 7 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 8 | 9 | **Describe the solution you'd like** 10 | A clear and concise description of what you want to happen. 11 | 12 | **Describe alternatives you've considered** 13 | A clear and concise description of any alternative solutions or features you've considered. 14 | 15 | **Additional context** 16 | Add any other context or screenshots about the feature request here. 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | --- 5 | 6 | **Describe the bug** 7 | A clear and concise description of what the bug is. 8 | 9 | **To Reproduce** 10 | Steps to reproduce the behavior: 11 | 1. Go to "..." 12 | 2. Click on "..." 13 | 3. Scroll down to "..." 14 | 4. See error 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Screenshots (Optional)** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **Environment (please complete the following information):** 23 | - Operating System: [e.g. Windows 10] 24 | - Hardware [e.g. GTX 1070] 25 | - Ethminer Version [e.g. 0.14] 26 | - Ethminer options used 27 | 28 | **Additional context** 29 | Add any other context about the problem here. 30 | -------------------------------------------------------------------------------- /libhwmon/wraphelper.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Wrappers to emulate dlopen() on other systems like Windows 3 | */ 4 | 5 | #include "wraphelper.h" 6 | 7 | #if defined(_WIN32) 8 | void* wrap_dlopen(const char* filename) 9 | { 10 | return (void*)LoadLibrary(filename); 11 | } 12 | void* wrap_dlsym(void* h, const char* sym) 13 | { 14 | return (void*)GetProcAddress((HINSTANCE)h, sym); 15 | } 16 | int wrap_dlclose(void* h) 17 | { 18 | /* FreeLibrary returns non-zero on success */ 19 | return (!FreeLibrary((HINSTANCE)h)); 20 | } 21 | #else 22 | /* assume we can use dlopen itself... */ 23 | void* wrap_dlopen(const char* filename) 24 | { 25 | return dlopen(filename, RTLD_NOW); 26 | } 27 | void* wrap_dlsym(void* h, const char* sym) 28 | { 29 | return dlsym(h, sym); 30 | } 31 | int wrap_dlclose(void* h) 32 | { 33 | return dlclose(h); 34 | } 35 | #endif 36 | -------------------------------------------------------------------------------- /libethash-cl/kernels/README.md: -------------------------------------------------------------------------------- 1 | # ethash-kernels 2 | For whatever reason, Zawawawa released his Ethash kernels as open source code. This repo is a verbaitm copy of that code with a simplistic build environment and [Ethminer](https://github.com/ethereum-mining/ethminer) as a target. Although the code for Ethminer has yet to be released. 3 | 4 | ## Requirements 5 | On Linux, all you need is [clrxasm](https://github.com/CLRX/CLRX-mirror) installed. Everything should build fairly quickly, just make sure to ```mkdir build``` before you ```make```. MacOS should be the same. Windows ¯\_(ツ)_/¯ 6 | 7 | ## Donations 8 | Please buy me alcohol: 9 | - BTC: 3L2S7FHvTHpjzWqvqgaZBAaqsDzWAgFAdP 10 | - BCH: qq22texutzx4ar4020lmqk0w9vrmvgauc5svtmg6ym 11 | - ETH: 0x9545144F8e473FcD1FF470ab55EF381D4f990C56 12 | - LTC: MWwiHTdKfQDerhQ8a5a4mavGmiAZQYWyB1 13 | 14 | You should also go support Zawawawa, buy him a beer or two for being an awesome chap. 15 | -------------------------------------------------------------------------------- /libdevcore/FixedHash.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | /** @file FixedHash.cpp 18 | * @author Gav Wood 19 | * @date 2014 20 | */ 21 | 22 | #include 23 | 24 | #include "FixedHash.h" 25 | 26 | using namespace std; 27 | using namespace dev; 28 | 29 | std::random_device dev::s_fixedHashEngine; 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | *.dylib 9 | 10 | # Compiled Static libraries 11 | *.lai 12 | *.la 13 | *.a 14 | 15 | # VS stuff 16 | build 17 | ipch 18 | *.sdf 19 | *.opensdf 20 | *.suo 21 | *.vcxproj 22 | *.vcxproj.filters 23 | *.sln 24 | 25 | # VIM stuff 26 | *.swp 27 | 28 | # Xcode stuff 29 | build_xc 30 | 31 | *.user 32 | *.user.* 33 | *~ 34 | 35 | # build system 36 | build.*/ 37 | extdep/install 38 | extdep/download 39 | /cmake-build-*/ 40 | 41 | *.pyc 42 | 43 | # MacOS Development 44 | .DS_Store 45 | # CocoaPods 46 | Pods/ 47 | Podfile.lock 48 | # Xcode 49 | .DS_Store 50 | build/ 51 | *.pbxuser 52 | !default.pbxuser 53 | *.mode1v3 54 | !default.mode1v3 55 | *.mode2v3 56 | !default.mode2v3 57 | *.perspectivev3 58 | !default.perspectivev3 59 | *.xcworkspace 60 | !default.xcworkspace 61 | xcuserdata 62 | *.xcuserstate 63 | profile 64 | *.moved-aside 65 | DerivedData 66 | project.pbxproj 67 | 68 | # JetBrains stuff 69 | .idea/ 70 | 71 | doc/html 72 | *.autosave 73 | node_modules/ 74 | 75 | # vscode 76 | .vscode/ 77 | -------------------------------------------------------------------------------- /libpoolprotocols/testing/SimulateClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "../PoolClient.h" 11 | 12 | using namespace std; 13 | using namespace dev; 14 | using namespace eth; 15 | 16 | class SimulateClient : public PoolClient, Worker 17 | { 18 | public: 19 | SimulateClient(unsigned const& block); 20 | ~SimulateClient() override; 21 | 22 | void connect() override; 23 | void disconnect() override; 24 | 25 | bool isPendingState() override { return false; } 26 | string ActiveEndPoint() override { return ""; }; 27 | 28 | void submitHashrate(uint64_t const& rate, string const& id) override; 29 | void submitSolution(const Solution& solution) override; 30 | 31 | private: 32 | 33 | void workLoop() override; 34 | unsigned m_block; 35 | std::chrono::steady_clock::time_point m_start_time; 36 | 37 | float hr_alpha = 0.45f; 38 | float hr_max = 0.0f; 39 | float hr_mean = 0.0f; 40 | }; 41 | -------------------------------------------------------------------------------- /libethash-cl/kernels/isa/GCN_ethash.isa: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | 5 | 6 | .amdcl2 7 | .64bit 8 | 9 | .ifgpu ellesmere 10 | .driver_version 257000 11 | .include "GCN_ethash_globaldata.isa" 12 | .include "GCN3_ethash_search.isa" 13 | .elseifgpu tonga 14 | .driver_version 200406 15 | .include "GCN_ethash_globaldata.isa" 16 | .include "GCN3_ethash_search.isa" 17 | .elseifgpu baffin 18 | .driver_version 257000 19 | .include "GCN_ethash_globaldata.isa" 20 | .include "GCN3_ethash_search.isa" 21 | .elseifgpu gfx804 22 | .driver_version 257000 23 | .include "GCN_ethash_globaldata.isa" 24 | .include "GCN3_ethash_search.isa" 25 | .elseifgpu gfx900 26 | .driver_version 257000 27 | .include "GCN_ethash_globaldata.isa" 28 | .include "GCN5_ethash_search.isa" 29 | .elseifgpu gfx901 30 | .driver_version 257000 31 | .include "GCN_ethash_globaldata.isa" 32 | .include "GCN5_ethash_search.isa" 33 | .elseifgpu gfx906 34 | .driver_version 2906007 35 | .include "GCN_ethash_globaldata.isa" 36 | .include "GCN5_ethash_search.isa" 37 | .else 38 | .error "Unsupported GPU!" 39 | .endif 40 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: Chromium 4 | AccessModifierOffset: -4 5 | AlignAfterOpenBracket: DontAlign 6 | BinPackParameters: true 7 | BraceWrapping: 8 | AfterClass: true 9 | AfterControlStatement: true 10 | AfterEnum: true 11 | AfterFunction: true 12 | AfterNamespace: true 13 | AfterObjCDeclaration: true 14 | AfterStruct: true 15 | AfterUnion: true 16 | BeforeCatch: true 17 | BeforeElse: true 18 | SplitEmptyFunction: false 19 | BreakBeforeBraces: Custom 20 | BreakBeforeTernaryOperators: false 21 | ColumnLimit: 100 22 | ConstructorInitializerIndentWidth: 2 23 | IncludeCategories: 24 | - Regex: '^".*' 25 | Priority: 1 26 | - Regex: '^' 29 | Priority: 2 30 | - Regex: '^<.*' 31 | Priority: 99 32 | - Regex: '.*' 33 | Priority: 4 34 | IncludeIsMainRegex: '(Test)?$' 35 | IndentCaseLabels: false 36 | IndentWidth: 4 37 | MaxEmptyLinesToKeep: 2 38 | PenaltyBreakAssignment: 1 39 | PenaltyBreakComment: 50 40 | TabWidth: 4 41 | ... 42 | 43 | -------------------------------------------------------------------------------- /ethminer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_policy(SET CMP0015 NEW) 2 | 3 | aux_source_directory(. SRC_LIST) 4 | 5 | include_directories(BEFORE ..) 6 | 7 | set(EXECUTABLE ethminer) 8 | 9 | file(GLOB HEADERS "*.h") 10 | 11 | add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) 12 | if(MSVC) 13 | target_sources(${EXECUTABLE} PRIVATE ethminer.rc) 14 | endif() 15 | 16 | hunter_add_package(CLI11) 17 | find_package(CLI11 CONFIG REQUIRED) 18 | 19 | target_link_libraries(ethminer PRIVATE ethcore poolprotocols devcore ethminer-buildinfo CLI11::CLI11 Boost::system Boost::thread) 20 | 21 | if(ETHDBUS) 22 | find_package(PkgConfig) 23 | set( ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/lib/x86_64-linux-gnu/pkgconfig" ) 24 | pkg_check_modules(DBUS dbus-1) 25 | include_directories(${DBUS_INCLUDE_DIRS}) 26 | link_directories(${DBUS_LIBRARY_DIRS}) 27 | target_link_libraries(ethminer PRIVATE ${DBUS_LIBRARIES}) 28 | endif() 29 | 30 | if(APICORE) 31 | target_link_libraries(ethminer PRIVATE apicore) 32 | endif() 33 | 34 | include(GNUInstallDirs) 35 | install(TARGETS ethminer DESTINATION ${CMAKE_INSTALL_BINDIR}) 36 | if(MSVC) 37 | install(FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) 38 | endif() 39 | -------------------------------------------------------------------------------- /libhwmon/wrapamdsysfs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Wrapper for AMD SysFS on linux, using adapted code from amdcovc by matszpk 3 | * 4 | * By Philipp Andreas - github@smurfy.de 5 | Reworked and simplified by Andrea Lanfranchi (github @AndreaLanfranchi) 6 | */ 7 | 8 | #pragma once 9 | 10 | typedef struct 11 | { 12 | int sysfs_gpucount; 13 | unsigned int* sysfs_device_id; 14 | unsigned int* sysfs_hwmon_id; 15 | unsigned int* sysfs_pci_domain_id; 16 | unsigned int* sysfs_pci_bus_id; 17 | unsigned int* sysfs_pci_device_id; 18 | } wrap_amdsysfs_handle; 19 | 20 | typedef struct 21 | { 22 | int DeviceId = -1; 23 | int HwMonId = -1; 24 | int PciDomain = -1; 25 | int PciBus = -1; 26 | int PciDevice = -1; 27 | 28 | } pciInfo; 29 | 30 | wrap_amdsysfs_handle* wrap_amdsysfs_create(); 31 | int wrap_amdsysfs_destroy(wrap_amdsysfs_handle* sysfsh); 32 | 33 | int wrap_amdsysfs_get_gpucount(wrap_amdsysfs_handle* sysfsh, int* gpucount); 34 | 35 | int wrap_amdsysfs_get_tempC(wrap_amdsysfs_handle* sysfsh, int index, unsigned int* tempC); 36 | 37 | int wrap_amdsysfs_get_fanpcnt(wrap_amdsysfs_handle* sysfsh, int index, unsigned int* fanpcnt); 38 | 39 | int wrap_amdsysfs_get_power_usage( 40 | wrap_amdsysfs_handle* sysfsh, int index, unsigned int* milliwatts); 41 | -------------------------------------------------------------------------------- /ethminer/DBusInt.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | class DBusInt 8 | { 9 | public: 10 | DBusInt() 11 | { 12 | dbus_error_init(&err); 13 | conn = dbus_bus_get(DBUS_BUS_SESSION, &err); 14 | if (!conn) 15 | { 16 | minelog << "DBus error " << err.name << ": " << err.message; 17 | } 18 | dbus_bus_request_name(conn, "eth.miner", DBUS_NAME_FLAG_REPLACE_EXISTING, &err); 19 | if (dbus_error_is_set(&err)) 20 | { 21 | minelog << "DBus error " << err.name << ": " << err.message; 22 | dbus_connection_close(conn); 23 | } 24 | minelog << "DBus initialized!"; 25 | } 26 | 27 | void send(const char* hash) 28 | { 29 | DBusMessage* msg; 30 | msg = dbus_message_new_signal("/eth/miner/hash", "eth.miner.monitor", "Hash"); 31 | if (msg == nullptr) 32 | { 33 | minelog << "Message is null!"; 34 | } 35 | dbus_message_append_args(msg, DBUS_TYPE_STRING, &hash, DBUS_TYPE_INVALID); 36 | if (!dbus_connection_send(conn, msg, nullptr)) 37 | cerr << "Error sending message!"; 38 | dbus_message_unref(msg); 39 | } 40 | 41 | private: 42 | DBusError err; 43 | DBusConnection* conn; 44 | }; 45 | -------------------------------------------------------------------------------- /libethcore/EthashAux.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | 18 | #include "EthashAux.h" 19 | 20 | #include 21 | 22 | using namespace dev; 23 | using namespace eth; 24 | 25 | Result EthashAux::eval(int epoch, h256 const& _headerHash, uint64_t _nonce) noexcept 26 | { 27 | auto headerHash = ethash::hash256_from_bytes(_headerHash.data()); 28 | auto& context = ethash::get_global_epoch_context(epoch); 29 | auto result = ethash::hash(context, headerHash, _nonce); 30 | h256 mix{reinterpret_cast(result.mix_hash.bytes), h256::ConstructFromPointer}; 31 | h256 final{reinterpret_cast(result.final_hash.bytes), h256::ConstructFromPointer}; 32 | return {final, mix}; 33 | } -------------------------------------------------------------------------------- /libethash-cl/kernels/isa/GCN_ethash_globaldata.isa: -------------------------------------------------------------------------------- 1 | .globaldata 2 | .gdata: 3 | .byte 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 4 | .byte 0x82, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 5 | .byte 0x8a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 6 | .byte 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80 7 | .byte 0x8b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 8 | .byte 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 9 | .byte 0x81, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80 10 | .byte 0x09, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 11 | .byte 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 12 | .byte 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 13 | .byte 0x09, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 14 | .byte 0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 15 | .byte 0x8b, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 16 | .byte 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 17 | .byte 0x89, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 18 | .byte 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 19 | .byte 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 20 | .byte 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 21 | .byte 0x0a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 22 | .byte 0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80 23 | .byte 0x81, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80 24 | .byte 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 25 | .byte 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00 26 | .byte 0x08, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80 -------------------------------------------------------------------------------- /libethash-cl/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # A custom command and target to turn the OpenCL kernel into a byte array header 2 | # The normal build depends on it properly and if the kernel file is changed, then 3 | # a rebuild of libethash-cl should be triggered 4 | 5 | #TODO: clean up the copy&pasting here 6 | add_custom_command( 7 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ethash.h 8 | COMMAND ${CMAKE_COMMAND} ARGS 9 | -DBIN2H_SOURCE_FILE="${CMAKE_CURRENT_SOURCE_DIR}/kernels/cl/ethash.cl" 10 | -DBIN2H_VARIABLE_NAME=ethash_cl 11 | -DBIN2H_HEADER_FILE="${CMAKE_CURRENT_BINARY_DIR}/ethash.h" 12 | -P "${CMAKE_CURRENT_SOURCE_DIR}/bin2h.cmake" 13 | COMMENT "Generating OpenCL Kernel Byte Array" 14 | DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/kernels/cl/ethash.cl 15 | ) 16 | add_custom_target(clbin2h_stable DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ethash.h ${CMAKE_CURRENT_SOURCE_DIR}/cl/ethash.cl) 17 | 18 | set(SOURCES 19 | CLMiner.h CLMiner.cpp 20 | ${CMAKE_CURRENT_BINARY_DIR}/ethash.h 21 | ) 22 | 23 | if(USE_SYS_OPENCL) 24 | # On macOS or using ROCm-OpenCL, use system OpenCL library. 25 | find_package(OpenCL REQUIRED) 26 | else() 27 | hunter_add_package(OpenCL) 28 | find_package(OpenCL CONFIG REQUIRED) 29 | endif() 30 | 31 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) 32 | include_directories(..) 33 | 34 | add_library(ethash-cl ${SOURCES}) 35 | target_link_libraries(ethash-cl PUBLIC ethcore ethash::ethash) 36 | target_link_libraries(ethash-cl PRIVATE OpenCL::OpenCL) 37 | target_link_libraries(ethash-cl PRIVATE Boost::filesystem Boost::thread) 38 | -------------------------------------------------------------------------------- /libethash-cl/kernels/Makefile: -------------------------------------------------------------------------------- 1 | SDIR=./isa 2 | BUILD=./bin 3 | 4 | ASFLAGS=-I$(SDIR) 5 | AS=clrxasm 6 | 7 | .PHONY: all 8 | all: ellesmere tonga baffin gfx900 gfx901 gfx906 9 | @echo "Built ethash kernel for Ellesmere, Tonga, Baffin, Gfx900 and Gfx901 architectures." 10 | 11 | .PHONY: clean 12 | clean: 13 | rm -f $(BUILD)/*.o $(BUILD)/*.bin 14 | 15 | %.bin: 16 | $(eval ARCH:=$(shell echo "$*" | sed -n 's/\(^[A-Za-z0-9]*\).*/\1/p')) 17 | $(eval LWS:=$(shell echo "$*" | sed -n 's/.*lws\([0-9]\+\)/\1/p')) 18 | $(AS) $(SDIR)/GCN_ethash.isa -g $(ARCH) -DFAST_EXIT -Dworksize=$(LWS) $(ASFLAGS) -o $(BUILD)/ethash_$(ARCH)_lws$(LWS)_exit.bin 19 | $(AS) $(SDIR)/GCN_ethash.isa -g $(ARCH) -Dworksize=$(LWS) $(ASFLAGS) -o $(BUILD)/ethash_$(ARCH)_lws$(LWS).bin 20 | 21 | .PHONY: ellesmere 22 | ellesmere: ellesmere_lws64.bin ellesmere_lws128.bin ellesmere_lws256.bin 23 | @echo "Built Ellesmere kernels..." 24 | 25 | .PHONY: tonga 26 | tonga: tonga_lws64.bin tonga_lws128.bin tonga_lws256.bin 27 | @echo "Built Tonga kernels..." 28 | 29 | .PHONY: baffin 30 | baffin: baffin_lws64.bin baffin_lws128.bin baffin_lws256.bin 31 | @echo "Built Baffin kernels..." 32 | 33 | .PHONY: gfx900 34 | gfx900: gfx900_lws64.bin gfx900_lws128.bin gfx900_lws256.bin 35 | @echo "Built gfx900 kernels..." 36 | 37 | .PHONY: gfx901 38 | gfx901: gfx901_lws64.bin gfx901_lws128.bin gfx901_lws256.bin 39 | @echo "Built gfx901 kernels..." 40 | 41 | .PHONY: gfx906 42 | gfx906: gfx906_lws64.bin gfx906_lws128.bin gfx906_lws256.bin 43 | @echo "Built gfx906 kernels..." 44 | -------------------------------------------------------------------------------- /scripts/install-cuda-ubuntu1604.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Install the core CUDA_VER toolkit for Ubuntu 16.04. 4 | # Requires the CUDA_VER environment variable to be set to the required version. 5 | # 6 | # Since this script updates environment variables, to execute correctly you must 7 | # 'source' this script, rather than executing it in a sub-process. 8 | # 9 | # Taken from https://github.com/tmcdonell/travis-scripts. 10 | 11 | set -e 12 | 13 | CUDA_VER=9.1.85-1 14 | if [ "$1" != "" ]; then 15 | CUDA_VER=$1 16 | fi 17 | if [ "$CUDA_VER" = "8" ]; then 18 | CUDA_VER=8.0.61-1 19 | CUDA_PACKAGE=cuda-core 20 | elif [ "$CUDA_VER" = "9" ]; then 21 | CUDA_VER=9.1.85-1 22 | elif [ "$CUDA_VER" = "9.1" ]; then 23 | CUDA_VER=9.1.85-1 24 | elif [ "$CUDA_VER" = "9.2" ]; then 25 | CUDA_VER=9.2.148-1 26 | elif [ "$CUDA_VER" = "10" ]; then 27 | CUDA_VER=10.0.130-1 28 | fi 29 | 30 | if [ -z $CUDA_PACKAGE ]; then 31 | CUDA_PACKAGE=cuda-nvcc 32 | fi 33 | 34 | sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub 35 | wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_${CUDA_VER}_amd64.deb 36 | sudo dpkg -i cuda-repo-ubuntu1604_${CUDA_VER}_amd64.deb 37 | sudo apt-get update -qq 38 | CUDA_APT=$(echo $CUDA_VER | sed 's/\.[0-9]\+\-[0-9]\+$//;s/\./-/') 39 | sudo apt-get install -qy $CUDA_PACKAGE-$CUDA_APT cuda-cudart-dev-$CUDA_APT 40 | sudo apt-get clean 41 | CUDA_APT=$(echo $CUDA_APT | sed 's/-/./') 42 | CUDA_HOME=/usr/local/cuda-$CUDA_APT 43 | PATH=${CUDA_HOME}/bin:${PATH} 44 | export CUDA_HOME 45 | export PATH 46 | -------------------------------------------------------------------------------- /libethash-cpu/CPUMiner.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | namespace dev 27 | { 28 | namespace eth 29 | { 30 | class CPUMiner : public Miner 31 | { 32 | public: 33 | CPUMiner(unsigned _index, CPSettings _settings, DeviceDescriptor& _device); 34 | ~CPUMiner() override; 35 | 36 | static unsigned getNumDevices(); 37 | static void enumDevices(std::map& _DevicesCollection); 38 | 39 | void search(const dev::eth::WorkPackage& w); 40 | 41 | protected: 42 | bool initDevice() override; 43 | bool initEpoch_internal() override; 44 | void kick_miner() override; 45 | 46 | private: 47 | atomic m_new_work = {false}; 48 | void workLoop() override; 49 | CPSettings m_settings; 50 | }; 51 | 52 | 53 | } // namespace eth 54 | } // namespace dev 55 | -------------------------------------------------------------------------------- /cmake/EthCheckCXXFlags.cmake: -------------------------------------------------------------------------------- 1 | include(CheckCXXCompilerFlag) 2 | 3 | # Adds CXX compiler flag if the flag is supported by the compiler. 4 | # 5 | # This is effectively a combination of CMake's check_cxx_compiler_flag() 6 | # and add_compile_options(): 7 | # 8 | # if(check_cxx_compiler_flag(flag)) 9 | # add_compile_options(flag) 10 | # 11 | function(eth_add_cxx_compiler_flag_if_supported FLAG) 12 | # Remove leading - or / from the flag name. 13 | string(REGEX REPLACE "^-|/" "" name ${FLAG}) 14 | check_cxx_compiler_flag(${FLAG} ${name}) 15 | if(${name}) 16 | add_compile_options(${FLAG}) 17 | endif() 18 | # If the optional argument passed, store the result there. 19 | if(ARGV1) 20 | set(${ARGV1} ${name} PARENT_SCOPE) 21 | endif() 22 | endfunction() 23 | 24 | # Adds CXX linker flag if the flag is supported by the linker. 25 | # 26 | # This is effectively a combination of CMake's check_cxx_compiler_flag() 27 | # which runs a test compile and link, with an update of the 28 | # CMAKE_CXX_LINK_FLAGS which is passed to the CXX driver for 29 | # the link phase. 30 | # 31 | # if(check_cxx_compiler_flag(flag)) 32 | # CMAKE_CXX_LINK_FLAGS += flag 33 | # 34 | function(eth_add_cxx_linker_flag_if_supported FLAG) 35 | # Remove leading - or / from the flag name. 36 | string(REGEX REPLACE "^-|/" "" name ${FLAG}) 37 | check_cxx_compiler_flag(${FLAG} ${name}) 38 | if(${name}) 39 | set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} ${FLAG}") 40 | endif() 41 | # If the optional argument passed, store the result there. 42 | if(ARGV1) 43 | set(${ARGV1} ${name} PARENT_SCOPE) 44 | endif() 45 | endfunction() 46 | -------------------------------------------------------------------------------- /scripts/install_cmake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # This script downloads the CMake binary and installs it in $PREFIX directory 4 | # (the cmake executable will be in $PREFIX/bin). By default $PREFIX is 5 | # ~/.local but can we changes with --prefix argument. 6 | 7 | # This is mostly suitable for CIs, not end users. 8 | 9 | set -e 10 | 11 | VERSION=3.8.1 12 | 13 | if [ "$1" = "--prefix" ]; then 14 | PREFIX="$2" 15 | else 16 | PREFIX=~/.local 17 | fi 18 | 19 | OS=$(uname -s) 20 | case $OS in 21 | Linux) SHA256=10ca0e25b7159a03da0c1ec627e686562dc2a40aad5985fd2088eb684b08e491;; 22 | Darwin) SHA256=cf8cf16eb1281127006507e69bbcfabec2ccbbc3dfb95888c39d578d037569f1;; 23 | esac 24 | 25 | 26 | BIN=$PREFIX/bin 27 | 28 | if test -f $BIN/cmake && ($BIN/cmake --version | grep -q "$VERSION"); then 29 | echo "CMake $VERSION already installed in $BIN" 30 | else 31 | FILE=cmake-$VERSION-$OS-x86_64.tar.gz 32 | VERSION_SERIES=$(echo $VERSION | awk '{ string=substr($0, 1, 3); print string; }') 33 | URL=https://cmake.org/files/v$VERSION_SERIES/$FILE 34 | ERROR=0 35 | TMPFILE=$(mktemp --tmpdir cmake-$VERSION-$OS-x86_64.XXXXXXXX.tar.gz) 36 | echo "Downloading CMake ($URL)..." 37 | curl -s "$URL" > "$TMPFILE" 38 | 39 | if type -p sha256sum > /dev/null; then 40 | SHASUM_TOOL="sha256sum" 41 | else 42 | SHASUM_TOOL="shasum -a256" 43 | fi 44 | 45 | SHASUM=$($SHASUM_TOOL "$TMPFILE") 46 | if ! (echo "$SHASUM" | grep -q "$SHA256"); then 47 | echo "Checksum mismatch!" 48 | echo "Actual: $SHASUM" 49 | echo "Expected: $SHA256" 50 | exit 1 51 | fi 52 | mkdir -p "$PREFIX" 53 | echo "Unpacking CMake to $PREFIX..." 54 | tar xzf "$TMPFILE" -C "$PREFIX" --strip 1 55 | rm $TMPFILE 56 | fi 57 | -------------------------------------------------------------------------------- /libdevcore/Common.h: -------------------------------------------------------------------------------- 1 | // ethminer -- Ethereum miner with OpenCL, CUDA and stratum support. 2 | // Copyright 2018 ethminer Authors. 3 | // Licensed under GNU General Public License, Version 3. See the LICENSE file. 4 | 5 | /// @file 6 | /// Very common stuff (i.e. that every other header needs except vector_ref.h). 7 | 8 | #pragma once 9 | 10 | #include "vector_ref.h" 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | using byte = uint8_t; 18 | 19 | namespace dev 20 | { 21 | // Binary data types. 22 | using bytes = std::vector; 23 | using bytesRef = vector_ref; 24 | using bytesConstRef = vector_ref; 25 | 26 | // Numeric types. 27 | using bigint = boost::multiprecision::number>; 28 | using u64 = boost::multiprecision::number>; 30 | using u128 = boost::multiprecision::number>; 32 | using u256 = boost::multiprecision::number>; 34 | using u160 = boost::multiprecision::number>; 36 | using u512 = boost::multiprecision::number>; 38 | 39 | // Null/Invalid values for convenience. 40 | static const u256 Invalid256 = ~(u256)0; 41 | 42 | /// Converts arbitrary value to string representation using std::stringstream. 43 | template 44 | std::string toString(_T const& _t) 45 | { 46 | std::ostringstream o; 47 | o << _t; 48 | return o.str(); 49 | } 50 | 51 | } // namespace dev 52 | -------------------------------------------------------------------------------- /libethash-cuda/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(CUDA REQUIRED) 2 | 3 | set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};--ptxas-options=-v;-use_fast_math) 4 | 5 | if (NOT MSVC) 6 | list(APPEND CUDA_NVCC_FLAGS "--disable-warnings") 7 | endif() 8 | 9 | list(APPEND CUDA_NVCC_FLAGS_RELEASE -O3) 10 | list(APPEND CUDA_NVCC_FLAGS_DEBUG -G) 11 | 12 | if(COMPUTE AND (COMPUTE GREATER 0)) 13 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_${COMPUTE},code=sm_${COMPUTE}") 14 | else() 15 | if (CUDA_VERSION VERSION_LESS 11.0) 16 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_30,code=sm_30") 17 | endif() 18 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_35,code=sm_35") 19 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_50,code=sm_50") 20 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_52,code=sm_52") 21 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_53,code=sm_53") 22 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_60,code=sm_60") 23 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_61,code=sm_61") 24 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_62,code=sm_62") 25 | if(NOT CUDA_VERSION VERSION_LESS 9.0) 26 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_70,code=sm_70") 27 | endif() 28 | if(NOT CUDA_VERSION VERSION_LESS 10.0) 29 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_75,code=sm_75") 30 | endif() 31 | if(NOT CUDA_VERSION VERSION_LESS 11.0) 32 | # NVIDIA A100 and NVIDIA DGX-A100 33 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_80,code=sm_80") 34 | endif() 35 | if(NOT CUDA_VERSION VERSION_LESS 11.1) 36 | # Tesla GA10x cards, RTX Ampere – RTX 3080/3090, RTX A6000, RTX A40 37 | list(APPEND CUDA_NVCC_FLAGS "-gencode arch=compute_86,code=sm_86") 38 | endif() 39 | endif() 40 | 41 | file(GLOB sources "*.cpp" "*.cu") 42 | file(GLOB headers "*.h" "*.cuh") 43 | 44 | cuda_add_library(ethash-cuda STATIC ${sources} ${headers}) 45 | target_link_libraries(ethash-cuda ethcore ethash::ethash Boost::thread) 46 | target_include_directories(ethash-cuda PUBLIC ${CUDA_INCLUDE_DIRS}) 47 | target_include_directories(ethash-cuda PRIVATE .. ${CMAKE_CURRENT_BINARY_DIR}) 48 | -------------------------------------------------------------------------------- /libethash-cuda/CUDAMiner.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | 18 | #pragma once 19 | 20 | #include "ethash_cuda_miner_kernel.h" 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | namespace dev 29 | { 30 | namespace eth 31 | { 32 | class CUDAMiner : public Miner 33 | { 34 | public: 35 | CUDAMiner(unsigned _index, CUSettings _settings, DeviceDescriptor& _device); 36 | ~CUDAMiner() override; 37 | 38 | static int getNumDevices(); 39 | static void enumDevices(std::map& _DevicesCollection); 40 | 41 | void search( 42 | uint8_t const* header, uint64_t target, uint64_t _startN, const dev::eth::WorkPackage& w); 43 | 44 | protected: 45 | bool initDevice() override; 46 | 47 | bool initEpoch_internal() override; 48 | 49 | void kick_miner() override; 50 | 51 | private: 52 | atomic m_new_work = {false}; 53 | 54 | void workLoop() override; 55 | 56 | std::vector m_search_buf; 57 | std::vector m_streams; 58 | uint64_t m_current_target = 0; 59 | 60 | CUSettings m_settings; 61 | 62 | const uint32_t m_batch_size; 63 | const uint32_t m_streams_batch_size; 64 | 65 | uint64_t m_allocated_memory_dag = 0; // dag_size is a uint64_t in EpochContext struct 66 | size_t m_allocated_memory_light_cache = 0; 67 | }; 68 | 69 | 70 | } // namespace eth 71 | } // namespace dev 72 | -------------------------------------------------------------------------------- /libdevcore/Guards.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | /** @file Guards.h 18 | * @author Gav Wood 19 | * @date 2014 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | 27 | namespace dev 28 | { 29 | using Mutex = std::mutex; 30 | using Guard = std::lock_guard; 31 | using UniqueGuard = std::unique_lock; 32 | 33 | template 34 | struct GenericGuardBool : GuardType 35 | { 36 | GenericGuardBool(MutexType& _m) : GuardType(_m) {} 37 | bool b = true; 38 | }; 39 | 40 | /** @brief Simple block guard. 41 | * The expression/block following is guarded though the given mutex. 42 | * Usage: 43 | * @code 44 | * Mutex m; 45 | * unsigned d; 46 | * ... 47 | * ETH_(m) d = 1; 48 | * ... 49 | * ETH_(m) { for (auto d = 10; d > 0; --d) foo(d); d = 0; } 50 | * @endcode 51 | * 52 | * There are several variants of this basic mechanism for different Mutex types and Guards. 53 | * 54 | * There is also the UNGUARD variant which allows an unguarded expression/block to exist within a 55 | * guarded expression. eg: 56 | * 57 | * @code 58 | * Mutex m; 59 | * int d; 60 | * ... 61 | * ETH_GUARDED(m) 62 | * { 63 | * for (auto d = 50; d > 25; --d) 64 | * foo(d); 65 | * ETH_UNGUARDED(m) 66 | * bar(); 67 | * for (; d > 0; --d) 68 | * foo(d); 69 | * } 70 | * @endcode 71 | */ 72 | 73 | #define DEV_GUARDED(MUTEX) \ 74 | for (GenericGuardBool __eth_l(MUTEX); __eth_l.b; __eth_l.b = false) 75 | 76 | } // namespace dev 77 | -------------------------------------------------------------------------------- /libdevcore/Worker.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | /** @file Worker.h 18 | * @author Gav Wood 19 | * @date 2014 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "Guards.h" 31 | 32 | extern bool g_exitOnError; 33 | 34 | namespace dev 35 | { 36 | enum class WorkerState 37 | { 38 | Starting, 39 | Started, 40 | Stopping, 41 | Stopped, 42 | Killing 43 | }; 44 | 45 | class Worker 46 | { 47 | public: 48 | Worker(std::string _name) : m_name(std::move(_name)) {} 49 | 50 | Worker(Worker const&) = delete; 51 | Worker& operator=(Worker const&) = delete; 52 | 53 | virtual ~Worker(); 54 | 55 | /// Starts worker thread; causes startedWorking() to be called. 56 | void startWorking(); 57 | 58 | /// Triggers worker thread it should stop 59 | void triggerStopWorking(); 60 | 61 | /// Stop worker thread; causes call to stopWorking() and waits till thread has stopped. 62 | void stopWorking(); 63 | 64 | /// Whether or not this worker should stop 65 | bool shouldStop() const { return m_state != WorkerState::Started; } 66 | 67 | private: 68 | virtual void workLoop() = 0; 69 | 70 | std::string m_name; 71 | 72 | mutable Mutex x_work; ///< Lock for the network existence. 73 | std::unique_ptr m_work; ///< The network thread. 74 | std::atomic m_state = {WorkerState::Starting}; 75 | }; 76 | 77 | } // namespace dev 78 | -------------------------------------------------------------------------------- /libethcore/EthashAux.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | namespace dev 27 | { 28 | namespace eth 29 | { 30 | struct Result 31 | { 32 | h256 value; 33 | h256 mixHash; 34 | }; 35 | 36 | class EthashAux 37 | { 38 | public: 39 | static Result eval(int epoch, h256 const& _headerHash, uint64_t _nonce) noexcept; 40 | }; 41 | 42 | struct EpochContext 43 | { 44 | int epochNumber; 45 | int lightNumItems; 46 | size_t lightSize; 47 | const ethash_hash512* lightCache; 48 | int dagNumItems; 49 | uint64_t dagSize; 50 | }; 51 | 52 | struct WorkPackage 53 | { 54 | WorkPackage() = default; 55 | 56 | explicit operator bool() const { return header != h256(); } 57 | 58 | std::string job; // Job identifier can be anything. Not necessarily a hash 59 | 60 | h256 boundary; 61 | h256 header; ///< When h256() means "pause until notified a new work package is available". 62 | h256 seed; 63 | 64 | int epoch = -1; 65 | int block = -1; 66 | 67 | uint64_t startNonce = 0; 68 | uint16_t exSizeBytes = 0; 69 | 70 | std::string algo = "ethash"; 71 | }; 72 | 73 | struct Solution 74 | { 75 | uint64_t nonce; // Solution found nonce 76 | h256 mixHash; // Mix hash 77 | WorkPackage work; // WorkPackage this solution refers to 78 | std::chrono::steady_clock::time_point tstamp; // Timestamp of found solution 79 | unsigned midx; // Originating miner Id 80 | }; 81 | 82 | } // namespace eth 83 | } // namespace dev 84 | -------------------------------------------------------------------------------- /libethash-cl/CLMiner.h: -------------------------------------------------------------------------------- 1 | /// OpenCL miner implementation. 2 | /// 3 | /// @file 4 | /// @copyright GNU General Public License 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #pragma GCC diagnostic push 18 | #if __GNUC__ >= 6 19 | #pragma GCC diagnostic ignored "-Wignored-attributes" 20 | #endif 21 | #pragma GCC diagnostic ignored "-Wmissing-braces" 22 | #define CL_USE_DEPRECATED_OPENCL_1_2_APIS true 23 | #define CL_HPP_ENABLE_EXCEPTIONS true 24 | #define CL_HPP_CL_1_2_DEFAULT_BUILD true 25 | #define CL_HPP_TARGET_OPENCL_VERSION 120 26 | #define CL_HPP_MINIMUM_OPENCL_VERSION 120 27 | #include "CL/cl2.hpp" 28 | #pragma GCC diagnostic pop 29 | 30 | // macOS OpenCL fix: 31 | #ifndef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 32 | #define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000 33 | #endif 34 | 35 | #ifndef CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 36 | #define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001 37 | #endif 38 | 39 | namespace dev 40 | { 41 | namespace eth 42 | { 43 | class CLMiner : public Miner 44 | { 45 | public: 46 | 47 | CLMiner(unsigned _index, CLSettings _settings, DeviceDescriptor& _device); 48 | ~CLMiner() override; 49 | 50 | static void enumDevices(std::map& _DevicesCollection); 51 | 52 | protected: 53 | bool initDevice() override; 54 | 55 | bool initEpoch_internal() override; 56 | 57 | void kick_miner() override; 58 | 59 | private: 60 | 61 | void workLoop() override; 62 | 63 | vector m_context; 64 | vector m_queue; 65 | vector m_abortqueue; 66 | cl::Kernel m_searchKernel; 67 | cl::Kernel m_dagKernel; 68 | cl::Device m_device; 69 | 70 | vector m_dag; 71 | vector m_light; 72 | vector m_header; 73 | vector m_searchBuffer; 74 | 75 | void clear_buffer() { 76 | m_dag.clear(); 77 | m_light.clear(); 78 | m_header.clear(); 79 | m_searchBuffer.clear(); 80 | m_queue.clear(); 81 | m_context.clear(); 82 | m_abortqueue.clear(); 83 | } 84 | 85 | CLSettings m_settings; 86 | 87 | unsigned m_dagItems = 0; 88 | uint64_t m_lastNonce = 0; 89 | 90 | }; 91 | 92 | } // namespace eth 93 | } // namespace dev 94 | -------------------------------------------------------------------------------- /cmake/EthCompilerSettings.cmake: -------------------------------------------------------------------------------- 1 | # Set necessary compile and link flags 2 | 3 | include(EthCheckCXXFlags) 4 | 5 | # C++11 check and activation 6 | if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") 7 | 8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unknown-pragmas -Wextra -Wno-error=parentheses -pedantic") 9 | 10 | eth_add_cxx_compiler_flag_if_supported(-ffunction-sections) 11 | eth_add_cxx_compiler_flag_if_supported(-fdata-sections) 12 | eth_add_cxx_linker_flag_if_supported(-Wl,--gc-sections) 13 | 14 | elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") 15 | 16 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unknown-pragmas -Wextra") 17 | 18 | eth_add_cxx_compiler_flag_if_supported(-ffunction-sections) 19 | eth_add_cxx_compiler_flag_if_supported(-fdata-sections) 20 | eth_add_cxx_linker_flag_if_supported(-Wl,--gc-sections) 21 | 22 | if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") 23 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++ -fcolor-diagnostics -Qunused-arguments") 24 | endif() 25 | 26 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 27 | 28 | # declare Windows Vista requirement 29 | # undefine windows.h MAX & MIN macros because they conflict with std::min & std::max functions 30 | # disable unsafe CRT Library functions warnings 31 | add_definitions(/D_WIN32_WINNT=0x0600 /DNOMINMAX /D_CRT_SECURE_NO_WARNINGS) 32 | 33 | # enable parallel compilation 34 | # specify Exception Handling Model 35 | # enable LTCG for faster builds 36 | # disable unknown pragma warnings (C4068) 37 | # disable conversion from 'size_t' to 'type', possible loss of data (C4267) 38 | # disable C++ exception specification ignored except to indicate a function is not __declspec(nothrow) (C4290) 39 | add_compile_options(/MP /EHsc /GL /wd4068 /wd4267 /wd4290) 40 | 41 | # enable LTCG for faster builds 42 | set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /LTCG") 43 | 44 | # enable LTCG for faster builds 45 | # enable unused references removal 46 | # enable RELEASE so that the executable file has its checksum set 47 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LTCG /OPT:REF /OPT:ICF /RELEASE") 48 | else () 49 | message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.") 50 | endif () 51 | 52 | set(SANITIZE NO CACHE STRING "Instrument build with provided sanitizer") 53 | if(SANITIZE) 54 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=${SANITIZE}") 55 | endif() 56 | -------------------------------------------------------------------------------- /libdevcore/Exceptions.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | /** @file Exceptions.h 18 | * @author Gav Wood 19 | * @date 2014 20 | */ 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | #include "CommonData.h" 31 | #include "FixedHash.h" 32 | 33 | namespace dev 34 | { 35 | /// Base class for all exceptions. 36 | struct Exception : virtual std::exception, virtual boost::exception 37 | { 38 | Exception(const std::string& _message = std::string()) : m_message(std::move(_message)) {} 39 | const char* what() const noexcept override 40 | { 41 | return m_message.empty() ? std::exception::what() : m_message.c_str(); 42 | } 43 | 44 | private: 45 | std::string m_message; 46 | }; 47 | 48 | #define DEV_SIMPLE_EXCEPTION(X) \ 49 | struct X : virtual Exception \ 50 | { \ 51 | const char* what() const noexcept override { return #X; } \ 52 | } 53 | 54 | 55 | DEV_SIMPLE_EXCEPTION(BadHexCharacter); 56 | 57 | struct ExternalFunctionFailure : virtual Exception 58 | { 59 | public: 60 | ExternalFunctionFailure(const std::string& _f) : Exception("Function " + _f + "() failed.") {} 61 | }; 62 | 63 | // error information to be added to exceptions 64 | using errinfo_invalidSymbol = boost::error_info; 65 | using errinfo_comment = boost::error_info; 66 | using errinfo_required = boost::error_info; 67 | using errinfo_got = boost::error_info; 68 | using RequirementError = boost::tuple; 69 | 70 | } // namespace dev 71 | -------------------------------------------------------------------------------- /libpoolprotocols/getwork/EthGetworkClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "../PoolClient.h" 14 | 15 | using namespace std; 16 | using namespace dev; 17 | using namespace eth; 18 | 19 | class EthGetworkClient : public PoolClient 20 | { 21 | public: 22 | EthGetworkClient(int worktimeout, unsigned farmRecheckPeriod); 23 | ~EthGetworkClient(); 24 | 25 | void connect() override; 26 | void disconnect() override; 27 | 28 | void submitHashrate(uint64_t const& rate, string const& id) override; 29 | void submitSolution(const Solution& solution) override; 30 | 31 | private: 32 | unsigned m_farmRecheckPeriod = 500; // In milliseconds 33 | 34 | void begin_connect(); 35 | void handle_resolve( 36 | const boost::system::error_code& ec, boost::asio::ip::tcp::resolver::iterator i); 37 | void handle_connect(const boost::system::error_code& ec); 38 | void handle_write(const boost::system::error_code& ec); 39 | void handle_read(const boost::system::error_code& ec, std::size_t bytes_transferred); 40 | std::string processError(Json::Value& JRes); 41 | void processResponse(Json::Value& JRes); 42 | void send(Json::Value const& jReq); 43 | void send(std::string const& sReq); 44 | void getwork_timer_elapsed(const boost::system::error_code& ec); 45 | 46 | WorkPackage m_current; 47 | 48 | std::atomic m_connecting = {false}; // Whether or not socket is on first try connect 49 | std::atomic m_txPending = {false}; // Whether or not an async socket operation is pending 50 | boost::lockfree::queue m_txQueue; 51 | 52 | boost::asio::io_context::strand m_io_strand; 53 | 54 | boost::asio::ip::tcp::socket m_socket; 55 | boost::asio::ip::tcp::resolver m_resolver; 56 | std::queue> m_endpoints; 57 | 58 | boost::asio::streambuf m_request; 59 | boost::asio::streambuf m_response; 60 | Json::StreamWriterBuilder m_jSwBuilder; 61 | std::string m_jsonGetWork; 62 | Json::Value m_pendingJReq; 63 | std::chrono::time_point m_pending_tstamp; 64 | 65 | boost::asio::deadline_timer m_getwork_timer; // The timer which triggers getWork requests 66 | 67 | // seconds to trigger a work_timeout (overwritten in constructor) 68 | int m_worktimeout; 69 | std::chrono::time_point m_current_tstamp; 70 | 71 | unsigned m_solution_submitted_max_id; // maximum json id we used to send a solution 72 | }; 73 | -------------------------------------------------------------------------------- /libdevcore/Terminal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace dev 4 | { 5 | namespace con 6 | { 7 | #define EthReset "\x1b[0m" // Text Reset 8 | 9 | // Regular Colors 10 | #define EthBlack "\x1b[30m" // Black 11 | #define EthCoal "\x1b[90m" // Black 12 | #define EthGray "\x1b[37m" // White 13 | #define EthWhite "\x1b[97m" // White 14 | #define EthMaroon "\x1b[31m" // Red 15 | #define EthRed "\x1b[91m" // Red 16 | #define EthGreen "\x1b[32m" // Green 17 | #define EthLime "\x1b[92m" // Green 18 | #define EthOrange "\x1b[33m" // Yellow 19 | #define EthYellow "\x1b[93m" // Yellow 20 | #define EthNavy "\x1b[34m" // Blue 21 | #define EthBlue "\x1b[94m" // Blue 22 | #define EthViolet "\x1b[35m" // Purple 23 | #define EthPurple "\x1b[95m" // Purple 24 | #define EthTeal "\x1b[36m" // Cyan 25 | #define EthCyan "\x1b[96m" // Cyan 26 | 27 | #define EthBlackBold "\x1b[1;30m" // Black 28 | #define EthCoalBold "\x1b[1;90m" // Black 29 | #define EthGrayBold "\x1b[1;37m" // White 30 | #define EthWhiteBold "\x1b[1;97m" // White 31 | #define EthMaroonBold "\x1b[1;31m" // Red 32 | #define EthRedBold "\x1b[1;91m" // Red 33 | #define EthGreenBold "\x1b[1;32m" // Green 34 | #define EthLimeBold "\x1b[1;92m" // Green 35 | #define EthOrangeBold "\x1b[1;33m" // Yellow 36 | #define EthYellowBold "\x1b[1;93m" // Yellow 37 | #define EthNavyBold "\x1b[1;34m" // Blue 38 | #define EthBlueBold "\x1b[1;94m" // Blue 39 | #define EthVioletBold "\x1b[1;35m" // Purple 40 | #define EthPurpleBold "\x1b[1;95m" // Purple 41 | #define EthTealBold "\x1b[1;36m" // Cyan 42 | #define EthCyanBold "\x1b[1;96m" // Cyan 43 | 44 | // Background 45 | #define EthOnBlack "\x1b[40m" // Black 46 | #define EthOnCoal "\x1b[100m" // Black 47 | #define EthOnGray "\x1b[47m" // White 48 | #define EthOnWhite "\x1b[107m" // White 49 | #define EthOnMaroon "\x1b[41m" // Red 50 | #define EthOnRed "\x1b[101m" // Red 51 | #define EthOnGreen "\x1b[42m" // Green 52 | #define EthOnLime "\x1b[102m" // Green 53 | #define EthOnOrange "\x1b[43m" // Yellow 54 | #define EthOnYellow "\x1b[103m" // Yellow 55 | #define EthOnNavy "\x1b[44m" // Blue 56 | #define EthOnBlue "\x1b[104m" // Blue 57 | #define EthOnViolet "\x1b[45m" // Purple 58 | #define EthOnPurple "\x1b[105m" // Purple 59 | #define EthOnTeal "\x1b[46m" // Cyan 60 | #define EthOnCyan "\x1b[106m" // Cyan 61 | 62 | // Underline 63 | #define EthBlackUnder "\x1b[4;30m" // Black 64 | #define EthGrayUnder "\x1b[4;37m" // White 65 | #define EthMaroonUnder "\x1b[4;31m" // Red 66 | #define EthGreenUnder "\x1b[4;32m" // Green 67 | #define EthOrangeUnder "\x1b[4;33m" // Yellow 68 | #define EthNavyUnder "\x1b[4;34m" // Blue 69 | #define EthVioletUnder "\x1b[4;35m" // Purple 70 | #define EthTealUnder "\x1b[4;36m" // Cyan 71 | 72 | } // namespace con 73 | 74 | } // namespace dev 75 | -------------------------------------------------------------------------------- /libethash-cl/bin2h.cmake: -------------------------------------------------------------------------------- 1 | # https://gist.github.com/sivachandran/3a0de157dccef822a230 2 | include(CMakeParseArguments) 3 | 4 | # Function to wrap a given string into multiple lines at the given column position. 5 | # Parameters: 6 | # VARIABLE - The name of the CMake variable holding the string. 7 | # AT_COLUMN - The column position at which string will be wrapped. 8 | function(WRAP_STRING) 9 | set(oneValueArgs VARIABLE AT_COLUMN) 10 | cmake_parse_arguments(WRAP_STRING "${options}" "${oneValueArgs}" "" ${ARGN}) 11 | 12 | string(LENGTH ${${WRAP_STRING_VARIABLE}} stringLength) 13 | math(EXPR offset "0") 14 | 15 | while(stringLength GREATER 0) 16 | 17 | if(stringLength GREATER ${WRAP_STRING_AT_COLUMN}) 18 | math(EXPR length "${WRAP_STRING_AT_COLUMN}") 19 | else() 20 | math(EXPR length "${stringLength}") 21 | endif() 22 | 23 | string(SUBSTRING ${${WRAP_STRING_VARIABLE}} ${offset} ${length} line) 24 | set(lines "${lines}\n${line}") 25 | 26 | math(EXPR stringLength "${stringLength} - ${length}") 27 | math(EXPR offset "${offset} + ${length}") 28 | endwhile() 29 | 30 | set(${WRAP_STRING_VARIABLE} "${lines}" PARENT_SCOPE) 31 | endfunction() 32 | 33 | # Script to embed contents of a file as byte array in C/C++ header file(.h). The header file 34 | # will contain a byte array and integer variable holding the size of the array. 35 | # Parameters 36 | # SOURCE_FILE - The path of source file whose contents will be embedded in the header file. 37 | # VARIABLE_NAME - The name of the variable for the byte array. The string "_SIZE" will be append 38 | # to this name and will be used a variable name for size variable. 39 | # HEADER_FILE - The path of header file. 40 | # APPEND - If specified appends to the header file instead of overwriting it 41 | # NULL_TERMINATE - If specified a null byte(zero) will be append to the byte array. This will be 42 | # useful if the source file is a text file and we want to use the file contents 43 | # as string. But the size variable holds size of the byte array without this 44 | # null byte. 45 | set(options APPEND NULL_TERMINATE) 46 | set(oneValueArgs SOURCE_FILE VARIABLE_NAME HEADER_FILE) 47 | # cmake_parse_arguments(BIN2H "${options}" "${oneValueArgs}" "" ${ARGN}) 48 | 49 | # reads source file contents as hex string 50 | file(READ ${BIN2H_SOURCE_FILE} hexString HEX) 51 | 52 | # wraps the hex string into multiple lines at column 32(i.e. 16 bytes per line) 53 | wrap_string(VARIABLE hexString AT_COLUMN 32) 54 | 55 | # adds '0x' prefix and comma suffix before and after every byte respectively 56 | string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " arrayValues ${hexString}) 57 | # removes trailing comma 58 | string(REGEX REPLACE ", $" "" arrayValues ${arrayValues}) 59 | 60 | # declares byte array and the length variables 61 | set(arrayDefinition "static const char ${BIN2H_VARIABLE_NAME}[] = {${arrayValues}\n};\n") 62 | file(WRITE ${BIN2H_HEADER_FILE} "${arrayDefinition}") 63 | -------------------------------------------------------------------------------- /libapicore/ApiServer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace dev; 16 | using namespace dev::eth; 17 | using namespace std::chrono; 18 | 19 | using boost::asio::ip::tcp; 20 | 21 | class ApiConnection 22 | { 23 | public: 24 | 25 | ApiConnection(boost::asio::io_context::strand& _strand, int id, bool readonly, string password); 26 | 27 | ~ApiConnection() = default; 28 | 29 | void start(); 30 | 31 | Json::Value getMinerStat1(); 32 | 33 | using Disconnected = std::function; 34 | void onDisconnected(Disconnected const& _handler) { m_onDisconnected = _handler; } 35 | 36 | int getId() { return m_sessionId; } 37 | 38 | tcp::socket& socket() { return m_socket; } 39 | 40 | private: 41 | void disconnect(); 42 | void processRequest(Json::Value& jRequest, Json::Value& jResponse); 43 | void recvSocketData(); 44 | void onRecvSocketDataCompleted( 45 | const boost::system::error_code& ec, std::size_t bytes_transferred); 46 | void sendSocketData(Json::Value const& jReq, bool _disconnect = false); 47 | void sendSocketData(std::string const& _s, bool _disconnect = false); 48 | void onSendSocketDataCompleted(const boost::system::error_code& ec, bool _disconnect = false); 49 | 50 | Json::Value getMinerStatDetail(); 51 | Json::Value getMinerStatDetailPerMiner(const TelemetryType& _t, std::shared_ptr _miner); 52 | 53 | std::string getHttpMinerStatDetail(); 54 | 55 | Disconnected m_onDisconnected; 56 | 57 | int m_sessionId; 58 | 59 | tcp::socket m_socket; 60 | boost::asio::io_context::strand& m_io_strand; 61 | boost::asio::streambuf m_sendBuffer; 62 | boost::asio::streambuf m_recvBuffer; 63 | Json::StreamWriterBuilder m_jSwBuilder; 64 | 65 | std::string m_message; // The internal message string buffer 66 | 67 | bool m_readonly = false; 68 | std::string m_password = ""; 69 | 70 | bool m_is_authenticated = true; 71 | }; 72 | 73 | 74 | class ApiServer 75 | { 76 | public: 77 | ApiServer(string address, int portnum, string password); 78 | bool isRunning() { return m_running.load(std::memory_order_relaxed); }; 79 | void start(); 80 | void stop(); 81 | 82 | private: 83 | void begin_accept(); 84 | void handle_accept(std::shared_ptr session, boost::system::error_code ec); 85 | 86 | int lastSessionId = 0; 87 | 88 | std::thread m_workThread; 89 | std::atomic m_readonly = {false}; 90 | std::string m_password = ""; 91 | std::atomic m_running = {false}; 92 | string m_address; 93 | uint16_t m_portnumber; 94 | tcp::acceptor m_acceptor; 95 | boost::asio::io_context::strand m_io_strand; 96 | std::vector> m_sessions; 97 | }; 98 | -------------------------------------------------------------------------------- /libethash-cuda/ethash_cuda_miner_kernel.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "cuda_runtime.h" 9 | 10 | // It is virtually impossible to get more than 11 | // one solution per stream hash calculation 12 | // Leave room for up to 4 results. A power 13 | // of 2 here will yield better CUDA optimization 14 | #define MAX_SEARCH_RESULTS 4U 15 | 16 | struct Search_Result 17 | { 18 | // One word for gid and 8 for mix hash 19 | uint32_t gid; 20 | uint32_t mix[8]; 21 | uint32_t pad[7]; // pad to size power of 2 22 | }; 23 | 24 | struct Search_results 25 | { 26 | Search_Result result[MAX_SEARCH_RESULTS]; 27 | uint32_t count = 0; 28 | }; 29 | 30 | #define ACCESSES 64 31 | #define THREADS_PER_HASH (128 / 16) 32 | 33 | typedef struct 34 | { 35 | uint4 uint4s[32 / sizeof(uint4)]; 36 | } hash32_t; 37 | 38 | typedef union 39 | { 40 | uint32_t words[128 / sizeof(uint32_t)]; 41 | uint2 uint2s[128 / sizeof(uint2)]; 42 | uint4 uint4s[128 / sizeof(uint4)]; 43 | } hash128_t; 44 | 45 | typedef union 46 | { 47 | uint32_t words[64 / sizeof(uint32_t)]; 48 | uint2 uint2s[64 / sizeof(uint2)]; 49 | uint4 uint4s[64 / sizeof(uint4)]; 50 | } hash64_t; 51 | 52 | void set_constants(hash128_t* _dag, uint32_t _dag_size, hash64_t* _light, uint32_t _light_size); 53 | void get_constants(hash128_t** _dag, uint32_t* _dag_size, hash64_t** _light, uint32_t* _light_size); 54 | 55 | void set_header(hash32_t _header); 56 | 57 | void set_target(uint64_t _target); 58 | 59 | void run_ethash_search(uint32_t gridSize, uint32_t blockSize, cudaStream_t stream, 60 | volatile Search_results* g_output, uint64_t start_nonce); 61 | 62 | void ethash_generate_dag(uint64_t dag_size, uint32_t blocks, uint32_t threads, cudaStream_t stream); 63 | 64 | struct cuda_runtime_error : public virtual std::runtime_error 65 | { 66 | cuda_runtime_error(const std::string& msg) : std::runtime_error(msg) {} 67 | }; 68 | 69 | #define CUDA_SAFE_CALL(call) \ 70 | do \ 71 | { \ 72 | cudaError_t err = call; \ 73 | if (cudaSuccess != err) \ 74 | { \ 75 | std::stringstream ss; \ 76 | ss << "CUDA error in func " << __FUNCTION__ << " at line " << __LINE__ << ' ' \ 77 | << cudaGetErrorString(err); \ 78 | throw cuda_runtime_error(ss.str()); \ 79 | } \ 80 | } while (0) 81 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: "{build}" 2 | branches: 3 | only: 4 | - master 5 | - /v\d+\..+/ 6 | - /release.*/ 7 | - appveyor 8 | - hunter 9 | clone_depth: 100 10 | os: "Visual Studio 2017" 11 | environment: 12 | matrix: 13 | - CUDA_VER: "8.0" 14 | - CUDA_VER: "9.1" 15 | - CUDA_VER: "10.0" 16 | HUNTER_CACHE_TOKEN: 17 | secure: VnpF1MH5MEFvUI5MiMMMFlmbDdst+bfom5ZFVgalYPp/SYDhbejjXJm9Dla/IgpC 18 | 19 | cache: 20 | - C:\CUDA\v8.0 -> appveyor.yml 21 | - C:\CUDA\v9.1 -> appveyor.yml 22 | - C:\CUDA\v10.0 -> appveyor.yml 23 | 24 | # Download CUDA Windows installer (local) and extract /compiler/* to /CUDA/vX.0/ zip archive. 25 | install: | 26 | git submodule update --init --recursive 27 | if "%CUDA_VER%" == "8.0" set CUDA_ARCHIVE=cuda_8.0.61_windows-exe 28 | if "%CUDA_VER%" == "9.1" set CUDA_ARCHIVE=cuda_9.1.85_windows 29 | if "%CUDA_VER%" == "10.0" set CUDA_ARCHIVE=cuda_10.0.130_411.31_windows 30 | if NOT EXIST C:\CUDA\v%CUDA_VER% (if "%CUDA_VER%" NEQ "8.0" curl -L https://developer.nvidia.com/compute/cuda/%CUDA_VER%/Prod/local_installers/%CUDA_ARCHIVE% -o %CUDA_ARCHIVE%.exe) 31 | if NOT EXIST C:\CUDA\v%CUDA_VER% (if "%CUDA_VER%" == "8.0" curl -L https://developer.nvidia.com/compute/cuda/8.0/Prod2/local_installers/cuda_8.0.61_windows-exe -o %CUDA_ARCHIVE%.exe) 32 | if NOT EXIST C:\CUDA mkdir C:\CUDA 33 | if NOT EXIST C:\CUDA\v%CUDA_VER% (if "%CUDA_VER%" NEQ "8.0" 7z x %CUDA_ARCHIVE%.exe -oC:\CUDA nvcc/* nvrtc*/*) 34 | if NOT EXIST C:\CUDA\v%CUDA_VER% (if "%CUDA_VER%" == "8.0" 7z x %CUDA_ARCHIVE%.exe -oC:\CUDA compiler/* nvrtc*/*) 35 | if NOT EXIST C:\CUDA\v%CUDA_VER% (if "%CUDA_VER%" NEQ "8.0" rename C:\CUDA\nvcc v%CUDA_VER%) 36 | if NOT EXIST C:\CUDA\v%CUDA_VER% (if "%CUDA_VER%" == "8.0" rename C:\CUDA\compiler v%CUDA_VER%) 37 | 38 | set PATH=C:\Python36-x64;C:\Python36-x64\Scripts;%PATH%;C:\CUDA\v%CUDA_VER%\bin 39 | pip install requests gitpython 40 | nvcc -V 41 | 42 | build_script: 43 | - call "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\Common7\Tools\VsMSBuildCmd.bat" 44 | - set CMAKE_ARGS=-G "Visual Studio 15 2017 Win64" -H. -Bbuild -DETHASHCUDA=ON -DAPICORE=ON -DHUNTER_JOBS_NUMBER=%NUMBER_OF_PROCESSORS% 45 | - if "%CUDA_VER%" NEQ "10.0" set CMAKE_ARGS=%CMAKE_ARGS% -T v140 46 | - cmake %CMAKE_ARGS% 47 | - cmake --build build --config Release --target package 48 | - ps: | 49 | . build/ethminer/buildinfo.ps1 50 | mv build/ethminer.zip build/$env:project_name-$env:project_version-cuda$env:CUDA_VER-$env:system_name-$env:system_processor.zip 51 | 52 | artifacts: 53 | - path: build/ethminer-*.zip 54 | name: ethminer 55 | 56 | deploy: 57 | # Create GitHub release, also set the release name and description. 58 | provider: GitHub 59 | tag: $(appveyor_repo_tag_name) 60 | release: "$(project_name) $(project_version)" 61 | description: "" 62 | force_update: true # Force update in case Travis CI created the release before. 63 | prerelease: $(project_version_is_prerelease) 64 | draft: false 65 | artifact: ethminer 66 | auth_token: 67 | secure: uDRcvbW+9GIyKlZ9guJfWOQ6jg0An6eULg6mEkYgdKn/GVNpYSKvO5oHxP0U8a+e 68 | on: 69 | appveyor_repo_tag: true 70 | -------------------------------------------------------------------------------- /libpoolprotocols/testing/SimulateClient.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "SimulateClient.h" 5 | 6 | using namespace std; 7 | using namespace std::chrono; 8 | using namespace dev; 9 | using namespace eth; 10 | 11 | SimulateClient::SimulateClient(unsigned const& block) : PoolClient(), Worker("sim") 12 | { 13 | m_block = block; 14 | } 15 | 16 | SimulateClient::~SimulateClient() = default; 17 | 18 | void SimulateClient::connect() 19 | { 20 | // Initialize new session 21 | m_connected.store(true, memory_order_relaxed); 22 | m_session = unique_ptr(new Session); 23 | m_session->subscribed.store(true, memory_order_relaxed); 24 | m_session->authorized.store(true, memory_order_relaxed); 25 | 26 | if (m_onConnected) 27 | m_onConnected(); 28 | 29 | // No need to worry about starting again. 30 | // Worker class prevents that 31 | startWorking(); 32 | } 33 | 34 | void SimulateClient::disconnect() 35 | { 36 | cnote << "Simulation results : " << EthWhiteBold << "Max " 37 | << dev::getFormattedHashes((double)hr_max, ScaleSuffix::Add, 6) << " Mean " 38 | << dev::getFormattedHashes((double)hr_mean, ScaleSuffix::Add, 6) << EthReset; 39 | 40 | m_conn->addDuration(m_session->duration()); 41 | m_session = nullptr; 42 | m_connected.store(false, memory_order_relaxed); 43 | 44 | if (m_onDisconnected) 45 | m_onDisconnected(); 46 | } 47 | 48 | void SimulateClient::submitHashrate(uint64_t const& rate, string const& id) 49 | { 50 | (void)rate; 51 | (void)id; 52 | } 53 | 54 | void SimulateClient::submitSolution(const Solution& solution) 55 | { 56 | // This is a fake submission only evaluated locally 57 | std::chrono::steady_clock::time_point submit_start = std::chrono::steady_clock::now(); 58 | bool accepted = 59 | EthashAux::eval(solution.work.epoch, solution.work.header, solution.nonce).value <= 60 | solution.work.boundary; 61 | std::chrono::milliseconds response_delay_ms = 62 | std::chrono::duration_cast( 63 | std::chrono::steady_clock::now() - submit_start); 64 | 65 | if (accepted) 66 | { 67 | if (m_onSolutionAccepted) 68 | m_onSolutionAccepted(response_delay_ms, solution.midx, false); 69 | } 70 | else 71 | { 72 | if (m_onSolutionRejected) 73 | m_onSolutionRejected(response_delay_ms, solution.midx); 74 | } 75 | } 76 | 77 | // Handles all logic here 78 | void SimulateClient::workLoop() 79 | { 80 | m_start_time = std::chrono::steady_clock::now(); 81 | 82 | // apply exponential sliding average 83 | // ref: https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average 84 | 85 | 86 | WorkPackage current; 87 | current.seed = h256::random(); // We don't actually need a real seed as the epoch 88 | // is calculated upon block number (see poolmanager) 89 | current.header = h256::random(); 90 | current.block = m_block; 91 | current.boundary = h256(dev::getTargetFromDiff(1)); 92 | m_onWorkReceived(current); // submit new fake job 93 | 94 | while (m_session) 95 | { 96 | float hr = Farm::f().HashRate(); 97 | hr_max = std::max(hr_max, hr); 98 | hr_mean = hr_alpha * hr_mean + (1.0f - hr_alpha) * hr; 99 | 100 | this_thread::sleep_for(chrono::milliseconds(200)); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /libpoolprotocols/PoolManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "PoolClient.h" 12 | #include "getwork/EthGetworkClient.h" 13 | #include "stratum/EthStratumClient.h" 14 | #include "testing/SimulateClient.h" 15 | 16 | using namespace std; 17 | 18 | namespace dev 19 | { 20 | namespace eth 21 | { 22 | struct PoolSettings 23 | { 24 | std::vector> connections; // List of connection definitions 25 | unsigned getWorkPollInterval = 500; // Interval (ms) between getwork requests 26 | unsigned noWorkTimeout = 180; // If no new jobs in this number of seconds drop connection 27 | unsigned noResponseTimeout = 2; // If no response in this number of seconds drop connection 28 | unsigned poolFailoverTimeout = 0; // Return to primary pool after this number of minutes 29 | bool reportHashrate = false; // Whether or not to report hashrate to pool 30 | unsigned hashRateInterval = 60; // Interval in seconds among hashrate submissions 31 | std::string hashRateId = 32 | h256::random().hex(HexPrefix::Add); // Unique identifier for HashRate submission 33 | unsigned connectionMaxRetries = 3; // Max number of connection retries 34 | unsigned delayBeforeRetry = 0; // Delay seconds before connect retry 35 | unsigned benchmarkBlock = 0; // Block number used by SimulateClient to test performances 36 | }; 37 | 38 | class PoolManager 39 | { 40 | public: 41 | PoolManager(PoolSettings _settings); 42 | static PoolManager& p() { return *m_this; } 43 | void addConnection(std::string _connstring); 44 | void addConnection(std::shared_ptr _uri); 45 | Json::Value getConnectionsJson(); 46 | void setActiveConnection(unsigned int idx); 47 | void setActiveConnection(std::string& _connstring); 48 | std::shared_ptr getActiveConnection(); 49 | void removeConnection(unsigned int idx); 50 | void start(); 51 | void stop(); 52 | bool isConnected() { return p_client->isConnected(); }; 53 | bool isRunning() { return m_running; }; 54 | int getCurrentEpoch(); 55 | double getCurrentDifficulty(); 56 | unsigned getConnectionSwitches(); 57 | unsigned getEpochChanges(); 58 | 59 | private: 60 | void rotateConnect(); 61 | 62 | void setClientHandlers(); 63 | 64 | void showMiningAt(); 65 | 66 | void setActiveConnectionCommon(unsigned int idx); 67 | 68 | PoolSettings m_Settings; 69 | 70 | void failovertimer_elapsed(const boost::system::error_code& ec); 71 | void submithrtimer_elapsed(const boost::system::error_code& ec); 72 | void reconnecttimer_elapsed(const boost::system::error_code& ec); 73 | 74 | std::atomic m_running = {false}; 75 | std::atomic m_stopping = {false}; 76 | std::atomic m_async_pending = {false}; 77 | 78 | unsigned m_connectionAttempt = 0; 79 | 80 | std::string m_selectedHost = ""; // Holds host name (and endpoint) of selected connection 81 | std::atomic m_connectionSwitches = {0}; 82 | 83 | unsigned m_activeConnectionIdx = 0; 84 | 85 | WorkPackage m_currentWp; 86 | 87 | boost::asio::io_context::strand m_io_strand; 88 | boost::asio::deadline_timer m_failovertimer; 89 | boost::asio::deadline_timer m_submithrtimer; 90 | boost::asio::deadline_timer m_reconnecttimer; 91 | 92 | std::unique_ptr p_client = nullptr; 93 | 94 | std::atomic m_epochChanges = {0}; 95 | 96 | static PoolManager* m_this; 97 | }; 98 | 99 | } // namespace eth 100 | } // namespace dev 101 | -------------------------------------------------------------------------------- /libethash-cuda/dagger_shuffled.cuh: -------------------------------------------------------------------------------- 1 | #include "ethash_cuda_miner_kernel_globals.h" 2 | 3 | #include "ethash_cuda_miner_kernel.h" 4 | 5 | #include "cuda_helper.h" 6 | 7 | #define _PARALLEL_HASH 4 8 | 9 | DEV_INLINE bool compute_hash(uint64_t nonce, uint2* mix_hash) 10 | { 11 | // sha3_512(header .. nonce) 12 | uint2 state[12]; 13 | 14 | state[4] = vectorize(nonce); 15 | 16 | keccak_f1600_init(state); 17 | 18 | // Threads work together in this phase in groups of 8. 19 | const int thread_id = threadIdx.x & (THREADS_PER_HASH - 1); 20 | const int mix_idx = thread_id & 3; 21 | 22 | for (int i = 0; i < THREADS_PER_HASH; i += _PARALLEL_HASH) 23 | { 24 | uint4 mix[_PARALLEL_HASH]; 25 | uint32_t offset[_PARALLEL_HASH]; 26 | uint32_t init0[_PARALLEL_HASH]; 27 | 28 | // share init among threads 29 | for (int p = 0; p < _PARALLEL_HASH; p++) 30 | { 31 | uint2 shuffle[8]; 32 | for (int j = 0; j < 8; j++) 33 | { 34 | shuffle[j].x = SHFL(state[j].x, i + p, THREADS_PER_HASH); 35 | shuffle[j].y = SHFL(state[j].y, i + p, THREADS_PER_HASH); 36 | } 37 | switch (mix_idx) 38 | { 39 | case 0: 40 | mix[p] = vectorize2(shuffle[0], shuffle[1]); 41 | break; 42 | case 1: 43 | mix[p] = vectorize2(shuffle[2], shuffle[3]); 44 | break; 45 | case 2: 46 | mix[p] = vectorize2(shuffle[4], shuffle[5]); 47 | break; 48 | case 3: 49 | mix[p] = vectorize2(shuffle[6], shuffle[7]); 50 | break; 51 | } 52 | init0[p] = SHFL(shuffle[0].x, 0, THREADS_PER_HASH); 53 | } 54 | 55 | for (uint32_t a = 0; a < ACCESSES; a += 4) 56 | { 57 | int t = bfe(a, 2u, 3u); 58 | 59 | for (uint32_t b = 0; b < 4; b++) 60 | { 61 | for (int p = 0; p < _PARALLEL_HASH; p++) 62 | { 63 | offset[p] = fnv(init0[p] ^ (a + b), ((uint32_t*)&mix[p])[b]) % d_dag_size; 64 | offset[p] = SHFL(offset[p], t, THREADS_PER_HASH); 65 | mix[p] = fnv4(mix[p], d_dag[offset[p]].uint4s[thread_id]); 66 | } 67 | } 68 | } 69 | 70 | for (int p = 0; p < _PARALLEL_HASH; p++) 71 | { 72 | uint2 shuffle[4]; 73 | uint32_t thread_mix = fnv_reduce(mix[p]); 74 | 75 | // update mix across threads 76 | shuffle[0].x = SHFL(thread_mix, 0, THREADS_PER_HASH); 77 | shuffle[0].y = SHFL(thread_mix, 1, THREADS_PER_HASH); 78 | shuffle[1].x = SHFL(thread_mix, 2, THREADS_PER_HASH); 79 | shuffle[1].y = SHFL(thread_mix, 3, THREADS_PER_HASH); 80 | shuffle[2].x = SHFL(thread_mix, 4, THREADS_PER_HASH); 81 | shuffle[2].y = SHFL(thread_mix, 5, THREADS_PER_HASH); 82 | shuffle[3].x = SHFL(thread_mix, 6, THREADS_PER_HASH); 83 | shuffle[3].y = SHFL(thread_mix, 7, THREADS_PER_HASH); 84 | 85 | if ((i + p) == thread_id) 86 | { 87 | // move mix into state: 88 | state[8] = shuffle[0]; 89 | state[9] = shuffle[1]; 90 | state[10] = shuffle[2]; 91 | state[11] = shuffle[3]; 92 | } 93 | } 94 | } 95 | 96 | // keccak_256(keccak_512(header..nonce) .. mix); 97 | if (cuda_swab64(keccak_f1600_final(state)) > d_target) 98 | return true; 99 | 100 | mix_hash[0] = state[8]; 101 | mix_hash[1] = state[9]; 102 | mix_hash[2] = state[10]; 103 | mix_hash[3] = state[11]; 104 | 105 | return false; 106 | } 107 | -------------------------------------------------------------------------------- /libdevcore/Log.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | 18 | #include "Log.h" 19 | 20 | #include 21 | #include 22 | 23 | #ifdef __APPLE__ 24 | #include 25 | #endif 26 | 27 | #include "Guards.h" 28 | 29 | using namespace std; 30 | using namespace dev; 31 | 32 | //⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙ 33 | 34 | // Logging 35 | unsigned g_logOptions = 0; 36 | bool g_logNoColor = false; 37 | bool g_logSyslog = false; 38 | bool g_logStdout = false; 39 | 40 | const char* LogChannel::name() 41 | { 42 | return EthGray ".."; 43 | } 44 | const char* WarnChannel::name() 45 | { 46 | return EthRed " X"; 47 | } 48 | const char* NoteChannel::name() 49 | { 50 | return EthBlue " i"; 51 | } 52 | 53 | LogOutputStreamBase::LogOutputStreamBase(char const* _id) 54 | { 55 | static std::locale logLocl = std::locale(""); 56 | m_sstr.imbue(logLocl); 57 | if (g_logSyslog) 58 | m_sstr << std::left << std::setw(8) << getThreadName() << " " EthReset; 59 | else 60 | { 61 | time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); 62 | char buf[24]; 63 | if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0) 64 | buf[0] = '\0'; // empty if case strftime fails 65 | m_sstr << _id << " " EthViolet << buf << " " EthBlue << std::left << std::setw(8) 66 | << getThreadName() << " " EthReset; 67 | } 68 | } 69 | 70 | /// Associate a name with each thread for nice logging. 71 | struct ThreadLocalLogName 72 | { 73 | ThreadLocalLogName(char const* _name) { name = _name; } 74 | thread_local static char const* name; 75 | }; 76 | 77 | thread_local char const* ThreadLocalLogName::name; 78 | 79 | ThreadLocalLogName g_logThreadName("main"); 80 | 81 | string dev::getThreadName() 82 | { 83 | #if defined(__linux__) || defined(__APPLE__) 84 | char buffer[128]; 85 | pthread_getname_np(pthread_self(), buffer, 127); 86 | buffer[127] = 0; 87 | return buffer; 88 | #else 89 | return ThreadLocalLogName::name ? ThreadLocalLogName::name : ""; 90 | #endif 91 | } 92 | 93 | void dev::setThreadName(char const* _n) 94 | { 95 | #if defined(__linux__) 96 | pthread_setname_np(pthread_self(), _n); 97 | #elif defined(__APPLE__) 98 | pthread_setname_np(_n); 99 | #else 100 | ThreadLocalLogName::name = _n; 101 | #endif 102 | } 103 | 104 | void dev::simpleDebugOut(std::string const& _s) 105 | { 106 | try 107 | { 108 | std::ostream& os = g_logStdout ? std::cout : std::clog; 109 | if (!g_logNoColor) 110 | { 111 | os << _s + '\n'; 112 | os.flush(); 113 | return; 114 | } 115 | bool skip = false; 116 | std::stringstream ss; 117 | for (auto it : _s) 118 | { 119 | if (!skip && it == '\x1b') 120 | skip = true; 121 | else if (skip && it == 'm') 122 | skip = false; 123 | else if (!skip) 124 | ss << it; 125 | } 126 | ss << '\n'; 127 | os << ss.str(); 128 | os.flush(); 129 | } 130 | catch (...) 131 | { 132 | return; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /libhwmon/wrapnvml.h: -------------------------------------------------------------------------------- 1 | /* 2 | * A trivial little dlopen()-based wrapper library for the 3 | * NVIDIA NVML library, to allow runtime discovery of NVML on an 4 | * arbitrary system. This is all very hackish and simple-minded, but 5 | * it serves my immediate needs in the short term until NVIDIA provides 6 | * a static NVML wrapper library themselves, hopefully in 7 | * CUDA 6.5 or maybe sometime shortly after. 8 | * 9 | * This trivial code is made available under the "new" 3-clause BSD license, 10 | * and/or any of the GPL licenses you prefer. 11 | * Feel free to use the code and modify as you see fit. 12 | * 13 | * John E. Stone - john.stone@gmail.com 14 | * 15 | */ 16 | 17 | #pragma once 18 | 19 | #include "wraphelper.h" 20 | 21 | #if defined(__cplusplus) 22 | extern "C" { 23 | #endif 24 | 25 | /* 26 | * Ugly hacks to avoid dependencies on the real nvml.h until it starts 27 | * getting included with the CUDA toolkit or a GDK that's got a known 28 | * install location, etc. 29 | */ 30 | typedef enum wrap_nvmlReturn_enum { WRAPNVML_SUCCESS = 0 } wrap_nvmlReturn_t; 31 | 32 | typedef void* wrap_nvmlDevice_t; 33 | 34 | /* our own version of the PCI info struct */ 35 | typedef struct 36 | { 37 | char bus_id_str[16]; /* string form of bus info */ 38 | unsigned int domain; 39 | unsigned int bus; 40 | unsigned int device; 41 | unsigned int pci_device_id; /* combined device and vendor id */ 42 | unsigned int pci_subsystem_id; 43 | unsigned int res0; /* NVML internal use only */ 44 | unsigned int res1; 45 | unsigned int res2; 46 | unsigned int res3; 47 | } wrap_nvmlPciInfo_t; 48 | 49 | 50 | /* 51 | * Handle to hold the function pointers for the entry points we need, 52 | * and the shared library itself. 53 | */ 54 | typedef struct 55 | { 56 | void* nvml_dll; 57 | int nvml_gpucount; 58 | unsigned int* nvml_pci_domain_id; 59 | unsigned int* nvml_pci_bus_id; 60 | unsigned int* nvml_pci_device_id; 61 | wrap_nvmlDevice_t* devs; 62 | wrap_nvmlReturn_t (*nvmlInit)(void); 63 | wrap_nvmlReturn_t (*nvmlDeviceGetCount)(int*); 64 | wrap_nvmlReturn_t (*nvmlDeviceGetHandleByIndex)(int, wrap_nvmlDevice_t*); 65 | wrap_nvmlReturn_t (*nvmlDeviceGetPciInfo)(wrap_nvmlDevice_t, wrap_nvmlPciInfo_t*); 66 | wrap_nvmlReturn_t (*nvmlDeviceGetName)(wrap_nvmlDevice_t, char*, int); 67 | wrap_nvmlReturn_t (*nvmlDeviceGetTemperature)(wrap_nvmlDevice_t, int, unsigned int*); 68 | wrap_nvmlReturn_t (*nvmlDeviceGetFanSpeed)(wrap_nvmlDevice_t, unsigned int*); 69 | wrap_nvmlReturn_t (*nvmlDeviceGetPowerUsage)(wrap_nvmlDevice_t, unsigned int*); 70 | wrap_nvmlReturn_t (*nvmlShutdown)(void); 71 | } wrap_nvml_handle; 72 | 73 | 74 | wrap_nvml_handle* wrap_nvml_create(); 75 | int wrap_nvml_destroy(wrap_nvml_handle* nvmlh); 76 | 77 | /* 78 | * Query the number of GPUs seen by NVML 79 | */ 80 | int wrap_nvml_get_gpucount(wrap_nvml_handle* nvmlh, int* gpucount); 81 | 82 | /* 83 | * query the name of the GPU model from the CUDA device ID 84 | * 85 | */ 86 | int wrap_nvml_get_gpu_name(wrap_nvml_handle* nvmlh, int gpuindex, char* namebuf, int bufsize); 87 | 88 | /* 89 | * Query the current GPU temperature (Celsius), from the CUDA device ID 90 | */ 91 | int wrap_nvml_get_tempC(wrap_nvml_handle* nvmlh, int gpuindex, unsigned int* tempC); 92 | 93 | /* 94 | * Query the current GPU fan speed (percent) from the CUDA device ID 95 | */ 96 | int wrap_nvml_get_fanpcnt(wrap_nvml_handle* nvmlh, int gpuindex, unsigned int* fanpcnt); 97 | 98 | /* 99 | * Query the current GPU power usage in milliwatts from the CUDA device ID 100 | * 101 | * This feature is only available on recent GPU generations and may be 102 | * limited in some cases only to Tesla series GPUs. 103 | * If the query is run on an unsupported GPU, this routine will return -1. 104 | */ 105 | int wrap_nvml_get_power_usage(wrap_nvml_handle* nvmlh, int gpuindex, unsigned int* milliwatts); 106 | 107 | 108 | #if defined(__cplusplus) 109 | } 110 | #endif 111 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). 6 | 7 | ## [0.19.0] - 2020-08-03 8 | 9 | ## [0.18.0] - 2019-07-23 10 | 11 | ## [0.17.1] - 2019-02-28 12 | 13 | - Fixed [[#1843](https://github.com/ethereum-mining/ethminer/pull/1843)]: 14 | Issue with using latest Nvidia drivers on Windows resolved. 15 | 16 | ## 0.16.1rc0 17 | 18 | ### Fixed 19 | 20 | - Display interval correction [#1606](https://github.com/ethereum-mining/ethminer/pull/1606) 21 | 22 | ## 0.16.0rc0 23 | 24 | ### Fixed 25 | 26 | - Eliminated duplicate solutions with stratum2 on difficulty changes. 27 | - Restored proper behavior of `-P` argument to identify workernames and emails 28 | 29 | ### Added 30 | 31 | - Basic API authentication to protect exposure of API port to the internet [#1228](https://github.com/ethereum-mining/ethminer/pull/1228). 32 | - Add `ispaused` information into response of `miner_getstathr` API query [#1232](https://github.com/ethereum-mining/ethminer/pull/1232). 33 | - API responses return "ethminer-" as version prefix. [#1300](https://github.com/ethereum-mining/ethminer/pull/1300). 34 | - Stratum mode autodetection. No need to specify `stratum+tcp` or `stratum1+tcp` or `stratum2+tcp` 35 | - Connection failed due to login errors (wrong address or worker) are marked Unrecoverable and no longer used 36 | - Replaced OpenCL kernel with opensource jawawawa OpenCL kernel 37 | - Added support for jawawawa AMD binary kernels 38 | - AMD auto kernel selection. Try bin first, if not fall back to OpenCL. 39 | - API: New method `miner_setverbosity`. [#1382](https://github.com/ethereum-mining/ethminer/pull/1382). 40 | - Implemented fast job switch algorithm on AMD reducing switch time to 1-2 milliseconds. 41 | - Added localization support for output number formatting. 42 | - Changed the --verbosity option to allow individual enable/disable of logging features. 43 | - Improved hash rate measurement accuracy. 44 | 45 | ### Removed 46 | 47 | - Command line argument `--stratum-email`: any information needed to authenticate on the pool **MUST BE** set using the `-P` argument 48 | 49 | ## 0.15.0rc1 50 | 51 | ### Fixed 52 | 53 | - Restore the ability to auto-config OpenCL work size [#1225](https://github.com/ethereum-mining/ethminer/pull/1225). 54 | - The API server totally broken fixed [#1227](https://github.com/ethereum-mining/ethminer/pull/1227). 55 | 56 | 57 | ## 0.15.0rc0 58 | 59 | ### Added 60 | 61 | - Add `--tstop` and `--tstart` option preventing GPU overheating [#1146](https://github.com/ethereum-mining/ethminer/pull/1146), [#1159](https://github.com/ethereum-mining/ethminer/pull/1159). 62 | - Added information about ordering CUDA devices in the README.md FAQ [#1162](https://github.com/ethereum-mining/ethminer/pull/1162). 63 | 64 | ### Fixed 65 | 66 | - Reconnecting with mining pool improved [#1135](https://github.com/ethereum-mining/ethminer/pull/1135). 67 | - Stratum nicehash. Avoid recalculating target with every job [#1156](https://github.com/ethereum-mining/ethminer/pull/1156). 68 | - Drop duplicate stratum jobs (pool bug workaround) [#1161](https://github.com/ethereum-mining/ethminer/pull/1161). 69 | - CLI11 command line parsing support added [#1160](https://github.com/ethereum-mining/ethminer/pull/1160). 70 | - Farm mode (get_work): fixed loss of valid shares and increment in stales [#1215](https://github.com/ethereum-mining/ethminer/pull/1215). 71 | - Stratum implementation improvements [#1222](https://github.com/ethereum-mining/ethminer/pull/1222). 72 | - Build fixes & improvements [#1214](https://github.com/ethereum-mining/ethminer/pull/1214). 73 | 74 | ### Removed 75 | 76 | - Disabled Debug configuration for Visual Studio [#69](https://github.com/ethereum-mining/ethminer/issues/69) [#1131](https://github.com/ethereum-mining/ethminer/pull/1131). 77 | 78 | 79 | [0.19.0]: https://github.com/ethereum-mining/ethminer/releases/tag/v0.19.0 80 | [0.18.0]: https://github.com/ethereum-mining/ethminer/releases/tag/v0.18.0 81 | [0.17.1]: https://github.com/ethereum-mining/ethminer/releases/tag/v0.17.1 82 | -------------------------------------------------------------------------------- /libdevcore/Log.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | /** @file Log.h 18 | * @author Gav Wood 19 | * @date 2014 20 | * 21 | * The logging subsystem. 22 | */ 23 | 24 | #pragma once 25 | 26 | #include 27 | #include 28 | 29 | #include "Common.h" 30 | #include "CommonData.h" 31 | #include "FixedHash.h" 32 | #include "Terminal.h" 33 | #include "vector_ref.h" 34 | 35 | /// The logging system's current verbosity. 36 | #define LOG_JSON 1 37 | #define LOG_PER_GPU 2 38 | #define LOG_CONNECT 32 39 | #define LOG_SWITCH 64 40 | #define LOG_SUBMIT 128 41 | #define LOG_PROGRAMFLOW 256 42 | #define LOG_NEXT 512 43 | 44 | #if DEV_BUILD 45 | #define DEV_BUILD_LOG_PROGRAMFLOW(_S, _V) \ 46 | if (g_logOptions & LOG_PROGRAMFLOW) \ 47 | { \ 48 | _S << _V; \ 49 | } \ 50 | ((void)(0)) 51 | #else 52 | #define DEV_BUILD_LOG_PROGRAMFLOW(_S, _V) ((void)(0)) 53 | #endif 54 | 55 | extern unsigned g_logOptions; 56 | extern bool g_logNoColor; 57 | extern bool g_logSyslog; 58 | extern bool g_logStdout; 59 | 60 | namespace dev 61 | { 62 | /// A simple log-output function that prints log messages to stdout. 63 | void simpleDebugOut(std::string const&); 64 | 65 | /// Set the current thread's log name. 66 | void setThreadName(char const* _n); 67 | 68 | /// Set the current thread's log name. 69 | std::string getThreadName(); 70 | 71 | /// The default logging channels. Each has an associated verbosity and three-letter prefix (name() 72 | /// ). Channels should inherit from LogChannel and define name() and verbosity. 73 | struct LogChannel 74 | { 75 | static const char* name(); 76 | }; 77 | struct WarnChannel : public LogChannel 78 | { 79 | static const char* name(); 80 | }; 81 | struct NoteChannel : public LogChannel 82 | { 83 | static const char* name(); 84 | }; 85 | 86 | class LogOutputStreamBase 87 | { 88 | public: 89 | LogOutputStreamBase(char const* _id); 90 | 91 | template 92 | void append(T const& _t) 93 | { 94 | m_sstr << _t; 95 | } 96 | 97 | protected: 98 | std::stringstream m_sstr; ///< The accrued log entry. 99 | }; 100 | 101 | /// Logging class, iostream-like, that can be shifted to. 102 | template 103 | class LogOutputStream : LogOutputStreamBase 104 | { 105 | public: 106 | /// Construct a new object. 107 | /// If _term is true the the prefix info is terminated with a ']' character; if not it ends only 108 | /// with a '|' character. 109 | LogOutputStream() : LogOutputStreamBase(Id::name()) {} 110 | 111 | /// Destructor. Posts the accrued log entry to the g_logPost function. 112 | ~LogOutputStream() { simpleDebugOut(m_sstr.str()); } 113 | 114 | /// Shift arbitrary data to the log. Spaces will be added between items as required. 115 | template 116 | LogOutputStream& operator<<(T const& _t) 117 | { 118 | append(_t); 119 | return *this; 120 | } 121 | }; 122 | 123 | #define clog(X) dev::LogOutputStream() 124 | 125 | // Simple cout-like stream objects for accessing common log channels. 126 | // Dirties the global namespace, but oh so convenient... 127 | #define cnote clog(dev::NoteChannel) 128 | #define cwarn clog(dev::WarnChannel) 129 | 130 | } // namespace dev 131 | -------------------------------------------------------------------------------- /libpoolprotocols/PoolURI.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | // A simple URI parser specifically for mining pool endpoints 28 | namespace dev 29 | { 30 | enum class SecureLevel 31 | { 32 | NONE = 0, 33 | TLS12, 34 | TLS 35 | }; 36 | 37 | enum class ProtocolFamily 38 | { 39 | GETWORK = 0, 40 | STRATUM, 41 | SIMULATION 42 | }; 43 | 44 | enum class UriHostNameType 45 | { 46 | Unknown = 0, // The type of the host name is not supplied 47 | Basic = 1, // The host is set, but the type cannot be determined 48 | Dns = 2, // The host name is a domain name system(DNS) style host name 49 | IPV4 = 3, // The host name is an Internet Protocol(IP) version 4 host address 50 | IPV6 = 4 // The host name is an Internet Protocol(IP) version 6 host address. 51 | }; 52 | 53 | class URI 54 | { 55 | public: 56 | URI() = delete; 57 | URI(std::string uri, bool _sim = false); 58 | 59 | std::string Scheme() const { return m_scheme; } 60 | std::string Host() const { return m_host; } 61 | std::string Path() const { return m_path; } 62 | unsigned short Port() const { return m_port; } 63 | std::string User() const { return m_user; } 64 | std::string Pass() const { return m_password; } 65 | std::string Workername() const { return m_worker; } 66 | std::string UserDotWorker() const; 67 | SecureLevel SecLevel() const; 68 | ProtocolFamily Family() const; 69 | UriHostNameType HostNameType() const; 70 | bool IsLoopBack() const; 71 | unsigned Version() const; 72 | std::string str() const { return m_uri; } 73 | 74 | static std::string KnownSchemes(ProtocolFamily family); 75 | 76 | void SetStratumMode(unsigned mode, bool confirmed) 77 | { 78 | m_stratumMode = mode; 79 | m_stratumModeConfirmed = confirmed; 80 | } 81 | void SetStratumMode(unsigned mode) { m_stratumMode = mode; } 82 | unsigned StratumMode() { return m_stratumMode; } 83 | bool StratumModeConfirmed() { return m_stratumModeConfirmed; } 84 | bool IsUnrecoverable() { return m_unrecoverable; } 85 | void MarkUnrecoverable() { m_unrecoverable = true; } 86 | 87 | bool Responds() { return m_responds; } 88 | void Responds(bool _value) { m_responds = _value; } 89 | 90 | void addDuration(unsigned long _minutes) { m_totalDuration += _minutes; } 91 | unsigned long getDuration() { return m_totalDuration; } 92 | 93 | private: 94 | std::string m_scheme; 95 | std::string m_authority; // Contains all text after scheme 96 | std::string m_userinfo; // Contains the userinfo part 97 | std::string m_urlinfo; // Contains the urlinfo part 98 | std::string m_hostinfo; // Contains the hostinfo part 99 | std::string m_pathinfo; // Contains the pathinfo part 100 | 101 | std::string m_host; 102 | std::string m_path; 103 | std::string m_query; 104 | std::string m_fragment; 105 | std::string m_user; 106 | std::string m_password = "X"; 107 | std::string m_worker; 108 | std::string m_uri; 109 | 110 | unsigned short m_stratumMode = 999; // Initial value 999 means not tested yet 111 | unsigned short m_port = 0; 112 | bool m_stratumModeConfirmed = false; 113 | bool m_unrecoverable = false; 114 | bool m_responds = false; 115 | 116 | UriHostNameType m_hostType = UriHostNameType::Unknown; 117 | bool m_isLoopBack; 118 | 119 | unsigned long m_totalDuration; // Total duration on this connection in minutes 120 | 121 | }; 122 | } // namespace dev 123 | -------------------------------------------------------------------------------- /libpoolprotocols/PoolClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | extern boost::asio::io_service g_io_service; 11 | 12 | using namespace std; 13 | 14 | namespace dev 15 | { 16 | namespace eth 17 | { 18 | struct Session 19 | { 20 | // Tstamp of sessio start 21 | chrono::steady_clock::time_point start = chrono::steady_clock::now(); 22 | // Whether or not worker is subscribed 23 | atomic subscribed = {false}; 24 | // Whether or not worker is authorized 25 | atomic authorized = {false}; 26 | // Total duration of session in minutes 27 | unsigned long duration() 28 | { 29 | return (chrono::duration_cast(chrono::steady_clock::now() - start)) 30 | .count(); 31 | } 32 | 33 | // EthereumStratum (1 and 2) 34 | 35 | // Extranonce currently active 36 | uint64_t extraNonce = 0; 37 | // Length of extranonce in bytes 38 | unsigned int extraNonceSizeBytes = 0; 39 | // Next work target 40 | h256 nextWorkBoundary = 41 | h256("0x00000000ffff0000000000000000000000000000000000000000000000000000"); 42 | 43 | // EthereumStratum (2 only) 44 | bool firstMiningSet = false; 45 | unsigned int timeout = 30; // Default to 30 seconds 46 | string sessionId = ""; 47 | string workerId = ""; 48 | string algo = "ethash"; 49 | unsigned int epoch = 0; 50 | chrono::steady_clock::time_point lastTxStamp = chrono::steady_clock::now(); 51 | 52 | }; 53 | 54 | class PoolClient 55 | { 56 | public: 57 | virtual ~PoolClient() noexcept = default; 58 | 59 | // Sets the connection definition to be used by the client 60 | void setConnection(std::shared_ptr _conn) 61 | { 62 | m_conn = _conn; 63 | m_conn->Responds(false); 64 | } 65 | 66 | // Gets a pointer to the currently active connection definition 67 | std::shared_ptr getConnection() { return m_conn; } 68 | 69 | // Releases the pointer to the connection definition 70 | void unsetConnection() { m_conn = nullptr; } 71 | 72 | virtual void connect() = 0; 73 | virtual void disconnect() = 0; 74 | virtual void submitHashrate(uint64_t const& rate, string const& id) = 0; 75 | virtual void submitSolution(const Solution& solution) = 0; 76 | virtual bool isConnected() { return m_connected.load(memory_order_relaxed); } 77 | virtual bool isPendingState() { return false; } 78 | 79 | virtual bool isSubscribed() 80 | { 81 | return (m_session ? m_session->subscribed.load(memory_order_relaxed) : false); 82 | } 83 | virtual bool isAuthorized() 84 | { 85 | return (m_session ? m_session->authorized.load(memory_order_relaxed) : false); 86 | } 87 | 88 | virtual string ActiveEndPoint() 89 | { 90 | return (m_connected.load(memory_order_relaxed) ? " [" + toString(m_endpoint) + "]" : ""); 91 | } 92 | 93 | using SolutionAccepted = function; 94 | using SolutionRejected = function; 95 | using Disconnected = function; 96 | using Connected = function; 97 | using WorkReceived = function; 98 | 99 | void onSolutionAccepted(SolutionAccepted const& _handler) { m_onSolutionAccepted = _handler; } 100 | void onSolutionRejected(SolutionRejected const& _handler) { m_onSolutionRejected = _handler; } 101 | void onDisconnected(Disconnected const& _handler) { m_onDisconnected = _handler; } 102 | void onConnected(Connected const& _handler) { m_onConnected = _handler; } 103 | void onWorkReceived(WorkReceived const& _handler) { m_onWorkReceived = _handler; } 104 | 105 | protected: 106 | unique_ptr m_session = nullptr; 107 | 108 | std::atomic m_connected = {false}; // This is related to socket ! Not session 109 | 110 | boost::asio::ip::basic_endpoint m_endpoint; 111 | 112 | std::shared_ptr m_conn = nullptr; 113 | 114 | SolutionAccepted m_onSolutionAccepted; 115 | SolutionRejected m_onSolutionRejected; 116 | Disconnected m_onDisconnected; 117 | Connected m_onConnected; 118 | WorkReceived m_onWorkReceived; 119 | }; 120 | } // namespace eth 121 | } // namespace dev 122 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | env: 3 | global: 4 | - secure: "Pu2hPyp3Ym3hmkW9iXVZObfE7tA3ITSaeR05VguJ9czJAMgaT7LmEN4LDoR2sQHbRAv+8QngbNUFpglzvZLIBIEefyEA39DThZptkKJ+hCUerRajfmXywSXCwPC7A1uTEY1YoUDlGvxVZA3Z7f17GFtKtDuHjLSWmrxHAM6wjK+qCweEq0umJJ+N+2DX2UpVLlWgYoknYSGipfjHRBEgPp4NRh08yvpDTFYSVQeL0qL7LbyAtkx6qhLCK6JZ2CsP3INQOoRwc8jP6VIFbuoHl3lkOzayNM49/e9wDdZ8FGqp0HjUFi7EYi/78Uvje7CrgdCiSVwoHbtAvcyPYcxu+qXzwh4AxslRL7UJtOzTbRaXfJvqt2oqtttFjD0Dk/iwnAthg7Su6UohivcUVj/9p1X1KdDbLJcoTag/MBcZP7VJDgnHjyqYwVciT1ZV0RWfuLBI584vFMTlsdzFXt384mUTCN02BOnRnw3Miq4a5irFXnDy23TdGersk7b//FPIBIhPv/wxCjUkJzTmt7ska5jACb/FHUoOyrE5mQLSVZbh/zlsIKf8yWZy7q7caowmwyPYZtAqNZWj1JmVs2c+0RmX2c76kCTHX4ocCcDx1QqV49/+R1Ah+pA7X7kcr9MklzL9z/lkAA7z5SF/UzdoGfBNicMKz5hUFixBqZ04ATw=" 5 | branches: 6 | only: 7 | - /^v\d+\..+$/ 8 | - master 9 | - ci 10 | - travis 11 | - hunter 12 | - coverity 13 | - /^release.*$/ 14 | matrix: 15 | include: 16 | - os: linux 17 | dist: trusty 18 | sudo: required 19 | env: 20 | - CUDA=ON 21 | - CUDA_VERSION=9 22 | - os: linux 23 | dist: trusty 24 | sudo: required 25 | env: 26 | - CUDA=ON 27 | - CUDA_VERSION=8 28 | - os: osx 29 | osx_image: xcode9.2 30 | env: 31 | - CUDA=ON 32 | - CUDA_VERSION=9 33 | cache: 34 | directories: 35 | - $HOME/.local 36 | before_install: 37 | - | 38 | if [ "$TRAVIS_OS_NAME" = linux ]; then 39 | echo "Checking format of sourcecode..." 40 | find . -type f \( -name '*.cpp' -o -name '*.h' -o -name '*.cu' -o -name '*.cuh' \) -print0 | xargs -r0 clang-format -i 41 | git diff --color # --exit-code 42 | fi 43 | - | 44 | if [ "$TRAVIS_OS_NAME" = linux ]; then 45 | sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test 46 | sudo apt-get -q update 47 | sudo apt-get -qy install g++-6 48 | scripts/install_cmake.sh 49 | . scripts/install-cuda-ubuntu1604.sh $CUDA_VERSION 50 | pyenv global 3.6 51 | pip install --user requests gitpython 52 | if [ "$CUDA_VERSION" = "8" ]; then 53 | sudo apt-get -qy install g++-5 54 | export CC=gcc-5 55 | export CXX=g++-5 56 | else 57 | export CC=gcc-6 58 | export CXX=g++-6 59 | fi 60 | elif [ "$TRAVIS_OS_NAME" == "osx" ]; then 61 | curl -L https://developer.nvidia.com/compute/cuda/9.1/Prod/local_installers/cuda_9.1.128_mac -o $HOME/cuda_9.1.128_mac.dmg 62 | hdiutil mount $HOME/cuda_9.1.128_mac.dmg 63 | sleep 5 64 | ls -ltr /Volumes/CUDAMacOSXInstaller/CUDAMacOSXInstaller.app/Contents/MacOS 65 | sudo /Volumes/CUDAMacOSXInstaller/CUDAMacOSXInstaller.app/Contents/MacOS/CUDAMacOSXInstaller --accept-eula --no-window; export BREW_STATUS=$? 66 | echo "Brew status $BREW_STATUS" 67 | if [ $BREW_STATUS -ne 0 ]; then 68 | echo "Brew Failed" 69 | exit $BREW_STATUS 70 | fi 71 | HOMEBREW_NO_AUTO_UPDATE=1 brew install -q python3 72 | pip3 install -q requests gitpython 73 | fi 74 | script: | 75 | cmake -DHUNTER_JOBS_NUMBER=4 -DETHASHCUDA=$CUDA -DETHASHCL=ON -DAPICORE=ON -H. -Bbuild 76 | cmake --build build --target package -- -j4 77 | build/ethminer/ethminer --help 78 | if [ "$TRAVIS_OS_NAME" = linux ]; then ldd -v build/ethminer/ethminer; fi 79 | if [ "$TRAVIS_OS_NAME" = osx ]; then otool -L build/ethminer/ethminer; fi 80 | . build/ethminer/buildinfo.sh 81 | mkdir package 82 | mv build/ethminer.tar.gz package/$PROJECT_NAME-$PROJECT_VERSION-cuda-$CUDA_VERSION-$SYSTEM_NAME-$SYSTEM_PROCESSOR.tar.gz 83 | 84 | 85 | deploy: 86 | - provider: releases 87 | api_key: 88 | secure: "KfYTW8o20BUEZc57vF3H4+qXgpDsMeWk3N4IQtNKkdhFzEUzQaXi1WHRtvcR5kq+rvDiXwy0fELglDZpCSa4wfQvM5fKlb7WPQgkyRZyCpwnXlqvb6dL8KxJekQHZ5fFpzc/ow0dx/UqzJgv+cWDnBEK/gl+9j+vt9oq1nV1LSaxmtO3Qs7y+ffq5Tbzo06q6/CfeyOZi23g+AYtnoEBKwYqa807atWM6cJpudPmyhYHQFgaQZMfzk44z/MnJb7nxtkqcx57KWaY2EHlFj6yrHMcXWyM8j+P0ZBwUbOpHkWvBpgmDKR2J3u0WmiJDDo3E6K0g9QgbAnF5+yqvpBC5kaSHAaicJ3+7ghSgo18Eea0BkLbmb0t93h5NJfRhg0GDjgG3LkHao9ALM35x3OXG38JI6bOLd6jSV2Vkg8qLWAZjP1TUb/4VTIFnyITSv+xrY7ZP9D0XcRybZ5Z0YnaI/J6NFJct9ICAlQ6cHkS0MO6PICTSbZbKhbDZP0Lt6iDDUeje5+uvPAl0uuzuciSqEM77JWYN/edOXurgkfljEny3P96AW70gUUBTVEE+4tjng4DMLHCH/1Jg/WfMPfSVC3AUR0WbvjMki6veMt37fy8Jys8gFpwZbMG3cCSkYXDDFWF/Q+p2v6pX76CZZz+LxO2XcZ7x4bw+c7AGzRWV7c=" 89 | file_glob: true 90 | file: package/* 91 | skip_cleanup: true 92 | on: 93 | tags: true 94 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | include(cmake/cable/bootstrap.cmake) 4 | 5 | include(CableBuildInfo) 6 | include(CableBuildType) 7 | include(CableToolchains) 8 | include(HunterGate) 9 | 10 | include(defaults/HunterCacheServers) 11 | 12 | cable_configure_toolchain(DEFAULT cxx11) 13 | 14 | set(HUNTER_CONFIGURATION_TYPES Release CACHE STRING "Build type of Hunter packages") 15 | set(HUNTER_JOBS_NUMBER 6 CACHE STRING "Number of parallel builds used by Hunter") 16 | HunterGate( 17 | URL "https://github.com/cpp-pm/hunter/archive/v0.23.295.tar.gz" 18 | SHA1 "8a3447594fa5948cc7c6888dd86a9e823259c69f" 19 | LOCAL 20 | ) 21 | 22 | project(ethminer) 23 | 24 | set(PROJECT_VERSION 0.19.0) 25 | 26 | cable_set_build_type(DEFAULT Release CONFIGURATION_TYPES Release RelWithDebInfo) 27 | 28 | option(ETHASHCL "Build with OpenCL mining" ON) 29 | option(ETHASHCUDA "Build with CUDA mining" ON) 30 | option(ETHASHCPU "Build with CPU mining (only for development)" OFF) 31 | option(ETHDBUS "Build with D-Bus support" OFF) 32 | option(APICORE "Build with API Server support" ON) 33 | option(BINKERN "Install AMD binary kernels" ON) 34 | option(DEVBUILD "Log developer metrics" OFF) 35 | option(USE_SYS_OPENCL "Build with system OpenCL" OFF) 36 | 37 | # propagates CMake configuration options to the compiler 38 | function(configureProject) 39 | if (ETHASHCL) 40 | add_definitions(-DETH_ETHASHCL) 41 | endif() 42 | if (ETHASHCUDA) 43 | add_definitions(-DETH_ETHASHCUDA) 44 | endif() 45 | if (ETHASHCPU) 46 | add_definitions(-DETH_ETHASHCPU) 47 | endif() 48 | if (ETHDBUS) 49 | add_definitions(-DETH_DBUS) 50 | endif() 51 | if (APICORE) 52 | add_definitions(-DAPI_CORE) 53 | endif() 54 | if (BINKERN) 55 | add_definitions(-DBIN_KERN) 56 | endif() 57 | if (DEVBUILD) 58 | add_definitions(-DDEV_BUILD) 59 | endif() 60 | if (USE_SYS_OPENCL) 61 | add_definitions(-DUSE_SYS_OPENCL) 62 | endif() 63 | endfunction() 64 | 65 | hunter_add_package(Boost COMPONENTS system filesystem thread) 66 | find_package(Boost CONFIG REQUIRED COMPONENTS system filesystem thread) 67 | 68 | hunter_add_package(jsoncpp) 69 | find_package(jsoncpp CONFIG REQUIRED) 70 | 71 | hunter_add_package(ethash) 72 | find_package(ethash CONFIG REQUIRED) 73 | 74 | configureProject() 75 | 76 | if(APPLE) 77 | set(USE_SYS_OPENCL ON) 78 | endif() 79 | 80 | message("----------------------------------------------------------------------------") 81 | message("-- CMake ${CMAKE_VERSION}") 82 | message("-- Build ${CMAKE_BUILD_TYPE} / ${CMAKE_SYSTEM_NAME}") 83 | message("----------------------------------------------------------------- components") 84 | message("-- ETHASHCL Build OpenCL components ${ETHASHCL}") 85 | message("-- ETHASHCUDA Build CUDA components ${ETHASHCUDA}") 86 | message("-- ETHASHCPU Build CPU components (only for development) ${ETHASHCPU}") 87 | message("-- ETHDBUS Build D-Bus components ${ETHDBUS}") 88 | message("-- APICORE Build API Server components ${APICORE}") 89 | message("-- BINKERN Install AMD binary kernels ${BINKERN}") 90 | message("-- DEVBUILD Build with dev logging ${DEVBUILD}") 91 | message("-- USE_SYS_OPENCL Build with system OpenCL ${USE_SYS_OPENCL}") 92 | message("----------------------------------------------------------------------------") 93 | message("") 94 | 95 | include(EthCompilerSettings) 96 | if(UNIX AND NOT APPLE) 97 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++") 98 | endif() 99 | 100 | cable_add_buildinfo_library(PROJECT_NAME ${PROJECT_NAME}) 101 | 102 | add_subdirectory(libdevcore) 103 | add_subdirectory(libethcore) 104 | add_subdirectory(libhwmon) 105 | add_subdirectory(libpoolprotocols) 106 | 107 | if (ETHASHCL) 108 | add_subdirectory(libethash-cl) 109 | if (BINKERN) 110 | add_subdirectory(libethash-cl/kernels) 111 | endif() 112 | endif () 113 | if (ETHASHCUDA) 114 | add_subdirectory(libethash-cuda) 115 | endif () 116 | if (ETHASHCPU) 117 | add_subdirectory(libethash-cpu) 118 | endif () 119 | if (APICORE) 120 | add_subdirectory(libapicore) 121 | endif() 122 | 123 | add_subdirectory(ethminer) 124 | 125 | 126 | if(WIN32) 127 | set(CPACK_GENERATOR ZIP) 128 | else() 129 | set(CPACK_GENERATOR TGZ) 130 | endif() 131 | set(CPACK_PACKAGE_FILE_NAME ${PROJECT_NAME}) 132 | set(CPACK_PACKAGE_CHECKSUM SHA256) 133 | set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY FALSE) 134 | include(CPack) 135 | -------------------------------------------------------------------------------- /libdevcore/Worker.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | /** @file Worker.cpp 18 | * @author Gav Wood 19 | * @date 2014 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "Log.h" 26 | #include "Worker.h" 27 | 28 | using namespace std; 29 | using namespace dev; 30 | 31 | void Worker::startWorking() 32 | { 33 | DEV_BUILD_LOG_PROGRAMFLOW(cnote, "Worker::startWorking() begin"); 34 | // cnote << "startWorking for thread" << m_name; 35 | Guard l(x_work); 36 | if (m_work) 37 | { 38 | WorkerState ex = WorkerState::Stopped; 39 | m_state.compare_exchange_strong(ex, WorkerState::Starting); 40 | } 41 | else 42 | { 43 | m_state = WorkerState::Starting; 44 | m_work.reset(new thread([&]() { 45 | setThreadName(m_name.c_str()); 46 | // cnote << "Thread begins"; 47 | while (m_state != WorkerState::Killing) 48 | { 49 | WorkerState ex = WorkerState::Starting; 50 | bool ok = m_state.compare_exchange_strong(ex, WorkerState::Started); 51 | // cnote << "Trying to set Started: Thread was" << (unsigned)ex << "; " 52 | //<< ok; 53 | (void)ok; 54 | 55 | try 56 | { 57 | workLoop(); 58 | } 59 | catch (std::exception const& _e) 60 | { 61 | clog(WarnChannel) << "Exception thrown in Worker thread: " << _e.what(); 62 | if (g_exitOnError) 63 | { 64 | clog(WarnChannel) << "Terminating due to --exit"; 65 | raise(SIGTERM); 66 | } 67 | } 68 | 69 | // ex = WorkerState::Stopping; 70 | // m_state.compare_exchange_strong(ex, WorkerState::Stopped); 71 | 72 | ex = m_state.exchange(WorkerState::Stopped); 73 | // cnote << "State: Stopped: Thread was" << (unsigned)ex; 74 | if (ex == WorkerState::Killing || ex == WorkerState::Starting) 75 | m_state.exchange(ex); 76 | 77 | while (m_state == WorkerState::Stopped) 78 | this_thread::sleep_for(chrono::milliseconds(20)); 79 | } 80 | })); 81 | // cnote << "Spawning" << m_name; 82 | } 83 | while (m_state == WorkerState::Starting) 84 | this_thread::sleep_for(chrono::microseconds(20)); 85 | DEV_BUILD_LOG_PROGRAMFLOW(cnote, "Worker::startWorking() end"); 86 | } 87 | 88 | void Worker::triggerStopWorking() 89 | { 90 | DEV_GUARDED(x_work) 91 | if (m_work) 92 | { 93 | WorkerState ex = WorkerState::Started; 94 | m_state.compare_exchange_strong(ex, WorkerState::Stopping); 95 | } 96 | } 97 | 98 | void Worker::stopWorking() 99 | { 100 | DEV_BUILD_LOG_PROGRAMFLOW(cnote, "Worker::stopWorking() begin"); 101 | DEV_GUARDED(x_work) 102 | if (m_work) 103 | { 104 | WorkerState ex = WorkerState::Started; 105 | m_state.compare_exchange_strong(ex, WorkerState::Stopping); 106 | 107 | DEV_BUILD_LOG_PROGRAMFLOW(cnote, "Worker::stopWorking() waiting for WorkerState::Stopped begin"); 108 | while (m_state != WorkerState::Stopped) 109 | this_thread::sleep_for(chrono::microseconds(20)); 110 | DEV_BUILD_LOG_PROGRAMFLOW(cnote, "Worker::stopWorking() waiting for WorkerState::Stopped end"); 111 | } 112 | DEV_BUILD_LOG_PROGRAMFLOW(cnote, "Worker::stopWorking() end"); 113 | } 114 | 115 | Worker::~Worker() 116 | { 117 | DEV_BUILD_LOG_PROGRAMFLOW(cnote, "Worker::~Worker() begin"); 118 | DEV_GUARDED(x_work) 119 | if (m_work) 120 | { 121 | m_state.exchange(WorkerState::Killing); 122 | m_work->join(); 123 | m_work.reset(); 124 | } 125 | DEV_BUILD_LOG_PROGRAMFLOW(cnote, "Worker::~Worker() end"); 126 | } 127 | -------------------------------------------------------------------------------- /docs/BUILD.md: -------------------------------------------------------------------------------- 1 | # Building from source 2 | 3 | ## Table of Contents 4 | 5 | * [Requirements](#requirements) 6 | * [Common](#common) 7 | * [Linux](#linux) 8 | * [OpenCL support on Linux](#opencl-support-on-linux) 9 | * [macOS](#macos) 10 | * [Windows](#windows) 11 | * [CMake configuration options](#cmake-configuration-options) 12 | * [Disable Hunter](#disable-hunter) 13 | * [Instructions](#instructions) 14 | * [Windows-specific script](#windows-specific-script) 15 | 16 | 17 | ## Requirements 18 | 19 | This project uses [CMake] and [Hunter] package manager. 20 | 21 | ### Common 22 | 23 | 1. [CMake] >= 3.5 24 | 2. [Git](https://git-scm.com/downloads) 25 | 3. [Perl](https://www.perl.org/get.html), needed to build OpenSSL 26 | 4. [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads) >= 9.0 (optional, install if you want NVidia CUDA support) 27 | 28 | ### Linux 29 | 30 | 1. GCC version >= 4.8 31 | 2. DBUS development libs if building with `-DETHDBUS`. E.g. on Ubuntu run: 32 | 33 | ```shell 34 | sudo apt install libdbus-1-dev 35 | ``` 36 | 37 | #### OpenCL support on Linux 38 | 39 | If you're planning to use [OpenCL on Linux](https://github.com/ruslo/hunter/wiki/pkg.opencl#pitfalls) 40 | you have to install the OpenGL libraries. E.g. on Ubuntu run: 41 | 42 | ```shell 43 | sudo apt-get install mesa-common-dev 44 | ``` 45 | 46 | If you want to use locally installed [ROCm-OpenCL](https://rocmdocs.amd.com/en/latest/) package, use build flag `-DUSE_SYS_OPENCL=ON` with cmake config. 47 | 48 | ### macOS 49 | 50 | 1. GCC version >= TBF 51 | 52 | ### Windows 53 | 54 | 1. [Visual Studio 2017](https://www.visualstudio.com/downloads/); Community Edition works fine. **Make sure you install MSVC 2015 toolkit (v140).** 55 | 56 | ## Instructions 57 | 58 | 1. Make sure git submodules are up to date: 59 | 60 | ```shell 61 | git submodule update --init --recursive 62 | ``` 63 | 64 | 2. Create a build directory: 65 | 66 | ```shell 67 | mkdir build 68 | cd build 69 | ``` 70 | 71 | 3. Configure the project with CMake. Check out the additional [configuration options](#cmake-configuration-options). 72 | 73 | ```shell 74 | cmake .. 75 | ``` 76 | 77 | **Note:** On Windows, it's possible to have issues with VS 2017 default compilers, due to CUDA expecting a specific toolset version; in that case, use the VS 2017 installer to get the VS 2015 compilers and pass the `-T v140` option: 78 | 79 | ```shell 80 | cmake .. -G "Visual Studio 15 2017 Win64" 81 | # or this if you have build errors in the CUDA step 82 | cmake .. -G "Visual Studio 15 2017 Win64" -T v140 83 | ``` 84 | 85 | 4. Build the project using [CMake Build Tool Mode]. This is a portable variant of `make`. 86 | 87 | ```shell 88 | cmake --build . 89 | ``` 90 | 91 | Note: On Windows, it is possible to have compiler issues if you don't specify the build config. In that case use: 92 | 93 | ```shell 94 | cmake --build . --config Release 95 | ``` 96 | 97 | 5. _(Optional, Linux only)_ Install the built executable: 98 | 99 | ```shell 100 | sudo make install 101 | ``` 102 | 103 | ### Windows-specific script 104 | 105 | Complete sample Windows batch file - **adapt it to your system**. Assumes that: 106 | 107 | * it's placed one folder up from the ethminer source folder 108 | * you have CMake installed 109 | * you have Perl installed 110 | 111 | ```bat 112 | @echo off 113 | setlocal 114 | 115 | rem add MSVC in PATH 116 | call "%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\Common7\Tools\VsMSBuildCmd.bat" 117 | 118 | rem add Perl in PATH; it's needed for OpenSSL build 119 | set "PERL_PATH=C:\Perl\perl\bin" 120 | set "PATH=%PERL_PATH%;%PATH%" 121 | 122 | rem switch to ethminer's source folder 123 | cd "%~dp0\ethminer\" 124 | 125 | if not exist "build\" mkdir "build\" 126 | 127 | rem For CUDA 9.x pass also `-T v140` 128 | cmake -G "Visual Studio 15 2017 Win64" -H. -Bbuild -DETHASHCL=ON -DETHASHCUDA=ON -DAPICORE=ON .. 129 | cmake --build . --config Release --target package 130 | 131 | endlocal 132 | pause 133 | ``` 134 | 135 | ## CMake configuration options 136 | 137 | Pass these options to CMake configuration command, e.g. 138 | 139 | ```shell 140 | cmake .. -DETHASHCUDA=ON -DETHASHCL=OFF 141 | ``` 142 | 143 | * `-DETHASHCL=ON` - enable OpenCL mining, `ON` by default. 144 | * `-DETHASHCUDA=ON` - enable CUDA mining, `ON` by default. 145 | * `-DAPICORE=ON` - enable API Server, `ON` by default. 146 | * `-DBINKERN=ON` - install AMD binary kernels, `ON` by default. 147 | * `-DETHDBUS=ON` - enable D-Bus support, `OFF` by default. 148 | * `-DUSE_SYS_OPENCL=ON` - Use system OpenCL, `OFF` by default, unless on macOS. Specify to use local **ROCm-OpenCL** package. 149 | 150 | ## Disable Hunter 151 | 152 | If you want to install dependencies yourself or use system package manager you can disable Hunter by adding 153 | [`-DHUNTER_ENABLED=OFF`](https://docs.hunter.sh/en/latest/reference/user-variables.html#hunter-enabled) 154 | to the configuration options. 155 | 156 | 157 | [CMake]: https://cmake.org/ 158 | [CMake Build Tool Mode]: https://cmake.org/cmake/help/latest/manual/cmake.1.html#build-tool-mode 159 | [Hunter]: https://docs.hunter.sh/ 160 | -------------------------------------------------------------------------------- /libhwmon/wrapadl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Wrapper for ADL, inspired by wrapnvml from John E. Stone 3 | * 4 | * By Philipp Andreas - github@smurfy.de 5 | * ADL power by Davesmacer 6 | */ 7 | #pragma once 8 | 9 | #if defined(__cplusplus) 10 | extern "C" { 11 | #endif 12 | 13 | typedef enum wrap_adlReturn_enum { WRAPADL_OK = 0 } wrap_adlReturn_t; 14 | 15 | // Some ADL defines and structs from adl sdk 16 | #if defined(__MSC_VER) 17 | #define ADL_API_CALL __cdecl 18 | #elif defined(_WIN32) 19 | #define ADL_API_CALL __stdcall 20 | #else 21 | #define ADL_API_CALL 22 | #endif 23 | 24 | typedef void*(ADL_API_CALL* ADL_MAIN_MALLOC_CALLBACK)(int); 25 | /// \brief Handle to ADL client context. 26 | /// 27 | /// ADL clients obtain context handle from initial call to \ref ADL2_Main_Control_Create. 28 | /// Clients have to pass the handle to each subsequent ADL call and finally destroy 29 | /// the context with call to \ref ADL2_Main_Control_Destroy 30 | /// \nosubgrouping 31 | typedef void* ADL_CONTEXT_HANDLE; 32 | 33 | #define ADL_MAX_PATH 256 34 | typedef struct AdapterInfo 35 | { 36 | /// \ALL_STRUCT_MEM 37 | 38 | /// Size of the structure. 39 | int iSize; 40 | /// The ADL index handle. One GPU may be associated with one or two index handles 41 | int iAdapterIndex; 42 | /// The unique device ID associated with this adapter. 43 | char strUDID[ADL_MAX_PATH]; 44 | /// The BUS number associated with this adapter. 45 | int iBusNumber; 46 | /// The driver number associated with this adapter. 47 | int iDeviceNumber; 48 | /// The function number. 49 | int iFunctionNumber; 50 | /// The vendor ID associated with this adapter. 51 | int iVendorID; 52 | /// Adapter name. 53 | char strAdapterName[ADL_MAX_PATH]; 54 | /// Display name. For example, "\\Display0" for Windows or ":0:0" for Linux. 55 | char strDisplayName[ADL_MAX_PATH]; 56 | /// Present or not; 1 if present and 0 if not present.It the logical adapter is present, the 57 | /// display name such as \\.\Display1 can be found from OS 58 | int iPresent; 59 | // @} 60 | 61 | #if defined(_WIN32) 62 | /// \WIN_STRUCT_MEM 63 | 64 | /// Exist or not; 1 is exist and 0 is not present. 65 | int iExist; 66 | /// Driver registry path. 67 | char strDriverPath[ADL_MAX_PATH]; 68 | /// Driver registry path Ext for. 69 | char strDriverPathExt[ADL_MAX_PATH]; 70 | /// PNP string from Windows. 71 | char strPNPString[ADL_MAX_PATH]; 72 | /// It is generated from EnumDisplayDevices. 73 | int iOSDisplayIndex; 74 | // @} 75 | #endif /* (_WIN32) */ 76 | 77 | #if defined(LINUX) 78 | /// \LNX_STRUCT_MEM 79 | 80 | /// Internal X screen number from GPUMapInfo (DEPRICATED use XScreenInfo) 81 | int iXScreenNum; 82 | /// Internal driver index from GPUMapInfo 83 | int iDrvIndex; 84 | /// \deprecated Internal x config file screen identifier name. Use XScreenInfo instead. 85 | char strXScreenConfigName[ADL_MAX_PATH]; 86 | 87 | // @} 88 | #endif /* (LINUX) */ 89 | } AdapterInfo, *LPAdapterInfo; 90 | 91 | typedef struct ADLTemperature 92 | { 93 | /// Must be set to the size of the structure 94 | int iSize; 95 | /// Temperature in millidegrees Celsius. 96 | int iTemperature; 97 | } ADLTemperature; 98 | 99 | typedef struct ADLFanSpeedValue 100 | { 101 | /// Must be set to the size of the structure 102 | int iSize; 103 | /// Possible valies: \ref ADL_DL_FANCTRL_SPEED_TYPE_PERCENT or \ref 104 | /// ADL_DL_FANCTRL_SPEED_TYPE_RPM 105 | int iSpeedType; 106 | /// Fan speed value 107 | int iFanSpeed; 108 | /// The only flag for now is: \ref ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED 109 | int iFlags; 110 | } ADLFanSpeedValue; 111 | 112 | /* 113 | * Handle to hold the function pointers for the entry points we need, 114 | * and the shared library itself. 115 | */ 116 | typedef struct 117 | { 118 | void* adl_dll; 119 | int adl_gpucount; 120 | int log_gpucount; 121 | int* phys_logi_device_id; 122 | LPAdapterInfo devs; 123 | ADL_CONTEXT_HANDLE context; 124 | wrap_adlReturn_t (*adlMainControlCreate)(ADL_MAIN_MALLOC_CALLBACK, int); 125 | wrap_adlReturn_t (*adlAdapterNumberOfAdapters)(int*); 126 | wrap_adlReturn_t (*adlAdapterAdapterInfoGet)(LPAdapterInfo, int); 127 | wrap_adlReturn_t (*adlAdapterAdapterIdGet)(int, int*); 128 | wrap_adlReturn_t (*adlOverdrive5TemperatureGet)(int, int, ADLTemperature*); 129 | wrap_adlReturn_t (*adlOverdrive5FanSpeedGet)(int, int, ADLFanSpeedValue*); 130 | wrap_adlReturn_t (*adlMainControlRefresh)(void); 131 | wrap_adlReturn_t (*adlMainControlDestroy)(void); 132 | wrap_adlReturn_t (*adl2MainControlCreate)(ADL_MAIN_MALLOC_CALLBACK, int, ADL_CONTEXT_HANDLE*); 133 | wrap_adlReturn_t (*adl2MainControlDestroy)(ADL_CONTEXT_HANDLE); 134 | wrap_adlReturn_t (*adl2Overdrive6CurrentPowerGet)(ADL_CONTEXT_HANDLE, int, int, int*); 135 | wrap_adlReturn_t (*adl2MainControlRefresh)(ADL_CONTEXT_HANDLE); 136 | } wrap_adl_handle; 137 | 138 | wrap_adl_handle* wrap_adl_create(); 139 | int wrap_adl_destroy(wrap_adl_handle* adlh); 140 | 141 | int wrap_adl_get_gpucount(wrap_adl_handle* adlh, int* gpucount); 142 | 143 | int wrap_adl_get_gpu_name(wrap_adl_handle* adlh, int gpuindex, char* namebuf, int bufsize); 144 | 145 | int wrap_adl_get_gpu_pci_id(wrap_adl_handle* adlh, int gpuindex, char* idbuf, int bufsize); 146 | 147 | int wrap_adl_get_tempC(wrap_adl_handle* adlh, int gpuindex, unsigned int* tempC); 148 | 149 | int wrap_adl_get_fanpcnt(wrap_adl_handle* adlh, int gpuindex, unsigned int* fanpcnt); 150 | 151 | int wrap_adl_get_power_usage(wrap_adl_handle* adlh, int gpuindex, unsigned int* milliwatts); 152 | 153 | 154 | #if defined(__cplusplus) 155 | } 156 | #endif 157 | -------------------------------------------------------------------------------- /libethash-cuda/ethash_cuda_miner_kernel.cu: -------------------------------------------------------------------------------- 1 | #include "ethash_cuda_miner_kernel.h" 2 | 3 | #include "ethash_cuda_miner_kernel_globals.h" 4 | 5 | #include "cuda_helper.h" 6 | 7 | #include "fnv.cuh" 8 | 9 | #define copy(dst, src, count) \ 10 | for (int i = 0; i != count; ++i) \ 11 | { \ 12 | (dst)[i] = (src)[i]; \ 13 | } 14 | 15 | #include "keccak.cuh" 16 | 17 | #include "dagger_shuffled.cuh" 18 | 19 | __global__ void ethash_search(volatile Search_results* g_output, uint64_t start_nonce) 20 | { 21 | uint32_t const gid = blockIdx.x * blockDim.x + threadIdx.x; 22 | uint2 mix[4]; 23 | if (compute_hash(start_nonce + gid, mix)) 24 | return; 25 | uint32_t index = atomicInc((uint32_t*)&g_output->count, 0xffffffff); 26 | if (index >= MAX_SEARCH_RESULTS) 27 | return; 28 | g_output->result[index].gid = gid; 29 | g_output->result[index].mix[0] = mix[0].x; 30 | g_output->result[index].mix[1] = mix[0].y; 31 | g_output->result[index].mix[2] = mix[1].x; 32 | g_output->result[index].mix[3] = mix[1].y; 33 | g_output->result[index].mix[4] = mix[2].x; 34 | g_output->result[index].mix[5] = mix[2].y; 35 | g_output->result[index].mix[6] = mix[3].x; 36 | g_output->result[index].mix[7] = mix[3].y; 37 | } 38 | 39 | void run_ethash_search(uint32_t gridSize, uint32_t blockSize, cudaStream_t stream, 40 | volatile Search_results* g_output, uint64_t start_nonce) 41 | { 42 | ethash_search<<>>(g_output, start_nonce); 43 | CUDA_SAFE_CALL(cudaGetLastError()); 44 | } 45 | 46 | #define ETHASH_DATASET_PARENTS 256 47 | #define NODE_WORDS (64 / 4) 48 | 49 | 50 | __global__ void ethash_calculate_dag_item(uint32_t start) 51 | { 52 | uint32_t const node_index = start + blockIdx.x * blockDim.x + threadIdx.x; 53 | if (((node_index >> 1) & (~1)) >= d_dag_size) 54 | return; 55 | union { 56 | hash128_t dag_node; 57 | uint2 dag_node_mem[25]; 58 | }; 59 | copy(dag_node.uint4s, d_light[node_index % d_light_size].uint4s, 4); 60 | dag_node.words[0] ^= node_index; 61 | SHA3_512(dag_node_mem); 62 | 63 | const int thread_id = threadIdx.x & 3; 64 | 65 | for (uint32_t i = 0; i != ETHASH_DATASET_PARENTS; ++i) 66 | { 67 | uint32_t parent_index = fnv(node_index ^ i, dag_node.words[i % NODE_WORDS]) % d_light_size; 68 | for (uint32_t t = 0; t < 4; t++) 69 | { 70 | uint32_t shuffle_index = SHFL(parent_index, t, 4); 71 | 72 | uint4 p4 = d_light[shuffle_index].uint4s[thread_id]; 73 | for (int w = 0; w < 4; w++) 74 | { 75 | uint4 s4 = make_uint4(SHFL(p4.x, w, 4), SHFL(p4.y, w, 4), SHFL(p4.z, w, 4), SHFL(p4.w, w, 4)); 76 | if (t == thread_id) 77 | { 78 | dag_node.uint4s[w] = fnv4(dag_node.uint4s[w], s4); 79 | } 80 | } 81 | } 82 | } 83 | SHA3_512(dag_node_mem); 84 | hash64_t* dag_nodes = (hash64_t*)d_dag; 85 | copy(dag_nodes[node_index].uint4s, dag_node.uint4s, 4); 86 | } 87 | 88 | void ethash_generate_dag( 89 | uint64_t dag_size, uint32_t gridSize, uint32_t blockSize, cudaStream_t stream) 90 | { 91 | const uint32_t work = (uint32_t)(dag_size / sizeof(hash64_t)); 92 | const uint32_t run = gridSize * blockSize; 93 | 94 | uint32_t base; 95 | for (base = 0; base <= work - run; base += run) 96 | { 97 | ethash_calculate_dag_item<<>>(base); 98 | CUDA_SAFE_CALL(cudaDeviceSynchronize()); 99 | } 100 | if (base < work) 101 | { 102 | uint32_t lastGrid = work - base; 103 | lastGrid = (lastGrid + blockSize - 1) / blockSize; 104 | ethash_calculate_dag_item<<>>(base); 105 | CUDA_SAFE_CALL(cudaDeviceSynchronize()); 106 | } 107 | CUDA_SAFE_CALL(cudaGetLastError()); 108 | } 109 | 110 | void set_constants(hash128_t* _dag, uint32_t _dag_size, hash64_t* _light, uint32_t _light_size) 111 | { 112 | CUDA_SAFE_CALL(cudaMemcpyToSymbol(d_dag, &_dag, sizeof(hash128_t*))); 113 | CUDA_SAFE_CALL(cudaMemcpyToSymbol(d_dag_size, &_dag_size, sizeof(uint32_t))); 114 | CUDA_SAFE_CALL(cudaMemcpyToSymbol(d_light, &_light, sizeof(hash64_t*))); 115 | CUDA_SAFE_CALL(cudaMemcpyToSymbol(d_light_size, &_light_size, sizeof(uint32_t))); 116 | } 117 | 118 | void get_constants(hash128_t** _dag, uint32_t* _dag_size, hash64_t** _light, uint32_t* _light_size) 119 | { 120 | /* 121 | Using the direct address of the targets did not work. 122 | So I've to read first into local variables when using cudaMemcpyFromSymbol() 123 | */ 124 | if (_dag) 125 | { 126 | hash128_t* _d; 127 | CUDA_SAFE_CALL(cudaMemcpyFromSymbol(&_d, d_dag, sizeof(hash128_t*))); 128 | *_dag = _d; 129 | } 130 | if (_dag_size) 131 | { 132 | uint32_t _ds; 133 | CUDA_SAFE_CALL(cudaMemcpyFromSymbol(&_ds, d_dag_size, sizeof(uint32_t))); 134 | *_dag_size = _ds; 135 | } 136 | if (_light) 137 | { 138 | hash64_t* _l; 139 | CUDA_SAFE_CALL(cudaMemcpyFromSymbol(&_l, d_light, sizeof(hash64_t*))); 140 | *_light = _l; 141 | } 142 | if (_light_size) 143 | { 144 | uint32_t _ls; 145 | CUDA_SAFE_CALL(cudaMemcpyFromSymbol(&_ls, d_light_size, sizeof(uint32_t))); 146 | *_light_size = _ls; 147 | } 148 | } 149 | 150 | void set_header(hash32_t _header) 151 | { 152 | CUDA_SAFE_CALL(cudaMemcpyToSymbol(d_header, &_header, sizeof(hash32_t))); 153 | } 154 | 155 | void set_target(uint64_t _target) 156 | { 157 | CUDA_SAFE_CALL(cudaMemcpyToSymbol(d_target, &_target, sizeof(uint64_t))); 158 | } 159 | -------------------------------------------------------------------------------- /libethcore/Miner.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethereum. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethereum is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | 18 | #include "Miner.h" 19 | 20 | namespace dev 21 | { 22 | namespace eth 23 | { 24 | 25 | unsigned Miner::s_dagLoadMode = 0; 26 | unsigned Miner::s_dagLoadIndex = 0; 27 | unsigned Miner::s_minersCount = 0; 28 | 29 | FarmFace* FarmFace::m_this = nullptr; 30 | 31 | DeviceDescriptor Miner::getDescriptor() 32 | { 33 | return m_deviceDescriptor; 34 | } 35 | 36 | void Miner::setWork(WorkPackage const& _work) 37 | { 38 | { 39 | 40 | boost::mutex::scoped_lock l(x_work); 41 | 42 | // Void work if this miner is paused 43 | if (paused()) 44 | m_work.header = h256(); 45 | else 46 | m_work = _work; 47 | 48 | #ifdef DEV_BUILD 49 | m_workSwitchStart = std::chrono::steady_clock::now(); 50 | #endif 51 | } 52 | 53 | kick_miner(); 54 | } 55 | 56 | void Miner::pause(MinerPauseEnum what) 57 | { 58 | boost::mutex::scoped_lock l(x_pause); 59 | m_pauseFlags.set(what); 60 | m_work.header = h256(); 61 | kick_miner(); 62 | } 63 | 64 | bool Miner::paused() 65 | { 66 | boost::mutex::scoped_lock l(x_pause); 67 | return m_pauseFlags.any(); 68 | } 69 | 70 | bool Miner::pauseTest(MinerPauseEnum what) 71 | { 72 | boost::mutex::scoped_lock l(x_pause); 73 | return m_pauseFlags.test(what); 74 | } 75 | 76 | std::string Miner::pausedString() 77 | { 78 | boost::mutex::scoped_lock l(x_pause); 79 | std::string retVar; 80 | if (m_pauseFlags.any()) 81 | { 82 | for (int i = 0; i < MinerPauseEnum::Pause_MAX; i++) 83 | { 84 | if (m_pauseFlags[(MinerPauseEnum)i]) 85 | { 86 | if (!retVar.empty()) 87 | retVar.append("; "); 88 | 89 | if (i == MinerPauseEnum::PauseDueToOverHeating) 90 | retVar.append("Overheating"); 91 | else if (i == MinerPauseEnum::PauseDueToAPIRequest) 92 | retVar.append("Api request"); 93 | else if (i == MinerPauseEnum::PauseDueToFarmPaused) 94 | retVar.append("Farm suspended"); 95 | else if (i == MinerPauseEnum::PauseDueToInsufficientMemory) 96 | retVar.append("Insufficient GPU memory"); 97 | else if (i == MinerPauseEnum::PauseDueToInitEpochError) 98 | retVar.append("Epoch initialization error"); 99 | 100 | } 101 | } 102 | } 103 | return retVar; 104 | } 105 | 106 | void Miner::resume(MinerPauseEnum fromwhat) 107 | { 108 | boost::mutex::scoped_lock l(x_pause); 109 | m_pauseFlags.reset(fromwhat); 110 | //if (!m_pauseFlags.any()) 111 | //{ 112 | // // TODO Push most recent job from farm ? 113 | // // If we do not push a new job the miner will stay idle 114 | // // till a new job arrives 115 | //} 116 | } 117 | 118 | float Miner::RetrieveHashRate() noexcept 119 | { 120 | return m_hashRate.load(std::memory_order_relaxed); 121 | } 122 | 123 | void Miner::TriggerHashRateUpdate() noexcept 124 | { 125 | bool b = false; 126 | if (m_hashRateUpdate.compare_exchange_strong(b, true)) 127 | return; 128 | // GPU didn't respond to last trigger, assume it's dead. 129 | // This can happen on CUDA if: 130 | // runtime of --cuda-grid-size * --cuda-streams exceeds time of m_collectInterval 131 | m_hashRate = 0.0; 132 | } 133 | 134 | bool Miner::initEpoch() 135 | { 136 | // When loading of DAG is sequential wait for 137 | // this instance to become current 138 | if (s_dagLoadMode == DAG_LOAD_MODE_SEQUENTIAL) 139 | { 140 | while (s_dagLoadIndex < m_index) 141 | { 142 | boost::system_time const timeout = 143 | boost::get_system_time() + boost::posix_time::seconds(3); 144 | boost::mutex::scoped_lock l(x_work); 145 | m_dag_loaded_signal.timed_wait(l, timeout); 146 | } 147 | if (shouldStop()) 148 | return false; 149 | } 150 | 151 | // Run the internal initialization 152 | // specific for miner 153 | bool result = initEpoch_internal(); 154 | 155 | // Advance to next miner or reset to zero for 156 | // next run if all have processed 157 | if (s_dagLoadMode == DAG_LOAD_MODE_SEQUENTIAL) 158 | { 159 | s_dagLoadIndex = (m_index + 1); 160 | if (s_minersCount == s_dagLoadIndex) 161 | s_dagLoadIndex = 0; 162 | else 163 | m_dag_loaded_signal.notify_all(); 164 | } 165 | 166 | return result; 167 | } 168 | 169 | WorkPackage Miner::work() const 170 | { 171 | boost::mutex::scoped_lock l(x_work); 172 | return m_work; 173 | } 174 | 175 | void Miner::updateHashRate(uint32_t _groupSize, uint32_t _increment) noexcept 176 | { 177 | m_groupCount += _increment; 178 | bool b = true; 179 | if (!m_hashRateUpdate.compare_exchange_strong(b, false)) 180 | return; 181 | using namespace std::chrono; 182 | auto t = steady_clock::now(); 183 | auto us = duration_cast(t - m_hashTime).count(); 184 | m_hashTime = t; 185 | 186 | m_hashRate.store( 187 | us ? (float(m_groupCount * _groupSize) * 1.0e6f) / us : 0.0f, std::memory_order_relaxed); 188 | m_groupCount = 0; 189 | } 190 | 191 | 192 | } // namespace eth 193 | } // namespace dev 194 | -------------------------------------------------------------------------------- /libpoolprotocols/stratum/EthStratumClient.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include "../PoolClient.h" 20 | 21 | using namespace std; 22 | using namespace dev; 23 | using namespace dev::eth; 24 | 25 | template 26 | class verbose_verification 27 | { 28 | public: 29 | verbose_verification(Verifier verifier) : verifier_(verifier) {} 30 | 31 | bool operator()(bool preverified, boost::asio::ssl::verify_context& ctx) 32 | { 33 | char subject_name[256]; 34 | X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle()); 35 | X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256); 36 | bool verified = verifier_(preverified, ctx); 37 | #ifdef DEV_BUILD 38 | cnote << "Certificate: " << subject_name << " " << (verified ? "Ok" : "Failed"); 39 | #else 40 | if (!verified) 41 | cnote << "Certificate: " << subject_name << " " 42 | << "Failed"; 43 | #endif 44 | return verified; 45 | } 46 | 47 | private: 48 | Verifier verifier_; 49 | }; 50 | 51 | class EthStratumClient : public PoolClient 52 | { 53 | public: 54 | enum StratumProtocol 55 | { 56 | STRATUM = 0, 57 | ETHPROXY, 58 | ETHEREUMSTRATUM, 59 | ETHEREUMSTRATUM2 60 | }; 61 | 62 | EthStratumClient(int worktimeout, int responsetimeout); 63 | 64 | void init_socket(); 65 | void connect() override; 66 | void disconnect() override; 67 | 68 | // Connected and Connection Statuses 69 | bool isConnected() override 70 | { 71 | bool _ret = PoolClient::isConnected(); 72 | return _ret && !isPendingState(); 73 | } 74 | bool isPendingState() override 75 | { 76 | return (m_connecting.load(std::memory_order_relaxed) || 77 | m_disconnecting.load(std::memory_order_relaxed)); 78 | } 79 | 80 | void submitHashrate(uint64_t const& rate, string const& id) override; 81 | void submitSolution(const Solution& solution) override; 82 | 83 | h256 currentHeaderHash() { return m_current.header; } 84 | bool current() { return static_cast(m_current); } 85 | 86 | private: 87 | void startSession(); 88 | void disconnect_finalize(); 89 | void enqueue_response_plea(); 90 | std::chrono::milliseconds dequeue_response_plea(); 91 | void clear_response_pleas(); 92 | void resolve_handler( 93 | const boost::system::error_code& ec, boost::asio::ip::tcp::resolver::iterator i); 94 | void start_connect(); 95 | void connect_handler(const boost::system::error_code& ec); 96 | void workloop_timer_elapsed(const boost::system::error_code& ec); 97 | 98 | void processResponse(Json::Value& responseObject); 99 | std::string processError(Json::Value& erroresponseObject); 100 | void processExtranonce(std::string& enonce); 101 | 102 | void recvSocketData(); 103 | void onRecvSocketDataCompleted( 104 | const boost::system::error_code& ec, std::size_t bytes_transferred); 105 | void send(Json::Value const& jReq); 106 | void sendSocketData(); 107 | void onSendSocketDataCompleted(const boost::system::error_code& ec); 108 | void onSSLShutdownCompleted(const boost::system::error_code& ec); 109 | 110 | std::atomic m_disconnecting = {false}; 111 | std::atomic m_connecting = {false}; 112 | std::atomic m_authpending = {false}; 113 | 114 | // seconds to trigger a work_timeout (overwritten in constructor) 115 | int m_worktimeout; 116 | 117 | // seconds timeout for responses and connection (overwritten in constructor) 118 | int m_responsetimeout; 119 | 120 | // default interval for workloop timer (milliseconds) 121 | int m_workloop_interval = 1000; 122 | 123 | WorkPackage m_current; 124 | std::chrono::time_point m_current_timestamp; 125 | 126 | boost::asio::io_service& m_io_service; // The IO service reference passed in the constructor 127 | boost::asio::io_context::strand m_io_strand; 128 | boost::asio::ip::tcp::socket* m_socket; 129 | std::string m_message; // The internal message string buffer 130 | bool m_newjobprocessed = false; 131 | 132 | // Use shared ptrs to avoid crashes due to async_writes 133 | // see 134 | // https://stackoverflow.com/questions/41526553/can-async-write-cause-segmentation-fault-when-this-is-deleted 135 | std::shared_ptr> m_securesocket; 136 | std::shared_ptr m_nonsecuresocket; 137 | 138 | boost::asio::streambuf m_sendBuffer; 139 | boost::asio::streambuf m_recvBuffer; 140 | Json::StreamWriterBuilder m_jSwBuilder; 141 | 142 | boost::asio::deadline_timer m_workloop_timer; 143 | 144 | std::atomic m_response_pleas_count = {0}; 145 | std::atomic m_response_plea_older; 146 | boost::lockfree::queue m_response_plea_times; 147 | 148 | std::atomic m_txPending = {false}; 149 | boost::lockfree::queue m_txQueue; 150 | 151 | boost::asio::ip::tcp::resolver m_resolver; 152 | std::queue> m_endpoints; 153 | 154 | unsigned m_solution_submitted_max_id; // maximum json id we used to send a solution 155 | 156 | ///@brief Auxiliary function to make verbose_verification objects. 157 | template 158 | verbose_verification make_verbose_verification(Verifier verifier) 159 | { 160 | return verbose_verification(verifier); 161 | } 162 | }; 163 | -------------------------------------------------------------------------------- /libdevcore/CommonData.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | 18 | #include 19 | 20 | #include "CommonData.h" 21 | #include "Exceptions.h" 22 | 23 | using namespace std; 24 | using namespace dev; 25 | 26 | int dev::fromHex(char _i, WhenError _throw) 27 | { 28 | if (_i >= '0' && _i <= '9') 29 | return _i - '0'; 30 | if (_i >= 'a' && _i <= 'f') 31 | return _i - 'a' + 10; 32 | if (_i >= 'A' && _i <= 'F') 33 | return _i - 'A' + 10; 34 | if (_throw == WhenError::Throw) 35 | BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i)); 36 | else 37 | return -1; 38 | } 39 | 40 | bytes dev::fromHex(std::string const& _s, WhenError _throw) 41 | { 42 | unsigned s = (_s[0] == '0' && _s[1] == 'x') ? 2 : 0; 43 | std::vector ret; 44 | ret.reserve((_s.size() - s + 1) / 2); 45 | 46 | if (_s.size() % 2) 47 | { 48 | int h = fromHex(_s[s++], WhenError::DontThrow); 49 | if (h != -1) 50 | ret.push_back(h); 51 | else if (_throw == WhenError::Throw) 52 | BOOST_THROW_EXCEPTION(BadHexCharacter()); 53 | else 54 | return bytes(); 55 | } 56 | for (unsigned i = s; i < _s.size(); i += 2) 57 | { 58 | int h = fromHex(_s[i], WhenError::DontThrow); 59 | int l = fromHex(_s[i + 1], WhenError::DontThrow); 60 | if (h != -1 && l != -1) 61 | ret.push_back((byte)(h * 16 + l)); 62 | else if (_throw == WhenError::Throw) 63 | BOOST_THROW_EXCEPTION(BadHexCharacter()); 64 | else 65 | return bytes(); 66 | } 67 | return ret; 68 | } 69 | 70 | bool dev::setenv(const char name[], const char value[], bool override) 71 | { 72 | #if _WIN32 73 | if (!override && std::getenv(name) != nullptr) 74 | return true; 75 | 76 | return ::_putenv_s(name, value) == 0; 77 | #else 78 | return ::setenv(name, value, override ? 1 : 0) == 0; 79 | #endif 80 | } 81 | 82 | std::string dev::getTargetFromDiff(double diff, HexPrefix _prefix) 83 | { 84 | using namespace boost::multiprecision; 85 | using BigInteger = boost::multiprecision::cpp_int; 86 | 87 | static BigInteger base("0x00000000ffff0000000000000000000000000000000000000000000000000000"); 88 | BigInteger product; 89 | 90 | if (diff == 0) 91 | { 92 | product = BigInteger("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); 93 | } 94 | else 95 | { 96 | diff = 1 / diff; 97 | 98 | BigInteger idiff(diff); 99 | product = base * idiff; 100 | 101 | std::string sdiff = boost::lexical_cast(diff); 102 | size_t ldiff = sdiff.length(); 103 | size_t offset = sdiff.find("."); 104 | 105 | if (offset != std::string::npos) 106 | { 107 | // Number of decimal places 108 | size_t precision = (ldiff - 1) - offset; 109 | 110 | // Effective sequence of decimal places 111 | string decimals = sdiff.substr(offset + 1); 112 | 113 | // Strip leading zeroes. If a string begins with 114 | // 0 or 0x boost parser considers it hex 115 | decimals = decimals.erase(0, decimals.find_first_not_of('0')); 116 | 117 | // Build up the divisor as string - just in case 118 | // parser does some implicit conversion with 10^precision 119 | string decimalDivisor = "1"; 120 | decimalDivisor.resize(precision + 1, '0'); 121 | 122 | // This is the multiplier for the decimal part 123 | BigInteger multiplier(decimals); 124 | 125 | // This is the divisor for the decimal part 126 | BigInteger divisor(decimalDivisor); 127 | 128 | BigInteger decimalproduct; 129 | decimalproduct = base * multiplier; 130 | decimalproduct /= divisor; 131 | 132 | // Add the computed decimal part 133 | // to product 134 | product += decimalproduct; 135 | } 136 | } 137 | 138 | // Normalize to 64 chars hex with "0x" prefix 139 | stringstream ss; 140 | ss << (_prefix == HexPrefix::Add ? "0x" : "") << setw(64) << setfill('0') << std::hex 141 | << product; 142 | 143 | string target = ss.str(); 144 | boost::algorithm::to_lower(target); 145 | return target; 146 | } 147 | 148 | double dev::getHashesToTarget(string _target) 149 | { 150 | using namespace boost::multiprecision; 151 | using BigInteger = boost::multiprecision::cpp_int; 152 | 153 | static BigInteger dividend( 154 | "0xffff000000000000000000000000000000000000000000000000000000000000"); 155 | BigInteger divisor(_target); 156 | return double(dividend / divisor); 157 | } 158 | 159 | std::string dev::getScaledSize(double _value, double _divisor, int _precision, string _sizes[], 160 | size_t _numsizes, ScaleSuffix _suffix) 161 | { 162 | double _newvalue = _value; 163 | size_t i = 0; 164 | while (_newvalue > _divisor && i <= (_numsizes - 1)) 165 | { 166 | _newvalue /= _divisor; 167 | i++; 168 | } 169 | 170 | std::stringstream _ret; 171 | _ret << fixed << setprecision(_precision) << _newvalue; 172 | if (_suffix == ScaleSuffix::Add) 173 | _ret << " " << _sizes[i]; 174 | return _ret.str(); 175 | } 176 | 177 | std::string dev::getFormattedHashes(double _hr, ScaleSuffix _suffix, int _precision) 178 | { 179 | static string suffixes[] = {"h", "Kh", "Mh", "Gh"}; 180 | return dev::getScaledSize(_hr, 1000.0, _precision, suffixes, 4, _suffix); 181 | } 182 | 183 | std::string dev::getFormattedMemory(double _mem, ScaleSuffix _suffix, int _precision) 184 | { 185 | static string suffixes[] = {"B", "KB", "MB", "GB"}; 186 | return dev::getScaledSize(_mem, 1024.0, _precision, suffixes, 4, _suffix); 187 | } 188 | 189 | std::string dev::padLeft(std::string _value, size_t _length, char _fillChar) 190 | { 191 | if (_length > _value.size()) 192 | _value.insert(0, (_length - _value.size()), _fillChar); 193 | return _value; 194 | } 195 | 196 | std::string dev::padRight(std::string _value, size_t _length, char _fillChar) 197 | { 198 | if (_length > _value.size()) 199 | _value.resize(_length, _fillChar); 200 | return _value; 201 | } 202 | -------------------------------------------------------------------------------- /libhwmon/wrapnvml.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * A trivial little dlopen()-based wrapper library for the 3 | * NVIDIA NVML library, to allow runtime discovery of NVML on an 4 | * arbitrary system. This is all very hackish and simple-minded, but 5 | * it serves my immediate needs in the short term until NVIDIA provides 6 | * a static NVML wrapper library themselves, hopefully in 7 | * CUDA 6.5 or maybe sometime shortly after. 8 | * 9 | * This trivial code is made available under the "new" 3-clause BSD license, 10 | * and/or any of the GPL licenses you prefer. 11 | * Feel free to use the code and modify as you see fit. 12 | * 13 | * John E. Stone - john.stone@gmail.com 14 | * 15 | * Modified to work with ethminer by 16 | * 17 | * Philipp Andreas - github@smurfy.de 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include "wrapnvml.h" 24 | 25 | #if defined(__cplusplus) 26 | extern "C" { 27 | #endif 28 | 29 | wrap_nvml_handle* wrap_nvml_create() 30 | { 31 | wrap_nvml_handle* nvmlh = nullptr; 32 | 33 | /* 34 | * We use hard-coded library installation locations for the time being... 35 | * No idea where or if libnvidia-ml.so is installed on MacOS X, a 36 | * deep scouring of the filesystem on one of the Mac CUDA build boxes 37 | * I used turned up nothing, so for now it's not going to work on OSX. 38 | */ 39 | #if defined(_WIN32) 40 | /* Windows */ 41 | #define libnvidia_ml "%PROGRAMFILES%/NVIDIA Corporation/NVSMI/nvml.dll" 42 | #elif defined(__linux) && (defined(__i386__) || defined(__ARM_ARCH_7A__)) 43 | /* In rpm based linux distributions link name is with extension .1 */ 44 | /* 32-bit linux assumed */ 45 | #define libnvidia_ml "libnvidia-ml.so.1" 46 | #elif defined(__linux) 47 | /* 64-bit linux assumed */ 48 | #define libnvidia_ml "libnvidia-ml.so.1" 49 | #else 50 | #define libnvidia_ml "" 51 | #warning "Unrecognized platform: need NVML DLL path for this platform..." 52 | return nullptr; 53 | #endif 54 | 55 | #ifdef _WIN32 56 | char tmp[512]; 57 | ExpandEnvironmentStringsA(libnvidia_ml, tmp, sizeof(tmp)); 58 | #else 59 | char tmp[512] = libnvidia_ml; 60 | #endif 61 | 62 | void* nvml_dll = wrap_dlopen(tmp); 63 | if (nvml_dll == nullptr) 64 | { 65 | cwarn << "Failed to obtain all required NVML function pointers"; 66 | cwarn << "NVIDIA hardware monitoring disabled"; 67 | return nullptr; 68 | } 69 | 70 | 71 | nvmlh = (wrap_nvml_handle*)calloc(1, sizeof(wrap_nvml_handle)); 72 | 73 | nvmlh->nvml_dll = nvml_dll; 74 | 75 | nvmlh->nvmlInit = (wrap_nvmlReturn_t(*)(void))wrap_dlsym(nvmlh->nvml_dll, "nvmlInit"); 76 | nvmlh->nvmlDeviceGetCount = 77 | (wrap_nvmlReturn_t(*)(int*))wrap_dlsym(nvmlh->nvml_dll, "nvmlDeviceGetCount_v2"); 78 | nvmlh->nvmlDeviceGetHandleByIndex = (wrap_nvmlReturn_t(*)(int, wrap_nvmlDevice_t*))wrap_dlsym( 79 | nvmlh->nvml_dll, "nvmlDeviceGetHandleByIndex_v2"); 80 | nvmlh->nvmlDeviceGetPciInfo = (wrap_nvmlReturn_t(*)( 81 | wrap_nvmlDevice_t, wrap_nvmlPciInfo_t*))wrap_dlsym(nvmlh->nvml_dll, "nvmlDeviceGetPciInfo"); 82 | nvmlh->nvmlDeviceGetName = (wrap_nvmlReturn_t(*)(wrap_nvmlDevice_t, char*, int))wrap_dlsym( 83 | nvmlh->nvml_dll, "nvmlDeviceGetName"); 84 | nvmlh->nvmlDeviceGetTemperature = (wrap_nvmlReturn_t(*)(wrap_nvmlDevice_t, int, 85 | unsigned int*))wrap_dlsym(nvmlh->nvml_dll, "nvmlDeviceGetTemperature"); 86 | nvmlh->nvmlDeviceGetFanSpeed = (wrap_nvmlReturn_t(*)( 87 | wrap_nvmlDevice_t, unsigned int*))wrap_dlsym(nvmlh->nvml_dll, "nvmlDeviceGetFanSpeed"); 88 | nvmlh->nvmlDeviceGetPowerUsage = (wrap_nvmlReturn_t(*)( 89 | wrap_nvmlDevice_t, unsigned int*))wrap_dlsym(nvmlh->nvml_dll, "nvmlDeviceGetPowerUsage"); 90 | nvmlh->nvmlShutdown = (wrap_nvmlReturn_t(*)())wrap_dlsym(nvmlh->nvml_dll, "nvmlShutdown"); 91 | 92 | if (nvmlh->nvmlInit == nullptr || nvmlh->nvmlShutdown == nullptr || 93 | nvmlh->nvmlDeviceGetCount == nullptr || nvmlh->nvmlDeviceGetHandleByIndex == nullptr || 94 | nvmlh->nvmlDeviceGetPciInfo == nullptr || nvmlh->nvmlDeviceGetName == nullptr || 95 | nvmlh->nvmlDeviceGetTemperature == nullptr || nvmlh->nvmlDeviceGetFanSpeed == nullptr || 96 | nvmlh->nvmlDeviceGetPowerUsage == nullptr) 97 | { 98 | cwarn << "Failed to obtain all required NVML function pointers"; 99 | cwarn << "NVIDIA hardware monitoring disabled"; 100 | 101 | wrap_dlclose(nvmlh->nvml_dll); 102 | free(nvmlh); 103 | return nullptr; 104 | } 105 | 106 | nvmlh->nvmlInit(); 107 | nvmlh->nvmlDeviceGetCount(&nvmlh->nvml_gpucount); 108 | 109 | nvmlh->devs = (wrap_nvmlDevice_t*)calloc(nvmlh->nvml_gpucount, sizeof(wrap_nvmlDevice_t)); 110 | nvmlh->nvml_pci_domain_id = (unsigned int*)calloc(nvmlh->nvml_gpucount, sizeof(unsigned int)); 111 | nvmlh->nvml_pci_bus_id = (unsigned int*)calloc(nvmlh->nvml_gpucount, sizeof(unsigned int)); 112 | nvmlh->nvml_pci_device_id = (unsigned int*)calloc(nvmlh->nvml_gpucount, sizeof(unsigned int)); 113 | 114 | /* Obtain GPU device handles we're going to need repeatedly... */ 115 | for (int i = 0; i < nvmlh->nvml_gpucount; i++) 116 | { 117 | nvmlh->nvmlDeviceGetHandleByIndex(i, &nvmlh->devs[i]); 118 | } 119 | 120 | /* Query PCI info for each NVML device, and build table for mapping of */ 121 | /* CUDA device IDs to NVML device IDs and vice versa */ 122 | for (int i = 0; i < nvmlh->nvml_gpucount; i++) 123 | { 124 | wrap_nvmlPciInfo_t pciinfo; 125 | nvmlh->nvmlDeviceGetPciInfo(nvmlh->devs[i], &pciinfo); 126 | nvmlh->nvml_pci_domain_id[i] = pciinfo.domain; 127 | nvmlh->nvml_pci_bus_id[i] = pciinfo.bus; 128 | nvmlh->nvml_pci_device_id[i] = pciinfo.device; 129 | } 130 | 131 | return nvmlh; 132 | } 133 | 134 | 135 | int wrap_nvml_destroy(wrap_nvml_handle* nvmlh) 136 | { 137 | nvmlh->nvmlShutdown(); 138 | 139 | wrap_dlclose(nvmlh->nvml_dll); 140 | free(nvmlh); 141 | return 0; 142 | } 143 | 144 | int wrap_nvml_get_gpucount(wrap_nvml_handle* nvmlh, int* gpucount) 145 | { 146 | *gpucount = nvmlh->nvml_gpucount; 147 | return 0; 148 | } 149 | 150 | int wrap_nvml_get_gpu_name(wrap_nvml_handle* nvmlh, int gpuindex, char* namebuf, int bufsize) 151 | { 152 | if (gpuindex < 0 || gpuindex >= nvmlh->nvml_gpucount) 153 | return -1; 154 | 155 | if (nvmlh->nvmlDeviceGetName(nvmlh->devs[gpuindex], namebuf, bufsize) != WRAPNVML_SUCCESS) 156 | return -1; 157 | 158 | return 0; 159 | } 160 | 161 | int wrap_nvml_get_tempC(wrap_nvml_handle* nvmlh, int gpuindex, unsigned int* tempC) 162 | { 163 | if (gpuindex < 0 || gpuindex >= nvmlh->nvml_gpucount) 164 | return -1; 165 | 166 | if (nvmlh->nvmlDeviceGetTemperature( 167 | nvmlh->devs[gpuindex], 0u /* NVML_TEMPERATURE_GPU */, tempC) != WRAPNVML_SUCCESS) 168 | return -1; 169 | 170 | return 0; 171 | } 172 | 173 | int wrap_nvml_get_fanpcnt(wrap_nvml_handle* nvmlh, int gpuindex, unsigned int* fanpcnt) 174 | { 175 | if (gpuindex < 0 || gpuindex >= nvmlh->nvml_gpucount) 176 | return -1; 177 | 178 | if (nvmlh->nvmlDeviceGetFanSpeed(nvmlh->devs[gpuindex], fanpcnt) != WRAPNVML_SUCCESS) 179 | return -1; 180 | 181 | return 0; 182 | } 183 | 184 | int wrap_nvml_get_power_usage(wrap_nvml_handle* nvmlh, int gpuindex, unsigned int* milliwatts) 185 | { 186 | if (gpuindex < 0 || gpuindex >= nvmlh->nvml_gpucount) 187 | return -1; 188 | 189 | if (nvmlh->nvmlDeviceGetPowerUsage(nvmlh->devs[gpuindex], milliwatts) != WRAPNVML_SUCCESS) 190 | return -1; 191 | 192 | return 0; 193 | } 194 | 195 | #if defined(__cplusplus) 196 | } 197 | #endif 198 | -------------------------------------------------------------------------------- /libdevcore/vector_ref.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace dev 10 | { 11 | /** 12 | * A modifiable reference to an existing object or vector in memory. 13 | */ 14 | template 15 | class vector_ref 16 | { 17 | public: 18 | using value_type = _T; 19 | using element_type = _T; 20 | using mutable_value_type = typename std::conditional::value, 21 | typename std::remove_const<_T>::type, _T>::type; 22 | 23 | static_assert(std::is_pod::value, 24 | "vector_ref can only be used with PODs due to its low-level treatment of data."); 25 | 26 | vector_ref() : m_data(nullptr), m_count(0) {} 27 | /// Creates a new vector_ref to point to @a _count elements starting at @a _data. 28 | vector_ref(_T* _data, size_t _count) : m_data(_data), m_count(_count) {} 29 | /// Creates a new vector_ref pointing to the data part of a string (given as pointer). 30 | vector_ref( 31 | typename std::conditional::value, std::string const*, std::string*>::type 32 | _data) 33 | : m_data(reinterpret_cast<_T*>(_data->data())), m_count(_data->size() / sizeof(_T)) 34 | {} 35 | /// Creates a new vector_ref pointing to the data part of a vector (given as pointer). 36 | vector_ref(typename std::conditional::value, 37 | std::vector::type> const*, std::vector<_T>*>::type _data) 38 | : m_data(_data->data()), m_count(_data->size()) 39 | {} 40 | /// Creates a new vector_ref pointing to the data part of a string (given as reference). 41 | vector_ref( 42 | typename std::conditional::value, std::string const&, std::string&>::type 43 | _data) 44 | : m_data(reinterpret_cast<_T*>(_data.data())), m_count(_data.size() / sizeof(_T)) 45 | {} 46 | #if DEV_LDB 47 | vector_ref(ldb::Slice const& _s) 48 | : m_data(reinterpret_cast<_T*>(_s.data())), m_count(_s.size() / sizeof(_T)) 49 | {} 50 | #endif 51 | explicit operator bool() const { return m_data && m_count; } 52 | 53 | bool contentsEqual(std::vector const& _c) const 54 | { 55 | if (!m_data || m_count == 0) 56 | return _c.empty(); 57 | return _c.size() == m_count && !memcmp(_c.data(), m_data, m_count * sizeof(_T)); 58 | } 59 | std::vector toVector() const 60 | { 61 | return std::vector(m_data, m_data + m_count); 62 | } 63 | std::vector toBytes() const 64 | { 65 | return std::vector(reinterpret_cast(m_data), 66 | reinterpret_cast(m_data) + m_count * sizeof(_T)); 67 | } 68 | std::string toString() const 69 | { 70 | return std::string((char const*)m_data, ((char const*)m_data) + m_count * sizeof(_T)); 71 | } 72 | 73 | template 74 | explicit operator vector_ref<_T2>() const 75 | { 76 | assert(m_count * sizeof(_T) / sizeof(_T2) * sizeof(_T2) / sizeof(_T) == m_count); 77 | return vector_ref<_T2>(reinterpret_cast<_T2*>(m_data), m_count * sizeof(_T) / sizeof(_T2)); 78 | } 79 | operator vector_ref<_T const>() const { return vector_ref<_T const>(m_data, m_count); } 80 | 81 | _T* data() const { return m_data; } 82 | /// @returns the number of elements referenced (not necessarily number of bytes). 83 | size_t count() const { return m_count; } 84 | /// @returns the number of elements referenced (not necessarily number of bytes). 85 | size_t size() const { return m_count; } 86 | bool empty() const { return !m_count; } 87 | /// @returns a new vector_ref pointing at the next chunk of @a size() elements. 88 | vector_ref<_T> next() const 89 | { 90 | if (!m_data) 91 | return *this; 92 | return vector_ref<_T>(m_data + m_count, m_count); 93 | } 94 | /// @returns a new vector_ref which is a shifted and shortened view of the original data. 95 | /// If this goes out of bounds in any way, returns an empty vector_ref. 96 | /// If @a _count is ~size_t(0), extends the view to the end of the data. 97 | vector_ref<_T> cropped(size_t _begin, size_t _count) const 98 | { 99 | if (m_data && _begin <= m_count && _count <= m_count && _begin + _count <= m_count) 100 | return vector_ref<_T>( 101 | m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); 102 | return {}; 103 | } 104 | /// @returns a new vector_ref which is a shifted view of the original data (not going beyond 105 | /// it). 106 | vector_ref<_T> cropped(size_t _begin) const 107 | { 108 | if (m_data && _begin <= m_count) 109 | return vector_ref<_T>(m_data + _begin, m_count - _begin); 110 | return {}; 111 | } 112 | void retarget(_T* _d, size_t _s) 113 | { 114 | m_data = _d; 115 | m_count = _s; 116 | } 117 | void retarget(std::vector<_T> const& _t) 118 | { 119 | m_data = _t.data(); 120 | m_count = _t.size(); 121 | } 122 | template 123 | bool overlapsWith(vector_ref _t) const 124 | { 125 | void const* f1 = data(); 126 | void const* t1 = data() + size(); 127 | void const* f2 = _t.data(); 128 | void const* t2 = _t.data() + _t.size(); 129 | return f1 < t2 && t1 > f2; 130 | } 131 | /// Copies the contents of this vector_ref to the contents of @a _t, up to the max size of @a 132 | /// _t. 133 | void copyTo(vector_ref::type> _t) const 134 | { 135 | if (overlapsWith(_t)) 136 | memmove(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); 137 | else 138 | memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); 139 | } 140 | /// Copies the contents of this vector_ref to the contents of @a _t, and zeros further trailing 141 | /// elements in @a _t. 142 | void populate(vector_ref::type> _t) const 143 | { 144 | copyTo(_t); 145 | memset(_t.data() + m_count, 0, std::max(_t.size(), m_count) - m_count); 146 | } 147 | /// Securely overwrite the memory. 148 | /// @note adapted from OpenSSL's implementation. 149 | void cleanse() 150 | { 151 | static unsigned char s_cleanseCounter = 0; 152 | auto* p = (uint8_t*)begin(); 153 | size_t const len = (uint8_t*)end() - p; 154 | size_t loop = len; 155 | size_t count = s_cleanseCounter; 156 | while (loop--) 157 | { 158 | *(p++) = (uint8_t)count; 159 | count += (17 + ((size_t)p & 0xf)); 160 | } 161 | p = (uint8_t*)memchr((uint8_t*)begin(), (uint8_t)count, len); 162 | if (p) 163 | count += (63 + (size_t)p); 164 | s_cleanseCounter = (uint8_t)count; 165 | memset((uint8_t*)begin(), 0, len); 166 | } 167 | 168 | _T* begin() { return m_data; } 169 | _T* end() { return m_data + m_count; } 170 | _T const* begin() const { return m_data; } 171 | _T const* end() const { return m_data + m_count; } 172 | 173 | _T& operator[](size_t _i) 174 | { 175 | assert(m_data); 176 | assert(_i < m_count); 177 | return m_data[_i]; 178 | } 179 | _T const& operator[](size_t _i) const 180 | { 181 | assert(m_data); 182 | assert(_i < m_count); 183 | return m_data[_i]; 184 | } 185 | 186 | bool operator==(vector_ref<_T> const& _cmp) const 187 | { 188 | return m_data == _cmp.m_data && m_count == _cmp.m_count; 189 | } 190 | bool operator!=(vector_ref<_T> const& _cmp) const { return !operator==(_cmp); } 191 | 192 | void reset() 193 | { 194 | m_data = nullptr; 195 | m_count = 0; 196 | } 197 | 198 | private: 199 | _T* m_data; 200 | size_t m_count; 201 | }; 202 | 203 | template 204 | vector_ref<_T const> ref(_T const& _t) 205 | { 206 | return vector_ref<_T const>(&_t, 1); 207 | } 208 | template 209 | vector_ref<_T> ref(_T& _t) 210 | { 211 | return vector_ref<_T>(&_t, 1); 212 | } 213 | template 214 | vector_ref<_T const> ref(std::vector<_T> const& _t) 215 | { 216 | return vector_ref<_T const>(&_t); 217 | } 218 | template 219 | vector_ref<_T> ref(std::vector<_T>& _t) 220 | { 221 | return vector_ref<_T>(&_t); 222 | } 223 | 224 | } // namespace dev 225 | -------------------------------------------------------------------------------- /libhwmon/wrapadl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Wrapper for ADL, inspired by wrapnvml from John E. Stone 3 | * 4 | * By Philipp Andreas - github@smurfy.de 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "wrapadl.h" 13 | #include "wraphelper.h" 14 | 15 | #if defined(__cplusplus) 16 | extern "C" { 17 | #endif 18 | 19 | void* ADL_API_CALL ADL_Main_Memory_Alloc(int iSize) 20 | { 21 | void* lpBuffer = malloc(iSize); 22 | return lpBuffer; 23 | } 24 | 25 | wrap_adl_handle* wrap_adl_create() 26 | { 27 | wrap_adl_handle* adlh = nullptr; 28 | 29 | #if defined(_WIN32) 30 | /* Windows */ 31 | #define libatiadlxx "atiadlxx.dll" 32 | #elif defined(__linux) && (defined(__i386__) || defined(__ARM_ARCH_7A__)) 33 | /* 32-bit linux assumed */ 34 | #define libatiadlxx "libatiadlxx.so" 35 | #elif defined(__linux) 36 | /* 64-bit linux assumed */ 37 | #define libatiadlxx "libatiadlxx.so" 38 | #else 39 | #define libatiadlxx "" 40 | #warning "Unrecognized platform: need ADL DLL path for this platform..." 41 | return nullptr; 42 | #endif 43 | 44 | #ifdef _WIN32 45 | char tmp[512]; 46 | ExpandEnvironmentStringsA(libatiadlxx, tmp, sizeof(tmp)); 47 | #else 48 | char tmp[512] = libatiadlxx; 49 | #endif 50 | 51 | void* adl_dll = wrap_dlopen(tmp); 52 | if (adl_dll == nullptr) 53 | { 54 | cwarn << "Failed to obtain all required ADL function pointers"; 55 | cwarn << "AMD hardware monitoring disabled"; 56 | return nullptr; 57 | } 58 | 59 | 60 | adlh = (wrap_adl_handle*)calloc(1, sizeof(wrap_adl_handle)); 61 | 62 | adlh->adl_dll = adl_dll; 63 | 64 | adlh->adlMainControlCreate = (wrap_adlReturn_t(*)(ADL_MAIN_MALLOC_CALLBACK, int))wrap_dlsym( 65 | adlh->adl_dll, "ADL_Main_Control_Create"); 66 | adlh->adlAdapterNumberOfAdapters = 67 | (wrap_adlReturn_t(*)(int*))wrap_dlsym(adlh->adl_dll, "ADL_Adapter_NumberOfAdapters_Get"); 68 | adlh->adlAdapterAdapterInfoGet = (wrap_adlReturn_t(*)(LPAdapterInfo, int))wrap_dlsym( 69 | adlh->adl_dll, "ADL_Adapter_AdapterInfo_Get"); 70 | adlh->adlAdapterAdapterIdGet = 71 | (wrap_adlReturn_t(*)(int, int*))wrap_dlsym(adlh->adl_dll, "ADL_Adapter_ID_Get"); 72 | adlh->adlOverdrive5TemperatureGet = (wrap_adlReturn_t(*)(int, int, ADLTemperature*))wrap_dlsym( 73 | adlh->adl_dll, "ADL_Overdrive5_Temperature_Get"); 74 | adlh->adlOverdrive5FanSpeedGet = (wrap_adlReturn_t(*)(int, int, ADLFanSpeedValue*))wrap_dlsym( 75 | adlh->adl_dll, "ADL_Overdrive5_FanSpeed_Get"); 76 | adlh->adlMainControlRefresh = 77 | (wrap_adlReturn_t(*)(void))wrap_dlsym(adlh->adl_dll, "ADL_Main_Control_Refresh"); 78 | adlh->adlMainControlDestroy = 79 | (wrap_adlReturn_t(*)(void))wrap_dlsym(adlh->adl_dll, "ADL_Main_Control_Destroy"); 80 | adlh->adl2MainControlCreate = (wrap_adlReturn_t(*)(ADL_MAIN_MALLOC_CALLBACK, int, 81 | ADL_CONTEXT_HANDLE*))wrap_dlsym(adlh->adl_dll, "ADL2_Main_Control_Create"); 82 | adlh->adl2MainControlDestroy = (wrap_adlReturn_t(*)(ADL_CONTEXT_HANDLE))wrap_dlsym( 83 | adlh->adl_dll, "ADL_Main_Control_Destroy"); 84 | adlh->adl2Overdrive6CurrentPowerGet = (wrap_adlReturn_t(*)(ADL_CONTEXT_HANDLE, int, int, 85 | int*))wrap_dlsym(adlh->adl_dll, "ADL2_Overdrive6_CurrentPower_Get"); 86 | adlh->adl2MainControlRefresh = (wrap_adlReturn_t(*)(ADL_CONTEXT_HANDLE))wrap_dlsym( 87 | adlh->adl_dll, "ADL2_Main_Control_Refresh"); 88 | 89 | 90 | if (adlh->adlMainControlCreate == nullptr || adlh->adlMainControlDestroy == nullptr || 91 | adlh->adlMainControlRefresh == nullptr || adlh->adlAdapterNumberOfAdapters == nullptr || 92 | adlh->adlAdapterAdapterInfoGet == nullptr || adlh->adlAdapterAdapterIdGet == nullptr || 93 | adlh->adlOverdrive5TemperatureGet == nullptr || adlh->adlOverdrive5FanSpeedGet == nullptr || 94 | adlh->adl2MainControlCreate == nullptr || adlh->adl2MainControlRefresh == nullptr || 95 | adlh->adl2MainControlDestroy == nullptr || adlh->adl2Overdrive6CurrentPowerGet == nullptr) 96 | { 97 | cwarn << "Failed to obtain all required ADL function pointers"; 98 | cwarn << "AMD hardware monitoring disabled"; 99 | 100 | wrap_dlclose(adlh->adl_dll); 101 | free(adlh); 102 | return nullptr; 103 | } 104 | 105 | adlh->adlMainControlCreate(ADL_Main_Memory_Alloc, 1); 106 | adlh->adlMainControlRefresh(); 107 | 108 | adlh->context = nullptr; 109 | 110 | adlh->adl2MainControlCreate(ADL_Main_Memory_Alloc, 1, &(adlh->context)); 111 | adlh->adl2MainControlRefresh(adlh->context); 112 | 113 | int logicalGpuCount = 0; 114 | adlh->adlAdapterNumberOfAdapters(&logicalGpuCount); 115 | 116 | adlh->phys_logi_device_id = (int*)calloc(logicalGpuCount, sizeof(int)); 117 | 118 | adlh->adl_gpucount = 0; 119 | int last_adapter = 0; 120 | if (logicalGpuCount > 0) 121 | { 122 | adlh->log_gpucount = logicalGpuCount; 123 | adlh->devs = (LPAdapterInfo)malloc(sizeof(AdapterInfo) * logicalGpuCount); 124 | memset(adlh->devs, '\0', sizeof(AdapterInfo) * logicalGpuCount); 125 | 126 | adlh->devs->iSize = sizeof(adlh->devs); 127 | 128 | int res = adlh->adlAdapterAdapterInfoGet(adlh->devs, sizeof(AdapterInfo) * logicalGpuCount); 129 | if (res != WRAPADL_OK) 130 | { 131 | cwarn << "Failed to obtain using adlAdapterAdapterInfoGet()."; 132 | cwarn << "AMD hardware monitoring disabled"; 133 | 134 | wrap_dlclose(adlh->adl_dll); 135 | free(adlh); 136 | return nullptr; 137 | } 138 | 139 | for (int i = 0; i < logicalGpuCount; i++) 140 | { 141 | int adapterIndex = adlh->devs[i].iAdapterIndex; 142 | int adapterID = 0; 143 | 144 | res = adlh->adlAdapterAdapterIdGet(adapterIndex, &adapterID); 145 | 146 | if (res != WRAPADL_OK) 147 | { 148 | continue; 149 | } 150 | 151 | adlh->phys_logi_device_id[adlh->adl_gpucount] = adapterIndex; 152 | 153 | if (adapterID == last_adapter) 154 | { 155 | continue; 156 | } 157 | 158 | last_adapter = adapterID; 159 | adlh->adl_gpucount++; 160 | } 161 | } 162 | 163 | return adlh; 164 | } 165 | 166 | int wrap_adl_destroy(wrap_adl_handle* adlh) 167 | { 168 | adlh->adlMainControlDestroy(); 169 | adlh->adl2MainControlDestroy(adlh->context); 170 | wrap_dlclose(adlh->adl_dll); 171 | free(adlh); 172 | return 0; 173 | } 174 | 175 | int wrap_adl_get_gpucount(wrap_adl_handle* adlh, int* gpucount) 176 | { 177 | *gpucount = adlh->adl_gpucount; 178 | return 0; 179 | } 180 | 181 | int wrap_adl_get_gpu_name(wrap_adl_handle* adlh, int gpuindex, char* namebuf, int bufsize) 182 | { 183 | if (gpuindex < 0 || gpuindex >= adlh->adl_gpucount) 184 | return -1; 185 | 186 | memcpy(namebuf, adlh->devs[adlh->phys_logi_device_id[gpuindex]].strAdapterName, bufsize); 187 | return 0; 188 | } 189 | 190 | int wrap_adl_get_gpu_pci_id(wrap_adl_handle* adlh, int gpuindex, char* idbuf, int bufsize) 191 | { 192 | if (gpuindex < 0 || gpuindex >= adlh->adl_gpucount) 193 | return -1; 194 | 195 | char buf[256]; 196 | sprintf(buf, "%04x:%02x:%02x", 197 | 0, // Is probably 0 198 | adlh->devs[adlh->phys_logi_device_id[gpuindex]].iBusNumber, 199 | adlh->devs[adlh->phys_logi_device_id[gpuindex]].iDeviceNumber); 200 | memcpy(idbuf, buf, bufsize); 201 | return 0; 202 | } 203 | 204 | int wrap_adl_get_tempC(wrap_adl_handle* adlh, int gpuindex, unsigned int* tempC) 205 | { 206 | 207 | if (gpuindex < 0 || gpuindex >= adlh->adl_gpucount) 208 | return -1; 209 | 210 | ADLTemperature* temperature = new ADLTemperature(); 211 | 212 | if (adlh->adlOverdrive5TemperatureGet(adlh->phys_logi_device_id[gpuindex], 0, temperature) != 213 | WRAPADL_OK) 214 | return -1; 215 | 216 | *tempC = unsigned(temperature->iTemperature / 1000); 217 | delete temperature; 218 | return 0; 219 | } 220 | 221 | int wrap_adl_get_fanpcnt(wrap_adl_handle* adlh, int gpuindex, unsigned int* fanpcnt) 222 | { 223 | 224 | if (gpuindex < 0 || gpuindex >= adlh->adl_gpucount) 225 | return -1; 226 | 227 | ADLFanSpeedValue* fan = new ADLFanSpeedValue(); 228 | fan->iSpeedType = 1; 229 | 230 | if (adlh->adlOverdrive5FanSpeedGet(adlh->phys_logi_device_id[gpuindex], 0, fan) != WRAPADL_OK) 231 | return -1; 232 | 233 | *fanpcnt = unsigned(fan->iFanSpeed); 234 | delete fan; 235 | return 0; 236 | } 237 | 238 | int wrap_adl_get_power_usage(wrap_adl_handle* adlh, int gpuindex, unsigned int* miliwatts) 239 | { 240 | 241 | if (gpuindex < 0 || gpuindex >= adlh->adl_gpucount) 242 | return -1; 243 | 244 | int power = 0; 245 | if (adlh->adl2Overdrive6CurrentPowerGet( 246 | adlh->context, adlh->phys_logi_device_id[gpuindex], 0, &power) != WRAPADL_OK) 247 | return -1; 248 | 249 | *miliwatts = (unsigned int)(power * 3.90625); 250 | return 0; 251 | } 252 | 253 | #if defined(__cplusplus) 254 | } 255 | #endif 256 | -------------------------------------------------------------------------------- /libdevcore/CommonData.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | /** @file CommonData.h 18 | * @author Gav Wood 19 | * @date 2014 20 | * 21 | * Shared algorithms and data types. 22 | */ 23 | 24 | #pragma once 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "Common.h" 36 | 37 | namespace dev 38 | { 39 | // String conversion functions, mainly to/from hex/nibble/byte representations. 40 | 41 | enum class WhenError 42 | { 43 | DontThrow = 0, 44 | Throw = 1, 45 | }; 46 | 47 | enum class HexPrefix 48 | { 49 | DontAdd = 0, 50 | Add = 1, 51 | }; 52 | 53 | enum class ScaleSuffix 54 | { 55 | DontAdd = 0, 56 | Add = 1 57 | }; 58 | 59 | /// Convert a series of bytes to the corresponding string of hex duplets. 60 | /// @param _w specifies the width of the first of the elements. Defaults to two - enough to 61 | /// represent a byte. 62 | /// @example toHex("A\x69") == "4169" 63 | template 64 | std::string toHex(T const& _data, int _w = 2, HexPrefix _prefix = HexPrefix::DontAdd) 65 | { 66 | std::ostringstream ret; 67 | unsigned ii = 0; 68 | for (auto i : _data) 69 | ret << std::hex << std::setfill('0') << std::setw(ii++ ? 2 : _w) 70 | << (int)(typename std::make_unsigned::type)i; 71 | return (_prefix == HexPrefix::Add) ? "0x" + ret.str() : ret.str(); 72 | } 73 | 74 | /// Converts a (printable) ASCII hex character into the correspnding integer value. 75 | /// @example fromHex('A') == 10 && fromHex('f') == 15 && fromHex('5') == 5 76 | int fromHex(char _i, WhenError _throw); 77 | 78 | /// Converts a (printable) ASCII hex string into the corresponding byte stream. 79 | /// @example fromHex("41626261") == asBytes("Abba") 80 | /// If _throw = ThrowType::DontThrow, it replaces bad hex characters with 0's, otherwise it will 81 | /// throw an exception. 82 | bytes fromHex(std::string const& _s, WhenError _throw = WhenError::DontThrow); 83 | 84 | /// Converts byte array to a string containing the same (binary) data. Unless 85 | /// the byte array happens to contain ASCII data, this won't be printable. 86 | inline std::string asString(bytes const& _b) 87 | { 88 | return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size())); 89 | } 90 | 91 | /// Converts a string to a byte array containing the string's (byte) data. 92 | inline bytes asBytes(std::string const& _b) 93 | { 94 | return bytes((byte const*)_b.data(), (byte const*)(_b.data() + _b.size())); 95 | } 96 | 97 | 98 | // Big-endian to/from host endian conversion functions. 99 | 100 | /// Converts a templated integer value to the big-endian byte-stream represented on a templated 101 | /// collection. The size of the collection object will be unchanged. If it is too small, it will not 102 | /// represent the value properly, if too big then the additional elements will be zeroed out. 103 | /// @a Out will typically be either std::string or bytes. 104 | /// @a T will typically by unsigned, u160, u256 or bigint. 105 | template 106 | inline void toBigEndian(T _val, Out& o_out) 107 | { 108 | static_assert(std::is_same::value || !std::numeric_limits::is_signed, 109 | "only unsigned types or bigint supported"); // bigint does not carry sign bit on shift 110 | for (auto i = o_out.size(); i != 0; _val >>= 8, i--) 111 | { 112 | T v = _val & (T)0xff; 113 | o_out[i - 1] = (typename Out::value_type)(uint8_t)v; 114 | } 115 | } 116 | 117 | /// Converts a big-endian byte-stream represented on a templated collection to a templated integer 118 | /// value. 119 | /// @a _In will typically be either std::string or bytes. 120 | /// @a T will typically by unsigned, u160, u256 or bigint. 121 | template 122 | inline T fromBigEndian(_In const& _bytes) 123 | { 124 | T ret = (T)0; 125 | for (auto i : _bytes) 126 | ret = 127 | (T)((ret << 8) | (byte)(typename std::make_unsigned::type)i); 128 | return ret; 129 | } 130 | 131 | /// Convenience functions for toBigEndian 132 | inline bytes toBigEndian(u256 _val) 133 | { 134 | bytes ret(32); 135 | toBigEndian(std::move(_val), ret); 136 | return ret; 137 | } 138 | inline bytes toBigEndian(u160 _val) 139 | { 140 | bytes ret(20); 141 | toBigEndian(_val, ret); 142 | return ret; 143 | } 144 | 145 | /// Convenience function for toBigEndian. 146 | /// @returns a byte array just big enough to represent @a _val. 147 | template 148 | inline bytes toCompactBigEndian(T _val, unsigned _min = 0) 149 | { 150 | static_assert(std::is_same::value || !std::numeric_limits::is_signed, 151 | "only unsigned types or bigint supported"); // bigint does not carry sign bit on shift 152 | int i = 0; 153 | for (T v = _val; v; ++i, v >>= 8) 154 | { 155 | } 156 | bytes ret(std::max(_min, i), 0); 157 | toBigEndian(_val, ret); 158 | return ret; 159 | } 160 | 161 | /// Convenience function for conversion of a u256 to hex 162 | inline std::string toHex(u256 val, HexPrefix prefix = HexPrefix::DontAdd) 163 | { 164 | std::string str = toHex(toBigEndian(val)); 165 | return (prefix == HexPrefix::Add) ? "0x" + str : str; 166 | } 167 | 168 | inline std::string toHex(uint64_t _n, HexPrefix _prefix = HexPrefix::DontAdd, int _bytes = 16) 169 | { 170 | // sizeof returns the number of bytes (not the number of bits) 171 | // thus if CHAR_BIT != 8 sizeof(uint64_t) will return != 8 172 | // Use fixed constant multiplier of 16 173 | std::ostringstream ret; 174 | ret << std::hex << std::setfill('0') << std::setw(_bytes) << _n; 175 | return (_prefix == HexPrefix::Add) ? "0x" + ret.str() : ret.str(); 176 | } 177 | 178 | inline std::string toHex(uint32_t _n, HexPrefix _prefix = HexPrefix::DontAdd, int _bytes = 8) 179 | { 180 | // sizeof returns the number of bytes (not the number of bits) 181 | // thus if CHAR_BIT != 8 sizeof(uint64_t) will return != 4 182 | // Use fixed constant multiplier of 8 183 | std::ostringstream ret; 184 | ret << std::hex << std::setfill('0') << std::setw(_bytes) << _n; 185 | return (_prefix == HexPrefix::Add) ? "0x" + ret.str() : ret.str(); 186 | } 187 | 188 | inline std::string toCompactHex(uint64_t _n, HexPrefix _prefix = HexPrefix::DontAdd) 189 | { 190 | std::ostringstream ret; 191 | ret << std::hex << _n; 192 | return (_prefix == HexPrefix::Add) ? "0x" + ret.str() : ret.str(); 193 | } 194 | 195 | inline std::string toCompactHex(uint32_t _n, HexPrefix _prefix = HexPrefix::DontAdd) 196 | { 197 | std::ostringstream ret; 198 | ret << std::hex << _n; 199 | return (_prefix == HexPrefix::Add) ? "0x" + ret.str() : ret.str(); 200 | } 201 | 202 | 203 | 204 | // Algorithms for string and string-like collections. 205 | 206 | /// Escapes a string into the C-string representation. 207 | /// @p _all if true will escape all characters, not just the unprintable ones. 208 | std::string escaped(std::string const& _s, bool _all = true); 209 | 210 | // General datatype convenience functions. 211 | 212 | /// Determine bytes required to encode the given integer value. @returns 0 if @a _i is zero. 213 | template 214 | inline unsigned bytesRequired(T _i) 215 | { 216 | static_assert(std::is_same::value || !std::numeric_limits::is_signed, 217 | "only unsigned types or bigint supported"); // bigint does not carry sign bit on shift 218 | unsigned i = 0; 219 | for (; _i != 0; ++i, _i >>= 8) 220 | { 221 | } 222 | return i; 223 | } 224 | 225 | /// Sets environment variable. 226 | /// 227 | /// Portable wrapper for setenv / _putenv C library functions. 228 | bool setenv(const char name[], const char value[], bool override = false); 229 | 230 | /// Gets a target hash from given difficulty 231 | std::string getTargetFromDiff(double diff, HexPrefix _prefix = HexPrefix::Add); 232 | 233 | /// Gets the difficulty expressed in hashes to target 234 | double getHashesToTarget(std::string _target); 235 | 236 | /// Generic function to scale a value 237 | std::string getScaledSize(double _value, double _divisor, int _precision, std::string _sizes[], 238 | size_t _numsizes, ScaleSuffix _suffix = ScaleSuffix::Add); 239 | 240 | /// Formats hashrate 241 | std::string getFormattedHashes(double _hr, ScaleSuffix _suffix = ScaleSuffix::Add, int _precision = 2); 242 | 243 | /// Formats hashrate 244 | std::string getFormattedMemory( 245 | double _mem, ScaleSuffix _suffix = ScaleSuffix::Add, int _precision = 2); 246 | 247 | /// Adjust string to a fixed length filling chars to the Left 248 | std::string padLeft(std::string _value, size_t _length, char _fillChar); 249 | 250 | /// Adjust string to a fixed length filling chars to the Right 251 | std::string padRight(std::string _value, size_t _length, char _fillChar); 252 | 253 | } // namespace dev 254 | -------------------------------------------------------------------------------- /libethcore/Farm.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of ethminer. 3 | 4 | ethminer is free software: you can redistribute it and/or modify 5 | it under the terms of the GNU General Public License as published by 6 | the Free Software Foundation, either version 3 of the License, or 7 | (at your option) any later version. 8 | 9 | ethminer is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | 14 | You should have received a copy of the GNU General Public License 15 | along with ethminer. If not, see . 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #include 38 | #if defined(__linux) 39 | #include 40 | #include 41 | #else 42 | #include 43 | #endif 44 | 45 | extern boost::asio::io_service g_io_service; 46 | 47 | namespace dev 48 | { 49 | namespace eth 50 | { 51 | struct FarmSettings 52 | { 53 | unsigned dagLoadMode = 0; // 0 = Parallel; 1 = Serialized 54 | bool noEval = false; // Whether or not to re-evaluate solutions 55 | unsigned hwMon = 0; // 0 - No monitor; 1 - Temp and Fan; 2 - Temp Fan Power 56 | unsigned ergodicity = 0; // 0=default, 1=per session, 2=per job 57 | unsigned tempStart = 40; // Temperature threshold to restart mining (if paused) 58 | unsigned tempStop = 0; // Temperature threshold to pause mining (overheating) 59 | }; 60 | 61 | /** 62 | * @brief A collective of Miners. 63 | * Miners ask for work, then submit proofs 64 | * @threadsafe 65 | */ 66 | class Farm : public FarmFace 67 | { 68 | public: 69 | unsigned tstart = 0, tstop = 0; 70 | 71 | Farm(std::map& _DevicesCollection, 72 | FarmSettings _settings, CUSettings _CUSettings, CLSettings _CLSettings, 73 | CPSettings _CPSettings); 74 | 75 | ~Farm(); 76 | 77 | static Farm& f() { return *m_this; } 78 | 79 | /** 80 | * @brief Randomizes the nonce scrambler 81 | */ 82 | void shuffle(); 83 | 84 | /** 85 | * @brief Sets the current mining mission. 86 | * @param _wp The work package we wish to be mining. 87 | */ 88 | void setWork(WorkPackage const& _newWp); 89 | 90 | /** 91 | * @brief Start a number of miners. 92 | */ 93 | bool start(); 94 | 95 | /** 96 | * @brief All mining activities to a full stop. 97 | * Implies all mining threads are stopped. 98 | */ 99 | void stop(); 100 | 101 | /** 102 | * @brief Signals all miners to suspend mining 103 | */ 104 | void pause(); 105 | 106 | /** 107 | * @brief Whether or not the whole farm has been paused 108 | */ 109 | bool paused(); 110 | 111 | /** 112 | * @brief Signals all miners to resume mining 113 | */ 114 | void resume(); 115 | 116 | /** 117 | * @brief Stop all mining activities and Starts them again 118 | */ 119 | void restart(); 120 | 121 | /** 122 | * @brief Stop all mining activities and Starts them again (async post) 123 | */ 124 | void restart_async(); 125 | 126 | /** 127 | * @brief Returns whether or not the farm has been started 128 | */ 129 | bool isMining() const { return m_isMining.load(std::memory_order_relaxed); } 130 | 131 | /** 132 | * @brief Spawn a reboot script (reboot.bat/reboot.sh) 133 | * @return false if no matching file was found 134 | */ 135 | bool reboot(const std::vector& args); 136 | 137 | /** 138 | * @brief Get information on the progress of mining this work package. 139 | * @return The progress with mining so far. 140 | */ 141 | TelemetryType& Telemetry() { return m_telemetry; } 142 | 143 | /** 144 | * @brief Gets current hashrate 145 | */ 146 | float HashRate() { return m_telemetry.farm.hashrate; }; 147 | 148 | /** 149 | * @brief Gets the collection of pointers to miner instances 150 | */ 151 | std::vector> getMiners() { return m_miners; } 152 | 153 | /** 154 | * @brief Gets the number of miner instances 155 | */ 156 | unsigned getMinersCount() { return (unsigned)m_miners.size(); }; 157 | 158 | /** 159 | * @brief Gets the pointer to a miner instance 160 | */ 161 | std::shared_ptr getMiner(unsigned index) 162 | { 163 | try 164 | { 165 | return m_miners.at(index); 166 | } 167 | catch (const std::exception&) 168 | { 169 | return nullptr; 170 | } 171 | } 172 | 173 | /** 174 | * @brief Accounts a solution to a miner and, as a consequence, to 175 | * the whole farm 176 | */ 177 | void accountSolution(unsigned _minerIdx, SolutionAccountingEnum _accounting) override; 178 | 179 | /** 180 | * @brief Gets the solutions account for the whole farm 181 | */ 182 | SolutionAccountType getSolutions(); 183 | 184 | /** 185 | * @brief Gets the solutions account for single miner 186 | */ 187 | SolutionAccountType getSolutions(unsigned _minerIdx); 188 | 189 | using SolutionFound = std::function; 190 | using MinerRestart = std::function; 191 | 192 | /** 193 | * @brief Provides a valid header based upon that received previously with setWork(). 194 | * @param _bi The now-valid header. 195 | * @return true if the header was good and that the Farm should pause until more work is 196 | * submitted. 197 | */ 198 | void onSolutionFound(SolutionFound const& _handler) { m_onSolutionFound = _handler; } 199 | 200 | void onMinerRestart(MinerRestart const& _handler) { m_onMinerRestart = _handler; } 201 | 202 | /** 203 | * @brief Gets the actual start nonce of the segment picked by the farm 204 | */ 205 | uint64_t get_nonce_scrambler() override { return m_nonce_scrambler; } 206 | 207 | /** 208 | * @brief Gets the actual width of each subsegment assigned to miners 209 | */ 210 | unsigned get_segment_width() override { return m_nonce_segment_with; } 211 | 212 | /** 213 | * @brief Sets the actual start nonce of the segment picked by the farm 214 | */ 215 | void set_nonce_scrambler(uint64_t n) { m_nonce_scrambler = n; } 216 | 217 | /** 218 | * @brief Sets the actual width of each subsegment assigned to miners 219 | */ 220 | void set_nonce_segment_width(unsigned n) 221 | { 222 | if (!m_currentWp.exSizeBytes) 223 | m_nonce_segment_with = n; 224 | } 225 | 226 | /** 227 | * @brief Provides the description of segments each miner is working on 228 | * @return a JsonObject 229 | */ 230 | Json::Value get_nonce_scrambler_json(); 231 | 232 | void setTStartTStop(unsigned tstart, unsigned tstop); 233 | 234 | unsigned get_tstart() override { return m_Settings.tempStart; } 235 | 236 | unsigned get_tstop() override { return m_Settings.tempStop; } 237 | 238 | unsigned get_ergodicity() override { return m_Settings.ergodicity; } 239 | 240 | /** 241 | * @brief Called from a Miner to note a WorkPackage has a solution. 242 | * @param _s The solution. 243 | */ 244 | void submitProof(Solution const& _s) override; 245 | 246 | private: 247 | std::atomic m_paused = {false}; 248 | 249 | // Async submits solution serializing execution 250 | // in Farm's strand 251 | void submitProofAsync(Solution const& _s); 252 | 253 | // Collects data about hashing and hardware status 254 | void collectData(const boost::system::error_code& ec); 255 | 256 | /** 257 | * @brief Spawn a file - must be located in the directory of ethminer binary 258 | * @return false if file was not found or it is not executeable 259 | */ 260 | bool spawn_file_in_bin_dir(const char* filename, const std::vector& args); 261 | 262 | mutable Mutex x_minerWork; 263 | std::vector> m_miners; // Collection of miners 264 | 265 | WorkPackage m_currentWp; 266 | EpochContext m_currentEc; 267 | 268 | std::atomic m_isMining = {false}; 269 | 270 | TelemetryType m_telemetry; // Holds progress and status info for farm and miners 271 | 272 | SolutionFound m_onSolutionFound; 273 | MinerRestart m_onMinerRestart; 274 | 275 | FarmSettings m_Settings; // Own Farm Settings 276 | CUSettings m_CUSettings; // Cuda settings passed to CUDA Miner instantiator 277 | CLSettings m_CLSettings; // OpenCL settings passed to CL Miner instantiator 278 | CPSettings m_CPSettings; // CPU settings passed to CPU Miner instantiator 279 | 280 | boost::asio::io_context::strand m_io_strand; 281 | boost::asio::deadline_timer m_collectTimer; 282 | static const int m_collectInterval = 5000; 283 | 284 | string m_pool_addresses; 285 | 286 | // StartNonce (non-NiceHash Mode) and 287 | // segment width assigned to each GPU as exponent of 2 288 | // considering an average block time of 15 seconds 289 | // a single device GPU should need a speed of 286 Mh/s 290 | // before it consumes the whole 2^32 segment 291 | uint64_t m_nonce_scrambler; 292 | unsigned int m_nonce_segment_with = 32; 293 | 294 | // Wrappers for hardware monitoring libraries and their mappers 295 | wrap_nvml_handle* nvmlh = nullptr; 296 | std::map map_nvml_handle = {}; 297 | 298 | #if defined(__linux) 299 | wrap_amdsysfs_handle* sysfsh = nullptr; 300 | std::map map_amdsysfs_handle = {}; 301 | #else 302 | wrap_adl_handle* adlh = nullptr; 303 | std::map map_adl_handle = {}; 304 | #endif 305 | 306 | static Farm* m_this; 307 | std::map& m_DevicesCollection; 308 | }; 309 | 310 | } // namespace eth 311 | } // namespace dev 312 | -------------------------------------------------------------------------------- /libhwmon/wrapamdsysfs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Wrapper for AMD SysFS on linux, using adapted code from amdcovc by matszpk 3 | * 4 | * By Philipp Andreas - github@smurfy.de 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | #if defined(__linux) 11 | #include 12 | #endif 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include "wrapamdsysfs.h" 28 | #include "wraphelper.h" 29 | 30 | static bool getFileContentValue(const char* filename, unsigned int& value) 31 | { 32 | value = 0; 33 | std::ifstream ifs(filename, std::ios::binary); 34 | std::string line; 35 | std::getline(ifs, line); 36 | char* p = (char*)line.c_str(); 37 | char* p2; 38 | errno = 0; 39 | value = strtoul(p, &p2, 0); 40 | if (errno != 0) 41 | return false; 42 | return (p != p2); 43 | } 44 | 45 | wrap_amdsysfs_handle* wrap_amdsysfs_create() 46 | { 47 | wrap_amdsysfs_handle* sysfsh = nullptr; 48 | 49 | #if defined(__linux) 50 | namespace fs = boost::filesystem; 51 | std::vector devices; // Used to collect devices 52 | 53 | char dbuf[120]; 54 | // Check directory exist 55 | fs::path drm_dir("/sys/class/drm"); 56 | if (!fs::exists(drm_dir) || !fs::is_directory(drm_dir)) 57 | return nullptr; 58 | 59 | // Regex patterns to identify directory elements 60 | std::regex cardPattern("^card[0-9]{1,}$"); 61 | std::regex hwmonPattern("^hwmon[0-9]{1,}$"); 62 | 63 | // Loop directory contents 64 | for (fs::directory_iterator dirEnt(drm_dir); dirEnt != fs::directory_iterator(); ++dirEnt) 65 | { 66 | // Skip non relevant entries 67 | if (!fs::is_directory(dirEnt->path()) || 68 | !std::regex_match(dirEnt->path().filename().string(), cardPattern)) 69 | continue; 70 | 71 | std::string devName = dirEnt->path().filename().string(); 72 | unsigned int devIndex = std::stoi(devName.substr(4), nullptr, 10); 73 | unsigned int vendorId = 0; 74 | unsigned int hwmonIndex = UINT_MAX; 75 | 76 | // Get AMD cards only (vendor 4098) 77 | fs::path vendor_file("/sys/class/drm/" + devName + "/device/vendor"); 78 | snprintf(dbuf, 120, "/sys/class/drm/%s/device/vendor", devName.c_str()); 79 | if (!fs::exists(vendor_file) || !fs::is_regular_file(vendor_file) || 80 | !getFileContentValue(dbuf, vendorId) || vendorId != 4098) 81 | continue; 82 | 83 | // Check it has dependant hwmon directory 84 | fs::path hwmon_dir("/sys/class/drm/" + devName + "/device/hwmon"); 85 | if (!fs::exists(hwmon_dir) || !fs::is_directory(hwmon_dir)) 86 | continue; 87 | 88 | // Loop subelements in hwmon directory 89 | for (fs::directory_iterator hwmonEnt(hwmon_dir); hwmonEnt != fs::directory_iterator(); 90 | ++hwmonEnt) 91 | { 92 | // Skip non relevant entries 93 | if (!fs::is_directory(hwmonEnt->path()) || 94 | !std::regex_match(hwmonEnt->path().filename().string(), hwmonPattern)) 95 | continue; 96 | 97 | unsigned int v = std::stoi(hwmonEnt->path().filename().string().substr(5), nullptr, 10); 98 | hwmonIndex = std::min(hwmonIndex, v); 99 | } 100 | if (hwmonIndex == UINT_MAX) 101 | continue; 102 | 103 | // Detect Pci Id 104 | fs::path uevent_file("/sys/class/drm/" + devName + "/device/uevent"); 105 | if (!fs::exists(uevent_file) || !fs::is_regular_file(uevent_file)) 106 | continue; 107 | 108 | snprintf(dbuf, 120, "/sys/class/drm/card%d/device/uevent", devIndex); 109 | std::ifstream ifs(dbuf, std::ios::binary); 110 | std::string line; 111 | int PciDomain = -1, PciBus = -1, PciDevice = -1, PciFunction = -1; 112 | while (std::getline(ifs, line)) 113 | { 114 | if (line.length() > 24 && line.substr(0, 13) == "PCI_SLOT_NAME") 115 | { 116 | std::string pciId = line.substr(14); 117 | std::vector pciIdParts; 118 | boost::split(pciIdParts, pciId, [](char c) { return (c == ':' || c == '.'); }); 119 | 120 | try 121 | { 122 | PciDomain = std::stoi(pciIdParts.at(0), nullptr, 16); 123 | PciBus = std::stoi(pciIdParts.at(1), nullptr, 16); 124 | PciDevice = std::stoi(pciIdParts.at(2), nullptr, 16); 125 | PciFunction = std::stoi(pciIdParts.at(3), nullptr, 16); 126 | } 127 | catch (const std::exception&) 128 | { 129 | PciDomain = PciBus = PciDevice = PciFunction = -1; 130 | } 131 | break; 132 | } 133 | } 134 | 135 | // If we got an error skip 136 | if (PciDomain == -1) 137 | continue; 138 | 139 | // We got all information needed 140 | // push in the list of collected devices 141 | pciInfo pInfo = pciInfo(); 142 | pInfo.DeviceId = devIndex; 143 | pInfo.HwMonId = hwmonIndex; 144 | pInfo.PciDomain = PciDomain; 145 | pInfo.PciBus = PciBus; 146 | pInfo.PciDevice = PciDevice; 147 | devices.push_back(pInfo); 148 | } 149 | 150 | // Nothing collected - exit 151 | if (!devices.size()) 152 | { 153 | cwarn << "Failed to obtain all required AMD file pointers"; 154 | cwarn << "AMD hardware monitoring disabled"; 155 | return nullptr; 156 | } 157 | 158 | unsigned int gpucount = devices.size(); 159 | sysfsh = (wrap_amdsysfs_handle*)calloc(1, sizeof(wrap_amdsysfs_handle)); 160 | if (sysfsh == nullptr) 161 | { 162 | cwarn << "Failed allocate memory"; 163 | cwarn << "AMD hardware monitoring disabled"; 164 | return sysfsh; 165 | } 166 | sysfsh->sysfs_gpucount = gpucount; 167 | sysfsh->sysfs_device_id = (unsigned int*)calloc(gpucount, sizeof(unsigned int)); 168 | sysfsh->sysfs_hwmon_id = (unsigned int*)calloc(gpucount, sizeof(unsigned int)); 169 | sysfsh->sysfs_pci_domain_id = (unsigned int*)calloc(gpucount, sizeof(unsigned int)); 170 | sysfsh->sysfs_pci_bus_id = (unsigned int*)calloc(gpucount, sizeof(unsigned int)); 171 | sysfsh->sysfs_pci_device_id = (unsigned int*)calloc(gpucount, sizeof(unsigned int)); 172 | 173 | gpucount = 0; 174 | for (auto const& device : devices) 175 | { 176 | sysfsh->sysfs_device_id[gpucount] = device.DeviceId; 177 | sysfsh->sysfs_hwmon_id[gpucount] = device.HwMonId; 178 | sysfsh->sysfs_pci_domain_id[gpucount] = device.PciDomain; 179 | sysfsh->sysfs_pci_bus_id[gpucount] = device.PciBus; 180 | sysfsh->sysfs_pci_device_id[gpucount] = device.PciDevice; 181 | gpucount++; 182 | } 183 | 184 | #endif 185 | return sysfsh; 186 | } 187 | 188 | int wrap_amdsysfs_destroy(wrap_amdsysfs_handle* sysfsh) 189 | { 190 | free(sysfsh); 191 | return 0; 192 | } 193 | 194 | int wrap_amdsysfs_get_gpucount(wrap_amdsysfs_handle* sysfsh, int* gpucount) 195 | { 196 | *gpucount = sysfsh->sysfs_gpucount; 197 | return 0; 198 | } 199 | 200 | int wrap_amdsysfs_get_tempC(wrap_amdsysfs_handle* sysfsh, int index, unsigned int* tempC) 201 | { 202 | if (index < 0 || index >= sysfsh->sysfs_gpucount) 203 | return -1; 204 | 205 | int gpuindex = sysfsh->sysfs_device_id[index]; 206 | 207 | int hwmonindex = sysfsh->sysfs_hwmon_id[index]; 208 | if (hwmonindex < 0) 209 | return -1; 210 | 211 | char dbuf[120]; 212 | snprintf( 213 | dbuf, 120, "/sys/class/drm/card%d/device/hwmon/hwmon%d/temp1_input", gpuindex, hwmonindex); 214 | 215 | unsigned int temp = 0; 216 | getFileContentValue(dbuf, temp); 217 | 218 | if (temp > 0) 219 | *tempC = temp / 1000; 220 | 221 | return 0; 222 | } 223 | 224 | int wrap_amdsysfs_get_fanpcnt(wrap_amdsysfs_handle* sysfsh, int index, unsigned int* fanpcnt) 225 | { 226 | if (index < 0 || index >= sysfsh->sysfs_gpucount) 227 | return -1; 228 | 229 | int gpuindex = sysfsh->sysfs_device_id[index]; 230 | int hwmonindex = sysfsh->sysfs_hwmon_id[index]; 231 | if (hwmonindex < 0) 232 | return -1; 233 | 234 | unsigned int pwm = 0, pwmMax = 255, pwmMin = 0; 235 | 236 | char dbuf[120]; 237 | snprintf(dbuf, 120, "/sys/class/drm/card%d/device/hwmon/hwmon%d/pwm1", gpuindex, hwmonindex); 238 | getFileContentValue(dbuf, pwm); 239 | 240 | snprintf( 241 | dbuf, 120, "/sys/class/drm/card%d/device/hwmon/hwmon%d/pwm1_max", gpuindex, hwmonindex); 242 | getFileContentValue(dbuf, pwmMax); 243 | 244 | snprintf( 245 | dbuf, 120, "/sys/class/drm/card%d/device/hwmon/hwmon%d/pwm1_min", gpuindex, hwmonindex); 246 | getFileContentValue(dbuf, pwmMin); 247 | 248 | *fanpcnt = (unsigned int)(double(pwm - pwmMin) / double(pwmMax - pwmMin) * 100.0); 249 | return 0; 250 | } 251 | 252 | int wrap_amdsysfs_get_power_usage(wrap_amdsysfs_handle* sysfsh, int index, unsigned int* milliwatts) 253 | { 254 | try 255 | { 256 | if (index < 0 || index >= sysfsh->sysfs_gpucount) 257 | return -1; 258 | 259 | int gpuindex = sysfsh->sysfs_device_id[index]; 260 | 261 | char dbuf[120]; 262 | snprintf(dbuf, 120, "/sys/kernel/debug/dri/%d/amdgpu_pm_info", gpuindex); 263 | 264 | std::ifstream ifs(dbuf, std::ios::binary); 265 | std::string line; 266 | 267 | while (std::getline(ifs, line)) 268 | { 269 | std::smatch sm; 270 | std::regex regex(R"(([\d|\.]+) W \(average GPU\))"); 271 | if (std::regex_search(line, sm, regex)) 272 | { 273 | if (sm.size() == 2) 274 | { 275 | double watt = atof(sm.str(1).c_str()); 276 | *milliwatts = (unsigned int)(watt * 1000); 277 | return 0; 278 | } 279 | } 280 | } 281 | } 282 | catch (const std::exception& ex) 283 | { 284 | cwarn << "Error in amdsysfs_get_power_usage: " << ex.what(); 285 | } 286 | 287 | return -1; 288 | } 289 | --------------------------------------------------------------------------------