From 926f9f037e20e9734434a717a036f0472690891d Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 24 Sep 2017 20:03:09 +0200 Subject: [PATCH 01/42] add nvidia backend --- backend/nvidia/autoAdjust.hpp | 112 +++++++ backend/nvidia/config.tpl | 25 ++ backend/nvidia/jconf.cpp | 274 +++++++++++++++++ backend/nvidia/jconf.h | 50 +++ backend/nvidia/minethd.cpp | 268 ++++++++++++++++ backend/nvidia/minethd.h | 65 ++++ backend/nvidia/nvcc_code/cryptonight.h | 44 +++ backend/nvidia/nvcc_code/cuda_aes.hpp | 305 ++++++++++++++++++ backend/nvidia/nvcc_code/cuda_blake.hpp | 193 ++++++++++++ backend/nvidia/nvcc_code/cuda_core.cu | 343 +++++++++++++++++++++ backend/nvidia/nvcc_code/cuda_device.hpp | 30 ++ backend/nvidia/nvcc_code/cuda_extra.cu | 345 +++++++++++++++++++++ backend/nvidia/nvcc_code/cuda_extra.h | 104 +++++++ backend/nvidia/nvcc_code/cuda_groestl.hpp | 357 ++++++++++++++++++++++ backend/nvidia/nvcc_code/cuda_jh.hpp | 301 ++++++++++++++++++ backend/nvidia/nvcc_code/cuda_keccak.hpp | 197 ++++++++++++ backend/nvidia/nvcc_code/cuda_skein.hpp | 347 +++++++++++++++++++++ 17 files changed, 3360 insertions(+) create mode 100644 backend/nvidia/autoAdjust.hpp create mode 100644 backend/nvidia/config.tpl create mode 100644 backend/nvidia/jconf.cpp create mode 100644 backend/nvidia/jconf.h create mode 100644 backend/nvidia/minethd.cpp create mode 100644 backend/nvidia/minethd.h create mode 100644 backend/nvidia/nvcc_code/cryptonight.h create mode 100644 backend/nvidia/nvcc_code/cuda_aes.hpp create mode 100644 backend/nvidia/nvcc_code/cuda_blake.hpp create mode 100644 backend/nvidia/nvcc_code/cuda_core.cu create mode 100644 backend/nvidia/nvcc_code/cuda_device.hpp create mode 100644 backend/nvidia/nvcc_code/cuda_extra.cu create mode 100644 backend/nvidia/nvcc_code/cuda_extra.h create mode 100644 backend/nvidia/nvcc_code/cuda_groestl.hpp create mode 100644 backend/nvidia/nvcc_code/cuda_jh.hpp create mode 100644 backend/nvidia/nvcc_code/cuda_keccak.hpp create mode 100644 backend/nvidia/nvcc_code/cuda_skein.hpp diff --git a/backend/nvidia/autoAdjust.hpp b/backend/nvidia/autoAdjust.hpp new file mode 100644 index 0000000..be9b53d --- /dev/null +++ b/backend/nvidia/autoAdjust.hpp @@ -0,0 +1,112 @@ + +#pragma once + +#include "autoAdjust.hpp" + +#include "nvcc_code/cryptonight.h" +#include "jconf.h" +#include "../../console.h" +#include "../../ConfigEditor.hpp" + +#include +#include +#include +#include + + +namespace xmrstak +{ +namespace nvidia +{ + +class autoAdjust +{ +public: + + autoAdjust() + { + + } + + /** print the adjusted values if needed + * + * Routine exit the application and print the adjusted values if needed else + * nothing is happened. + */ + bool printConfig() + { + int deviceCount = 0; + if(cuda_get_devicecount(&deviceCount) == 0) + std::exit(0); + // evaluate config parameter for if auto adjustment is needed + // evaluate config parameter for if auto adjustment is needed + for(int i = 0; i < deviceCount; i++) + { + + nvid_ctx ctx; + + ctx.device_id = i; + // -1 trigger auto adjustment + ctx.device_blocks = -1; + ctx.device_threads = -1; + + // set all evice option those marked as auto (-1) to a valid value +#ifndef _WIN32 + ctx.device_bfactor = 0; + ctx.device_bsleep = 0; +#else + // windows pass, try to avoid that windows kills the miner if the gpu is blocked for 2 seconds + ctx.device_bfactor = 6; + ctx.device_bsleep = 25; +#endif + if( cuda_get_deviceinfo(&ctx) != 1 ) + { + printer::inst()->print_msg(L0, "Setup failed for GPU %d. Exitting.\n", cfg.id); + std::exit(0); + } + nvidCtxVec.push_back(ctx); + + } + + generateThreadConfig(); + return true; + + } + +private: + + void generateThreadConfig() + { + // load the template of the backend config into a char variable + const char *tpl = + #include "./config.tpl" + ; + + ConfigEditor configTpl{}; + configTpl.set( std::string(tpl) ); + + std::string conf; + conf += std::string("\"gpu_threads_conf\" :\n[\n"); + int i = 0; + for(auto& ctx : nvidCtxVec) + { + + conf += std::string(" { \"index\" : ") + std::to_string(ctx.device_id) + ",\n" + + " \"threads\" : " + std::to_string(ctx.device_threads) + ", \"blocks\" : " + std::to_string(ctx.device_blocks) + ",\n" + + " \"bfactor\" : " + std::to_string(ctx.device_bfactor) + ", \"bsleep\" : " + std::to_string(ctx.device_bsleep) + ",\n" + + " \"affine_to_cpu\" : false,\n" + + " },\n"; + ++i; + } + conf += std::string("],\n\n"); + + configTpl.replace("GPUCONFIG",conf); + configTpl.write("nvidia.txt"); + printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", "nvidia.txt"); + } + + std::vector nvidCtxVec; +}; + +} // namespace nvidia +} // namepsace xmrstak diff --git a/backend/nvidia/config.tpl b/backend/nvidia/config.tpl new file mode 100644 index 0000000..bf7a614 --- /dev/null +++ b/backend/nvidia/config.tpl @@ -0,0 +1,25 @@ +R"===( +/* + * GPU configuration. You should play around with threads and blocks as the fastest settings will vary. + * index - GPU index number usually starts from 0. + * threads - Number of GPU threads (nothing to do with CPU threads). + * blocks - Number of GPU blocks (nothing to do with CPU threads). + * bfactor - Enables running the Cryptonight kernel in smaller pieces. + * Increase if you want to reduce GPU lag. Recommended setting on GUI systems - 8 + * bsleep - Insert a delay of X microseconds between kernel launches. + * Increase if you want to reduce GPU lag. Recommended setting on GUI systems - 100 + * affine_to_cpu - This will affine the thread to a CPU. This can make a GPU miner play along nicer with a CPU miner. + * + * On the first run the miner will look at your system and suggest a basic configuration that will work, + * you can try to tweak it from there to get the best performance. + * + * A filled out configuration should look like this: + * "gpu_threads_conf" : + * [ + * { "index" : 0, "threads" : 17, "blocks" : 60, "bfactor" : 0, "bsleep" : 0, "affine_to_cpu" : false}, + * ], + */ + +GPUCONFIG + +)===" diff --git a/backend/nvidia/jconf.cpp b/backend/nvidia/jconf.cpp new file mode 100644 index 0000000..2184acd --- /dev/null +++ b/backend/nvidia/jconf.cpp @@ -0,0 +1,274 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining + * it with OpenSSL (or a modified version of that library), containing parts + * covered by the terms of OpenSSL License and SSLeay License, the licensors + * of this Program grant you additional permission to convey the resulting work. + * + */ + +#include "jconf.h" + +#include +#include +#include + +#ifdef _WIN32 +#define strcasecmp _stricmp +#include +#else +#include +#endif + +#include "../../rapidjson/document.h" +#include "../../rapidjson/error/en.h" +#include "../../jext.h" +#include "../../console.h" + +namespace xmrstak +{ +namespace nvidia +{ + +using namespace rapidjson; + +/* + * This enum needs to match index in oConfigValues, otherwise we will get a runtime error + */ +enum configEnum { aGpuThreadsConf }; + +struct configVal { + configEnum iName; + const char* sName; + Type iType; +}; + +// Same order as in configEnum, as per comment above +// kNullType means any type +configVal oConfigValues[] = { + { aGpuThreadsConf, "gpu_threads_conf", kNullType } +}; + +inline bool checkType(Type have, Type want) +{ + if(want == have) + return true; + else if(want == kNullType) + return true; + else if(want == kTrueType && have == kFalseType) + return true; + else if(want == kFalseType && have == kTrueType) + return true; + else + return false; +} + +constexpr size_t iConfigCnt = (sizeof(oConfigValues)/sizeof(oConfigValues[0])); + + + +struct jconf::opaque_private +{ + Document jsonDoc; + const Value* configValues[iConfigCnt]; //Compile time constant + + opaque_private() + { + } +}; + + +bool jconf::NeedsAutoconf() +{ + return !prv->configValues[aGpuThreadsConf]->IsArray(); +} + +jconf* jconf::oInst = nullptr; + +jconf::jconf() +{ + prv = new opaque_private(); +} + +size_t jconf::GetGPUThreadCount() +{ + if(prv->configValues[aGpuThreadsConf]->IsArray()) + return prv->configValues[aGpuThreadsConf]->Size(); + else + return 0; +} + +bool jconf::GetGPUThreadConfig(size_t id, thd_cfg &cfg) +{ + if(!prv->configValues[aGpuThreadsConf]->IsArray()) + return false; + + if(id >= prv->configValues[aGpuThreadsConf]->Size()) + return false; + + const Value& oThdConf = prv->configValues[aGpuThreadsConf]->GetArray()[id]; + + if(!oThdConf.IsObject()) + return false; + + const Value *gid, *blocks, *threads, *bfactor, *bsleep, *aff; + gid = GetObjectMember(oThdConf, "index"); + blocks = GetObjectMember(oThdConf, "blocks"); + threads = GetObjectMember(oThdConf, "threads"); + bfactor = GetObjectMember(oThdConf, "bfactor"); + bsleep = GetObjectMember(oThdConf, "bsleep"); + aff = GetObjectMember(oThdConf, "affine_to_cpu"); + + if(gid == nullptr || blocks == nullptr || threads == nullptr || + bfactor == nullptr || bsleep == nullptr || aff == nullptr) + { + return false; + } + + if(!gid->IsNumber() || gid->GetInt() < 0) + return false; + + if(!blocks->IsNumber() || blocks->GetInt() < 0) + return false; + + if(!threads->IsNumber() || threads->GetInt() < 0) + return false; + + if(!bfactor->IsNumber() || bfactor->GetInt() < 0) + return false; + + if(!bsleep->IsNumber() || bsleep->GetInt() < 0) + return false; + + if(!aff->IsUint64() && !aff->IsBool()) + return false; + + cfg.id = gid->GetInt(); + cfg.blocks = blocks->GetInt(); + cfg.threads = threads->GetInt(); + cfg.bfactor = bfactor->GetInt(); + cfg.bsleep = bsleep->GetInt(); + + if(aff->IsNumber()) + cfg.cpu_aff = aff->GetInt(); + else + cfg.cpu_aff = -1; + + return true; +} + +bool jconf::parse_config(const char* sFilename) +{ + FILE * pFile; + char * buffer; + size_t flen; + + pFile = fopen(sFilename, "rb"); + if (pFile == NULL) + { + printer::inst()->print_msg(L0, "Failed to open config file %s.", sFilename); + return false; + } + + fseek(pFile,0,SEEK_END); + flen = ftell(pFile); + rewind(pFile); + + if(flen >= 64*1024) + { + fclose(pFile); + printer::inst()->print_msg(L0, "Oversized config file - %s.", sFilename); + return false; + } + + if(flen <= 16) + { + fclose(pFile); + printer::inst()->print_msg(L0, "File is empty or too short - %s.", sFilename); + return false; + } + + buffer = (char*)malloc(flen + 3); + if(fread(buffer+1, flen, 1, pFile) != 1) + { + free(buffer); + fclose(pFile); + printer::inst()->print_msg(L0, "Read error while reading %s.", sFilename); + return false; + } + fclose(pFile); + + //Replace Unicode BOM with spaces - we always use UTF-8 + unsigned char* ubuffer = (unsigned char*)buffer; + if(ubuffer[1] == 0xEF && ubuffer[2] == 0xBB && ubuffer[3] == 0xBF) + { + buffer[1] = ' '; + buffer[2] = ' '; + buffer[3] = ' '; + } + + buffer[0] = '{'; + buffer[flen] = '}'; + buffer[flen + 1] = '\0'; + + prv->jsonDoc.Parse(buffer, flen+2); + free(buffer); + + if(prv->jsonDoc.HasParseError()) + { + printer::inst()->print_msg(L0, "JSON config parse error(offset %llu): %s", + int_port(prv->jsonDoc.GetErrorOffset()), GetParseError_En(prv->jsonDoc.GetParseError())); + return false; + } + + + if(!prv->jsonDoc.IsObject()) + { //This should never happen as we created the root ourselves + printer::inst()->print_msg(L0, "Invalid config file. No root?\n"); + return false; + } + + for(size_t i = 0; i < iConfigCnt; i++) + { + if(oConfigValues[i].iName != i) + { + printer::inst()->print_msg(L0, "Code error. oConfigValues are not in order. %s",oConfigValues[i].sName); + return false; + } + + prv->configValues[i] = GetObjectMember(prv->jsonDoc, oConfigValues[i].sName); + + if(prv->configValues[i] == nullptr) + { + printer::inst()->print_msg(L0, "Invalid config file. Missing value \"%s\".", oConfigValues[i].sName); + return false; + } + + if(!checkType(prv->configValues[i]->GetType(), oConfigValues[i].iType)) + { + printer::inst()->print_msg(L0, "Invalid config file. Value \"%s\" has unexpected type.", oConfigValues[i].sName); + return false; + } + } + if(NeedsAutoconf()) + return true; + + return true; +} + +} // namespace nvidia +} // namespace xmrstak \ No newline at end of file diff --git a/backend/nvidia/jconf.h b/backend/nvidia/jconf.h new file mode 100644 index 0000000..e398f30 --- /dev/null +++ b/backend/nvidia/jconf.h @@ -0,0 +1,50 @@ +#pragma once +#include +#include + +namespace xmrstak +{ +namespace nvidia +{ + +class jconf +{ +public: + static jconf* inst() + { + if (oInst == nullptr) oInst = new jconf; + return oInst; + }; + + bool parse_config(const char* sFilename = "nvidia.txt"); + + struct thd_cfg { + uint32_t id; + uint32_t blocks; + uint32_t threads; + uint32_t bfactor; + uint32_t bsleep; + bool bDoubleMode; + bool bNoPrefetch; + int32_t cpu_aff; + + long long iCpuAff; + }; + + size_t GetGPUThreadCount(); + + bool GetGPUThreadConfig(size_t id, thd_cfg &cfg); + + bool NeedsAutoconf(); + +private: + jconf(); + static jconf* oInst; + + struct opaque_private; + opaque_private* prv; + +}; + +} // namespace nvidia +} // namepsace xmrstak diff --git a/backend/nvidia/minethd.cpp b/backend/nvidia/minethd.cpp new file mode 100644 index 0000000..9a331f3 --- /dev/null +++ b/backend/nvidia/minethd.cpp @@ -0,0 +1,268 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining + * it with OpenSSL (or a modified version of that library), containing parts + * covered by the terms of OpenSSL License and SSLeay License, the licensors + * of this Program grant you additional permission to convey the resulting work. + * + */ + +#include +#include +#include +#include +#include +#include +#include "../../console.h" +#include "../../crypto/cryptonight_aesni.h" +#include "../cpu/minethd.h" +#include "../cpu/jconf.h" + +#include "../../executor.h" +#include "minethd.h" +#include "../../jconf.h" +#include "../../crypto/cryptonight.h" +#include "autoAdjust.hpp" + + +#ifndef USE_PRECOMPILED_HEADERS +#ifdef WIN32 +#include +#include +#else +#include +#include +#endif +#include +#endif + +namespace xmrstak +{ +namespace nvidia +{ + +#ifdef WIN32 + HINSTANCE lib_handle; +#else + void *lib_handle; +#endif + +minethd::minethd(miner_work& pWork, size_t iNo, const jconf::thd_cfg& cfg) +{ + oWork = pWork; + bQuit = 0; + iThreadNo = (uint8_t)iNo; + iJobNo = 0; + + ctx.device_id = (int)cfg.id; + ctx.device_blocks = (int)cfg.blocks; + ctx.device_threads = (int)cfg.threads; + ctx.device_bfactor = (int)cfg.bfactor; + ctx.device_bsleep = (int)cfg.bsleep; + + oWorkThd = std::thread(&minethd::work_main, this); +} + + +bool minethd::self_test() +{ + cryptonight_ctx* ctx0; + unsigned char out[32]; + bool bResult = true; + + ctx0 = new cryptonight_ctx; + if(cpu::jconf::inst()->HaveHardwareAes()) + { + //cryptonight_hash_ctx("This is a test", 14, out, ctx0); + bResult = memcmp(out, "\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 32) == 0; + } + else + { + //cryptonight_hash_ctx_soft("This is a test", 14, out, ctx0); + bResult = memcmp(out, "\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 32) == 0; + } + delete ctx0; + + //if(!bResult) + // printer::inst()->print_msg(L0, + // "Cryptonight hash self-test failed. This might be caused by bad compiler optimizations."); + + return bResult; +} + + +extern "C" std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork) +{ + return nvidia::minethd::thread_starter(threadOffset, pWork); +} + +std::vector* minethd::thread_starter(uint32_t threadOffset, miner_work& pWork) +{ + std::vector* pvThreads = new std::vector(); + + if(!ConfigEditor::file_exist("nvidia.txt")) + { + autoAdjust adjust; + if(!adjust.printConfig()) + return pvThreads; + } + + if(!jconf::inst()->parse_config("nvidia.txt")) + { + win_exit(); + } + + int deviceCount = 0; + if(cuda_get_devicecount(&deviceCount) != 1) + { + std::cout<<"WARNING: NVIDIA no device found"<GetGPUThreadCount(); + pvThreads->reserve(n); + + jconf::thd_cfg cfg; + for (i = 0; i < n; i++) + { + jconf::inst()->GetGPUThreadConfig(i, cfg); + minethd* thd = new minethd(pWork, i + threadOffset, cfg); + + if(cfg.cpu_aff >= 0) + { +#if defined(__APPLE__) + printer::inst()->print_msg(L1, "WARNING on MacOS thread affinity is only advisory."); +#endif + cpu::minethd::thd_setaffinity(thd->oWorkThd.native_handle(), cfg.cpu_aff); + } + + pvThreads->push_back(thd); + + if(cfg.cpu_aff >= 0) + printer::inst()->print_msg(L1, "Starting GPU thread, affinity: %d.", (int)cfg.cpu_aff); + else + printer::inst()->print_msg(L1, "Starting GPU thread, no affinity."); + } + + return pvThreads; +} + +void minethd::switch_work(miner_work& pWork) +{ + // iConsumeCnt is a basic lock-like polling mechanism just in case we happen to push work + // faster than threads can consume them. This should never happen in real life. + // Pool cant physically send jobs faster than every 250ms or so due to net latency. + + while (GlobalStates::iConsumeCnt.load(std::memory_order_seq_cst) < GlobalStates::iThreadCount) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + GlobalStates::oGlobalWork = pWork; + GlobalStates::iConsumeCnt.store(0, std::memory_order_seq_cst); + GlobalStates::iGlobalJobNo++; +} + +void minethd::consume_work() +{ + memcpy(&oWork, &GlobalStates::oGlobalWork, sizeof(miner_work)); + iJobNo++; + GlobalStates::iConsumeCnt++; +} + +void minethd::work_main() +{ + uint64_t iCount = 0; + uint32_t iNonce; + cryptonight_ctx* cpu_ctx; + cpu_ctx = cpu::minethd::minethd_alloc_ctx(); + cn_hash_fun hash_fun = cpu::minethd::func_selector(cpu::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/); + + GlobalStates::iConsumeCnt++; + + if(/*cuda_get_deviceinfo(&ctx) != 1 ||*/ cryptonight_extra_cpu_init(&ctx) != 1) + { + printer::inst()->print_msg(L0, "Setup failed for GPU %d. Exitting.\n", (int)iThreadNo); + std::exit(0); + } + + while (bQuit == 0) + { + if (oWork.bStall) + { + /* We are stalled here because the executor didn't find a job for us yet, + either because of network latency, or a socket problem. Since we are + raison d'etre of this software it us sensible to just wait until we have something*/ + + while (GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + consume_work(); + continue; + } + + cryptonight_extra_cpu_set_data(&ctx, oWork.bWorkBlob, oWork.iWorkSize); + iNonce = calc_start_nonce(oWork.iResumeCnt); + + assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); + + while(GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + { + + uint32_t foundNonce[10]; + uint32_t foundCount; + + cryptonight_extra_cpu_prepare(&ctx, iNonce); + cryptonight_core_cpu_hash(&ctx); + cryptonight_extra_cpu_final(&ctx, iNonce, oWork.iTarget, &foundCount, foundNonce); + + for(size_t i = 0; i < foundCount; i++) + { + + uint8_t bWorkBlob[112]; + uint8_t bResult[32]; + + memcpy(bWorkBlob, oWork.bWorkBlob, oWork.iWorkSize); + memset(bResult, 0, sizeof(job_result::bResult)); + + *(uint32_t*)(bWorkBlob + 39) = foundNonce[i]; + + hash_fun(bWorkBlob, oWork.iWorkSize, bResult, cpu_ctx); + if ( (*((uint64_t*)(bResult + 24))) < oWork.iTarget) + { + std::cout<<"found NVIDIA"<push_event(ex_event(job_result(oWork.sJobID, foundNonce[i], bResult), oWork.iPoolId)); + } + else + std::cout<<"wrong NVIDIA"<(high_resolution_clock::now()).time_since_epoch().count(); + iHashCount.store(iCount, std::memory_order_relaxed); + iTimestamp.store(iStamp, std::memory_order_relaxed); + std::this_thread::yield(); + } + + consume_work(); + } +} + +} // namespace xmrstak + +} //namespace nvidia diff --git a/backend/nvidia/minethd.h b/backend/nvidia/minethd.h new file mode 100644 index 0000000..a4b095e --- /dev/null +++ b/backend/nvidia/minethd.h @@ -0,0 +1,65 @@ +#pragma once +#include +#include +#include +#include "nvcc_code/cryptonight.h" +#include "../../crypto/cryptonight.h" +#include "../../jconf.h" +#include "./jconf.h" +#include "../IBackend.hpp" +#include + +namespace xmrstak +{ +namespace nvidia +{ + +class minethd : public IBackend +{ +public: + + static void switch_work(miner_work& pWork); + static std::vector* thread_starter(uint32_t threadOffset, miner_work& pWork); + static bool self_test(); + +private: + typedef void (*cn_hash_fun)(const void*, size_t, void*, cryptonight_ctx*); + + minethd(miner_work& pWork, size_t iNo, const jconf::thd_cfg& cfg); + + // We use the top 10 bits of the nonce for thread and resume + // This allows us to resume up to 128 threads 4 times before + // we get nonce collisions + // Bottom 22 bits allow for an hour of work at 1000 H/s + inline uint32_t calc_start_nonce(uint32_t resume) + { + return reverseBits(iThreadNo + GlobalStates::iThreadCount * resume); + } + + // Limited version of the nonce calc above + inline uint32_t calc_nicehash_nonce(uint32_t start, uint32_t resume) + { + return start | ( ( reverseBits(iThreadNo + GlobalStates::iThreadCount * resume) >> 4u ) ); + } + + void work_main(); + void consume_work(); + + static std::atomic iGlobalJobNo; + static std::atomic iConsumeCnt; + static uint64_t iThreadCount; + uint64_t iJobNo; + + static miner_work oGlobalWork; + miner_work oWork; + + std::thread oWorkThd; + uint8_t iThreadNo; + + nvid_ctx ctx; + + bool bQuit; +}; + +} // namespace nvidia +} // namepsace xmrstak diff --git a/backend/nvidia/nvcc_code/cryptonight.h b/backend/nvidia/nvcc_code/cryptonight.h new file mode 100644 index 0000000..bec9997 --- /dev/null +++ b/backend/nvidia/nvcc_code/cryptonight.h @@ -0,0 +1,44 @@ +#pragma once + +#include + +typedef struct { + int device_id; + const char *device_name; + int device_arch[2]; + int device_mpcount; + int device_blocks; + int device_threads; + int device_bfactor; + int device_bsleep; + + uint32_t *d_input; + uint32_t inputlen; + uint32_t *d_result_count; + uint32_t *d_result_nonce; + uint32_t *d_long_state; + uint32_t *d_ctx_state; + uint32_t *d_ctx_a; + uint32_t *d_ctx_b; + uint32_t *d_ctx_key1; + uint32_t *d_ctx_key2; + uint32_t *d_ctx_text; +} nvid_ctx; + +extern "C" { + +/** get device count + * + * @param deviceCount[out] cuda device count + * @return error code: 0 == error is occurred, 1 == no error + */ +int cuda_get_devicecount( int* deviceCount); +int cuda_get_deviceinfo(nvid_ctx *ctx); +int cryptonight_extra_cpu_init(nvid_ctx *ctx); +void cryptonight_extra_cpu_set_data( nvid_ctx* ctx, const void *data, uint32_t len); +void cryptonight_extra_cpu_prepare(nvid_ctx* ctx, uint32_t startNonce); +void cryptonight_core_cpu_hash(nvid_ctx* ctx); +void cryptonight_extra_cpu_final(nvid_ctx* ctx, uint32_t startNonce, uint64_t target, uint32_t* rescount, uint32_t *resnonce); + +} + diff --git a/backend/nvidia/nvcc_code/cuda_aes.hpp b/backend/nvidia/nvcc_code/cuda_aes.hpp new file mode 100644 index 0000000..e478600 --- /dev/null +++ b/backend/nvidia/nvcc_code/cuda_aes.hpp @@ -0,0 +1,305 @@ + +#pragma once + +#include + +#define N_COLS 4 +#define WPOLY 0x011b + +static __constant__ uint32_t d_t_fn[1024] = +{ + 0xa56363c6U, 0x847c7cf8U, 0x997777eeU, 0x8d7b7bf6U, + 0x0df2f2ffU, 0xbd6b6bd6U, 0xb16f6fdeU, 0x54c5c591U, + 0x50303060U, 0x03010102U, 0xa96767ceU, 0x7d2b2b56U, + 0x19fefee7U, 0x62d7d7b5U, 0xe6abab4dU, 0x9a7676ecU, + 0x45caca8fU, 0x9d82821fU, 0x40c9c989U, 0x877d7dfaU, + 0x15fafaefU, 0xeb5959b2U, 0xc947478eU, 0x0bf0f0fbU, + 0xecadad41U, 0x67d4d4b3U, 0xfda2a25fU, 0xeaafaf45U, + 0xbf9c9c23U, 0xf7a4a453U, 0x967272e4U, 0x5bc0c09bU, + 0xc2b7b775U, 0x1cfdfde1U, 0xae93933dU, 0x6a26264cU, + 0x5a36366cU, 0x413f3f7eU, 0x02f7f7f5U, 0x4fcccc83U, + 0x5c343468U, 0xf4a5a551U, 0x34e5e5d1U, 0x08f1f1f9U, + 0x937171e2U, 0x73d8d8abU, 0x53313162U, 0x3f15152aU, + 0x0c040408U, 0x52c7c795U, 0x65232346U, 0x5ec3c39dU, + 0x28181830U, 0xa1969637U, 0x0f05050aU, 0xb59a9a2fU, + 0x0907070eU, 0x36121224U, 0x9b80801bU, 0x3de2e2dfU, + 0x26ebebcdU, 0x6927274eU, 0xcdb2b27fU, 0x9f7575eaU, + 0x1b090912U, 0x9e83831dU, 0x742c2c58U, 0x2e1a1a34U, + 0x2d1b1b36U, 0xb26e6edcU, 0xee5a5ab4U, 0xfba0a05bU, + 0xf65252a4U, 0x4d3b3b76U, 0x61d6d6b7U, 0xceb3b37dU, + 0x7b292952U, 0x3ee3e3ddU, 0x712f2f5eU, 0x97848413U, + 0xf55353a6U, 0x68d1d1b9U, 0x00000000U, 0x2cededc1U, + 0x60202040U, 0x1ffcfce3U, 0xc8b1b179U, 0xed5b5bb6U, + 0xbe6a6ad4U, 0x46cbcb8dU, 0xd9bebe67U, 0x4b393972U, + 0xde4a4a94U, 0xd44c4c98U, 0xe85858b0U, 0x4acfcf85U, + 0x6bd0d0bbU, 0x2aefefc5U, 0xe5aaaa4fU, 0x16fbfbedU, + 0xc5434386U, 0xd74d4d9aU, 0x55333366U, 0x94858511U, + 0xcf45458aU, 0x10f9f9e9U, 0x06020204U, 0x817f7ffeU, + 0xf05050a0U, 0x443c3c78U, 0xba9f9f25U, 0xe3a8a84bU, + 0xf35151a2U, 0xfea3a35dU, 0xc0404080U, 0x8a8f8f05U, + 0xad92923fU, 0xbc9d9d21U, 0x48383870U, 0x04f5f5f1U, + 0xdfbcbc63U, 0xc1b6b677U, 0x75dadaafU, 0x63212142U, + 0x30101020U, 0x1affffe5U, 0x0ef3f3fdU, 0x6dd2d2bfU, + 0x4ccdcd81U, 0x140c0c18U, 0x35131326U, 0x2fececc3U, + 0xe15f5fbeU, 0xa2979735U, 0xcc444488U, 0x3917172eU, + 0x57c4c493U, 0xf2a7a755U, 0x827e7efcU, 0x473d3d7aU, + 0xac6464c8U, 0xe75d5dbaU, 0x2b191932U, 0x957373e6U, + 0xa06060c0U, 0x98818119U, 0xd14f4f9eU, 0x7fdcdca3U, + 0x66222244U, 0x7e2a2a54U, 0xab90903bU, 0x8388880bU, + 0xca46468cU, 0x29eeeec7U, 0xd3b8b86bU, 0x3c141428U, + 0x79dedea7U, 0xe25e5ebcU, 0x1d0b0b16U, 0x76dbdbadU, + 0x3be0e0dbU, 0x56323264U, 0x4e3a3a74U, 0x1e0a0a14U, + 0xdb494992U, 0x0a06060cU, 0x6c242448U, 0xe45c5cb8U, + 0x5dc2c29fU, 0x6ed3d3bdU, 0xefacac43U, 0xa66262c4U, + 0xa8919139U, 0xa4959531U, 0x37e4e4d3U, 0x8b7979f2U, + 0x32e7e7d5U, 0x43c8c88bU, 0x5937376eU, 0xb76d6ddaU, + 0x8c8d8d01U, 0x64d5d5b1U, 0xd24e4e9cU, 0xe0a9a949U, + 0xb46c6cd8U, 0xfa5656acU, 0x07f4f4f3U, 0x25eaeacfU, + 0xaf6565caU, 0x8e7a7af4U, 0xe9aeae47U, 0x18080810U, + 0xd5baba6fU, 0x887878f0U, 0x6f25254aU, 0x722e2e5cU, + 0x241c1c38U, 0xf1a6a657U, 0xc7b4b473U, 0x51c6c697U, + 0x23e8e8cbU, 0x7cdddda1U, 0x9c7474e8U, 0x211f1f3eU, + 0xdd4b4b96U, 0xdcbdbd61U, 0x868b8b0dU, 0x858a8a0fU, + 0x907070e0U, 0x423e3e7cU, 0xc4b5b571U, 0xaa6666ccU, + 0xd8484890U, 0x05030306U, 0x01f6f6f7U, 0x120e0e1cU, + 0xa36161c2U, 0x5f35356aU, 0xf95757aeU, 0xd0b9b969U, + 0x91868617U, 0x58c1c199U, 0x271d1d3aU, 0xb99e9e27U, + 0x38e1e1d9U, 0x13f8f8ebU, 0xb398982bU, 0x33111122U, + 0xbb6969d2U, 0x70d9d9a9U, 0x898e8e07U, 0xa7949433U, + 0xb69b9b2dU, 0x221e1e3cU, 0x92878715U, 0x20e9e9c9U, + 0x49cece87U, 0xff5555aaU, 0x78282850U, 0x7adfdfa5U, + 0x8f8c8c03U, 0xf8a1a159U, 0x80898909U, 0x170d0d1aU, + 0xdabfbf65U, 0x31e6e6d7U, 0xc6424284U, 0xb86868d0U, + 0xc3414182U, 0xb0999929U, 0x772d2d5aU, 0x110f0f1eU, + 0xcbb0b07bU, 0xfc5454a8U, 0xd6bbbb6dU, 0x3a16162cU, + 0x6363c6a5U, 0x7c7cf884U, 0x7777ee99U, 0x7b7bf68dU, + 0xf2f2ff0dU, 0x6b6bd6bdU, 0x6f6fdeb1U, 0xc5c59154U, + 0x30306050U, 0x01010203U, 0x6767cea9U, 0x2b2b567dU, + 0xfefee719U, 0xd7d7b562U, 0xabab4de6U, 0x7676ec9aU, + 0xcaca8f45U, 0x82821f9dU, 0xc9c98940U, 0x7d7dfa87U, + 0xfafaef15U, 0x5959b2ebU, 0x47478ec9U, 0xf0f0fb0bU, + 0xadad41ecU, 0xd4d4b367U, 0xa2a25ffdU, 0xafaf45eaU, + 0x9c9c23bfU, 0xa4a453f7U, 0x7272e496U, 0xc0c09b5bU, + 0xb7b775c2U, 0xfdfde11cU, 0x93933daeU, 0x26264c6aU, + 0x36366c5aU, 0x3f3f7e41U, 0xf7f7f502U, 0xcccc834fU, + 0x3434685cU, 0xa5a551f4U, 0xe5e5d134U, 0xf1f1f908U, + 0x7171e293U, 0xd8d8ab73U, 0x31316253U, 0x15152a3fU, + 0x0404080cU, 0xc7c79552U, 0x23234665U, 0xc3c39d5eU, + 0x18183028U, 0x969637a1U, 0x05050a0fU, 0x9a9a2fb5U, + 0x07070e09U, 0x12122436U, 0x80801b9bU, 0xe2e2df3dU, + 0xebebcd26U, 0x27274e69U, 0xb2b27fcdU, 0x7575ea9fU, + 0x0909121bU, 0x83831d9eU, 0x2c2c5874U, 0x1a1a342eU, + 0x1b1b362dU, 0x6e6edcb2U, 0x5a5ab4eeU, 0xa0a05bfbU, + 0x5252a4f6U, 0x3b3b764dU, 0xd6d6b761U, 0xb3b37dceU, + 0x2929527bU, 0xe3e3dd3eU, 0x2f2f5e71U, 0x84841397U, + 0x5353a6f5U, 0xd1d1b968U, 0x00000000U, 0xededc12cU, + 0x20204060U, 0xfcfce31fU, 0xb1b179c8U, 0x5b5bb6edU, + 0x6a6ad4beU, 0xcbcb8d46U, 0xbebe67d9U, 0x3939724bU, + 0x4a4a94deU, 0x4c4c98d4U, 0x5858b0e8U, 0xcfcf854aU, + 0xd0d0bb6bU, 0xefefc52aU, 0xaaaa4fe5U, 0xfbfbed16U, + 0x434386c5U, 0x4d4d9ad7U, 0x33336655U, 0x85851194U, + 0x45458acfU, 0xf9f9e910U, 0x02020406U, 0x7f7ffe81U, + 0x5050a0f0U, 0x3c3c7844U, 0x9f9f25baU, 0xa8a84be3U, + 0x5151a2f3U, 0xa3a35dfeU, 0x404080c0U, 0x8f8f058aU, + 0x92923fadU, 0x9d9d21bcU, 0x38387048U, 0xf5f5f104U, + 0xbcbc63dfU, 0xb6b677c1U, 0xdadaaf75U, 0x21214263U, + 0x10102030U, 0xffffe51aU, 0xf3f3fd0eU, 0xd2d2bf6dU, + 0xcdcd814cU, 0x0c0c1814U, 0x13132635U, 0xececc32fU, + 0x5f5fbee1U, 0x979735a2U, 0x444488ccU, 0x17172e39U, + 0xc4c49357U, 0xa7a755f2U, 0x7e7efc82U, 0x3d3d7a47U, + 0x6464c8acU, 0x5d5dbae7U, 0x1919322bU, 0x7373e695U, + 0x6060c0a0U, 0x81811998U, 0x4f4f9ed1U, 0xdcdca37fU, + 0x22224466U, 0x2a2a547eU, 0x90903babU, 0x88880b83U, + 0x46468ccaU, 0xeeeec729U, 0xb8b86bd3U, 0x1414283cU, + 0xdedea779U, 0x5e5ebce2U, 0x0b0b161dU, 0xdbdbad76U, + 0xe0e0db3bU, 0x32326456U, 0x3a3a744eU, 0x0a0a141eU, + 0x494992dbU, 0x06060c0aU, 0x2424486cU, 0x5c5cb8e4U, + 0xc2c29f5dU, 0xd3d3bd6eU, 0xacac43efU, 0x6262c4a6U, + 0x919139a8U, 0x959531a4U, 0xe4e4d337U, 0x7979f28bU, + 0xe7e7d532U, 0xc8c88b43U, 0x37376e59U, 0x6d6ddab7U, + 0x8d8d018cU, 0xd5d5b164U, 0x4e4e9cd2U, 0xa9a949e0U, + 0x6c6cd8b4U, 0x5656acfaU, 0xf4f4f307U, 0xeaeacf25U, + 0x6565caafU, 0x7a7af48eU, 0xaeae47e9U, 0x08081018U, + 0xbaba6fd5U, 0x7878f088U, 0x25254a6fU, 0x2e2e5c72U, + 0x1c1c3824U, 0xa6a657f1U, 0xb4b473c7U, 0xc6c69751U, + 0xe8e8cb23U, 0xdddda17cU, 0x7474e89cU, 0x1f1f3e21U, + 0x4b4b96ddU, 0xbdbd61dcU, 0x8b8b0d86U, 0x8a8a0f85U, + 0x7070e090U, 0x3e3e7c42U, 0xb5b571c4U, 0x6666ccaaU, + 0x484890d8U, 0x03030605U, 0xf6f6f701U, 0x0e0e1c12U, + 0x6161c2a3U, 0x35356a5fU, 0x5757aef9U, 0xb9b969d0U, + 0x86861791U, 0xc1c19958U, 0x1d1d3a27U, 0x9e9e27b9U, + 0xe1e1d938U, 0xf8f8eb13U, 0x98982bb3U, 0x11112233U, + 0x6969d2bbU, 0xd9d9a970U, 0x8e8e0789U, 0x949433a7U, + 0x9b9b2db6U, 0x1e1e3c22U, 0x87871592U, 0xe9e9c920U, + 0xcece8749U, 0x5555aaffU, 0x28285078U, 0xdfdfa57aU, + 0x8c8c038fU, 0xa1a159f8U, 0x89890980U, 0x0d0d1a17U, + 0xbfbf65daU, 0xe6e6d731U, 0x424284c6U, 0x6868d0b8U, + 0x414182c3U, 0x999929b0U, 0x2d2d5a77U, 0x0f0f1e11U, + 0xb0b07bcbU, 0x5454a8fcU, 0xbbbb6dd6U, 0x16162c3aU, + 0x63c6a563U, 0x7cf8847cU, 0x77ee9977U, 0x7bf68d7bU, + 0xf2ff0df2U, 0x6bd6bd6bU, 0x6fdeb16fU, 0xc59154c5U, + 0x30605030U, 0x01020301U, 0x67cea967U, 0x2b567d2bU, + 0xfee719feU, 0xd7b562d7U, 0xab4de6abU, 0x76ec9a76U, + 0xca8f45caU, 0x821f9d82U, 0xc98940c9U, 0x7dfa877dU, + 0xfaef15faU, 0x59b2eb59U, 0x478ec947U, 0xf0fb0bf0U, + 0xad41ecadU, 0xd4b367d4U, 0xa25ffda2U, 0xaf45eaafU, + 0x9c23bf9cU, 0xa453f7a4U, 0x72e49672U, 0xc09b5bc0U, + 0xb775c2b7U, 0xfde11cfdU, 0x933dae93U, 0x264c6a26U, + 0x366c5a36U, 0x3f7e413fU, 0xf7f502f7U, 0xcc834fccU, + 0x34685c34U, 0xa551f4a5U, 0xe5d134e5U, 0xf1f908f1U, + 0x71e29371U, 0xd8ab73d8U, 0x31625331U, 0x152a3f15U, + 0x04080c04U, 0xc79552c7U, 0x23466523U, 0xc39d5ec3U, + 0x18302818U, 0x9637a196U, 0x050a0f05U, 0x9a2fb59aU, + 0x070e0907U, 0x12243612U, 0x801b9b80U, 0xe2df3de2U, + 0xebcd26ebU, 0x274e6927U, 0xb27fcdb2U, 0x75ea9f75U, + 0x09121b09U, 0x831d9e83U, 0x2c58742cU, 0x1a342e1aU, + 0x1b362d1bU, 0x6edcb26eU, 0x5ab4ee5aU, 0xa05bfba0U, + 0x52a4f652U, 0x3b764d3bU, 0xd6b761d6U, 0xb37dceb3U, + 0x29527b29U, 0xe3dd3ee3U, 0x2f5e712fU, 0x84139784U, + 0x53a6f553U, 0xd1b968d1U, 0x00000000U, 0xedc12cedU, + 0x20406020U, 0xfce31ffcU, 0xb179c8b1U, 0x5bb6ed5bU, + 0x6ad4be6aU, 0xcb8d46cbU, 0xbe67d9beU, 0x39724b39U, + 0x4a94de4aU, 0x4c98d44cU, 0x58b0e858U, 0xcf854acfU, + 0xd0bb6bd0U, 0xefc52aefU, 0xaa4fe5aaU, 0xfbed16fbU, + 0x4386c543U, 0x4d9ad74dU, 0x33665533U, 0x85119485U, + 0x458acf45U, 0xf9e910f9U, 0x02040602U, 0x7ffe817fU, + 0x50a0f050U, 0x3c78443cU, 0x9f25ba9fU, 0xa84be3a8U, + 0x51a2f351U, 0xa35dfea3U, 0x4080c040U, 0x8f058a8fU, + 0x923fad92U, 0x9d21bc9dU, 0x38704838U, 0xf5f104f5U, + 0xbc63dfbcU, 0xb677c1b6U, 0xdaaf75daU, 0x21426321U, + 0x10203010U, 0xffe51affU, 0xf3fd0ef3U, 0xd2bf6dd2U, + 0xcd814ccdU, 0x0c18140cU, 0x13263513U, 0xecc32fecU, + 0x5fbee15fU, 0x9735a297U, 0x4488cc44U, 0x172e3917U, + 0xc49357c4U, 0xa755f2a7U, 0x7efc827eU, 0x3d7a473dU, + 0x64c8ac64U, 0x5dbae75dU, 0x19322b19U, 0x73e69573U, + 0x60c0a060U, 0x81199881U, 0x4f9ed14fU, 0xdca37fdcU, + 0x22446622U, 0x2a547e2aU, 0x903bab90U, 0x880b8388U, + 0x468cca46U, 0xeec729eeU, 0xb86bd3b8U, 0x14283c14U, + 0xdea779deU, 0x5ebce25eU, 0x0b161d0bU, 0xdbad76dbU, + 0xe0db3be0U, 0x32645632U, 0x3a744e3aU, 0x0a141e0aU, + 0x4992db49U, 0x060c0a06U, 0x24486c24U, 0x5cb8e45cU, + 0xc29f5dc2U, 0xd3bd6ed3U, 0xac43efacU, 0x62c4a662U, + 0x9139a891U, 0x9531a495U, 0xe4d337e4U, 0x79f28b79U, + 0xe7d532e7U, 0xc88b43c8U, 0x376e5937U, 0x6ddab76dU, + 0x8d018c8dU, 0xd5b164d5U, 0x4e9cd24eU, 0xa949e0a9U, + 0x6cd8b46cU, 0x56acfa56U, 0xf4f307f4U, 0xeacf25eaU, + 0x65caaf65U, 0x7af48e7aU, 0xae47e9aeU, 0x08101808U, + 0xba6fd5baU, 0x78f08878U, 0x254a6f25U, 0x2e5c722eU, + 0x1c38241cU, 0xa657f1a6U, 0xb473c7b4U, 0xc69751c6U, + 0xe8cb23e8U, 0xdda17cddU, 0x74e89c74U, 0x1f3e211fU, + 0x4b96dd4bU, 0xbd61dcbdU, 0x8b0d868bU, 0x8a0f858aU, + 0x70e09070U, 0x3e7c423eU, 0xb571c4b5U, 0x66ccaa66U, + 0x4890d848U, 0x03060503U, 0xf6f701f6U, 0x0e1c120eU, + 0x61c2a361U, 0x356a5f35U, 0x57aef957U, 0xb969d0b9U, + 0x86179186U, 0xc19958c1U, 0x1d3a271dU, 0x9e27b99eU, + 0xe1d938e1U, 0xf8eb13f8U, 0x982bb398U, 0x11223311U, + 0x69d2bb69U, 0xd9a970d9U, 0x8e07898eU, 0x9433a794U, + 0x9b2db69bU, 0x1e3c221eU, 0x87159287U, 0xe9c920e9U, + 0xce8749ceU, 0x55aaff55U, 0x28507828U, 0xdfa57adfU, + 0x8c038f8cU, 0xa159f8a1U, 0x89098089U, 0x0d1a170dU, + 0xbf65dabfU, 0xe6d731e6U, 0x4284c642U, 0x68d0b868U, + 0x4182c341U, 0x9929b099U, 0x2d5a772dU, 0x0f1e110fU, + 0xb07bcbb0U, 0x54a8fc54U, 0xbb6dd6bbU, 0x162c3a16U, + 0xc6a56363U, 0xf8847c7cU, 0xee997777U, 0xf68d7b7bU, + 0xff0df2f2U, 0xd6bd6b6bU, 0xdeb16f6fU, 0x9154c5c5U, + 0x60503030U, 0x02030101U, 0xcea96767U, 0x567d2b2bU, + 0xe719fefeU, 0xb562d7d7U, 0x4de6ababU, 0xec9a7676U, + 0x8f45cacaU, 0x1f9d8282U, 0x8940c9c9U, 0xfa877d7dU, + 0xef15fafaU, 0xb2eb5959U, 0x8ec94747U, 0xfb0bf0f0U, + 0x41ecadadU, 0xb367d4d4U, 0x5ffda2a2U, 0x45eaafafU, + 0x23bf9c9cU, 0x53f7a4a4U, 0xe4967272U, 0x9b5bc0c0U, + 0x75c2b7b7U, 0xe11cfdfdU, 0x3dae9393U, 0x4c6a2626U, + 0x6c5a3636U, 0x7e413f3fU, 0xf502f7f7U, 0x834fccccU, + 0x685c3434U, 0x51f4a5a5U, 0xd134e5e5U, 0xf908f1f1U, + 0xe2937171U, 0xab73d8d8U, 0x62533131U, 0x2a3f1515U, + 0x080c0404U, 0x9552c7c7U, 0x46652323U, 0x9d5ec3c3U, + 0x30281818U, 0x37a19696U, 0x0a0f0505U, 0x2fb59a9aU, + 0x0e090707U, 0x24361212U, 0x1b9b8080U, 0xdf3de2e2U, + 0xcd26ebebU, 0x4e692727U, 0x7fcdb2b2U, 0xea9f7575U, + 0x121b0909U, 0x1d9e8383U, 0x58742c2cU, 0x342e1a1aU, + 0x362d1b1bU, 0xdcb26e6eU, 0xb4ee5a5aU, 0x5bfba0a0U, + 0xa4f65252U, 0x764d3b3bU, 0xb761d6d6U, 0x7dceb3b3U, + 0x527b2929U, 0xdd3ee3e3U, 0x5e712f2fU, 0x13978484U, + 0xa6f55353U, 0xb968d1d1U, 0x00000000U, 0xc12cededU, + 0x40602020U, 0xe31ffcfcU, 0x79c8b1b1U, 0xb6ed5b5bU, + 0xd4be6a6aU, 0x8d46cbcbU, 0x67d9bebeU, 0x724b3939U, + 0x94de4a4aU, 0x98d44c4cU, 0xb0e85858U, 0x854acfcfU, + 0xbb6bd0d0U, 0xc52aefefU, 0x4fe5aaaaU, 0xed16fbfbU, + 0x86c54343U, 0x9ad74d4dU, 0x66553333U, 0x11948585U, + 0x8acf4545U, 0xe910f9f9U, 0x04060202U, 0xfe817f7fU, + 0xa0f05050U, 0x78443c3cU, 0x25ba9f9fU, 0x4be3a8a8U, + 0xa2f35151U, 0x5dfea3a3U, 0x80c04040U, 0x058a8f8fU, + 0x3fad9292U, 0x21bc9d9dU, 0x70483838U, 0xf104f5f5U, + 0x63dfbcbcU, 0x77c1b6b6U, 0xaf75dadaU, 0x42632121U, + 0x20301010U, 0xe51affffU, 0xfd0ef3f3U, 0xbf6dd2d2U, + 0x814ccdcdU, 0x18140c0cU, 0x26351313U, 0xc32fececU, + 0xbee15f5fU, 0x35a29797U, 0x88cc4444U, 0x2e391717U, + 0x9357c4c4U, 0x55f2a7a7U, 0xfc827e7eU, 0x7a473d3dU, + 0xc8ac6464U, 0xbae75d5dU, 0x322b1919U, 0xe6957373U, + 0xc0a06060U, 0x19988181U, 0x9ed14f4fU, 0xa37fdcdcU, + 0x44662222U, 0x547e2a2aU, 0x3bab9090U, 0x0b838888U, + 0x8cca4646U, 0xc729eeeeU, 0x6bd3b8b8U, 0x283c1414U, + 0xa779dedeU, 0xbce25e5eU, 0x161d0b0bU, 0xad76dbdbU, + 0xdb3be0e0U, 0x64563232U, 0x744e3a3aU, 0x141e0a0aU, + 0x92db4949U, 0x0c0a0606U, 0x486c2424U, 0xb8e45c5cU, + 0x9f5dc2c2U, 0xbd6ed3d3U, 0x43efacacU, 0xc4a66262U, + 0x39a89191U, 0x31a49595U, 0xd337e4e4U, 0xf28b7979U, + 0xd532e7e7U, 0x8b43c8c8U, 0x6e593737U, 0xdab76d6dU, + 0x018c8d8dU, 0xb164d5d5U, 0x9cd24e4eU, 0x49e0a9a9U, + 0xd8b46c6cU, 0xacfa5656U, 0xf307f4f4U, 0xcf25eaeaU, + 0xcaaf6565U, 0xf48e7a7aU, 0x47e9aeaeU, 0x10180808U, + 0x6fd5babaU, 0xf0887878U, 0x4a6f2525U, 0x5c722e2eU, + 0x38241c1cU, 0x57f1a6a6U, 0x73c7b4b4U, 0x9751c6c6U, + 0xcb23e8e8U, 0xa17cddddU, 0xe89c7474U, 0x3e211f1fU, + 0x96dd4b4bU, 0x61dcbdbdU, 0x0d868b8bU, 0x0f858a8aU, + 0xe0907070U, 0x7c423e3eU, 0x71c4b5b5U, 0xccaa6666U, + 0x90d84848U, 0x06050303U, 0xf701f6f6U, 0x1c120e0eU, + 0xc2a36161U, 0x6a5f3535U, 0xaef95757U, 0x69d0b9b9U, + 0x17918686U, 0x9958c1c1U, 0x3a271d1dU, 0x27b99e9eU, + 0xd938e1e1U, 0xeb13f8f8U, 0x2bb39898U, 0x22331111U, + 0xd2bb6969U, 0xa970d9d9U, 0x07898e8eU, 0x33a79494U, + 0x2db69b9bU, 0x3c221e1eU, 0x15928787U, 0xc920e9e9U, + 0x8749ceceU, 0xaaff5555U, 0x50782828U, 0xa57adfdfU, + 0x038f8c8cU, 0x59f8a1a1U, 0x09808989U, 0x1a170d0dU, + 0x65dabfbfU, 0xd731e6e6U, 0x84c64242U, 0xd0b86868U, + 0x82c34141U, 0x29b09999U, 0x5a772d2dU, 0x1e110f0fU, + 0x7bcbb0b0U, 0xa8fc5454U, 0x6dd6bbbbU, 0x2c3a1616U +}; + +#define t_fn0(x) (sharedMemory[ (x)]) +#define t_fn1(x) (sharedMemory[256 + (x)]) +#define t_fn2(x) (sharedMemory[512 + (x)]) +#define t_fn3(x) (sharedMemory[768 + (x)]) + + +#define round(dummy,y,x,k) \ + y[0] = (k)[0] ^ (t_fn0(x[0] & 0xff) ^ t_fn1((x[1] >> 8) & 0xff) ^ t_fn2((x[2] >> 16) & 0xff) ^ t_fn3((x[3] >> 24))); \ + y[1] = (k)[1] ^ (t_fn0(x[1] & 0xff) ^ t_fn1((x[2] >> 8) & 0xff) ^ t_fn2((x[3] >> 16) & 0xff) ^ t_fn3((x[0] >> 24))); \ + y[2] = (k)[2] ^ (t_fn0(x[2] & 0xff) ^ t_fn1((x[3] >> 8) & 0xff) ^ t_fn2((x[0] >> 16) & 0xff) ^ t_fn3((x[1] >> 24))); \ + y[3] = (k)[3] ^ (t_fn0(x[3] & 0xff) ^ t_fn1((x[0] >> 8) & 0xff) ^ t_fn2((x[1] >> 16) & 0xff) ^ t_fn3((x[2] >> 24) )); + +__device__ __forceinline__ static void cn_aes_single_round(uint32_t * __restrict__ sharedMemory, const uint32_t * __restrict__ in, uint32_t * __restrict__ out, const uint32_t * __restrict__ expandedKey) +{ + round(sharedMemory, out, in, expandedKey); +} + +__device__ __forceinline__ static void cn_aes_pseudo_round_mut(const uint32_t * __restrict__ sharedMemory, uint32_t * __restrict__ val, const uint32_t * __restrict__ expandedKey) +{ + uint32_t b1[4]; + round(sharedMemory, b1, val, expandedKey); + round(sharedMemory, val, b1, expandedKey + 1 * N_COLS); + round(sharedMemory, b1, val, expandedKey + 2 * N_COLS); + round(sharedMemory, val, b1, expandedKey + 3 * N_COLS); + round(sharedMemory, b1, val, expandedKey + 4 * N_COLS); + round(sharedMemory, val, b1, expandedKey + 5 * N_COLS); + round(sharedMemory, b1, val, expandedKey + 6 * N_COLS); + round(sharedMemory, val, b1, expandedKey + 7 * N_COLS); + round(sharedMemory, b1, val, expandedKey + 8 * N_COLS); + round(sharedMemory, val, b1, expandedKey + 9 * N_COLS); +} + +__device__ __forceinline__ static void cn_aes_gpu_init(uint32_t *sharedMemory) +{ + for(int i = threadIdx.x; i < 1024; i += blockDim.x) + sharedMemory[i] = d_t_fn[i]; +} diff --git a/backend/nvidia/nvcc_code/cuda_blake.hpp b/backend/nvidia/nvcc_code/cuda_blake.hpp new file mode 100644 index 0000000..07ae169 --- /dev/null +++ b/backend/nvidia/nvcc_code/cuda_blake.hpp @@ -0,0 +1,193 @@ +#pragma once + +typedef struct { + uint32_t h[8], s[4], t[2]; + int buflen, nullt; + uint8_t buf[64]; +} blake_state; + +#define U8TO32(p) \ + (((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | \ + ((uint32_t)((p)[2]) << 8) | ((uint32_t)((p)[3]) )) + +#define U32TO8(p, v) \ + (p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \ + (p)[2] = (uint8_t)((v) >> 8); (p)[3] = (uint8_t)((v) ); + +#define BLAKE_ROT(x,n) ROTR32(x, n) +#define BLAKE_G(a,b,c,d,e) \ + v[a] += (m[d_blake_sigma[i][e]] ^ d_blake_cst[d_blake_sigma[i][e+1]]) + v[b]; \ + v[d] = BLAKE_ROT(v[d] ^ v[a],16); \ + v[c] += v[d]; \ + v[b] = BLAKE_ROT(v[b] ^ v[c],12); \ + v[a] += (m[d_blake_sigma[i][e+1]] ^ d_blake_cst[d_blake_sigma[i][e]])+v[b]; \ + v[d] = BLAKE_ROT(v[d] ^ v[a], 8); \ + v[c] += v[d]; \ + v[b] = BLAKE_ROT(v[b] ^ v[c], 7); + +__constant__ uint8_t d_blake_sigma[14][16] = +{ + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, + {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, + {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, + {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, + {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, + {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, + {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, + {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, + {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, + {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, + {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8} +}; +__constant__ uint32_t d_blake_cst[16] += { + 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, + 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, + 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917 +}; + +__device__ void cn_blake_compress(blake_state * __restrict__ S, const uint8_t * __restrict__ block) +{ + uint32_t v[16], m[16], i; + + for (i = 0; i < 16; ++i) m[i] = U8TO32(block + i * 4); + for (i = 0; i < 8; ++i) v[i] = S->h[i]; + v[ 8] = S->s[0] ^ 0x243F6A88; + v[ 9] = S->s[1] ^ 0x85A308D3; + v[10] = S->s[2] ^ 0x13198A2E; + v[11] = S->s[3] ^ 0x03707344; + v[12] = 0xA4093822; + v[13] = 0x299F31D0; + v[14] = 0x082EFA98; + v[15] = 0xEC4E6C89; + + if (S->nullt == 0) + { + v[12] ^= S->t[0]; + v[13] ^= S->t[0]; + v[14] ^= S->t[1]; + v[15] ^= S->t[1]; + } + + for (i = 0; i < 14; ++i) + { + BLAKE_G(0, 4, 8, 12, 0); + BLAKE_G(1, 5, 9, 13, 2); + BLAKE_G(2, 6, 10, 14, 4); + BLAKE_G(3, 7, 11, 15, 6); + BLAKE_G(3, 4, 9, 14, 14); + BLAKE_G(2, 7, 8, 13, 12); + BLAKE_G(0, 5, 10, 15, 8); + BLAKE_G(1, 6, 11, 12, 10); + } + + for (i = 0; i < 16; ++i) S->h[i % 8] ^= v[i]; + for (i = 0; i < 8; ++i) S->h[i] ^= S->s[i % 4]; +} + +__device__ void cn_blake_update(blake_state * __restrict__ S, const uint8_t * __restrict__ data, uint64_t datalen) +{ + int left = S->buflen >> 3; + int fill = 64 - left; + + if (left && (((datalen >> 3) & 0x3F) >= (unsigned) fill)) + { + memcpy((void *) (S->buf + left), (void *) data, fill); + S->t[0] += 512; + if (S->t[0] == 0) S->t[1]++; + cn_blake_compress(S, S->buf); + data += fill; + datalen -= (fill << 3); + left = 0; + } + + while (datalen >= 512) + { + S->t[0] += 512; + if (S->t[0] == 0) S->t[1]++; + cn_blake_compress(S, data); + data += 64; + datalen -= 512; + } + + if (datalen > 0) + { + memcpy((void *) (S->buf + left), (void *) data, datalen >> 3); + S->buflen = (left << 3) + datalen; + } + else + { + S->buflen = 0; + } +} + +__device__ void cn_blake_final(blake_state * __restrict__ S, uint8_t * __restrict__ digest) +{ + const uint8_t padding[] = + { + 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + }; + + uint8_t pa = 0x81, pb = 0x01; + uint8_t msglen[8]; + uint32_t lo = S->t[0] + S->buflen, hi = S->t[1]; + if (lo < (unsigned) S->buflen) hi++; + U32TO8(msglen + 0, hi); + U32TO8(msglen + 4, lo); + + if (S->buflen == 440) + { + S->t[0] -= 8; + cn_blake_update(S, &pa, 8); + } + else + { + if (S->buflen < 440) + { + if (S->buflen == 0) S->nullt = 1; + S->t[0] -= 440 - S->buflen; + cn_blake_update(S, padding, 440 - S->buflen); + } + else + { + S->t[0] -= 512 - S->buflen; + cn_blake_update(S, padding, 512 - S->buflen); + S->t[0] -= 440; + cn_blake_update(S, padding + 1, 440); + S->nullt = 1; + } + cn_blake_update(S, &pb, 8); + S->t[0] -= 8; + } + S->t[0] -= 64; + cn_blake_update(S, msglen, 64); + + U32TO8(digest + 0, S->h[0]); + U32TO8(digest + 4, S->h[1]); + U32TO8(digest + 8, S->h[2]); + U32TO8(digest + 12, S->h[3]); + U32TO8(digest + 16, S->h[4]); + U32TO8(digest + 20, S->h[5]); + U32TO8(digest + 24, S->h[6]); + U32TO8(digest + 28, S->h[7]); +} + +__device__ void cn_blake(const uint8_t * __restrict__ in, uint64_t inlen, uint8_t * __restrict__ out) +{ + blake_state bs; + blake_state *S = (blake_state *)&bs; + + S->h[0] = 0x6A09E667; S->h[1] = 0xBB67AE85; S->h[2] = 0x3C6EF372; + S->h[3] = 0xA54FF53A; S->h[4] = 0x510E527F; S->h[5] = 0x9B05688C; + S->h[6] = 0x1F83D9AB; S->h[7] = 0x5BE0CD19; + S->t[0] = S->t[1] = S->buflen = S->nullt = 0; + S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0; + + cn_blake_update(S, (uint8_t *)in, inlen * 8); + cn_blake_final(S, (uint8_t *)out); +} diff --git a/backend/nvidia/nvcc_code/cuda_core.cu b/backend/nvidia/nvcc_code/cuda_core.cu new file mode 100644 index 0000000..7590cf5 --- /dev/null +++ b/backend/nvidia/nvcc_code/cuda_core.cu @@ -0,0 +1,343 @@ +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +extern "C" void compat_usleep(uint64_t waitTime) +{ + if (waitTime > 0) + { + if (waitTime > 100) + { + // use a waitable timer for larger intervals > 0.1ms + + HANDLE timer; + LARGE_INTEGER ft; + + ft.QuadPart = -(10*waitTime); // Convert to 100 nanosecond interval, negative value indicates relative time + + timer = CreateWaitableTimer(NULL, TRUE, NULL); + SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); + WaitForSingleObject(timer, INFINITE); + CloseHandle(timer); + } + else + { + // use a polling loop for short intervals <= 100ms + + LARGE_INTEGER perfCnt, start, now; + __int64 elapsed; + + QueryPerformanceFrequency(&perfCnt); + QueryPerformanceCounter(&start); + do { + SwitchToThread(); + QueryPerformanceCounter((LARGE_INTEGER*) &now); + elapsed = (__int64)((now.QuadPart - start.QuadPart) / (float)perfCnt.QuadPart * 1000 * 1000); + } while ( elapsed < waitTime ); + } + } +} +#else +#include +extern "C" void compat_usleep(uint64_t waitTime) +{ + usleep(waitTime); +} +#endif + +#include "cryptonight.h" +#include "cuda_extra.h" +#include "cuda_aes.hpp" +#include "cuda_device.hpp" + +/* sm_2X is limited to 2GB due to the small TLB + * therefore we never use 64bit indices + */ +#if defined(XMR_STAK_LARGEGRID) && (__CUDA_ARCH__ >= 300) +typedef uint64_t IndexType; +#else +typedef int IndexType; +#endif + +__device__ __forceinline__ uint64_t cuda_mul128( uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi ) +{ + *product_hi = __umul64hi( multiplier, multiplicand ); + return (multiplier * multiplicand ); +} + +template< typename T > +__device__ __forceinline__ T loadGlobal64( T * const addr ) +{ + T x; + asm volatile( "ld.global.cg.u64 %0, [%1];" : "=l"( x ) : "l"( addr ) ); + return x; +} + +template< typename T > +__device__ __forceinline__ T loadGlobal32( T * const addr ) +{ + T x; + asm volatile( "ld.global.cg.u32 %0, [%1];" : "=r"( x ) : "l"( addr ) ); + return x; +} + + +template< typename T > +__device__ __forceinline__ void storeGlobal32( T* addr, T const & val ) +{ + asm volatile( "st.global.cg.u32 [%0], %1;" : : "l"( addr ), "r"( val ) ); +} + +__global__ void cryptonight_core_gpu_phase1( int threads, int bfactor, int partidx, uint32_t * __restrict__ long_state, uint32_t * __restrict__ ctx_state, uint32_t * __restrict__ ctx_key1 ) +{ + __shared__ uint32_t sharedMemory[1024]; + + cn_aes_gpu_init( sharedMemory ); + __syncthreads( ); + + const int thread = ( blockDim.x * blockIdx.x + threadIdx.x ) >> 3; + const int sub = ( threadIdx.x & 7 ) << 2; + + const int batchsize = 0x80000 >> bfactor; + const int start = partidx * batchsize; + const int end = start + batchsize; + + if ( thread >= threads ) + return; + + uint32_t key[40], text[4]; + + MEMCPY8( key, ctx_key1 + thread * 40, 20 ); + + if( partidx == 0 ) + { + // first round + MEMCPY8( text, ctx_state + thread * 50 + sub + 16, 2 ); + } + else + { + // load previous text data + MEMCPY8( text, &long_state[( (uint64_t) thread << 19 ) + sub + start - 32], 2 ); + } + __syncthreads( ); + for ( int i = start; i < end; i += 32 ) + { + cn_aes_pseudo_round_mut( sharedMemory, text, key ); + MEMCPY8(&long_state[((uint64_t) thread << 19) + (sub + i)], text, 2); + } +} + +/** avoid warning `unused parameter` */ +template< typename T > +__forceinline__ __device__ void unusedVar( const T& ) +{ +} + +/** shuffle data for + * + * - this method can be used with all compute architectures + * - for =sm_30 + * @param sub thread number within the group, range [0;4) + * @param value value to share with other threads within the group + * @param src thread number within the group from where the data is read, range [0;4) + */ +__forceinline__ __device__ uint32_t shuffle(volatile uint32_t* ptr,const uint32_t sub,const int val,const uint32_t src) +{ +#if( __CUDA_ARCH__ < 300 ) + ptr[sub] = val; + return ptr[src&3]; +#else + unusedVar( ptr ); + unusedVar( sub ); + return __shfl( val, src, 4 ); +#endif +} + +#ifdef XMR_STAK_THREADS +__launch_bounds__( XMR_STAK_THREADS * 4 ) +#endif +__global__ void cryptonight_core_gpu_phase2( int threads, int bfactor, int partidx, uint32_t * d_long_state, uint32_t * d_ctx_a, uint32_t * d_ctx_b ) +{ + __shared__ uint32_t sharedMemory[1024]; + + cn_aes_gpu_init( sharedMemory ); + + __syncthreads( ); + + const int thread = ( blockDim.x * blockIdx.x + threadIdx.x ) >> 2; + const int sub = threadIdx.x & 3; + const int sub2 = sub & 2; + +#if( __CUDA_ARCH__ < 300 ) + extern __shared__ uint32_t shuffleMem[]; + volatile uint32_t* sPtr = (volatile uint32_t*)(shuffleMem + (threadIdx.x& 0xFFFFFFFC)); +#else + volatile uint32_t* sPtr = NULL; +#endif + if ( thread >= threads ) + return; + + int i, k; + uint32_t j; + const int batchsize = ITER >> ( 2 + bfactor ); + const int start = partidx * batchsize; + const int end = start + batchsize; + uint32_t * long_state = &d_long_state[(IndexType) thread << 19]; + uint32_t * ctx_a = d_ctx_a + thread * 4; + uint32_t * ctx_b = d_ctx_b + thread * 4; + uint32_t a, d[2]; + uint32_t t1[2], t2[2], res; + + a = ctx_a[sub]; + d[1] = ctx_b[sub]; + #pragma unroll 2 + for ( i = start; i < end; ++i ) + { + #pragma unroll 2 + for ( int x = 0; x < 2; ++x ) + { + j = ( ( shuffle(sPtr,sub, a, 0) & 0x1FFFF0 ) >> 2 ) + sub; + + const uint32_t x_0 = loadGlobal32( long_state + j ); + const uint32_t x_1 = shuffle(sPtr,sub, x_0, sub + 1); + const uint32_t x_2 = shuffle(sPtr,sub, x_0, sub + 2); + const uint32_t x_3 = shuffle(sPtr,sub, x_0, sub + 3); + d[x] = a ^ + t_fn0( x_0 & 0xff ) ^ + t_fn1( (x_1 >> 8) & 0xff ) ^ + t_fn2( (x_2 >> 16) & 0xff ) ^ + t_fn3( ( x_3 >> 24 ) ); + + + //XOR_BLOCKS_DST(c, b, &long_state[j]); + t1[0] = shuffle(sPtr,sub, d[x], 0); + //long_state[j] = d[0] ^ d[1]; + storeGlobal32( long_state + j, d[0] ^ d[1] ); + + //MUL_SUM_XOR_DST(c, a, &long_state[((uint32_t *)c)[0] & 0x1FFFF0]); + j = ( ( *t1 & 0x1FFFF0 ) >> 2 ) + sub; + + uint32_t yy[2]; + *( (uint64_t*) yy ) = loadGlobal64( ( (uint64_t *) long_state )+( j >> 1 ) ); + uint32_t zz[2]; + zz[0] = shuffle(sPtr,sub, yy[0], 0); + zz[1] = shuffle(sPtr,sub, yy[1], 0); + + t1[1] = shuffle(sPtr,sub, d[x], 1); + #pragma unroll + for ( k = 0; k < 2; k++ ) + t2[k] = shuffle(sPtr,sub, a, k + sub2); + + *( (uint64_t *) t2 ) += sub2 ? ( *( (uint64_t *) t1 ) * *( (uint64_t*) zz ) ) : __umul64hi( *( (uint64_t *) t1 ), *( (uint64_t*) zz ) ); + + res = *( (uint64_t *) t2 ) >> ( sub & 1 ? 32 : 0 ); + + storeGlobal32( long_state + j, res ); + a = ( sub & 1 ? yy[1] : yy[0] ) ^ res; + } + } + + if ( bfactor > 0 ) + { + ctx_a[sub] = a; + ctx_b[sub] = d[1]; + } +} + +__global__ void cryptonight_core_gpu_phase3( int threads, int bfactor, int partidx, const uint32_t * __restrict__ long_state, uint32_t * __restrict__ d_ctx_state, uint32_t * __restrict__ d_ctx_key2 ) +{ + __shared__ uint32_t sharedMemory[1024]; + + cn_aes_gpu_init( sharedMemory ); + __syncthreads( ); + + int thread = ( blockDim.x * blockIdx.x + threadIdx.x ) >> 3; + int sub = ( threadIdx.x & 7 ) << 2; + + const int batchsize = 0x80000 >> bfactor; + const int start = partidx * batchsize; + const int end = start + batchsize; + + if ( thread >= threads ) + return; + + uint32_t key[40], text[4]; + MEMCPY8( key, d_ctx_key2 + thread * 40, 20 ); + MEMCPY8( text, d_ctx_state + thread * 50 + sub + 16, 2 ); + + __syncthreads( ); + for ( int i = start; i < end; i += 32 ) + { +#pragma unroll + for ( int j = 0; j < 4; ++j ) + text[j] ^= long_state[((IndexType) thread << 19) + (sub + i + j)]; + + cn_aes_pseudo_round_mut( sharedMemory, text, key ); + } + + MEMCPY8( d_ctx_state + thread * 50 + sub + 16, text, 2 ); +} + +extern "C" void cryptonight_core_cpu_hash(nvid_ctx* ctx) +{ + dim3 grid( ctx->device_blocks ); + dim3 block( ctx->device_threads ); + dim3 block4( ctx->device_threads << 2 ); + dim3 block8( ctx->device_threads << 3 ); + + int partcount = 1 << ctx->device_bfactor; + + /* bfactor for phase 1 and 3 + * + * phase 1 and 3 consume less time than phase 2, therefore we begin with the + * kernel splitting if the user defined a `bfactor >= 5` + */ + int bfactorOneThree = ctx->device_bfactor - 4; + if( bfactorOneThree < 0 ) + bfactorOneThree = 0; + + int partcountOneThree = 1 << bfactorOneThree; + + for ( int i = 0; i < partcountOneThree; i++ ) + { + CUDA_CHECK_KERNEL(ctx->device_id, cryptonight_core_gpu_phase1<<< grid, block8 >>>( ctx->device_blocks*ctx->device_threads, + bfactorOneThree, i, + ctx->d_long_state, ctx->d_ctx_state, ctx->d_ctx_key1 )); + + if ( partcount > 1 && ctx->device_bsleep > 0) compat_usleep( ctx->device_bsleep ); + } + if ( partcount > 1 && ctx->device_bsleep > 0) compat_usleep( ctx->device_bsleep ); + + for ( int i = 0; i < partcount; i++ ) + { + CUDA_CHECK_KERNEL(ctx->device_id, cryptonight_core_gpu_phase2<<< + grid, + block4, + block4.x * sizeof(uint32_t) * static_cast< int >( ctx->device_arch[0] < 3 ) + >>>( + ctx->device_blocks*ctx->device_threads, + ctx->device_bfactor, + i, + ctx->d_long_state, + ctx->d_ctx_a, + ctx->d_ctx_b + )); + + if ( partcount > 1 && ctx->device_bsleep > 0) compat_usleep( ctx->device_bsleep ); + } + + for ( int i = 0; i < partcountOneThree; i++ ) + { + CUDA_CHECK_KERNEL(ctx->device_id, cryptonight_core_gpu_phase3<<< grid, block8 >>>( ctx->device_blocks*ctx->device_threads, + bfactorOneThree, i, + ctx->d_long_state, + ctx->d_ctx_state, ctx->d_ctx_key2 )); + } +} diff --git a/backend/nvidia/nvcc_code/cuda_device.hpp b/backend/nvidia/nvcc_code/cuda_device.hpp new file mode 100644 index 0000000..078c165 --- /dev/null +++ b/backend/nvidia/nvcc_code/cuda_device.hpp @@ -0,0 +1,30 @@ + +#pragma once + +#include +#include +#include +#include + +/** execute and check a CUDA api command + * + * @param id gpu id (thread id) + * @param ... CUDA api command + */ +#define CUDA_CHECK(id, ...) { \ + cudaError_t error = __VA_ARGS__; \ + if(error!=cudaSuccess){ \ + std::cerr << "[CUDA] Error gpu " << id << ": <" << __FILE__ << ">:" << __LINE__ << std::endl; \ + throw std::runtime_error(std::string("[CUDA] Error: ") + std::string(cudaGetErrorString(error))); \ + } \ +} \ +( (void) 0 ) + +/** execute and check a CUDA kernel + * + * @param id gpu id (thread id) + * @param ... CUDA kernel call + */ +#define CUDA_CHECK_KERNEL(id, ...) \ + __VA_ARGS__; \ + CUDA_CHECK(id, cudaGetLastError()) diff --git a/backend/nvidia/nvcc_code/cuda_extra.cu b/backend/nvidia/nvcc_code/cuda_extra.cu new file mode 100644 index 0000000..94a4adb --- /dev/null +++ b/backend/nvidia/nvcc_code/cuda_extra.cu @@ -0,0 +1,345 @@ +#include +#include +#include +#include +#include +#include + +#ifdef __CUDACC__ +__constant__ +#else +const +#endif +uint64_t keccakf_rndc[24] ={ + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, + 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, + 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, + 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, + 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, + 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 +}; + +typedef unsigned char BitSequence; +typedef unsigned long long DataLength; + +#include "cryptonight.h" +#include "cuda_extra.h" +#include "cuda_keccak.hpp" +#include "cuda_blake.hpp" +#include "cuda_groestl.hpp" +#include "cuda_jh.hpp" +#include "cuda_skein.hpp" +#include "cuda_device.hpp" + +__constant__ uint8_t d_sub_byte[16][16] ={ + {0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 }, + {0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 }, + {0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 }, + {0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 }, + {0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 }, + {0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf }, + {0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 }, + {0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 }, + {0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 }, + {0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb }, + {0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 }, + {0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 }, + {0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a }, + {0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e }, + {0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf }, + {0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 } +}; + +__device__ __forceinline__ void cryptonight_aes_set_key( uint32_t * __restrict__ key, const uint32_t * __restrict__ data ) +{ + int i, j; + uint8_t temp[4]; + const uint32_t aes_gf[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; + + MEMSET4( key, 0, 40 ); + MEMCPY4( key, data, 8 ); + +#pragma unroll + for ( i = 8; i < 40; i++ ) + { + *(uint32_t *) temp = key[i - 1]; + if ( i % 8 == 0 ) + { + *(uint32_t *) temp = ROTR32( *(uint32_t *) temp, 8 ); + for ( j = 0; j < 4; j++ ) + temp[j] = d_sub_byte[( temp[j] >> 4 ) & 0x0f][temp[j] & 0x0f]; + *(uint32_t *) temp ^= aes_gf[i / 8 - 1]; + } + else + { + if ( i % 8 == 4 ) + { +#pragma unroll + for ( j = 0; j < 4; j++ ) + temp[j] = d_sub_byte[( temp[j] >> 4 ) & 0x0f][temp[j] & 0x0f]; + } + } + + key[i] = key[( i - 8 )] ^ *(uint32_t *) temp; + } +} + +__global__ void cryptonight_extra_gpu_prepare( int threads, uint32_t * __restrict__ d_input, uint32_t len, uint32_t startNonce, uint32_t * __restrict__ d_ctx_state, uint32_t * __restrict__ d_ctx_a, uint32_t * __restrict__ d_ctx_b, uint32_t * __restrict__ d_ctx_key1, uint32_t * __restrict__ d_ctx_key2 ) +{ + int thread = ( blockDim.x * blockIdx.x + threadIdx.x ); + + if ( thread >= threads ) + return; + + uint32_t ctx_state[50]; + uint32_t ctx_a[4]; + uint32_t ctx_b[4]; + uint32_t ctx_key1[40]; + uint32_t ctx_key2[40]; + uint32_t input[21]; + + memcpy( input, d_input, len ); + //*((uint32_t *)(((char *)input) + 39)) = startNonce + thread; + uint32_t nonce = startNonce + thread; + for ( int i = 0; i < sizeof (uint32_t ); ++i ) + ( ( (char *) input ) + 39 )[i] = ( (char*) ( &nonce ) )[i]; //take care of pointer alignment + + cn_keccak( (uint8_t *) input, len, (uint8_t *) ctx_state ); + cryptonight_aes_set_key( ctx_key1, ctx_state ); + cryptonight_aes_set_key( ctx_key2, ctx_state + 8 ); + XOR_BLOCKS_DST( ctx_state, ctx_state + 8, ctx_a ); + XOR_BLOCKS_DST( ctx_state + 4, ctx_state + 12, ctx_b ); + + memcpy( d_ctx_state + thread * 50, ctx_state, 50 * 4 ); + memcpy( d_ctx_a + thread * 4, ctx_a, 4 * 4 ); + memcpy( d_ctx_b + thread * 4, ctx_b, 4 * 4 ); + memcpy( d_ctx_key1 + thread * 40, ctx_key1, 40 * 4 ); + memcpy( d_ctx_key2 + thread * 40, ctx_key2, 40 * 4 ); +} + +__global__ void cryptonight_extra_gpu_final( int threads, uint64_t target, uint32_t* __restrict__ d_res_count, uint32_t * __restrict__ d_res_nonce, uint32_t * __restrict__ d_ctx_state ) +{ + const int thread = blockDim.x * blockIdx.x + threadIdx.x; + + if ( thread >= threads ) + return; + + int i; + uint32_t * __restrict__ ctx_state = d_ctx_state + thread * 50; + uint64_t hash[4]; + uint32_t state[50]; + +#pragma unroll + for ( i = 0; i < 50; i++ ) + state[i] = ctx_state[i]; + + cn_keccakf2( (uint64_t *) state ); + + switch ( ( (uint8_t *) state )[0] & 0x03 ) + { + case 0: + cn_blake( (const uint8_t *) state, 200, (uint8_t *) hash ); + break; + case 1: + cn_groestl( (const BitSequence *) state, 200, (BitSequence *) hash ); + break; + case 2: + cn_jh( (const BitSequence *) state, 200, (BitSequence *) hash ); + break; + case 3: + cn_skein( (const BitSequence *) state, 200, (BitSequence *) hash ); + break; + default: + break; + } + + // Note that comparison is equivalent to subtraction - we can't just compare 8 32-bit values + // and expect an accurate result for target > 32-bit without implementing carries + + if ( hash[3] < target ) + { + uint32_t idx = atomicInc( d_res_count, 0xFFFFFFFF ); + + if(idx < 10) + d_res_nonce[idx] = thread; + } +} + +extern "C" void cryptonight_extra_cpu_set_data( nvid_ctx* ctx, const void *data, uint32_t len ) +{ + ctx->inputlen = len; + CUDA_CHECK(ctx->device_id, cudaMemcpy( ctx->d_input, data, len, cudaMemcpyHostToDevice )); +} + +extern "C" int cryptonight_extra_cpu_init(nvid_ctx* ctx) +{ + cudaError_t err; + err = cudaSetDevice(ctx->device_id); + if(err != cudaSuccess) + { + printf("GPU %d: %s", ctx->device_id, cudaGetErrorString(err)); + return 0; + } + + cudaDeviceReset(); + cudaSetDeviceFlags(cudaDeviceScheduleBlockingSync); + cudaDeviceSetCacheConfig(cudaFuncCachePreferL1); + + size_t wsize = ctx->device_blocks * ctx->device_threads; + CUDA_CHECK(ctx->device_id, cudaMalloc(&ctx->d_long_state, (size_t)MEMORY * wsize)); + CUDA_CHECK(ctx->device_id, cudaMalloc(&ctx->d_ctx_state, 50 * sizeof(uint32_t) * wsize)); + CUDA_CHECK(ctx->device_id, cudaMalloc(&ctx->d_ctx_key1, 40 * sizeof(uint32_t) * wsize)); + CUDA_CHECK(ctx->device_id, cudaMalloc(&ctx->d_ctx_key2, 40 * sizeof(uint32_t) * wsize)); + CUDA_CHECK(ctx->device_id, cudaMalloc(&ctx->d_ctx_text, 32 * sizeof(uint32_t) * wsize)); + CUDA_CHECK(ctx->device_id, cudaMalloc(&ctx->d_ctx_a, 4 * sizeof(uint32_t) * wsize)); + CUDA_CHECK(ctx->device_id, cudaMalloc(&ctx->d_ctx_b, 4 * sizeof(uint32_t) * wsize)); + CUDA_CHECK(ctx->device_id, cudaMalloc(&ctx->d_input, 21 * sizeof (uint32_t ) )); + CUDA_CHECK(ctx->device_id, cudaMalloc(&ctx->d_result_count, sizeof (uint32_t ) )); + CUDA_CHECK(ctx->device_id, cudaMalloc(&ctx->d_result_nonce, 10 * sizeof (uint32_t ) )); + return 1; +} + +extern "C" void cryptonight_extra_cpu_prepare(nvid_ctx* ctx, uint32_t startNonce) +{ + int threadsperblock = 128; + uint32_t wsize = ctx->device_blocks * ctx->device_threads; + + dim3 grid( ( wsize + threadsperblock - 1 ) / threadsperblock ); + dim3 block( threadsperblock ); + + CUDA_CHECK_KERNEL(ctx->device_id, cryptonight_extra_gpu_prepare<<>>( wsize, ctx->d_input, ctx->inputlen, startNonce, + ctx->d_ctx_state, ctx->d_ctx_a, ctx->d_ctx_b, ctx->d_ctx_key1, ctx->d_ctx_key2 )); +} + +extern "C" void cryptonight_extra_cpu_final(nvid_ctx* ctx, uint32_t startNonce, uint64_t target, uint32_t* rescount, uint32_t *resnonce) +{ + int threadsperblock = 128; + uint32_t wsize = ctx->device_blocks * ctx->device_threads; + + dim3 grid( ( wsize + threadsperblock - 1 ) / threadsperblock ); + dim3 block( threadsperblock ); + + CUDA_CHECK(ctx->device_id, cudaMemset( ctx->d_result_nonce, 0xFF, 10 * sizeof (uint32_t ) )); + CUDA_CHECK(ctx->device_id, cudaMemset( ctx->d_result_count, 0, sizeof (uint32_t ) )); + + CUDA_CHECK_KERNEL(ctx->device_id, cryptonight_extra_gpu_final<<>>( wsize, target, ctx->d_result_count, ctx->d_result_nonce, ctx->d_ctx_state )); + + CUDA_CHECK(ctx->device_id, cudaMemcpy( rescount, ctx->d_result_count, sizeof (uint32_t ), cudaMemcpyDeviceToHost )); + CUDA_CHECK(ctx->device_id, cudaMemcpy( resnonce, ctx->d_result_nonce, 10 * sizeof (uint32_t ), cudaMemcpyDeviceToHost )); + + /* There is only a 32bit limit for the counter on the device side + * therefore this value can be greater than 10, in that case limit rescount + * to 10 entries. + */ + if(*rescount > 10) + *rescount = 10; + for(int i=0; i < *rescount; i++) + resnonce[i] += startNonce; +} + +extern "C" int cuda_get_devicecount( int* deviceCount) +{ + cudaError_t err; + *deviceCount = 0; + err = cudaGetDeviceCount(deviceCount); + if(err != cudaSuccess) + { + if(err == cudaErrorNoDevice) + printf("ERROR: NVIDIA no CUDA device found!\n"); + else if(err == cudaErrorInsufficientDriver) + printf("WARNING: NVIDIA Insufficient driver!\n"); + else + printf("WARNING: NVIDIA Unable to query number of CUDA devices!\n"); + return 0; + } + + return 1; +} + +extern "C" int cuda_get_deviceinfo(nvid_ctx* ctx) +{ + cudaError_t err; + int version; + + err = cudaDriverGetVersion(&version); + if(err != cudaSuccess) + { + printf("Unable to query CUDA driver version! Is an nVidia driver installed?\n"); + return 0; + } + + if(version < CUDART_VERSION) + { + printf("Driver does not support CUDA %d.%d API! Update your nVidia driver!\n", CUDART_VERSION / 1000, (CUDART_VERSION % 1000) / 10); + return 0; + } + + int GPU_N; + if(cuda_get_devicecount(&GPU_N) == 0) + { + return 0; + } + + if(ctx->device_id >= GPU_N) + { + printf("Invalid device ID!\n"); + return 0; + } + + cudaDeviceProp props; + err = cudaGetDeviceProperties(&props, ctx->device_id); + if(err != cudaSuccess) + { + printf("\nGPU %d: %s\n%s line %d\n", ctx->device_id, cudaGetErrorString(err), __FILE__, __LINE__); + return 0; + } + + ctx->device_name = strdup(props.name); + ctx->device_mpcount = props.multiProcessorCount; + ctx->device_arch[0] = props.major; + ctx->device_arch[1] = props.minor; + + // set all evice option those marked as auto (-1) to a valid value + if(ctx->device_blocks == -1) + { + /* good values based of my experience + * - 3 * SMX count >=sm_30 + * - 2 * SMX count for device_blocks = props.multiProcessorCount * + ( props.major < 3 ? 2 : 3 ); + } + if(ctx->device_threads == -1) + { + /* sm_20 devices can only run 512 threads per cuda block + * `cryptonight_core_gpu_phase1` and `cryptonight_core_gpu_phase3` starts + * `8 * ctx->device_threads` threads per block + */ + ctx->device_threads = 64; + if(props.major < 6) + { + // try to stay under 950 threads ( 1900MiB memory per for hashes ) + while(ctx->device_blocks * ctx->device_threads >= 950 && ctx->device_threads > 2) + { + ctx->device_threads /= 2; + } + } + + // stay within 85% of the available RAM + while(ctx->device_threads > 2) + { + size_t freeMemory = 0; + size_t totalMemory = 0; + CUDA_CHECK(ctx->device_id, cudaMemGetInfo(&freeMemory, &totalMemory)); + freeMemory = (freeMemory * size_t(85)) / 100; + if( freeMemory > (size_t(ctx->device_blocks) * size_t(ctx->device_threads) * size_t(2u * 1024u * 1024u)) ) + break; + else + ctx->device_threads /= 2; + } + } + + return 1; +} diff --git a/backend/nvidia/nvcc_code/cuda_extra.h b/backend/nvidia/nvcc_code/cuda_extra.h new file mode 100644 index 0000000..3ccdcd6 --- /dev/null +++ b/backend/nvidia/nvcc_code/cuda_extra.h @@ -0,0 +1,104 @@ +#pragma once + +#ifdef __INTELLISENSE__ +#define __CUDA_ARCH__ 520 +/* avoid red underlining */ + +struct uint3 +{ + unsigned int x, y, z; +}; + +struct uint3 threadIdx; +struct uint3 blockIdx; +struct uint3 blockDim; +#define __funnelshift_r(a,b,c) 1 +#define __syncthreads() +#define asm(x) +#define __shfl(a,b,c) 1 +#endif + +#define MEMORY (1 << 21) // 2 MiB / 2097152 B +#define ITER (1 << 20) // 1048576 +#define AES_BLOCK_SIZE 16 +#define AES_KEY_SIZE 32 +#define INIT_SIZE_BLK 8 +#define INIT_SIZE_BYTE (INIT_SIZE_BLK * AES_BLOCK_SIZE) // 128 B + +#define C32(x) ((uint32_t)(x ## U)) +#define T32(x) ((x) & C32(0xFFFFFFFF)) + +#if __CUDA_ARCH__ >= 350 +__forceinline__ __device__ uint64_t cuda_ROTL64(const uint64_t value, const int offset) +{ + uint2 result; + if(offset >= 32) + { + asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.x) : "r"(__double2loint(__longlong_as_double(value))), "r"(__double2hiint(__longlong_as_double(value))), "r"(offset)); + asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.y) : "r"(__double2hiint(__longlong_as_double(value))), "r"(__double2loint(__longlong_as_double(value))), "r"(offset)); + } + else + { + asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.x) : "r"(__double2hiint(__longlong_as_double(value))), "r"(__double2loint(__longlong_as_double(value))), "r"(offset)); + asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.y) : "r"(__double2loint(__longlong_as_double(value))), "r"(__double2hiint(__longlong_as_double(value))), "r"(offset)); + } + return __double_as_longlong(__hiloint2double(result.y, result.x)); +} +#define ROTL64(x, n) (cuda_ROTL64(x, n)) +#else +#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +#endif + +#if __CUDA_ARCH__ < 350 +#define ROTL32(x, n) T32(((x) << (n)) | ((x) >> (32 - (n)))) +#define ROTR32(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) +#else +#define ROTL32(x, n) __funnelshift_l( (x), (x), (n) ) +#define ROTR32(x, n) __funnelshift_r( (x), (x), (n) ) +#endif + +#define MEMSET8(dst,what,cnt) { \ + int i_memset8; \ + uint64_t *out_memset8 = (uint64_t *)(dst); \ + for( i_memset8 = 0; i_memset8 < cnt; i_memset8++ ) \ + out_memset8[i_memset8] = (what); } + +#define MEMSET4(dst,what,cnt) { \ + int i_memset4; \ + uint32_t *out_memset4 = (uint32_t *)(dst); \ + for( i_memset4 = 0; i_memset4 < cnt; i_memset4++ ) \ + out_memset4[i_memset4] = (what); } + +#define MEMCPY8(dst,src,cnt) { \ + int i_memcpy8; \ + uint64_t *in_memcpy8 = (uint64_t *)(src); \ + uint64_t *out_memcpy8 = (uint64_t *)(dst); \ + for( i_memcpy8 = 0; i_memcpy8 < cnt; i_memcpy8++ ) \ + out_memcpy8[i_memcpy8] = in_memcpy8[i_memcpy8]; } + +#define MEMCPY4(dst,src,cnt) { \ + int i_memcpy4; \ + uint32_t *in_memcpy4 = (uint32_t *)(src); \ + uint32_t *out_memcpy4 = (uint32_t *)(dst); \ + for( i_memcpy4 = 0; i_memcpy4 < cnt; i_memcpy4++ ) \ + out_memcpy4[i_memcpy4] = in_memcpy4[i_memcpy4]; } + +#define XOR_BLOCKS(a,b) { \ + ((uint64_t *)a)[0] ^= ((uint64_t *)b)[0]; \ + ((uint64_t *)a)[1] ^= ((uint64_t *)b)[1]; } + +#define XOR_BLOCKS_DST(x,y,z) { \ + ((uint64_t *)z)[0] = ((uint64_t *)(x))[0] ^ ((uint64_t *)(y))[0]; \ + ((uint64_t *)z)[1] = ((uint64_t *)(x))[1] ^ ((uint64_t *)(y))[1]; } + +#define MUL_SUM_XOR_DST(a,c,dst) { \ + const uint64_t dst0 = ((uint64_t *)dst)[0]; \ + uint64_t hi, lo = cuda_mul128(((uint64_t *)a)[0], dst0, &hi) + ((uint64_t *)c)[1]; \ + hi += ((uint64_t *)c)[0]; \ + ((uint64_t *)c)[0] = dst0 ^ hi; \ + ((uint64_t *)dst)[0] = hi; \ + ((uint64_t *)c)[1] = atomicExch(((unsigned long long int *)dst) + 1, (unsigned long long int)lo) ^ lo; \ + } + +#define E2I(x) ((size_t)(((*((uint64_t*)(x)) >> 4) & 0x1ffff))) + diff --git a/backend/nvidia/nvcc_code/cuda_groestl.hpp b/backend/nvidia/nvcc_code/cuda_groestl.hpp new file mode 100644 index 0000000..a37934c --- /dev/null +++ b/backend/nvidia/nvcc_code/cuda_groestl.hpp @@ -0,0 +1,357 @@ +#pragma once + +#define GROESTL_ROWS 8 +#define GROESTL_LENGTHFIELDLEN GROESTL_ROWS +#define GROESTL_COLS512 8 + +#define GROESTL_SIZE512 (GROESTL_ROWS*GROESTL_COLS512) + +#define GROESTL_ROUNDS512 10 +#define GROESTL_HASH_BIT_LEN 256 + +#define GROESTL_ROTL32(v, n) ROTL32(v, n) + + +#define li_32(h) 0x##h##u +#define GROESTL_EXT_BYTE(var,n) ((uint8_t)((uint32_t)(var) >> (8*n))) + +#define u32BIG(a) \ + ((GROESTL_ROTL32(a,8) & li_32(00FF00FF)) | (GROESTL_ROTL32(a,24) & li_32(FF00FF00))) + +typedef struct { + uint32_t chaining[GROESTL_SIZE512/sizeof(uint32_t)]; /* actual state */ + uint32_t block_counter1, + block_counter2; /* message block counter(s) */ + BitSequence buffer[GROESTL_SIZE512]; /* data buffer */ + int buf_ptr; /* data buffer pointer */ + int bits_in_last_byte; /* no. of message bits in last byte of data buffer */ +} groestlHashState; + + +__constant__ uint32_t d_groestl_T[512] = +{ + 0xa5f432c6, 0xc6a597f4, 0x84976ff8, 0xf884eb97, 0x99b05eee, 0xee99c7b0, 0x8d8c7af6, 0xf68df78c, 0xd17e8ff, 0xff0de517, 0xbddc0ad6, 0xd6bdb7dc, 0xb1c816de, 0xdeb1a7c8, 0x54fc6d91, 0x915439fc +, 0x50f09060, 0x6050c0f0, 0x3050702, 0x2030405, 0xa9e02ece, 0xcea987e0, 0x7d87d156, 0x567dac87, 0x192bcce7, 0xe719d52b, 0x62a613b5, 0xb56271a6, 0xe6317c4d, 0x4de69a31, 0x9ab559ec, 0xec9ac3b5 +, 0x45cf408f, 0x8f4505cf, 0x9dbca31f, 0x1f9d3ebc, 0x40c04989, 0x894009c0, 0x879268fa, 0xfa87ef92, 0x153fd0ef, 0xef15c53f, 0xeb2694b2, 0xb2eb7f26, 0xc940ce8e, 0x8ec90740, 0xb1de6fb, 0xfb0bed1d +, 0xec2f6e41, 0x41ec822f, 0x67a91ab3, 0xb3677da9, 0xfd1c435f, 0x5ffdbe1c, 0xea256045, 0x45ea8a25, 0xbfdaf923, 0x23bf46da, 0xf7025153, 0x53f7a602, 0x96a145e4, 0xe496d3a1, 0x5bed769b, 0x9b5b2ded +, 0xc25d2875, 0x75c2ea5d, 0x1c24c5e1, 0xe11cd924, 0xaee9d43d, 0x3dae7ae9, 0x6abef24c, 0x4c6a98be, 0x5aee826c, 0x6c5ad8ee, 0x41c3bd7e, 0x7e41fcc3, 0x206f3f5, 0xf502f106, 0x4fd15283, 0x834f1dd1 +, 0x5ce48c68, 0x685cd0e4, 0xf4075651, 0x51f4a207, 0x345c8dd1, 0xd134b95c, 0x818e1f9, 0xf908e918, 0x93ae4ce2, 0xe293dfae, 0x73953eab, 0xab734d95, 0x53f59762, 0x6253c4f5, 0x3f416b2a, 0x2a3f5441 +, 0xc141c08, 0x80c1014, 0x52f66395, 0x955231f6, 0x65afe946, 0x46658caf, 0x5ee27f9d, 0x9d5e21e2, 0x28784830, 0x30286078, 0xa1f8cf37, 0x37a16ef8, 0xf111b0a, 0xa0f1411, 0xb5c4eb2f, 0x2fb55ec4 +, 0x91b150e, 0xe091c1b, 0x365a7e24, 0x2436485a, 0x9bb6ad1b, 0x1b9b36b6, 0x3d4798df, 0xdf3da547, 0x266aa7cd, 0xcd26816a, 0x69bbf54e, 0x4e699cbb, 0xcd4c337f, 0x7fcdfe4c, 0x9fba50ea, 0xea9fcfba +, 0x1b2d3f12, 0x121b242d, 0x9eb9a41d, 0x1d9e3ab9, 0x749cc458, 0x5874b09c, 0x2e724634, 0x342e6872, 0x2d774136, 0x362d6c77, 0xb2cd11dc, 0xdcb2a3cd, 0xee299db4, 0xb4ee7329, 0xfb164d5b, 0x5bfbb616 +, 0xf601a5a4, 0xa4f65301, 0x4dd7a176, 0x764decd7, 0x61a314b7, 0xb76175a3, 0xce49347d, 0x7dcefa49, 0x7b8ddf52, 0x527ba48d, 0x3e429fdd, 0xdd3ea142, 0x7193cd5e, 0x5e71bc93, 0x97a2b113, 0x139726a2 +, 0xf504a2a6, 0xa6f55704, 0x68b801b9, 0xb96869b8, 0x0, 0x0, 0x2c74b5c1, 0xc12c9974, 0x60a0e040, 0x406080a0, 0x1f21c2e3, 0xe31fdd21, 0xc8433a79, 0x79c8f243, 0xed2c9ab6, 0xb6ed772c +, 0xbed90dd4, 0xd4beb3d9, 0x46ca478d, 0x8d4601ca, 0xd9701767, 0x67d9ce70, 0x4bddaf72, 0x724be4dd, 0xde79ed94, 0x94de3379, 0xd467ff98, 0x98d42b67, 0xe82393b0, 0xb0e87b23, 0x4ade5b85, 0x854a11de +, 0x6bbd06bb, 0xbb6b6dbd, 0x2a7ebbc5, 0xc52a917e, 0xe5347b4f, 0x4fe59e34, 0x163ad7ed, 0xed16c13a, 0xc554d286, 0x86c51754, 0xd762f89a, 0x9ad72f62, 0x55ff9966, 0x6655ccff, 0x94a7b611, 0x119422a7 +, 0xcf4ac08a, 0x8acf0f4a, 0x1030d9e9, 0xe910c930, 0x60a0e04, 0x406080a, 0x819866fe, 0xfe81e798, 0xf00baba0, 0xa0f05b0b, 0x44ccb478, 0x7844f0cc, 0xbad5f025, 0x25ba4ad5, 0xe33e754b, 0x4be3963e +, 0xf30eaca2, 0xa2f35f0e, 0xfe19445d, 0x5dfeba19, 0xc05bdb80, 0x80c01b5b, 0x8a858005, 0x58a0a85, 0xadecd33f, 0x3fad7eec, 0xbcdffe21, 0x21bc42df, 0x48d8a870, 0x7048e0d8, 0x40cfdf1, 0xf104f90c +, 0xdf7a1963, 0x63dfc67a, 0xc1582f77, 0x77c1ee58, 0x759f30af, 0xaf75459f, 0x63a5e742, 0x426384a5, 0x30507020, 0x20304050, 0x1a2ecbe5, 0xe51ad12e, 0xe12effd, 0xfd0ee112, 0x6db708bf, 0xbf6d65b7 +, 0x4cd45581, 0x814c19d4, 0x143c2418, 0x1814303c, 0x355f7926, 0x26354c5f, 0x2f71b2c3, 0xc32f9d71, 0xe13886be, 0xbee16738, 0xa2fdc835, 0x35a26afd, 0xcc4fc788, 0x88cc0b4f, 0x394b652e, 0x2e395c4b +, 0x57f96a93, 0x93573df9, 0xf20d5855, 0x55f2aa0d, 0x829d61fc, 0xfc82e39d, 0x47c9b37a, 0x7a47f4c9, 0xacef27c8, 0xc8ac8bef, 0xe73288ba, 0xbae76f32, 0x2b7d4f32, 0x322b647d, 0x95a442e6, 0xe695d7a4 +, 0xa0fb3bc0, 0xc0a09bfb, 0x98b3aa19, 0x199832b3, 0xd168f69e, 0x9ed12768, 0x7f8122a3, 0xa37f5d81, 0x66aaee44, 0x446688aa, 0x7e82d654, 0x547ea882, 0xabe6dd3b, 0x3bab76e6, 0x839e950b, 0xb83169e +, 0xca45c98c, 0x8cca0345, 0x297bbcc7, 0xc729957b, 0xd36e056b, 0x6bd3d66e, 0x3c446c28, 0x283c5044, 0x798b2ca7, 0xa779558b, 0xe23d81bc, 0xbce2633d, 0x1d273116, 0x161d2c27, 0x769a37ad, 0xad76419a +, 0x3b4d96db, 0xdb3bad4d, 0x56fa9e64, 0x6456c8fa, 0x4ed2a674, 0x744ee8d2, 0x1e223614, 0x141e2822, 0xdb76e492, 0x92db3f76, 0xa1e120c, 0xc0a181e, 0x6cb4fc48, 0x486c90b4, 0xe4378fb8, 0xb8e46b37 +, 0x5de7789f, 0x9f5d25e7, 0x6eb20fbd, 0xbd6e61b2, 0xef2a6943, 0x43ef862a, 0xa6f135c4, 0xc4a693f1, 0xa8e3da39, 0x39a872e3, 0xa4f7c631, 0x31a462f7, 0x37598ad3, 0xd337bd59, 0x8b8674f2, 0xf28bff86 +, 0x325683d5, 0xd532b156, 0x43c54e8b, 0x8b430dc5, 0x59eb856e, 0x6e59dceb, 0xb7c218da, 0xdab7afc2, 0x8c8f8e01, 0x18c028f, 0x64ac1db1, 0xb16479ac, 0xd26df19c, 0x9cd2236d, 0xe03b7249, 0x49e0923b +, 0xb4c71fd8, 0xd8b4abc7, 0xfa15b9ac, 0xacfa4315, 0x709faf3, 0xf307fd09, 0x256fa0cf, 0xcf25856f, 0xafea20ca, 0xcaaf8fea, 0x8e897df4, 0xf48ef389, 0xe9206747, 0x47e98e20, 0x18283810, 0x10182028 +, 0xd5640b6f, 0x6fd5de64, 0x888373f0, 0xf088fb83, 0x6fb1fb4a, 0x4a6f94b1, 0x7296ca5c, 0x5c72b896, 0x246c5438, 0x3824706c, 0xf1085f57, 0x57f1ae08, 0xc7522173, 0x73c7e652, 0x51f36497, 0x975135f3 +, 0x2365aecb, 0xcb238d65, 0x7c8425a1, 0xa17c5984, 0x9cbf57e8, 0xe89ccbbf, 0x21635d3e, 0x3e217c63, 0xdd7cea96, 0x96dd377c, 0xdc7f1e61, 0x61dcc27f, 0x86919c0d, 0xd861a91, 0x85949b0f, 0xf851e94 +, 0x90ab4be0, 0xe090dbab, 0x42c6ba7c, 0x7c42f8c6, 0xc4572671, 0x71c4e257, 0xaae529cc, 0xccaa83e5, 0xd873e390, 0x90d83b73, 0x50f0906, 0x6050c0f, 0x103f4f7, 0xf701f503, 0x12362a1c, 0x1c123836 +, 0xa3fe3cc2, 0xc2a39ffe, 0x5fe18b6a, 0x6a5fd4e1, 0xf910beae, 0xaef94710, 0xd06b0269, 0x69d0d26b, 0x91a8bf17, 0x17912ea8, 0x58e87199, 0x995829e8, 0x2769533a, 0x3a277469, 0xb9d0f727, 0x27b94ed0 +, 0x384891d9, 0xd938a948, 0x1335deeb, 0xeb13cd35, 0xb3cee52b, 0x2bb356ce, 0x33557722, 0x22334455, 0xbbd604d2, 0xd2bbbfd6, 0x709039a9, 0xa9704990, 0x89808707, 0x7890e80, 0xa7f2c133, 0x33a766f2 +, 0xb6c1ec2d, 0x2db65ac1, 0x22665a3c, 0x3c227866, 0x92adb815, 0x15922aad, 0x2060a9c9, 0xc9208960, 0x49db5c87, 0x874915db, 0xff1ab0aa, 0xaaff4f1a, 0x7888d850, 0x5078a088, 0x7a8e2ba5, 0xa57a518e +, 0x8f8a8903, 0x38f068a, 0xf8134a59, 0x59f8b213, 0x809b9209, 0x980129b, 0x1739231a, 0x1a173439, 0xda751065, 0x65daca75, 0x315384d7, 0xd731b553, 0xc651d584, 0x84c61351, 0xb8d303d0, 0xd0b8bbd3 +, 0xc35edc82, 0x82c31f5e, 0xb0cbe229, 0x29b052cb, 0x7799c35a, 0x5a77b499, 0x11332d1e, 0x1e113c33, 0xcb463d7b, 0x7bcbf646, 0xfc1fb7a8, 0xa8fc4b1f, 0xd6610c6d, 0x6dd6da61, 0x3a4e622c, 0x2c3a584e +}; + +#define GROESTL_ROTATE_COLUMN_DOWN(v1, v2, amount_bytes, temp_var) \ + { temp_var = (v1<<(8*amount_bytes))|(v2>>(8*(4-amount_bytes))); \ + v2 = (v2<<(8*amount_bytes))|(v1>>(8*(4-amount_bytes))); \ + v1 = temp_var; } + +#define GROESTL_COLUMN(x,y,i,c0,c1,c2,c3,c4,c5,c6,c7,tv1,tv2,tu,tl,t) \ + tu = d_groestl_T[2*(uint32_t)x[4*c0+0]]; \ + tl = d_groestl_T[2*(uint32_t)x[4*c0+0]+1]; \ + tv1 = d_groestl_T[2*(uint32_t)x[4*c1+1]]; \ + tv2 = d_groestl_T[2*(uint32_t)x[4*c1+1]+1]; \ + GROESTL_ROTATE_COLUMN_DOWN(tv1,tv2,1,t) \ + tu ^= tv1; \ + tl ^= tv2; \ + tv1 = d_groestl_T[2*(uint32_t)x[4*c2+2]]; \ + tv2 = d_groestl_T[2*(uint32_t)x[4*c2+2]+1]; \ + GROESTL_ROTATE_COLUMN_DOWN(tv1,tv2,2,t) \ + tu ^= tv1; \ + tl ^= tv2; \ + tv1 = d_groestl_T[2*(uint32_t)x[4*c3+3]]; \ + tv2 = d_groestl_T[2*(uint32_t)x[4*c3+3]+1]; \ + GROESTL_ROTATE_COLUMN_DOWN(tv1,tv2,3,t) \ + tu ^= tv1; \ + tl ^= tv2; \ + tl ^= d_groestl_T[2*(uint32_t)x[4*c4+0]]; \ + tu ^= d_groestl_T[2*(uint32_t)x[4*c4+0]+1]; \ + tv1 = d_groestl_T[2*(uint32_t)x[4*c5+1]]; \ + tv2 = d_groestl_T[2*(uint32_t)x[4*c5+1]+1]; \ + GROESTL_ROTATE_COLUMN_DOWN(tv1,tv2,1,t) \ + tl ^= tv1; \ + tu ^= tv2; \ + tv1 = d_groestl_T[2*(uint32_t)x[4*c6+2]]; \ + tv2 = d_groestl_T[2*(uint32_t)x[4*c6+2]+1]; \ + GROESTL_ROTATE_COLUMN_DOWN(tv1,tv2,2,t) \ + tl ^= tv1; \ + tu ^= tv2; \ + tv1 = d_groestl_T[2*(uint32_t)x[4*c7+3]]; \ + tv2 = d_groestl_T[2*(uint32_t)x[4*c7+3]+1]; \ + GROESTL_ROTATE_COLUMN_DOWN(tv1,tv2,3,t) \ + tl ^= tv1; \ + tu ^= tv2; \ + y[i] = tu; \ + y[i+1] = tl; + +__device__ void cn_groestl_RND512P(uint8_t * __restrict__ x, uint32_t * __restrict__ y, uint32_t r) +{ + uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp; + uint32_t* x32 = (uint32_t*)x; + x32[ 0] ^= 0x00000000^r; + x32[ 2] ^= 0x00000010^r; + x32[ 4] ^= 0x00000020^r; + x32[ 6] ^= 0x00000030^r; + x32[ 8] ^= 0x00000040^r; + x32[10] ^= 0x00000050^r; + x32[12] ^= 0x00000060^r; + x32[14] ^= 0x00000070^r; + GROESTL_COLUMN(x,y, 0, 0, 2, 4, 6, 9, 11, 13, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y, 2, 2, 4, 6, 8, 11, 13, 15, 1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y, 4, 4, 6, 8, 10, 13, 15, 1, 3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y, 6, 6, 8, 10, 12, 15, 1, 3, 5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y, 8, 8, 10, 12, 14, 1, 3, 5, 7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y,10, 10, 12, 14, 0, 3, 5, 7, 9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y,12, 12, 14, 0, 2, 5, 7, 9, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y,14, 14, 0, 2, 4, 7, 9, 11, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); +} + +__device__ void cn_groestl_RND512Q(uint8_t * __restrict__ x, uint32_t * __restrict__ y, uint32_t r) +{ + uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp; + uint32_t* x32 = (uint32_t*)x; + x32[ 0] = ~x32[ 0]; + x32[ 1] ^= 0xffffffff^r; + x32[ 2] = ~x32[ 2]; + x32[ 3] ^= 0xefffffff^r; + x32[ 4] = ~x32[ 4]; + x32[ 5] ^= 0xdfffffff^r; + x32[ 6] = ~x32[ 6]; + x32[ 7] ^= 0xcfffffff^r; + x32[ 8] = ~x32[ 8]; + x32[ 9] ^= 0xbfffffff^r; + x32[10] = ~x32[10]; + x32[11] ^= 0xafffffff^r; + x32[12] = ~x32[12]; + x32[13] ^= 0x9fffffff^r; + x32[14] = ~x32[14]; + x32[15] ^= 0x8fffffff^r; + GROESTL_COLUMN(x,y, 0, 2, 6, 10, 14, 1, 5, 9, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y, 2, 4, 8, 12, 0, 3, 7, 11, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y, 4, 6, 10, 14, 2, 5, 9, 13, 1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y, 6, 8, 12, 0, 4, 7, 11, 15, 3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y, 8, 10, 14, 2, 6, 9, 13, 1, 5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y,10, 12, 0, 4, 8, 11, 15, 3, 7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y,12, 14, 2, 6, 10, 13, 1, 5, 9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); + GROESTL_COLUMN(x,y,14, 0, 4, 8, 12, 15, 3, 7, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); +} + +__device__ void cn_groestl_F512(uint32_t * __restrict__ h, const uint32_t * __restrict__ m) +{ + int i; + uint32_t Ptmp[2*GROESTL_COLS512]; + uint32_t Qtmp[2*GROESTL_COLS512]; + uint32_t y[2*GROESTL_COLS512]; + uint32_t z[2*GROESTL_COLS512]; + + for (i = 0; i < 2*GROESTL_COLS512; i++) + { + z[i] = m[i]; + Ptmp[i] = h[i]^m[i]; + } + + cn_groestl_RND512Q((uint8_t*)z, y, 0x00000000); + cn_groestl_RND512Q((uint8_t*)y, z, 0x01000000); + cn_groestl_RND512Q((uint8_t*)z, y, 0x02000000); + cn_groestl_RND512Q((uint8_t*)y, z, 0x03000000); + cn_groestl_RND512Q((uint8_t*)z, y, 0x04000000); + cn_groestl_RND512Q((uint8_t*)y, z, 0x05000000); + cn_groestl_RND512Q((uint8_t*)z, y, 0x06000000); + cn_groestl_RND512Q((uint8_t*)y, z, 0x07000000); + cn_groestl_RND512Q((uint8_t*)z, y, 0x08000000); + cn_groestl_RND512Q((uint8_t*)y, Qtmp, 0x09000000); + + cn_groestl_RND512P((uint8_t*)Ptmp, y, 0x00000000); + cn_groestl_RND512P((uint8_t*)y, z, 0x00000001); + cn_groestl_RND512P((uint8_t*)z, y, 0x00000002); + cn_groestl_RND512P((uint8_t*)y, z, 0x00000003); + cn_groestl_RND512P((uint8_t*)z, y, 0x00000004); + cn_groestl_RND512P((uint8_t*)y, z, 0x00000005); + cn_groestl_RND512P((uint8_t*)z, y, 0x00000006); + cn_groestl_RND512P((uint8_t*)y, z, 0x00000007); + cn_groestl_RND512P((uint8_t*)z, y, 0x00000008); + cn_groestl_RND512P((uint8_t*)y, Ptmp, 0x00000009); + + for (i = 0; i < 2*GROESTL_COLS512; i++) + h[i] ^= Ptmp[i]^Qtmp[i]; +} + +__device__ void cn_groestl_outputtransformation(groestlHashState *ctx) +{ + int j; + uint32_t temp[2*GROESTL_COLS512]; + uint32_t y[2*GROESTL_COLS512]; + uint32_t z[2*GROESTL_COLS512]; + + for (j = 0; j < 2*GROESTL_COLS512; j++) + temp[j] = ctx->chaining[j]; + + cn_groestl_RND512P((uint8_t*)temp, y, 0x00000000); + cn_groestl_RND512P((uint8_t*)y, z, 0x00000001); + cn_groestl_RND512P((uint8_t*)z, y, 0x00000002); + cn_groestl_RND512P((uint8_t*)y, z, 0x00000003); + cn_groestl_RND512P((uint8_t*)z, y, 0x00000004); + cn_groestl_RND512P((uint8_t*)y, z, 0x00000005); + cn_groestl_RND512P((uint8_t*)z, y, 0x00000006); + cn_groestl_RND512P((uint8_t*)y, z, 0x00000007); + cn_groestl_RND512P((uint8_t*)z, y, 0x00000008); + cn_groestl_RND512P((uint8_t*)y, temp, 0x00000009); + + for (j = 0; j < 2*GROESTL_COLS512; j++) + ctx->chaining[j] ^= temp[j]; +} + +__device__ void cn_groestl_transform(groestlHashState * __restrict__ ctx, + const uint8_t * __restrict__ input, int msglen) +{ + for (; msglen >= GROESTL_SIZE512; msglen -= GROESTL_SIZE512, input += GROESTL_SIZE512) + { + cn_groestl_F512(ctx->chaining,(uint32_t*)input); + ctx->block_counter1++; + + if (ctx->block_counter1 == 0) + ctx->block_counter2++; + } +} + +__device__ void cn_groestl_final(groestlHashState* __restrict__ ctx, + BitSequence* __restrict__ output) +{ + int i, j = 0, hashbytelen = GROESTL_HASH_BIT_LEN/8; + uint8_t *s = (BitSequence*)ctx->chaining; + + if (ctx->bits_in_last_byte) + { + ctx->buffer[(int)ctx->buf_ptr-1] &= ((1<bits_in_last_byte)-1)<<(8-ctx->bits_in_last_byte); + ctx->buffer[(int)ctx->buf_ptr-1] ^= 0x1<<(7-ctx->bits_in_last_byte); + ctx->bits_in_last_byte = 0; + } + else + { + ctx->buffer[(int)ctx->buf_ptr++] = 0x80; + } + + if (ctx->buf_ptr > GROESTL_SIZE512-GROESTL_LENGTHFIELDLEN) + { + while (ctx->buf_ptr < GROESTL_SIZE512) + ctx->buffer[(int)ctx->buf_ptr++] = 0; + + cn_groestl_transform(ctx, ctx->buffer, GROESTL_SIZE512); + ctx->buf_ptr = 0; + } + + while (ctx->buf_ptr < GROESTL_SIZE512-GROESTL_LENGTHFIELDLEN) + ctx->buffer[(int)ctx->buf_ptr++] = 0; + + ctx->block_counter1++; + if (ctx->block_counter1 == 0) + ctx->block_counter2++; + ctx->buf_ptr = GROESTL_SIZE512; + + while (ctx->buf_ptr > GROESTL_SIZE512-(int)sizeof(uint32_t)) + { + ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter1; + ctx->block_counter1 >>= 8; + } + while (ctx->buf_ptr > GROESTL_SIZE512-GROESTL_LENGTHFIELDLEN) + { + ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter2; + ctx->block_counter2 >>= 8; + } + cn_groestl_transform(ctx, ctx->buffer, GROESTL_SIZE512); + cn_groestl_outputtransformation(ctx); + + for (i = GROESTL_SIZE512-hashbytelen; i < GROESTL_SIZE512; i++,j++) + output[j] = s[i]; + + for (i = 0; i < GROESTL_COLS512; i++) + ctx->chaining[i] = 0; + for (i = 0; i < GROESTL_SIZE512; i++) + ctx->buffer[i] = 0; +} + +__device__ void cn_groestl_update(groestlHashState* __restrict__ ctx, + const BitSequence* __restrict__ input, DataLength databitlen) +{ + int index = 0; + int msglen = (int)(databitlen/8); + int rem = (int)(databitlen%8); + + if (ctx->buf_ptr) + { + while (ctx->buf_ptr < GROESTL_SIZE512 && index < msglen) + ctx->buffer[(int)ctx->buf_ptr++] = input[index++]; + + if (ctx->buf_ptr < GROESTL_SIZE512) + { + if (rem) + { + ctx->bits_in_last_byte = rem; + ctx->buffer[(int)ctx->buf_ptr++] = input[index]; + } + return; + } + + ctx->buf_ptr = 0; + cn_groestl_transform(ctx, ctx->buffer, GROESTL_SIZE512); + } + + cn_groestl_transform(ctx, input+index, msglen-index); + index += ((msglen-index)/GROESTL_SIZE512)*GROESTL_SIZE512; + + while (index < msglen) + ctx->buffer[(int)ctx->buf_ptr++] = input[index++]; + + if (rem) + { + ctx->bits_in_last_byte = rem; + ctx->buffer[(int)ctx->buf_ptr++] = input[index]; + } +} + +__device__ void cn_groestl_init(groestlHashState* ctx) +{ + int i = 0; + + for(;i<(GROESTL_SIZE512/sizeof(uint32_t));i++) + ctx->chaining[i] = 0; + + ctx->chaining[2*GROESTL_COLS512-1] = u32BIG((uint32_t)GROESTL_HASH_BIT_LEN); + ctx->buf_ptr = 0; + ctx->block_counter1 = 0; + ctx->block_counter2 = 0; + ctx->bits_in_last_byte = 0; +} + +__device__ void cn_groestl(const BitSequence * __restrict__ data, DataLength len, BitSequence * __restrict__ hashval) +{ + DataLength databitlen = len << 3; + groestlHashState context; + + cn_groestl_init(&context); + cn_groestl_update(&context, data, databitlen); + cn_groestl_final(&context, hashval); +} diff --git a/backend/nvidia/nvcc_code/cuda_jh.hpp b/backend/nvidia/nvcc_code/cuda_jh.hpp new file mode 100644 index 0000000..679046e --- /dev/null +++ b/backend/nvidia/nvcc_code/cuda_jh.hpp @@ -0,0 +1,301 @@ +#include + +typedef struct { + int hashbitlen; + unsigned long long databitlen; + unsigned long long datasize_in_buffer; + uint64_t x[8][2]; + unsigned char buffer[64]; +} jhHashState; + +__constant__ unsigned char d_JH256_H0[512] = +{ + 0xeb, 0x98, 0xa3, 0x41, 0x2c, 0x20, 0xd3, 0xeb, 0x92, 0xcd, 0xbe, 0x7b, 0x9c, 0xb2, 0x45, 0xc1, + 0x1c, 0x93, 0x51, 0x91, 0x60, 0xd4, 0xc7, 0xfa, 0x26, 0x0, 0x82, 0xd6, 0x7e, 0x50, 0x8a, 0x3, + 0xa4, 0x23, 0x9e, 0x26, 0x77, 0x26, 0xb9, 0x45, 0xe0, 0xfb, 0x1a, 0x48, 0xd4, 0x1a, 0x94, 0x77, + 0xcd, 0xb5, 0xab, 0x26, 0x2, 0x6b, 0x17, 0x7a, 0x56, 0xf0, 0x24, 0x42, 0xf, 0xff, 0x2f, 0xa8, + 0x71, 0xa3, 0x96, 0x89, 0x7f, 0x2e, 0x4d, 0x75, 0x1d, 0x14, 0x49, 0x8, 0xf7, 0x7d, 0xe2, 0x62, + 0x27, 0x76, 0x95, 0xf7, 0x76, 0x24, 0x8f, 0x94, 0x87, 0xd5, 0xb6, 0x57, 0x47, 0x80, 0x29, 0x6c, + 0x5c, 0x5e, 0x27, 0x2d, 0xac, 0x8e, 0xd, 0x6c, 0x51, 0x84, 0x50, 0xc6, 0x57, 0x5, 0x7a, 0xf, + 0x7b, 0xe4, 0xd3, 0x67, 0x70, 0x24, 0x12, 0xea, 0x89, 0xe3, 0xab, 0x13, 0xd3, 0x1c, 0xd7, 0x69 +}; + +__constant__ unsigned char d_E8_rc[42][32] = +{ + {0x72, 0xd5, 0xde, 0xa2, 0xdf, 0x15, 0xf8, 0x67, 0x7b, 0x84, 0x15, 0xa, 0xb7, 0x23, 0x15, 0x57, 0x81, 0xab, 0xd6, 0x90, 0x4d, 0x5a, 0x87, 0xf6, 0x4e, 0x9f, 0x4f, 0xc5, 0xc3, 0xd1, 0x2b, 0x40}, + {0xea, 0x98, 0x3a, 0xe0, 0x5c, 0x45, 0xfa, 0x9c, 0x3, 0xc5, 0xd2, 0x99, 0x66, 0xb2, 0x99, 0x9a, 0x66, 0x2, 0x96, 0xb4, 0xf2, 0xbb, 0x53, 0x8a, 0xb5, 0x56, 0x14, 0x1a, 0x88, 0xdb, 0xa2, 0x31}, + {0x3, 0xa3, 0x5a, 0x5c, 0x9a, 0x19, 0xe, 0xdb, 0x40, 0x3f, 0xb2, 0xa, 0x87, 0xc1, 0x44, 0x10, 0x1c, 0x5, 0x19, 0x80, 0x84, 0x9e, 0x95, 0x1d, 0x6f, 0x33, 0xeb, 0xad, 0x5e, 0xe7, 0xcd, 0xdc}, + {0x10, 0xba, 0x13, 0x92, 0x2, 0xbf, 0x6b, 0x41, 0xdc, 0x78, 0x65, 0x15, 0xf7, 0xbb, 0x27, 0xd0, 0xa, 0x2c, 0x81, 0x39, 0x37, 0xaa, 0x78, 0x50, 0x3f, 0x1a, 0xbf, 0xd2, 0x41, 0x0, 0x91, 0xd3}, + {0x42, 0x2d, 0x5a, 0xd, 0xf6, 0xcc, 0x7e, 0x90, 0xdd, 0x62, 0x9f, 0x9c, 0x92, 0xc0, 0x97, 0xce, 0x18, 0x5c, 0xa7, 0xb, 0xc7, 0x2b, 0x44, 0xac, 0xd1, 0xdf, 0x65, 0xd6, 0x63, 0xc6, 0xfc, 0x23}, + {0x97, 0x6e, 0x6c, 0x3, 0x9e, 0xe0, 0xb8, 0x1a, 0x21, 0x5, 0x45, 0x7e, 0x44, 0x6c, 0xec, 0xa8, 0xee, 0xf1, 0x3, 0xbb, 0x5d, 0x8e, 0x61, 0xfa, 0xfd, 0x96, 0x97, 0xb2, 0x94, 0x83, 0x81, 0x97}, + {0x4a, 0x8e, 0x85, 0x37, 0xdb, 0x3, 0x30, 0x2f, 0x2a, 0x67, 0x8d, 0x2d, 0xfb, 0x9f, 0x6a, 0x95, 0x8a, 0xfe, 0x73, 0x81, 0xf8, 0xb8, 0x69, 0x6c, 0x8a, 0xc7, 0x72, 0x46, 0xc0, 0x7f, 0x42, 0x14}, + {0xc5, 0xf4, 0x15, 0x8f, 0xbd, 0xc7, 0x5e, 0xc4, 0x75, 0x44, 0x6f, 0xa7, 0x8f, 0x11, 0xbb, 0x80, 0x52, 0xde, 0x75, 0xb7, 0xae, 0xe4, 0x88, 0xbc, 0x82, 0xb8, 0x0, 0x1e, 0x98, 0xa6, 0xa3, 0xf4}, + {0x8e, 0xf4, 0x8f, 0x33, 0xa9, 0xa3, 0x63, 0x15, 0xaa, 0x5f, 0x56, 0x24, 0xd5, 0xb7, 0xf9, 0x89, 0xb6, 0xf1, 0xed, 0x20, 0x7c, 0x5a, 0xe0, 0xfd, 0x36, 0xca, 0xe9, 0x5a, 0x6, 0x42, 0x2c, 0x36}, + {0xce, 0x29, 0x35, 0x43, 0x4e, 0xfe, 0x98, 0x3d, 0x53, 0x3a, 0xf9, 0x74, 0x73, 0x9a, 0x4b, 0xa7, 0xd0, 0xf5, 0x1f, 0x59, 0x6f, 0x4e, 0x81, 0x86, 0xe, 0x9d, 0xad, 0x81, 0xaf, 0xd8, 0x5a, 0x9f}, + {0xa7, 0x5, 0x6, 0x67, 0xee, 0x34, 0x62, 0x6a, 0x8b, 0xb, 0x28, 0xbe, 0x6e, 0xb9, 0x17, 0x27, 0x47, 0x74, 0x7, 0x26, 0xc6, 0x80, 0x10, 0x3f, 0xe0, 0xa0, 0x7e, 0x6f, 0xc6, 0x7e, 0x48, 0x7b}, + {0xd, 0x55, 0xa, 0xa5, 0x4a, 0xf8, 0xa4, 0xc0, 0x91, 0xe3, 0xe7, 0x9f, 0x97, 0x8e, 0xf1, 0x9e, 0x86, 0x76, 0x72, 0x81, 0x50, 0x60, 0x8d, 0xd4, 0x7e, 0x9e, 0x5a, 0x41, 0xf3, 0xe5, 0xb0, 0x62}, + {0xfc, 0x9f, 0x1f, 0xec, 0x40, 0x54, 0x20, 0x7a, 0xe3, 0xe4, 0x1a, 0x0, 0xce, 0xf4, 0xc9, 0x84, 0x4f, 0xd7, 0x94, 0xf5, 0x9d, 0xfa, 0x95, 0xd8, 0x55, 0x2e, 0x7e, 0x11, 0x24, 0xc3, 0x54, 0xa5}, + {0x5b, 0xdf, 0x72, 0x28, 0xbd, 0xfe, 0x6e, 0x28, 0x78, 0xf5, 0x7f, 0xe2, 0xf, 0xa5, 0xc4, 0xb2, 0x5, 0x89, 0x7c, 0xef, 0xee, 0x49, 0xd3, 0x2e, 0x44, 0x7e, 0x93, 0x85, 0xeb, 0x28, 0x59, 0x7f}, + {0x70, 0x5f, 0x69, 0x37, 0xb3, 0x24, 0x31, 0x4a, 0x5e, 0x86, 0x28, 0xf1, 0x1d, 0xd6, 0xe4, 0x65, 0xc7, 0x1b, 0x77, 0x4, 0x51, 0xb9, 0x20, 0xe7, 0x74, 0xfe, 0x43, 0xe8, 0x23, 0xd4, 0x87, 0x8a}, + {0x7d, 0x29, 0xe8, 0xa3, 0x92, 0x76, 0x94, 0xf2, 0xdd, 0xcb, 0x7a, 0x9, 0x9b, 0x30, 0xd9, 0xc1, 0x1d, 0x1b, 0x30, 0xfb, 0x5b, 0xdc, 0x1b, 0xe0, 0xda, 0x24, 0x49, 0x4f, 0xf2, 0x9c, 0x82, 0xbf}, + {0xa4, 0xe7, 0xba, 0x31, 0xb4, 0x70, 0xbf, 0xff, 0xd, 0x32, 0x44, 0x5, 0xde, 0xf8, 0xbc, 0x48, 0x3b, 0xae, 0xfc, 0x32, 0x53, 0xbb, 0xd3, 0x39, 0x45, 0x9f, 0xc3, 0xc1, 0xe0, 0x29, 0x8b, 0xa0}, + {0xe5, 0xc9, 0x5, 0xfd, 0xf7, 0xae, 0x9, 0xf, 0x94, 0x70, 0x34, 0x12, 0x42, 0x90, 0xf1, 0x34, 0xa2, 0x71, 0xb7, 0x1, 0xe3, 0x44, 0xed, 0x95, 0xe9, 0x3b, 0x8e, 0x36, 0x4f, 0x2f, 0x98, 0x4a}, + {0x88, 0x40, 0x1d, 0x63, 0xa0, 0x6c, 0xf6, 0x15, 0x47, 0xc1, 0x44, 0x4b, 0x87, 0x52, 0xaf, 0xff, 0x7e, 0xbb, 0x4a, 0xf1, 0xe2, 0xa, 0xc6, 0x30, 0x46, 0x70, 0xb6, 0xc5, 0xcc, 0x6e, 0x8c, 0xe6}, + {0xa4, 0xd5, 0xa4, 0x56, 0xbd, 0x4f, 0xca, 0x0, 0xda, 0x9d, 0x84, 0x4b, 0xc8, 0x3e, 0x18, 0xae, 0x73, 0x57, 0xce, 0x45, 0x30, 0x64, 0xd1, 0xad, 0xe8, 0xa6, 0xce, 0x68, 0x14, 0x5c, 0x25, 0x67}, + {0xa3, 0xda, 0x8c, 0xf2, 0xcb, 0xe, 0xe1, 0x16, 0x33, 0xe9, 0x6, 0x58, 0x9a, 0x94, 0x99, 0x9a, 0x1f, 0x60, 0xb2, 0x20, 0xc2, 0x6f, 0x84, 0x7b, 0xd1, 0xce, 0xac, 0x7f, 0xa0, 0xd1, 0x85, 0x18}, + {0x32, 0x59, 0x5b, 0xa1, 0x8d, 0xdd, 0x19, 0xd3, 0x50, 0x9a, 0x1c, 0xc0, 0xaa, 0xa5, 0xb4, 0x46, 0x9f, 0x3d, 0x63, 0x67, 0xe4, 0x4, 0x6b, 0xba, 0xf6, 0xca, 0x19, 0xab, 0xb, 0x56, 0xee, 0x7e}, + {0x1f, 0xb1, 0x79, 0xea, 0xa9, 0x28, 0x21, 0x74, 0xe9, 0xbd, 0xf7, 0x35, 0x3b, 0x36, 0x51, 0xee, 0x1d, 0x57, 0xac, 0x5a, 0x75, 0x50, 0xd3, 0x76, 0x3a, 0x46, 0xc2, 0xfe, 0xa3, 0x7d, 0x70, 0x1}, + {0xf7, 0x35, 0xc1, 0xaf, 0x98, 0xa4, 0xd8, 0x42, 0x78, 0xed, 0xec, 0x20, 0x9e, 0x6b, 0x67, 0x79, 0x41, 0x83, 0x63, 0x15, 0xea, 0x3a, 0xdb, 0xa8, 0xfa, 0xc3, 0x3b, 0x4d, 0x32, 0x83, 0x2c, 0x83}, + {0xa7, 0x40, 0x3b, 0x1f, 0x1c, 0x27, 0x47, 0xf3, 0x59, 0x40, 0xf0, 0x34, 0xb7, 0x2d, 0x76, 0x9a, 0xe7, 0x3e, 0x4e, 0x6c, 0xd2, 0x21, 0x4f, 0xfd, 0xb8, 0xfd, 0x8d, 0x39, 0xdc, 0x57, 0x59, 0xef}, + {0x8d, 0x9b, 0xc, 0x49, 0x2b, 0x49, 0xeb, 0xda, 0x5b, 0xa2, 0xd7, 0x49, 0x68, 0xf3, 0x70, 0xd, 0x7d, 0x3b, 0xae, 0xd0, 0x7a, 0x8d, 0x55, 0x84, 0xf5, 0xa5, 0xe9, 0xf0, 0xe4, 0xf8, 0x8e, 0x65}, + {0xa0, 0xb8, 0xa2, 0xf4, 0x36, 0x10, 0x3b, 0x53, 0xc, 0xa8, 0x7, 0x9e, 0x75, 0x3e, 0xec, 0x5a, 0x91, 0x68, 0x94, 0x92, 0x56, 0xe8, 0x88, 0x4f, 0x5b, 0xb0, 0x5c, 0x55, 0xf8, 0xba, 0xbc, 0x4c}, + {0xe3, 0xbb, 0x3b, 0x99, 0xf3, 0x87, 0x94, 0x7b, 0x75, 0xda, 0xf4, 0xd6, 0x72, 0x6b, 0x1c, 0x5d, 0x64, 0xae, 0xac, 0x28, 0xdc, 0x34, 0xb3, 0x6d, 0x6c, 0x34, 0xa5, 0x50, 0xb8, 0x28, 0xdb, 0x71}, + {0xf8, 0x61, 0xe2, 0xf2, 0x10, 0x8d, 0x51, 0x2a, 0xe3, 0xdb, 0x64, 0x33, 0x59, 0xdd, 0x75, 0xfc, 0x1c, 0xac, 0xbc, 0xf1, 0x43, 0xce, 0x3f, 0xa2, 0x67, 0xbb, 0xd1, 0x3c, 0x2, 0xe8, 0x43, 0xb0}, + {0x33, 0xa, 0x5b, 0xca, 0x88, 0x29, 0xa1, 0x75, 0x7f, 0x34, 0x19, 0x4d, 0xb4, 0x16, 0x53, 0x5c, 0x92, 0x3b, 0x94, 0xc3, 0xe, 0x79, 0x4d, 0x1e, 0x79, 0x74, 0x75, 0xd7, 0xb6, 0xee, 0xaf, 0x3f}, + {0xea, 0xa8, 0xd4, 0xf7, 0xbe, 0x1a, 0x39, 0x21, 0x5c, 0xf4, 0x7e, 0x9, 0x4c, 0x23, 0x27, 0x51, 0x26, 0xa3, 0x24, 0x53, 0xba, 0x32, 0x3c, 0xd2, 0x44, 0xa3, 0x17, 0x4a, 0x6d, 0xa6, 0xd5, 0xad}, + {0xb5, 0x1d, 0x3e, 0xa6, 0xaf, 0xf2, 0xc9, 0x8, 0x83, 0x59, 0x3d, 0x98, 0x91, 0x6b, 0x3c, 0x56, 0x4c, 0xf8, 0x7c, 0xa1, 0x72, 0x86, 0x60, 0x4d, 0x46, 0xe2, 0x3e, 0xcc, 0x8, 0x6e, 0xc7, 0xf6}, + {0x2f, 0x98, 0x33, 0xb3, 0xb1, 0xbc, 0x76, 0x5e, 0x2b, 0xd6, 0x66, 0xa5, 0xef, 0xc4, 0xe6, 0x2a, 0x6, 0xf4, 0xb6, 0xe8, 0xbe, 0xc1, 0xd4, 0x36, 0x74, 0xee, 0x82, 0x15, 0xbc, 0xef, 0x21, 0x63}, + {0xfd, 0xc1, 0x4e, 0xd, 0xf4, 0x53, 0xc9, 0x69, 0xa7, 0x7d, 0x5a, 0xc4, 0x6, 0x58, 0x58, 0x26, 0x7e, 0xc1, 0x14, 0x16, 0x6, 0xe0, 0xfa, 0x16, 0x7e, 0x90, 0xaf, 0x3d, 0x28, 0x63, 0x9d, 0x3f}, + {0xd2, 0xc9, 0xf2, 0xe3, 0x0, 0x9b, 0xd2, 0xc, 0x5f, 0xaa, 0xce, 0x30, 0xb7, 0xd4, 0xc, 0x30, 0x74, 0x2a, 0x51, 0x16, 0xf2, 0xe0, 0x32, 0x98, 0xd, 0xeb, 0x30, 0xd8, 0xe3, 0xce, 0xf8, 0x9a}, + {0x4b, 0xc5, 0x9e, 0x7b, 0xb5, 0xf1, 0x79, 0x92, 0xff, 0x51, 0xe6, 0x6e, 0x4, 0x86, 0x68, 0xd3, 0x9b, 0x23, 0x4d, 0x57, 0xe6, 0x96, 0x67, 0x31, 0xcc, 0xe6, 0xa6, 0xf3, 0x17, 0xa, 0x75, 0x5}, + {0xb1, 0x76, 0x81, 0xd9, 0x13, 0x32, 0x6c, 0xce, 0x3c, 0x17, 0x52, 0x84, 0xf8, 0x5, 0xa2, 0x62, 0xf4, 0x2b, 0xcb, 0xb3, 0x78, 0x47, 0x15, 0x47, 0xff, 0x46, 0x54, 0x82, 0x23, 0x93, 0x6a, 0x48}, + {0x38, 0xdf, 0x58, 0x7, 0x4e, 0x5e, 0x65, 0x65, 0xf2, 0xfc, 0x7c, 0x89, 0xfc, 0x86, 0x50, 0x8e, 0x31, 0x70, 0x2e, 0x44, 0xd0, 0xb, 0xca, 0x86, 0xf0, 0x40, 0x9, 0xa2, 0x30, 0x78, 0x47, 0x4e}, + {0x65, 0xa0, 0xee, 0x39, 0xd1, 0xf7, 0x38, 0x83, 0xf7, 0x5e, 0xe9, 0x37, 0xe4, 0x2c, 0x3a, 0xbd, 0x21, 0x97, 0xb2, 0x26, 0x1, 0x13, 0xf8, 0x6f, 0xa3, 0x44, 0xed, 0xd1, 0xef, 0x9f, 0xde, 0xe7}, + {0x8b, 0xa0, 0xdf, 0x15, 0x76, 0x25, 0x92, 0xd9, 0x3c, 0x85, 0xf7, 0xf6, 0x12, 0xdc, 0x42, 0xbe, 0xd8, 0xa7, 0xec, 0x7c, 0xab, 0x27, 0xb0, 0x7e, 0x53, 0x8d, 0x7d, 0xda, 0xaa, 0x3e, 0xa8, 0xde}, + {0xaa, 0x25, 0xce, 0x93, 0xbd, 0x2, 0x69, 0xd8, 0x5a, 0xf6, 0x43, 0xfd, 0x1a, 0x73, 0x8, 0xf9, 0xc0, 0x5f, 0xef, 0xda, 0x17, 0x4a, 0x19, 0xa5, 0x97, 0x4d, 0x66, 0x33, 0x4c, 0xfd, 0x21, 0x6a}, + {0x35, 0xb4, 0x98, 0x31, 0xdb, 0x41, 0x15, 0x70, 0xea, 0x1e, 0xf, 0xbb, 0xed, 0xcd, 0x54, 0x9b, 0x9a, 0xd0, 0x63, 0xa1, 0x51, 0x97, 0x40, 0x72, 0xf6, 0x75, 0x9d, 0xbf, 0x91, 0x47, 0x6f, 0xe2} +}; + +#define JH_SWAP1(x) (x) = ((((x) & 0x5555555555555555ULL) << 1) | (((x) & 0xaaaaaaaaaaaaaaaaULL) >> 1)); +#define JH_SWAP2(x) (x) = ((((x) & 0x3333333333333333ULL) << 2) | (((x) & 0xccccccccccccccccULL) >> 2)); +#define JH_SWAP4(x) (x) = ((((x) & 0x0f0f0f0f0f0f0f0fULL) << 4) | (((x) & 0xf0f0f0f0f0f0f0f0ULL) >> 4)); +#define JH_SWAP8(x) (x) = ((((x) & 0x00ff00ff00ff00ffULL) << 8) | (((x) & 0xff00ff00ff00ff00ULL) >> 8)); +#define JH_SWAP16(x) (x) = ((((x) & 0x0000ffff0000ffffULL) << 16) | (((x) & 0xffff0000ffff0000ULL) >> 16)); +#define JH_SWAP32(x) (x) = (((x) << 32) | ((x) >> 32)); + +#define JH_L(m0,m1,m2,m3,m4,m5,m6,m7) \ + (m4) ^= (m1); \ + (m5) ^= (m2); \ + (m6) ^= (m0) ^ (m3); \ + (m7) ^= (m0); \ + (m0) ^= (m5); \ + (m1) ^= (m6); \ + (m2) ^= (m4) ^ (m7); \ + (m3) ^= (m4); + +#define JH_SS(m0,m1,m2,m3,m4,m5,m6,m7,cc0,cc1) \ + m3 = ~(m3); \ + m7 = ~(m7); \ + m0 ^= ((~(m2)) & (cc0)); \ + m4 ^= ((~(m6)) & (cc1)); \ + temp0 = (cc0) ^ ((m0) & (m1));\ + temp1 = (cc1) ^ ((m4) & (m5));\ + m0 ^= ((m2) & (m3)); \ + m4 ^= ((m6) & (m7)); \ + m3 ^= ((~(m1)) & (m2)); \ + m7 ^= ((~(m5)) & (m6)); \ + m1 ^= ((m0) & (m2)); \ + m5 ^= ((m4) & (m6)); \ + m2 ^= ((m0) & (~(m3))); \ + m6 ^= ((m4) & (~(m7))); \ + m0 ^= ((m1) | (m3)); \ + m4 ^= ((m5) | (m7)); \ + m3 ^= ((m1) & (m2)); \ + m7 ^= ((m5) & (m6)); \ + m1 ^= (temp0 & (m0)); \ + m5 ^= (temp1 & (m4)); \ + m2 ^= temp0; \ + m6 ^= temp1; + +__device__ void cn_jh_E8(jhHashState *state) +{ + uint64_t i,roundnumber,temp0,temp1; + + for (roundnumber = 0; roundnumber < 42; roundnumber = roundnumber+7) + { + for (i = 0; i < 2; i++) + { + JH_SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64_t *)d_E8_rc[roundnumber+0])[i],((uint64_t *)d_E8_rc[roundnumber+0])[i+2] ); + JH_L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); + JH_SWAP1(state->x[1][i]); JH_SWAP1(state->x[3][i]); JH_SWAP1(state->x[5][i]); JH_SWAP1(state->x[7][i]); + } + + for (i = 0; i < 2; i++) + { + JH_SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64_t *)d_E8_rc[roundnumber+1])[i],((uint64_t *)d_E8_rc[roundnumber+1])[i+2] ); + JH_L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); + JH_SWAP2(state->x[1][i]); JH_SWAP2(state->x[3][i]); JH_SWAP2(state->x[5][i]); JH_SWAP2(state->x[7][i]); + } + + for (i = 0; i < 2; i++) + { + JH_SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64_t *)d_E8_rc[roundnumber+2])[i],((uint64_t *)d_E8_rc[roundnumber+2])[i+2] ); + JH_L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); + JH_SWAP4(state->x[1][i]); JH_SWAP4(state->x[3][i]); JH_SWAP4(state->x[5][i]); JH_SWAP4(state->x[7][i]); + } + + for (i = 0; i < 2; i++) + { + JH_SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64_t *)d_E8_rc[roundnumber+3])[i],((uint64_t *)d_E8_rc[roundnumber+3])[i+2] ); + JH_L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); + JH_SWAP8(state->x[1][i]); JH_SWAP8(state->x[3][i]); JH_SWAP8(state->x[5][i]); JH_SWAP8(state->x[7][i]); + } + + for (i = 0; i < 2; i++) + { + JH_SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64_t *)d_E8_rc[roundnumber+4])[i],((uint64_t *)d_E8_rc[roundnumber+4])[i+2] ); + JH_L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); + JH_SWAP16(state->x[1][i]); JH_SWAP16(state->x[3][i]); JH_SWAP16(state->x[5][i]); JH_SWAP16(state->x[7][i]); + } + + for (i = 0; i < 2; i++) + { + JH_SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64_t *)d_E8_rc[roundnumber+5])[i],((uint64_t *)d_E8_rc[roundnumber+5])[i+2] ); + JH_L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); + JH_SWAP32(state->x[1][i]); JH_SWAP32(state->x[3][i]); JH_SWAP32(state->x[5][i]); JH_SWAP32(state->x[7][i]); + } + + for (i = 0; i < 2; i++) + { + JH_SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64_t *)d_E8_rc[roundnumber+6])[i],((uint64_t *)d_E8_rc[roundnumber+6])[i+2] ); + JH_L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); + } + + for (i = 1; i < 8; i = i+2) + { + temp0 = state->x[i][0]; + state->x[i][0] = state->x[i][1]; + state->x[i][1] = temp0; + } + } +} + +__device__ void cn_jh_F8(jhHashState *state) +{ + uint64_t i; + + for (i = 0; i < 8; i++) + state->x[i >> 1][i & 1] ^= ((uint64_t *)state->buffer)[i]; + + cn_jh_E8(state); + + for (i = 0; i < 8; i++) + state->x[(8+i) >> 1][(8+i) & 1] ^= ((uint64_t *)state->buffer)[i]; +} + +__device__ void cn_jh_update(jhHashState * __restrict__ state, const BitSequence * __restrict__ data, DataLength databitlen) +{ + DataLength index; + + state->databitlen += databitlen; + index = 0; + + if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) < 512) ) + { + if ( (databitlen & 7) == 0 ) + memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)); + else + memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)+1); + state->datasize_in_buffer += databitlen; + databitlen = 0; + } + + if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) >= 512) ) + { + memcpy( state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3) ); + index = 64-(state->datasize_in_buffer >> 3); + databitlen = databitlen - (512 - state->datasize_in_buffer); + cn_jh_F8(state); + state->datasize_in_buffer = 0; + } + + for ( ; databitlen >= 512; index = index+64, databitlen = databitlen - 512) + { + memcpy(state->buffer, data+index, 64); + cn_jh_F8(state); + } + + if ( databitlen > 0) + { + if ((databitlen & 7) == 0) + memcpy(state->buffer, data+index, (databitlen & 0x1ff) >> 3); + else + memcpy(state->buffer, data+index, ((databitlen & 0x1ff) >> 3)+1); + state->datasize_in_buffer = databitlen; + } +} + +/*pad the message, process the padded block(s), truncate the hash value H to obtain the message digest*/ +__device__ void cn_jh_final(jhHashState * __restrict__ state, BitSequence * __restrict__ hashval) +{ + unsigned int i; + //uint32_t *bufptr = (uint32_t *)state->buffer; + + if ( (state->databitlen & 0x1ff) == 0 ) + { + /*pad the message when databitlen is multiple of 512 bits, then process the padded block*/ + memset(state->buffer, 0, 64); + //for( i = 0; i < 16; i++ ) *(bufptr+i) = 0x00000000; + state->buffer[0] = 0x80; + state->buffer[63] = state->databitlen & 0xff; + state->buffer[62] = (state->databitlen >> 8) & 0xff; + state->buffer[61] = (state->databitlen >> 16) & 0xff; + state->buffer[60] = (state->databitlen >> 24) & 0xff; + state->buffer[59] = (state->databitlen >> 32) & 0xff; + state->buffer[58] = (state->databitlen >> 40) & 0xff; + state->buffer[57] = (state->databitlen >> 48) & 0xff; + state->buffer[56] = (state->databitlen >> 56) & 0xff; + cn_jh_F8(state); + } + else + { + /*set the rest of the bytes in the buffer to 0*/ + if ( (state->datasize_in_buffer & 7) == 0) + { + for (i = (state->databitlen & 0x1ff) >> 3; i < 64; i++) + state->buffer[i] = 0; + } + else + { + for (i = ((state->databitlen & 0x1ff) >> 3)+1; i < 64; i++) + state->buffer[i] = 0; + } + + /*pad and process the partial block when databitlen is not multiple of 512 bits, then hash the padded blocks*/ + state->buffer[((state->databitlen & 0x1ff) >> 3)] |= 1 << (7- (state->databitlen & 7)); + + cn_jh_F8(state); + memset(state->buffer, 0, 64); + //for( i = 0; i < 16; i++ ) *(bufptr+i) = 0x00000000; + state->buffer[63] = state->databitlen & 0xff; + state->buffer[62] = (state->databitlen >> 8) & 0xff; + state->buffer[61] = (state->databitlen >> 16) & 0xff; + state->buffer[60] = (state->databitlen >> 24) & 0xff; + state->buffer[59] = (state->databitlen >> 32) & 0xff; + state->buffer[58] = (state->databitlen >> 40) & 0xff; + state->buffer[57] = (state->databitlen >> 48) & 0xff; + state->buffer[56] = (state->databitlen >> 56) & 0xff; + cn_jh_F8(state); + } + + memcpy(hashval,(unsigned char*)state->x+64+32,32); +} + +__device__ void cn_jh_init(jhHashState *state, int hashbitlen) +{ + state->databitlen = 0; + state->datasize_in_buffer = 0; + state->hashbitlen = hashbitlen; + memcpy(state->x, d_JH256_H0, 128); +} + +__device__ void cn_jh(const BitSequence * __restrict__ data, DataLength len, BitSequence * __restrict__ hashval) +{ + int hashbitlen = 256; + DataLength databitlen = len << 3; + jhHashState state; + + cn_jh_init(&state, hashbitlen); + cn_jh_update(&state, data, databitlen); + cn_jh_final(&state, hashval); +} diff --git a/backend/nvidia/nvcc_code/cuda_keccak.hpp b/backend/nvidia/nvcc_code/cuda_keccak.hpp new file mode 100644 index 0000000..99c6516 --- /dev/null +++ b/backend/nvidia/nvcc_code/cuda_keccak.hpp @@ -0,0 +1,197 @@ +#if __CUDA_ARCH__ >= 350 + __forceinline__ __device__ uint64_t cuda_rotl64(const uint64_t value, const int offset) + { + uint2 result; + if(offset >= 32) + { + asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.x) : "r"(__double2loint(__longlong_as_double(value))), "r"(__double2hiint(__longlong_as_double(value))), "r"(offset)); + asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.y) : "r"(__double2hiint(__longlong_as_double(value))), "r"(__double2loint(__longlong_as_double(value))), "r"(offset)); + } + else + { + asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.x) : "r"(__double2hiint(__longlong_as_double(value))), "r"(__double2loint(__longlong_as_double(value))), "r"(offset)); + asm("shf.l.wrap.b32 %0, %1, %2, %3;" : "=r"(result.y) : "r"(__double2loint(__longlong_as_double(value))), "r"(__double2hiint(__longlong_as_double(value))), "r"(offset)); + } + return __double_as_longlong(__hiloint2double(result.y, result.x)); + } + #define rotl64_1(x, y) (cuda_rotl64((x), (y))) +#else + #define rotl64_1(x, y) ((x) << (y) | ((x) >> (64 - (y)))) +#endif + +#define rotl64_2(x, y) rotl64_1(((x) >> 32) | ((x) << 32), (y)) +#define bitselect(a, b, c) ((a) ^ ((c) & ((b) ^ (a)))) + +__device__ __forceinline__ void cn_keccakf2(uint64_t *s) +{ + uint8_t i; + + for(i = 0; i < 24; ++i) + { + uint64_t bc[5], tmpxor[5], tmp1, tmp2; + + tmpxor[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20]; + tmpxor[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21]; + tmpxor[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22]; + tmpxor[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23]; + tmpxor[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24]; + + bc[0] = tmpxor[0] ^ rotl64_1(tmpxor[2], 1); + bc[1] = tmpxor[1] ^ rotl64_1(tmpxor[3], 1); + bc[2] = tmpxor[2] ^ rotl64_1(tmpxor[4], 1); + bc[3] = tmpxor[3] ^ rotl64_1(tmpxor[0], 1); + bc[4] = tmpxor[4] ^ rotl64_1(tmpxor[1], 1); + + tmp1 = s[1] ^ bc[0]; + + s[0] ^= bc[4]; + s[1] = rotl64_2(s[6] ^ bc[0], 12); + s[6] = rotl64_1(s[9] ^ bc[3], 20); + s[9] = rotl64_2(s[22] ^ bc[1], 29); + s[22] = rotl64_2(s[14] ^ bc[3], 7); + s[14] = rotl64_1(s[20] ^ bc[4], 18); + s[20] = rotl64_2(s[2] ^ bc[1], 30); + s[2] = rotl64_2(s[12] ^ bc[1], 11); + s[12] = rotl64_1(s[13] ^ bc[2], 25); + s[13] = rotl64_1(s[19] ^ bc[3], 8); + s[19] = rotl64_2(s[23] ^ bc[2], 24); + s[23] = rotl64_2(s[15] ^ bc[4], 9); + s[15] = rotl64_1(s[4] ^ bc[3], 27); + s[4] = rotl64_1(s[24] ^ bc[3], 14); + s[24] = rotl64_1(s[21] ^ bc[0], 2); + s[21] = rotl64_2(s[8] ^ bc[2], 23); + s[8] = rotl64_2(s[16] ^ bc[0], 13); + s[16] = rotl64_2(s[5] ^ bc[4], 4); + s[5] = rotl64_1(s[3] ^ bc[2], 28); + s[3] = rotl64_1(s[18] ^ bc[2], 21); + s[18] = rotl64_1(s[17] ^ bc[1], 15); + s[17] = rotl64_1(s[11] ^ bc[0], 10); + s[11] = rotl64_1(s[7] ^ bc[1], 6); + s[7] = rotl64_1(s[10] ^ bc[4], 3); + s[10] = rotl64_1(tmp1, 1); + + tmp1 = s[0]; tmp2 = s[1]; s[0] = bitselect(s[0] ^ s[2], s[0], s[1]); s[1] = bitselect(s[1] ^ s[3], s[1], s[2]); s[2] = bitselect(s[2] ^ s[4], s[2], s[3]); s[3] = bitselect(s[3] ^ tmp1, s[3], s[4]); s[4] = bitselect(s[4] ^ tmp2, s[4], tmp1); + tmp1 = s[5]; tmp2 = s[6]; s[5] = bitselect(s[5] ^ s[7], s[5], s[6]); s[6] = bitselect(s[6] ^ s[8], s[6], s[7]); s[7] = bitselect(s[7] ^ s[9], s[7], s[8]); s[8] = bitselect(s[8] ^ tmp1, s[8], s[9]); s[9] = bitselect(s[9] ^ tmp2, s[9], tmp1); + tmp1 = s[10]; tmp2 = s[11]; s[10] = bitselect(s[10] ^ s[12], s[10], s[11]); s[11] = bitselect(s[11] ^ s[13], s[11], s[12]); s[12] = bitselect(s[12] ^ s[14], s[12], s[13]); s[13] = bitselect(s[13] ^ tmp1, s[13], s[14]); s[14] = bitselect(s[14] ^ tmp2, s[14], tmp1); + tmp1 = s[15]; tmp2 = s[16]; s[15] = bitselect(s[15] ^ s[17], s[15], s[16]); s[16] = bitselect(s[16] ^ s[18], s[16], s[17]); s[17] = bitselect(s[17] ^ s[19], s[17], s[18]); s[18] = bitselect(s[18] ^ tmp1, s[18], s[19]); s[19] = bitselect(s[19] ^ tmp2, s[19], tmp1); + tmp1 = s[20]; tmp2 = s[21]; s[20] = bitselect(s[20] ^ s[22], s[20], s[21]); s[21] = bitselect(s[21] ^ s[23], s[21], s[22]); s[22] = bitselect(s[22] ^ s[24], s[22], s[23]); s[23] = bitselect(s[23] ^ tmp1, s[23], s[24]); s[24] = bitselect(s[24] ^ tmp2, s[24], tmp1); + s[0] ^= keccakf_rndc[i]; + } +} + +__device__ __forceinline__ void cn_keccakf(uint64_t *s) +{ + uint64_t bc[5], tmpxor[5], tmp1, tmp2; + + tmpxor[0] = s[0] ^ s[5]; + tmpxor[1] = s[1] ^ s[6] ^ 0x8000000000000000ULL; + tmpxor[2] = s[2] ^ s[7]; + tmpxor[3] = s[3] ^ s[8]; + tmpxor[4] = s[4] ^ s[9]; + + bc[0] = tmpxor[0] ^ rotl64_1(tmpxor[2], 1); + bc[1] = tmpxor[1] ^ rotl64_1(tmpxor[3], 1); + bc[2] = tmpxor[2] ^ rotl64_1(tmpxor[4], 1); + bc[3] = tmpxor[3] ^ rotl64_1(tmpxor[0], 1); + bc[4] = tmpxor[4] ^ rotl64_1(tmpxor[1], 1); + + tmp1 = s[1] ^ bc[0]; + + s[0] ^= bc[4]; + s[1] = rotl64_2(s[6] ^ bc[0], 12); + s[6] = rotl64_1(s[9] ^ bc[3], 20); + s[9] = rotl64_2(bc[1], 29); + s[22] = rotl64_2(bc[3], 7); + s[14] = rotl64_1(bc[4], 18); + s[20] = rotl64_2(s[2] ^ bc[1], 30); + s[2] = rotl64_2(bc[1], 11); + s[12] = rotl64_1(bc[2], 25); + s[13] = rotl64_1(bc[3], 8); + s[19] = rotl64_2(bc[2], 24); + s[23] = rotl64_2(bc[4], 9); + s[15] = rotl64_1(s[4] ^ bc[3], 27); + s[4] = rotl64_1(bc[3], 14); + s[24] = rotl64_1(bc[0], 2); + s[21] = rotl64_2(s[8] ^ bc[2], 23); + s[8] = rotl64_2(0x8000000000000000ULL ^ bc[0], 13); + s[16] = rotl64_2(s[5] ^ bc[4], 4); + s[5] = rotl64_1(s[3] ^ bc[2], 28); + s[3] = rotl64_1(bc[2], 21); + s[18] = rotl64_1(bc[1], 15); + s[17] = rotl64_1(bc[0], 10); + s[11] = rotl64_1(s[7] ^ bc[1], 6); + s[7] = rotl64_1(bc[4], 3); + s[10] = rotl64_1(tmp1, 1); + + tmp1 = s[0]; tmp2 = s[1]; s[0] = bitselect(s[0] ^ s[2], s[0], s[1]); s[1] = bitselect(s[1] ^ s[3], s[1], s[2]); s[2] = bitselect(s[2] ^ s[4], s[2], s[3]); s[3] = bitselect(s[3] ^ tmp1, s[3], s[4]); s[4] = bitselect(s[4] ^ tmp2, s[4], tmp1); + tmp1 = s[5]; tmp2 = s[6]; s[5] = bitselect(s[5] ^ s[7], s[5], s[6]); s[6] = bitselect(s[6] ^ s[8], s[6], s[7]); s[7] = bitselect(s[7] ^ s[9], s[7], s[8]); s[8] = bitselect(s[8] ^ tmp1, s[8], s[9]); s[9] = bitselect(s[9] ^ tmp2, s[9], tmp1); + tmp1 = s[10]; tmp2 = s[11]; s[10] = bitselect(s[10] ^ s[12], s[10], s[11]); s[11] = bitselect(s[11] ^ s[13], s[11], s[12]); s[12] = bitselect(s[12] ^ s[14], s[12], s[13]); s[13] = bitselect(s[13] ^ tmp1, s[13], s[14]); s[14] = bitselect(s[14] ^ tmp2, s[14], tmp1); + tmp1 = s[15]; tmp2 = s[16]; s[15] = bitselect(s[15] ^ s[17], s[15], s[16]); s[16] = bitselect(s[16] ^ s[18], s[16], s[17]); s[17] = bitselect(s[17] ^ s[19], s[17], s[18]); s[18] = bitselect(s[18] ^ tmp1, s[18], s[19]); s[19] = bitselect(s[19] ^ tmp2, s[19], tmp1); + tmp1 = s[20]; tmp2 = s[21]; s[20] = bitselect(s[20] ^ s[22], s[20], s[21]); s[21] = bitselect(s[21] ^ s[23], s[21], s[22]); s[22] = bitselect(s[22] ^ s[24], s[22], s[23]); s[23] = bitselect(s[23] ^ tmp1, s[23], s[24]); s[24] = bitselect(s[24] ^ tmp2, s[24], tmp1); + s[0] ^= 0x0000000000000001; + + for(int i = 1; i < 24; ++i) + { + tmpxor[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20]; + tmpxor[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21]; + tmpxor[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22]; + tmpxor[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23]; + tmpxor[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24]; + + bc[0] = tmpxor[0] ^ rotl64_1(tmpxor[2], 1); + bc[1] = tmpxor[1] ^ rotl64_1(tmpxor[3], 1); + bc[2] = tmpxor[2] ^ rotl64_1(tmpxor[4], 1); + bc[3] = tmpxor[3] ^ rotl64_1(tmpxor[0], 1); + bc[4] = tmpxor[4] ^ rotl64_1(tmpxor[1], 1); + + tmp1 = s[1] ^ bc[0]; + + s[0] ^= bc[4]; + s[1] = rotl64_2(s[6] ^ bc[0], 12); + s[6] = rotl64_1(s[9] ^ bc[3], 20); + s[9] = rotl64_2(s[22] ^ bc[1], 29); + s[22] = rotl64_2(s[14] ^ bc[3], 7); + s[14] = rotl64_1(s[20] ^ bc[4], 18); + s[20] = rotl64_2(s[2] ^ bc[1], 30); + s[2] = rotl64_2(s[12] ^ bc[1], 11); + s[12] = rotl64_1(s[13] ^ bc[2], 25); + s[13] = rotl64_1(s[19] ^ bc[3], 8); + s[19] = rotl64_2(s[23] ^ bc[2], 24); + s[23] = rotl64_2(s[15] ^ bc[4], 9); + s[15] = rotl64_1(s[4] ^ bc[3], 27); + s[4] = rotl64_1(s[24] ^ bc[3], 14); + s[24] = rotl64_1(s[21] ^ bc[0], 2); + s[21] = rotl64_2(s[8] ^ bc[2], 23); + s[8] = rotl64_2(s[16] ^ bc[0], 13); + s[16] = rotl64_2(s[5] ^ bc[4], 4); + s[5] = rotl64_1(s[3] ^ bc[2], 28); + s[3] = rotl64_1(s[18] ^ bc[2], 21); + s[18] = rotl64_1(s[17] ^ bc[1], 15); + s[17] = rotl64_1(s[11] ^ bc[0], 10); + s[11] = rotl64_1(s[7] ^ bc[1], 6); + s[7] = rotl64_1(s[10] ^ bc[4], 3); + s[10] = rotl64_1(tmp1, 1); + + tmp1 = s[0]; tmp2 = s[1]; s[0] = bitselect(s[0] ^ s[2], s[0], s[1]); s[1] = bitselect(s[1] ^ s[3], s[1], s[2]); s[2] = bitselect(s[2] ^ s[4], s[2], s[3]); s[3] = bitselect(s[3] ^ tmp1, s[3], s[4]); s[4] = bitselect(s[4] ^ tmp2, s[4], tmp1); + tmp1 = s[5]; tmp2 = s[6]; s[5] = bitselect(s[5] ^ s[7], s[5], s[6]); s[6] = bitselect(s[6] ^ s[8], s[6], s[7]); s[7] = bitselect(s[7] ^ s[9], s[7], s[8]); s[8] = bitselect(s[8] ^ tmp1, s[8], s[9]); s[9] = bitselect(s[9] ^ tmp2, s[9], tmp1); + tmp1 = s[10]; tmp2 = s[11]; s[10] = bitselect(s[10] ^ s[12], s[10], s[11]); s[11] = bitselect(s[11] ^ s[13], s[11], s[12]); s[12] = bitselect(s[12] ^ s[14], s[12], s[13]); s[13] = bitselect(s[13] ^ tmp1, s[13], s[14]); s[14] = bitselect(s[14] ^ tmp2, s[14], tmp1); + tmp1 = s[15]; tmp2 = s[16]; s[15] = bitselect(s[15] ^ s[17], s[15], s[16]); s[16] = bitselect(s[16] ^ s[18], s[16], s[17]); s[17] = bitselect(s[17] ^ s[19], s[17], s[18]); s[18] = bitselect(s[18] ^ tmp1, s[18], s[19]); s[19] = bitselect(s[19] ^ tmp2, s[19], tmp1); + tmp1 = s[20]; tmp2 = s[21]; s[20] = bitselect(s[20] ^ s[22], s[20], s[21]); s[21] = bitselect(s[21] ^ s[23], s[21], s[22]); s[22] = bitselect(s[22] ^ s[24], s[22], s[23]); s[23] = bitselect(s[23] ^ tmp1, s[23], s[24]); s[24] = bitselect(s[24] ^ tmp2, s[24], tmp1); + s[0] ^= keccakf_rndc[i]; + } +} + +__device__ __forceinline__ void cn_keccak(const uint8_t * __restrict__ in, uint32_t len, uint8_t * __restrict__ md) +{ + uint64_t st[25]; + + MEMSET8(st + 8, 0x00, 25 - 8); + memcpy(st, in, len); + ((uint8_t*)st)[len] = 0x01; + st[16] = 0x8000000000000000ULL; + + cn_keccakf(st); + + MEMCPY8(md, st, 25); + return; +} diff --git a/backend/nvidia/nvcc_code/cuda_skein.hpp b/backend/nvidia/nvcc_code/cuda_skein.hpp new file mode 100644 index 0000000..041a593 --- /dev/null +++ b/backend/nvidia/nvcc_code/cuda_skein.hpp @@ -0,0 +1,347 @@ +#pragma once + +typedef unsigned int uint_t; /* native unsigned integer */ + +#define SKEIN_MODIFIER_WORDS ( 2) /* number of modifier (tweak) words */ + +#define SKEIN_256_STATE_WORDS ( 4) +#define SKEIN_512_STATE_WORDS ( 8) +#define SKEIN1024_STATE_WORDS (16) + +#define SKEIN_256_STATE_BYTES ( 8*SKEIN_256_STATE_WORDS) +#define SKEIN_512_STATE_BYTES ( 8*SKEIN_512_STATE_WORDS) +#define SKEIN1024_STATE_BYTES ( 8*SKEIN1024_STATE_WORDS) + +#define SKEIN_256_STATE_BITS (64*SKEIN_256_STATE_WORDS) +#define SKEIN_512_STATE_BITS (64*SKEIN_512_STATE_WORDS) +#define SKEIN1024_STATE_BITS (64*SKEIN1024_STATE_WORDS) + +#define SKEIN_256_BLOCK_BYTES ( 8*SKEIN_256_STATE_WORDS) +#define SKEIN_512_BLOCK_BYTES ( 8*SKEIN_512_STATE_WORDS) +#define SKEIN1024_BLOCK_BYTES ( 8*SKEIN1024_STATE_WORDS) + +#define SKEIN_MK_64(hi32,lo32) ((lo32) + (((uint64_t) (hi32)) << 32)) +#define SKEIN_KS_PARITY SKEIN_MK_64(0x1BD11BDA,0xA9FC1A22) + +#define SKEIN_T1_BIT(BIT) ((BIT) - 64) /* offset 64 because it's the second word */ + +#define SKEIN_T1_POS_FIRST SKEIN_T1_BIT(126) /* bits 126 : first block flag */ +#define SKEIN_T1_POS_BIT_PAD SKEIN_T1_BIT(119) /* bit 119 : partial final input byte */ +#define SKEIN_T1_POS_FINAL SKEIN_T1_BIT(127) /* bit 127 : final block flag */ +#define SKEIN_T1_POS_BLK_TYPE SKEIN_T1_BIT(120) /* bits 120..125: type field */ + +#define SKEIN_T1_FLAG_FIRST (((uint64_t) 1 ) << SKEIN_T1_POS_FIRST) +#define SKEIN_T1_FLAG_BIT_PAD (((uint64_t) 1 ) << SKEIN_T1_POS_BIT_PAD) +#define SKEIN_T1_FLAG_FINAL (((uint64_t) 1 ) << SKEIN_T1_POS_FINAL) + +#define SKEIN_BLK_TYPE_MSG (48) /* message processing */ +#define SKEIN_BLK_TYPE_OUT (63) /* output stage */ + +#define SKEIN_T1_BLK_TYPE(T) (((uint64_t) (SKEIN_BLK_TYPE_##T)) << SKEIN_T1_POS_BLK_TYPE) + +#define SKEIN_T1_BLK_TYPE_MSG SKEIN_T1_BLK_TYPE(MSG) /* message processing */ +#define SKEIN_T1_BLK_TYPE_OUT SKEIN_T1_BLK_TYPE(OUT) /* output stage */ + +#define SKEIN_T1_BLK_TYPE_OUT_FINAL (SKEIN_T1_BLK_TYPE_OUT | SKEIN_T1_FLAG_FINAL) + +#define Skein_Set_Tweak(ctxPtr,TWK_NUM,tVal) {(ctxPtr)->h.T[TWK_NUM] = (tVal);} + +#define Skein_Set_T0(ctxPtr,T0) Skein_Set_Tweak(ctxPtr,0,T0) +#define Skein_Set_T1(ctxPtr,T1) Skein_Set_Tweak(ctxPtr,1,T1) + +#define Skein_Set_T0_T1(ctxPtr,T0,T1) { \ + Skein_Set_T0(ctxPtr,(T0)); \ + Skein_Set_T1(ctxPtr,(T1)); } + +#define Skein_Start_New_Type(ctxPtr,BLK_TYPE) \ +{ Skein_Set_T0_T1(ctxPtr,0,SKEIN_T1_FLAG_FIRST | SKEIN_T1_BLK_TYPE_##BLK_TYPE); (ctxPtr)->h.bCnt=0; } + +#define Skein_Set_Bit_Pad_Flag(hdr) { (hdr).T[1] |= SKEIN_T1_FLAG_BIT_PAD; } + +#define KW_TWK_BASE (0) +#define KW_KEY_BASE (3) +#define ks (kw + KW_KEY_BASE) +#define ts (kw + KW_TWK_BASE) + +#define R512(p0,p1,p2,p3,p4,p5,p6,p7,R512ROT,rNum) \ + X##p0 += X##p1; X##p1 = ROTL64(X##p1,R512ROT##_0); X##p1 ^= X##p0; \ + X##p2 += X##p3; X##p3 = ROTL64(X##p3,R512ROT##_1); X##p3 ^= X##p2; \ + X##p4 += X##p5; X##p5 = ROTL64(X##p5,R512ROT##_2); X##p5 ^= X##p4; \ + X##p6 += X##p7; X##p7 = ROTL64(X##p7,R512ROT##_3); X##p7 ^= X##p6; + +#define I512(R) \ + X0 += ks[((R)+1) % 9]; \ + X1 += ks[((R)+2) % 9]; \ + X2 += ks[((R)+3) % 9]; \ + X3 += ks[((R)+4) % 9]; \ + X4 += ks[((R)+5) % 9]; \ + X5 += ks[((R)+6) % 9] + ts[((R)+1) % 3]; \ + X6 += ks[((R)+7) % 9] + ts[((R)+2) % 3]; \ + X7 += ks[((R)+8) % 9] + (R)+1; + + +#define R512_8_rounds(R) \ + R512(0,1,2,3,4,5,6,7,R_512_0,8*(R)+ 1); \ + R512(2,1,4,7,6,5,0,3,R_512_1,8*(R)+ 2); \ + R512(4,1,6,3,0,5,2,7,R_512_2,8*(R)+ 3); \ + R512(6,1,0,7,2,5,4,3,R_512_3,8*(R)+ 4); \ + I512(2*(R)); \ + R512(0,1,2,3,4,5,6,7,R_512_4,8*(R)+ 5); \ + R512(2,1,4,7,6,5,0,3,R_512_5,8*(R)+ 6); \ + R512(4,1,6,3,0,5,2,7,R_512_6,8*(R)+ 7); \ + R512(6,1,0,7,2,5,4,3,R_512_7,8*(R)+ 8); \ + I512(2*(R)+1); + +typedef struct +{ + size_t hashBitLen; + size_t bCnt; + uint64_t T[SKEIN_MODIFIER_WORDS]; +} Skein_Ctxt_Hdr_t; + +typedef struct { + Skein_Ctxt_Hdr_t h; + uint64_t X[SKEIN_256_STATE_WORDS]; + uint8_t b[SKEIN_256_BLOCK_BYTES]; +} Skein_256_Ctxt_t; + +typedef struct { + Skein_Ctxt_Hdr_t h; + uint64_t X[SKEIN_512_STATE_WORDS]; + uint8_t b[SKEIN_512_BLOCK_BYTES]; +} Skein_512_Ctxt_t; + +typedef struct { + Skein_Ctxt_Hdr_t h; + uint64_t X[SKEIN1024_STATE_WORDS]; + uint8_t b[SKEIN1024_BLOCK_BYTES]; +} Skein1024_Ctxt_t; + +typedef struct { + uint_t statebits; + union { + Skein_Ctxt_Hdr_t h; + Skein_256_Ctxt_t ctx_256; + Skein_512_Ctxt_t ctx_512; + Skein1024_Ctxt_t ctx1024; + } u; +} skeinHashState; + +__device__ void cn_skein_init(skeinHashState *state, size_t hashBitLen) +{ + const uint64_t SKEIN_512_IV_256[] = + { + SKEIN_MK_64(0xCCD044A1,0x2FDB3E13), + SKEIN_MK_64(0xE8359030,0x1A79A9EB), + SKEIN_MK_64(0x55AEA061,0x4F816E6F), + SKEIN_MK_64(0x2A2767A4,0xAE9B94DB), + SKEIN_MK_64(0xEC06025E,0x74DD7683), + SKEIN_MK_64(0xE7A436CD,0xC4746251), + SKEIN_MK_64(0xC36FBAF9,0x393AD185), + SKEIN_MK_64(0x3EEDBA18,0x33EDFC13) + }; + + Skein_512_Ctxt_t *ctx = &state->u.ctx_512; + + ctx->h.hashBitLen = hashBitLen; + + memcpy(ctx->X, SKEIN_512_IV_256, sizeof(ctx->X)); + + Skein_Start_New_Type(ctx, MSG); +} + +__device__ void cn_skein512_processblock(Skein_512_Ctxt_t * __restrict__ ctx, const uint8_t * __restrict__ blkPtr, size_t blkCnt, size_t byteCntAdd) +{ + enum { + R_512_0_0=46, R_512_0_1=36, R_512_0_2=19, R_512_0_3=37, + R_512_1_0=33, R_512_1_1=27, R_512_1_2=14, R_512_1_3=42, + R_512_2_0=17, R_512_2_1=49, R_512_2_2=36, R_512_2_3=39, + R_512_3_0=44, R_512_3_1= 9, R_512_3_2=54, R_512_3_3=56, + R_512_4_0=39, R_512_4_1=30, R_512_4_2=34, R_512_4_3=24, + R_512_5_0=13, R_512_5_1=50, R_512_5_2=10, R_512_5_3=17, + R_512_6_0=25, R_512_6_1=29, R_512_6_2=39, R_512_6_3=43, + R_512_7_0= 8, R_512_7_1=35, R_512_7_2=56, R_512_7_3=22 + }; + + uint64_t X0,X1,X2,X3,X4,X5,X6,X7; + uint64_t w[SKEIN_512_STATE_WORDS]; + uint64_t kw[SKEIN_512_STATE_WORDS+4]; + + ts[0] = ctx->h.T[0]; + ts[1] = ctx->h.T[1]; + + do + { + + ts[0] += byteCntAdd; + + ks[0] = ctx->X[0]; + ks[1] = ctx->X[1]; + ks[2] = ctx->X[2]; + ks[3] = ctx->X[3]; + ks[4] = ctx->X[4]; + ks[5] = ctx->X[5]; + ks[6] = ctx->X[6]; + ks[7] = ctx->X[7]; + ks[8] = ks[0] ^ ks[1] ^ ks[2] ^ ks[3] ^ + ks[4] ^ ks[5] ^ ks[6] ^ ks[7] ^ SKEIN_KS_PARITY; + + ts[2] = ts[0] ^ ts[1]; + + memcpy(w, blkPtr, SKEIN_512_STATE_WORDS << 3); + + X0 = w[0] + ks[0]; + X1 = w[1] + ks[1]; + X2 = w[2] + ks[2]; + X3 = w[3] + ks[3]; + X4 = w[4] + ks[4]; + X5 = w[5] + ks[5] + ts[0]; + X6 = w[6] + ks[6] + ts[1]; + X7 = w[7] + ks[7]; + + blkPtr += SKEIN_512_BLOCK_BYTES; + + R512_8_rounds( 0); + R512_8_rounds( 1); + R512_8_rounds( 2); + R512_8_rounds( 3); + R512_8_rounds( 4); + R512_8_rounds( 5); + R512_8_rounds( 6); + R512_8_rounds( 7); + R512_8_rounds( 8); + + ctx->X[0] = X0 ^ w[0]; + ctx->X[1] = X1 ^ w[1]; + ctx->X[2] = X2 ^ w[2]; + ctx->X[3] = X3 ^ w[3]; + ctx->X[4] = X4 ^ w[4]; + ctx->X[5] = X5 ^ w[5]; + ctx->X[6] = X6 ^ w[6]; + ctx->X[7] = X7 ^ w[7]; + + ts[1] &= ~SKEIN_T1_FLAG_FIRST; + } + while (--blkCnt); + + ctx->h.T[0] = ts[0]; + ctx->h.T[1] = ts[1]; +} + +__device__ void cn_skein_final(skeinHashState * __restrict__ state, uint8_t * __restrict__ hashVal) +{ + size_t i,n,byteCnt; + uint64_t X[SKEIN_512_STATE_WORDS]; + Skein_512_Ctxt_t *ctx = (Skein_512_Ctxt_t *)&state->u.ctx_512; + //size_t tmp; + //uint8_t *p8; + //uint64_t *p64; + + ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL; + + if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES) + { + memset(&ctx->b[ctx->h.bCnt],0,SKEIN_512_BLOCK_BYTES - ctx->h.bCnt); + //p8 = &ctx->b[ctx->h.bCnt]; + //tmp = SKEIN_512_BLOCK_BYTES - ctx->h.bCnt; + //for( i = 0; i < tmp; i++ ) *(p8+i) = 0; + } + + cn_skein512_processblock(ctx,ctx->b,1,ctx->h.bCnt); + + byteCnt = (ctx->h.hashBitLen + 7) >> 3; + + //uint8_t b[SKEIN_512_BLOCK_BYTES] == 64 + memset(ctx->b,0,sizeof(ctx->b)); + //p64 = (uint64_t *)ctx->b; + //for( i = 0; i < 8; i++ ) *(p64+i) = 0; + + memcpy(X,ctx->X,sizeof(X)); + + for (i=0;i*SKEIN_512_BLOCK_BYTES < byteCnt;i++) + { + ((uint64_t *)ctx->b)[0]= (uint64_t)i; + Skein_Start_New_Type(ctx,OUT_FINAL); + cn_skein512_processblock(ctx,ctx->b,1,sizeof(uint64_t)); + n = byteCnt - i*SKEIN_512_BLOCK_BYTES; + if (n >= SKEIN_512_BLOCK_BYTES) + n = SKEIN_512_BLOCK_BYTES; + memcpy(hashVal+i*SKEIN_512_BLOCK_BYTES,ctx->X,n); + memcpy(ctx->X,X,sizeof(X)); /* restore the counter mode key for next time */ + } +} + +__device__ void cn_skein512_update(Skein_512_Ctxt_t * __restrict__ ctx, const uint8_t * __restrict__ msg, size_t msgByteCnt) +{ + size_t n; + + if (msgByteCnt + ctx->h.bCnt > SKEIN_512_BLOCK_BYTES) + { + + if (ctx->h.bCnt) + { + + n = SKEIN_512_BLOCK_BYTES - ctx->h.bCnt; + + if (n) + { + memcpy(&ctx->b[ctx->h.bCnt],msg,n); + msgByteCnt -= n; + msg += n; + ctx->h.bCnt += n; + } + + cn_skein512_processblock(ctx,ctx->b,1,SKEIN_512_BLOCK_BYTES); + ctx->h.bCnt = 0; + } + + if (msgByteCnt > SKEIN_512_BLOCK_BYTES) + { + n = (msgByteCnt-1) / SKEIN_512_BLOCK_BYTES; + cn_skein512_processblock(ctx,msg,n,SKEIN_512_BLOCK_BYTES); + msgByteCnt -= n * SKEIN_512_BLOCK_BYTES; + msg += n * SKEIN_512_BLOCK_BYTES; + } + } + + if (msgByteCnt) + { + memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt); + ctx->h.bCnt += msgByteCnt; + } +} + +__device__ void cn_skein_update(skeinHashState * __restrict__ state, const BitSequence * __restrict__ data, DataLength databitlen) +{ + if ((databitlen & 7) == 0) + { + cn_skein512_update(&state->u.ctx_512,data,databitlen >> 3); + } + else + { + + size_t bCnt = (databitlen >> 3) + 1; + uint8_t b,mask; + + mask = (uint8_t) (1u << (7 - (databitlen & 7))); + b = (uint8_t) ((data[bCnt-1] & (0-mask)) | mask); + + cn_skein512_update(&state->u.ctx_512,data,bCnt-1); + cn_skein512_update(&state->u.ctx_512,&b , 1 ); + + Skein_Set_Bit_Pad_Flag(state->u.h); + } +} + +__device__ void cn_skein(const BitSequence * __restrict__ data, DataLength len, BitSequence * __restrict__ hashval) +{ + int hashbitlen = 256; + DataLength databitlen = len << 3; + skeinHashState state; + + state.statebits = 64*SKEIN_512_STATE_WORDS; + + cn_skein_init(&state, hashbitlen); + cn_skein_update(&state, data, databitlen); + cn_skein_final(&state, hashval); +} From de4cce9a9bf9b67dbe26098972d3c1b4e00d597f Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 24 Sep 2017 20:03:42 +0200 Subject: [PATCH 02/42] add amd backend - add backend - add auto suggestion --- backend/amd/amd_gpu/gpu.cpp | 869 ++++++++++++++++++++++++++++++++++++ backend/amd/amd_gpu/gpu.h | 50 +++ backend/amd/autoAdjust.hpp | 113 +++++ backend/amd/config.tpl | 24 + backend/amd/jconf.cpp | 261 +++++++++++ backend/amd/jconf.h | 43 ++ backend/amd/minethd.cpp | 241 ++++++++++ backend/amd/minethd.h | 60 +++ 8 files changed, 1661 insertions(+) create mode 100644 backend/amd/amd_gpu/gpu.cpp create mode 100644 backend/amd/amd_gpu/gpu.h create mode 100644 backend/amd/autoAdjust.hpp create mode 100644 backend/amd/config.tpl create mode 100644 backend/amd/jconf.cpp create mode 100644 backend/amd/jconf.h create mode 100644 backend/amd/minethd.cpp create mode 100644 backend/amd/minethd.h diff --git a/backend/amd/amd_gpu/gpu.cpp b/backend/amd/amd_gpu/gpu.cpp new file mode 100644 index 0000000..ebf1093 --- /dev/null +++ b/backend/amd/amd_gpu/gpu.cpp @@ -0,0 +1,869 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +const char* sSourcePath = "opencl\\cryptonight.cl"; + +static inline void port_sleep(size_t sec) +{ + Sleep(sec * 1000); +} +#else +#include +const char* sSourcePath = "opencl/cryptonight.cl"; + +static inline void port_sleep(size_t sec) +{ + sleep(sec); +} +#endif // _WIN32 + +#if 0 +static inline long long unsigned int int_port(size_t i) +{ + return i; +} +#endif + +#include "gpu.h" + +const char* err_to_str(cl_int ret) +{ + switch(ret) + { + case CL_SUCCESS: + return "CL_SUCCESS"; + case CL_DEVICE_NOT_FOUND: + return "CL_DEVICE_NOT_FOUND"; + case CL_DEVICE_NOT_AVAILABLE: + return "CL_DEVICE_NOT_AVAILABLE"; + case CL_COMPILER_NOT_AVAILABLE: + return "CL_COMPILER_NOT_AVAILABLE"; + case CL_MEM_OBJECT_ALLOCATION_FAILURE: + return "CL_MEM_OBJECT_ALLOCATION_FAILURE"; + case CL_OUT_OF_RESOURCES: + return "CL_OUT_OF_RESOURCES"; + case CL_OUT_OF_HOST_MEMORY: + return "CL_OUT_OF_HOST_MEMORY"; + case CL_PROFILING_INFO_NOT_AVAILABLE: + return "CL_PROFILING_INFO_NOT_AVAILABLE"; + case CL_MEM_COPY_OVERLAP: + return "CL_MEM_COPY_OVERLAP"; + case CL_IMAGE_FORMAT_MISMATCH: + return "CL_IMAGE_FORMAT_MISMATCH"; + case CL_IMAGE_FORMAT_NOT_SUPPORTED: + return "CL_IMAGE_FORMAT_NOT_SUPPORTED"; + case CL_BUILD_PROGRAM_FAILURE: + return "CL_BUILD_PROGRAM_FAILURE"; + case CL_MAP_FAILURE: + return "CL_MAP_FAILURE"; + case CL_MISALIGNED_SUB_BUFFER_OFFSET: + return "CL_MISALIGNED_SUB_BUFFER_OFFSET"; + case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: + return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST"; + case CL_COMPILE_PROGRAM_FAILURE: + return "CL_COMPILE_PROGRAM_FAILURE"; + case CL_LINKER_NOT_AVAILABLE: + return "CL_LINKER_NOT_AVAILABLE"; + case CL_LINK_PROGRAM_FAILURE: + return "CL_LINK_PROGRAM_FAILURE"; + case CL_DEVICE_PARTITION_FAILED: + return "CL_DEVICE_PARTITION_FAILED"; + case CL_KERNEL_ARG_INFO_NOT_AVAILABLE: + return "CL_KERNEL_ARG_INFO_NOT_AVAILABLE"; + case CL_INVALID_VALUE: + return "CL_INVALID_VALUE"; + case CL_INVALID_DEVICE_TYPE: + return "CL_INVALID_DEVICE_TYPE"; + case CL_INVALID_PLATFORM: + return "CL_INVALID_PLATFORM"; + case CL_INVALID_DEVICE: + return "CL_INVALID_DEVICE"; + case CL_INVALID_CONTEXT: + return "CL_INVALID_CONTEXT"; + case CL_INVALID_QUEUE_PROPERTIES: + return "CL_INVALID_QUEUE_PROPERTIES"; + case CL_INVALID_COMMAND_QUEUE: + return "CL_INVALID_COMMAND_QUEUE"; + case CL_INVALID_HOST_PTR: + return "CL_INVALID_HOST_PTR"; + case CL_INVALID_MEM_OBJECT: + return "CL_INVALID_MEM_OBJECT"; + case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: + return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR"; + case CL_INVALID_IMAGE_SIZE: + return "CL_INVALID_IMAGE_SIZE"; + case CL_INVALID_SAMPLER: + return "CL_INVALID_SAMPLER"; + case CL_INVALID_BINARY: + return "CL_INVALID_BINARY"; + case CL_INVALID_BUILD_OPTIONS: + return "CL_INVALID_BUILD_OPTIONS"; + case CL_INVALID_PROGRAM: + return "CL_INVALID_PROGRAM"; + case CL_INVALID_PROGRAM_EXECUTABLE: + return "CL_INVALID_PROGRAM_EXECUTABLE"; + case CL_INVALID_KERNEL_NAME: + return "CL_INVALID_KERNEL_NAME"; + case CL_INVALID_KERNEL_DEFINITION: + return "CL_INVALID_KERNEL_DEFINITION"; + case CL_INVALID_KERNEL: + return "CL_INVALID_KERNEL"; + case CL_INVALID_ARG_INDEX: + return "CL_INVALID_ARG_INDEX"; + case CL_INVALID_ARG_VALUE: + return "CL_INVALID_ARG_VALUE"; + case CL_INVALID_ARG_SIZE: + return "CL_INVALID_ARG_SIZE"; + case CL_INVALID_KERNEL_ARGS: + return "CL_INVALID_KERNEL_ARGS"; + case CL_INVALID_WORK_DIMENSION: + return "CL_INVALID_WORK_DIMENSION"; + case CL_INVALID_WORK_GROUP_SIZE: + return "CL_INVALID_WORK_GROUP_SIZE"; + case CL_INVALID_WORK_ITEM_SIZE: + return "CL_INVALID_WORK_ITEM_SIZE"; + case CL_INVALID_GLOBAL_OFFSET: + return "CL_INVALID_GLOBAL_OFFSET"; + case CL_INVALID_EVENT_WAIT_LIST: + return "CL_INVALID_EVENT_WAIT_LIST"; + case CL_INVALID_EVENT: + return "CL_INVALID_EVENT"; + case CL_INVALID_OPERATION: + return "CL_INVALID_OPERATION"; + case CL_INVALID_GL_OBJECT: + return "CL_INVALID_GL_OBJECT"; + case CL_INVALID_BUFFER_SIZE: + return "CL_INVALID_BUFFER_SIZE"; + case CL_INVALID_MIP_LEVEL: + return "CL_INVALID_MIP_LEVEL"; + case CL_INVALID_GLOBAL_WORK_SIZE: + return "CL_INVALID_GLOBAL_WORK_SIZE"; + case CL_INVALID_PROPERTY: + return "CL_INVALID_PROPERTY"; + case CL_INVALID_IMAGE_DESCRIPTOR: + return "CL_INVALID_IMAGE_DESCRIPTOR"; + case CL_INVALID_COMPILER_OPTIONS: + return "CL_INVALID_COMPILER_OPTIONS"; + case CL_INVALID_LINKER_OPTIONS: + return "CL_INVALID_LINKER_OPTIONS"; + case CL_INVALID_DEVICE_PARTITION_COUNT: + return "CL_INVALID_DEVICE_PARTITION_COUNT"; +#ifdef CL_VERSION_2_0 + case CL_INVALID_PIPE_SIZE: + return "CL_INVALID_PIPE_SIZE"; + case CL_INVALID_DEVICE_QUEUE: + return "CL_INVALID_DEVICE_QUEUE"; +#endif + default: + return "UNKNOWN_ERROR"; + } +} + +#if 0 +void printer::inst()->print_msg(L1,const char* fmt, ...); +void printer::inst()->print_str(const char* str); +#endif + +char* LoadTextFile(const char* filename) +{ + size_t flen; + char* out; + FILE* kernel = fopen(filename, "rb"); + + if(kernel == NULL) + return NULL; + + fseek(kernel, 0, SEEK_END); + flen = ftell(kernel); + fseek(kernel, 0, SEEK_SET); + + out = (char*)malloc(flen+1); + size_t r = fread(out, flen, 1, kernel); + fclose(kernel); + + if(r != 1) + { + free(out); + return NULL; + } + + out[flen] = '\0'; + return out; +} + +size_t InitOpenCLGpu(cl_context opencl_ctx, GpuContext* ctx, char* source_code) +{ + size_t MaximumWorkSize; + cl_int ret; + + if((ret = clGetDeviceInfo(ctx->DeviceID, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), &MaximumWorkSize, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when querying a device's max worksize using clGetDeviceInfo.", err_to_str(ret)); + return ERR_OCL_API; + } + + printer::inst()->print_msg(L1,"Device %lu work size %lu / %lu.", ctx->deviceIdx, ctx->workSize, MaximumWorkSize); +#ifdef CL_VERSION_2_0 + const cl_queue_properties CommandQueueProperties[] = { 0, 0, 0 }; + ctx->CommandQueues = clCreateCommandQueueWithProperties(opencl_ctx, ctx->DeviceID, CommandQueueProperties, &ret); +#else + const cl_command_queue_properties CommandQueueProperties = { 0 }; + ctx->CommandQueues = clCreateCommandQueue(opencl_ctx, ctx->DeviceID, CommandQueueProperties, &ret); +#endif + + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateCommandQueueWithProperties.", err_to_str(ret)); + return ERR_OCL_API; + } + + ctx->InputBuffer = clCreateBuffer(opencl_ctx, CL_MEM_READ_ONLY, 88, NULL, &ret); + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateBuffer to create input buffer.", err_to_str(ret)); + return ERR_OCL_API; + } + + size_t g_thd = ctx->rawIntensity; + ctx->ExtraBuffers[0] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, (1 << 21) * g_thd, NULL, &ret); + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateBuffer to create hash scratchpads buffer.", err_to_str(ret)); + return ERR_OCL_API; + } + + ctx->ExtraBuffers[1] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, 200 * g_thd, NULL, &ret); + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateBuffer to create hash states buffer.", err_to_str(ret)); + return ERR_OCL_API; + } + + // Blake-256 branches + ctx->ExtraBuffers[2] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret); + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateBuffer to create Branch 0 buffer.", err_to_str(ret)); + return ERR_OCL_API; + } + + // Groestl-256 branches + ctx->ExtraBuffers[3] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret); + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateBuffer to create Branch 1 buffer.", err_to_str(ret)); + return ERR_OCL_API; + } + + // JH-256 branches + ctx->ExtraBuffers[4] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret); + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateBuffer to create Branch 2 buffer.", err_to_str(ret)); + return ERR_OCL_API; + } + + // Skein-512 branches + ctx->ExtraBuffers[5] = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * (g_thd + 2), NULL, &ret); + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateBuffer to create Branch 3 buffer.", err_to_str(ret)); + return ERR_OCL_API; + } + + // Assume we may find up to 0xFF nonces in one run - it's reasonable + ctx->OutputBuffer = clCreateBuffer(opencl_ctx, CL_MEM_READ_WRITE, sizeof(cl_uint) * 0x100, NULL, &ret); + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateBuffer to create output buffer.", err_to_str(ret)); + return ERR_OCL_API; + } + + ctx->Program = clCreateProgramWithSource(opencl_ctx, 1, (const char**)&source_code, NULL, &ret); + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateProgramWithSource on the contents of cryptonight.cl", err_to_str(ret)); + return ERR_OCL_API; + } + + char options[32]; + snprintf(options, sizeof(options), "-I. -DWORKSIZE=%llu", int_port(ctx->workSize)); + ret = clBuildProgram(ctx->Program, 1, &ctx->DeviceID, options, NULL, NULL); + if(ret != CL_SUCCESS) + { + size_t len; + printer::inst()->print_msg(L1,"Error %s when calling clBuildProgram.", err_to_str(ret)); + + if((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_LOG, 0, NULL, &len)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clGetProgramBuildInfo for length of build log output.", err_to_str(ret)); + return ERR_OCL_API; + } + + char* BuildLog = (char*)malloc(len + 1); + BuildLog[0] = '\0'; + + if((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_LOG, len, BuildLog, NULL)) != CL_SUCCESS) + { + free(BuildLog); + printer::inst()->print_msg(L1,"Error %s when calling clGetProgramBuildInfo for build log.", err_to_str(ret)); + return ERR_OCL_API; + } + + printer::inst()->print_str("Build log:\n"); + printer::inst()->print_str(BuildLog); + + free(BuildLog); + return ERR_OCL_API; + } + + cl_build_status status; + do + { + if((ret = clGetProgramBuildInfo(ctx->Program, ctx->DeviceID, CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &status, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clGetProgramBuildInfo for status of build.", err_to_str(ret)); + return ERR_OCL_API; + } + port_sleep(1); + } + while(status == CL_BUILD_IN_PROGRESS); + + const char *KernelNames[] = { "cn0", "cn1", "cn2", "Blake", "Groestl", "JH", "Skein" }; + for(int i = 0; i < 7; ++i) + { + ctx->Kernels[i] = clCreateKernel(ctx->Program, KernelNames[i], &ret); + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateKernel for kernel %s.", err_to_str(ret), KernelNames[i]); + return ERR_OCL_API; + } + } + + ctx->Nonce = 0; + return 0; +} + +const cl_platform_info attributeTypes[5] = { + CL_PLATFORM_NAME, + CL_PLATFORM_VENDOR, + CL_PLATFORM_VERSION, + CL_PLATFORM_PROFILE, + CL_PLATFORM_EXTENSIONS +}; + +const char* const attributeNames[] = { + "CL_PLATFORM_NAME", + "CL_PLATFORM_VENDOR", + "CL_PLATFORM_VERSION", + "CL_PLATFORM_PROFILE", + "CL_PLATFORM_EXTENSIONS" +}; + +#define NELEMS(x) (sizeof(x) / sizeof((x)[0])) + +void PrintDeviceInfo(cl_device_id device) +{ + char queryBuffer[1024]; + int queryInt; + cl_int clError; + clError = clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(queryBuffer), &queryBuffer, NULL); + printf(" CL_DEVICE_NAME: %s\n", queryBuffer); + queryBuffer[0] = '\0'; + clError = clGetDeviceInfo(device, CL_DEVICE_VENDOR, sizeof(queryBuffer), &queryBuffer, NULL); + printf(" CL_DEVICE_VENDOR: %s\n", queryBuffer); + queryBuffer[0] = '\0'; + clError = clGetDeviceInfo(device, CL_DRIVER_VERSION, sizeof(queryBuffer), &queryBuffer, NULL); + printf(" CL_DRIVER_VERSION: %s\n", queryBuffer); + queryBuffer[0] = '\0'; + clError = clGetDeviceInfo(device, CL_DEVICE_VERSION, sizeof(queryBuffer), &queryBuffer, NULL); + printf(" CL_DEVICE_VERSION: %s\n", queryBuffer); + queryBuffer[0] = '\0'; + clError = clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(int), &queryInt, NULL); + printf(" CL_DEVICE_MAX_COMPUTE_UNITS: %d\n", queryInt); +} + +uint32_t getNumPlatforms() +{ + cl_uint num_platforms = 0; + cl_platform_id * platforms = NULL; + cl_int clStatus; + + // Get platform and device information + clStatus = clGetPlatformIDs(0, NULL, &num_platforms); + platforms = (cl_platform_id *) malloc(sizeof(cl_platform_id) * num_platforms); + clStatus = clGetPlatformIDs(num_platforms, platforms, NULL); + + return num_platforms; +} + +std::vector getAMDDevices(int index) +{ + std::vector ctxVec; + cl_platform_id * platforms = NULL; + cl_int clStatus; + cl_uint num_devices; + cl_device_id *device_list = NULL; + + uint32_t numPlatforms = getNumPlatforms(); + + + platforms = (cl_platform_id *) malloc(sizeof(cl_platform_id) * numPlatforms); + clStatus = clGetPlatformIDs(numPlatforms, platforms, NULL); + + clStatus = clGetDeviceIDs( platforms[index], CL_DEVICE_TYPE_GPU, 0, NULL, &num_devices); + device_list = (cl_device_id *) malloc(sizeof(cl_device_id)*num_devices); + clStatus = clGetDeviceIDs( platforms[index], CL_DEVICE_TYPE_GPU, num_devices, device_list, NULL); + for (int k = 0; k < num_devices; k++) { + cl_int clError; + std::vector devVendorVec(1024); + clError = clGetDeviceInfo(device_list[k], CL_DEVICE_VENDOR, devVendorVec.size(), devVendorVec.data(), NULL); + std::string devVendor(devVendorVec.data()); + if( devVendor.find("Advanced Micro Devices") != std::string::npos) + { + GpuContext ctx; + ctx.deviceIdx = k; + clError = clGetDeviceInfo(device_list[k], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(int), &(ctx.computeUnits), NULL); + size_t maxMem; + clError = clGetDeviceInfo(device_list[k], CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(size_t), &(maxMem), NULL); + clError = clGetDeviceInfo(device_list[k], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(size_t), &(ctx.freeMem), NULL); + // if environment variable GPU_SINGLE_ALLOC_PERCENT is not set we can not allocate the full memory + ctx.freeMem = std::min(ctx.freeMem, maxMem); + std::vector devNameVec(1024); + clError = clGetDeviceInfo(device_list[k], CL_DEVICE_NAME, devNameVec.size(), devNameVec.data(), NULL); + ctx.name = std::string(devNameVec.data()); + printer::inst()->print_msg(L0,"Found OpenCL GPU %s.",ctx.name.c_str()); + ctx.DeviceID = device_list[k]; + ctxVec.push_back(ctx); + } + } + + + free(device_list); + free(platforms); + + return ctxVec; +} + +int getAMDPlatformIdx() +{ + + uint32_t numPlatforms = getNumPlatforms(); + + if(numPlatforms == 0) + { + printer::inst()->print_msg(L0,"WARNING: No OpenCL platform found."); + return -1; + } + cl_platform_id * platforms = NULL; + cl_int clStatus; + + platforms = (cl_platform_id *) malloc(sizeof(cl_platform_id) * numPlatforms); + clStatus = clGetPlatformIDs(numPlatforms, platforms, NULL); + + int platformIndex = -1; + + for (int i = 0; i < numPlatforms; i++) { + size_t infoSize; + clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, 0, NULL, &infoSize); + std::vector platformNameVec(infoSize); + + clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, infoSize, platformNameVec.data(), NULL); + std::string platformName(platformNameVec.data()); + if( platformName.find("Advanced Micro Devices") != std::string::npos) + { + platformIndex = i; + printer::inst()->print_msg(L0,"Found AMD platform index id = %i, name = %s",i , platformName.c_str()); + break; + } + } + + free(platforms); + return platformIndex; +} + +// RequestedDeviceIdxs is a list of OpenCL device indexes +// NumDevicesRequested is number of devices in RequestedDeviceIdxs list +// Returns 0 on success, -1 on stupid params, -2 on OpenCL API error +size_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx) +{ + + cl_context opencl_ctx; + cl_int ret; + cl_uint entries; + + if((ret = clGetPlatformIDs(0, NULL, &entries)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clGetPlatformIDs for number of platforms.", err_to_str(ret)); + return ERR_OCL_API; + } + + + // The number of platforms naturally is the index of the last platform plus one. + if(entries <= platform_idx) + { + printer::inst()->print_msg(L1,"Selected OpenCL platform index %d doesn't exist.", platform_idx); + return ERR_STUPID_PARAMS; + } + + + + cl_platform_id * platforms = NULL; + cl_int clStatus; + uint32_t numPlatforms = getNumPlatforms(); + + platforms = (cl_platform_id *) malloc(sizeof(cl_platform_id) * numPlatforms); + clStatus = clGetPlatformIDs(numPlatforms, platforms, NULL); + + size_t infoSize; + clGetPlatformInfo(platforms[platform_idx], CL_PLATFORM_VENDOR, 0, NULL, &infoSize); + std::vector platformNameVec(infoSize); + clGetPlatformInfo(platforms[platform_idx], CL_PLATFORM_VENDOR, infoSize, platformNameVec.data(), NULL); + std::string platformName(platformNameVec.data()); + if( platformName.find("Advanced Micro Devices") == std::string::npos) + { + printer::inst()->print_msg(L1,"WARNING: using non AMD device: %s", platformName.c_str()); + return ERR_STUPID_PARAMS; + } + + free(platforms); + + /*MSVC skimping on devel costs by shoehorning C99 to be a subset of C++? Noooo... can't be.*/ +#ifdef __GNUC__ + cl_platform_id PlatformIDList[entries]; +#else + cl_platform_id* PlatformIDList = _alloca(entries * sizeof(cl_platform_id)); +#endif + if((ret = clGetPlatformIDs(entries, PlatformIDList, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clGetPlatformIDs for platform ID information.", err_to_str(ret)); + return ERR_OCL_API; + } + + if((ret = clGetDeviceIDs(PlatformIDList[platform_idx], CL_DEVICE_TYPE_GPU, 0, NULL, &entries)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clGetDeviceIDs for number of devices.", err_to_str(ret)); + return ERR_OCL_API; + } + + // Same as the platform index sanity check, except we must check all requested device indexes + for(int i = 0; i < num_gpus; ++i) + { + if(entries <= ctx[i].deviceIdx) + { + printer::inst()->print_msg(L1,"Selected OpenCL device index %lu doesn't exist.\n", ctx[i].deviceIdx); + return ERR_STUPID_PARAMS; + } + } + +#ifdef __GNUC__ + cl_device_id DeviceIDList[entries]; +#else + cl_device_id* DeviceIDList = _alloca(entries * sizeof(cl_device_id)); +#endif + if((ret = clGetDeviceIDs(PlatformIDList[platform_idx], CL_DEVICE_TYPE_GPU, entries, DeviceIDList, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clGetDeviceIDs for device ID information.", err_to_str(ret)); + return ERR_OCL_API; + } + + // Indexes sanity checked above +#ifdef __GNUC__ + cl_device_id TempDeviceList[num_gpus]; +#else + cl_device_id* TempDeviceList = _alloca(entries * sizeof(cl_device_id)); +#endif + for(int i = 0; i < num_gpus; ++i) + { + ctx[i].DeviceID = DeviceIDList[ctx[i].deviceIdx]; + TempDeviceList[i] = DeviceIDList[ctx[i].deviceIdx]; + } + + opencl_ctx = clCreateContext(NULL, num_gpus, TempDeviceList, NULL, NULL, &ret); + if(ret != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clCreateContext.", err_to_str(ret)); + return ERR_OCL_API; + } + + char* source_code = LoadTextFile(sSourcePath); + if(source_code == NULL) + { + printer::inst()->print_msg(L1,"Couldn't locate GPU source code file at %s.", sSourcePath); + return ERR_STUPID_PARAMS; + } + + for(int i = 0; i < num_gpus; ++i) + { + if((ret = InitOpenCLGpu(opencl_ctx, &ctx[i], source_code)) != ERR_SUCCESS) + { + free(source_code); + return ret; + } + } + free(source_code); + + return ERR_SUCCESS; +} + +size_t XMRSetJob(GpuContext* ctx, uint8_t* input, size_t input_len, uint32_t target) +{ + cl_int ret; + + if(input_len > 84) + return ERR_STUPID_PARAMS; + + input[input_len] = 0x01; + memset(input + input_len + 1, 0, 88 - input_len - 1); + + if((ret = clEnqueueWriteBuffer(ctx->CommandQueues, ctx->InputBuffer, CL_TRUE, 0, 88, input, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueWriteBuffer to fill input buffer.", err_to_str(ret)); + return ERR_OCL_API; + } + + if((ret = clSetKernelArg(ctx->Kernels[0], 0, sizeof(cl_mem), &ctx->InputBuffer)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel 0, argument 0.", err_to_str(ret)); + return ERR_OCL_API; + } + + // Scratchpads + if((ret = clSetKernelArg(ctx->Kernels[0], 1, sizeof(cl_mem), ctx->ExtraBuffers + 0)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel 0, argument 1.", err_to_str(ret)); + return ERR_OCL_API; + } + + // States + if((ret = clSetKernelArg(ctx->Kernels[0], 2, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel 0, argument 2.", err_to_str(ret)); + return ERR_OCL_API; + } + + // CN2 Kernel + + // Scratchpads + if((ret = clSetKernelArg(ctx->Kernels[1], 0, sizeof(cl_mem), ctx->ExtraBuffers + 0)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel 1, argument 0.", err_to_str(ret)); + return ERR_OCL_API; + } + + // States + if((ret = clSetKernelArg(ctx->Kernels[1], 1, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel 1, argument 1.", err_to_str(ret)); + return ERR_OCL_API; + } + + // CN3 Kernel + // Scratchpads + if((ret = clSetKernelArg(ctx->Kernels[2], 0, sizeof(cl_mem), ctx->ExtraBuffers + 0)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel 2, argument 0.", err_to_str(ret)); + return ERR_OCL_API; + } + + // States + if((ret = clSetKernelArg(ctx->Kernels[2], 1, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel 2, argument 1.", err_to_str(ret)); + return ERR_OCL_API; + } + + // Branch 0 + if((ret = clSetKernelArg(ctx->Kernels[2], 2, sizeof(cl_mem), ctx->ExtraBuffers + 2)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel 2, argument 2.", err_to_str(ret)); + return ERR_OCL_API; + } + + // Branch 1 + if((ret = clSetKernelArg(ctx->Kernels[2], 3, sizeof(cl_mem), ctx->ExtraBuffers + 3)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel 2, argument 3.", err_to_str(ret)); + return ERR_OCL_API; + } + + // Branch 2 + if((ret = clSetKernelArg(ctx->Kernels[2], 4, sizeof(cl_mem), ctx->ExtraBuffers + 4)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel 2, argument 4.", err_to_str(ret)); + return ERR_OCL_API; + } + + // Branch 3 + if((ret = clSetKernelArg(ctx->Kernels[2], 5, sizeof(cl_mem), ctx->ExtraBuffers + 5)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel 2, argument 5.", err_to_str(ret)); + return ERR_OCL_API; + } + + for(int i = 0; i < 4; ++i) + { + // States + if((ret = clSetKernelArg(ctx->Kernels[i + 3], 0, sizeof(cl_mem), ctx->ExtraBuffers + 1)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel %d, argument %d.", err_to_str(ret), i + 3, 0); + return ERR_OCL_API; + } + + // Nonce buffer + if((ret = clSetKernelArg(ctx->Kernels[i + 3], 1, sizeof(cl_mem), ctx->ExtraBuffers + (i + 2))) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel %d, argument %d.", err_to_str(ret), i + 3, 1); + return ERR_OCL_API; + } + + // Output + if((ret = clSetKernelArg(ctx->Kernels[i + 3], 2, sizeof(cl_mem), &ctx->OutputBuffer)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel %d, argument %d.", err_to_str(ret), i + 3, 2); + return ERR_OCL_API; + } + + // Target + if((ret = clSetKernelArg(ctx->Kernels[i + 3], 3, sizeof(cl_uint), &target)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel %d, argument %d.", err_to_str(ret), i + 3, 3); + return ERR_OCL_API; + } + } + + return ERR_SUCCESS; +} + +size_t XMRRunJob(GpuContext* ctx, cl_uint* HashOutput) +{ + cl_int ret; + cl_uint zero = 0; + size_t BranchNonces[4]; + memset(BranchNonces,0,sizeof(size_t)*4); + + size_t g_thd = ctx->rawIntensity; + size_t w_size = ctx->workSize; + + for(int i = 2; i < 6; ++i) + { + if((ret = clEnqueueWriteBuffer(ctx->CommandQueues, ctx->ExtraBuffers[i], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), &zero, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueWriteBuffer to zero branch buffer counter %d.", err_to_str(ret), i - 2); + return ERR_OCL_API; + } + } + + if((ret = clEnqueueWriteBuffer(ctx->CommandQueues, ctx->OutputBuffer, CL_FALSE, sizeof(cl_uint) * 0xFF, sizeof(cl_uint), &zero, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret)); + return ERR_OCL_API; + } + + clFinish(ctx->CommandQueues); + + size_t Nonce[2] = {ctx->Nonce, 1}, gthreads[2] = { g_thd, 8 }, lthreads[2] = { w_size, 8 }; + if((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[0], 2, Nonce, gthreads, lthreads, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueNDRangeKernel for kernel %d.", err_to_str(ret), 0); + return ERR_OCL_API; + } + + /*for(int i = 1; i < 3; ++i) + { + if((ret = clEnqueueNDRangeKernel(*ctx->CommandQueues, ctx->Kernels[i], 1, &ctx->Nonce, &g_thd, &w_size, 0, NULL, NULL)) != CL_SUCCESS) + { + Log(LOG_CRITICAL, "Error %s when calling clEnqueueNDRangeKernel for kernel %d.", err_to_str(ret), i); + return(ERR_OCL_API); + } + }*/ + + if((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[1], 1, &ctx->Nonce, &g_thd, &w_size, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueNDRangeKernel for kernel %d.", err_to_str(ret), 1); + return ERR_OCL_API; + } + + if((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[2], 2, Nonce, gthreads, lthreads, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueNDRangeKernel for kernel %d.", err_to_str(ret), 2); + return ERR_OCL_API; + } + + if((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[2], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret)); + return ERR_OCL_API; + } + + if((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[3], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces + 1, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret)); + return ERR_OCL_API; + } + + if((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[4], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces + 2, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret)); + return ERR_OCL_API; + } + + if((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->ExtraBuffers[5], CL_FALSE, sizeof(cl_uint) * g_thd, sizeof(cl_uint), BranchNonces + 3, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret)); + return ERR_OCL_API; + } + + clFinish(ctx->CommandQueues); + + for(int i = 0; i < 4; ++i) + { + if(BranchNonces[i]) + { + // Threads + if((clSetKernelArg(ctx->Kernels[i + 3], 4, sizeof(cl_ulong), BranchNonces + i)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clSetKernelArg for kernel %d, argument %d.", err_to_str(ret), i + 3, 4); + return(ERR_OCL_API); + } + + BranchNonces[i] = ((size_t)ceil( (double)BranchNonces[i] / (double)w_size) ) * w_size; + if((ret = clEnqueueNDRangeKernel(ctx->CommandQueues, ctx->Kernels[i + 3], 1, &ctx->Nonce, BranchNonces + i, &w_size, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueNDRangeKernel for kernel %d.", err_to_str(ret), i + 3); + return ERR_OCL_API; + } + } + } + + if((ret = clEnqueueReadBuffer(ctx->CommandQueues, ctx->OutputBuffer, CL_TRUE, 0, sizeof(cl_uint) * 0x100, HashOutput, 0, NULL, NULL)) != CL_SUCCESS) + { + printer::inst()->print_msg(L1,"Error %s when calling clEnqueueReadBuffer to fetch results.", err_to_str(ret)); + return ERR_OCL_API; + } + + clFinish(ctx->CommandQueues); + ctx->Nonce += g_thd; + + return ERR_SUCCESS; +} diff --git a/backend/amd/amd_gpu/gpu.h b/backend/amd/amd_gpu/gpu.h new file mode 100644 index 0000000..8a71cfa --- /dev/null +++ b/backend/amd/amd_gpu/gpu.h @@ -0,0 +1,50 @@ +#pragma once + +#if defined(__APPLE__) +#include +#else +#include +#endif + +#include +#include +#include "../../../console.h" + +#define ERR_SUCCESS (0) +#define ERR_OCL_API (2) +#define ERR_STUPID_PARAMS (1) + + + +struct GpuContext +{ + /*Input vars*/ + size_t deviceIdx; + size_t rawIntensity; + size_t workSize; + + /*Output vars*/ + cl_device_id DeviceID; + cl_command_queue CommandQueues; + cl_mem InputBuffer; + cl_mem OutputBuffer; + cl_mem ExtraBuffers[6]; + cl_program Program; + cl_kernel Kernels[7]; + size_t freeMem; + int computeUnits; + std::string name; + + size_t Nonce; + +}; + +uint32_t getNumPlatforms(); +int getAMDPlatformIdx(); +std::vector getAMDDevices(int index); + +size_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx); +size_t XMRSetJob(GpuContext* ctx, uint8_t* input, size_t input_len, uint32_t target); +size_t XMRRunJob(GpuContext* ctx, cl_uint* HashOutput); + + diff --git a/backend/amd/autoAdjust.hpp b/backend/amd/autoAdjust.hpp new file mode 100644 index 0000000..fd9ea94 --- /dev/null +++ b/backend/amd/autoAdjust.hpp @@ -0,0 +1,113 @@ + +#pragma once + +#include "autoAdjust.hpp" + + +#include "jconf.h" +#include "../../console.h" +#include "../../ConfigEditor.hpp" +#include "amd_gpu/gpu.h" + +#include +#include +#include +#include +#include +#include + +#if defined(__APPLE__) +#include +#else +#include +#endif + + +namespace xmrstak +{ +namespace amd +{ + +class autoAdjust +{ +public: + + autoAdjust() + { + + } + + /** print the adjusted values if needed + * + * Routine exit the application and print the adjusted values if needed else + * nothing is happened. + */ + bool printConfig() + { + + int platformIndex = getAMDPlatformIdx(); + + if(platformIndex == -1) + { + printer::inst()->print_msg(L0,"WARNING: No AMD OpenCL platform found. Possible driver issues or wrong vendor driver."); + return false; + } + + devVec = getAMDDevices(0); + + + int deviceCount = devVec.size(); + + if(deviceCount == 0) + return false; + + + generateThreadConfig(platformIndex); + return true; + + } + +private: + + void generateThreadConfig(const int platformIndex) + { + // load the template of the backend config into a char variable + const char *tpl = + #include "./config.tpl" + ; + + ConfigEditor configTpl{}; + configTpl.set( std::string(tpl) ); + + std::string conf; + conf += std::string("\"gpu_threads_conf\" :\n[\n"); + int i = 0; + for(auto& ctx : devVec) + { + // use 90% of available memory + size_t availableMem = (ctx.freeMem * 100u) / 110; + size_t units = ctx.computeUnits; + size_t perThread = (size_t(1u)<<21) + 224u; + size_t max_intensity = availableMem / perThread; + size_t intensity = std::min( size_t(1000u) , max_intensity ); + conf += std::string(" // gpu: ") + ctx.name + "\n"; + conf += std::string(" { \"index\" : ") + std::to_string(ctx.deviceIdx) + ",\n" + + " \"intensity\" : " + std::to_string(intensity) + ", \"worksize\" : " + std::to_string(8) + ",\n" + + " \"affine_to_cpu\" : false, \n" + " },\n"; + ++i; + } + conf += std::string("],\n\n"); + + configTpl.replace("PLATFORMINDEX",std::to_string(platformIndex)); + configTpl.replace("NUMGPUS",std::to_string(devVec.size())); + configTpl.replace("GPUCONFIG",conf); + configTpl.write("amd.txt"); + printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", "amd.txt"); + } + + std::vector devVec; +}; + +} // namespace amd +} // namepsace xmrstak diff --git a/backend/amd/config.tpl b/backend/amd/config.tpl new file mode 100644 index 0000000..6d08730 --- /dev/null +++ b/backend/amd/config.tpl @@ -0,0 +1,24 @@ +R"===( + +/* + * Number of GPUs that you have in your system. Each GPU will get its own CPU thread. + */ +"gpu_thread_num" : NUMGPUS, + +/* + * GPU configuration. You should play around with intensity and worksize as the fastest settings will vary. + * index - GPU index number usually starts from 0 + * intensity - Number of parallel GPU threads (nothing to do with CPU threads) + * worksize - Number of local GPU threads (nothing to do with CPU threads) + * affine_to_cpu - This will affine the thread to a CPU. This can make a GPU miner play along nicer with a CPU miner. + */ + + +GPUCONFIG + +/* + * Platform index. This will be 0 unless you have different OpenCL platform - eg. AMD and Intel. + */ +"platform_index" : PLATFORMINDEX, + +)===" diff --git a/backend/amd/jconf.cpp b/backend/amd/jconf.cpp new file mode 100644 index 0000000..f8a551e --- /dev/null +++ b/backend/amd/jconf.cpp @@ -0,0 +1,261 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining + * it with OpenSSL (or a modified version of that library), containing parts + * covered by the terms of OpenSSL License and SSLeay License, the licensors + * of this Program grant you additional permission to convey the resulting work. + * + */ + + +#include "jconf.h" + +#include +#include +#include + +#ifdef _WIN32 +#define strcasecmp _stricmp +#include +#else +#include +#endif + +#include "../../rapidjson/document.h" +#include "../../rapidjson/error/en.h" +#include "../../jext.h" +#include "../../console.h" + +namespace xmrstak +{ +namespace amd +{ + +using namespace rapidjson; + +/* + * This enum needs to match index in oConfigValues, otherwise we will get a runtime error + */ +enum configEnum { iGpuThreadNum, aGpuThreadsConf, iPlatformIdx }; + +struct configVal { + configEnum iName; + const char* sName; + Type iType; +}; + +//Same order as in configEnum, as per comment above +configVal oConfigValues[] = { + { iGpuThreadNum, "gpu_thread_num", kNumberType }, + { aGpuThreadsConf, "gpu_threads_conf", kArrayType }, + { iPlatformIdx, "platform_index", kNumberType } +}; + +constexpr size_t iConfigCnt = (sizeof(oConfigValues)/sizeof(oConfigValues[0])); + +inline bool checkType(Type have, Type want) +{ + if(want == have) + return true; + else if(want == kTrueType && have == kFalseType) + return true; + else if(want == kFalseType && have == kTrueType) + return true; + else + return false; +} + +struct jconf::opaque_private +{ + Document jsonDoc; + const Value* configValues[iConfigCnt]; //Compile time constant + + opaque_private() + { + } +}; + +jconf* jconf::oInst = nullptr; + +jconf::jconf() +{ + prv = new opaque_private(); +} + +bool jconf::GetThreadConfig(size_t id, thd_cfg &cfg) +{ + if(id >= prv->configValues[aGpuThreadsConf]->Size()) + return false; + + const Value& oThdConf = prv->configValues[aGpuThreadsConf]->GetArray()[id]; + + if(!oThdConf.IsObject()) + return false; + + const Value *idx, *intensity, *w_size, *aff; + idx = GetObjectMember(oThdConf, "index"); + intensity = GetObjectMember(oThdConf, "intensity"); + w_size = GetObjectMember(oThdConf, "worksize"); + aff = GetObjectMember(oThdConf, "affine_to_cpu"); + + if(idx == nullptr || intensity == nullptr || w_size == nullptr || aff == nullptr) + return false; + + if(!idx->IsUint64() || !intensity->IsUint64() || !w_size->IsUint64()) + return false; + + if(!aff->IsUint64() && !aff->IsBool()) + return false; + + cfg.index = idx->GetUint64(); + cfg.intensity = intensity->GetUint64(); + cfg.w_size = w_size->GetUint64(); + + if(aff->IsNumber()) + cfg.cpu_aff = aff->GetInt64(); + else + cfg.cpu_aff = -1; + + return true; +} + +size_t jconf::GetPlatformIdx() +{ + return prv->configValues[iPlatformIdx]->GetUint64(); +} + +size_t jconf::GetThreadCount() +{ + return prv->configValues[aGpuThreadsConf]->Size(); +} + +bool jconf::parse_config(const char* sFilename) +{ + FILE * pFile; + char * buffer; + size_t flen; + + pFile = fopen(sFilename, "rb"); + if (pFile == NULL) + { + printer::inst()->print_msg(L0, "Failed to open config file %s.", sFilename); + return false; + } + + fseek(pFile,0,SEEK_END); + flen = ftell(pFile); + rewind(pFile); + + if(flen >= 64*1024) + { + fclose(pFile); + printer::inst()->print_msg(L0, "Oversized config file - %s.", sFilename); + return false; + } + + if(flen <= 16) + { + printer::inst()->print_msg(L0, "File is empty or too short - %s.", sFilename); + return false; + } + + buffer = (char*)malloc(flen + 3); + if(fread(buffer+1, flen, 1, pFile) != 1) + { + free(buffer); + fclose(pFile); + printer::inst()->print_msg(L0, "Read error while reading %s.", sFilename); + return false; + } + fclose(pFile); + + //Replace Unicode BOM with spaces - we always use UTF-8 + unsigned char* ubuffer = (unsigned char*)buffer; + if(ubuffer[1] == 0xEF && ubuffer[2] == 0xBB && ubuffer[3] == 0xBF) + { + buffer[1] = ' '; + buffer[2] = ' '; + buffer[3] = ' '; + } + + buffer[0] = '{'; + buffer[flen] = '}'; + buffer[flen + 1] = '\0'; + + prv->jsonDoc.Parse(buffer, flen+2); + free(buffer); + + if(prv->jsonDoc.HasParseError()) + { + printer::inst()->print_msg(L0, "JSON config parse error(offset %llu): %s", + int_port(prv->jsonDoc.GetErrorOffset()), GetParseError_En(prv->jsonDoc.GetParseError())); + return false; + } + + + if(!prv->jsonDoc.IsObject()) + { //This should never happen as we created the root ourselves + printer::inst()->print_msg(L0, "Invalid config file. No root?\n"); + return false; + } + + for(size_t i = 0; i < iConfigCnt; i++) + { + if(oConfigValues[i].iName != i) + { + printer::inst()->print_msg(L0, "Code error. oConfigValues are not in order."); + return false; + } + + prv->configValues[i] = GetObjectMember(prv->jsonDoc, oConfigValues[i].sName); + + if(prv->configValues[i] == nullptr) + { + printer::inst()->print_msg(L0, "Invalid config file. Missing value \"%s\".", oConfigValues[i].sName); + return false; + } + + if(!checkType(prv->configValues[i]->GetType(), oConfigValues[i].iType)) + { + printer::inst()->print_msg(L0, "Invalid config file. Value \"%s\" has unexpected type.", oConfigValues[i].sName); + return false; + } + } + + size_t n_thd = prv->configValues[aGpuThreadsConf]->Size(); + if(prv->configValues[iGpuThreadNum]->GetUint64() != n_thd) + { + printer::inst()->print_msg(L0, + "Invalid config file. Your GPU config array has %llu members, while you want to use %llu threads.", + int_port(n_thd), int_port(prv->configValues[iGpuThreadNum]->GetUint64())); + return false; + } + + thd_cfg c; + for(size_t i=0; i < n_thd; i++) + { + if(!GetThreadConfig(i, c)) + { + printer::inst()->print_msg(L0, "Thread %llu has invalid config.", int_port(i)); + return false; + } + } + +} + +} // namespace amd +} // namespace xmrstak diff --git a/backend/amd/jconf.h b/backend/amd/jconf.h new file mode 100644 index 0000000..463284a --- /dev/null +++ b/backend/amd/jconf.h @@ -0,0 +1,43 @@ +#pragma once +#include +#include + +namespace xmrstak +{ +namespace amd +{ + +class jconf +{ +public: + static jconf* inst() + { + if (oInst == nullptr) oInst = new jconf; + return oInst; + }; + + bool parse_config(const char* sFilename = "amd.txt"); + + struct thd_cfg { + size_t index; + size_t intensity; + size_t w_size; + long long cpu_aff; + }; + + size_t GetThreadCount(); + bool GetThreadConfig(size_t id, thd_cfg &cfg); + + size_t GetPlatformIdx(); + +private: + jconf(); + static jconf* oInst; + + struct opaque_private; + opaque_private* prv; + +}; + +} // namespace amd +} // namespace xmrstak diff --git a/backend/amd/minethd.cpp b/backend/amd/minethd.cpp new file mode 100644 index 0000000..7e3c603 --- /dev/null +++ b/backend/amd/minethd.cpp @@ -0,0 +1,241 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining + * it with OpenSSL (or a modified version of that library), containing parts + * covered by the terms of OpenSSL License and SSLeay License, the licensors + * of this Program grant you additional permission to convey the resulting work. + * + */ + +#include +#include +#include +#include + +#include "../../ConfigEditor.hpp" +#include "autoAdjust.hpp" + +#include +#include "../../console.h" +#include "../../crypto/cryptonight_aesni.h" +#include "../cpu/minethd.h" +#include "../cpu/jconf.h" + +#include "../../executor.h" +#include "minethd.h" +#include "../../jconf.h" +#include "../../crypto/cryptonight.h" +#include "amd_gpu/gpu.h" + + +namespace xmrstak +{ +namespace amd +{ + +minethd::minethd(miner_work& pWork, size_t iNo, GpuContext* ctx) +{ + oWork = pWork; + bQuit = 0; + iThreadNo = (uint8_t)iNo; + iJobNo = 0; + iHashCount = 0; + iTimestamp = 0; + pGpuCtx = ctx; + + oWorkThd = std::thread(&minethd::work_main, this); +} + +extern "C" std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork) +{ + return amd::minethd::thread_starter(threadOffset, pWork); +} + + +bool minethd::init_gpus() +{ + size_t i, n = jconf::inst()->GetThreadCount(); + + printer::inst()->print_msg(L1, "Compiling code and initializing GPUs. This will take a while..."); + vGpuData.resize(n); + + jconf::thd_cfg cfg; + for(i = 0; i < n; i++) + { + jconf::inst()->GetThreadConfig(i, cfg); + vGpuData[i].deviceIdx = cfg.index; + vGpuData[i].rawIntensity = cfg.intensity; + vGpuData[i].workSize = cfg.w_size; + } + + return InitOpenCL(vGpuData.data(), n, jconf::inst()->GetPlatformIdx()) == ERR_SUCCESS; +} + +std::vector minethd::vGpuData; + +std::vector* minethd::thread_starter(uint32_t threadOffset, miner_work& pWork) +{ + std::vector* pvThreads = new std::vector(); + + if(!ConfigEditor::file_exist("amd.txt")) + { + autoAdjust adjust; + if(!adjust.printConfig()) + return pvThreads; + } +/* + if(!ConfigEditor::file_exist("amd.txt")) + { + printer::inst()->print_msg(L0, "WARNING: missing config file 'amd.txt'"); + return pvThreads; + } +*/ + if(!jconf::inst()->parse_config()) + { + win_exit(); + } + + // \ todo get device count and exit if no opencl device + + if(!init_gpus()) + { + printer::inst()->print_msg(L1, "WARNING: AMD device not found"); + return pvThreads; + } + + size_t i, n = jconf::inst()->GetThreadCount(); + pvThreads->reserve(n); + + jconf::thd_cfg cfg; + for (i = 0; i < n; i++) + { + jconf::inst()->GetThreadConfig(i, cfg); + minethd* thd = new minethd(pWork, i + threadOffset, &vGpuData[i]); + + if(cfg.cpu_aff >= 0) + { +#if defined(__APPLE__) + printer::inst()->print_msg(L1, "WARNING on MacOS thread affinity is only advisory."); +#endif + cpu::minethd::thd_setaffinity(thd->oWorkThd.native_handle(), cfg.cpu_aff); + } + + pvThreads->push_back(thd); + if(cfg.cpu_aff >= 0) + printer::inst()->print_msg(L1, "Starting GPU thread, affinity: %d.", (int)cfg.cpu_aff); + else + printer::inst()->print_msg(L1, "Starting GPU thread, no affinity."); + } + + return pvThreads; +} + +void minethd::switch_work(miner_work& pWork) +{ + // iConsumeCnt is a basic lock-like polling mechanism just in case we happen to push work + // faster than threads can consume them. This should never happen in real life. + // Pool cant physically send jobs faster than every 250ms or so due to net latency. + + while (GlobalStates::iConsumeCnt.load(std::memory_order_seq_cst) < GlobalStates::iThreadCount) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + GlobalStates::oGlobalWork = pWork; + GlobalStates::iConsumeCnt.store(0, std::memory_order_seq_cst); + GlobalStates::iGlobalJobNo++; +} + +void minethd::consume_work() +{ + memcpy(&oWork, &GlobalStates::oGlobalWork, sizeof(miner_work)); + iJobNo++; + GlobalStates::iConsumeCnt++; + +} + +void minethd::work_main() +{ + uint64_t iCount = 0; + + cryptonight_ctx* cpu_ctx; + cpu_ctx = cpu::minethd::minethd_alloc_ctx(); + cn_hash_fun hash_fun = cpu::minethd::func_selector(cpu::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/); + + GlobalStates::iConsumeCnt++; + + while (bQuit == 0) + { + if (oWork.bStall) + { + /* We are stalled here because the executor didn't find a job for us yet, + either because of network latency, or a socket problem. Since we are + raison d'etre of this software it us sensible to just wait until we have something*/ + + while (GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + consume_work(); + continue; + } + + assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); + pGpuCtx->Nonce = calc_start_nonce(oWork.iResumeCnt); + uint32_t target = oWork.iTarget32; + XMRSetJob(pGpuCtx, oWork.bWorkBlob, oWork.iWorkSize, target); + + while(GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + { + cl_uint results[0x100]; + memset(results,0,sizeof(cl_uint)*(0x100)); + + XMRRunJob(pGpuCtx, results); + + for(size_t i = 0; i < results[0xFF]; i++) + { + uint8_t bWorkBlob[112]; + uint8_t bResult[32]; + + memcpy(bWorkBlob, oWork.bWorkBlob, oWork.iWorkSize); + memset(bResult, 0, sizeof(job_result::bResult)); + + *(uint32_t*)(bWorkBlob + 39) = results[i]; + + hash_fun(bWorkBlob, oWork.iWorkSize, bResult, cpu_ctx); + if ( (*((uint64_t*)(bResult + 24))) < oWork.iTarget) + { + std::cout<<"found AMD"<push_event(ex_event(job_result(oWork.sJobID, results[i], bResult), oWork.iPoolId)); + } + else + std::cout<<"wrong AMD"<push_event(ex_event(job_result(oWork.sJobID, results[i], bResult), oWork.iPoolId)); + } + + iCount += pGpuCtx->rawIntensity; + using namespace std::chrono; + uint64_t iStamp = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); + iHashCount.store(iCount, std::memory_order_relaxed); + iTimestamp.store(iStamp, std::memory_order_relaxed); + std::this_thread::yield(); + } + + consume_work(); + } +} + +} // namespace amd +} // namespace xmrstak diff --git a/backend/amd/minethd.h b/backend/amd/minethd.h new file mode 100644 index 0000000..d308110 --- /dev/null +++ b/backend/amd/minethd.h @@ -0,0 +1,60 @@ +#pragma once +#include +#include +#include "./jconf.h" +#include "../IBackend.hpp" + +#include "amd_gpu/gpu.h" + +namespace xmrstak +{ +namespace amd +{ + +class minethd : public IBackend +{ +public: + + static void switch_work(miner_work& pWork); + static std::vector* thread_starter(uint32_t threadOffset, miner_work& pWork); + static bool init_gpus(); + +private: + typedef void (*cn_hash_fun)(const void*, size_t, void*, cryptonight_ctx*); + + minethd(miner_work& pWork, size_t iNo, GpuContext* ctx); + + // We use the top 8 bits of the nonce for thread and resume + // This allows us to resume up to 64 threads 4 times before + // we get nonce collisions + // Bottom 24 bits allow for an hour of work at 4000 H/s + inline uint32_t calc_start_nonce(uint32_t resume) + { + return reverseBits(iThreadNo + GlobalStates::iThreadCount * resume); + } + + void work_main(); + void double_work_main(); + void consume_work(); + + uint64_t iJobNo; + + static miner_work oGlobalWork; + miner_work oWork; + + std::thread oWorkThd; + uint8_t iThreadNo; + + bool bQuit; + bool bNoPrefetch; + + //Mutable ptr to vector below, different for each thread + GpuContext* pGpuCtx; + + // WARNING - this vector (but not its contents) must be immutable + // once the threads are started + static std::vector vGpuData; +}; + +} // namespace amd +} // namespace xmrstak From 18a48e11d26ed1f3c1ed37154a6b3d5873317bd8 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 24 Sep 2017 20:04:19 +0200 Subject: [PATCH 03/42] add cpu backend - move needed files from root to backend folder --- backend/cpu/autoAdjust.hpp | 173 +++++++++++ backend/cpu/autoAdjustHwloc.hpp | 211 +++++++++++++ backend/cpu/config.tpl | 90 ++++++ backend/cpu/jconf.cpp | 347 ++++++++++++++++++++++ backend/cpu/jconf.h | 59 ++++ backend/cpu/minethd.cpp | 506 ++++++++++++++++++++++++++++++++ backend/cpu/minethd.h | 74 +++++ 7 files changed, 1460 insertions(+) create mode 100644 backend/cpu/autoAdjust.hpp create mode 100644 backend/cpu/autoAdjustHwloc.hpp create mode 100644 backend/cpu/config.tpl create mode 100644 backend/cpu/jconf.cpp create mode 100644 backend/cpu/jconf.h create mode 100644 backend/cpu/minethd.cpp create mode 100644 backend/cpu/minethd.h diff --git a/backend/cpu/autoAdjust.hpp b/backend/cpu/autoAdjust.hpp new file mode 100644 index 0000000..67a2142 --- /dev/null +++ b/backend/cpu/autoAdjust.hpp @@ -0,0 +1,173 @@ +#pragma once +#include "jconf.h" +#include "../../console.h" +#include "../../ConfigEditor.hpp" +#include + +#ifdef _WIN32 +#include +#else +#include +#endif // _WIN32 + + +namespace xmrstak +{ +namespace cpu +{ +// Mask bits between h and l and return the value +// This enables us to put in values exactly like in the manual +// For example EBX[31:22] is get_masked(cpu_info[1], 31, 22) +inline int32_t get_masked(int32_t val, int32_t h, int32_t l) +{ + val &= (0x7FFFFFFF >> (31-(h-l))) << l; + return val >> l; +} + +class autoAdjust +{ +public: + + autoAdjust() + { + } + + bool printConfig() + { + + ConfigEditor configTpl{}; + + // load the template of the backend config into a char variable + const char *tpl = + #include "./config.tpl" + ; + configTpl.set( std::string(tpl) ); + + std::string conf; + conf += std::string("\"cpu_threads_conf\" :\n[\n"); + + if(!detectL3Size() || L3KB_size < 1024 || L3KB_size > 102400) + { + if(L3KB_size < 1024 || L3KB_size > 102400) + printer::inst()->print_msg(L0, "Autoconf failed: L3 size sanity check failed - %u KB.", L3KB_size); + + conf += std::string(" { \"low_power_mode\" : false, \"no_prefetch\" : true, \"affine_to_cpu\" : false },\n"); + printer::inst()->print_msg(L0, "Autoconf FAILED. Create config for a single thread. Please try to add new ones until the hashrate slows down."); + } + else + { + printer::inst()->print_msg(L0, "Autoconf L3 size detected at %u KB.", L3KB_size); + + detectCPUConf(); + + printer::inst()->print_msg(L0, "Autoconf core count detected as %u on %s.", corecnt, + linux_layout ? "Linux" : "Windows"); + + uint32_t aff_id = 0; + for(uint32_t i=0; i < corecnt; i++) + { + bool double_mode; + + if(L3KB_size <= 0) + break; + + double_mode = L3KB_size / 2048 > (int32_t)(corecnt-i); + + conf += std::string(" { \"low_power_mode\" : "); + conf += std::string(double_mode ? "true" : "false"); + conf += std::string(", \"no_prefetch\" : true, \"affine_to_cpu\" : "); + conf += std::to_string(aff_id); + conf += std::string(" },\n"); + + if(!linux_layout || old_amd) + { + aff_id += 2; + + if(aff_id >= corecnt) + aff_id = 1; + } + else + aff_id++; + + if(double_mode) + L3KB_size -= 4096; + else + L3KB_size -= 2048; + } + } + + conf += std::string("],\n\n"); + + configTpl.replace("CPUCONFIG",conf); + configTpl.write("cpu.txt"); + printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", "cpu.txt"); + + return true; + } + +private: + bool detectL3Size() + { + int32_t cpu_info[4]; + char cpustr[13] = {0}; + + xmrstak::cpu::jconf::cpuid(0, 0, cpu_info); + memcpy(cpustr, &cpu_info[1], 4); + memcpy(cpustr+4, &cpu_info[3], 4); + memcpy(cpustr+8, &cpu_info[2], 4); + + if(strcmp(cpustr, "GenuineIntel") == 0) + { + xmrstak::cpu::jconf::cpuid(4, 3, cpu_info); + + if(get_masked(cpu_info[0], 7, 5) != 3) + { + printer::inst()->print_msg(L0, "Autoconf failed: Couln't find L3 cache page."); + return false; + } + + L3KB_size = ((get_masked(cpu_info[1], 31, 22) + 1) * (get_masked(cpu_info[1], 21, 12) + 1) * + (get_masked(cpu_info[1], 11, 0) + 1) * (cpu_info[2] + 1)) / 1024; + + return true; + } + else if(strcmp(cpustr, "AuthenticAMD") == 0) + { + xmrstak::cpu::jconf::cpuid(0x80000006, 0, cpu_info); + + L3KB_size = get_masked(cpu_info[3], 31, 18) * 512; + + xmrstak::cpu::jconf::cpuid(1, 0, cpu_info); + if(get_masked(cpu_info[0], 11, 8) < 0x17) //0x17h is Zen + old_amd = true; + + return true; + } + else + { + printer::inst()->print_msg(L0, "Autoconf failed: Unknown CPU type: %s.", cpustr); + return false; + } + } + + void detectCPUConf() + { +#ifdef _WIN32 + SYSTEM_INFO info; + GetSystemInfo(&info); + corecnt = info.dwNumberOfProcessors; + linux_layout = false; +#else + corecnt = sysconf(_SC_NPROCESSORS_ONLN); + linux_layout = true; +#endif // _WIN32 + } + + int32_t L3KB_size = 0; + uint32_t corecnt; + bool old_amd = false; + bool linux_layout; +}; + +} // namespace cpu +} // namepsace xmrstak diff --git a/backend/cpu/autoAdjustHwloc.hpp b/backend/cpu/autoAdjustHwloc.hpp new file mode 100644 index 0000000..968aac7 --- /dev/null +++ b/backend/cpu/autoAdjustHwloc.hpp @@ -0,0 +1,211 @@ +#pragma once + +#include "../../console.h" +#include +#include + +#ifdef _WIN32 +#include +#else +#include +#endif // _WIN32 + +#include +#include "../../ConfigEditor.hpp" + +namespace xmrstak +{ +namespace cpu +{ + +class autoAdjust +{ +public: + + autoAdjust() + { + } + + bool printConfig() + { + + hwloc_topology_t topology; + hwloc_topology_init(&topology); + hwloc_topology_load(topology); + + std::string conf; + ConfigEditor configTpl{}; + + // load the template of the backend config into a char variable + const char *tpl = + #include "./config.tpl" + ; + configTpl.set( std::string(tpl) ); + + conf += std::string("\"cpu_threads_conf\" :\n[\n"); + try + { + std::vector tlcs; + tlcs.reserve(16); + results.reserve(16); + + findChildrenCaches(hwloc_get_root_obj(topology), + [&tlcs](hwloc_obj_t found) { tlcs.emplace_back(found); } ); + + if(tlcs.size() == 0) + throw(std::runtime_error("The CPU doesn't seem to have a cache.")); + + for(hwloc_obj_t obj : tlcs) + proccessTopLevelCache(obj); + + for(uint32_t id : results) + { + conf += std::string(" { \"low_power_mode\" : "); + conf += std::string((id & 0x8000000) != 0 ? "true" : "false"); + conf += std::string(", \"no_prefetch\" : true, \"affine_to_cpu\" : "); + conf += std::to_string(id & 0x7FFFFFF); + conf += std::string(" },\n"); + } + } + catch(const std::runtime_error& err) + { + // \todo add fallback to default auto adjust + conf += std::string(" { \"low_power_mode\" : false, \"no_prefetch\" : true, \"affine_to_cpu\" : false },\n"); + printer::inst()->print_msg(L0, "Autoconf FAILED: %s. Create config for a single thread.", err.what()); + } + conf += std::string("],\n\n"); + + configTpl.replace("CPUCONFIG",conf); + configTpl.write("cpu.txt"); + printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", "cpu.txt"); + /* Destroy topology object. */ + hwloc_topology_destroy(topology); + + return true; + } + +private: + static constexpr size_t hashSize = 2 * 1024 * 1024; + std::vector results; + + template + inline void findChildrenByType(hwloc_obj_t obj, hwloc_obj_type_t type, func lambda) + { + for(size_t i=0; i < obj->arity; i++) + { + if(obj->children[i]->type == type) + lambda(obj->children[i]); + else + findChildrenByType(obj->children[i], type, lambda); + } + } + + inline bool isCacheObject(hwloc_obj_t obj) + { +#if HWLOC_API_VERSION >= 0x20000 + return hwloc_obj_type_is_cache(obj->type); +#else + return obj->type == HWLOC_OBJ_CACHE; +#endif // HWLOC_API_VERSION + } + + template + inline void findChildrenCaches(hwloc_obj_t obj, func lambda) + { + for(size_t i=0; i < obj->arity; i++) + { + if(isCacheObject(obj->children[i])) + lambda(obj->children[i]); + else + findChildrenCaches(obj->children[i], lambda); + } + } + + inline bool isCacheExclusive(hwloc_obj_t obj) + { + const char* value = hwloc_obj_get_info_by_name(obj, "Inclusive"); + return value == nullptr || value[0] != '1'; + } + + // Top level cache isn't shared with other cores on the same package + // This will usually be 1 x L3, but can be 2 x L2 per package + void proccessTopLevelCache(hwloc_obj_t obj) + { + if(obj->attr == nullptr) + throw(std::runtime_error("Cache object hasn't got attributes.")); + + size_t PUs = 0; + findChildrenByType(obj, HWLOC_OBJ_PU, [&PUs](hwloc_obj_t found) { PUs++; } ); + + //Strange case, but we will handle it silently, surely there must be one PU somewhere? + if(PUs == 0) + return; + + if(obj->attr->cache.size == 0) + { + //We will always have one child if PUs > 0 + if(!isCacheObject(obj->children[0])) + throw(std::runtime_error("The CPU doesn't seem to have a cache.")); + + //Try our luck with lower level caches + for(size_t i=0; i < obj->arity; i++) + proccessTopLevelCache(obj->children[i]); + return; + } + + size_t cacheSize = obj->attr->cache.size; + if(isCacheExclusive(obj)) + { + for(size_t i=0; i < obj->arity; i++) + { + hwloc_obj_t l2obj = obj->children[i]; + //If L2 is exclusive and greater or equal to 2MB add room for one more hash + if(isCacheObject(l2obj) && l2obj->attr != nullptr && l2obj->attr->cache.size >= hashSize) + cacheSize += hashSize; + } + } + + std::vector cores; + cores.reserve(16); + findChildrenByType(obj, HWLOC_OBJ_CORE, [&cores](hwloc_obj_t found) { cores.emplace_back(found); } ); + + size_t cacheHashes = (cacheSize + hashSize/2) / hashSize; + + //Firstly allocate PU 0 of every CORE, then PU 1 etc. + size_t pu_id = 0; + while(cacheHashes > 0 && PUs > 0) + { + bool allocated_pu = false; + for(hwloc_obj_t core : cores) + { + if(core->arity <= pu_id || core->children[pu_id]->type != HWLOC_OBJ_PU) + continue; + + size_t os_id = core->children[pu_id]->os_index; + + if(cacheHashes > PUs) + { + cacheHashes -= 2; + os_id |= 0x8000000; //double hash marker bit + } + else + cacheHashes--; + PUs--; + + allocated_pu = true; + results.emplace_back(os_id); + + if(cacheHashes == 0) + break; + } + + if(!allocated_pu) + throw(std::runtime_error("Failed to allocate a PU.")); + + pu_id++; + } + } +}; + +} // namespace cpu +} // namepsace xmrstak diff --git a/backend/cpu/config.tpl b/backend/cpu/config.tpl new file mode 100644 index 0000000..43c1cb8 --- /dev/null +++ b/backend/cpu/config.tpl @@ -0,0 +1,90 @@ +R"===( +/* + * Thread configuration for each thread. Make sure it matches the number above. + * low_power_mode - This mode will double the cache usage, and double the single thread performance. It will + * consume much less power (as less cores are working), but will max out at around 80-85% of + * the maximum performance. + * + * no_prefetch - Some sytems can gain up to extra 5% here, but sometimes it will have no difference or make + * things slower. + * + * affine_to_cpu - This can be either false (no affinity), or the CPU core number. Note that on hyperthreading + * systems it is better to assign threads to physical cores. On Windows this usually means selecting + * even or odd numbered cpu numbers. For Linux it will be usually the lower CPU numbers, so for a 4 + * physical core CPU you should select cpu numbers 0-3. + * + * On the first run the miner will look at your system and suggest a basic configuration that will work, + * you can try to tweak it from there to get the best performance. + * + * A filled out configuration should look like this: + * "cpu_threads_conf" : + * [ + * { "low_power_mode" : false, "no_prefetch" : true, "affine_to_cpu" : 0 }, + * { "low_power_mode" : false, "no_prefetch" : true, "affine_to_cpu" : 1 }, + * ], + */ + +CPUCONFIG + +/* + * LARGE PAGE SUPPORT + * Large pages need a properly set up OS. It can be difficult if you are not used to systems administration, + * but the performance results are worth the trouble - you will get around 20% boost. Slow memory mode is + * meant as a backup, you won't get stellar results there. If you are running into trouble, especially + * on Windows, please read the common issues in the README. + * + * By default we will try to allocate large pages. This means you need to "Run As Administrator" on Windows. + * You need to edit your system's group policies to enable locking large pages. Here are the steps from MSDN + * + * 1. On the Start menu, click Run. In the Open box, type gpedit.msc. + * 2. On the Local Group Policy Editor console, expand Computer Configuration, and then expand Windows Settings. + * 3. Expand Security Settings, and then expand Local Policies. + * 4. Select the User Rights Assignment folder. + * 5. The policies will be displayed in the details pane. + * 6. In the pane, double-click Lock pages in memory. + * 7. In the Local Security Setting – Lock pages in memory dialog box, click Add User or Group. + * 8. In the Select Users, Service Accounts, or Groups dialog box, add an account that you will run the miner on + * 9. Reboot for change to take effect. + * + * Windows also tends to fragment memory a lot. If you are running on a system with 4-8GB of RAM you might need + * to switch off all the auto-start applications and reboot to have a large enough chunk of contiguous memory. + * + * On Linux you will need to configure large page support "sudo sysctl -w vm.nr_hugepages=128" and increase your + * ulimit -l. To do do this you need to add following lines to /etc/security/limits.conf - "* soft memlock 262144" + * and "* hard memlock 262144". You can also do it Windows-style and simply run-as-root, but this is NOT + * recommended for security reasons. + * + * Memory locking means that the kernel can't swap out the page to disk - something that is unlikely to happen on a + * command line system that isn't starved of memory. I haven't observed any difference on a CLI Linux system between + * locked and unlocked memory. If that is your setup see option "no_mlck". + */ + +/* + * use_slow_memory defines our behavior with regards to large pages. There are three possible options here: + * always - Don't even try to use large pages. Always use slow memory. + * warn - We will try to use large pages, but fall back to slow memory if that fails. + * no_mlck - This option is only relevant on Linux, where we can use large pages without locking memory. + * It will never use slow memory, but it won't attempt to mlock + * never - If we fail to allocate large pages we will print an error and exit. + */ +"use_slow_memory" : "warn", + +/* + * NiceHash mode + * nicehash_nonce - Limit the nonce to 3 bytes as required by nicehash. This cuts all the safety margins, and + * if a block isn't found within 30 minutes then you might run into nonce collisions. Number + * of threads in this mode is hard-limited to 32. + */ +"nicehash_nonce" : false, + +/* + * Manual hardware AES override + * + * Some VMs don't report AES capability correctly. You can set this value to true to enforce hardware AES or + * to false to force disable AES or null to let the miner decide if AES is used. + * + * WARNING: setting this to true on a CPU that doesn't support hardware AES will crash the miner. + */ +"aes_override" : null, + +)===" diff --git a/backend/cpu/jconf.cpp b/backend/cpu/jconf.cpp new file mode 100644 index 0000000..e919096 --- /dev/null +++ b/backend/cpu/jconf.cpp @@ -0,0 +1,347 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining + * it with OpenSSL (or a modified version of that library), containing parts + * covered by the terms of OpenSSL License and SSLeay License, the licensors + * of this Program grant you additional permission to convey the resulting work. + * + */ + +#include "jconf.h" +#include "../../console.h" +#include + +#include +#include +#include + +#ifdef _WIN32 +#define strcasecmp _stricmp +#include +#else +#include +#endif + +#include "../../rapidjson/document.h" +#include "../../rapidjson/error/en.h" +#include "../../jext.h" + +namespace xmrstak +{ +namespace cpu +{ + +using namespace rapidjson; + +/* + * This enum needs to match index in oConfigValues, otherwise we will get a runtime error + */ +enum configEnum { aCpuThreadsConf, sUseSlowMem, bNiceHashMode, bAesOverride }; + +struct configVal { + configEnum iName; + const char* sName; + Type iType; +}; + +// Same order as in configEnum, as per comment above +// kNullType means any type +configVal oConfigValues[] = { + { aCpuThreadsConf, "cpu_threads_conf", kNullType }, + { sUseSlowMem, "use_slow_memory", kStringType }, + { bNiceHashMode, "nicehash_nonce", kTrueType }, + { bAesOverride, "aes_override", kNullType } +}; + +constexpr size_t iConfigCnt = (sizeof(oConfigValues)/sizeof(oConfigValues[0])); + +inline bool checkType(Type have, Type want) +{ + if(want == have) + return true; + else if(want == kNullType) + return true; + else if(want == kTrueType && have == kFalseType) + return true; + else if(want == kFalseType && have == kTrueType) + return true; + else + return false; +} + +struct jconf::opaque_private +{ + Document jsonDoc; + const Value* configValues[iConfigCnt]; //Compile time constant + + opaque_private() + { + } +}; + +jconf* jconf::oInst = nullptr; + +jconf::jconf() +{ + prv = new opaque_private(); +} + +bool jconf::GetThreadConfig(size_t id, thd_cfg &cfg) +{ + if(!prv->configValues[aCpuThreadsConf]->IsArray()) + return false; + + if(id >= prv->configValues[aCpuThreadsConf]->Size()) + return false; + + const Value& oThdConf = prv->configValues[aCpuThreadsConf]->GetArray()[id]; + + if(!oThdConf.IsObject()) + return false; + + const Value *mode, *no_prefetch, *aff; + mode = GetObjectMember(oThdConf, "low_power_mode"); + no_prefetch = GetObjectMember(oThdConf, "no_prefetch"); + aff = GetObjectMember(oThdConf, "affine_to_cpu"); + + if(mode == nullptr || no_prefetch == nullptr || aff == nullptr) + return false; + + if(!mode->IsBool() || !no_prefetch->IsBool()) + return false; + + if(!aff->IsNumber() && !aff->IsBool()) + return false; + + if(aff->IsNumber() && aff->GetInt64() < 0) + return false; + + cfg.bDoubleMode = mode->GetBool(); + cfg.bNoPrefetch = no_prefetch->GetBool(); + + if(aff->IsNumber()) + cfg.iCpuAff = aff->GetInt64(); + else + cfg.iCpuAff = -1; + + return true; +} + +jconf::slow_mem_cfg jconf::GetSlowMemSetting() +{ + const char* opt = prv->configValues[sUseSlowMem]->GetString(); + + if(strcasecmp(opt, "always") == 0) + return always_use; + else if(strcasecmp(opt, "no_mlck") == 0) + return no_mlck; + else if(strcasecmp(opt, "warn") == 0) + return print_warning; + else if(strcasecmp(opt, "never") == 0) + return never_use; + else + return unknown_value; +} + +size_t jconf::GetThreadCount() +{ + if(prv->configValues[aCpuThreadsConf]->IsArray()) + return prv->configValues[aCpuThreadsConf]->Size(); + else + return 0; +} + +bool jconf::NeedsAutoconf() +{ + return !prv->configValues[aCpuThreadsConf]->IsArray(); +} + +bool jconf::NiceHashMode() +{ + return prv->configValues[bNiceHashMode]->GetBool(); +} + +void jconf::cpuid(uint32_t eax, int32_t ecx, int32_t val[4]) +{ + memset(val, 0, sizeof(int32_t)*4); + +#ifdef _WIN32 + __cpuidex(val, eax, ecx); +#else + __cpuid_count(eax, ecx, val[0], val[1], val[2], val[3]); +#endif +} + +bool jconf::check_cpu_features() +{ + constexpr int AESNI_BIT = 1 << 25; + constexpr int SSE2_BIT = 1 << 26; + int32_t cpu_info[4]; + bool bHaveSse2; + + cpuid(1, 0, cpu_info); + + bHaveAes = (cpu_info[2] & AESNI_BIT) != 0; + bHaveSse2 = (cpu_info[3] & SSE2_BIT) != 0; + + return bHaveSse2; +} + +bool jconf::parse_config(const char* sFilename) +{ + FILE * pFile; + char * buffer; + size_t flen; + + if(!check_cpu_features()) + { + printer::inst()->print_msg(L0, "CPU support of SSE2 is required."); + return false; + } + + pFile = fopen(sFilename, "rb"); + if (pFile == NULL) + { + printer::inst()->print_msg(L0, "Failed to open config file %s.", sFilename); + return false; + } + + fseek(pFile,0,SEEK_END); + flen = ftell(pFile); + rewind(pFile); + + if(flen >= 64*1024) + { + fclose(pFile); + printer::inst()->print_msg(L0, "Oversized config file - %s.", sFilename); + return false; + } + + if(flen <= 16) + { + fclose(pFile); + printer::inst()->print_msg(L0, "File is empty or too short - %s.", sFilename); + return false; + } + + buffer = (char*)malloc(flen + 3); + if(fread(buffer+1, flen, 1, pFile) != 1) + { + free(buffer); + fclose(pFile); + printer::inst()->print_msg(L0, "Read error while reading %s.", sFilename); + return false; + } + fclose(pFile); + + //Replace Unicode BOM with spaces - we always use UTF-8 + unsigned char* ubuffer = (unsigned char*)buffer; + if(ubuffer[1] == 0xEF && ubuffer[2] == 0xBB && ubuffer[3] == 0xBF) + { + buffer[1] = ' '; + buffer[2] = ' '; + buffer[3] = ' '; + } + + buffer[0] = '{'; + buffer[flen] = '}'; + buffer[flen + 1] = '\0'; + + prv->jsonDoc.Parse(buffer, flen+2); + free(buffer); + + if(prv->jsonDoc.HasParseError()) + { + printer::inst()->print_msg(L0, "JSON config parse error(offset %llu): %s", + int_port(prv->jsonDoc.GetErrorOffset()), GetParseError_En(prv->jsonDoc.GetParseError())); + return false; + } + + if(!prv->jsonDoc.IsObject()) + { //This should never happen as we created the root ourselves + printer::inst()->print_msg(L0, "Invalid config file. No root?\n"); + return false; + } + + for(size_t i = 0; i < iConfigCnt; i++) + { + if(oConfigValues[i].iName != i) + { + printer::inst()->print_msg(L0, "Code error. oConfigValues are not in order."); + return false; + } + + prv->configValues[i] = GetObjectMember(prv->jsonDoc, oConfigValues[i].sName); + + if(prv->configValues[i] == nullptr) + { + printer::inst()->print_msg(L0, "Invalid config file. Missing value \"%s\".", oConfigValues[i].sName); + return false; + } + + if(!checkType(prv->configValues[i]->GetType(), oConfigValues[i].iType)) + { + printer::inst()->print_msg(L0, "Invalid config file. Value \"%s\" has unexpected type.", oConfigValues[i].sName); + return false; + } + } + + thd_cfg c; + for(size_t i=0; i < GetThreadCount(); i++) + { + if(!GetThreadConfig(i, c)) + { + printer::inst()->print_msg(L0, "Thread %llu has invalid config.", int_port(i)); + return false; + } + } + + if(NiceHashMode() && GetThreadCount() >= 32) + { + printer::inst()->print_msg(L0, "You need to use less than 32 threads in NiceHash mode."); + return false; + } + + if(GetSlowMemSetting() == unknown_value) + { + printer::inst()->print_msg(L0, + "Invalid config file. use_slow_memory must be \"always\", \"no_mlck\", \"warn\" or \"never\""); + return false; + } + +#ifdef _WIN32 + if(GetSlowMemSetting() == no_mlck) + { + printer::inst()->print_msg(L0, "On Windows large pages need mlock. Please use another option."); + return false; + } +#endif // _WIN32 + + //if(NeedsAutoconf()) + // return true; + + if(prv->configValues[bAesOverride]->IsBool()) + bHaveAes = prv->configValues[bAesOverride]->GetBool(); + + if(!bHaveAes) + printer::inst()->print_msg(L0, "Your CPU doesn't support hardware AES. Don't expect high hashrates."); + + return true; +} + +} // namespace cpu +} // namepsace xmrstak diff --git a/backend/cpu/jconf.h b/backend/cpu/jconf.h new file mode 100644 index 0000000..39fe6d9 --- /dev/null +++ b/backend/cpu/jconf.h @@ -0,0 +1,59 @@ +#pragma once +#include +#include + +namespace xmrstak +{ +namespace cpu +{ + +class jconf +{ +public: + static jconf* inst() + { + if (oInst == nullptr) oInst = new jconf; + return oInst; + }; + + bool parse_config(const char* sFilename = "cpu.txt"); + + struct thd_cfg { + bool bDoubleMode; + bool bNoPrefetch; + long long iCpuAff; + }; + + enum slow_mem_cfg { + always_use, + no_mlck, + print_warning, + never_use, + unknown_value + }; + + size_t GetThreadCount(); + bool GetThreadConfig(size_t id, thd_cfg &cfg); + bool NeedsAutoconf(); + + slow_mem_cfg GetSlowMemSetting(); + + bool NiceHashMode(); + + inline bool HaveHardwareAes() { return bHaveAes; } + + static void cpuid(uint32_t eax, int32_t ecx, int32_t val[4]); + +private: + jconf(); + static jconf* oInst; + + bool check_cpu_features(); + struct opaque_private; + opaque_private* prv; + + bool bHaveAes; +}; + +} // namespace cpu +} // namepsace xmrstak diff --git a/backend/cpu/minethd.cpp b/backend/cpu/minethd.cpp new file mode 100644 index 0000000..e6d1bd6 --- /dev/null +++ b/backend/cpu/minethd.cpp @@ -0,0 +1,506 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining + * it with OpenSSL (or a modified version of that library), containing parts + * covered by the terms of OpenSSL License and SSLeay License, the licensors + * of this Program grant you additional permission to convey the resulting work. + * + */ + +#include +#include +#include +#include +#include +#include +#include "../../console.h" +#include "../IBackend.hpp" +#include "../GlobalStates.hpp" +#include "../../ConfigEditor.hpp" + +#include "../../executor.h" +#include "minethd.h" +#include "./jconf.h" +#include "../../crypto/cryptonight_aesni.h" +#include "../../hwlocMemory.hpp" +#include "../miner_work.h" + +#ifndef CONF_NO_HWLOC +# include "autoAdjustHwloc.hpp" +#else +# include "autoAdjust.hpp" +#endif + + +#ifdef _WIN32 +#include + +namespace xmrstak +{ +namespace cpu +{ +void minethd::thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id) +{ + SetThreadAffinityMask(h, 1ULL << cpu_id); +} + +} // namespace cpu +} // namespace xmrstak + +#else +#include + +#if defined(__APPLE__) +#include +#include +#define SYSCTL_CORE_COUNT "machdep.cpu.core_count" +#elif defined(__FreeBSD__) +#include +#endif + +namespace xmrstak +{ +namespace cpu +{ + +void minethd::thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id) +{ +#if defined(__APPLE__) + thread_port_t mach_thread; + thread_affinity_policy_data_t policy = { static_cast(cpu_id) }; + mach_thread = pthread_mach_thread_np(h); + thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1); +#elif defined(__FreeBSD__) + cpuset_t mn; + CPU_ZERO(&mn); + CPU_SET(cpu_id, &mn); + pthread_setaffinity_np(h, sizeof(cpuset_t), &mn); +#else + cpu_set_t mn; + CPU_ZERO(&mn); + CPU_SET(cpu_id, &mn); + pthread_setaffinity_np(h, sizeof(cpu_set_t), &mn); +#endif +} + +} // namespace cpu +} // namespace xmrstak + +#endif // _WIN32 + + +namespace xmrstak +{ +namespace cpu +{ + +minethd::minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefetch, int64_t affinity) +{ + oWork = pWork; + bQuit = 0; + iThreadNo = (uint8_t)iNo; + iJobNo = 0; + bNoPrefetch = no_prefetch; + this->affinity = affinity; + + std::lock_guard lock(work_thd_mtx); + if(double_work) + oWorkThd = std::thread(&minethd::double_work_main, this); + else + oWorkThd = std::thread(&minethd::work_main, this); +} + +cryptonight_ctx* minethd::minethd_alloc_ctx() +{ + cryptonight_ctx* ctx; + alloc_msg msg = { 0 }; + + switch (jconf::inst()->GetSlowMemSetting()) + { + case jconf::never_use: + ctx = cryptonight_alloc_ctx(1, 1, &msg); + if (ctx == NULL) + printer::inst()->print_msg(L0, "MEMORY ALLOC FAILED: %s", msg.warning); + return ctx; + + case jconf::no_mlck: + ctx = cryptonight_alloc_ctx(1, 0, &msg); + if (ctx == NULL) + printer::inst()->print_msg(L0, "MEMORY ALLOC FAILED: %s", msg.warning); + return ctx; + + case jconf::print_warning: + ctx = cryptonight_alloc_ctx(1, 1, &msg); + if (msg.warning != NULL) + printer::inst()->print_msg(L0, "MEMORY ALLOC FAILED: %s", msg.warning); + if (ctx == NULL) + ctx = cryptonight_alloc_ctx(0, 0, NULL); + return ctx; + + case jconf::always_use: + return cryptonight_alloc_ctx(0, 0, NULL); + + case jconf::unknown_value: + return NULL; //Shut up compiler + } + + return nullptr; //Should never happen +} + +bool minethd::self_test() +{ + alloc_msg msg = { 0 }; + size_t res; + bool fatal = false; + + switch (jconf::inst()->GetSlowMemSetting()) + { + case jconf::never_use: + res = cryptonight_init(1, 1, &msg); + fatal = true; + break; + + case jconf::no_mlck: + res = cryptonight_init(1, 0, &msg); + fatal = true; + break; + + case jconf::print_warning: + res = cryptonight_init(1, 1, &msg); + break; + + case jconf::always_use: + res = cryptonight_init(0, 0, &msg); + break; + + case jconf::unknown_value: + default: + return false; //Shut up compiler + } + + if(msg.warning != nullptr) + printer::inst()->print_msg(L0, "MEMORY INIT ERROR: %s", msg.warning); + + if(res == 0 && fatal) + return false; + + cryptonight_ctx *ctx0, *ctx1; + if((ctx0 = minethd_alloc_ctx()) == nullptr) + return false; + + if((ctx1 = minethd_alloc_ctx()) == nullptr) + { + cryptonight_free_ctx(ctx0); + return false; + } + + unsigned char out[64]; + bool bResult; + + cn_hash_fun hashf; + cn_hash_fun_dbl hashdf; + + hashf = func_selector(jconf::inst()->HaveHardwareAes(), false); + hashf("This is a test", 14, out, ctx0); + bResult = memcmp(out, "\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 32) == 0; + + hashf = func_selector(jconf::inst()->HaveHardwareAes(), true); + hashf("This is a test", 14, out, ctx0); + bResult &= memcmp(out, "\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 32) == 0; + + hashdf = func_dbl_selector(jconf::inst()->HaveHardwareAes(), false); + hashdf("The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy log", 43, out, ctx0, ctx1); + bResult &= memcmp(out, "\x3e\xbb\x7f\x9f\x7d\x27\x3d\x7c\x31\x8d\x86\x94\x77\x55\x0c\xc8\x00\xcf\xb1\x1b\x0c\xad\xb7\xff\xbd\xf6\xf8\x9f\x3a\x47\x1c\x59" + "\xb4\x77\xd5\x02\xe4\xd8\x48\x7f\x42\xdf\xe3\x8e\xed\x73\x81\x7a\xda\x91\xb7\xe2\x63\xd2\x91\x71\xb6\x5c\x44\x3a\x01\x2a\x41\x22", 64) == 0; + + hashdf = func_dbl_selector(jconf::inst()->HaveHardwareAes(), true); + hashdf("The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy log", 43, out, ctx0, ctx1); + bResult &= memcmp(out, "\x3e\xbb\x7f\x9f\x7d\x27\x3d\x7c\x31\x8d\x86\x94\x77\x55\x0c\xc8\x00\xcf\xb1\x1b\x0c\xad\xb7\xff\xbd\xf6\xf8\x9f\x3a\x47\x1c\x59" + "\xb4\x77\xd5\x02\xe4\xd8\x48\x7f\x42\xdf\xe3\x8e\xed\x73\x81\x7a\xda\x91\xb7\xe2\x63\xd2\x91\x71\xb6\x5c\x44\x3a\x01\x2a\x41\x22", 64) == 0; + + cryptonight_free_ctx(ctx0); + cryptonight_free_ctx(ctx1); + + if(!bResult) + printer::inst()->print_msg(L0, + "Cryptonight hash self-test failed. This might be caused by bad compiler optimizations."); + + return bResult; +} + +std::vector minethd::thread_starter(uint32_t threadOffset, miner_work& pWork) +{ + std::vector pvThreads; + + if(!ConfigEditor::file_exist("cpu.txt")) + { + autoAdjust adjust; + if(!adjust.printConfig()) + return pvThreads; + } + + if(!xmrstak::cpu::jconf::inst()->parse_config("cpu.txt")) + { + win_exit(); + } + + + //Launch the requested number of single and double threads, to distribute + //load evenly we need to alternate single and double threads + size_t i, n = jconf::inst()->GetThreadCount(); + pvThreads.reserve(n); + + jconf::thd_cfg cfg; + for (i = 0; i < n; i++) + { + jconf::inst()->GetThreadConfig(i, cfg); + + // \todo need thread offset + minethd* thd = new minethd(pWork, i + threadOffset, cfg.bDoubleMode, cfg.bNoPrefetch, cfg.iCpuAff); + pvThreads.push_back(thd); + + if(cfg.iCpuAff >= 0) + printer::inst()->print_msg(L1, "Starting %s thread, affinity: %d.", cfg.bDoubleMode ? "double" : "single", (int)cfg.iCpuAff); + else + printer::inst()->print_msg(L1, "Starting %s thread, no affinity.", cfg.bDoubleMode ? "double" : "single"); + } + + return pvThreads; +} + +void minethd::consume_work() +{ + memcpy(&oWork, &GlobalStates::oGlobalWork, sizeof(miner_work)); + iJobNo++; + GlobalStates::iConsumeCnt++; +} + +minethd::cn_hash_fun minethd::func_selector(bool bHaveAes, bool bNoPrefetch) +{ + // We have two independent flag bits in the functions + // therefore we will build a binary digit and select the + // function as a two digit binary + // Digit order SOFT_AES, NO_PREFETCH + + static const cn_hash_fun func_table[4] = { + cryptonight_hash<0x80000, MEMORY, false, false>, + cryptonight_hash<0x80000, MEMORY, false, true>, + cryptonight_hash<0x80000, MEMORY, true, false>, + cryptonight_hash<0x80000, MEMORY, true, true> + }; + + std::bitset<2> digit; + digit.set(0, !bNoPrefetch); + digit.set(1, !bHaveAes); + + return func_table[digit.to_ulong()]; +} + +void minethd::pin_thd_affinity() +{ + //Lock is needed because we need to use oWorkThd + std::lock_guard lock(work_thd_mtx); + + // pin memory to NUMA node + bindMemoryToNUMANode(affinity); + +#if defined(__APPLE__) + printer::inst()->print_msg(L1, "WARNING on MacOS thread affinity is only advisory."); +#endif + thd_setaffinity(oWorkThd.native_handle(), affinity); +} + +void minethd::work_main() +{ + if(affinity >= 0) //-1 means no affinity + pin_thd_affinity(); + + cn_hash_fun hash_fun; + cryptonight_ctx* ctx; + uint64_t iCount = 0; + uint64_t* piHashVal; + uint32_t* piNonce; + job_result result; + + hash_fun = func_selector(jconf::inst()->HaveHardwareAes(), bNoPrefetch); + ctx = minethd_alloc_ctx(); + + piHashVal = (uint64_t*)(result.bResult + 24); + piNonce = (uint32_t*)(oWork.bWorkBlob + 39); + GlobalStates::iConsumeCnt++; + + while (bQuit == 0) + { + if (oWork.bStall) + { + /* We are stalled here because the executor didn't find a job for us yet, + either because of network latency, or a socket problem. Since we are + raison d'etre of this software it us sensible to just wait until we have something*/ + + while (GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + consume_work(); + continue; + } + + if(oWork.bNiceHash) + result.iNonce = calc_nicehash_nonce(*piNonce, oWork.iResumeCnt); + else + result.iNonce = calc_start_nonce(oWork.iResumeCnt); + + assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); + memcpy(result.sJobID, oWork.sJobID, sizeof(job_result::sJobID)); + + while(GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + { + if ((iCount & 0xF) == 0) //Store stats every 16 hashes + { + using namespace std::chrono; + uint64_t iStamp = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); + iHashCount.store(iCount, std::memory_order_relaxed); + iTimestamp.store(iStamp, std::memory_order_relaxed); + } + iCount++; + + *piNonce = ++result.iNonce; + + hash_fun(oWork.bWorkBlob, oWork.iWorkSize, result.bResult, ctx); + + if (*piHashVal < oWork.iTarget) + executor::inst()->push_event(ex_event(result, oWork.iPoolId)); + + std::this_thread::yield(); + } + + consume_work(); + } + + cryptonight_free_ctx(ctx); +} + +minethd::cn_hash_fun_dbl minethd::func_dbl_selector(bool bHaveAes, bool bNoPrefetch) +{ + // We have two independent flag bits in the functions + // therefore we will build a binary digit and select the + // function as a two digit binary + // Digit order SOFT_AES, NO_PREFETCH + + static const cn_hash_fun_dbl func_table[4] = { + cryptonight_double_hash<0x80000, MEMORY, false, false>, + cryptonight_double_hash<0x80000, MEMORY, false, true>, + cryptonight_double_hash<0x80000, MEMORY, true, false>, + cryptonight_double_hash<0x80000, MEMORY, true, true> + }; + + std::bitset<2> digit; + digit.set(0, !bNoPrefetch); + digit.set(1, !bHaveAes); + + return func_table[digit.to_ulong()]; +} + +void minethd::double_work_main() +{ + if(affinity >= 0) //-1 means no affinity + pin_thd_affinity(); + + cn_hash_fun_dbl hash_fun; + cryptonight_ctx* ctx0; + cryptonight_ctx* ctx1; + uint64_t iCount = 0; + uint64_t *piHashVal0, *piHashVal1; + uint32_t *piNonce0, *piNonce1; + uint8_t bDoubleHashOut[64]; + uint8_t bDoubleWorkBlob[sizeof(miner_work::bWorkBlob) * 2]; + uint32_t iNonce; + job_result res; + + hash_fun = func_dbl_selector(jconf::inst()->HaveHardwareAes(), bNoPrefetch); + ctx0 = minethd_alloc_ctx(); + ctx1 = minethd_alloc_ctx(); + + piHashVal0 = (uint64_t*)(bDoubleHashOut + 24); + piHashVal1 = (uint64_t*)(bDoubleHashOut + 32 + 24); + piNonce0 = (uint32_t*)(bDoubleWorkBlob + 39); + piNonce1 = nullptr; + + GlobalStates::iConsumeCnt++; + + while (bQuit == 0) + { + if (oWork.bStall) + { + /* We are stalled here because the executor didn't find a job for us yet, + either because of network latency, or a socket problem. Since we are + raison d'etre of this software it us sensible to just wait until we have something*/ + + while (GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + consume_work(); + memcpy(bDoubleWorkBlob, oWork.bWorkBlob, oWork.iWorkSize); + memcpy(bDoubleWorkBlob + oWork.iWorkSize, oWork.bWorkBlob, oWork.iWorkSize); + piNonce1 = (uint32_t*)(bDoubleWorkBlob + oWork.iWorkSize + 39); + continue; + } + + if(oWork.bNiceHash) + iNonce = calc_nicehash_nonce(*piNonce0, oWork.iResumeCnt); + else + iNonce = calc_start_nonce(oWork.iResumeCnt); + + assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); + + while (GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + { + if ((iCount & 0x7) == 0) //Store stats every 16 hashes + { + using namespace std::chrono; + uint64_t iStamp = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); + iHashCount.store(iCount, std::memory_order_relaxed); + iTimestamp.store(iStamp, std::memory_order_relaxed); + } + + iCount += 2; + + *piNonce0 = ++iNonce; + *piNonce1 = ++iNonce; + + hash_fun(bDoubleWorkBlob, oWork.iWorkSize, bDoubleHashOut, ctx0, ctx1); + + if (*piHashVal0 < oWork.iTarget) + executor::inst()->push_event(ex_event(job_result(oWork.sJobID, iNonce-1, bDoubleHashOut), oWork.iPoolId)); + + if (*piHashVal1 < oWork.iTarget) + executor::inst()->push_event(ex_event(job_result(oWork.sJobID, iNonce, bDoubleHashOut + 32), oWork.iPoolId)); + + std::this_thread::yield(); + } + + consume_work(); + memcpy(bDoubleWorkBlob, oWork.bWorkBlob, oWork.iWorkSize); + memcpy(bDoubleWorkBlob + oWork.iWorkSize, oWork.bWorkBlob, oWork.iWorkSize); + piNonce1 = (uint32_t*)(bDoubleWorkBlob + oWork.iWorkSize + 39); + } + + cryptonight_free_ctx(ctx0); + cryptonight_free_ctx(ctx1); +} + +} // namespace cpu +} // namepsace xmrstak diff --git a/backend/cpu/minethd.h b/backend/cpu/minethd.h new file mode 100644 index 0000000..3997daa --- /dev/null +++ b/backend/cpu/minethd.h @@ -0,0 +1,74 @@ +#pragma once +#include +#include +#include +#include +#include "../../crypto/cryptonight.h" +#include "../miner_work.h" +#include "../IBackend.hpp" +#include "../GlobalStates.hpp" +#include + +namespace xmrstak +{ +namespace cpu +{ + +class minethd : public IBackend +{ +public: + static std::vector thread_starter(uint32_t threadOffset, miner_work& pWork); + static bool self_test(); + + typedef void (*cn_hash_fun)(const void*, size_t, void*, cryptonight_ctx*); + + static cn_hash_fun func_selector(bool bHaveAes, bool bNoPrefetch); + static void thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id); + + static cryptonight_ctx* minethd_alloc_ctx(); + +private: + + typedef void (*cn_hash_fun_dbl)(const void*, size_t, void*, cryptonight_ctx* __restrict, cryptonight_ctx* __restrict); + static cn_hash_fun_dbl func_dbl_selector(bool bHaveAes, bool bNoPrefetch); + + minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefetch, int64_t affinity); + + // We use the top 10 bits of the nonce for thread and resume + // This allows us to resume up to 128 threads 4 times before + // we get nonce collisions + // Bottom 22 bits allow for an hour of work at 1000 H/s + inline uint32_t calc_start_nonce(uint32_t resume) + { + return reverseBits(iThreadNo + GlobalStates::iThreadCount * resume); + } + + // Limited version of the nonce calc above + inline uint32_t calc_nicehash_nonce(uint32_t start, uint32_t resume) + { + return start | ( ( reverseBits(iThreadNo + GlobalStates::iThreadCount * resume) >> 4u ) ); + } + + void work_main(); + void double_work_main(); + void consume_work(); + + uint64_t iJobNo; + + static miner_work oGlobalWork; + miner_work oWork; + + void pin_thd_affinity(); + // Held by the creating context to prevent a race cond with oWorkThd = std::thread(...) + std::mutex work_thd_mtx; + + std::thread oWorkThd; + uint8_t iThreadNo; + int64_t affinity; + + bool bQuit; + bool bNoPrefetch; +}; + +} // namespace cpu +} // namepsace xmrstak From 2cc79914a6fddb3f87a707d85ecc93d1340a2996 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 24 Sep 2017 20:04:51 +0200 Subject: [PATCH 04/42] add generic backend files - add Plugin.h to load a backend - add backend interface --- backend/BackendConnector.cpp | 90 +++++++++++++++++++++++++++++++ backend/BackendConnector.hpp | 18 +++++++ backend/GlobalStates.cpp | 55 +++++++++++++++++++ backend/GlobalStates.hpp | 20 +++++++ backend/IBackend.hpp | 20 +++++++ backend/Plugin.hpp | 90 +++++++++++++++++++++++++++++++ backend/miner_work.h | 102 +++++++++++++++++++++++++++++++++++ 7 files changed, 395 insertions(+) create mode 100644 backend/BackendConnector.cpp create mode 100644 backend/BackendConnector.hpp create mode 100644 backend/GlobalStates.cpp create mode 100644 backend/GlobalStates.hpp create mode 100644 backend/IBackend.hpp create mode 100644 backend/Plugin.hpp create mode 100644 backend/miner_work.h diff --git a/backend/BackendConnector.cpp b/backend/BackendConnector.cpp new file mode 100644 index 0000000..f7a63fe --- /dev/null +++ b/backend/BackendConnector.cpp @@ -0,0 +1,90 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining + * it with OpenSSL (or a modified version of that library), containing parts + * covered by the terms of OpenSSL License and SSLeay License, the licensors + * of this Program grant you additional permission to convey the resulting work. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "IBackend.hpp" +#include "BackendConnector.hpp" + +#include "cpu/minethd.h" +#ifndef CONF_NO_CUDA +# include "nvidia/minethd.h" +#endif +#ifndef CONF_NO_OPENCL +# include "amd/minethd.h" +#endif +#include "miner_work.h" +#include "GlobalStates.hpp" + #include + +#include "Plugin.hpp" + +namespace xmrstak +{ + + +bool BackendConnector::self_test() +{ + + return true; +} + +std::vector* BackendConnector::thread_starter(miner_work& pWork) +{ + GlobalStates::iGlobalJobNo = 0; + GlobalStates::iConsumeCnt = 0; + + + std::vector* pvThreads = new std::vector; + + auto cpuThreads = cpu::minethd::thread_starter(pvThreads->size(), pWork); + pvThreads->insert(std::end(*pvThreads), std::begin(cpuThreads), std::end(cpuThreads)); + if(cpuThreads.size() == 0) + printer::inst()->print_msg(L0, "WARNING: backend CPU disabled."); + +#ifndef CONF_NO_CUDA + Plugin nvidiaPlugin("NVIDIA", "./libxmrstak_cuda_backend"); + std::vector* nvidiaThreads = nvidiaPlugin.startBackend(pvThreads->size(), pWork); + pvThreads->insert(std::end(*pvThreads), std::begin(*nvidiaThreads), std::end(*nvidiaThreads)); + if(nvidiaThreads->size() == 0) + printer::inst()->print_msg(L0, "WARNING: backend NVIDIA disabled."); +#endif + +#ifndef CONF_NO_OPENCL + Plugin amdPlugin("AMD", "./libxmrstak_opencl_backend"); + std::vector* amdThreads = amdPlugin.startBackend(pvThreads->size(), pWork); + pvThreads->insert(std::end(*pvThreads), std::begin(*amdThreads), std::end(*amdThreads)); + if(amdThreads->size() == 0) + printer::inst()->print_msg(L0, "WARNING: backend AMD disabled."); +#endif + + GlobalStates::iThreadCount = pvThreads->size(); + return pvThreads; +} + +} // namepsace xmrstak diff --git a/backend/BackendConnector.hpp b/backend/BackendConnector.hpp new file mode 100644 index 0000000..024d9b1 --- /dev/null +++ b/backend/BackendConnector.hpp @@ -0,0 +1,18 @@ +#pragma once +#include +#include +#include +#include +#include "IBackend.hpp" +#include "miner_work.h" + +namespace xmrstak +{ + + struct BackendConnector + { + static std::vector* thread_starter(miner_work& pWork); + static bool self_test(); + }; + +} // namepsace xmrstak diff --git a/backend/GlobalStates.cpp b/backend/GlobalStates.cpp new file mode 100644 index 0000000..99356b5 --- /dev/null +++ b/backend/GlobalStates.cpp @@ -0,0 +1,55 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining + * it with OpenSSL (or a modified version of that library), containing parts + * covered by the terms of OpenSSL License and SSLeay License, the licensors + * of this Program grant you additional permission to convey the resulting work. + * + */ + +#include +#include +#include +#include + + +#include "miner_work.h" +#include "GlobalStates.hpp" + +namespace xmrstak +{ + +std::atomic GlobalStates::iGlobalJobNo; +std::atomic GlobalStates::iConsumeCnt; //Threads get jobs as they are initialized +miner_work GlobalStates::oGlobalWork; +uint64_t GlobalStates::iThreadCount = 0; + +void GlobalStates::switch_work(miner_work& pWork) +{ + // iConsumeCnt is a basic lock-like polling mechanism just in case we happen to push work + // faster than threads can consume them. This should never happen in real life. + // Pool cant physically send jobs faster than every 250ms or so due to net latency. + + while (iConsumeCnt.load(std::memory_order_seq_cst) < iThreadCount) + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + oGlobalWork = pWork; + iConsumeCnt.store(0, std::memory_order_seq_cst); + iGlobalJobNo++; +} + +} // namepsace xmrstak diff --git a/backend/GlobalStates.hpp b/backend/GlobalStates.hpp new file mode 100644 index 0000000..293009d --- /dev/null +++ b/backend/GlobalStates.hpp @@ -0,0 +1,20 @@ +#pragma once +#include +#include "miner_work.h" + +namespace xmrstak +{ + +struct GlobalStates +{ + + static void switch_work(miner_work& pWork); + + static miner_work oGlobalWork; + static std::atomic iGlobalJobNo; + static std::atomic iConsumeCnt; + static uint64_t iThreadCount; + +}; + +} // namepsace xmrstak diff --git a/backend/IBackend.hpp b/backend/IBackend.hpp new file mode 100644 index 0000000..5037028 --- /dev/null +++ b/backend/IBackend.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + + +namespace xmrstak +{ + + struct IBackend + { + std::atomic iHashCount; + std::atomic iTimestamp; + + IBackend() : iHashCount(0), iTimestamp(0) + { + } + }; + +} // namepsace xmrstak diff --git a/backend/Plugin.hpp b/backend/Plugin.hpp new file mode 100644 index 0000000..762f955 --- /dev/null +++ b/backend/Plugin.hpp @@ -0,0 +1,90 @@ +#pragma once +#include +#include +#include +#include +#include "IBackend.hpp" +#include + +#ifndef USE_PRECOMPILED_HEADERS +#ifdef WIN32 +#include +#include +#else +#include +#include +#endif +#include +#endif + +namespace xmrstak +{ + +struct Plugin +{ + + Plugin(const std::string backendName, const std::string libName) : fn_starterBackend(nullptr), m_backendName(backendName) + { +#ifdef WIN32 + libBackend = LoadLibrary(TEXT((libName + ".dll").c_str())); +#else + libBackend = dlopen((libName + ".so").c_str(), RTLD_LAZY); +#endif + if (!libBackend) + { + std::cerr << "WARNING: "<< m_backendName <<" cannot load backend library: " << dlerror() << std::endl; + return; + } + +#ifdef WIN32 + fn_starterBackend = (func_t*) GetProcAddress(libBackend, "xmrstak_start_backend"); + if (!fn_starterBackend) + { + std::cerr << "WARNING: backend plugin " << libName << " contains no entry 'xmrstak_start_backend'" << std::endl; + } +#else + // reset last error + dlerror(); + fn_starterBackend = (starterBackend_t) dlsym(libBackend, "xmrstak_start_backend"); + const char* dlsym_error = dlerror(); + if (dlsym_error) + { + std::cerr << "WARNING: backend plugin " << libName << " contains no entry 'xmrstak_start_backend'" << std::endl; + } +#endif + } + + std::vector* startBackend(uint32_t threadOffset, miner_work& pWork) + { + if(fn_starterBackend == nullptr) + { + std::vector* pvThreads = new std::vector(); + std::cerr << "WARNING: " << m_backendName << " Backend disabled"<< std::endl; + return pvThreads; + } + + return fn_starterBackend(threadOffset, pWork); + } + + std::string m_backendName; + + typedef std::vector* (*starterBackend_t)(uint32_t threadOffset, miner_work& pWork); + + starterBackend_t fn_starterBackend; + +#ifdef WIN32 + HINSTANCE libBackend; +#else + void *libBackend; +#endif + +/* \todo add unload to destructor and change usage of Plugin that libs keeped open until the miner endss +#ifdef WIN32 + FreeLibrary(libBackend); +#else + dlclose(libBackend); +#endif + * */ +}; + +} // namepsace xmrstak diff --git a/backend/miner_work.h b/backend/miner_work.h new file mode 100644 index 0000000..b922f4a --- /dev/null +++ b/backend/miner_work.h @@ -0,0 +1,102 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +namespace xmrstak +{ + // only allowed for unsigned value \todo add static assert + template + T reverseBits(T value) + { + /* init with value (to get LSB) */ + T result = value; + /* extra shift needed at end */ + int s = sizeof(T) * CHAR_BIT - 1; + for (value >>= 1; value; value >>= 1) + { + result <<= 1; + result |= value & 1; + s--; + } + /* shift when values highest bits are zero */ + result <<= s; + return result; + } + + struct miner_work + { + char sJobID[64]; + uint8_t bWorkBlob[112]; + uint32_t iWorkSize; + uint32_t iResumeCnt; + uint64_t iTarget; + // \todo remove workaround needed for amd + uint32_t iTarget32; + bool bNiceHash; + bool bStall; + size_t iPoolId; + + miner_work() : iWorkSize(0), bNiceHash(false), bStall(true), iPoolId(0) { } + + miner_work(const char* sJobID, const uint8_t* bWork, uint32_t iWorkSize, uint32_t iResumeCnt, + uint64_t iTarget, size_t iPoolId) : iWorkSize(iWorkSize), iResumeCnt(iResumeCnt), + iTarget(iTarget), bNiceHash(false), bStall(false), iPoolId(iPoolId) + { + assert(iWorkSize <= sizeof(bWorkBlob)); + memcpy(this->sJobID, sJobID, sizeof(miner_work::sJobID)); + memcpy(this->bWorkBlob, bWork, iWorkSize); + } + + miner_work(miner_work const&) = delete; + + miner_work& operator=(miner_work const& from) + { + assert(this != &from); + + iWorkSize = from.iWorkSize; + iResumeCnt = from.iResumeCnt; + iTarget = from.iTarget; + iTarget32 = from.iTarget32; + bNiceHash = from.bNiceHash; + bStall = from.bStall; + iPoolId = from.iPoolId; + + assert(iWorkSize <= sizeof(bWorkBlob)); + memcpy(sJobID, from.sJobID, sizeof(sJobID)); + memcpy(bWorkBlob, from.bWorkBlob, iWorkSize); + + return *this; + } + + miner_work(miner_work&& from) : iWorkSize(from.iWorkSize), iTarget(from.iTarget),iTarget32(from.iTarget32), + bStall(from.bStall), iPoolId(from.iPoolId) + { + assert(iWorkSize <= sizeof(bWorkBlob)); + memcpy(sJobID, from.sJobID, sizeof(sJobID)); + memcpy(bWorkBlob, from.bWorkBlob, iWorkSize); + } + + miner_work& operator=(miner_work&& from) + { + assert(this != &from); + + iWorkSize = from.iWorkSize; + iResumeCnt = from.iResumeCnt; + iTarget = from.iTarget; + iTarget32 = from.iTarget32; + bNiceHash = from.bNiceHash; + bStall = from.bStall; + iPoolId = from.iPoolId; + + assert(iWorkSize <= sizeof(bWorkBlob)); + memcpy(sJobID, from.sJobID, sizeof(sJobID)); + memcpy(bWorkBlob, from.bWorkBlob, iWorkSize); + + return *this; + } + }; +} // namepsace xmrstak From 652b79f6845dc8ec823ebe56ba11d39bd861734c Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 24 Sep 2017 20:07:07 +0200 Subject: [PATCH 05/42] update CMake --- CMakeLists.txt | 161 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac01604..f88a2a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,128 @@ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${BUILD_TYPE}") # option to add static libgcc and libstdc++ option(CMAKE_LINK_STATIC "link as much as possible libraries static" OFF) +################################################################################ +# Find CUDA +################################################################################ +#option(CUDA_USE_STATIC_CUDA_RUNTIME "Use the static version of the CUDA runtime library if available" OFF) +#set(CUDA_USE_STATIC_CUDA_RUNTIME OFF CACHE BOOL "Use the static version of the CUDA runtime library if available" FORCE) + +find_package(CUDA 7.5 QUIET) + +if(CUDA_FOUND) + + option(XMR-STAK_LARGEGRID "Support large CUDA block count > 128" ON) + if(XMR-STAK_LARGEGRID) + add_definitions("-DXMR_STAK_LARGEGRID=${XMR-STAK_LARGEGRID}") + endif() + + set(DEVICE_COMPILER "nvcc") + set(CUDA_COMPILER "${DEVICE_COMPILER}" CACHE STRING "Select the device compiler") + + if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + list(APPEND DEVICE_COMPILER "clang") + endif() + + set_property(CACHE CUDA_COMPILER PROPERTY STRINGS "${DEVICE_COMPILER}") + + set(XMR-STAK_THREADS 0 CACHE STRING "Set maximum number of threads (for compile time optimization)") + if(NOT XMR-STAK_THREADS EQUAL 0) + message(STATUS "xmr-stak-nvidia: set max threads per block to ${XMR-STAK_THREADS}") + add_definitions("-DXMR_STAK_THREADS=${XMR-STAK_THREADS}") + endif() + + set(CUDA_ARCH "20;30;35;37;50;52;60;61;62" CACHE STRING "Set GPU architecture (semicolon separated list, e.g. '-DCUDA_ARCH=20;35;60')") + + # validate architectures (only numbers are allowed) + foreach(CUDA_ARCH_ELEM ${CUDA_ARCH}) + string(REGEX MATCH "^[0-9]+$" IS_NUMBER ${CUDA_ARCH}) + if(NOT IS_NUMBER) + message(FATAL_ERROR "Defined compute architecture '${CUDA_ARCH_ELEM}' in " + "'${CUDA_ARCH}' is not an integral number, use e.g. '30' (for compute architecture 3.0).") + endif() + unset(IS_NUMBER) + + if(${CUDA_ARCH_ELEM} LESS 20) + message(FATAL_ERROR "Unsupported CUDA architecture '${CUDA_ARCH_ELEM}' specified. " + "Use '20' (for compute architecture 2.0) or higher.") + endif() + endforeach() + + option(CUDA_SHOW_REGISTER "Show registers used for each kernel and compute architecture" OFF) + option(CUDA_KEEP_FILES "Keep all intermediate files that are generated during internal compilation steps" OFF) + + if("${CUDA_COMPILER}" STREQUAL "clang") + set(CLANG_BUILD_FLAGS "-O3 -x cuda --cuda-path=${CUDA_TOOLKIT_ROOT_DIR}") + # activation usage of FMA + set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} -ffp-contract=fast") + + if(CUDA_SHOW_REGISTER) + set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} -Xcuda-ptxas -v") + endif(CUDA_SHOW_REGISTER) + + if(CUDA_KEEP_FILES) + set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} -save-temps=${PROJECT_BINARY_DIR}") + endif(CUDA_KEEP_FILES) + + foreach(CUDA_ARCH_ELEM ${CUDA_ARCH}) + # set flags to create device code for the given architectures + set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} --cuda-gpu-arch=sm_${CUDA_ARCH_ELEM}") + endforeach() + + elseif("${CUDA_COMPILER}" STREQUAL "nvcc") + # avoid that nvcc in CUDA < 8 tries to use libc `memcpy` within the kernel + if(CUDA_VERSION VERSION_LESS 8.0) + add_definitions(-D_FORCE_INLINES) + endif() + foreach(CUDA_ARCH_ELEM ${CUDA_ARCH}) + # set flags to create device code for the given architecture + set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} + "--generate-code arch=compute_${CUDA_ARCH_ELEM},code=sm_${CUDA_ARCH_ELEM} --generate-code arch=compute_${CUDA_ARCH_ELEM},code=compute_${CUDA_ARCH_ELEM}") + endforeach() + + # give each thread an independent default stream + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --default-stream per-thread") + + option(CUDA_SHOW_CODELINES "Show kernel lines in cuda-gdb and cuda-memcheck" OFF) + + if(CUDA_SHOW_CODELINES) + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" --source-in-ptx -lineinfo) + set(CUDA_KEEP_FILES ON CACHE BOOL "activate keep files" FORCE) + endif(CUDA_SHOW_CODELINES) + + if(CUDA_SHOW_REGISTER) + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" -Xptxas=-v) + endif(CUDA_SHOW_REGISTER) + + if(CUDA_KEEP_FILES) + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" --keep --keep-dir "${PROJECT_BINARY_DIR}") + endif(CUDA_KEEP_FILES) + + else() + message(FATAL_ERROR "selected CUDA compiler '${CUDA_COMPILER}' is not supported") + endif() +else() + add_definitions("-DCONF_NO_CUDA") +endif() + +# help to find AMD app SDK on systems with a software module system +list(APPEND CMAKE_PREFIX_PATH "$ENV{AMDAPPSDKROOT}") +# allow user to extent CMAKE_PREFIX_PATH via environment variable +list(APPEND CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}") + +############################################################################### +# Find OpenCL +############################################################################### + +find_package(OpenCL) +include_directories(SYSTEM ${OpenCL_INCLUDE_DIRS}) +#set(LIBS ${LIBS} ${OpenCL_LIBRARY}) +link_directories(${OpenCL_LIBRARY}) + +if(NOT OpenCL_FOUND) + add_definitions("-DCONF_NO_OPENCL") +endif() + ################################################################################ # Find PThreads ################################################################################ @@ -111,7 +233,7 @@ if(HWLOC_ENABLE) /usr/local /usr ENV "PROGRAMFILES(X86)" - ENV "HWLOC_ROOT" + ENV "MICROHTTPD_ROOT" PATH_SUFFIXES include) @@ -160,7 +282,28 @@ if(CMAKE_LINK_STATIC) set(LIBS "-static-libgcc -static-libstdc++ ${LIBS}") endif() -file(GLOB SRCFILES_CPP "*.cpp" "crypto/*.cpp") +if(CUDA_FOUND) + file(GLOB CUDASRCFILES "backend/nvidia/nvcc_code/*.cu" "backend/nvidia/*.cpp") + + # build device code with nvcc + cuda_add_library(xmrstak_cuda_backend + SHARED + ${CUDASRCFILES} + ) + target_link_libraries(xmrstak_cuda_backend ${CUDA_LIBRARIES}) +endif() + +if(OpenCL_FOUND) + file(GLOB OPENCLSRCFILES_C "backend/amd/amd_gpu/*.cpp" "console.cpp" "backend/amd/*.cpp") + add_library(xmrstak_opencl_backend + SHARED + ${OPENCLSRCFILES_C} + ) + #set_property(TARGET xmrstak_opencl_backend PROPERTY C_STANDARD 99) + target_link_libraries(xmrstak_opencl_backend PUBLIC ${OpenCL_LIBRARY}) +endif() + +file(GLOB SRCFILES_CPP "*.cpp" "crypto/*.cpp" "backend/cpu/*.cpp" "backend/*.cpp") file(GLOB SRCFILES_C "crypto/*.c") add_library(xmr-stak-c @@ -175,7 +318,9 @@ add_executable(xmr-stak-cpu ) set(EXECUTABLE_OUTPUT_PATH "bin") -target_link_libraries(xmr-stak-cpu ${LIBS} xmr-stak-c) +set(LIBRARY_OUTPUT_PATH "bin") + +target_link_libraries(xmr-stak-cpu ${LIBS} xmr-stak-c ${CMAKE_DL_LIBS}) ################################################################################ # Install @@ -185,8 +330,18 @@ target_link_libraries(xmr-stak-cpu ${LIBS} xmr-stak-c) if( NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "${PROJECT_BINARY_DIR}" ) install(TARGETS xmr-stak-cpu RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") + if(CUDA_FOUND) + install(TARGETS xmrstak_cuda_backend + LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") + endif() + if(OpenCL_FOUND) + install(TARGETS xmrstak_opencl_backend + LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") + endif() endif() +install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/opencl" + DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") # avoid overwrite of user defined settings # install `config.txt`if file not exists in `${CMAKE_INSTALL_PREFIX}/bin` From 7d88cf456b70268336970ff584ea0c22deac8bfa Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 24 Sep 2017 20:07:34 +0200 Subject: [PATCH 06/42] update rot files - add config file editor - move telemetry out of minethd --- ConfigEditor.hpp | 57 +++++ autoAdjust.hpp | 154 ------------ autoAdjustHwloc.hpp | 195 ---------------- cli-miner.cpp | 50 ++-- config.txt | 280 ++++++++-------------- console.cpp | 16 ++ console.h | 2 + executor.cpp | 47 ++-- executor.h | 16 +- jconf.cpp | 145 +----------- jconf.h | 11 - jpsock.cpp | 3 + minethd.cpp | 555 -------------------------------------------- minethd.h | 144 ------------ msgstruct.h | 3 + telemetry.cpp | 107 +++++++++ telemetry.h | 23 ++ version.h | 4 +- webdesign.cpp | 2 +- 19 files changed, 374 insertions(+), 1440 deletions(-) create mode 100644 ConfigEditor.hpp delete mode 100644 autoAdjust.hpp delete mode 100644 autoAdjustHwloc.hpp delete mode 100644 minethd.cpp delete mode 100644 minethd.h create mode 100644 telemetry.cpp create mode 100644 telemetry.h diff --git a/ConfigEditor.hpp b/ConfigEditor.hpp new file mode 100644 index 0000000..80607ff --- /dev/null +++ b/ConfigEditor.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include +#include +#include +#include +#include + + +namespace xmrstak +{ + +struct ConfigEditor +{ + std::string m_fileContent; + + ConfigEditor() + { + + } + + static bool file_exist( const std::string filename) + { + std::ifstream fstream(filename); + return fstream.good(); + } + + void set( const std::string && content) + { + m_fileContent = content; + } + + bool load(const std::string filename) + { + std::ifstream fstream(filename); + m_fileContent = std::string( + (std::istreambuf_iterator(fstream)), + std::istreambuf_iterator() + ); + return fstream.good(); + } + + void write(const std::string filename) + { + std::ofstream out(filename); + out << m_fileContent; + out.close(); + } + + void replace(const std::string search, const std::string substring) + { + m_fileContent = std::regex_replace(m_fileContent, std::regex(search), substring); + } + +}; + +} // namepsace xmrstak diff --git a/autoAdjust.hpp b/autoAdjust.hpp deleted file mode 100644 index 93a88e8..0000000 --- a/autoAdjust.hpp +++ /dev/null @@ -1,154 +0,0 @@ -#pragma once -#include "jconf.h" -#include "console.h" - -#ifdef _WIN32 -#include -#else -#include -#endif // _WIN32 - -// Mask bits between h and l and return the value -// This enables us to put in values exactly like in the manual -// For example EBX[31:22] is get_masked(cpu_info[1], 31, 22) -inline int32_t get_masked(int32_t val, int32_t h, int32_t l) -{ - val &= (0x7FFFFFFF >> (31-(h-l))) << l; - return val >> l; -} - -class autoAdjust -{ -public: - - autoAdjust() - { - } - - void printConfig() - { - printer::inst()->print_str("The configuration for 'cpu_threads_conf' in your config file is 'null'.\n"); - printer::inst()->print_str("The miner evaluates your system and prints a suggestion for the section `cpu_threads_conf` to the terminal.\n"); - printer::inst()->print_str("The values are not optimal, please try to tweak the values based on notes in config.txt.\n"); - printer::inst()->print_str("Please copy & paste the block within the asterisks to your config.\n\n"); - - if(!detectL3Size() || L3KB_size < 1024 || L3KB_size > 102400) - { - if(L3KB_size < 1024 || L3KB_size > 102400) - printer::inst()->print_msg(L0, "Autoconf failed: L3 size sanity check failed - %u KB.", L3KB_size); - - printer::inst()->print_msg(L0, "Autoconf failed: Printing config for a single thread. Please try to add new ones until the hashrate slows down."); - printer::inst()->print_str("\n**************** Copy&Paste BEGIN ****************\n\n"); - printer::inst()->print_str("\"cpu_threads_conf\" :\n[\n"); - printer::inst()->print_str(" { \"low_power_mode\" : false, \"no_prefetch\" : true, \"affine_to_cpu\" : false },\n"); - printer::inst()->print_str("],\n\n**************** Copy&Paste END ****************\n"); - return; - } - - printer::inst()->print_msg(L0, "Autoconf L3 size detected at %u KB.", L3KB_size); - - detectCPUConf(); - - printer::inst()->print_msg(L0, "Autoconf core count detected as %u on %s.", corecnt, - linux_layout ? "Linux" : "Windows"); - - printer::inst()->print_str("\n**************** Copy&Paste BEGIN ****************\n\n"); - printer::inst()->print_str("\"cpu_threads_conf\" :\n[\n"); - - uint32_t aff_id = 0; - char strbuf[256]; - for(uint32_t i=0; i < corecnt; i++) - { - bool double_mode; - - if(L3KB_size <= 0) - break; - - double_mode = L3KB_size / 2048 > (int32_t)(corecnt-i); - - snprintf(strbuf, sizeof(strbuf), " { \"low_power_mode\" : %s, \"no_prefetch\" : true, \"affine_to_cpu\" : %u },\n", - double_mode ? "true" : "false", aff_id); - printer::inst()->print_str(strbuf); - - if(!linux_layout || old_amd) - { - aff_id += 2; - - if(aff_id >= corecnt) - aff_id = 1; - } - else - aff_id++; - - if(double_mode) - L3KB_size -= 4096; - else - L3KB_size -= 2048; - } - - printer::inst()->print_str("],\n\n**************** Copy&Paste END ****************\n"); - } - -private: - bool detectL3Size() - { - int32_t cpu_info[4]; - char cpustr[13] = {0}; - - jconf::cpuid(0, 0, cpu_info); - memcpy(cpustr, &cpu_info[1], 4); - memcpy(cpustr+4, &cpu_info[3], 4); - memcpy(cpustr+8, &cpu_info[2], 4); - - if(strcmp(cpustr, "GenuineIntel") == 0) - { - jconf::cpuid(4, 3, cpu_info); - - if(get_masked(cpu_info[0], 7, 5) != 3) - { - printer::inst()->print_msg(L0, "Autoconf failed: Couln't find L3 cache page."); - return false; - } - - L3KB_size = ((get_masked(cpu_info[1], 31, 22) + 1) * (get_masked(cpu_info[1], 21, 12) + 1) * - (get_masked(cpu_info[1], 11, 0) + 1) * (cpu_info[2] + 1)) / 1024; - - return true; - } - else if(strcmp(cpustr, "AuthenticAMD") == 0) - { - jconf::cpuid(0x80000006, 0, cpu_info); - - L3KB_size = get_masked(cpu_info[3], 31, 18) * 512; - - jconf::cpuid(1, 0, cpu_info); - if(get_masked(cpu_info[0], 11, 8) < 0x17) //0x17h is Zen - old_amd = true; - - return true; - } - else - { - printer::inst()->print_msg(L0, "Autoconf failed: Unknown CPU type: %s.", cpustr); - return false; - } - } - - void detectCPUConf() - { -#ifdef _WIN32 - SYSTEM_INFO info; - GetSystemInfo(&info); - corecnt = info.dwNumberOfProcessors; - linux_layout = false; -#else - corecnt = sysconf(_SC_NPROCESSORS_ONLN); - linux_layout = true; -#endif // _WIN32 - } - - int32_t L3KB_size = 0; - uint32_t corecnt; - bool old_amd = false; - bool linux_layout; -}; diff --git a/autoAdjustHwloc.hpp b/autoAdjustHwloc.hpp deleted file mode 100644 index 92a668a..0000000 --- a/autoAdjustHwloc.hpp +++ /dev/null @@ -1,195 +0,0 @@ -#pragma once - -#include "console.h" -#include -#include - -#ifdef _WIN32 -#include -#else -#include -#endif // _WIN32 - -class autoAdjust -{ -public: - - autoAdjust() - { - } - - void printConfig() - { - printer::inst()->print_str("The configuration for 'cpu_threads_conf' in your config file is 'null'.\n"); - printer::inst()->print_str("The miner evaluates your system and prints a suggestion for the section `cpu_threads_conf` to the terminal.\n"); - printer::inst()->print_str("The values are not optimal, please try to tweak the values based on notes in config.txt.\n"); - printer::inst()->print_str("Please copy & paste the block within the asterisks to your config.\n\n"); - - hwloc_topology_t topology; - hwloc_topology_init(&topology); - hwloc_topology_load(topology); - - try - { - std::vector tlcs; - tlcs.reserve(16); - results.reserve(16); - - findChildrenCaches(hwloc_get_root_obj(topology), - [&tlcs](hwloc_obj_t found) { tlcs.emplace_back(found); } ); - - if(tlcs.size() == 0) - throw(std::runtime_error("The CPU doesn't seem to have a cache.")); - - for(hwloc_obj_t obj : tlcs) - proccessTopLevelCache(obj); - - printer::inst()->print_str("\n**************** Copy&Paste BEGIN ****************\n\n"); - printer::inst()->print_str("\"cpu_threads_conf\" :\n[\n"); - - for(uint32_t id : results) - { - char str[128]; - snprintf(str, sizeof(str), " { \"low_power_mode\" : %s, \"no_prefetch\" : true, \"affine_to_cpu\" : %u },\n", - (id & 0x8000000) != 0 ? "true" : "false", id & 0x7FFFFFF); - printer::inst()->print_str(str); - } - - printer::inst()->print_str("],\n\n**************** Copy&Paste END ****************\n"); - } - catch(const std::runtime_error& err) - { - printer::inst()->print_msg(L0, "Autoconf FAILED: %s", err.what()); - printer::inst()->print_str("\nPrinting config for a single thread. Please try to add new ones until the hashrate slows down.\n"); - printer::inst()->print_str("\n**************** FAILURE Copy&Paste BEGIN ****************\n\n"); - printer::inst()->print_str("\"cpu_threads_conf\" :\n[\n"); - printer::inst()->print_str(" { \"low_power_mode\" : false, \"no_prefetch\" : true, \"affine_to_cpu\" : false },\n"); - printer::inst()->print_str("],\n\n**************** FAILURE Copy&Paste END ****************\n"); - } - - /* Destroy topology object. */ - hwloc_topology_destroy(topology); - } - -private: - static constexpr size_t hashSize = 2 * 1024 * 1024; - std::vector results; - - template - inline void findChildrenByType(hwloc_obj_t obj, hwloc_obj_type_t type, func lambda) - { - for(size_t i=0; i < obj->arity; i++) - { - if(obj->children[i]->type == type) - lambda(obj->children[i]); - else - findChildrenByType(obj->children[i], type, lambda); - } - } - - inline bool isCacheObject(hwloc_obj_t obj) - { -#if HWLOC_API_VERSION >= 0x20000 - return hwloc_obj_type_is_cache(obj->type); -#else - return obj->type == HWLOC_OBJ_CACHE; -#endif // HWLOC_API_VERSION - } - - template - inline void findChildrenCaches(hwloc_obj_t obj, func lambda) - { - for(size_t i=0; i < obj->arity; i++) - { - if(isCacheObject(obj->children[i])) - lambda(obj->children[i]); - else - findChildrenCaches(obj->children[i], lambda); - } - } - - inline bool isCacheExclusive(hwloc_obj_t obj) - { - const char* value = hwloc_obj_get_info_by_name(obj, "Inclusive"); - return value == nullptr || value[0] != '1'; - } - - // Top level cache isn't shared with other cores on the same package - // This will usually be 1 x L3, but can be 2 x L2 per package - void proccessTopLevelCache(hwloc_obj_t obj) - { - if(obj->attr == nullptr) - throw(std::runtime_error("Cache object hasn't got attributes.")); - - size_t PUs = 0; - findChildrenByType(obj, HWLOC_OBJ_PU, [&PUs](hwloc_obj_t found) { PUs++; } ); - - //Strange case, but we will handle it silently, surely there must be one PU somewhere? - if(PUs == 0) - return; - - if(obj->attr->cache.size == 0) - { - //We will always have one child if PUs > 0 - if(!isCacheObject(obj->children[0])) - throw(std::runtime_error("The CPU doesn't seem to have a cache.")); - - //Try our luck with lower level caches - for(size_t i=0; i < obj->arity; i++) - proccessTopLevelCache(obj->children[i]); - return; - } - - size_t cacheSize = obj->attr->cache.size; - if(isCacheExclusive(obj)) - { - for(size_t i=0; i < obj->arity; i++) - { - hwloc_obj_t l2obj = obj->children[i]; - //If L2 is exclusive and greater or equal to 2MB add room for one more hash - if(isCacheObject(l2obj) && l2obj->attr != nullptr && l2obj->attr->cache.size >= hashSize) - cacheSize += hashSize; - } - } - - std::vector cores; - cores.reserve(16); - findChildrenByType(obj, HWLOC_OBJ_CORE, [&cores](hwloc_obj_t found) { cores.emplace_back(found); } ); - - size_t cacheHashes = (cacheSize + hashSize/2) / hashSize; - - //Firstly allocate PU 0 of every CORE, then PU 1 etc. - size_t pu_id = 0; - while(cacheHashes > 0 && PUs > 0) - { - bool allocated_pu = false; - for(hwloc_obj_t core : cores) - { - if(core->arity <= pu_id || core->children[pu_id]->type != HWLOC_OBJ_PU) - continue; - - size_t os_id = core->children[pu_id]->os_index; - - if(cacheHashes > PUs) - { - cacheHashes -= 2; - os_id |= 0x8000000; //double hash marker bit - } - else - cacheHashes--; - PUs--; - - allocated_pu = true; - results.emplace_back(os_id); - - if(cacheHashes == 0) - break; - } - - if(!allocated_pu) - throw(std::runtime_error("Failed to allocate a PU.")); - - pu_id++; - } - } -}; diff --git a/cli-miner.cpp b/cli-miner.cpp index 45d2c16..d7d2781 100644 --- a/cli-miner.cpp +++ b/cli-miner.cpp @@ -22,15 +22,13 @@ */ #include "executor.h" -#include "minethd.h" +#include "backend/miner_work.h" +#include "backend/GlobalStates.hpp" +#include "backend/BackendConnector.hpp" #include "jconf.h" #include "console.h" #include "donate-level.h" -#ifndef CONF_NO_HWLOC -# include "autoAdjustHwloc.hpp" -#else -# include "autoAdjust.hpp" -#endif + #include "version.h" #ifndef CONF_NO_HTTPD @@ -48,19 +46,9 @@ #include #endif -//Do a press any key for the windows folk. *insert any key joke here* + #ifdef _WIN32 -void win_exit() -{ - printer::inst()->print_str("Press any key to exit."); - get_key(); - return; -} - -#define strcasecmp _stricmp - -#else -void win_exit() { return; } +# define strcasecmp _stricmp #endif // _WIN32 void do_benchmark(); @@ -109,15 +97,7 @@ int main(int argc, char *argv[]) return 0; } - if(jconf::inst()->NeedsAutoconf()) - { - autoAdjust adjust; - adjust.printConfig(); - win_exit(); - return 0; - } - - if (!minethd::self_test()) + if (!xmrstak::BackendConnector::self_test()) { win_exit(); return 0; @@ -144,6 +124,12 @@ int main(int argc, char *argv[]) printer::inst()->print_str("-------------------------------------------------------------------\n"); printer::inst()->print_str( XMR_STAK_NAME" " XMR_STAK_VERSION " mining software, CPU Version.\n"); printer::inst()->print_str("Based on CPU mining code by wolf9466 (heavily optimized by fireice_uk).\n"); +#ifndef CONF_NO_CUDA + printer::inst()->print_str("NVIDIA mining code was written by KlausT and psychocrypt.\n"); +#endif +#ifndef CONF_NO_OPENCL + printer::inst()->print_str("AMD mining code was written by wolf9466.\n"); +#endif printer::inst()->print_str("Brought to you by fireice_uk and psychocrypt under GPLv3.\n\n"); char buffer[64]; snprintf(buffer, sizeof(buffer), "Configurable dev donation level is set to %.1f %%\n\n", fDevDonationLevel * 100.0); @@ -196,20 +182,20 @@ int main(int argc, char *argv[]) void do_benchmark() { using namespace std::chrono; - std::vector* pvThreads; + std::vector* pvThreads; printer::inst()->print_msg(L0, "Running a 60 second benchmark..."); uint8_t work[76] = {0}; - minethd::miner_work oWork = minethd::miner_work("", work, sizeof(work), 0, 0, false, 0); - pvThreads = minethd::thread_starter(oWork); + xmrstak::miner_work oWork = xmrstak::miner_work("", work, sizeof(work), 0, 0, 0); + pvThreads = xmrstak::BackendConnector::thread_starter(oWork); uint64_t iStartStamp = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); std::this_thread::sleep_for(std::chrono::seconds(60)); - oWork = minethd::miner_work(); - minethd::switch_work(oWork); + oWork = xmrstak::miner_work(); + xmrstak::GlobalStates::switch_work(oWork); double fTotalHps = 0.0; for (uint32_t i = 0; i < pvThreads->size(); i++) diff --git a/config.txt b/config.txt index 36d10d4..781f505 100644 --- a/config.txt +++ b/config.txt @@ -1,184 +1,96 @@ -/* - * Thread configuration for each thread. Make sure it matches the number above. - * low_power_mode - This mode will double the cache usage, and double the single thread performance. It will - * consume much less power (as less cores are working), but will max out at around 80-85% of - * the maximum performance. - * - * no_prefetch - Some sytems can gain up to extra 5% here, but sometimes it will have no difference or make - * things slower. - * - * affine_to_cpu - This can be either false (no affinity), or the CPU core number. Note that on hyperthreading - * systems it is better to assign threads to physical cores. On Windows this usually means selecting - * even or odd numbered cpu numbers. For Linux it will be usually the lower CPU numbers, so for a 4 - * physical core CPU you should select cpu numbers 0-3. - * - * On the first run the miner will look at your system and suggest a basic configuration that will work, - * you can try to tweak it from there to get the best performance. - * - * A filled out configuration should look like this: - * "cpu_threads_conf" : - * [ - * { "low_power_mode" : false, "no_prefetch" : true, "affine_to_cpu" : 0 }, - * { "low_power_mode" : false, "no_prefetch" : true, "affine_to_cpu" : 1 }, - * ], - */ -"cpu_threads_conf" : -null, - -/* - * LARGE PAGE SUPPORT - * Large pages need a properly set up OS. It can be difficult if you are not used to systems administration, - * but the performance results are worth the trouble - you will get around 20% boost. Slow memory mode is - * meant as a backup, you won't get stellar results there. If you are running into trouble, especially - * on Windows, please read the common issues in the README. - * - * By default we will try to allocate large pages. This means you need to "Run As Administrator" on Windows. - * You need to edit your system's group policies to enable locking large pages. Here are the steps from MSDN - * - * 1. On the Start menu, click Run. In the Open box, type gpedit.msc. - * 2. On the Local Group Policy Editor console, expand Computer Configuration, and then expand Windows Settings. - * 3. Expand Security Settings, and then expand Local Policies. - * 4. Select the User Rights Assignment folder. - * 5. The policies will be displayed in the details pane. - * 6. In the pane, double-click Lock pages in memory. - * 7. In the Local Security Setting – Lock pages in memory dialog box, click Add User or Group. - * 8. In the Select Users, Service Accounts, or Groups dialog box, add an account that you will run the miner on - * 9. Reboot for change to take effect. - * - * Windows also tends to fragment memory a lot. If you are running on a system with 4-8GB of RAM you might need - * to switch off all the auto-start applications and reboot to have a large enough chunk of contiguous memory. - * - * On Linux you will need to configure large page support "sudo sysctl -w vm.nr_hugepages=128" and increase your - * ulimit -l. To do do this you need to add following lines to /etc/security/limits.conf - "* soft memlock 262144" - * and "* hard memlock 262144". You can also do it Windows-style and simply run-as-root, but this is NOT - * recommended for security reasons. - * - * Memory locking means that the kernel can't swap out the page to disk - something that is unlikely to happen on a - * command line system that isn't starved of memory. I haven't observed any difference on a CLI Linux system between - * locked and unlocked memory. If that is your setup see option "no_mlck". - */ - -/* - * use_slow_memory defines our behavior with regards to large pages. There are three possible options here: - * always - Don't even try to use large pages. Always use slow memory. - * warn - We will try to use large pages, but fall back to slow memory if that fails. - * no_mlck - This option is only relevant on Linux, where we can use large pages without locking memory. - * It will never use slow memory, but it won't attempt to mlock - * never - If we fail to allocate large pages we will print an error and exit. - */ -"use_slow_memory" : "warn", - -/* - * NiceHash mode - * nicehash_nonce - Limit the nonce to 3 bytes as required by nicehash. This cuts all the safety margins, and - * if a block isn't found within 30 minutes then you might run into nonce collisions. Number - * of threads in this mode is hard-limited to 32. - */ -"nicehash_nonce" : false, - -/* - * Manual hardware AES override - * - * Some VMs don't report AES capability correctly. You can set this value to true to enforce hardware AES or - * to false to force disable AES or null to let the miner decide if AES is used. - * - * WARNING: setting this to true on a CPU that doesn't support hardware AES will crash the miner. - */ -"aes_override" : null, - -/* - * TLS Settings - * If you need real security, make sure tls_secure_algo is enabled (otherwise MITM attack can downgrade encryption - * to trivially breakable stuff like DES and MD5), and verify the server's fingerprint through a trusted channel. - * - * use_tls - This option will make us connect using Transport Layer Security. - * tls_secure_algo - Use only secure algorithms. This will make us quit with an error if we can't negotiate a secure algo. - * tls_fingerprint - Server's SHA256 fingerprint. If this string is non-empty then we will check the server's cert against it. - */ -"use_tls" : false, -"tls_secure_algo" : true, -"tls_fingerprint" : "", - -/* - * pool_address - Pool address should be in the form "pool.supportxmr.com:3333". Only stratum pools are supported. - * wallet_address - Your wallet, or pool login. - * pool_password - Can be empty in most cases or "x". - * - * We feature pools up to 1MH/s. For a more complete list see M5M400's pool list at www.moneropools.com - */ -"pool_address" : "pool.usxmrpool.com:3333", -"wallet_address" : "", -"pool_password" : "", - -/* - * Network timeouts. - * Because of the way this client is written it doesn't need to constantly talk (keep-alive) to the server to make - * sure it is there. We detect a buggy / overloaded server by the call timeout. The default values will be ok for - * nearly all cases. If they aren't the pool has most likely overload issues. Low call timeout values are preferable - - * long timeouts mean that we waste hashes on potentially stale jobs. Connection report will tell you how long the - * server usually takes to process our calls. - * - * call_timeout - How long should we wait for a response from the server before we assume it is dead and drop the connection. - * retry_time - How long should we wait before another connection attempt. - * Both values are in seconds. - * giveup_limit - Limit how many times we try to reconnect to the pool. Zero means no limit. Note that stak miners - * don't mine while the connection is lost, so your computer's power usage goes down to idle. - */ -"call_timeout" : 10, -"retry_time" : 10, -"giveup_limit" : 0, - -/* - * Output control. - * Since most people are used to miners printing all the time, that's what we do by default too. This is suboptimal - * really, since you cannot see errors under pages and pages of text and performance stats. Given that we have internal - * performance monitors, there is very little reason to spew out pages of text instead of concise reports. - * Press 'h' (hashrate), 'r' (results) or 'c' (connection) to print reports. - * - * verbose_level - 0 - Don't print anything. - * 1 - Print intro, connection event, disconnect event - * 2 - All of level 1, and new job (block) event if the difficulty is different from the last job - * 3 - All of level 1, and new job (block) event in all cases, result submission event. - * 4 - All of level 3, and automatic hashrate report printing - */ -"verbose_level" : 3, - -/* - * Automatic hashrate report - * - * h_print_time - How often, in seconds, should we print a hashrate report if verbose_level is set to 4. - * This option has no effect if verbose_level is not 4. - */ -"h_print_time" : 60, - -/* - * Daemon mode - * - * If you are running the process in the background and you don't need the keyboard reports, set this to true. - * This should solve the hashrate problems on some emulated terminals. - */ -"daemon_mode" : false, - -/* - * Output file - * - * output_file - This option will log all output to a file. - * - */ -"output_file" : "", - -/* - * Built-in web server - * I like checking my hashrate on my phone. Don't you? - * Keep in mind that you will need to set up port forwarding on your router if you want to access it from - * outside of your home network. Ports lower than 1024 on Linux systems will require root. - * - * httpd_port - Port we should listen on. Default, 0, will switch off the server. - */ -"httpd_port" : 0, - -/* - * prefer_ipv4 - IPv6 preference. If the host is available on both IPv4 and IPv6 net, which one should be choose? - * This setting will only be needed in 2020's. No need to worry about it now. - */ -"prefer_ipv4" : true, +/* + * TLS Settings + * If you need real security, make sure tls_secure_algo is enabled (otherwise MITM attack can downgrade encryption + * to trivially breakable stuff like DES and MD5), and verify the server's fingerprint through a trusted channel. + * + * use_tls - This option will make us connect using Transport Layer Security. + * tls_secure_algo - Use only secure algorithms. This will make us quit with an error if we can't negotiate a secure algo. + * tls_fingerprint - Server's SHA256 fingerprint. If this string is non-empty then we will check the server's cert against it. + */ +"use_tls" : false, +"tls_secure_algo" : true, +"tls_fingerprint" : "", + +/* + * pool_address - Pool address should be in the form "pool.supportxmr.com:3333". Only stratum pools are supported. + * wallet_address - Your wallet, or pool login. + * pool_password - Can be empty in most cases or "x". + * + * We feature pools up to 1MH/s. For a more complete list see M5M400's pool list at www.moneropools.com + */ +"pool_address" : "pool.usxmrpool.com:3333", +"wallet_address" : "", +"pool_password" : "", + +/* + * Network timeouts. + * Because of the way this client is written it doesn't need to constantly talk (keep-alive) to the server to make + * sure it is there. We detect a buggy / overloaded server by the call timeout. The default values will be ok for + * nearly all cases. If they aren't the pool has most likely overload issues. Low call timeout values are preferable - + * long timeouts mean that we waste hashes on potentially stale jobs. Connection report will tell you how long the + * server usually takes to process our calls. + * + * call_timeout - How long should we wait for a response from the server before we assume it is dead and drop the connection. + * retry_time - How long should we wait before another connection attempt. + * Both values are in seconds. + * giveup_limit - Limit how many times we try to reconnect to the pool. Zero means no limit. Note that stak miners + * don't mine while the connection is lost, so your computer's power usage goes down to idle. + */ +"call_timeout" : 10, +"retry_time" : 10, +"giveup_limit" : 0, + +/* + * Output control. + * Since most people are used to miners printing all the time, that's what we do by default too. This is suboptimal + * really, since you cannot see errors under pages and pages of text and performance stats. Given that we have internal + * performance monitors, there is very little reason to spew out pages of text instead of concise reports. + * Press 'h' (hashrate), 'r' (results) or 'c' (connection) to print reports. + * + * verbose_level - 0 - Don't print anything. + * 1 - Print intro, connection event, disconnect event + * 2 - All of level 1, and new job (block) event if the difficulty is different from the last job + * 3 - All of level 1, and new job (block) event in all cases, result submission event. + * 4 - All of level 3, and automatic hashrate report printing + */ +"verbose_level" : 3, + +/* + * Automatic hashrate report + * + * h_print_time - How often, in seconds, should we print a hashrate report if verbose_level is set to 4. + * This option has no effect if verbose_level is not 4. + */ +"h_print_time" : 60, + +/* + * Daemon mode + * + * If you are running the process in the background and you don't need the keyboard reports, set this to true. + * This should solve the hashrate problems on some emulated terminals. + */ +"daemon_mode" : false, + +/* + * Output file + * + * output_file - This option will log all output to a file. + * + */ +"output_file" : "", + +/* + * Built-in web server + * I like checking my hashrate on my phone. Don't you? + * Keep in mind that you will need to set up port forwarding on your router if you want to access it from + * outside of your home network. Ports lower than 1024 on Linux systems will require root. + * + * httpd_port - Port we should listen on. Default, 0, will switch off the server. + */ +"httpd_port" : 0, + +/* + * prefer_ipv4 - IPv6 preference. If the host is available on both IPv4 and IPv6 net, which one should be choose? + * This setting will only be needed in 2020's. No need to worry about it now. + */ +"prefer_ipv4" : true, diff --git a/console.cpp b/console.cpp index 6a2555b..c6b7d4d 100644 --- a/console.cpp +++ b/console.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -211,3 +212,18 @@ void printer::print_str(const char* str) fflush(logfile); } } + +//Do a press any key for the windows folk. *insert any key joke here* +#ifdef _WIN32 +void win_exit() +{ + printer::inst()->print_str("Press any key to exit."); + get_key(); + std::exit(1); +} + +#else +void win_exit() { + std::exit(1); +} +#endif // _WIN32 diff --git a/console.h b/console.h index 47c3c94..51efaef 100644 --- a/console.h +++ b/console.h @@ -41,3 +41,5 @@ private: verbosity verbose_level; FILE* logfile; }; + +void win_exit(); diff --git a/executor.cpp b/executor.cpp index 948b156..99f7ad5 100644 --- a/executor.cpp +++ b/executor.cpp @@ -29,7 +29,12 @@ #include #include "executor.h" #include "jpsock.h" -#include "minethd.h" + +#include "telemetry.h" +#include "backend/miner_work.h" +#include "backend/GlobalStates.hpp" +#include "backend/BackendConnector.hpp" + #include "jconf.h" #include "console.h" #include "donate-level.h" @@ -116,8 +121,8 @@ void executor::sched_reconnect() printer::inst()->print_msg(L1, "Pool connection lost. Waiting %lld s before retry (attempt %llu).", rt, int_port(iReconnectAttempts)); - auto work = minethd::miner_work(); - minethd::switch_work(work); + auto work = xmrstak::miner_work(); + xmrstak::GlobalStates::switch_work(work); push_timed_event(ex_event(EV_RECONNECT, usr_pool_id), rt); } @@ -229,12 +234,13 @@ void executor::on_pool_have_job(size_t pool_id, pool_job& oPoolJob) jpsock* pool = pick_pool_by_id(pool_id); - minethd::miner_work oWork(oPoolJob.sJobID, oPoolJob.bWorkBlob, + xmrstak::miner_work oWork(oPoolJob.sJobID, oPoolJob.bWorkBlob, oPoolJob.iWorkLen, oPoolJob.iResumeCnt, oPoolJob.iTarget, - pool_id != dev_pool_id && jconf::inst()->NiceHashMode(), pool_id); - minethd::switch_work(oWork); + oWork.iTarget32 = oPoolJob.iTarget32; + + xmrstak::GlobalStates::switch_work(oWork); if(pool_id == dev_pool_id) return; @@ -350,11 +356,13 @@ void executor::on_switch_pool(size_t pool_id) return; } - minethd::miner_work oWork(oPoolJob.sJobID, oPoolJob.bWorkBlob, + xmrstak::miner_work oWork(oPoolJob.sJobID, oPoolJob.bWorkBlob, oPoolJob.iWorkLen, oPoolJob.iResumeCnt, oPoolJob.iTarget, - jconf::inst()->NiceHashMode(), pool_id); + pool_id); - minethd::switch_work(oWork); + oWork.iTarget32 = oPoolJob.iTarget32; + + xmrstak::GlobalStates::switch_work(oWork); if(dev_pool->is_running()) push_timed_event(ex_event(EV_DEV_POOL_EXIT), 5); @@ -365,9 +373,18 @@ void executor::ex_main() { assert(1000 % iTickTime == 0); - minethd::miner_work oWork = minethd::miner_work(); - pvThreads = minethd::thread_starter(oWork); - telem = new telemetry(pvThreads->size()); + xmrstak::miner_work oWork = xmrstak::miner_work(); + + // \todo collect all backend threads + pvThreads = xmrstak::BackendConnector::thread_starter(oWork); + + if(pvThreads->size()==0) + { + printer::inst()->print_msg(L1, "ERROR: No miner backend enabled."); + win_exit(); + } + + telem = new xmrstak::telemetry(pvThreads->size()); current_pool_id = usr_pool_id; usr_pool = new jpsock(usr_pool_id, jconf::inst()->GetTlsSetting()); @@ -499,9 +516,9 @@ void executor::hashrate_report(std::string& out) size_t i; out.append("HASHRATE REPORT\n"); - out.append("| ID | 2.5s | 60s | 15m |"); + out.append("| ID | 10s | 60s | 15m |"); if(nthd != 1) - out.append(" ID | 2.5s | 60s | 15m |\n"); + out.append(" ID | 10s | 60s | 15m |\n"); else out.append(1, '\n'); @@ -509,7 +526,7 @@ void executor::hashrate_report(std::string& out) { double fHps[3]; - fHps[0] = telem->calc_telemetry_data(2500, i); + fHps[0] = telem->calc_telemetry_data(10000, i); fHps[1] = telem->calc_telemetry_data(60000, i); fHps[2] = telem->calc_telemetry_data(900000, i); diff --git a/executor.h b/executor.h index 968db06..57e435f 100644 --- a/executor.h +++ b/executor.h @@ -5,10 +5,20 @@ #include #include #include +#include "telemetry.h" +#include "backend/IBackend.hpp" class jpsock; + + +namespace xmrstak +{ +namespace cpu +{ class minethd; -class telemetry; + +} // namespace cpu +} // namepsace xmrstak class executor { @@ -50,8 +60,8 @@ private: std::mutex timed_event_mutex; thdq oEventQ; - telemetry* telem; - std::vector* pvThreads; + xmrstak::telemetry* telem; + std::vector* pvThreads; size_t current_pool_id; diff --git a/jconf.cpp b/jconf.cpp index 4ac4c13..60075d9 100644 --- a/jconf.cpp +++ b/jconf.cpp @@ -45,7 +45,7 @@ using namespace rapidjson; /* * This enum needs to match index in oConfigValues, otherwise we will get a runtime error */ -enum configEnum { aCpuThreadsConf, sUseSlowMem, bNiceHashMode, bAesOverride, +enum configEnum { bTlsMode, bTlsSecureAlgo, sTlsFingerprint, sPoolAddr, sWalletAddr, sPoolPwd, iCallTimeout, iNetRetry, iGiveUpLimit, iVerboseLevel, iAutohashTime, bDaemonMode, sOutputFile, iHttpdPort, bPreferIpv4 }; @@ -59,10 +59,6 @@ struct configVal { // Same order as in configEnum, as per comment above // kNullType means any type configVal oConfigValues[] = { - { aCpuThreadsConf, "cpu_threads_conf", kNullType }, - { sUseSlowMem, "use_slow_memory", kStringType }, - { bNiceHashMode, "nicehash_nonce", kTrueType }, - { bAesOverride, "aes_override", kNullType }, { bTlsMode, "use_tls", kTrueType }, { bTlsSecureAlgo, "tls_secure_algo", kTrueType }, { sTlsFingerprint, "tls_fingerprint", kStringType }, @@ -113,63 +109,6 @@ jconf::jconf() prv = new opaque_private(); } -bool jconf::GetThreadConfig(size_t id, thd_cfg &cfg) -{ - if(!prv->configValues[aCpuThreadsConf]->IsArray()) - return false; - - if(id >= prv->configValues[aCpuThreadsConf]->Size()) - return false; - - const Value& oThdConf = prv->configValues[aCpuThreadsConf]->GetArray()[id]; - - if(!oThdConf.IsObject()) - return false; - - const Value *mode, *no_prefetch, *aff; - mode = GetObjectMember(oThdConf, "low_power_mode"); - no_prefetch = GetObjectMember(oThdConf, "no_prefetch"); - aff = GetObjectMember(oThdConf, "affine_to_cpu"); - - if(mode == nullptr || no_prefetch == nullptr || aff == nullptr) - return false; - - if(!mode->IsBool() || !no_prefetch->IsBool()) - return false; - - if(!aff->IsNumber() && !aff->IsBool()) - return false; - - if(aff->IsNumber() && aff->GetInt64() < 0) - return false; - - cfg.bDoubleMode = mode->GetBool(); - cfg.bNoPrefetch = no_prefetch->GetBool(); - - if(aff->IsNumber()) - cfg.iCpuAff = aff->GetInt64(); - else - cfg.iCpuAff = -1; - - return true; -} - -jconf::slow_mem_cfg jconf::GetSlowMemSetting() -{ - const char* opt = prv->configValues[sUseSlowMem]->GetString(); - - if(strcasecmp(opt, "always") == 0) - return always_use; - else if(strcasecmp(opt, "no_mlck") == 0) - return no_mlck; - else if(strcasecmp(opt, "warn") == 0) - return print_warning; - else if(strcasecmp(opt, "never") == 0) - return never_use; - else - return unknown_value; -} - bool jconf::GetTlsSetting() { return prv->configValues[bTlsMode]->GetBool(); @@ -205,19 +144,6 @@ bool jconf::PreferIpv4() return prv->configValues[bPreferIpv4]->GetBool(); } -size_t jconf::GetThreadCount() -{ - if(prv->configValues[aCpuThreadsConf]->IsArray()) - return prv->configValues[aCpuThreadsConf]->Size(); - else - return 0; -} - -bool jconf::NeedsAutoconf() -{ - return !prv->configValues[aCpuThreadsConf]->IsArray(); -} - uint64_t jconf::GetCallTimeout() { return prv->configValues[iCallTimeout]->GetUint64(); @@ -248,11 +174,6 @@ uint16_t jconf::GetHttpdPort() return prv->configValues[iHttpdPort]->GetUint(); } -bool jconf::NiceHashMode() -{ - return prv->configValues[bNiceHashMode]->GetBool(); -} - bool jconf::DaemonMode() { return prv->configValues[bDaemonMode]->GetBool(); @@ -263,44 +184,12 @@ const char* jconf::GetOutputFile() return prv->configValues[sOutputFile]->GetString(); } -void jconf::cpuid(uint32_t eax, int32_t ecx, int32_t val[4]) -{ - memset(val, 0, sizeof(int32_t)*4); - -#ifdef _WIN32 - __cpuidex(val, eax, ecx); -#else - __cpuid_count(eax, ecx, val[0], val[1], val[2], val[3]); -#endif -} - -bool jconf::check_cpu_features() -{ - constexpr int AESNI_BIT = 1 << 25; - constexpr int SSE2_BIT = 1 << 26; - int32_t cpu_info[4]; - bool bHaveSse2; - - cpuid(1, 0, cpu_info); - - bHaveAes = (cpu_info[2] & AESNI_BIT) != 0; - bHaveSse2 = (cpu_info[3] & SSE2_BIT) != 0; - - return bHaveSse2; -} - bool jconf::parse_config(const char* sFilename) { FILE * pFile; char * buffer; size_t flen; - if(!check_cpu_features()) - { - printer::inst()->print_msg(L0, "CPU support of SSE2 is required."); - return false; - } - pFile = fopen(sFilename, "rb"); if (pFile == NULL) { @@ -389,29 +278,6 @@ bool jconf::parse_config(const char* sFilename) } } - thd_cfg c; - for(size_t i=0; i < GetThreadCount(); i++) - { - if(!GetThreadConfig(i, c)) - { - printer::inst()->print_msg(L0, "Thread %llu has invalid config.", int_port(i)); - return false; - } - } - - if(NiceHashMode() && GetThreadCount() >= 32) - { - printer::inst()->print_msg(L0, "You need to use less than 32 threads in NiceHash mode."); - return false; - } - - if(GetSlowMemSetting() == unknown_value) - { - printer::inst()->print_msg(L0, - "Invalid config file. use_slow_memory must be \"always\", \"no_mlck\", \"warn\" or \"never\""); - return false; - } - if(!prv->configValues[iCallTimeout]->IsUint64() || !prv->configValues[iNetRetry]->IsUint64() || !prv->configValues[iGiveUpLimit]->IsUint64()) @@ -454,14 +320,5 @@ bool jconf::parse_config(const char* sFilename) printer::inst()->set_verbose_level(prv->configValues[iVerboseLevel]->GetUint64()); - if(NeedsAutoconf()) - return true; - - if(prv->configValues[bAesOverride]->IsBool()) - bHaveAes = prv->configValues[bAesOverride]->GetBool(); - - if(!bHaveAes) - printer::inst()->print_msg(L0, "Your CPU doesn't support hardware AES. Don't expect high hashrates."); - return true; } diff --git a/jconf.h b/jconf.h index c42fbe0..dd6a010 100644 --- a/jconf.h +++ b/jconf.h @@ -27,12 +27,6 @@ public: unknown_value }; - size_t GetThreadCount(); - bool GetThreadConfig(size_t id, thd_cfg &cfg); - bool NeedsAutoconf(); - - slow_mem_cfg GetSlowMemSetting(); - bool GetTlsSetting(); bool TlsSecureAlgos(); const char* GetTlsFingerprint(); @@ -52,15 +46,10 @@ public: uint16_t GetHttpdPort(); - bool NiceHashMode(); - bool DaemonMode(); bool PreferIpv4(); - inline bool HaveHardwareAes() { return bHaveAes; } - - static void cpuid(uint32_t eax, int32_t ecx, int32_t val[4]); private: jconf(); diff --git a/jpsock.cpp b/jpsock.cpp index d179f2a..d287375 100644 --- a/jpsock.cpp +++ b/jpsock.cpp @@ -394,7 +394,10 @@ bool jpsock::process_pool_job(const opq_json_val* params) if(!hex2bin(sTempStr, 8, (unsigned char*)&iTempInt) || iTempInt == 0) return set_socket_error("PARSE error: Invalid target"); + oPoolJob.iTarget = t32_to_t64(iTempInt); + oPoolJob.iTarget32 = iTempInt; + } else if(target_slen <= 16) { diff --git a/minethd.cpp b/minethd.cpp deleted file mode 100644 index fac9fb4..0000000 --- a/minethd.cpp +++ /dev/null @@ -1,555 +0,0 @@ -/* - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Additional permission under GNU GPL version 3 section 7 - * - * If you modify this Program, or any covered work, by linking or combining - * it with OpenSSL (or a modified version of that library), containing parts - * covered by the terms of OpenSSL License and SSLeay License, the licensors - * of this Program grant you additional permission to convey the resulting work. - * - */ - -#include -#include -#include -#include -#include -#include -#include "console.h" - -#ifdef _WIN32 -#include - -void thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id) -{ - SetThreadAffinityMask(h, 1ULL << cpu_id); -} -#else -#include - -#if defined(__APPLE__) -#include -#include -#define SYSCTL_CORE_COUNT "machdep.cpu.core_count" -#elif defined(__FreeBSD__) -#include -#endif - - -void thd_setaffinity(std::thread::native_handle_type h, uint64_t cpu_id) -{ -#if defined(__APPLE__) - thread_port_t mach_thread; - thread_affinity_policy_data_t policy = { static_cast(cpu_id) }; - mach_thread = pthread_mach_thread_np(h); - thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1); -#elif defined(__FreeBSD__) - cpuset_t mn; - CPU_ZERO(&mn); - CPU_SET(cpu_id, &mn); - pthread_setaffinity_np(h, sizeof(cpuset_t), &mn); -#else - cpu_set_t mn; - CPU_ZERO(&mn); - CPU_SET(cpu_id, &mn); - pthread_setaffinity_np(h, sizeof(cpu_set_t), &mn); -#endif -} -#endif // _WIN32 - -#include "executor.h" -#include "minethd.h" -#include "jconf.h" -#include "crypto/cryptonight_aesni.h" -#include "hwlocMemory.hpp" - -telemetry::telemetry(size_t iThd) -{ - ppHashCounts = new uint64_t*[iThd]; - ppTimestamps = new uint64_t*[iThd]; - iBucketTop = new uint32_t[iThd]; - - for (size_t i = 0; i < iThd; i++) - { - ppHashCounts[i] = new uint64_t[iBucketSize]; - ppTimestamps[i] = new uint64_t[iBucketSize]; - iBucketTop[i] = 0; - memset(ppHashCounts[0], 0, sizeof(uint64_t) * iBucketSize); - memset(ppTimestamps[0], 0, sizeof(uint64_t) * iBucketSize); - } -} - -double telemetry::calc_telemetry_data(size_t iLastMilisec, size_t iThread) -{ - using namespace std::chrono; - uint64_t iTimeNow = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); - - uint64_t iEarliestHashCnt = 0; - uint64_t iEarliestStamp = 0; - uint64_t iLastestStamp = 0; - uint64_t iLastestHashCnt = 0; - bool bHaveFullSet = false; - - //Start at 1, buckettop points to next empty - for (size_t i = 1; i < iBucketSize; i++) - { - size_t idx = (iBucketTop[iThread] - i) & iBucketMask; //overflow expected here - - if (ppTimestamps[iThread][idx] == 0) - break; //That means we don't have the data yet - - if (iLastestStamp == 0) - { - iLastestStamp = ppTimestamps[iThread][idx]; - iLastestHashCnt = ppHashCounts[iThread][idx]; - } - - if (iTimeNow - ppTimestamps[iThread][idx] > iLastMilisec) - { - bHaveFullSet = true; - break; //We are out of the requested time period - } - - iEarliestStamp = ppTimestamps[iThread][idx]; - iEarliestHashCnt = ppHashCounts[iThread][idx]; - } - - if (!bHaveFullSet || iEarliestStamp == 0 || iLastestStamp == 0) - return nan(""); - - //Don't think that can happen, but just in case - if (iLastestStamp - iEarliestStamp == 0) - return nan(""); - - double fHashes, fTime; - fHashes = iLastestHashCnt - iEarliestHashCnt; - fTime = iLastestStamp - iEarliestStamp; - fTime /= 1000.0; - - return fHashes / fTime; -} - -void telemetry::push_perf_value(size_t iThd, uint64_t iHashCount, uint64_t iTimestamp) -{ - size_t iTop = iBucketTop[iThd]; - ppHashCounts[iThd][iTop] = iHashCount; - ppTimestamps[iThd][iTop] = iTimestamp; - - iBucketTop[iThd] = (iTop + 1) & iBucketMask; -} - -minethd::minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefetch, int64_t affinity) -{ - oWork = pWork; - bQuit = 0; - iThreadNo = (uint8_t)iNo; - iJobNo = 0; - iHashCount = 0; - iTimestamp = 0; - bNoPrefetch = no_prefetch; - this->affinity = affinity; - - std::lock_guard lock(work_thd_mtx); - if(double_work) - oWorkThd = std::thread(&minethd::double_work_main, this); - else - oWorkThd = std::thread(&minethd::work_main, this); -} - -std::atomic minethd::iGlobalJobNo; -std::atomic minethd::iConsumeCnt; //Threads get jobs as they are initialized -minethd::miner_work minethd::oGlobalWork; -uint64_t minethd::iThreadCount = 0; - -cryptonight_ctx* minethd_alloc_ctx() -{ - cryptonight_ctx* ctx; - alloc_msg msg = { 0 }; - - switch (jconf::inst()->GetSlowMemSetting()) - { - case jconf::never_use: - ctx = cryptonight_alloc_ctx(1, 1, &msg); - if (ctx == NULL) - printer::inst()->print_msg(L0, "MEMORY ALLOC FAILED: %s", msg.warning); - return ctx; - - case jconf::no_mlck: - ctx = cryptonight_alloc_ctx(1, 0, &msg); - if (ctx == NULL) - printer::inst()->print_msg(L0, "MEMORY ALLOC FAILED: %s", msg.warning); - return ctx; - - case jconf::print_warning: - ctx = cryptonight_alloc_ctx(1, 1, &msg); - if (msg.warning != NULL) - printer::inst()->print_msg(L0, "MEMORY ALLOC FAILED: %s", msg.warning); - if (ctx == NULL) - ctx = cryptonight_alloc_ctx(0, 0, NULL); - return ctx; - - case jconf::always_use: - return cryptonight_alloc_ctx(0, 0, NULL); - - case jconf::unknown_value: - return NULL; //Shut up compiler - } - - return nullptr; //Should never happen -} - -bool minethd::self_test() -{ - alloc_msg msg = { 0 }; - size_t res; - bool fatal = false; - - switch (jconf::inst()->GetSlowMemSetting()) - { - case jconf::never_use: - res = cryptonight_init(1, 1, &msg); - fatal = true; - break; - - case jconf::no_mlck: - res = cryptonight_init(1, 0, &msg); - fatal = true; - break; - - case jconf::print_warning: - res = cryptonight_init(1, 1, &msg); - break; - - case jconf::always_use: - res = cryptonight_init(0, 0, &msg); - break; - - case jconf::unknown_value: - default: - return false; //Shut up compiler - } - - if(msg.warning != nullptr) - printer::inst()->print_msg(L0, "MEMORY INIT ERROR: %s", msg.warning); - - if(res == 0 && fatal) - return false; - - cryptonight_ctx *ctx0, *ctx1; - if((ctx0 = minethd_alloc_ctx()) == nullptr) - return false; - - if((ctx1 = minethd_alloc_ctx()) == nullptr) - { - cryptonight_free_ctx(ctx0); - return false; - } - - unsigned char out[64]; - bool bResult; - - cn_hash_fun hashf; - cn_hash_fun_dbl hashdf; - - hashf = func_selector(jconf::inst()->HaveHardwareAes(), false); - hashf("This is a test", 14, out, ctx0); - bResult = memcmp(out, "\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 32) == 0; - - hashf = func_selector(jconf::inst()->HaveHardwareAes(), true); - hashf("This is a test", 14, out, ctx0); - bResult &= memcmp(out, "\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 32) == 0; - - hashdf = func_dbl_selector(jconf::inst()->HaveHardwareAes(), false); - hashdf("The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy log", 43, out, ctx0, ctx1); - bResult &= memcmp(out, "\x3e\xbb\x7f\x9f\x7d\x27\x3d\x7c\x31\x8d\x86\x94\x77\x55\x0c\xc8\x00\xcf\xb1\x1b\x0c\xad\xb7\xff\xbd\xf6\xf8\x9f\x3a\x47\x1c\x59" - "\xb4\x77\xd5\x02\xe4\xd8\x48\x7f\x42\xdf\xe3\x8e\xed\x73\x81\x7a\xda\x91\xb7\xe2\x63\xd2\x91\x71\xb6\x5c\x44\x3a\x01\x2a\x41\x22", 64) == 0; - - hashdf = func_dbl_selector(jconf::inst()->HaveHardwareAes(), true); - hashdf("The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy log", 43, out, ctx0, ctx1); - bResult &= memcmp(out, "\x3e\xbb\x7f\x9f\x7d\x27\x3d\x7c\x31\x8d\x86\x94\x77\x55\x0c\xc8\x00\xcf\xb1\x1b\x0c\xad\xb7\xff\xbd\xf6\xf8\x9f\x3a\x47\x1c\x59" - "\xb4\x77\xd5\x02\xe4\xd8\x48\x7f\x42\xdf\xe3\x8e\xed\x73\x81\x7a\xda\x91\xb7\xe2\x63\xd2\x91\x71\xb6\x5c\x44\x3a\x01\x2a\x41\x22", 64) == 0; - - cryptonight_free_ctx(ctx0); - cryptonight_free_ctx(ctx1); - - if(!bResult) - printer::inst()->print_msg(L0, - "Cryptonight hash self-test failed. This might be caused by bad compiler optimizations."); - - return bResult; -} - -std::vector* minethd::thread_starter(miner_work& pWork) -{ - iGlobalJobNo = 0; - iConsumeCnt = 0; - std::vector* pvThreads = new std::vector; - - //Launch the requested number of single and double threads, to distribute - //load evenly we need to alternate single and double threads - size_t i, n = jconf::inst()->GetThreadCount(); - pvThreads->reserve(n); - - jconf::thd_cfg cfg; - for (i = 0; i < n; i++) - { - jconf::inst()->GetThreadConfig(i, cfg); - - minethd* thd = new minethd(pWork, i, cfg.bDoubleMode, cfg.bNoPrefetch, cfg.iCpuAff); - pvThreads->push_back(thd); - - if(cfg.iCpuAff >= 0) - printer::inst()->print_msg(L1, "Starting %s thread, affinity: %d.", cfg.bDoubleMode ? "double" : "single", (int)cfg.iCpuAff); - else - printer::inst()->print_msg(L1, "Starting %s thread, no affinity.", cfg.bDoubleMode ? "double" : "single"); - } - - iThreadCount = n; - return pvThreads; -} - -void minethd::switch_work(miner_work& pWork) -{ - // iConsumeCnt is a basic lock-like polling mechanism just in case we happen to push work - // faster than threads can consume them. This should never happen in real life. - // Pool cant physically send jobs faster than every 250ms or so due to net latency. - - while (iConsumeCnt.load(std::memory_order_seq_cst) < iThreadCount) - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - oGlobalWork = pWork; - iConsumeCnt.store(0, std::memory_order_seq_cst); - iGlobalJobNo++; -} - -void minethd::consume_work() -{ - memcpy(&oWork, &oGlobalWork, sizeof(miner_work)); - iJobNo++; - iConsumeCnt++; -} - -minethd::cn_hash_fun minethd::func_selector(bool bHaveAes, bool bNoPrefetch) -{ - // We have two independent flag bits in the functions - // therefore we will build a binary digit and select the - // function as a two digit binary - // Digit order SOFT_AES, NO_PREFETCH - - static const cn_hash_fun func_table[4] = { - cryptonight_hash<0x80000, MEMORY, false, false>, - cryptonight_hash<0x80000, MEMORY, false, true>, - cryptonight_hash<0x80000, MEMORY, true, false>, - cryptonight_hash<0x80000, MEMORY, true, true> - }; - - std::bitset<2> digit; - digit.set(0, !bNoPrefetch); - digit.set(1, !bHaveAes); - - return func_table[digit.to_ulong()]; -} - -void minethd::pin_thd_affinity() -{ - //Lock is needed because we need to use oWorkThd - std::lock_guard lock(work_thd_mtx); - - // pin memory to NUMA node - bindMemoryToNUMANode(affinity); - -#if defined(__APPLE__) - printer::inst()->print_msg(L1, "WARNING on MacOS thread affinity is only advisory."); -#endif - thd_setaffinity(oWorkThd.native_handle(), affinity); -} - -void minethd::work_main() -{ - if(affinity >= 0) //-1 means no affinity - pin_thd_affinity(); - - cn_hash_fun hash_fun; - cryptonight_ctx* ctx; - uint64_t iCount = 0; - uint64_t* piHashVal; - uint32_t* piNonce; - job_result result; - - hash_fun = func_selector(jconf::inst()->HaveHardwareAes(), bNoPrefetch); - ctx = minethd_alloc_ctx(); - - piHashVal = (uint64_t*)(result.bResult + 24); - piNonce = (uint32_t*)(oWork.bWorkBlob + 39); - iConsumeCnt++; - - while (bQuit == 0) - { - if (oWork.bStall) - { - /* We are stalled here because the executor didn't find a job for us yet, - either because of network latency, or a socket problem. Since we are - raison d'etre of this software it us sensible to just wait until we have something*/ - - while (iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - consume_work(); - continue; - } - - if(oWork.bNiceHash) - result.iNonce = calc_nicehash_nonce(*piNonce, oWork.iResumeCnt); - else - result.iNonce = calc_start_nonce(oWork.iResumeCnt); - - assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); - memcpy(result.sJobID, oWork.sJobID, sizeof(job_result::sJobID)); - - while(iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) - { - if ((iCount & 0xF) == 0) //Store stats every 16 hashes - { - using namespace std::chrono; - uint64_t iStamp = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); - iHashCount.store(iCount, std::memory_order_relaxed); - iTimestamp.store(iStamp, std::memory_order_relaxed); - } - iCount++; - - *piNonce = ++result.iNonce; - - hash_fun(oWork.bWorkBlob, oWork.iWorkSize, result.bResult, ctx); - - if (*piHashVal < oWork.iTarget) - executor::inst()->push_event(ex_event(result, oWork.iPoolId)); - - std::this_thread::yield(); - } - - consume_work(); - } - - cryptonight_free_ctx(ctx); -} - -minethd::cn_hash_fun_dbl minethd::func_dbl_selector(bool bHaveAes, bool bNoPrefetch) -{ - // We have two independent flag bits in the functions - // therefore we will build a binary digit and select the - // function as a two digit binary - // Digit order SOFT_AES, NO_PREFETCH - - static const cn_hash_fun_dbl func_table[4] = { - cryptonight_double_hash<0x80000, MEMORY, false, false>, - cryptonight_double_hash<0x80000, MEMORY, false, true>, - cryptonight_double_hash<0x80000, MEMORY, true, false>, - cryptonight_double_hash<0x80000, MEMORY, true, true> - }; - - std::bitset<2> digit; - digit.set(0, !bNoPrefetch); - digit.set(1, !bHaveAes); - - return func_table[digit.to_ulong()]; -} - -void minethd::double_work_main() -{ - if(affinity >= 0) //-1 means no affinity - pin_thd_affinity(); - - cn_hash_fun_dbl hash_fun; - cryptonight_ctx* ctx0; - cryptonight_ctx* ctx1; - uint64_t iCount = 0; - uint64_t *piHashVal0, *piHashVal1; - uint32_t *piNonce0, *piNonce1; - uint8_t bDoubleHashOut[64]; - uint8_t bDoubleWorkBlob[sizeof(miner_work::bWorkBlob) * 2]; - uint32_t iNonce; - job_result res; - - hash_fun = func_dbl_selector(jconf::inst()->HaveHardwareAes(), bNoPrefetch); - ctx0 = minethd_alloc_ctx(); - ctx1 = minethd_alloc_ctx(); - - piHashVal0 = (uint64_t*)(bDoubleHashOut + 24); - piHashVal1 = (uint64_t*)(bDoubleHashOut + 32 + 24); - piNonce0 = (uint32_t*)(bDoubleWorkBlob + 39); - piNonce1 = nullptr; - - iConsumeCnt++; - - while (bQuit == 0) - { - if (oWork.bStall) - { - /* We are stalled here because the executor didn't find a job for us yet, - either because of network latency, or a socket problem. Since we are - raison d'etre of this software it us sensible to just wait until we have something*/ - - while (iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - consume_work(); - memcpy(bDoubleWorkBlob, oWork.bWorkBlob, oWork.iWorkSize); - memcpy(bDoubleWorkBlob + oWork.iWorkSize, oWork.bWorkBlob, oWork.iWorkSize); - piNonce1 = (uint32_t*)(bDoubleWorkBlob + oWork.iWorkSize + 39); - continue; - } - - if(oWork.bNiceHash) - iNonce = calc_nicehash_nonce(*piNonce0, oWork.iResumeCnt); - else - iNonce = calc_start_nonce(oWork.iResumeCnt); - - assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); - - while (iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) - { - if ((iCount & 0x7) == 0) //Store stats every 16 hashes - { - using namespace std::chrono; - uint64_t iStamp = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); - iHashCount.store(iCount, std::memory_order_relaxed); - iTimestamp.store(iStamp, std::memory_order_relaxed); - } - - iCount += 2; - - *piNonce0 = ++iNonce; - *piNonce1 = ++iNonce; - - hash_fun(bDoubleWorkBlob, oWork.iWorkSize, bDoubleHashOut, ctx0, ctx1); - - if (*piHashVal0 < oWork.iTarget) - executor::inst()->push_event(ex_event(job_result(oWork.sJobID, iNonce-1, bDoubleHashOut), oWork.iPoolId)); - - if (*piHashVal1 < oWork.iTarget) - executor::inst()->push_event(ex_event(job_result(oWork.sJobID, iNonce, bDoubleHashOut + 32), oWork.iPoolId)); - - std::this_thread::yield(); - } - - consume_work(); - memcpy(bDoubleWorkBlob, oWork.bWorkBlob, oWork.iWorkSize); - memcpy(bDoubleWorkBlob + oWork.iWorkSize, oWork.bWorkBlob, oWork.iWorkSize); - piNonce1 = (uint32_t*)(bDoubleWorkBlob + oWork.iWorkSize + 39); - } - - cryptonight_free_ctx(ctx0); - cryptonight_free_ctx(ctx1); -} diff --git a/minethd.h b/minethd.h deleted file mode 100644 index 293e8de..0000000 --- a/minethd.h +++ /dev/null @@ -1,144 +0,0 @@ -#pragma once -#include -#include -#include -#include "crypto/cryptonight.h" - -class telemetry -{ -public: - telemetry(size_t iThd); - void push_perf_value(size_t iThd, uint64_t iHashCount, uint64_t iTimestamp); - double calc_telemetry_data(size_t iLastMilisec, size_t iThread); - -private: - constexpr static size_t iBucketSize = 2 << 11; //Power of 2 to simplify calculations - constexpr static size_t iBucketMask = iBucketSize - 1; - uint32_t* iBucketTop; - uint64_t** ppHashCounts; - uint64_t** ppTimestamps; -}; - -class minethd -{ -public: - struct miner_work - { - char sJobID[64]; - uint8_t bWorkBlob[112]; - uint32_t iWorkSize; - uint32_t iResumeCnt; - uint64_t iTarget; - bool bNiceHash; - bool bStall; - size_t iPoolId; - - miner_work() : iWorkSize(0), bStall(true), iPoolId(0) { } - - miner_work(const char* sJobID, const uint8_t* bWork, uint32_t iWorkSize, uint32_t iResumeCnt, - uint64_t iTarget, bool bNiceHash, size_t iPoolId) : iWorkSize(iWorkSize), iResumeCnt(iResumeCnt), - iTarget(iTarget), bNiceHash(bNiceHash), bStall(false), iPoolId(iPoolId) - { - assert(iWorkSize <= sizeof(bWorkBlob)); - memcpy(this->sJobID, sJobID, sizeof(miner_work::sJobID)); - memcpy(this->bWorkBlob, bWork, iWorkSize); - } - - miner_work(miner_work const&) = delete; - - miner_work& operator=(miner_work const& from) - { - assert(this != &from); - - iWorkSize = from.iWorkSize; - iResumeCnt = from.iResumeCnt; - iTarget = from.iTarget; - bNiceHash = from.bNiceHash; - bStall = from.bStall; - iPoolId = from.iPoolId; - - assert(iWorkSize <= sizeof(bWorkBlob)); - memcpy(sJobID, from.sJobID, sizeof(sJobID)); - memcpy(bWorkBlob, from.bWorkBlob, iWorkSize); - - return *this; - } - - miner_work(miner_work&& from) : iWorkSize(from.iWorkSize), iTarget(from.iTarget), - bStall(from.bStall), iPoolId(from.iPoolId) - { - assert(iWorkSize <= sizeof(bWorkBlob)); - memcpy(sJobID, from.sJobID, sizeof(sJobID)); - memcpy(bWorkBlob, from.bWorkBlob, iWorkSize); - } - - miner_work& operator=(miner_work&& from) - { - assert(this != &from); - - iWorkSize = from.iWorkSize; - iResumeCnt = from.iResumeCnt; - iTarget = from.iTarget; - bNiceHash = from.bNiceHash; - bStall = from.bStall; - iPoolId = from.iPoolId; - - assert(iWorkSize <= sizeof(bWorkBlob)); - memcpy(sJobID, from.sJobID, sizeof(sJobID)); - memcpy(bWorkBlob, from.bWorkBlob, iWorkSize); - - return *this; - } - }; - - static void switch_work(miner_work& pWork); - static std::vector* thread_starter(miner_work& pWork); - static bool self_test(); - - std::atomic iHashCount; - std::atomic iTimestamp; - -private: - typedef void (*cn_hash_fun)(const void*, size_t, void*, cryptonight_ctx*); - typedef void (*cn_hash_fun_dbl)(const void*, size_t, void*, cryptonight_ctx* __restrict, cryptonight_ctx* __restrict); - - minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefetch, int64_t affinity); - - // We use the top 10 bits of the nonce for thread and resume - // This allows us to resume up to 128 threads 4 times before - // we get nonce collisions - // Bottom 22 bits allow for an hour of work at 1000 H/s - inline uint32_t calc_start_nonce(uint32_t resume) - { return (resume * iThreadCount + iThreadNo) << 22; } - - // Limited version of the nonce calc above - inline uint32_t calc_nicehash_nonce(uint32_t start, uint32_t resume) - { return start | (resume * iThreadCount + iThreadNo) << 18; } - - static cn_hash_fun func_selector(bool bHaveAes, bool bNoPrefetch); - static cn_hash_fun_dbl func_dbl_selector(bool bHaveAes, bool bNoPrefetch); - - void work_main(); - void double_work_main(); - void consume_work(); - - static std::atomic iGlobalJobNo; - static std::atomic iConsumeCnt; - static uint64_t iThreadCount; - uint64_t iJobNo; - - static miner_work oGlobalWork; - miner_work oWork; - - void pin_thd_affinity(); - // Held by the creating context to prevent a race cond with oWorkThd = std::thread(...) - std::mutex work_thd_mtx; - - std::thread oWorkThd; - uint8_t iThreadNo; - int64_t affinity; - - bool bQuit; - bool bNoPrefetch; -}; - diff --git a/msgstruct.h b/msgstruct.h index 6f4a6fb..f3a39b2 100644 --- a/msgstruct.h +++ b/msgstruct.h @@ -11,6 +11,8 @@ struct pool_job char sJobID[64]; uint8_t bWorkBlob[112]; uint64_t iTarget; + // \todo remove workaround needed for amd + uint32_t iTarget32; uint32_t iWorkLen; uint32_t iResumeCnt; @@ -38,6 +40,7 @@ struct job_result } }; + enum ex_event_name { EV_INVALID_VAL, EV_SOCK_READY, EV_SOCK_ERROR, EV_POOL_HAVE_JOB, EV_MINER_HAVE_RESULT, EV_PERF_TICK, EV_RECONNECT, EV_SWITCH_POOL, EV_DEV_POOL_EXIT, EV_USR_HASHRATE, EV_USR_RESULTS, EV_USR_CONNSTAT, diff --git a/telemetry.cpp b/telemetry.cpp new file mode 100644 index 0000000..fafccd5 --- /dev/null +++ b/telemetry.cpp @@ -0,0 +1,107 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Additional permission under GNU GPL version 3 section 7 + * + * If you modify this Program, or any covered work, by linking or combining + * it with OpenSSL (or a modified version of that library), containing parts + * covered by the terms of OpenSSL License and SSLeay License, the licensors + * of this Program grant you additional permission to convey the resulting work. + * + */ + +#include +#include +#include +#include "telemetry.h" + +namespace xmrstak +{ + +telemetry::telemetry(size_t iThd) +{ + ppHashCounts = new uint64_t*[iThd]; + ppTimestamps = new uint64_t*[iThd]; + iBucketTop = new uint32_t[iThd]; + + for (size_t i = 0; i < iThd; i++) + { + ppHashCounts[i] = new uint64_t[iBucketSize]; + ppTimestamps[i] = new uint64_t[iBucketSize]; + iBucketTop[i] = 0; + memset(ppHashCounts[i], 0, sizeof(uint64_t) * iBucketSize); + memset(ppTimestamps[i], 0, sizeof(uint64_t) * iBucketSize); + } +} + +double telemetry::calc_telemetry_data(size_t iLastMilisec, size_t iThread) +{ + using namespace std::chrono; + uint64_t iTimeNow = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); + + uint64_t iEarliestHashCnt = 0; + uint64_t iEarliestStamp = 0; + uint64_t iLastestStamp = 0; + uint64_t iLastestHashCnt = 0; + bool bHaveFullSet = false; + + //Start at 1, buckettop points to next empty + for (size_t i = 1; i < iBucketSize; i++) + { + size_t idx = (iBucketTop[iThread] - i) & iBucketMask; //overflow expected here + + if (ppTimestamps[iThread][idx] == 0) + break; //That means we don't have the data yet + + if (iLastestStamp == 0) + { + iLastestStamp = ppTimestamps[iThread][idx]; + iLastestHashCnt = ppHashCounts[iThread][idx]; + } + + if (iTimeNow - ppTimestamps[iThread][idx] > iLastMilisec) + { + bHaveFullSet = true; + break; //We are out of the requested time period + } + + iEarliestStamp = ppTimestamps[iThread][idx]; + iEarliestHashCnt = ppHashCounts[iThread][idx]; + } + + if (!bHaveFullSet || iEarliestStamp == 0 || iLastestStamp == 0) + return nan(""); + + //Don't think that can happen, but just in case + if (iLastestStamp - iEarliestStamp == 0) + return nan(""); + + double fHashes, fTime; + fHashes = iLastestHashCnt - iEarliestHashCnt; + fTime = iLastestStamp - iEarliestStamp; + fTime /= 1000.0; + + return fHashes / fTime; +} + +void telemetry::push_perf_value(size_t iThd, uint64_t iHashCount, uint64_t iTimestamp) +{ + size_t iTop = iBucketTop[iThd]; + ppHashCounts[iThd][iTop] = iHashCount; + ppTimestamps[iThd][iTop] = iTimestamp; + + iBucketTop[iThd] = (iTop + 1) & iBucketMask; +} + +} // namepsace xmrstak diff --git a/telemetry.h b/telemetry.h new file mode 100644 index 0000000..0538090 --- /dev/null +++ b/telemetry.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +namespace xmrstak +{ + +class telemetry +{ +public: + telemetry(size_t iThd); + void push_perf_value(size_t iThd, uint64_t iHashCount, uint64_t iTimestamp); + double calc_telemetry_data(size_t iLastMilisec, size_t iThread); + +private: + constexpr static size_t iBucketSize = 2 << 11; //Power of 2 to simplify calculations + constexpr static size_t iBucketMask = iBucketSize - 1; + uint32_t* iBucketTop; + uint64_t** ppHashCounts; + uint64_t** ppTimestamps; +}; + +} // namepsace xmrstak diff --git a/version.h b/version.h index 04a6ced..44214c8 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ #pragma once -#define XMR_STAK_NAME "xmr-stak-cpu" -#define XMR_STAK_VERSION "1.3.0-1.5.0-dev" +#define XMR_STAK_NAME "xmr-stak" +#define XMR_STAK_VERSION "2.0.0-predev" diff --git a/webdesign.cpp b/webdesign.cpp index e07b015..4dfd3c2 100644 --- a/webdesign.cpp +++ b/webdesign.cpp @@ -115,7 +115,7 @@ extern const char sHtmlCommonHeader [] = extern const char sHtmlHashrateBodyHigh [] = "
" "" - ""; + ""; extern const char sHtmlHashrateTableRow [] = ""; From 4085d47d03c1762dfc95f893ed0ee86ad9eaee41 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 24 Sep 2017 20:08:54 +0200 Subject: [PATCH 07/42] add amd opencl files --- opencl/blake256.cl | 96 +++++ opencl/cryptonight.cl | 970 ++++++++++++++++++++++++++++++++++++++++++ opencl/groestl256.cl | 289 +++++++++++++ opencl/jh.cl | 272 ++++++++++++ opencl/wolf-aes.cl | 87 ++++ opencl/wolf-skein.cl | 111 +++++ 6 files changed, 1825 insertions(+) create mode 100644 opencl/blake256.cl create mode 100644 opencl/cryptonight.cl create mode 100644 opencl/groestl256.cl create mode 100644 opencl/jh.cl create mode 100644 opencl/wolf-aes.cl create mode 100644 opencl/wolf-skein.cl diff --git a/opencl/blake256.cl b/opencl/blake256.cl new file mode 100644 index 0000000..6be0eb0 --- /dev/null +++ b/opencl/blake256.cl @@ -0,0 +1,96 @@ +/* +* blake256 kernel implementation. +* +* ==========================(LICENSE BEGIN)============================ +* Copyright (c) 2014 djm34 +* Copyright (c) 2014 tpruvot +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +* ===========================(LICENSE END)============================= +* +* @author djm34 +*/ +__constant static const int sigma[16][16] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } +}; + + +__constant static const sph_u32 c_IV256[8] = { + 0x6A09E667, 0xBB67AE85, + 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, + 0x1F83D9AB, 0x5BE0CD19 +}; + +/* Second part (64-80) msg never change, store it */ +__constant static const sph_u32 c_Padding[16] = { + 0, 0, 0, 0, + 0x80000000, 0, 0, 0, + 0, 0, 0, 0, + 0, 1, 0, 640, +}; +__constant static const sph_u32 c_u256[16] = { + 0x243F6A88, 0x85A308D3, + 0x13198A2E, 0x03707344, + 0xA4093822, 0x299F31D0, + 0x082EFA98, 0xEC4E6C89, + 0x452821E6, 0x38D01377, + 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, + 0x3F84D5B5, 0xB5470917 +}; + +#define GS(a,b,c,d,x) { \ + const sph_u32 idx1 = sigma[r][x]; \ + const sph_u32 idx2 = sigma[r][x+1]; \ + v[a] += (m[idx1] ^ c_u256[idx2]) + v[b]; \ + v[d] ^= v[a]; \ + v[d] = rotate(v[d], 16U); \ + v[c] += v[d]; \ + v[b] ^= v[c]; \ + v[b] = rotate(v[b], 20U); \ +\ + v[a] += (m[idx2] ^ c_u256[idx1]) + v[b]; \ + v[d] ^= v[a]; \ + v[d] = rotate(v[d], 24U); \ + v[c] += v[d]; \ + v[b] ^= v[c]; \ + v[b] = rotate(v[b], 25U); \ +} + + + + + diff --git a/opencl/cryptonight.cl b/opencl/cryptonight.cl new file mode 100644 index 0000000..0478160 --- /dev/null +++ b/opencl/cryptonight.cl @@ -0,0 +1,970 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef cl_amd_media_ops +#pragma OPENCL EXTENSION cl_amd_media_ops : enable +#else +/* taken from https://www.khronos.org/registry/OpenCL/extensions/amd/cl_amd_media_ops.txt + * Build-in Function + * uintn amd_bitalign (uintn src0, uintn src1, uintn src2) + * Description + * dst.s0 = (uint) (((((long)src0.s0) << 32) | (long)src1.s0) >> (src2.s0 & 31)) + * similar operation applied to other components of the vectors. + * + * The implemented function is modified because the last is in our case always a scalar. + * We can ignore the bitwise AND operation. + */ +inline uint2 amd_bitalign( const uint2 src0, const uint2 src1, const uint src2) +{ + uint2 result; + result.s0 = (uint) (((((long)src0.s0) << 32) | (long)src1.s0) >> (src2)); + result.s1 = (uint) (((((long)src0.s1) << 32) | (long)src1.s1) >> (src2)); + return result; +} +#endif + +#ifdef cl_amd_media_ops2 +#pragma OPENCL EXTENSION cl_amd_media_ops2 : enable +#else +/* taken from: https://www.khronos.org/registry/OpenCL/extensions/amd/cl_amd_media_ops2.txt + * Built-in Function: + * uintn amd_bfe (uintn src0, uintn src1, uintn src2) + * Description + * NOTE: operator >> below represent logical right shift + * offset = src1.s0 & 31; + * width = src2.s0 & 31; + * if width = 0 + * dst.s0 = 0; + * else if (offset + width) < 32 + * dst.s0 = (src0.s0 << (32 - offset - width)) >> (32 - width); + * else + * dst.s0 = src0.s0 >> offset; + * similar operation applied to other components of the vectors + */ +inline int amd_bfe(const uint src0, const uint offset, const uint width) +{ + /* casts are removed because we can implement everything as uint + * int offset = src1; + * int width = src2; + * remove check for edge case, this function is always called with + * `width==8` + * @code + * if ( width == 0 ) + * return 0; + * @endcode + */ + if ( (offset + width) < 32u ) + return (src0 << (32u - offset - width)) >> (32u - width); + + return src0 >> offset; +} +#endif + +#include "opencl/wolf-aes.cl" +#include "opencl/wolf-skein.cl" +#include "opencl/jh.cl" +#include "opencl/blake256.cl" +#include "opencl/groestl256.cl" + +static const __constant ulong keccakf_rndc[24] = +{ + 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, + 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, + 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, + 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, + 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, + 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, + 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, + 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 +}; + +static const __constant uchar sbox[256] = +{ + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 +}; + + +void keccakf1600(ulong *s) +{ + for(int i = 0; i < 24; ++i) + { + ulong bc[5], tmp1, tmp2; + bc[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20] ^ rotate(s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22], 1UL); + bc[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21] ^ rotate(s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23], 1UL); + bc[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22] ^ rotate(s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24], 1UL); + bc[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23] ^ rotate(s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20], 1UL); + bc[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24] ^ rotate(s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21], 1UL); + + tmp1 = s[1] ^ bc[0]; + + s[0] ^= bc[4]; + s[1] = rotate(s[6] ^ bc[0], 44UL); + s[6] = rotate(s[9] ^ bc[3], 20UL); + s[9] = rotate(s[22] ^ bc[1], 61UL); + s[22] = rotate(s[14] ^ bc[3], 39UL); + s[14] = rotate(s[20] ^ bc[4], 18UL); + s[20] = rotate(s[2] ^ bc[1], 62UL); + s[2] = rotate(s[12] ^ bc[1], 43UL); + s[12] = rotate(s[13] ^ bc[2], 25UL); + s[13] = rotate(s[19] ^ bc[3], 8UL); + s[19] = rotate(s[23] ^ bc[2], 56UL); + s[23] = rotate(s[15] ^ bc[4], 41UL); + s[15] = rotate(s[4] ^ bc[3], 27UL); + s[4] = rotate(s[24] ^ bc[3], 14UL); + s[24] = rotate(s[21] ^ bc[0], 2UL); + s[21] = rotate(s[8] ^ bc[2], 55UL); + s[8] = rotate(s[16] ^ bc[0], 35UL); + s[16] = rotate(s[5] ^ bc[4], 36UL); + s[5] = rotate(s[3] ^ bc[2], 28UL); + s[3] = rotate(s[18] ^ bc[2], 21UL); + s[18] = rotate(s[17] ^ bc[1], 15UL); + s[17] = rotate(s[11] ^ bc[0], 10UL); + s[11] = rotate(s[7] ^ bc[1], 6UL); + s[7] = rotate(s[10] ^ bc[4], 3UL); + s[10] = rotate(tmp1, 1UL); + + tmp1 = s[0]; tmp2 = s[1]; s[0] = bitselect(s[0] ^ s[2], s[0], s[1]); s[1] = bitselect(s[1] ^ s[3], s[1], s[2]); s[2] = bitselect(s[2] ^ s[4], s[2], s[3]); s[3] = bitselect(s[3] ^ tmp1, s[3], s[4]); s[4] = bitselect(s[4] ^ tmp2, s[4], tmp1); + tmp1 = s[5]; tmp2 = s[6]; s[5] = bitselect(s[5] ^ s[7], s[5], s[6]); s[6] = bitselect(s[6] ^ s[8], s[6], s[7]); s[7] = bitselect(s[7] ^ s[9], s[7], s[8]); s[8] = bitselect(s[8] ^ tmp1, s[8], s[9]); s[9] = bitselect(s[9] ^ tmp2, s[9], tmp1); + tmp1 = s[10]; tmp2 = s[11]; s[10] = bitselect(s[10] ^ s[12], s[10], s[11]); s[11] = bitselect(s[11] ^ s[13], s[11], s[12]); s[12] = bitselect(s[12] ^ s[14], s[12], s[13]); s[13] = bitselect(s[13] ^ tmp1, s[13], s[14]); s[14] = bitselect(s[14] ^ tmp2, s[14], tmp1); + tmp1 = s[15]; tmp2 = s[16]; s[15] = bitselect(s[15] ^ s[17], s[15], s[16]); s[16] = bitselect(s[16] ^ s[18], s[16], s[17]); s[17] = bitselect(s[17] ^ s[19], s[17], s[18]); s[18] = bitselect(s[18] ^ tmp1, s[18], s[19]); s[19] = bitselect(s[19] ^ tmp2, s[19], tmp1); + tmp1 = s[20]; tmp2 = s[21]; s[20] = bitselect(s[20] ^ s[22], s[20], s[21]); s[21] = bitselect(s[21] ^ s[23], s[21], s[22]); s[22] = bitselect(s[22] ^ s[24], s[22], s[23]); s[23] = bitselect(s[23] ^ tmp1, s[23], s[24]); s[24] = bitselect(s[24] ^ tmp2, s[24], tmp1); + s[0] ^= keccakf_rndc[i]; + } +} + +static const __constant uint keccakf_rotc[24] = +{ + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 +}; + +static const __constant uint keccakf_piln[24] = +{ + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 +}; + +void keccakf1600_1(ulong *st) +{ + int i, round; + ulong t, bc[5]; + + #pragma unroll 1 + for(round = 0; round < 24; ++round) + { + + // Theta + bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20]; + bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21]; + bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22]; + bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23]; + bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24]; + + #pragma unroll 1 + for (i = 0; i < 5; ++i) { + t = bc[(i + 4) % 5] ^ rotate(bc[(i + 1) % 5], 1UL); + st[i ] ^= t; + st[i + 5] ^= t; + st[i + 10] ^= t; + st[i + 15] ^= t; + st[i + 20] ^= t; + } + + // Rho Pi + t = st[1]; + #pragma unroll + for (i = 0; i < 24; ++i) { + bc[0] = st[keccakf_piln[i]]; + st[keccakf_piln[i]] = rotate(t, (ulong)keccakf_rotc[i]); + t = bc[0]; + } + + //ulong tmp1 = st[0]; ulong tmp2 = st[1]; st[0] = bitselect(st[0] ^ st[2], st[0], st[1]); st[1] = bitselect(st[1] ^ st[3], st[1], st[2]); st[2] = bitselect(st[2] ^ st[4], st[2], st[3]); st[3] = bitselect(st[3] ^ tmp1, st[3], st[4]); st[4] = bitselect(st[4] ^ tmp2, st[4], tmp1); + //tmp1 = st[5]; tmp2 = st[6]; st[5] = bitselect(st[5] ^ st[7], st[5], st[6]); st[6] = bitselect(st[6] ^ st[8], st[6], st[7]); st[7] = bitselect(st[7] ^ st[9], st[7], st[8]); st[8] = bitselect(st[8] ^ tmp1, st[8], st[9]); st[9] = bitselect(st[9] ^ tmp2, st[9], tmp1); + //tmp1 = st[10]; tmp2 = st[11]; st[10] = bitselect(st[10] ^ st[12], st[10], st[11]); st[11] = bitselect(st[11] ^ st[13], st[11], st[12]); st[12] = bitselect(st[12] ^ st[14], st[12], st[13]); st[13] = bitselect(st[13] ^ tmp1, st[13], st[14]); st[14] = bitselect(st[14] ^ tmp2, st[14], tmp1); + //tmp1 = st[15]; tmp2 = st[16]; st[15] = bitselect(st[15] ^ st[17], st[15], st[16]); st[16] = bitselect(st[16] ^ st[18], st[16], st[17]); st[17] = bitselect(st[17] ^ st[19], st[17], st[18]); st[18] = bitselect(st[18] ^ tmp1, st[18], st[19]); st[19] = bitselect(st[19] ^ tmp2, st[19], tmp1); + //tmp1 = st[20]; tmp2 = st[21]; st[20] = bitselect(st[20] ^ st[22], st[20], st[21]); st[21] = bitselect(st[21] ^ st[23], st[21], st[22]); st[22] = bitselect(st[22] ^ st[24], st[22], st[23]); st[23] = bitselect(st[23] ^ tmp1, st[23], st[24]); st[24] = bitselect(st[24] ^ tmp2, st[24], tmp1); + + #pragma unroll 1 + for(int i = 0; i < 25; i += 5) + { + ulong tmp[5]; + + #pragma unroll 1 + for(int x = 0; x < 5; ++x) + tmp[x] = bitselect(st[i + x] ^ st[i + ((x + 2) % 5)], st[i + x], st[i + ((x + 1) % 5)]); + + #pragma unroll 1 + for(int x = 0; x < 5; ++x) st[i + x] = tmp[x]; + } + + // Iota + st[0] ^= keccakf_rndc[round]; + } +} + +void keccakf1600_2(ulong *st) +{ + int i, round; + ulong t, bc[5]; + + #pragma unroll 1 + for(round = 0; round < 24; ++round) + { + + // Theta + //bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20]; + //bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21]; + //bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22]; + //bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23]; + //bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24]; + + /* + #pragma unroll + for (i = 0; i < 5; ++i) { + t = bc[(i + 4) % 5] ^ rotate(bc[(i + 1) % 5], 1UL); + st[i ] ^= t; + st[i + 5] ^= t; + st[i + 10] ^= t; + st[i + 15] ^= t; + st[i + 20] ^= t; + } + */ + + bc[0] = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20] ^ rotate(st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22], 1UL); + bc[1] = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21] ^ rotate(st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23], 1UL); + bc[2] = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22] ^ rotate(st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24], 1UL); + bc[3] = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23] ^ rotate(st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20], 1UL); + bc[4] = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24] ^ rotate(st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21], 1UL); + + st[0] ^= bc[4]; + st[5] ^= bc[4]; + st[10] ^= bc[4]; + st[15] ^= bc[4]; + st[20] ^= bc[4]; + + st[1] ^= bc[0]; + st[6] ^= bc[0]; + st[11] ^= bc[0]; + st[16] ^= bc[0]; + st[21] ^= bc[0]; + + st[2] ^= bc[1]; + st[7] ^= bc[1]; + st[12] ^= bc[1]; + st[17] ^= bc[1]; + st[22] ^= bc[1]; + + st[3] ^= bc[2]; + st[8] ^= bc[2]; + st[13] ^= bc[2]; + st[18] ^= bc[2]; + st[23] ^= bc[2]; + + st[4] ^= bc[3]; + st[9] ^= bc[3]; + st[14] ^= bc[3]; + st[19] ^= bc[3]; + st[24] ^= bc[3]; + + // Rho Pi + t = st[1]; + #pragma unroll + for (i = 0; i < 24; ++i) { + bc[0] = st[keccakf_piln[i]]; + st[keccakf_piln[i]] = rotate(t, (ulong)keccakf_rotc[i]); + t = bc[0]; + } + + + + /*ulong tmp1 = st[1] ^ bc[0]; + + st[0] ^= bc[4]; + st[1] = rotate(st[6] ^ bc[0], 44UL); + st[6] = rotate(st[9] ^ bc[3], 20UL); + st[9] = rotate(st[22] ^ bc[1], 61UL); + st[22] = rotate(st[14] ^ bc[3], 39UL); + st[14] = rotate(st[20] ^ bc[4], 18UL); + st[20] = rotate(st[2] ^ bc[1], 62UL); + st[2] = rotate(st[12] ^ bc[1], 43UL); + st[12] = rotate(st[13] ^ bc[2], 25UL); + st[13] = rotate(st[19] ^ bc[3], 8UL); + st[19] = rotate(st[23] ^ bc[2], 56UL); + st[23] = rotate(st[15] ^ bc[4], 41UL); + st[15] = rotate(st[4] ^ bc[3], 27UL); + st[4] = rotate(st[24] ^ bc[3], 14UL); + st[24] = rotate(st[21] ^ bc[0], 2UL); + st[21] = rotate(st[8] ^ bc[2], 55UL); + st[8] = rotate(st[16] ^ bc[0], 35UL); + st[16] = rotate(st[5] ^ bc[4], 36UL); + st[5] = rotate(st[3] ^ bc[2], 28UL); + st[3] = rotate(st[18] ^ bc[2], 21UL); + st[18] = rotate(st[17] ^ bc[1], 15UL); + st[17] = rotate(st[11] ^ bc[0], 10UL); + st[11] = rotate(st[7] ^ bc[1], 6UL); + st[7] = rotate(st[10] ^ bc[4], 3UL); + st[10] = rotate(tmp1, 1UL); + */ + + + //ulong tmp1 = st[0]; ulong tmp2 = st[1]; st[0] = bitselect(st[0] ^ st[2], st[0], st[1]); st[1] = bitselect(st[1] ^ st[3], st[1], st[2]); st[2] = bitselect(st[2] ^ st[4], st[2], st[3]); st[3] = bitselect(st[3] ^ tmp1, st[3], st[4]); st[4] = bitselect(st[4] ^ tmp2, st[4], tmp1); + //tmp1 = st[5]; tmp2 = st[6]; st[5] = bitselect(st[5] ^ st[7], st[5], st[6]); st[6] = bitselect(st[6] ^ st[8], st[6], st[7]); st[7] = bitselect(st[7] ^ st[9], st[7], st[8]); st[8] = bitselect(st[8] ^ tmp1, st[8], st[9]); st[9] = bitselect(st[9] ^ tmp2, st[9], tmp1); + //tmp1 = st[10]; tmp2 = st[11]; st[10] = bitselect(st[10] ^ st[12], st[10], st[11]); st[11] = bitselect(st[11] ^ st[13], st[11], st[12]); st[12] = bitselect(st[12] ^ st[14], st[12], st[13]); st[13] = bitselect(st[13] ^ tmp1, st[13], st[14]); st[14] = bitselect(st[14] ^ tmp2, st[14], tmp1); + //tmp1 = st[15]; tmp2 = st[16]; st[15] = bitselect(st[15] ^ st[17], st[15], st[16]); st[16] = bitselect(st[16] ^ st[18], st[16], st[17]); st[17] = bitselect(st[17] ^ st[19], st[17], st[18]); st[18] = bitselect(st[18] ^ tmp1, st[18], st[19]); st[19] = bitselect(st[19] ^ tmp2, st[19], tmp1); + //tmp1 = st[20]; tmp2 = st[21]; st[20] = bitselect(st[20] ^ st[22], st[20], st[21]); st[21] = bitselect(st[21] ^ st[23], st[21], st[22]); st[22] = bitselect(st[22] ^ st[24], st[22], st[23]); st[23] = bitselect(st[23] ^ tmp1, st[23], st[24]); st[24] = bitselect(st[24] ^ tmp2, st[24], tmp1); + + #pragma unroll + for(int i = 0; i < 25; i += 5) + { + ulong tmp1 = st[i], tmp2 = st[i + 1]; + + st[i] = bitselect(st[i] ^ st[i + 2], st[i], st[i + 1]); + st[i + 1] = bitselect(st[i + 1] ^ st[i + 3], st[i + 1], st[i + 2]); + st[i + 2] = bitselect(st[i + 2] ^ st[i + 4], st[i + 2], st[i + 3]); + st[i + 3] = bitselect(st[i + 3] ^ tmp1, st[i + 3], st[i + 4]); + st[i + 4] = bitselect(st[i + 4] ^ tmp2, st[i + 4], tmp1); + } + + // Iota + st[0] ^= keccakf_rndc[round]; + } +} + +void CNKeccak(ulong *output, ulong *input) +{ + ulong st[25]; + + // Copy 72 bytes + for(int i = 0; i < 9; ++i) st[i] = input[i]; + + // Last four and '1' bit for padding + //st[9] = as_ulong((uint2)(((uint *)input)[18], 0x00000001U)); + + st[9] = (input[9] & 0x00000000FFFFFFFFUL) | 0x0000000100000000UL; + + for(int i = 10; i < 25; ++i) st[i] = 0x00UL; + + // Last bit of padding + st[16] = 0x8000000000000000UL; + + keccakf1600_1(st); + + for(int i = 0; i < 25; ++i) output[i] = st[i]; +} + +static const __constant uchar rcon[8] = { 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40 }; + +#define BYTE(x, y) (amd_bfe((x), (y) << 3U, 8U)) + +#define SubWord(inw) ((sbox[BYTE(inw, 3)] << 24) | (sbox[BYTE(inw, 2)] << 16) | (sbox[BYTE(inw, 1)] << 8) | sbox[BYTE(inw, 0)]) + +void AESExpandKey256(uint *keybuf) +{ + //#pragma unroll 4 + for(uint c = 8, i = 1; c < 60; ++c) + { + // For 256-bit keys, an sbox permutation is done every other 4th uint generated, AND every 8th + uint t = ((!(c & 7)) || ((c & 7) == 4)) ? SubWord(keybuf[c - 1]) : keybuf[c - 1]; + + // If the uint we're generating has an index that is a multiple of 8, rotate and XOR with the round constant, + // then XOR this with previously generated uint. If it's 4 after a multiple of 8, only the sbox permutation + // is done, followed by the XOR. If neither are true, only the XOR with the previously generated uint is done. + keybuf[c] = keybuf[c - 8] ^ ((!(c & 7)) ? rotate(t, 24U) ^ as_uint((uchar4)(rcon[i++], 0U, 0U, 0U)) : t); + } +} + +#define IDX(x) (x) + +__attribute__((reqd_work_group_size(WORKSIZE, 8, 1))) +__kernel void cn0(__global ulong *input, __global uint4 *Scratchpad, __global ulong *states) +{ + ulong State[25]; + uint ExpandedKey1[256]; + __local uint AES0[256], AES1[256], AES2[256], AES3[256]; + uint4 text; + + states += (25 * (get_global_id(0) - get_global_offset(0))); + Scratchpad += ((get_global_id(0) - get_global_offset(0))) * (0x80000 >> 2); + + for(int i = get_local_id(0); i < 256; i += WORKSIZE) + { + const uint tmp = AES0_C[i]; + AES0[i] = tmp; + AES1[i] = rotate(tmp, 8U); + AES2[i] = rotate(tmp, 16U); + AES3[i] = rotate(tmp, 24U); + } + barrier(CLK_LOCAL_MEM_FENCE); + + ((ulong8 *)State)[0] = vload8(0, input); + State[8] = input[8]; + State[9] = input[9]; + State[10] = input[10]; + + ((uint *)State)[9] &= 0x00FFFFFFU; + ((uint *)State)[9] |= ((get_global_id(0)) & 0xFF) << 24; + ((uint *)State)[10] &= 0xFF000000U; + ((uint *)State)[10] |= ((get_global_id(0) >> 8)); + + for(int i = 11; i < 25; ++i) State[i] = 0x00UL; + + // Last bit of padding + State[16] = 0x8000000000000000UL; + + keccakf1600_2(State); + + mem_fence(CLK_GLOBAL_MEM_FENCE); + + #pragma unroll + for(int i = 0; i < 25; ++i) states[i] = State[i]; + + text = vload4(get_local_id(1) + 4, (__global uint *)(states)); + + #pragma unroll + for(int i = 0; i < 4; ++i) ((ulong *)ExpandedKey1)[i] = states[i]; + + AESExpandKey256(ExpandedKey1); + + mem_fence(CLK_LOCAL_MEM_FENCE); + + #pragma unroll 2 + for(int i = 0; i < 0x4000; ++i) + { + #pragma unroll + for(int j = 0; j < 10; ++j) + text = AES_Round(AES0, AES1, AES2, AES3, text, ((uint4 *)ExpandedKey1)[j]); + + Scratchpad[IDX((i << 3) + get_local_id(1))] = text; + } + + mem_fence(CLK_GLOBAL_MEM_FENCE); +} + +__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) +__kernel void cn1(__global uint4 *Scratchpad, __global ulong *states) +{ + ulong a[2], b[2]; + __local uint AES0[256], AES1[256], AES2[256], AES3[256]; + + Scratchpad += ((get_global_id(0) - get_global_offset(0))) * (0x80000 >> 2); + states += (25 * (get_global_id(0) - get_global_offset(0))); + + for(int i = get_local_id(0); i < 256; i += WORKSIZE) + { + const uint tmp = AES0_C[i]; + AES0[i] = tmp; + AES1[i] = rotate(tmp, 8U); + AES2[i] = rotate(tmp, 16U); + AES3[i] = rotate(tmp, 24U); + } + barrier(CLK_LOCAL_MEM_FENCE); + + a[0] = states[0] ^ states[4]; + b[0] = states[2] ^ states[6]; + a[1] = states[1] ^ states[5]; + b[1] = states[3] ^ states[7]; + + uint4 b_x = ((uint4 *)b)[0]; + + mem_fence(CLK_LOCAL_MEM_FENCE); + + #pragma unroll 8 + for(int i = 0; i < 0x80000; ++i) + { + ulong c[2]; + + ((uint4 *)c)[0] = Scratchpad[IDX((a[0] & 0x1FFFF0) >> 4)]; + ((uint4 *)c)[0] = AES_Round(AES0, AES1, AES2, AES3, ((uint4 *)c)[0], ((uint4 *)a)[0]); + //b_x ^= ((uint4 *)c)[0]; + + Scratchpad[IDX((a[0] & 0x1FFFF0) >> 4)] = b_x ^ ((uint4 *)c)[0]; + + uint4 tmp; + tmp = Scratchpad[IDX((c[0] & 0x1FFFF0) >> 4)]; + + a[1] += c[0] * as_ulong2(tmp).s0; + a[0] += mul_hi(c[0], as_ulong2(tmp).s0); + + Scratchpad[IDX((c[0] & 0x1FFFF0) >> 4)] = ((uint4 *)a)[0]; + + ((uint4 *)a)[0] ^= tmp; + + b_x = ((uint4 *)c)[0]; + } + + mem_fence(CLK_GLOBAL_MEM_FENCE); +} + +__attribute__((reqd_work_group_size(WORKSIZE, 8, 1))) +__kernel void cn2(__global uint4 *Scratchpad, __global ulong *states, __global uint *Branch0, __global uint *Branch1, __global uint *Branch2, __global uint *Branch3) +{ + __local uint AES0[256], AES1[256], AES2[256], AES3[256]; + uint ExpandedKey2[256]; + ulong State[25]; + uint4 text; + + Scratchpad += ((get_global_id(0) - get_global_offset(0))) * (0x80000 >> 2); + states += (25 * (get_global_id(0) - get_global_offset(0))); + + for(int i = get_local_id(0); i < 256; i += WORKSIZE) + { + const uint tmp = AES0_C[i]; + AES0[i] = tmp; + AES1[i] = rotate(tmp, 8U); + AES2[i] = rotate(tmp, 16U); + AES3[i] = rotate(tmp, 24U); + } + barrier(CLK_LOCAL_MEM_FENCE); + + #if defined(__Tahiti__) || defined(__Pitcairn__) + + for(int i = 0; i < 4; ++i) ((ulong *)ExpandedKey2)[i] = states[i + 4]; + text = vload4(get_local_id(1) + 4, (__global uint *)states); + + #else + + text = vload4(get_local_id(1) + 4, (__global uint *)states); + ((uint8 *)ExpandedKey2)[0] = vload8(1, (__global uint *)states); + + #endif + + AESExpandKey256(ExpandedKey2); + + barrier(CLK_LOCAL_MEM_FENCE); + + #pragma unroll 2 + for(int i = 0; i < 0x4000; ++i) + { + text ^= Scratchpad[IDX((i << 3) + get_local_id(1))]; + + #pragma unroll + for(int j = 0; j < 10; ++j) + text = AES_Round(AES0, AES1, AES2, AES3, text, ((uint4 *)ExpandedKey2)[j]); + } + + vstore2(as_ulong2(text), get_local_id(1) + 4, states); + + barrier(CLK_GLOBAL_MEM_FENCE); + + if(!get_local_id(1)) + { + for(int i = 0; i < 25; ++i) State[i] = states[i]; + + keccakf1600_2(State); + + for(int i = 0; i < 25; ++i) states[i] = State[i]; + + switch(State[0] & 3) + { + case 0: + Branch0[atomic_inc(Branch0 + get_global_size(0))] = get_global_id(0) - get_global_offset(0); + break; + case 1: + Branch1[atomic_inc(Branch1 + get_global_size(0))] = get_global_id(0) - get_global_offset(0); + break; + case 2: + Branch2[atomic_inc(Branch2 + get_global_size(0))] = get_global_id(0) - get_global_offset(0); + break; + case 3: + Branch3[atomic_inc(Branch3 + get_global_size(0))] = get_global_id(0) - get_global_offset(0); + break; + } + } + + mem_fence(CLK_GLOBAL_MEM_FENCE); +} + +/* +__kernel void cryptonight(__global ulong *input, __global uint4 *Scratchpad, __global ulong *states, __global uint *Branch0, __global uint *Branch1, __global uint *Branch2, __global uint *Branch3, ulong ThreadCount) +{ + uchar State[200]; + __local uint AES0[256], AES1[256], AES2[256], AES3[256]; + uchar ExpandedKey1[256], ExpandedKey2[256]; + ulong inbuf[10], a[2], b[2]; + uint4 text[8]; + + for(int i = 0; i < 256; ++i) + { + const uint tmp = AES0_C[i]; + AES0[i] = tmp; + AES1[i] = rotate(tmp, 8U); + AES2[i] = rotate(tmp, 16U); + AES3[i] = rotate(tmp, 24U); + } + + ((ulong8 *)inbuf)[0] = vload8(0, input); + inbuf[8] = input[8]; + inbuf[9] = (ulong)((__global uint *)input)[18]; + + ((uint *)(((uchar *)inbuf) + 39))[0] = get_global_id(0); + CNKeccak((ulong *)State, inbuf); + + a[0] = ((ulong *)State)[0] ^ ((ulong *)State)[4]; + b[0] = ((ulong *)State)[2] ^ ((ulong *)State)[6]; + a[1] = ((ulong *)State)[1] ^ ((ulong *)State)[5]; + b[1] = ((ulong *)State)[3] ^ ((ulong *)State)[7]; + + for(uint i = 0; i < 8; ++i) text[i] = vload4(i + 4, (uint *)(State)); + + for(int i = 0; i < 4; ++i) ((ulong *)ExpandedKey1)[i] = ((ulong *)State)[i]; + for(int i = 0; i < 4; ++i) ((ulong *)ExpandedKey2)[i] = ((ulong *)State)[i + 4]; + + AESExpandKey256(ExpandedKey1); + AESExpandKey256(ExpandedKey2); + + mem_fence(CLK_LOCAL_MEM_FENCE); + + Scratchpad += ((1 << 17) * (get_global_id(0) - get_global_offset(0))); + + //#pragma unroll 1 + for(int i = 0; i < (1 << 17); i += 8) + { + #pragma unroll + for(int j = 0; j < 10; ++j) + { + #pragma unroll + for(int x = 0; x < 8; ++x) + text[x] = AES_Round(AES0, AES1, AES2, AES3, text[x], ((uint4 *)ExpandedKey1)[j]); + } + + for(int j = 0; j < 8; ++j) *(Scratchpad + i + j) = text[j]; + } + + + uint4 b_x = ((uint4 *)b)[0]; + + //#pragma unroll 1 + for(int i = 0; i < 0x80000; ++i) + { + ulong c[2]; + + ((uint4 *)c)[0] = Scratchpad[(a[0] & 0x1FFFF0) >> 4]; + ((uint4 *)c)[0] = AES_Round(AES0, AES1, AES2, AES3, ((uint4 *)c)[0], ((uint4 *)a)[0]); + b_x ^= ((uint4 *)c)[0]; + + Scratchpad[(a[0] & 0x1FFFF0) >> 4] = b_x; + + uint4 tmp; + tmp = Scratchpad[(c[0] & 0x1FFFF0) >> 4]; + + a[1] += c[0] * as_ulong2(tmp).s0; + a[0] += mul_hi(c[0], as_ulong2(tmp).s0); + + Scratchpad[(c[0] & 0x1FFFF0) >> 4] = ((uint4 *)a)[0]; + + ((uint4 *)a)[0] ^= tmp; + + b_x = ((uint4 *)c)[0]; + } + + for(uint i = 0; i < 8; ++i) text[i] = vload4(i + 4, (uint *)(State)); + + for(int i = 0; i < (1 << 17); i += 8) + { + #pragma unroll + for(int j = 0; j < 8; ++j) text[j] ^= Scratchpad[i + j]; + + #pragma unroll 1 + for(int j = 0; j < 10; ++j) + { + #pragma unroll + for(int x = 0; x < 8; ++x) + text[x] = AES_Round(AES0, AES1, AES2, AES3, text[x], ((uint4 *)ExpandedKey2)[j]); + } + } + + for(uint i = 0; i < 8; ++i) vstore4(text[i], i + 4, (uint *)(State)); + + keccakf1600((ulong *)State); + + states += (25 * (get_global_id(0) - get_global_offset(0))); + + for(int i = 0; i < 25; ++i) states[i] = ((ulong *)State)[i]; + + switch(State[0] & 3) + { + case 0: + Branch0[atomic_inc(Branch0 + ThreadCount)] = get_global_id(0) - get_global_offset(0); + break; + case 1: + Branch1[atomic_inc(Branch1 + ThreadCount)] = get_global_id(0) - get_global_offset(0); + break; + case 2: + Branch2[atomic_inc(Branch2 + ThreadCount)] = get_global_id(0) - get_global_offset(0); + break; + case 3: + Branch3[atomic_inc(Branch3 + ThreadCount)] = get_global_id(0) - get_global_offset(0); + break; + } +} +*/ + +#define VSWAP8(x) (((x) >> 56) | (((x) >> 40) & 0x000000000000FF00UL) | (((x) >> 24) & 0x0000000000FF0000UL) \ + | (((x) >> 8) & 0x00000000FF000000UL) | (((x) << 8) & 0x000000FF00000000UL) \ + | (((x) << 24) & 0x0000FF0000000000UL) | (((x) << 40) & 0x00FF000000000000UL) | (((x) << 56) & 0xFF00000000000000UL)) + +#define VSWAP4(x) ((((x) >> 24) & 0xFFU) | (((x) >> 8) & 0xFF00U) | (((x) << 8) & 0xFF0000U) | (((x) << 24) & 0xFF000000U)) + +__kernel void Skein(__global ulong *states, __global uint *BranchBuf, __global uint *output, uint Target, ulong Threads) +{ + const ulong idx = get_global_id(0) - get_global_offset(0); + + if(idx >= Threads) return; + + states += 25 * BranchBuf[idx]; + + // skein + ulong8 h = vload8(0, SKEIN512_256_IV); + + // Type field begins with final bit, first bit, then six bits of type; the last 96 + // bits are input processed (including in the block to be processed with that tweak) + // The output transform is only one run of UBI, since we need only 256 bits of output + // The tweak for the output transform is Type = Output with the Final bit set + // T[0] for the output is 8, and I don't know why - should be message size... + ulong t[3] = { 0x00UL, 0x7000000000000000UL, 0x00UL }; + ulong8 p, m; + + for(uint i = 0; i < 4; ++i) + { + if(i < 3) t[0] += 0x40UL; + else t[0] += 0x08UL; + + t[2] = t[0] ^ t[1]; + + m = (i < 3) ? vload8(i, states) : (ulong8)(states[24], 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL); + const ulong h8 = h.s0 ^ h.s1 ^ h.s2 ^ h.s3 ^ h.s4 ^ h.s5 ^ h.s6 ^ h.s7 ^ SKEIN_KS_PARITY; + p = Skein512Block(m, h, h8, t); + + h = m ^ p; + + if(i < 2) t[1] = 0x3000000000000000UL; + else t[1] = 0xB000000000000000UL; + } + + t[0] = 0x08UL; + t[1] = 0xFF00000000000000UL; + t[2] = t[0] ^ t[1]; + + p = (ulong8)(0); + const ulong h8 = h.s0 ^ h.s1 ^ h.s2 ^ h.s3 ^ h.s4 ^ h.s5 ^ h.s6 ^ h.s7 ^ SKEIN_KS_PARITY; + + p = Skein512Block(p, h, h8, t); + + //vstore8(p, 0, output); + + if(as_uint16(p).s7 <= Target) output[atomic_inc(output + 0xFF)] = BranchBuf[idx] + get_global_offset(0); + + mem_fence(CLK_GLOBAL_MEM_FENCE); +} + +#define SWAP8(x) as_ulong(as_uchar8(x).s76543210) + +__kernel void JH(__global ulong *states, __global uint *BranchBuf, __global uint *output, uint Target, ulong Threads) +{ + const uint idx = get_global_id(0) - get_global_offset(0); + + if(idx >= Threads) return; + + states += 25 * BranchBuf[idx]; + + sph_u64 h0h = 0xEBD3202C41A398EBUL, h0l = 0xC145B29C7BBECD92UL, h1h = 0xFAC7D4609151931CUL, h1l = 0x038A507ED6820026UL, h2h = 0x45B92677269E23A4UL, h2l = 0x77941AD4481AFBE0UL, h3h = 0x7A176B0226ABB5CDUL, h3l = 0xA82FFF0F4224F056UL; + sph_u64 h4h = 0x754D2E7F8996A371UL, h4l = 0x62E27DF70849141DUL, h5h = 0x948F2476F7957627UL, h5l = 0x6C29804757B6D587UL, h6h = 0x6C0D8EAC2D275E5CUL, h6l = 0x0F7A0557C6508451UL, h7h = 0xEA12247067D3E47BUL, h7l = 0x69D71CD313ABE389UL; + sph_u64 tmp; + + for(int i = 0; i < 5; ++i) + { + ulong input[8]; + + if(i < 3) + { + for(int x = 0; x < 8; ++x) input[x] = (states[(i << 3) + x]); + } + else if(i == 3) + { + input[0] = (states[24]); + input[1] = 0x80UL; + for(int x = 2; x < 8; ++x) input[x] = 0x00UL; + } + else + { + input[7] = 0x4006000000000000UL; + + for(int x = 0; x < 7; ++x) input[x] = 0x00UL; + } + + h0h ^= input[0]; + h0l ^= input[1]; + h1h ^= input[2]; + h1l ^= input[3]; + h2h ^= input[4]; + h2l ^= input[5]; + h3h ^= input[6]; + h3l ^= input[7]; + + E8; + + h4h ^= input[0]; + h4l ^= input[1]; + h5h ^= input[2]; + h5l ^= input[3]; + h6h ^= input[4]; + h6l ^= input[5]; + h7h ^= input[6]; + h7l ^= input[7]; + } + + //output[0] = h6h; + //output[1] = h6l; + //output[2] = h7h; + //output[3] = h7l; + + if(as_uint2(h7l).s1 <= Target) output[atomic_inc(output + 0xFF)] = BranchBuf[idx] + get_global_offset(0); +} + +#define SWAP4(x) as_uint(as_uchar4(x).s3210) + +__kernel void Blake(__global ulong *states, __global uint *BranchBuf, __global uint *output, uint Target, ulong Threads) +{ + const uint idx = get_global_id(0) - get_global_offset(0); + + if(idx >= Threads) return; + + states += 25 * BranchBuf[idx]; + + unsigned int m[16]; + unsigned int v[16]; + uint h[8]; + + ((uint8 *)h)[0] = vload8(0U, c_IV256); + + for(uint i = 0, bitlen = 0; i < 4; ++i) + { + if(i < 3) + { + ((uint16 *)m)[0] = vload16(i, (__global uint *)states); + for(int i = 0; i < 16; ++i) m[i] = SWAP4(m[i]); + bitlen += 512; + } + else + { + m[0] = SWAP4(((__global uint *)states)[48]); + m[1] = SWAP4(((__global uint *)states)[49]); + m[2] = 0x80000000U; + + for(int i = 3; i < 13; ++i) m[i] = 0x00U; + + m[13] = 1U; + m[14] = 0U; + m[15] = 0x640; + bitlen += 64; + } + + ((uint16 *)v)[0].lo = ((uint8 *)h)[0]; + ((uint16 *)v)[0].hi = vload8(0U, c_u256); + + //v[12] ^= (i < 3) ? (i + 1) << 9 : 1600U; + //v[13] ^= (i < 3) ? (i + 1) << 9 : 1600U; + + v[12] ^= bitlen; + v[13] ^= bitlen; + + for(int r = 0; r < 14; r++) + { + GS(0, 4, 0x8, 0xC, 0x0); + GS(1, 5, 0x9, 0xD, 0x2); + GS(2, 6, 0xA, 0xE, 0x4); + GS(3, 7, 0xB, 0xF, 0x6); + GS(0, 5, 0xA, 0xF, 0x8); + GS(1, 6, 0xB, 0xC, 0xA); + GS(2, 7, 0x8, 0xD, 0xC); + GS(3, 4, 0x9, 0xE, 0xE); + } + + ((uint8 *)h)[0] ^= ((uint8 *)v)[0] ^ ((uint8 *)v)[1]; + } + + for(int i = 0; i < 8; ++i) h[i] = SWAP4(h[i]); + + //for(int i = 0; i < 4; ++i) output[i] = ((ulong *)h)[i]; + if(h[7] <= Target) output[atomic_inc(output + 0xFF)] = BranchBuf[idx] + get_global_offset(0); +} + +__kernel void Groestl(__global ulong *states, __global uint *BranchBuf, __global uint *output, uint Target, ulong Threads) +{ + const uint idx = get_global_id(0) - get_global_offset(0); + + if(idx >= Threads) return; + + states += 25 * BranchBuf[idx]; + + ulong State[8]; + + for(int i = 0; i < 7; ++i) State[i] = 0UL; + + State[7] = 0x0001000000000000UL; + + for(uint i = 0; i < 4; ++i) + { + ulong H[8], M[8]; + + if(i < 3) + { + ((ulong8 *)M)[0] = vload8(i, states); + } + else + { + M[0] = states[24]; + M[1] = 0x80UL; + + for(int x = 2; x < 7; ++x) M[x] = 0UL; + + M[7] = 0x0400000000000000UL; + } + + for(int x = 0; x < 8; ++x) H[x] = M[x] ^ State[x]; + + PERM_SMALL_P(H); + PERM_SMALL_Q(M); + + for(int x = 0; x < 8; ++x) State[x] ^= H[x] ^ M[x]; + } + + ulong tmp[8]; + + for(int i = 0; i < 8; ++i) tmp[i] = State[i]; + + PERM_SMALL_P(State); + + for(int i = 0; i < 8; ++i) State[i] ^= tmp[i]; + + //for(int i = 0; i < 4; ++i) output[i] = State[i + 4]; + if(as_uint2(State[7]).s1 <= Target) output[atomic_inc(output + 0xFF)] = BranchBuf[idx] + get_global_offset(0); +} diff --git a/opencl/groestl256.cl b/opencl/groestl256.cl new file mode 100644 index 0000000..1139c4d --- /dev/null +++ b/opencl/groestl256.cl @@ -0,0 +1,289 @@ +/* $Id: groestl.c 260 2011-07-21 01:02:38Z tp $ */ +/* + * Groestl256 + * + * ==========================(LICENSE BEGIN)============================ + * Copyright (c) 2014 djm34 + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#define SPH_C64(x) x +#define SPH_ROTL64(x, y) rotate((x), (ulong)(y)) + + +#define C64e(x) ((SPH_C64(x) >> 56) \ + | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) \ + | ((SPH_C64(x) >> 24) & SPH_C64(0x0000000000FF0000)) \ + | ((SPH_C64(x) >> 8) & SPH_C64(0x00000000FF000000)) \ + | ((SPH_C64(x) << 8) & SPH_C64(0x000000FF00000000)) \ + | ((SPH_C64(x) << 24) & SPH_C64(0x0000FF0000000000)) \ + | ((SPH_C64(x) << 40) & SPH_C64(0x00FF000000000000)) \ + | ((SPH_C64(x) << 56) & SPH_C64(0xFF00000000000000))) + +#define B64_0(x) ((x) & 0xFF) +#define B64_1(x) (((x) >> 8) & 0xFF) +#define B64_2(x) (((x) >> 16) & 0xFF) +#define B64_3(x) (((x) >> 24) & 0xFF) +#define B64_4(x) (((x) >> 32) & 0xFF) +#define B64_5(x) (((x) >> 40) & 0xFF) +#define B64_6(x) (((x) >> 48) & 0xFF) +#define B64_7(x) ((x) >> 56) +#define R64 SPH_ROTL64 +#define PC64(j, r) ((sph_u64)((j) + (r))) +#define QC64(j, r) (((sph_u64)(r) << 56) ^ (~((sph_u64)(j) << 56))) + +static const __constant ulong T0_G[] = +{ + 0xc6a597f4a5f432c6UL, 0xf884eb9784976ff8UL, 0xee99c7b099b05eeeUL, 0xf68df78c8d8c7af6UL, + 0xff0de5170d17e8ffUL, 0xd6bdb7dcbddc0ad6UL, 0xdeb1a7c8b1c816deUL, 0x915439fc54fc6d91UL, + 0x6050c0f050f09060UL, 0x0203040503050702UL, 0xcea987e0a9e02eceUL, 0x567dac877d87d156UL, + 0xe719d52b192bcce7UL, 0xb56271a662a613b5UL, 0x4de69a31e6317c4dUL, 0xec9ac3b59ab559ecUL, + 0x8f4505cf45cf408fUL, 0x1f9d3ebc9dbca31fUL, 0x894009c040c04989UL, 0xfa87ef92879268faUL, + 0xef15c53f153fd0efUL, 0xb2eb7f26eb2694b2UL, 0x8ec90740c940ce8eUL, 0xfb0bed1d0b1de6fbUL, + 0x41ec822fec2f6e41UL, 0xb3677da967a91ab3UL, 0x5ffdbe1cfd1c435fUL, 0x45ea8a25ea256045UL, + 0x23bf46dabfdaf923UL, 0x53f7a602f7025153UL, 0xe496d3a196a145e4UL, 0x9b5b2ded5bed769bUL, + 0x75c2ea5dc25d2875UL, 0xe11cd9241c24c5e1UL, 0x3dae7ae9aee9d43dUL, 0x4c6a98be6abef24cUL, + 0x6c5ad8ee5aee826cUL, 0x7e41fcc341c3bd7eUL, 0xf502f1060206f3f5UL, 0x834f1dd14fd15283UL, + 0x685cd0e45ce48c68UL, 0x51f4a207f4075651UL, 0xd134b95c345c8dd1UL, 0xf908e9180818e1f9UL, + 0xe293dfae93ae4ce2UL, 0xab734d9573953eabUL, 0x6253c4f553f59762UL, 0x2a3f54413f416b2aUL, + 0x080c10140c141c08UL, 0x955231f652f66395UL, 0x46658caf65afe946UL, 0x9d5e21e25ee27f9dUL, + 0x3028607828784830UL, 0x37a16ef8a1f8cf37UL, 0x0a0f14110f111b0aUL, 0x2fb55ec4b5c4eb2fUL, + 0x0e091c1b091b150eUL, 0x2436485a365a7e24UL, 0x1b9b36b69bb6ad1bUL, 0xdf3da5473d4798dfUL, + 0xcd26816a266aa7cdUL, 0x4e699cbb69bbf54eUL, 0x7fcdfe4ccd4c337fUL, 0xea9fcfba9fba50eaUL, + 0x121b242d1b2d3f12UL, 0x1d9e3ab99eb9a41dUL, 0x5874b09c749cc458UL, 0x342e68722e724634UL, + 0x362d6c772d774136UL, 0xdcb2a3cdb2cd11dcUL, 0xb4ee7329ee299db4UL, 0x5bfbb616fb164d5bUL, + 0xa4f65301f601a5a4UL, 0x764decd74dd7a176UL, 0xb76175a361a314b7UL, 0x7dcefa49ce49347dUL, + 0x527ba48d7b8ddf52UL, 0xdd3ea1423e429fddUL, 0x5e71bc937193cd5eUL, 0x139726a297a2b113UL, + 0xa6f55704f504a2a6UL, 0xb96869b868b801b9UL, 0x0000000000000000UL, 0xc12c99742c74b5c1UL, + 0x406080a060a0e040UL, 0xe31fdd211f21c2e3UL, 0x79c8f243c8433a79UL, 0xb6ed772ced2c9ab6UL, + 0xd4beb3d9bed90dd4UL, 0x8d4601ca46ca478dUL, 0x67d9ce70d9701767UL, 0x724be4dd4bddaf72UL, + 0x94de3379de79ed94UL, 0x98d42b67d467ff98UL, 0xb0e87b23e82393b0UL, 0x854a11de4ade5b85UL, + 0xbb6b6dbd6bbd06bbUL, 0xc52a917e2a7ebbc5UL, 0x4fe59e34e5347b4fUL, 0xed16c13a163ad7edUL, + 0x86c51754c554d286UL, 0x9ad72f62d762f89aUL, 0x6655ccff55ff9966UL, 0x119422a794a7b611UL, + 0x8acf0f4acf4ac08aUL, 0xe910c9301030d9e9UL, 0x0406080a060a0e04UL, 0xfe81e798819866feUL, + 0xa0f05b0bf00baba0UL, 0x7844f0cc44ccb478UL, 0x25ba4ad5bad5f025UL, 0x4be3963ee33e754bUL, + 0xa2f35f0ef30eaca2UL, 0x5dfeba19fe19445dUL, 0x80c01b5bc05bdb80UL, 0x058a0a858a858005UL, + 0x3fad7eecadecd33fUL, 0x21bc42dfbcdffe21UL, 0x7048e0d848d8a870UL, 0xf104f90c040cfdf1UL, + 0x63dfc67adf7a1963UL, 0x77c1ee58c1582f77UL, 0xaf75459f759f30afUL, 0x426384a563a5e742UL, + 0x2030405030507020UL, 0xe51ad12e1a2ecbe5UL, 0xfd0ee1120e12effdUL, 0xbf6d65b76db708bfUL, + 0x814c19d44cd45581UL, 0x1814303c143c2418UL, 0x26354c5f355f7926UL, 0xc32f9d712f71b2c3UL, + 0xbee16738e13886beUL, 0x35a26afda2fdc835UL, 0x88cc0b4fcc4fc788UL, 0x2e395c4b394b652eUL, + 0x93573df957f96a93UL, 0x55f2aa0df20d5855UL, 0xfc82e39d829d61fcUL, 0x7a47f4c947c9b37aUL, + 0xc8ac8befacef27c8UL, 0xbae76f32e73288baUL, 0x322b647d2b7d4f32UL, 0xe695d7a495a442e6UL, + 0xc0a09bfba0fb3bc0UL, 0x199832b398b3aa19UL, 0x9ed12768d168f69eUL, 0xa37f5d817f8122a3UL, + 0x446688aa66aaee44UL, 0x547ea8827e82d654UL, 0x3bab76e6abe6dd3bUL, 0x0b83169e839e950bUL, + 0x8cca0345ca45c98cUL, 0xc729957b297bbcc7UL, 0x6bd3d66ed36e056bUL, 0x283c50443c446c28UL, + 0xa779558b798b2ca7UL, 0xbce2633de23d81bcUL, 0x161d2c271d273116UL, 0xad76419a769a37adUL, + 0xdb3bad4d3b4d96dbUL, 0x6456c8fa56fa9e64UL, 0x744ee8d24ed2a674UL, 0x141e28221e223614UL, + 0x92db3f76db76e492UL, 0x0c0a181e0a1e120cUL, 0x486c90b46cb4fc48UL, 0xb8e46b37e4378fb8UL, + 0x9f5d25e75de7789fUL, 0xbd6e61b26eb20fbdUL, 0x43ef862aef2a6943UL, 0xc4a693f1a6f135c4UL, + 0x39a872e3a8e3da39UL, 0x31a462f7a4f7c631UL, 0xd337bd5937598ad3UL, 0xf28bff868b8674f2UL, + 0xd532b156325683d5UL, 0x8b430dc543c54e8bUL, 0x6e59dceb59eb856eUL, 0xdab7afc2b7c218daUL, + 0x018c028f8c8f8e01UL, 0xb16479ac64ac1db1UL, 0x9cd2236dd26df19cUL, 0x49e0923be03b7249UL, + 0xd8b4abc7b4c71fd8UL, 0xacfa4315fa15b9acUL, 0xf307fd090709faf3UL, 0xcf25856f256fa0cfUL, + 0xcaaf8feaafea20caUL, 0xf48ef3898e897df4UL, 0x47e98e20e9206747UL, 0x1018202818283810UL, + 0x6fd5de64d5640b6fUL, 0xf088fb83888373f0UL, 0x4a6f94b16fb1fb4aUL, 0x5c72b8967296ca5cUL, + 0x3824706c246c5438UL, 0x57f1ae08f1085f57UL, 0x73c7e652c7522173UL, 0x975135f351f36497UL, + 0xcb238d652365aecbUL, 0xa17c59847c8425a1UL, 0xe89ccbbf9cbf57e8UL, 0x3e217c6321635d3eUL, + 0x96dd377cdd7cea96UL, 0x61dcc27fdc7f1e61UL, 0x0d861a9186919c0dUL, 0x0f851e9485949b0fUL, + 0xe090dbab90ab4be0UL, 0x7c42f8c642c6ba7cUL, 0x71c4e257c4572671UL, 0xccaa83e5aae529ccUL, + 0x90d83b73d873e390UL, 0x06050c0f050f0906UL, 0xf701f5030103f4f7UL, 0x1c12383612362a1cUL, + 0xc2a39ffea3fe3cc2UL, 0x6a5fd4e15fe18b6aUL, 0xaef94710f910beaeUL, 0x69d0d26bd06b0269UL, + 0x17912ea891a8bf17UL, 0x995829e858e87199UL, 0x3a2774692769533aUL, 0x27b94ed0b9d0f727UL, + 0xd938a948384891d9UL, 0xeb13cd351335deebUL, 0x2bb356ceb3cee52bUL, 0x2233445533557722UL, + 0xd2bbbfd6bbd604d2UL, 0xa9704990709039a9UL, 0x07890e8089808707UL, 0x33a766f2a7f2c133UL, + 0x2db65ac1b6c1ec2dUL, 0x3c22786622665a3cUL, 0x15922aad92adb815UL, 0xc92089602060a9c9UL, + 0x874915db49db5c87UL, 0xaaff4f1aff1ab0aaUL, 0x5078a0887888d850UL, 0xa57a518e7a8e2ba5UL, + 0x038f068a8f8a8903UL, 0x59f8b213f8134a59UL, 0x0980129b809b9209UL, 0x1a1734391739231aUL, + 0x65daca75da751065UL, 0xd731b553315384d7UL, 0x84c61351c651d584UL, 0xd0b8bbd3b8d303d0UL, + 0x82c31f5ec35edc82UL, 0x29b052cbb0cbe229UL, 0x5a77b4997799c35aUL, 0x1e113c3311332d1eUL, + 0x7bcbf646cb463d7bUL, 0xa8fc4b1ffc1fb7a8UL, 0x6dd6da61d6610c6dUL, 0x2c3a584e3a4e622cUL +}; + +static const __constant ulong T4_G[] = +{ + 0xA5F432C6C6A597F4UL, 0x84976FF8F884EB97UL, 0x99B05EEEEE99C7B0UL, 0x8D8C7AF6F68DF78CUL, + 0x0D17E8FFFF0DE517UL, 0xBDDC0AD6D6BDB7DCUL, 0xB1C816DEDEB1A7C8UL, 0x54FC6D91915439FCUL, + 0x50F090606050C0F0UL, 0x0305070202030405UL, 0xA9E02ECECEA987E0UL, 0x7D87D156567DAC87UL, + 0x192BCCE7E719D52BUL, 0x62A613B5B56271A6UL, 0xE6317C4D4DE69A31UL, 0x9AB559ECEC9AC3B5UL, + 0x45CF408F8F4505CFUL, 0x9DBCA31F1F9D3EBCUL, 0x40C04989894009C0UL, 0x879268FAFA87EF92UL, + 0x153FD0EFEF15C53FUL, 0xEB2694B2B2EB7F26UL, 0xC940CE8E8EC90740UL, 0x0B1DE6FBFB0BED1DUL, + 0xEC2F6E4141EC822FUL, 0x67A91AB3B3677DA9UL, 0xFD1C435F5FFDBE1CUL, 0xEA25604545EA8A25UL, + 0xBFDAF92323BF46DAUL, 0xF702515353F7A602UL, 0x96A145E4E496D3A1UL, 0x5BED769B9B5B2DEDUL, + 0xC25D287575C2EA5DUL, 0x1C24C5E1E11CD924UL, 0xAEE9D43D3DAE7AE9UL, 0x6ABEF24C4C6A98BEUL, + 0x5AEE826C6C5AD8EEUL, 0x41C3BD7E7E41FCC3UL, 0x0206F3F5F502F106UL, 0x4FD15283834F1DD1UL, + 0x5CE48C68685CD0E4UL, 0xF407565151F4A207UL, 0x345C8DD1D134B95CUL, 0x0818E1F9F908E918UL, + 0x93AE4CE2E293DFAEUL, 0x73953EABAB734D95UL, 0x53F597626253C4F5UL, 0x3F416B2A2A3F5441UL, + 0x0C141C08080C1014UL, 0x52F66395955231F6UL, 0x65AFE94646658CAFUL, 0x5EE27F9D9D5E21E2UL, + 0x2878483030286078UL, 0xA1F8CF3737A16EF8UL, 0x0F111B0A0A0F1411UL, 0xB5C4EB2F2FB55EC4UL, + 0x091B150E0E091C1BUL, 0x365A7E242436485AUL, 0x9BB6AD1B1B9B36B6UL, 0x3D4798DFDF3DA547UL, + 0x266AA7CDCD26816AUL, 0x69BBF54E4E699CBBUL, 0xCD4C337F7FCDFE4CUL, 0x9FBA50EAEA9FCFBAUL, + 0x1B2D3F12121B242DUL, 0x9EB9A41D1D9E3AB9UL, 0x749CC4585874B09CUL, 0x2E724634342E6872UL, + 0x2D774136362D6C77UL, 0xB2CD11DCDCB2A3CDUL, 0xEE299DB4B4EE7329UL, 0xFB164D5B5BFBB616UL, + 0xF601A5A4A4F65301UL, 0x4DD7A176764DECD7UL, 0x61A314B7B76175A3UL, 0xCE49347D7DCEFA49UL, + 0x7B8DDF52527BA48DUL, 0x3E429FDDDD3EA142UL, 0x7193CD5E5E71BC93UL, 0x97A2B113139726A2UL, + 0xF504A2A6A6F55704UL, 0x68B801B9B96869B8UL, 0x0000000000000000UL, 0x2C74B5C1C12C9974UL, + 0x60A0E040406080A0UL, 0x1F21C2E3E31FDD21UL, 0xC8433A7979C8F243UL, 0xED2C9AB6B6ED772CUL, + 0xBED90DD4D4BEB3D9UL, 0x46CA478D8D4601CAUL, 0xD970176767D9CE70UL, 0x4BDDAF72724BE4DDUL, + 0xDE79ED9494DE3379UL, 0xD467FF9898D42B67UL, 0xE82393B0B0E87B23UL, 0x4ADE5B85854A11DEUL, + 0x6BBD06BBBB6B6DBDUL, 0x2A7EBBC5C52A917EUL, 0xE5347B4F4FE59E34UL, 0x163AD7EDED16C13AUL, + 0xC554D28686C51754UL, 0xD762F89A9AD72F62UL, 0x55FF99666655CCFFUL, 0x94A7B611119422A7UL, + 0xCF4AC08A8ACF0F4AUL, 0x1030D9E9E910C930UL, 0x060A0E040406080AUL, 0x819866FEFE81E798UL, + 0xF00BABA0A0F05B0BUL, 0x44CCB4787844F0CCUL, 0xBAD5F02525BA4AD5UL, 0xE33E754B4BE3963EUL, + 0xF30EACA2A2F35F0EUL, 0xFE19445D5DFEBA19UL, 0xC05BDB8080C01B5BUL, 0x8A858005058A0A85UL, + 0xADECD33F3FAD7EECUL, 0xBCDFFE2121BC42DFUL, 0x48D8A8707048E0D8UL, 0x040CFDF1F104F90CUL, + 0xDF7A196363DFC67AUL, 0xC1582F7777C1EE58UL, 0x759F30AFAF75459FUL, 0x63A5E742426384A5UL, + 0x3050702020304050UL, 0x1A2ECBE5E51AD12EUL, 0x0E12EFFDFD0EE112UL, 0x6DB708BFBF6D65B7UL, + 0x4CD45581814C19D4UL, 0x143C24181814303CUL, 0x355F792626354C5FUL, 0x2F71B2C3C32F9D71UL, + 0xE13886BEBEE16738UL, 0xA2FDC83535A26AFDUL, 0xCC4FC78888CC0B4FUL, 0x394B652E2E395C4BUL, + 0x57F96A9393573DF9UL, 0xF20D585555F2AA0DUL, 0x829D61FCFC82E39DUL, 0x47C9B37A7A47F4C9UL, + 0xACEF27C8C8AC8BEFUL, 0xE73288BABAE76F32UL, 0x2B7D4F32322B647DUL, 0x95A442E6E695D7A4UL, + 0xA0FB3BC0C0A09BFBUL, 0x98B3AA19199832B3UL, 0xD168F69E9ED12768UL, 0x7F8122A3A37F5D81UL, + 0x66AAEE44446688AAUL, 0x7E82D654547EA882UL, 0xABE6DD3B3BAB76E6UL, 0x839E950B0B83169EUL, + 0xCA45C98C8CCA0345UL, 0x297BBCC7C729957BUL, 0xD36E056B6BD3D66EUL, 0x3C446C28283C5044UL, + 0x798B2CA7A779558BUL, 0xE23D81BCBCE2633DUL, 0x1D273116161D2C27UL, 0x769A37ADAD76419AUL, + 0x3B4D96DBDB3BAD4DUL, 0x56FA9E646456C8FAUL, 0x4ED2A674744EE8D2UL, 0x1E223614141E2822UL, + 0xDB76E49292DB3F76UL, 0x0A1E120C0C0A181EUL, 0x6CB4FC48486C90B4UL, 0xE4378FB8B8E46B37UL, + 0x5DE7789F9F5D25E7UL, 0x6EB20FBDBD6E61B2UL, 0xEF2A694343EF862AUL, 0xA6F135C4C4A693F1UL, + 0xA8E3DA3939A872E3UL, 0xA4F7C63131A462F7UL, 0x37598AD3D337BD59UL, 0x8B8674F2F28BFF86UL, + 0x325683D5D532B156UL, 0x43C54E8B8B430DC5UL, 0x59EB856E6E59DCEBUL, 0xB7C218DADAB7AFC2UL, + 0x8C8F8E01018C028FUL, 0x64AC1DB1B16479ACUL, 0xD26DF19C9CD2236DUL, 0xE03B724949E0923BUL, + 0xB4C71FD8D8B4ABC7UL, 0xFA15B9ACACFA4315UL, 0x0709FAF3F307FD09UL, 0x256FA0CFCF25856FUL, + 0xAFEA20CACAAF8FEAUL, 0x8E897DF4F48EF389UL, 0xE920674747E98E20UL, 0x1828381010182028UL, + 0xD5640B6F6FD5DE64UL, 0x888373F0F088FB83UL, 0x6FB1FB4A4A6F94B1UL, 0x7296CA5C5C72B896UL, + 0x246C54383824706CUL, 0xF1085F5757F1AE08UL, 0xC752217373C7E652UL, 0x51F36497975135F3UL, + 0x2365AECBCB238D65UL, 0x7C8425A1A17C5984UL, 0x9CBF57E8E89CCBBFUL, 0x21635D3E3E217C63UL, + 0xDD7CEA9696DD377CUL, 0xDC7F1E6161DCC27FUL, 0x86919C0D0D861A91UL, 0x85949B0F0F851E94UL, + 0x90AB4BE0E090DBABUL, 0x42C6BA7C7C42F8C6UL, 0xC457267171C4E257UL, 0xAAE529CCCCAA83E5UL, + 0xD873E39090D83B73UL, 0x050F090606050C0FUL, 0x0103F4F7F701F503UL, 0x12362A1C1C123836UL, + 0xA3FE3CC2C2A39FFEUL, 0x5FE18B6A6A5FD4E1UL, 0xF910BEAEAEF94710UL, 0xD06B026969D0D26BUL, + 0x91A8BF1717912EA8UL, 0x58E87199995829E8UL, 0x2769533A3A277469UL, 0xB9D0F72727B94ED0UL, + 0x384891D9D938A948UL, 0x1335DEEBEB13CD35UL, 0xB3CEE52B2BB356CEUL, 0x3355772222334455UL, + 0xBBD604D2D2BBBFD6UL, 0x709039A9A9704990UL, 0x8980870707890E80UL, 0xA7F2C13333A766F2UL, + 0xB6C1EC2D2DB65AC1UL, 0x22665A3C3C227866UL, 0x92ADB81515922AADUL, 0x2060A9C9C9208960UL, + 0x49DB5C87874915DBUL, 0xFF1AB0AAAAFF4F1AUL, 0x7888D8505078A088UL, 0x7A8E2BA5A57A518EUL, + 0x8F8A8903038F068AUL, 0xF8134A5959F8B213UL, 0x809B92090980129BUL, 0x1739231A1A173439UL, + 0xDA75106565DACA75UL, 0x315384D7D731B553UL, 0xC651D58484C61351UL, 0xB8D303D0D0B8BBD3UL, + 0xC35EDC8282C31F5EUL, 0xB0CBE22929B052CBUL, 0x7799C35A5A77B499UL, 0x11332D1E1E113C33UL, + 0xCB463D7B7BCBF646UL, 0xFC1FB7A8A8FC4B1FUL, 0xD6610C6D6DD6DA61UL, 0x3A4E622C2C3A584EUL +}; + +#define RSTT(d, a, b0, b1, b2, b3, b4, b5, b6, b7) do { \ + t[d] = T0_G[B64_0(a[b0])] \ + ^ R64(T0_G[B64_1(a[b1])], 8) \ + ^ R64(T0_G[B64_2(a[b2])], 16) \ + ^ R64(T0_G[B64_3(a[b3])], 24) \ + ^ T4_G[B64_4(a[b4])] \ + ^ R64(T4_G[B64_5(a[b5])], 8) \ + ^ R64(T4_G[B64_6(a[b6])], 16) \ + ^ R64(T4_G[B64_7(a[b7])], 24); \ + } while (0) + +#define ROUND_SMALL_P(a, r) do { \ + ulong t[8]; \ + a[0] ^= PC64(0x00, r); \ + a[1] ^= PC64(0x10, r); \ + a[2] ^= PC64(0x20, r); \ + a[3] ^= PC64(0x30, r); \ + a[4] ^= PC64(0x40, r); \ + a[5] ^= PC64(0x50, r); \ + a[6] ^= PC64(0x60, r); \ + a[7] ^= PC64(0x70, r); \ + RSTT(0, a, 0, 1, 2, 3, 4, 5, 6, 7); \ + RSTT(1, a, 1, 2, 3, 4, 5, 6, 7, 0); \ + RSTT(2, a, 2, 3, 4, 5, 6, 7, 0, 1); \ + RSTT(3, a, 3, 4, 5, 6, 7, 0, 1, 2); \ + RSTT(4, a, 4, 5, 6, 7, 0, 1, 2, 3); \ + RSTT(5, a, 5, 6, 7, 0, 1, 2, 3, 4); \ + RSTT(6, a, 6, 7, 0, 1, 2, 3, 4, 5); \ + RSTT(7, a, 7, 0, 1, 2, 3, 4, 5, 6); \ + a[0] = t[0]; \ + a[1] = t[1]; \ + a[2] = t[2]; \ + a[3] = t[3]; \ + a[4] = t[4]; \ + a[5] = t[5]; \ + a[6] = t[6]; \ + a[7] = t[7]; \ + } while (0) + +#define ROUND_SMALL_Pf(a,r) do { \ + a[0] ^= PC64(0x00, r); \ + a[1] ^= PC64(0x10, r); \ + a[2] ^= PC64(0x20, r); \ + a[3] ^= PC64(0x30, r); \ + a[4] ^= PC64(0x40, r); \ + a[5] ^= PC64(0x50, r); \ + a[6] ^= PC64(0x60, r); \ + a[7] ^= PC64(0x70, r); \ + RSTT(7, a, 7, 0, 1, 2, 3, 4, 5, 6); \ + a[7] = t[7]; \ + } while (0) + +#define ROUND_SMALL_Q(a, r) do { \ + ulong t[8]; \ + a[0] ^= QC64(0x00, r); \ + a[1] ^= QC64(0x10, r); \ + a[2] ^= QC64(0x20, r); \ + a[3] ^= QC64(0x30, r); \ + a[4] ^= QC64(0x40, r); \ + a[5] ^= QC64(0x50, r); \ + a[6] ^= QC64(0x60, r); \ + a[7] ^= QC64(0x70, r); \ + RSTT(0, a, 1, 3, 5, 7, 0, 2, 4, 6); \ + RSTT(1, a, 2, 4, 6, 0, 1, 3, 5, 7); \ + RSTT(2, a, 3, 5, 7, 1, 2, 4, 6, 0); \ + RSTT(3, a, 4, 6, 0, 2, 3, 5, 7, 1); \ + RSTT(4, a, 5, 7, 1, 3, 4, 6, 0, 2); \ + RSTT(5, a, 6, 0, 2, 4, 5, 7, 1, 3); \ + RSTT(6, a, 7, 1, 3, 5, 6, 0, 2, 4); \ + RSTT(7, a, 0, 2, 4, 6, 7, 1, 3, 5); \ + a[0] = t[0]; \ + a[1] = t[1]; \ + a[2] = t[2]; \ + a[3] = t[3]; \ + a[4] = t[4]; \ + a[5] = t[5]; \ + a[6] = t[6]; \ + a[7] = t[7]; \ + } while (0) + +#define PERM_SMALL_P(a) do { \ + for (int r = 0; r < 10; r ++) \ + ROUND_SMALL_P(a, r); \ + } while (0) + +#define PERM_SMALL_Pf(a) do { \ + for (int r = 0; r < 9; r ++) { \ + ROUND_SMALL_P(a, r);} \ + ROUND_SMALL_Pf(a,9); \ + } while (0) + +#define PERM_SMALL_Q(a) do { \ + for (int r = 0; r < 10; r ++) \ + ROUND_SMALL_Q(a, r); \ + } while (0) + diff --git a/opencl/jh.cl b/opencl/jh.cl new file mode 100644 index 0000000..d034abc --- /dev/null +++ b/opencl/jh.cl @@ -0,0 +1,272 @@ +/* $Id: jh.c 255 2011-06-07 19:50:20Z tp $ */ +/* + * JH implementation. + * + * ==========================(LICENSE BEGIN)============================ + * + * Copyright (c) 2007-2010 Projet RNRT SAPHIR + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ===========================(LICENSE END)============================= + * + * @author Thomas Pornin + */ + +#define SPH_JH_64 1 +#define SPH_LITTLE_ENDIAN 1 + +#define SPH_C32(x) x +#define SPH_C64(x) x +typedef uint sph_u32; +typedef ulong sph_u64; + +/* + * The internal bitslice representation may use either big-endian or + * little-endian (true bitslice operations do not care about the bit + * ordering, and the bit-swapping linear operations in JH happen to + * be invariant through endianness-swapping). The constants must be + * defined according to the chosen endianness; we use some + * byte-swapping macros for that. + */ + +#if SPH_LITTLE_ENDIAN + +#define C32e(x) ((SPH_C32(x) >> 24) \ + | ((SPH_C32(x) >> 8) & SPH_C32(0x0000FF00)) \ + | ((SPH_C32(x) << 8) & SPH_C32(0x00FF0000)) \ + | ((SPH_C32(x) << 24) & SPH_C32(0xFF000000))) +#define dec32e_aligned sph_dec32le_aligned +#define enc32e sph_enc32le + +#define C64e(x) ((SPH_C64(x) >> 56) \ + | ((SPH_C64(x) >> 40) & SPH_C64(0x000000000000FF00)) \ + | ((SPH_C64(x) >> 24) & SPH_C64(0x0000000000FF0000)) \ + | ((SPH_C64(x) >> 8) & SPH_C64(0x00000000FF000000)) \ + | ((SPH_C64(x) << 8) & SPH_C64(0x000000FF00000000)) \ + | ((SPH_C64(x) << 24) & SPH_C64(0x0000FF0000000000)) \ + | ((SPH_C64(x) << 40) & SPH_C64(0x00FF000000000000)) \ + | ((SPH_C64(x) << 56) & SPH_C64(0xFF00000000000000))) +#define dec64e_aligned sph_dec64le_aligned +#define enc64e sph_enc64le + +#else + +#define C32e(x) SPH_C32(x) +#define dec32e_aligned sph_dec32be_aligned +#define enc32e sph_enc32be +#define C64e(x) SPH_C64(x) +#define dec64e_aligned sph_dec64be_aligned +#define enc64e sph_enc64be + +#endif + +#define Sb(x0, x1, x2, x3, c) do { \ + x3 = ~x3; \ + x0 ^= (c) & ~x2; \ + tmp = (c) ^ (x0 & x1); \ + x0 ^= x2 & x3; \ + x3 ^= ~x1 & x2; \ + x1 ^= x0 & x2; \ + x2 ^= x0 & ~x3; \ + x0 ^= x1 | x3; \ + x3 ^= x1 & x2; \ + x1 ^= tmp & x0; \ + x2 ^= tmp; \ + } while (0) + +#define Lb(x0, x1, x2, x3, x4, x5, x6, x7) do { \ + x4 ^= x1; \ + x5 ^= x2; \ + x6 ^= x3 ^ x0; \ + x7 ^= x0; \ + x0 ^= x5; \ + x1 ^= x6; \ + x2 ^= x7 ^ x4; \ + x3 ^= x4; \ + } while (0) + +static const __constant ulong C[] = +{ + 0x67F815DFA2DED572UL, 0x571523B70A15847BUL, 0xF6875A4D90D6AB81UL, 0x402BD1C3C54F9F4EUL, + 0x9CFA455CE03A98EAUL, 0x9A99B26699D2C503UL, 0x8A53BBF2B4960266UL, 0x31A2DB881A1456B5UL, + 0xDB0E199A5C5AA303UL, 0x1044C1870AB23F40UL, 0x1D959E848019051CUL, 0xDCCDE75EADEB336FUL, + 0x416BBF029213BA10UL, 0xD027BBF7156578DCUL, 0x5078AA3739812C0AUL, 0xD3910041D2BF1A3FUL, + 0x907ECCF60D5A2D42UL, 0xCE97C0929C9F62DDUL, 0xAC442BC70BA75C18UL, 0x23FCC663D665DFD1UL, + 0x1AB8E09E036C6E97UL, 0xA8EC6C447E450521UL, 0xFA618E5DBB03F1EEUL, 0x97818394B29796FDUL, + 0x2F3003DB37858E4AUL, 0x956A9FFB2D8D672AUL, 0x6C69B8F88173FE8AUL, 0x14427FC04672C78AUL, + 0xC45EC7BD8F15F4C5UL, 0x80BB118FA76F4475UL, 0xBC88E4AEB775DE52UL, 0xF4A3A6981E00B882UL, + 0x1563A3A9338FF48EUL, 0x89F9B7D524565FAAUL, 0xFDE05A7C20EDF1B6UL, 0x362C42065AE9CA36UL, + 0x3D98FE4E433529CEUL, 0xA74B9A7374F93A53UL, 0x86814E6F591FF5D0UL, 0x9F5AD8AF81AD9D0EUL, + 0x6A6234EE670605A7UL, 0x2717B96EBE280B8BUL, 0x3F1080C626077447UL, 0x7B487EC66F7EA0E0UL, + 0xC0A4F84AA50A550DUL, 0x9EF18E979FE7E391UL, 0xD48D605081727686UL, 0x62B0E5F3415A9E7EUL, + 0x7A205440EC1F9FFCUL, 0x84C9F4CE001AE4E3UL, 0xD895FA9DF594D74FUL, 0xA554C324117E2E55UL, + 0x286EFEBD2872DF5BUL, 0xB2C4A50FE27FF578UL, 0x2ED349EEEF7C8905UL, 0x7F5928EB85937E44UL, + 0x4A3124B337695F70UL, 0x65E4D61DF128865EUL, 0xE720B95104771BC7UL, 0x8A87D423E843FE74UL, + 0xF2947692A3E8297DUL, 0xC1D9309B097ACBDDUL, 0xE01BDC5BFB301B1DUL, 0xBF829CF24F4924DAUL, + 0xFFBF70B431BAE7A4UL, 0x48BCF8DE0544320DUL, 0x39D3BB5332FCAE3BUL, 0xA08B29E0C1C39F45UL, + 0x0F09AEF7FD05C9E5UL, 0x34F1904212347094UL, 0x95ED44E301B771A2UL, 0x4A982F4F368E3BE9UL, + 0x15F66CA0631D4088UL, 0xFFAF52874B44C147UL, 0x30C60AE2F14ABB7EUL, 0xE68C6ECCC5B67046UL, + 0x00CA4FBD56A4D5A4UL, 0xAE183EC84B849DDAUL, 0xADD1643045CE5773UL, 0x67255C1468CEA6E8UL, + 0x16E10ECBF28CDAA3UL, 0x9A99949A5806E933UL, 0x7B846FC220B2601FUL, 0x1885D1A07FACCED1UL, + 0xD319DD8DA15B5932UL, 0x46B4A5AAC01C9A50UL, 0xBA6B04E467633D9FUL, 0x7EEE560BAB19CAF6UL, + 0x742128A9EA79B11FUL, 0xEE51363B35F7BDE9UL, 0x76D350755AAC571DUL, 0x01707DA3FEC2463AUL, + 0x42D8A498AFC135F7UL, 0x79676B9E20ECED78UL, 0xA8DB3AEA15638341UL, 0x832C83324D3BC3FAUL, + 0xF347271C1F3B40A7UL, 0x9A762DB734F04059UL, 0xFD4F21D26C4E3EE7UL, 0xEF5957DC398DFDB8UL, + 0xDAEB492B490C9B8DUL, 0x0D70F36849D7A25BUL, 0x84558D7AD0AE3B7DUL, 0x658EF8E4F0E9A5F5UL, + 0x533B1036F4A2B8A0UL, 0x5AEC3E759E07A80CUL, 0x4F88E85692946891UL, 0x4CBCBAF8555CB05BUL, + 0x7B9487F3993BBBE3UL, 0x5D1C6B72D6F4DA75UL, 0x6DB334DC28ACAE64UL, 0x71DB28B850A5346CUL, + 0x2A518D10F2E261F8UL, 0xFC75DD593364DBE3UL, 0xA23FCE43F1BCAC1CUL, 0xB043E8023CD1BB67UL, + 0x75A12988CA5B0A33UL, 0x5C5316B44D19347FUL, 0x1E4D790EC3943B92UL, 0x3FAFEEB6D7757479UL, + 0x21391ABEF7D4A8EAUL, 0x5127234C097EF45CUL, 0xD23C32BA5324A326UL, 0xADD5A66D4A17A344UL, + 0x08C9F2AFA63E1DB5UL, 0x563C6B91983D5983UL, 0x4D608672A17CF84CUL, 0xF6C76E08CC3EE246UL, + 0x5E76BCB1B333982FUL, 0x2AE6C4EFA566D62BUL, 0x36D4C1BEE8B6F406UL, 0x6321EFBC1582EE74UL, + 0x69C953F40D4EC1FDUL, 0x26585806C45A7DA7UL, 0x16FAE0061614C17EUL, 0x3F9D63283DAF907EUL, + 0x0CD29B00E3F2C9D2UL, 0x300CD4B730CEAA5FUL, 0x9832E0F216512A74UL, 0x9AF8CEE3D830EB0DUL, + 0x9279F1B57B9EC54BUL, 0xD36886046EE651FFUL, 0x316796E6574D239BUL, 0x05750A17F3A6E6CCUL, + 0xCE6C3213D98176B1UL, 0x62A205F88452173CUL, 0x47154778B3CB2BF4UL, 0x486A9323825446FFUL, + 0x65655E4E0758DF38UL, 0x8E5086FC897CFCF2UL, 0x86CA0BD0442E7031UL, 0x4E477830A20940F0UL, + 0x8338F7D139EEA065UL, 0xBD3A2CE437E95EF7UL, 0x6FF8130126B29721UL, 0xE7DE9FEFD1ED44A3UL, + 0xD992257615DFA08BUL, 0xBE42DC12F6F7853CUL, 0x7EB027AB7CECA7D8UL, 0xDEA83EAADA7D8D53UL, + 0xD86902BD93CE25AAUL, 0xF908731AFD43F65AUL, 0xA5194A17DAEF5FC0UL, 0x6A21FD4C33664D97UL, + 0x701541DB3198B435UL, 0x9B54CDEDBB0F1EEAUL, 0x72409751A163D09AUL, 0xE26F4791BF9D75F6UL +}; + +#define Ceven_hi(r) (C[((r) << 2) + 0]) +#define Ceven_lo(r) (C[((r) << 2) + 1]) +#define Codd_hi(r) (C[((r) << 2) + 2]) +#define Codd_lo(r) (C[((r) << 2) + 3]) + +#define S(x0, x1, x2, x3, cb, r) do { \ + Sb(x0 ## h, x1 ## h, x2 ## h, x3 ## h, cb ## hi(r)); \ + Sb(x0 ## l, x1 ## l, x2 ## l, x3 ## l, cb ## lo(r)); \ + } while (0) + +#define L(x0, x1, x2, x3, x4, x5, x6, x7) do { \ + Lb(x0 ## h, x1 ## h, x2 ## h, x3 ## h, \ + x4 ## h, x5 ## h, x6 ## h, x7 ## h); \ + Lb(x0 ## l, x1 ## l, x2 ## l, x3 ## l, \ + x4 ## l, x5 ## l, x6 ## l, x7 ## l); \ + } while (0) + +#define Wz(x, c, n) do { \ + sph_u64 t = (x ## h & (c)) << (n); \ + x ## h = ((x ## h >> (n)) & (c)) | t; \ + t = (x ## l & (c)) << (n); \ + x ## l = ((x ## l >> (n)) & (c)) | t; \ + } while (0) + +#define W0(x) Wz(x, SPH_C64(0x5555555555555555), 1) +#define W1(x) Wz(x, SPH_C64(0x3333333333333333), 2) +#define W2(x) Wz(x, SPH_C64(0x0F0F0F0F0F0F0F0F), 4) +#define W3(x) Wz(x, SPH_C64(0x00FF00FF00FF00FF), 8) +#define W4(x) Wz(x, SPH_C64(0x0000FFFF0000FFFF), 16) +#define W5(x) Wz(x, SPH_C64(0x00000000FFFFFFFF), 32) +#define W6(x) do { \ + sph_u64 t = x ## h; \ + x ## h = x ## l; \ + x ## l = t; \ + } while (0) + +#define SL(ro) SLu(r + ro, ro) + +#define SLu(r, ro) do { \ + S(h0, h2, h4, h6, Ceven_, r); \ + S(h1, h3, h5, h7, Codd_, r); \ + L(h0, h2, h4, h6, h1, h3, h5, h7); \ + W ## ro(h1); \ + W ## ro(h3); \ + W ## ro(h5); \ + W ## ro(h7); \ + } while (0) + +#if SPH_SMALL_FOOTPRINT_JH + +/* + * The "small footprint" 64-bit version just uses a partially unrolled + * loop. + */ + +#define E8 do { \ + unsigned r; \ + for (r = 0; r < 42; r += 7) { \ + SL(0); \ + SL(1); \ + SL(2); \ + SL(3); \ + SL(4); \ + SL(5); \ + SL(6); \ + } \ + } while (0) + +#else + +/* + * On a "true 64-bit" architecture, we can unroll at will. + */ + +#define E8 do { \ + SLu( 0, 0); \ + SLu( 1, 1); \ + SLu( 2, 2); \ + SLu( 3, 3); \ + SLu( 4, 4); \ + SLu( 5, 5); \ + SLu( 6, 6); \ + SLu( 7, 0); \ + SLu( 8, 1); \ + SLu( 9, 2); \ + SLu(10, 3); \ + SLu(11, 4); \ + SLu(12, 5); \ + SLu(13, 6); \ + SLu(14, 0); \ + SLu(15, 1); \ + SLu(16, 2); \ + SLu(17, 3); \ + SLu(18, 4); \ + SLu(19, 5); \ + SLu(20, 6); \ + SLu(21, 0); \ + SLu(22, 1); \ + SLu(23, 2); \ + SLu(24, 3); \ + SLu(25, 4); \ + SLu(26, 5); \ + SLu(27, 6); \ + SLu(28, 0); \ + SLu(29, 1); \ + SLu(30, 2); \ + SLu(31, 3); \ + SLu(32, 4); \ + SLu(33, 5); \ + SLu(34, 6); \ + SLu(35, 0); \ + SLu(36, 1); \ + SLu(37, 2); \ + SLu(38, 3); \ + SLu(39, 4); \ + SLu(40, 5); \ + SLu(41, 6); \ + } while (0) + +#endif + diff --git a/opencl/wolf-aes.cl b/opencl/wolf-aes.cl new file mode 100644 index 0000000..23a41a7 --- /dev/null +++ b/opencl/wolf-aes.cl @@ -0,0 +1,87 @@ +#ifndef WOLF_AES_CL +#define WOLF_AES_CL + +// AES table - the other three are generated on the fly + +static const __constant uint AES0_C[256] = +{ + 0xA56363C6U, 0x847C7CF8U, 0x997777EEU, 0x8D7B7BF6U, + 0x0DF2F2FFU, 0xBD6B6BD6U, 0xB16F6FDEU, 0x54C5C591U, + 0x50303060U, 0x03010102U, 0xA96767CEU, 0x7D2B2B56U, + 0x19FEFEE7U, 0x62D7D7B5U, 0xE6ABAB4DU, 0x9A7676ECU, + 0x45CACA8FU, 0x9D82821FU, 0x40C9C989U, 0x877D7DFAU, + 0x15FAFAEFU, 0xEB5959B2U, 0xC947478EU, 0x0BF0F0FBU, + 0xECADAD41U, 0x67D4D4B3U, 0xFDA2A25FU, 0xEAAFAF45U, + 0xBF9C9C23U, 0xF7A4A453U, 0x967272E4U, 0x5BC0C09BU, + 0xC2B7B775U, 0x1CFDFDE1U, 0xAE93933DU, 0x6A26264CU, + 0x5A36366CU, 0x413F3F7EU, 0x02F7F7F5U, 0x4FCCCC83U, + 0x5C343468U, 0xF4A5A551U, 0x34E5E5D1U, 0x08F1F1F9U, + 0x937171E2U, 0x73D8D8ABU, 0x53313162U, 0x3F15152AU, + 0x0C040408U, 0x52C7C795U, 0x65232346U, 0x5EC3C39DU, + 0x28181830U, 0xA1969637U, 0x0F05050AU, 0xB59A9A2FU, + 0x0907070EU, 0x36121224U, 0x9B80801BU, 0x3DE2E2DFU, + 0x26EBEBCDU, 0x6927274EU, 0xCDB2B27FU, 0x9F7575EAU, + 0x1B090912U, 0x9E83831DU, 0x742C2C58U, 0x2E1A1A34U, + 0x2D1B1B36U, 0xB26E6EDCU, 0xEE5A5AB4U, 0xFBA0A05BU, + 0xF65252A4U, 0x4D3B3B76U, 0x61D6D6B7U, 0xCEB3B37DU, + 0x7B292952U, 0x3EE3E3DDU, 0x712F2F5EU, 0x97848413U, + 0xF55353A6U, 0x68D1D1B9U, 0x00000000U, 0x2CEDEDC1U, + 0x60202040U, 0x1FFCFCE3U, 0xC8B1B179U, 0xED5B5BB6U, + 0xBE6A6AD4U, 0x46CBCB8DU, 0xD9BEBE67U, 0x4B393972U, + 0xDE4A4A94U, 0xD44C4C98U, 0xE85858B0U, 0x4ACFCF85U, + 0x6BD0D0BBU, 0x2AEFEFC5U, 0xE5AAAA4FU, 0x16FBFBEDU, + 0xC5434386U, 0xD74D4D9AU, 0x55333366U, 0x94858511U, + 0xCF45458AU, 0x10F9F9E9U, 0x06020204U, 0x817F7FFEU, + 0xF05050A0U, 0x443C3C78U, 0xBA9F9F25U, 0xE3A8A84BU, + 0xF35151A2U, 0xFEA3A35DU, 0xC0404080U, 0x8A8F8F05U, + 0xAD92923FU, 0xBC9D9D21U, 0x48383870U, 0x04F5F5F1U, + 0xDFBCBC63U, 0xC1B6B677U, 0x75DADAAFU, 0x63212142U, + 0x30101020U, 0x1AFFFFE5U, 0x0EF3F3FDU, 0x6DD2D2BFU, + 0x4CCDCD81U, 0x140C0C18U, 0x35131326U, 0x2FECECC3U, + 0xE15F5FBEU, 0xA2979735U, 0xCC444488U, 0x3917172EU, + 0x57C4C493U, 0xF2A7A755U, 0x827E7EFCU, 0x473D3D7AU, + 0xAC6464C8U, 0xE75D5DBAU, 0x2B191932U, 0x957373E6U, + 0xA06060C0U, 0x98818119U, 0xD14F4F9EU, 0x7FDCDCA3U, + 0x66222244U, 0x7E2A2A54U, 0xAB90903BU, 0x8388880BU, + 0xCA46468CU, 0x29EEEEC7U, 0xD3B8B86BU, 0x3C141428U, + 0x79DEDEA7U, 0xE25E5EBCU, 0x1D0B0B16U, 0x76DBDBADU, + 0x3BE0E0DBU, 0x56323264U, 0x4E3A3A74U, 0x1E0A0A14U, + 0xDB494992U, 0x0A06060CU, 0x6C242448U, 0xE45C5CB8U, + 0x5DC2C29FU, 0x6ED3D3BDU, 0xEFACAC43U, 0xA66262C4U, + 0xA8919139U, 0xA4959531U, 0x37E4E4D3U, 0x8B7979F2U, + 0x32E7E7D5U, 0x43C8C88BU, 0x5937376EU, 0xB76D6DDAU, + 0x8C8D8D01U, 0x64D5D5B1U, 0xD24E4E9CU, 0xE0A9A949U, + 0xB46C6CD8U, 0xFA5656ACU, 0x07F4F4F3U, 0x25EAEACFU, + 0xAF6565CAU, 0x8E7A7AF4U, 0xE9AEAE47U, 0x18080810U, + 0xD5BABA6FU, 0x887878F0U, 0x6F25254AU, 0x722E2E5CU, + 0x241C1C38U, 0xF1A6A657U, 0xC7B4B473U, 0x51C6C697U, + 0x23E8E8CBU, 0x7CDDDDA1U, 0x9C7474E8U, 0x211F1F3EU, + 0xDD4B4B96U, 0xDCBDBD61U, 0x868B8B0DU, 0x858A8A0FU, + 0x907070E0U, 0x423E3E7CU, 0xC4B5B571U, 0xAA6666CCU, + 0xD8484890U, 0x05030306U, 0x01F6F6F7U, 0x120E0E1CU, + 0xA36161C2U, 0x5F35356AU, 0xF95757AEU, 0xD0B9B969U, + 0x91868617U, 0x58C1C199U, 0x271D1D3AU, 0xB99E9E27U, + 0x38E1E1D9U, 0x13F8F8EBU, 0xB398982BU, 0x33111122U, + 0xBB6969D2U, 0x70D9D9A9U, 0x898E8E07U, 0xA7949433U, + 0xB69B9B2DU, 0x221E1E3CU, 0x92878715U, 0x20E9E9C9U, + 0x49CECE87U, 0xFF5555AAU, 0x78282850U, 0x7ADFDFA5U, + 0x8F8C8C03U, 0xF8A1A159U, 0x80898909U, 0x170D0D1AU, + 0xDABFBF65U, 0x31E6E6D7U, 0xC6424284U, 0xB86868D0U, + 0xC3414182U, 0xB0999929U, 0x772D2D5AU, 0x110F0F1EU, + 0xCBB0B07BU, 0xFC5454A8U, 0xD6BBBB6DU, 0x3A16162CU +}; + +#define BYTE(x, y) (amd_bfe((x), (y) << 3U, 8U)) + +uint4 AES_Round(const __local uint *AES0, const __local uint *AES1, const __local uint *AES2, const __local uint *AES3, const uint4 X, const uint4 key) +{ + uint4 Y; + Y.s0 = AES0[BYTE(X.s0, 0)] ^ AES1[BYTE(X.s1, 1)] ^ AES2[BYTE(X.s2, 2)] ^ AES3[BYTE(X.s3, 3)]; + Y.s1 = AES0[BYTE(X.s1, 0)] ^ AES1[BYTE(X.s2, 1)] ^ AES2[BYTE(X.s3, 2)] ^ AES3[BYTE(X.s0, 3)]; + Y.s2 = AES0[BYTE(X.s2, 0)] ^ AES1[BYTE(X.s3, 1)] ^ AES2[BYTE(X.s0, 2)] ^ AES3[BYTE(X.s1, 3)]; + Y.s3 = AES0[BYTE(X.s3, 0)] ^ AES1[BYTE(X.s0, 1)] ^ AES2[BYTE(X.s1, 2)] ^ AES3[BYTE(X.s2, 3)]; + Y ^= key; + return(Y); +} + +#endif diff --git a/opencl/wolf-skein.cl b/opencl/wolf-skein.cl new file mode 100644 index 0000000..c5c2bd8 --- /dev/null +++ b/opencl/wolf-skein.cl @@ -0,0 +1,111 @@ +#ifndef WOLF_SKEIN_CL +#define WOLF_SKEIN_CL + +// Vectorized Skein implementation macros and functions by Wolf + +#define SKEIN_KS_PARITY 0x1BD11BDAA9FC1A22 + +static const __constant ulong SKEIN256_IV[8] = +{ + 0xCCD044A12FDB3E13UL, 0xE83590301A79A9EBUL, + 0x55AEA0614F816E6FUL, 0x2A2767A4AE9B94DBUL, + 0xEC06025E74DD7683UL, 0xE7A436CDC4746251UL, + 0xC36FBAF9393AD185UL, 0x3EEDBA1833EDFC13UL +}; + +static const __constant ulong SKEIN512_256_IV[8] = +{ + 0xCCD044A12FDB3E13UL, 0xE83590301A79A9EBUL, + 0x55AEA0614F816E6FUL, 0x2A2767A4AE9B94DBUL, + 0xEC06025E74DD7683UL, 0xE7A436CDC4746251UL, + 0xC36FBAF9393AD185UL, 0x3EEDBA1833EDFC13UL +}; + +#define SKEIN_INJECT_KEY(p, s) do { \ + p += h; \ + p.s5 += t[s % 3]; \ + p.s6 += t[(s + 1) % 3]; \ + p.s7 += s; \ +} while(0) + +ulong SKEIN_ROT(const uint2 x, const uint y) +{ + if(y < 32) return(as_ulong(amd_bitalign(x, x.s10, 32 - y))); + else return(as_ulong(amd_bitalign(x.s10, x, 32 - (y - 32)))); +} + +void SkeinMix8(ulong4 *pv0, ulong4 *pv1, const uint rc0, const uint rc1, const uint rc2, const uint rc3) +{ + *pv0 += *pv1; + (*pv1).s0 = SKEIN_ROT(as_uint2((*pv1).s0), rc0); + (*pv1).s1 = SKEIN_ROT(as_uint2((*pv1).s1), rc1); + (*pv1).s2 = SKEIN_ROT(as_uint2((*pv1).s2), rc2); + (*pv1).s3 = SKEIN_ROT(as_uint2((*pv1).s3), rc3); + *pv1 ^= *pv0; +} + +ulong8 SkeinEvenRound(ulong8 p, const ulong8 h, const ulong *t, const uint s) +{ + SKEIN_INJECT_KEY(p, s); + ulong4 pv0 = p.even, pv1 = p.odd; + + SkeinMix8(&pv0, &pv1, 46, 36, 19, 37); + pv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0)); + pv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1)); + + SkeinMix8(&pv0, &pv1, 33, 27, 14, 42); + pv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0)); + pv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1)); + + SkeinMix8(&pv0, &pv1, 17, 49, 36, 39); + pv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0)); + pv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1)); + + SkeinMix8(&pv0, &pv1, 44, 9, 54, 56); + return(shuffle2(pv0, pv1, (ulong8)(1, 4, 2, 7, 3, 6, 0, 5))); +} + +ulong8 SkeinOddRound(ulong8 p, const ulong8 h, const ulong *t, const uint s) +{ + SKEIN_INJECT_KEY(p, s); + ulong4 pv0 = p.even, pv1 = p.odd; + + SkeinMix8(&pv0, &pv1, 39, 30, 34, 24); + pv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0)); + pv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1)); + + SkeinMix8(&pv0, &pv1, 13, 50, 10, 17); + pv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0)); + pv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1)); + + SkeinMix8(&pv0, &pv1, 25, 29, 39, 43); + pv0 = shuffle(pv0, (ulong4)(1, 2, 3, 0)); + pv1 = shuffle(pv1, (ulong4)(0, 3, 2, 1)); + + SkeinMix8(&pv0, &pv1, 8, 35, 56, 22); + return(shuffle2(pv0, pv1, (ulong8)(1, 4, 2, 7, 3, 6, 0, 5))); +} + +ulong8 Skein512Block(ulong8 p, ulong8 h, ulong h8, const ulong *t) +{ + #pragma unroll + for(int i = 0; i < 18; ++i) + { + p = SkeinEvenRound(p, h, t, i); + ++i; + ulong tmp = h.s0; + h = shuffle(h, (ulong8)(1, 2, 3, 4, 5, 6, 7, 0)); + h.s7 = h8; + h8 = tmp; + p = SkeinOddRound(p, h, t, i); + tmp = h.s0; + h = shuffle(h, (ulong8)(1, 2, 3, 4, 5, 6, 7, 0)); + h.s7 = h8; + h8 = tmp; + } + + SKEIN_INJECT_KEY(p, 18); + return(p); +} + +#endif From 9967fbb0b0031f735d3ab8a275417e59cd28cac9 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 24 Sep 2017 21:14:35 +0200 Subject: [PATCH 08/42] fix windows support - fix broken windows support --- CMakeLists.txt | 79 +++++++++++++++++++++--------- WINCOMPILE.md | 3 +- backend/BackendConnector.cpp | 10 ++-- backend/Plugin.hpp | 9 +++- backend/amd/amd_gpu/gpu.cpp | 7 +-- backend/amd/minethd.h | 2 +- backend/cpu/minethd.h | 4 +- cli-miner.cpp => cli/cli-miner.cpp | 18 +++---- jconf.cpp | 7 --- 9 files changed, 86 insertions(+), 53 deletions(-) rename cli-miner.cpp => cli/cli-miner.cpp (95%) diff --git a/CMakeLists.txt b/CMakeLists.txt index f88a2a9..3412b3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,9 +163,10 @@ endif() # Find PThreads ################################################################################ -find_package(Threads REQUIRED) -set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT}) - +if(NOT WIN32) + find_package(Threads REQUIRED) + set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT}) +endif() ################################################################################ # Find microhttpd ################################################################################ @@ -268,10 +269,16 @@ endif() # Compile & Link ################################################################################ -# activate sse2 and aes-ni -if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC") +if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + # remove warnings that f_open() is not save and f_open_s should be used + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + # disable min define to allow usage of std::min + add_definitions(-DNOMINMAX) +else() + # activate sse2 and aes-ni set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2 -maes") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2 -maes") + endif() # activate static libgcc and libstdc++ linking @@ -282,6 +289,20 @@ if(CMAKE_LINK_STATIC) set(LIBS "-static-libgcc -static-libstdc++ ${LIBS}") endif() +file(GLOB SRCFILES_C "crypto/*.c") + +add_library(xmr-stak-c + STATIC + ${SRCFILES_C} +) + +file(GLOB BACKEND_CPP "*.cpp" "backend/cpu/*.cpp" "backend/*.cpp" "crypto/*.cpp") +add_library(xmr-stak-backend + STATIC + ${BACKEND_CPP} +) +target_link_libraries(xmr-stak-backend xmr-stak-c ${CMAKE_DL_LIBS}) + if(CUDA_FOUND) file(GLOB CUDASRCFILES "backend/nvidia/nvcc_code/*.cu" "backend/nvidia/*.cpp") @@ -290,26 +311,27 @@ if(CUDA_FOUND) SHARED ${CUDASRCFILES} ) - target_link_libraries(xmrstak_cuda_backend ${CUDA_LIBRARIES}) + target_link_libraries(xmrstak_cuda_backend ${CUDA_LIBRARIES}) + if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + target_link_libraries(xmrstak_cuda_backend xmr-stak-backend) + endif() endif() if(OpenCL_FOUND) - file(GLOB OPENCLSRCFILES_C "backend/amd/amd_gpu/*.cpp" "console.cpp" "backend/amd/*.cpp") + file(GLOB OPENCLSRCFILES_C "backend/amd/amd_gpu/*.cpp" "backend/amd/*.cpp") add_library(xmrstak_opencl_backend SHARED ${OPENCLSRCFILES_C} ) - #set_property(TARGET xmrstak_opencl_backend PROPERTY C_STANDARD 99) - target_link_libraries(xmrstak_opencl_backend PUBLIC ${OpenCL_LIBRARY}) + target_link_libraries(xmrstak_opencl_backend ${OpenCL_LIBRARY} ) + if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + target_link_libraries(xmrstak_opencl_backend xmr-stak-backend) + endif() endif() -file(GLOB SRCFILES_CPP "*.cpp" "crypto/*.cpp" "backend/cpu/*.cpp" "backend/*.cpp") -file(GLOB SRCFILES_C "crypto/*.c") +file(GLOB SRCFILES_CPP "cli/*.cpp") +set_source_files_properties(${SRCFILES_CPP} PROPERTIES LANGUAGE CXX) -add_library(xmr-stak-c - STATIC - ${SRCFILES_C} -) set_property(TARGET xmr-stak-c PROPERTY C_STANDARD 99) target_link_libraries(xmr-stak-c ${LIBS}) @@ -320,34 +342,47 @@ add_executable(xmr-stak-cpu set(EXECUTABLE_OUTPUT_PATH "bin") set(LIBRARY_OUTPUT_PATH "bin") -target_link_libraries(xmr-stak-cpu ${LIBS} xmr-stak-c ${CMAKE_DL_LIBS}) +target_link_libraries(xmr-stak-cpu ${LIBS} xmr-stak-c xmr-stak-backend) ################################################################################ # Install ################################################################################ + # do not install the binary if the project and install are equal if( NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "${PROJECT_BINARY_DIR}" ) install(TARGETS xmr-stak-cpu RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") if(CUDA_FOUND) - install(TARGETS xmrstak_cuda_backend - LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") + if(WIN32) + install(TARGETS xmrstak_cuda_backend + RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") + else() + install(TARGETS xmrstak_cuda_backend + LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") + endif() endif() if(OpenCL_FOUND) - install(TARGETS xmrstak_opencl_backend - LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") + if(WIN32) + install(TARGETS xmrstak_opencl_backend + RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") + else() + install(TARGETS xmrstak_opencl_backend + LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") + endif() endif() + + set(WIN_OUTPUT_RELEASE "/Release") endif() install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/opencl" - DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") + DESTINATION "${CMAKE_INSTALL_PREFIX}/bin${WIN_OUTPUT_RELEASE}") # avoid overwrite of user defined settings # install `config.txt`if file not exists in `${CMAKE_INSTALL_PREFIX}/bin` install(CODE " \ if(NOT EXISTS ${CMAKE_INSTALL_PREFIX}/bin/config.txt)\n \ file(INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/config.txt \ - DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)\n \ + DESTINATION ${CMAKE_INSTALL_PREFIX}/bin${WIN_OUTPUT_RELEASE})\n \ endif()" ) diff --git a/WINCOMPILE.md b/WINCOMPILE.md index ec810af..13bbf9e 100644 --- a/WINCOMPILE.md +++ b/WINCOMPILE.md @@ -68,8 +68,7 @@ mkdir build cd build cmake -G "Visual Studio 15 2017 Win64" -T v141,host=x64 .. - msbuild xmr-stak-cpu.sln /p:Configuration=Release + cmake --build . --config Release --target install cd bin\Release - copy ..\..\..\config.txt . ``` - customize your `config.txt` file by adding the pool, username and password diff --git a/backend/BackendConnector.cpp b/backend/BackendConnector.cpp index f7a63fe..bb03e69 100644 --- a/backend/BackendConnector.cpp +++ b/backend/BackendConnector.cpp @@ -62,22 +62,22 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) std::vector* pvThreads = new std::vector; - auto cpuThreads = cpu::minethd::thread_starter(pvThreads->size(), pWork); + auto cpuThreads = cpu::minethd::thread_starter(static_cast(pvThreads->size()), pWork); pvThreads->insert(std::end(*pvThreads), std::begin(cpuThreads), std::end(cpuThreads)); if(cpuThreads.size() == 0) printer::inst()->print_msg(L0, "WARNING: backend CPU disabled."); #ifndef CONF_NO_CUDA - Plugin nvidiaPlugin("NVIDIA", "./libxmrstak_cuda_backend"); - std::vector* nvidiaThreads = nvidiaPlugin.startBackend(pvThreads->size(), pWork); + Plugin nvidiaPlugin("NVIDIA", "libxmrstak_cuda_backend"); + std::vector* nvidiaThreads = nvidiaPlugin.startBackend(static_cast(pvThreads->size()), pWork); pvThreads->insert(std::end(*pvThreads), std::begin(*nvidiaThreads), std::end(*nvidiaThreads)); if(nvidiaThreads->size() == 0) printer::inst()->print_msg(L0, "WARNING: backend NVIDIA disabled."); #endif #ifndef CONF_NO_OPENCL - Plugin amdPlugin("AMD", "./libxmrstak_opencl_backend"); - std::vector* amdThreads = amdPlugin.startBackend(pvThreads->size(), pWork); + Plugin amdPlugin("AMD", "libxmrstak_opencl_backend"); + std::vector* amdThreads = amdPlugin.startBackend(static_cast(pvThreads->size()), pWork); pvThreads->insert(std::end(*pvThreads), std::begin(*amdThreads), std::end(*amdThreads)); if(amdThreads->size() == 0) printer::inst()->print_msg(L0, "WARNING: backend AMD disabled."); diff --git a/backend/Plugin.hpp b/backend/Plugin.hpp index 762f955..347d5db 100644 --- a/backend/Plugin.hpp +++ b/backend/Plugin.hpp @@ -27,17 +27,22 @@ struct Plugin { #ifdef WIN32 libBackend = LoadLibrary(TEXT((libName + ".dll").c_str())); + if (!libBackend) + { + std::cerr << "WARNING: "<< m_backendName <<" cannot load backend library: " << (libName + ".dll") << std::endl; + return; + } #else libBackend = dlopen((libName + ".so").c_str(), RTLD_LAZY); -#endif if (!libBackend) { std::cerr << "WARNING: "<< m_backendName <<" cannot load backend library: " << dlerror() << std::endl; return; } +#endif #ifdef WIN32 - fn_starterBackend = (func_t*) GetProcAddress(libBackend, "xmrstak_start_backend"); + fn_starterBackend = (starterBackend_t) GetProcAddress(libBackend, "xmrstak_start_backend"); if (!fn_starterBackend) { std::cerr << "WARNING: backend plugin " << libName << " contains no entry 'xmrstak_start_backend'" << std::endl; diff --git a/backend/amd/amd_gpu/gpu.cpp b/backend/amd/amd_gpu/gpu.cpp index ebf1093..30aa5a8 100644 --- a/backend/amd/amd_gpu/gpu.cpp +++ b/backend/amd/amd_gpu/gpu.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -552,7 +553,7 @@ size_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx) #ifdef __GNUC__ cl_platform_id PlatformIDList[entries]; #else - cl_platform_id* PlatformIDList = _alloca(entries * sizeof(cl_platform_id)); + cl_platform_id* PlatformIDList = (cl_platform_id*)_alloca(entries * sizeof(cl_platform_id)); #endif if((ret = clGetPlatformIDs(entries, PlatformIDList, NULL)) != CL_SUCCESS) { @@ -579,7 +580,7 @@ size_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx) #ifdef __GNUC__ cl_device_id DeviceIDList[entries]; #else - cl_device_id* DeviceIDList = _alloca(entries * sizeof(cl_device_id)); + cl_device_id* DeviceIDList = (cl_device_id*)_alloca(entries * sizeof(cl_device_id)); #endif if((ret = clGetDeviceIDs(PlatformIDList[platform_idx], CL_DEVICE_TYPE_GPU, entries, DeviceIDList, NULL)) != CL_SUCCESS) { @@ -591,7 +592,7 @@ size_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx) #ifdef __GNUC__ cl_device_id TempDeviceList[num_gpus]; #else - cl_device_id* TempDeviceList = _alloca(entries * sizeof(cl_device_id)); + cl_device_id* TempDeviceList = (cl_device_id*)_alloca(entries * sizeof(cl_device_id)); #endif for(int i = 0; i < num_gpus; ++i) { diff --git a/backend/amd/minethd.h b/backend/amd/minethd.h index d308110..349dcfd 100644 --- a/backend/amd/minethd.h +++ b/backend/amd/minethd.h @@ -30,7 +30,7 @@ private: // Bottom 24 bits allow for an hour of work at 4000 H/s inline uint32_t calc_start_nonce(uint32_t resume) { - return reverseBits(iThreadNo + GlobalStates::iThreadCount * resume); + return reverseBits(static_cast(iThreadNo + GlobalStates::iThreadCount * resume)); } void work_main(); diff --git a/backend/cpu/minethd.h b/backend/cpu/minethd.h index 3997daa..44b216c 100644 --- a/backend/cpu/minethd.h +++ b/backend/cpu/minethd.h @@ -40,13 +40,13 @@ private: // Bottom 22 bits allow for an hour of work at 1000 H/s inline uint32_t calc_start_nonce(uint32_t resume) { - return reverseBits(iThreadNo + GlobalStates::iThreadCount * resume); + return reverseBits(static_cast(iThreadNo + GlobalStates::iThreadCount * resume)); } // Limited version of the nonce calc above inline uint32_t calc_nicehash_nonce(uint32_t start, uint32_t resume) { - return start | ( ( reverseBits(iThreadNo + GlobalStates::iThreadCount * resume) >> 4u ) ); + return start | ( ( reverseBits(static_cast(iThreadNo + GlobalStates::iThreadCount * resume)) >> 4u ) ); } void work_main(); diff --git a/cli-miner.cpp b/cli/cli-miner.cpp similarity index 95% rename from cli-miner.cpp rename to cli/cli-miner.cpp index d7d2781..3129f34 100644 --- a/cli-miner.cpp +++ b/cli/cli-miner.cpp @@ -21,18 +21,18 @@ * */ -#include "executor.h" -#include "backend/miner_work.h" -#include "backend/GlobalStates.hpp" -#include "backend/BackendConnector.hpp" -#include "jconf.h" -#include "console.h" -#include "donate-level.h" +#include "../executor.h" +#include "../backend/miner_work.h" +#include "../backend/GlobalStates.hpp" +#include "../backend/BackendConnector.hpp" +#include "../jconf.h" +#include "../console.h" +#include "../donate-level.h" -#include "version.h" +#include "../version.h" #ifndef CONF_NO_HTTPD -# include "httpd.h" +# include "../httpd.h" #endif #include diff --git a/jconf.cpp b/jconf.cpp index 60075d9..f5fb3bc 100644 --- a/jconf.cpp +++ b/jconf.cpp @@ -310,13 +310,6 @@ bool jconf::parse_config(const char* sFilename) } #endif // CONF_NO_TLS -#ifdef _WIN32 - if(GetSlowMemSetting() == no_mlck) - { - printer::inst()->print_msg(L0, "On Windows large pages need mlock. Please use another option."); - return false; - } -#endif // _WIN32 printer::inst()->set_verbose_level(prv->configValues[iVerboseLevel]->GetUint64()); From 47a9063e270bc6c8bc766560b1c304f1ba8bf9c4 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 24 Sep 2017 21:23:33 +0200 Subject: [PATCH 09/42] add CMake flags to disable backends - add `CUDA_ENABLE` - add `OpenCL_ENABLE` --- CMakeLists.txt | 180 ++++++++++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 85 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3412b3c..e9cbddd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,99 +43,104 @@ option(CMAKE_LINK_STATIC "link as much as possible libraries static" OFF) #option(CUDA_USE_STATIC_CUDA_RUNTIME "Use the static version of the CUDA runtime library if available" OFF) #set(CUDA_USE_STATIC_CUDA_RUNTIME OFF CACHE BOOL "Use the static version of the CUDA runtime library if available" FORCE) -find_package(CUDA 7.5 QUIET) +option(CUDA_ENABLE "Enable or disable NVIDIA CUDA support" ON) +if(CUDA_ENABLE) + find_package(CUDA 7.5 QUIET) -if(CUDA_FOUND) + if(CUDA_FOUND) - option(XMR-STAK_LARGEGRID "Support large CUDA block count > 128" ON) - if(XMR-STAK_LARGEGRID) - add_definitions("-DXMR_STAK_LARGEGRID=${XMR-STAK_LARGEGRID}") - endif() - - set(DEVICE_COMPILER "nvcc") - set(CUDA_COMPILER "${DEVICE_COMPILER}" CACHE STRING "Select the device compiler") - - if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") - list(APPEND DEVICE_COMPILER "clang") - endif() - - set_property(CACHE CUDA_COMPILER PROPERTY STRINGS "${DEVICE_COMPILER}") - - set(XMR-STAK_THREADS 0 CACHE STRING "Set maximum number of threads (for compile time optimization)") - if(NOT XMR-STAK_THREADS EQUAL 0) - message(STATUS "xmr-stak-nvidia: set max threads per block to ${XMR-STAK_THREADS}") - add_definitions("-DXMR_STAK_THREADS=${XMR-STAK_THREADS}") - endif() - - set(CUDA_ARCH "20;30;35;37;50;52;60;61;62" CACHE STRING "Set GPU architecture (semicolon separated list, e.g. '-DCUDA_ARCH=20;35;60')") - - # validate architectures (only numbers are allowed) - foreach(CUDA_ARCH_ELEM ${CUDA_ARCH}) - string(REGEX MATCH "^[0-9]+$" IS_NUMBER ${CUDA_ARCH}) - if(NOT IS_NUMBER) - message(FATAL_ERROR "Defined compute architecture '${CUDA_ARCH_ELEM}' in " - "'${CUDA_ARCH}' is not an integral number, use e.g. '30' (for compute architecture 3.0).") + option(XMR-STAK_LARGEGRID "Support large CUDA block count > 128" ON) + if(XMR-STAK_LARGEGRID) + add_definitions("-DXMR_STAK_LARGEGRID=${XMR-STAK_LARGEGRID}") endif() - unset(IS_NUMBER) - if(${CUDA_ARCH_ELEM} LESS 20) - message(FATAL_ERROR "Unsupported CUDA architecture '${CUDA_ARCH_ELEM}' specified. " - "Use '20' (for compute architecture 2.0) or higher.") + set(DEVICE_COMPILER "nvcc") + set(CUDA_COMPILER "${DEVICE_COMPILER}" CACHE STRING "Select the device compiler") + + if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + list(APPEND DEVICE_COMPILER "clang") endif() - endforeach() - option(CUDA_SHOW_REGISTER "Show registers used for each kernel and compute architecture" OFF) - option(CUDA_KEEP_FILES "Keep all intermediate files that are generated during internal compilation steps" OFF) + set_property(CACHE CUDA_COMPILER PROPERTY STRINGS "${DEVICE_COMPILER}") - if("${CUDA_COMPILER}" STREQUAL "clang") - set(CLANG_BUILD_FLAGS "-O3 -x cuda --cuda-path=${CUDA_TOOLKIT_ROOT_DIR}") - # activation usage of FMA - set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} -ffp-contract=fast") + set(XMR-STAK_THREADS 0 CACHE STRING "Set maximum number of threads (for compile time optimization)") + if(NOT XMR-STAK_THREADS EQUAL 0) + message(STATUS "xmr-stak-nvidia: set max threads per block to ${XMR-STAK_THREADS}") + add_definitions("-DXMR_STAK_THREADS=${XMR-STAK_THREADS}") + endif() - if(CUDA_SHOW_REGISTER) - set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} -Xcuda-ptxas -v") - endif(CUDA_SHOW_REGISTER) - - if(CUDA_KEEP_FILES) - set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} -save-temps=${PROJECT_BINARY_DIR}") - endif(CUDA_KEEP_FILES) + set(CUDA_ARCH "20;30;35;37;50;52;60;61;62" CACHE STRING "Set GPU architecture (semicolon separated list, e.g. '-DCUDA_ARCH=20;35;60')") + # validate architectures (only numbers are allowed) foreach(CUDA_ARCH_ELEM ${CUDA_ARCH}) - # set flags to create device code for the given architectures - set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} --cuda-gpu-arch=sm_${CUDA_ARCH_ELEM}") + string(REGEX MATCH "^[0-9]+$" IS_NUMBER ${CUDA_ARCH}) + if(NOT IS_NUMBER) + message(FATAL_ERROR "Defined compute architecture '${CUDA_ARCH_ELEM}' in " + "'${CUDA_ARCH}' is not an integral number, use e.g. '30' (for compute architecture 3.0).") + endif() + unset(IS_NUMBER) + + if(${CUDA_ARCH_ELEM} LESS 20) + message(FATAL_ERROR "Unsupported CUDA architecture '${CUDA_ARCH_ELEM}' specified. " + "Use '20' (for compute architecture 2.0) or higher.") + endif() endforeach() - elseif("${CUDA_COMPILER}" STREQUAL "nvcc") - # avoid that nvcc in CUDA < 8 tries to use libc `memcpy` within the kernel - if(CUDA_VERSION VERSION_LESS 8.0) - add_definitions(-D_FORCE_INLINES) + option(CUDA_SHOW_REGISTER "Show registers used for each kernel and compute architecture" OFF) + option(CUDA_KEEP_FILES "Keep all intermediate files that are generated during internal compilation steps" OFF) + + if("${CUDA_COMPILER}" STREQUAL "clang") + set(CLANG_BUILD_FLAGS "-O3 -x cuda --cuda-path=${CUDA_TOOLKIT_ROOT_DIR}") + # activation usage of FMA + set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} -ffp-contract=fast") + + if(CUDA_SHOW_REGISTER) + set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} -Xcuda-ptxas -v") + endif(CUDA_SHOW_REGISTER) + + if(CUDA_KEEP_FILES) + set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} -save-temps=${PROJECT_BINARY_DIR}") + endif(CUDA_KEEP_FILES) + + foreach(CUDA_ARCH_ELEM ${CUDA_ARCH}) + # set flags to create device code for the given architectures + set(CLANG_BUILD_FLAGS "${CLANG_BUILD_FLAGS} --cuda-gpu-arch=sm_${CUDA_ARCH_ELEM}") + endforeach() + + elseif("${CUDA_COMPILER}" STREQUAL "nvcc") + # avoid that nvcc in CUDA < 8 tries to use libc `memcpy` within the kernel + if(CUDA_VERSION VERSION_LESS 8.0) + add_definitions(-D_FORCE_INLINES) + endif() + foreach(CUDA_ARCH_ELEM ${CUDA_ARCH}) + # set flags to create device code for the given architecture + set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} + "--generate-code arch=compute_${CUDA_ARCH_ELEM},code=sm_${CUDA_ARCH_ELEM} --generate-code arch=compute_${CUDA_ARCH_ELEM},code=compute_${CUDA_ARCH_ELEM}") + endforeach() + + # give each thread an independent default stream + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --default-stream per-thread") + + option(CUDA_SHOW_CODELINES "Show kernel lines in cuda-gdb and cuda-memcheck" OFF) + + if(CUDA_SHOW_CODELINES) + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" --source-in-ptx -lineinfo) + set(CUDA_KEEP_FILES ON CACHE BOOL "activate keep files" FORCE) + endif(CUDA_SHOW_CODELINES) + + if(CUDA_SHOW_REGISTER) + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" -Xptxas=-v) + endif(CUDA_SHOW_REGISTER) + + if(CUDA_KEEP_FILES) + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" --keep --keep-dir "${PROJECT_BINARY_DIR}") + endif(CUDA_KEEP_FILES) + + else() + message(FATAL_ERROR "selected CUDA compiler '${CUDA_COMPILER}' is not supported") endif() - foreach(CUDA_ARCH_ELEM ${CUDA_ARCH}) - # set flags to create device code for the given architecture - set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} - "--generate-code arch=compute_${CUDA_ARCH_ELEM},code=sm_${CUDA_ARCH_ELEM} --generate-code arch=compute_${CUDA_ARCH_ELEM},code=compute_${CUDA_ARCH_ELEM}") - endforeach() - - # give each thread an independent default stream - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --default-stream per-thread") - - option(CUDA_SHOW_CODELINES "Show kernel lines in cuda-gdb and cuda-memcheck" OFF) - - if(CUDA_SHOW_CODELINES) - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" --source-in-ptx -lineinfo) - set(CUDA_KEEP_FILES ON CACHE BOOL "activate keep files" FORCE) - endif(CUDA_SHOW_CODELINES) - - if(CUDA_SHOW_REGISTER) - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" -Xptxas=-v) - endif(CUDA_SHOW_REGISTER) - - if(CUDA_KEEP_FILES) - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" --keep --keep-dir "${PROJECT_BINARY_DIR}") - endif(CUDA_KEEP_FILES) - else() - message(FATAL_ERROR "selected CUDA compiler '${CUDA_COMPILER}' is not supported") + message(FATAL_ERROR "CUDA NOT found: use `-DCUDA_ENABLE=OFF` to build without NVIDIA GPU support") endif() else() add_definitions("-DCONF_NO_CUDA") @@ -150,12 +155,17 @@ list(APPEND CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}") # Find OpenCL ############################################################################### -find_package(OpenCL) -include_directories(SYSTEM ${OpenCL_INCLUDE_DIRS}) -#set(LIBS ${LIBS} ${OpenCL_LIBRARY}) -link_directories(${OpenCL_LIBRARY}) - -if(NOT OpenCL_FOUND) +option(OpenCL_ENABLE "Enable or disable the requirement of hwloc" ON) +if(OpenCL_ENABLE) + find_package(OpenCL QUIET) + if(OpenCL_FOUND) + include_directories(SYSTEM ${OpenCL_INCLUDE_DIRS}) + #set(LIBS ${LIBS} ${OpenCL_LIBRARY}) + link_directories(${OpenCL_LIBRARY}) + else() + message(FATAL_ERROR "OpenCL NOT found: use `-DOpenCL_ENABLE=OFF` to build without OpenCL support for AMD gpu's") + endif() +else() add_definitions("-DCONF_NO_OPENCL") endif() From 2c5c6f382a74538ceb028a61e49ebd01447efaa4 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 24 Sep 2017 21:32:09 +0200 Subject: [PATCH 10/42] add option to disable CPU backend --- CMakeLists.txt | 13 +++++++++++-- backend/BackendConnector.cpp | 12 +++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e9cbddd..6ff459f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,7 @@ option(CMAKE_LINK_STATIC "link as much as possible libraries static" OFF) #option(CUDA_USE_STATIC_CUDA_RUNTIME "Use the static version of the CUDA runtime library if available" OFF) #set(CUDA_USE_STATIC_CUDA_RUNTIME OFF CACHE BOOL "Use the static version of the CUDA runtime library if available" FORCE) -option(CUDA_ENABLE "Enable or disable NVIDIA CUDA support" ON) +option(CUDA_ENABLE "Enable or disable CUDA support (NVIDIA backend)" ON) if(CUDA_ENABLE) find_package(CUDA 7.5 QUIET) @@ -155,7 +155,7 @@ list(APPEND CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}") # Find OpenCL ############################################################################### -option(OpenCL_ENABLE "Enable or disable the requirement of hwloc" ON) +option(OpenCL_ENABLE "Enable or disable OpenCL spport (AMD GPU support)" ON) if(OpenCL_ENABLE) find_package(OpenCL QUIET) if(OpenCL_FOUND) @@ -169,6 +169,15 @@ else() add_definitions("-DCONF_NO_OPENCL") endif() +############################################################################### +# CPU backend +############################################################################### + +option(CPU_ENABLE "Enable or disable CPU support" ON) +if(NOT CPU_ENABLE) + add_definitions("-DCONF_NO_CPU") +endif() + ################################################################################ # Find PThreads ################################################################################ diff --git a/backend/BackendConnector.cpp b/backend/BackendConnector.cpp index bb03e69..6abc379 100644 --- a/backend/BackendConnector.cpp +++ b/backend/BackendConnector.cpp @@ -62,11 +62,6 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) std::vector* pvThreads = new std::vector; - auto cpuThreads = cpu::minethd::thread_starter(static_cast(pvThreads->size()), pWork); - pvThreads->insert(std::end(*pvThreads), std::begin(cpuThreads), std::end(cpuThreads)); - if(cpuThreads.size() == 0) - printer::inst()->print_msg(L0, "WARNING: backend CPU disabled."); - #ifndef CONF_NO_CUDA Plugin nvidiaPlugin("NVIDIA", "libxmrstak_cuda_backend"); std::vector* nvidiaThreads = nvidiaPlugin.startBackend(static_cast(pvThreads->size()), pWork); @@ -82,6 +77,13 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) if(amdThreads->size() == 0) printer::inst()->print_msg(L0, "WARNING: backend AMD disabled."); #endif + +#ifndef CONF_NO_CPU + auto cpuThreads = cpu::minethd::thread_starter(static_cast(pvThreads->size()), pWork); + pvThreads->insert(std::end(*pvThreads), std::begin(cpuThreads), std::end(cpuThreads)); + if(cpuThreads.size() == 0) + printer::inst()->print_msg(L0, "WARNING: backend CPU disabled."); +#endif GlobalStates::iThreadCount = pvThreads->size(); return pvThreads; From 87357352c9db1b94289afbfce017ed9a0bd89dcc Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 24 Sep 2017 21:44:03 +0200 Subject: [PATCH 11/42] simplify templates --- backend/amd/autoAdjust.hpp | 2 -- backend/amd/config.tpl | 7 ++++++- backend/cpu/autoAdjust.hpp | 3 --- backend/cpu/autoAdjustHwloc.hpp | 2 -- backend/cpu/config.tpl | 3 +++ backend/nvidia/autoAdjust.hpp | 2 -- backend/nvidia/config.tpl | 3 +++ 7 files changed, 12 insertions(+), 10 deletions(-) diff --git a/backend/amd/autoAdjust.hpp b/backend/amd/autoAdjust.hpp index fd9ea94..de67456 100644 --- a/backend/amd/autoAdjust.hpp +++ b/backend/amd/autoAdjust.hpp @@ -80,7 +80,6 @@ private: configTpl.set( std::string(tpl) ); std::string conf; - conf += std::string("\"gpu_threads_conf\" :\n[\n"); int i = 0; for(auto& ctx : devVec) { @@ -97,7 +96,6 @@ private: " },\n"; ++i; } - conf += std::string("],\n\n"); configTpl.replace("PLATFORMINDEX",std::to_string(platformIndex)); configTpl.replace("NUMGPUS",std::to_string(devVec.size())); diff --git a/backend/amd/config.tpl b/backend/amd/config.tpl index 6d08730..b8b6dc4 100644 --- a/backend/amd/config.tpl +++ b/backend/amd/config.tpl @@ -11,10 +11,15 @@ R"===( * intensity - Number of parallel GPU threads (nothing to do with CPU threads) * worksize - Number of local GPU threads (nothing to do with CPU threads) * affine_to_cpu - This will affine the thread to a CPU. This can make a GPU miner play along nicer with a CPU miner. + * "gpu_threads_conf" : + * [ + * { "index" : 0, "intensity" : 1000, "worksize" : 8, "affine_to_cpu" : false }, + * ], */ - +"gpu_threads_conf" : [ GPUCONFIG +], /* * Platform index. This will be 0 unless you have different OpenCL platform - eg. AMD and Intel. diff --git a/backend/cpu/autoAdjust.hpp b/backend/cpu/autoAdjust.hpp index 67a2142..e7f35a9 100644 --- a/backend/cpu/autoAdjust.hpp +++ b/backend/cpu/autoAdjust.hpp @@ -44,7 +44,6 @@ public: configTpl.set( std::string(tpl) ); std::string conf; - conf += std::string("\"cpu_threads_conf\" :\n[\n"); if(!detectL3Size() || L3KB_size < 1024 || L3KB_size > 102400) { @@ -96,8 +95,6 @@ public: } } - conf += std::string("],\n\n"); - configTpl.replace("CPUCONFIG",conf); configTpl.write("cpu.txt"); printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", "cpu.txt"); diff --git a/backend/cpu/autoAdjustHwloc.hpp b/backend/cpu/autoAdjustHwloc.hpp index 968aac7..161aa5c 100644 --- a/backend/cpu/autoAdjustHwloc.hpp +++ b/backend/cpu/autoAdjustHwloc.hpp @@ -42,7 +42,6 @@ public: ; configTpl.set( std::string(tpl) ); - conf += std::string("\"cpu_threads_conf\" :\n[\n"); try { std::vector tlcs; @@ -73,7 +72,6 @@ public: conf += std::string(" { \"low_power_mode\" : false, \"no_prefetch\" : true, \"affine_to_cpu\" : false },\n"); printer::inst()->print_msg(L0, "Autoconf FAILED: %s. Create config for a single thread.", err.what()); } - conf += std::string("],\n\n"); configTpl.replace("CPUCONFIG",conf); configTpl.write("cpu.txt"); diff --git a/backend/cpu/config.tpl b/backend/cpu/config.tpl index 43c1cb8..7d57340 100644 --- a/backend/cpu/config.tpl +++ b/backend/cpu/config.tpl @@ -24,7 +24,10 @@ R"===( * ], */ +"cpu_threads_conf" : +[ CPUCONFIG +], /* * LARGE PAGE SUPPORT diff --git a/backend/nvidia/autoAdjust.hpp b/backend/nvidia/autoAdjust.hpp index be9b53d..41599b7 100644 --- a/backend/nvidia/autoAdjust.hpp +++ b/backend/nvidia/autoAdjust.hpp @@ -86,7 +86,6 @@ private: configTpl.set( std::string(tpl) ); std::string conf; - conf += std::string("\"gpu_threads_conf\" :\n[\n"); int i = 0; for(auto& ctx : nvidCtxVec) { @@ -98,7 +97,6 @@ private: " },\n"; ++i; } - conf += std::string("],\n\n"); configTpl.replace("GPUCONFIG",conf); configTpl.write("nvidia.txt"); diff --git a/backend/nvidia/config.tpl b/backend/nvidia/config.tpl index bf7a614..99dc023 100644 --- a/backend/nvidia/config.tpl +++ b/backend/nvidia/config.tpl @@ -20,6 +20,9 @@ R"===( * ], */ +"gpu_threads_conf" : +[ GPUCONFIG +], )===" From ef551cc032716d8cb21ecfdff73bb6c2bc581740 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Mon, 25 Sep 2017 09:40:43 +0200 Subject: [PATCH 12/42] fix windows compile - fix build documentation - fix plugin load methods - fix symbol export for plugins --- CMakeLists.txt | 4 ++-- WINCOMPILE.md | 2 +- backend/BackendConnector.cpp | 4 ++-- backend/Plugin.hpp | 12 ++++++------ backend/amd/minethd.cpp | 8 ++++++-- backend/nvidia/autoAdjust.hpp | 2 +- backend/nvidia/minethd.cpp | 8 +++++++- 7 files changed, 25 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ff459f..8871951 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -390,7 +390,7 @@ if( NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "${PROJECT_BINARY_DIR}" ) LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") endif() endif() - +else() set(WIN_OUTPUT_RELEASE "/Release") endif() @@ -400,7 +400,7 @@ install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/opencl" # avoid overwrite of user defined settings # install `config.txt`if file not exists in `${CMAKE_INSTALL_PREFIX}/bin` install(CODE " \ - if(NOT EXISTS ${CMAKE_INSTALL_PREFIX}/bin/config.txt)\n \ + if(NOT EXISTS ${CMAKE_INSTALL_PREFIX}/bin${WIN_OUTPUT_RELEASE}/config.txt)\n \ file(INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/config.txt \ DESTINATION ${CMAKE_INSTALL_PREFIX}/bin${WIN_OUTPUT_RELEASE})\n \ endif()" diff --git a/WINCOMPILE.md b/WINCOMPILE.md index 13bbf9e..f70ecff 100644 --- a/WINCOMPILE.md +++ b/WINCOMPILE.md @@ -67,7 +67,7 @@ set CMAKE_PREFIX_PATH=C:\xmr-stak-dep\hwloc;C:\xmr-stak-dep\libmicrohttpd;C:\xmr-stak-dep\openssl mkdir build cd build - cmake -G "Visual Studio 15 2017 Win64" -T v141,host=x64 .. + cmake -G "Visual Studio 15 2017 Win64" -T v140,host=x64 .. cmake --build . --config Release --target install cd bin\Release ``` diff --git a/backend/BackendConnector.cpp b/backend/BackendConnector.cpp index 6abc379..f1b71b4 100644 --- a/backend/BackendConnector.cpp +++ b/backend/BackendConnector.cpp @@ -63,7 +63,7 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) std::vector* pvThreads = new std::vector; #ifndef CONF_NO_CUDA - Plugin nvidiaPlugin("NVIDIA", "libxmrstak_cuda_backend"); + Plugin nvidiaPlugin("NVIDIA", "xmrstak_cuda_backend"); std::vector* nvidiaThreads = nvidiaPlugin.startBackend(static_cast(pvThreads->size()), pWork); pvThreads->insert(std::end(*pvThreads), std::begin(*nvidiaThreads), std::end(*nvidiaThreads)); if(nvidiaThreads->size() == 0) @@ -71,7 +71,7 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) #endif #ifndef CONF_NO_OPENCL - Plugin amdPlugin("AMD", "libxmrstak_opencl_backend"); + Plugin amdPlugin("AMD", "xmrstak_opencl_backend"); std::vector* amdThreads = amdPlugin.startBackend(static_cast(pvThreads->size()), pWork); pvThreads->insert(std::end(*pvThreads), std::begin(*amdThreads), std::end(*amdThreads)); if(amdThreads->size() == 0) diff --git a/backend/Plugin.hpp b/backend/Plugin.hpp index 347d5db..4c85375 100644 --- a/backend/Plugin.hpp +++ b/backend/Plugin.hpp @@ -27,14 +27,14 @@ struct Plugin { #ifdef WIN32 libBackend = LoadLibrary(TEXT((libName + ".dll").c_str())); - if (!libBackend) + if(!libBackend) { std::cerr << "WARNING: "<< m_backendName <<" cannot load backend library: " << (libName + ".dll") << std::endl; return; } #else - libBackend = dlopen((libName + ".so").c_str(), RTLD_LAZY); - if (!libBackend) + libBackend = dlopen((std::string("lib") + libName + ".so").c_str(), RTLD_LAZY); + if(!libBackend) { std::cerr << "WARNING: "<< m_backendName <<" cannot load backend library: " << dlerror() << std::endl; return; @@ -45,16 +45,16 @@ struct Plugin fn_starterBackend = (starterBackend_t) GetProcAddress(libBackend, "xmrstak_start_backend"); if (!fn_starterBackend) { - std::cerr << "WARNING: backend plugin " << libName << " contains no entry 'xmrstak_start_backend'" << std::endl; + std::cerr << "WARNING: backend plugin " << libName << " contains no entry 'xmrstak_start_backend': " <* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork) +extern "C" { +#ifdef WIN32 +__declspec(dllexport) +#endif +std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork) { return amd::minethd::thread_starter(threadOffset, pWork); } - +} // extern "C" bool minethd::init_gpus() { diff --git a/backend/nvidia/autoAdjust.hpp b/backend/nvidia/autoAdjust.hpp index 41599b7..0e6c40f 100644 --- a/backend/nvidia/autoAdjust.hpp +++ b/backend/nvidia/autoAdjust.hpp @@ -61,7 +61,7 @@ public: #endif if( cuda_get_deviceinfo(&ctx) != 1 ) { - printer::inst()->print_msg(L0, "Setup failed for GPU %d. Exitting.\n", cfg.id); + printer::inst()->print_msg(L0, "Setup failed for GPU %d. Exitting.\n", i); std::exit(0); } nvidCtxVec.push_back(ctx); diff --git a/backend/nvidia/minethd.cpp b/backend/nvidia/minethd.cpp index 9a331f3..d62728d 100644 --- a/backend/nvidia/minethd.cpp +++ b/backend/nvidia/minethd.cpp @@ -105,10 +105,16 @@ bool minethd::self_test() } -extern "C" std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork) +extern "C" +{ +#ifdef WIN32 +__declspec(dllexport) +#endif +std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork) { return nvidia::minethd::thread_starter(threadOffset, pWork); } +} // extern "C" std::vector* minethd::thread_starter(uint32_t threadOffset, miner_work& pWork) { From b1e92092bb5c93863d869a2d6b6e057918a77b2f Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Wed, 27 Sep 2017 16:22:34 +0200 Subject: [PATCH 13/42] fix singleton issues on windows - pass all singletons into the backend libraries - move some cpu config features from the cpu config file to the global config.txt - add global jconf to the xported singleton list --- Environment.hpp | 42 ++++++++++++++++ backend/BackendConnector.cpp | 11 +++-- backend/GlobalStates.cpp | 4 -- backend/GlobalStates.hpp | 25 ++++++++-- backend/Plugin.hpp | 9 ++-- backend/amd/minethd.cpp | 26 +++++----- backend/amd/minethd.h | 3 +- backend/cpu/autoAdjust.hpp | 9 ++-- backend/cpu/config.tpl | 61 ----------------------- backend/cpu/jconf.cpp | 94 +----------------------------------- backend/cpu/jconf.h | 18 +------ backend/cpu/minethd.cpp | 53 ++++++++++---------- backend/cpu/minethd.h | 4 +- backend/miner_work.h | 1 + backend/nvidia/minethd.cpp | 27 ++++++----- backend/nvidia/minethd.h | 5 +- cli/cli-miner.cpp | 2 +- config.txt | 91 ++++++++++++++++++++++++++++------ console.cpp | 2 - console.h | 8 +-- executor.cpp | 6 +-- jconf.cpp | 92 +++++++++++++++++++++++++++++++++-- jconf.h | 16 ++++-- 23 files changed, 330 insertions(+), 279 deletions(-) create mode 100644 Environment.hpp diff --git a/Environment.hpp b/Environment.hpp new file mode 100644 index 0000000..9f887a1 --- /dev/null +++ b/Environment.hpp @@ -0,0 +1,42 @@ +#pragma once + +class printer; +class jconf; + +namespace xmrstak +{ + +class GlobalStates; + +struct Environment +{ + + static Environment& inst() + { + static Environment env; + return env; + } + + Environment& operator=(const Environment& env) + { + this->pPrinter = env.pPrinter; + this->pGlobalStates = env.pGlobalStates; + this->pJconfConfig = env.pJconfConfig; + return *this; + } + + + Environment() : pPrinter(nullptr), pGlobalStates(nullptr) + { + } + + + printer* pPrinter; + + GlobalStates* pGlobalStates; + + jconf* pJconfConfig; + +}; + +} // namepsace xmrstak diff --git a/backend/BackendConnector.cpp b/backend/BackendConnector.cpp index f1b71b4..194cb5c 100644 --- a/backend/BackendConnector.cpp +++ b/backend/BackendConnector.cpp @@ -43,6 +43,7 @@ #include #include "Plugin.hpp" +#include "../Environment.hpp" namespace xmrstak { @@ -56,15 +57,15 @@ bool BackendConnector::self_test() std::vector* BackendConnector::thread_starter(miner_work& pWork) { - GlobalStates::iGlobalJobNo = 0; - GlobalStates::iConsumeCnt = 0; + GlobalStates::inst().iGlobalJobNo = 0; + GlobalStates::inst().iConsumeCnt = 0; std::vector* pvThreads = new std::vector; #ifndef CONF_NO_CUDA Plugin nvidiaPlugin("NVIDIA", "xmrstak_cuda_backend"); - std::vector* nvidiaThreads = nvidiaPlugin.startBackend(static_cast(pvThreads->size()), pWork); + std::vector* nvidiaThreads = nvidiaPlugin.startBackend(static_cast(pvThreads->size()), pWork, Environment::inst()); pvThreads->insert(std::end(*pvThreads), std::begin(*nvidiaThreads), std::end(*nvidiaThreads)); if(nvidiaThreads->size() == 0) printer::inst()->print_msg(L0, "WARNING: backend NVIDIA disabled."); @@ -72,7 +73,7 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) #ifndef CONF_NO_OPENCL Plugin amdPlugin("AMD", "xmrstak_opencl_backend"); - std::vector* amdThreads = amdPlugin.startBackend(static_cast(pvThreads->size()), pWork); + std::vector* amdThreads = amdPlugin.startBackend(static_cast(pvThreads->size()), pWork, Environment::inst()); pvThreads->insert(std::end(*pvThreads), std::begin(*amdThreads), std::end(*amdThreads)); if(amdThreads->size() == 0) printer::inst()->print_msg(L0, "WARNING: backend AMD disabled."); @@ -85,7 +86,7 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) printer::inst()->print_msg(L0, "WARNING: backend CPU disabled."); #endif - GlobalStates::iThreadCount = pvThreads->size(); + GlobalStates::inst().iThreadCount = pvThreads->size(); return pvThreads; } diff --git a/backend/GlobalStates.cpp b/backend/GlobalStates.cpp index 99356b5..5251da8 100644 --- a/backend/GlobalStates.cpp +++ b/backend/GlobalStates.cpp @@ -33,10 +33,6 @@ namespace xmrstak { -std::atomic GlobalStates::iGlobalJobNo; -std::atomic GlobalStates::iConsumeCnt; //Threads get jobs as they are initialized -miner_work GlobalStates::oGlobalWork; -uint64_t GlobalStates::iThreadCount = 0; void GlobalStates::switch_work(miner_work& pWork) { diff --git a/backend/GlobalStates.hpp b/backend/GlobalStates.hpp index 293009d..a9818ba 100644 --- a/backend/GlobalStates.hpp +++ b/backend/GlobalStates.hpp @@ -1,6 +1,7 @@ #pragma once #include #include "miner_work.h" +#include "../Environment.hpp" namespace xmrstak { @@ -8,12 +9,26 @@ namespace xmrstak struct GlobalStates { - static void switch_work(miner_work& pWork); + static inline GlobalStates& inst() + { + auto& env = Environment::inst(); + if(env.pGlobalStates == nullptr) + env.pGlobalStates = new GlobalStates; + return *env.pGlobalStates; + } - static miner_work oGlobalWork; - static std::atomic iGlobalJobNo; - static std::atomic iConsumeCnt; - static uint64_t iThreadCount; + void switch_work(miner_work& pWork); + + miner_work oGlobalWork; + std::atomic iGlobalJobNo; + std::atomic iConsumeCnt; + uint64_t iThreadCount; + + private: + + GlobalStates() : iThreadCount(0) + { + } }; diff --git a/backend/Plugin.hpp b/backend/Plugin.hpp index 4c85375..9ba9716 100644 --- a/backend/Plugin.hpp +++ b/backend/Plugin.hpp @@ -5,6 +5,7 @@ #include #include "IBackend.hpp" #include +#include "../Environment.hpp" #ifndef USE_PRECOMPILED_HEADERS #ifdef WIN32 @@ -33,7 +34,7 @@ struct Plugin return; } #else - libBackend = dlopen((std::string("lib") + libName + ".so").c_str(), RTLD_LAZY); + libBackend = dlopen((std::string("./lib") + libName + ".so").c_str(), RTLD_LAZY); if(!libBackend) { std::cerr << "WARNING: "<< m_backendName <<" cannot load backend library: " << dlerror() << std::endl; @@ -59,7 +60,7 @@ struct Plugin #endif } - std::vector* startBackend(uint32_t threadOffset, miner_work& pWork) + std::vector* startBackend(uint32_t threadOffset, miner_work& pWork, Environment& env) { if(fn_starterBackend == nullptr) { @@ -68,12 +69,12 @@ struct Plugin return pvThreads; } - return fn_starterBackend(threadOffset, pWork); + return fn_starterBackend(threadOffset, pWork, env); } std::string m_backendName; - typedef std::vector* (*starterBackend_t)(uint32_t threadOffset, miner_work& pWork); + typedef std::vector* (*starterBackend_t)(uint32_t threadOffset, miner_work& pWork, Environment& env); starterBackend_t fn_starterBackend; diff --git a/backend/amd/minethd.cpp b/backend/amd/minethd.cpp index a7b84a7..0821c0e 100644 --- a/backend/amd/minethd.cpp +++ b/backend/amd/minethd.cpp @@ -33,12 +33,13 @@ #include "../../console.h" #include "../../crypto/cryptonight_aesni.h" #include "../cpu/minethd.h" -#include "../cpu/jconf.h" +#include "../../jconf.h" #include "../../executor.h" #include "minethd.h" #include "../../jconf.h" #include "../../crypto/cryptonight.h" +#include "../../Environment.hpp" #include "amd_gpu/gpu.h" @@ -64,8 +65,9 @@ extern "C" { #ifdef WIN32 __declspec(dllexport) #endif -std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork) +std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork, Environment& env) { + Environment::inst() = env; return amd::minethd::thread_starter(threadOffset, pWork); } } // extern "C" @@ -154,19 +156,19 @@ void minethd::switch_work(miner_work& pWork) // faster than threads can consume them. This should never happen in real life. // Pool cant physically send jobs faster than every 250ms or so due to net latency. - while (GlobalStates::iConsumeCnt.load(std::memory_order_seq_cst) < GlobalStates::iThreadCount) + while (GlobalStates::inst().iConsumeCnt.load(std::memory_order_seq_cst) < GlobalStates::inst().iThreadCount) std::this_thread::sleep_for(std::chrono::milliseconds(100)); - GlobalStates::oGlobalWork = pWork; - GlobalStates::iConsumeCnt.store(0, std::memory_order_seq_cst); - GlobalStates::iGlobalJobNo++; + GlobalStates::inst().oGlobalWork = pWork; + GlobalStates::inst().iConsumeCnt.store(0, std::memory_order_seq_cst); + GlobalStates::inst().iGlobalJobNo++; } void minethd::consume_work() { - memcpy(&oWork, &GlobalStates::oGlobalWork, sizeof(miner_work)); + memcpy(&oWork, &GlobalStates::inst().oGlobalWork, sizeof(miner_work)); iJobNo++; - GlobalStates::iConsumeCnt++; + GlobalStates::inst().iConsumeCnt++; } @@ -176,9 +178,9 @@ void minethd::work_main() cryptonight_ctx* cpu_ctx; cpu_ctx = cpu::minethd::minethd_alloc_ctx(); - cn_hash_fun hash_fun = cpu::minethd::func_selector(cpu::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/); + cn_hash_fun hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/); - GlobalStates::iConsumeCnt++; + GlobalStates::inst().iConsumeCnt++; while (bQuit == 0) { @@ -188,7 +190,7 @@ void minethd::work_main() either because of network latency, or a socket problem. Since we are raison d'etre of this software it us sensible to just wait until we have something*/ - while (GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while (GlobalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) std::this_thread::sleep_for(std::chrono::milliseconds(100)); consume_work(); @@ -200,7 +202,7 @@ void minethd::work_main() uint32_t target = oWork.iTarget32; XMRSetJob(pGpuCtx, oWork.bWorkBlob, oWork.iWorkSize, target); - while(GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while(GlobalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) { cl_uint results[0x100]; memset(results,0,sizeof(cl_uint)*(0x100)); diff --git a/backend/amd/minethd.h b/backend/amd/minethd.h index 349dcfd..4fb3b13 100644 --- a/backend/amd/minethd.h +++ b/backend/amd/minethd.h @@ -3,6 +3,7 @@ #include #include "./jconf.h" #include "../IBackend.hpp" +#include "../../Environment.hpp" #include "amd_gpu/gpu.h" @@ -30,7 +31,7 @@ private: // Bottom 24 bits allow for an hour of work at 4000 H/s inline uint32_t calc_start_nonce(uint32_t resume) { - return reverseBits(static_cast(iThreadNo + GlobalStates::iThreadCount * resume)); + return reverseBits(static_cast(iThreadNo + GlobalStates::inst().iThreadCount * resume)); } void work_main(); diff --git a/backend/cpu/autoAdjust.hpp b/backend/cpu/autoAdjust.hpp index e7f35a9..092f085 100644 --- a/backend/cpu/autoAdjust.hpp +++ b/backend/cpu/autoAdjust.hpp @@ -1,6 +1,7 @@ #pragma once #include "jconf.h" #include "../../console.h" +#include "../../jconf.h" #include "../../ConfigEditor.hpp" #include @@ -108,14 +109,14 @@ private: int32_t cpu_info[4]; char cpustr[13] = {0}; - xmrstak::cpu::jconf::cpuid(0, 0, cpu_info); + ::jconf::cpuid(0, 0, cpu_info); memcpy(cpustr, &cpu_info[1], 4); memcpy(cpustr+4, &cpu_info[3], 4); memcpy(cpustr+8, &cpu_info[2], 4); if(strcmp(cpustr, "GenuineIntel") == 0) { - xmrstak::cpu::jconf::cpuid(4, 3, cpu_info); + ::jconf::cpuid(4, 3, cpu_info); if(get_masked(cpu_info[0], 7, 5) != 3) { @@ -130,11 +131,11 @@ private: } else if(strcmp(cpustr, "AuthenticAMD") == 0) { - xmrstak::cpu::jconf::cpuid(0x80000006, 0, cpu_info); + ::jconf::cpuid(0x80000006, 0, cpu_info); L3KB_size = get_masked(cpu_info[3], 31, 18) * 512; - xmrstak::cpu::jconf::cpuid(1, 0, cpu_info); + ::jconf::cpuid(1, 0, cpu_info); if(get_masked(cpu_info[0], 11, 8) < 0x17) //0x17h is Zen old_amd = true; diff --git a/backend/cpu/config.tpl b/backend/cpu/config.tpl index 7d57340..990a31d 100644 --- a/backend/cpu/config.tpl +++ b/backend/cpu/config.tpl @@ -29,65 +29,4 @@ R"===( CPUCONFIG ], -/* - * LARGE PAGE SUPPORT - * Large pages need a properly set up OS. It can be difficult if you are not used to systems administration, - * but the performance results are worth the trouble - you will get around 20% boost. Slow memory mode is - * meant as a backup, you won't get stellar results there. If you are running into trouble, especially - * on Windows, please read the common issues in the README. - * - * By default we will try to allocate large pages. This means you need to "Run As Administrator" on Windows. - * You need to edit your system's group policies to enable locking large pages. Here are the steps from MSDN - * - * 1. On the Start menu, click Run. In the Open box, type gpedit.msc. - * 2. On the Local Group Policy Editor console, expand Computer Configuration, and then expand Windows Settings. - * 3. Expand Security Settings, and then expand Local Policies. - * 4. Select the User Rights Assignment folder. - * 5. The policies will be displayed in the details pane. - * 6. In the pane, double-click Lock pages in memory. - * 7. In the Local Security Setting – Lock pages in memory dialog box, click Add User or Group. - * 8. In the Select Users, Service Accounts, or Groups dialog box, add an account that you will run the miner on - * 9. Reboot for change to take effect. - * - * Windows also tends to fragment memory a lot. If you are running on a system with 4-8GB of RAM you might need - * to switch off all the auto-start applications and reboot to have a large enough chunk of contiguous memory. - * - * On Linux you will need to configure large page support "sudo sysctl -w vm.nr_hugepages=128" and increase your - * ulimit -l. To do do this you need to add following lines to /etc/security/limits.conf - "* soft memlock 262144" - * and "* hard memlock 262144". You can also do it Windows-style and simply run-as-root, but this is NOT - * recommended for security reasons. - * - * Memory locking means that the kernel can't swap out the page to disk - something that is unlikely to happen on a - * command line system that isn't starved of memory. I haven't observed any difference on a CLI Linux system between - * locked and unlocked memory. If that is your setup see option "no_mlck". - */ - -/* - * use_slow_memory defines our behavior with regards to large pages. There are three possible options here: - * always - Don't even try to use large pages. Always use slow memory. - * warn - We will try to use large pages, but fall back to slow memory if that fails. - * no_mlck - This option is only relevant on Linux, where we can use large pages without locking memory. - * It will never use slow memory, but it won't attempt to mlock - * never - If we fail to allocate large pages we will print an error and exit. - */ -"use_slow_memory" : "warn", - -/* - * NiceHash mode - * nicehash_nonce - Limit the nonce to 3 bytes as required by nicehash. This cuts all the safety margins, and - * if a block isn't found within 30 minutes then you might run into nonce collisions. Number - * of threads in this mode is hard-limited to 32. - */ -"nicehash_nonce" : false, - -/* - * Manual hardware AES override - * - * Some VMs don't report AES capability correctly. You can set this value to true to enforce hardware AES or - * to false to force disable AES or null to let the miner decide if AES is used. - * - * WARNING: setting this to true on a CPU that doesn't support hardware AES will crash the miner. - */ -"aes_override" : null, - )===" diff --git a/backend/cpu/jconf.cpp b/backend/cpu/jconf.cpp index e919096..021d607 100644 --- a/backend/cpu/jconf.cpp +++ b/backend/cpu/jconf.cpp @@ -50,7 +50,7 @@ using namespace rapidjson; /* * This enum needs to match index in oConfigValues, otherwise we will get a runtime error */ -enum configEnum { aCpuThreadsConf, sUseSlowMem, bNiceHashMode, bAesOverride }; +enum configEnum { aCpuThreadsConf, sUseSlowMem }; struct configVal { configEnum iName; @@ -61,10 +61,7 @@ struct configVal { // Same order as in configEnum, as per comment above // kNullType means any type configVal oConfigValues[] = { - { aCpuThreadsConf, "cpu_threads_conf", kNullType }, - { sUseSlowMem, "use_slow_memory", kStringType }, - { bNiceHashMode, "nicehash_nonce", kTrueType }, - { bAesOverride, "aes_override", kNullType } + { aCpuThreadsConf, "cpu_threads_conf", kNullType } }; constexpr size_t iConfigCnt = (sizeof(oConfigValues)/sizeof(oConfigValues[0])); @@ -141,21 +138,6 @@ bool jconf::GetThreadConfig(size_t id, thd_cfg &cfg) return true; } -jconf::slow_mem_cfg jconf::GetSlowMemSetting() -{ - const char* opt = prv->configValues[sUseSlowMem]->GetString(); - - if(strcasecmp(opt, "always") == 0) - return always_use; - else if(strcasecmp(opt, "no_mlck") == 0) - return no_mlck; - else if(strcasecmp(opt, "warn") == 0) - return print_warning; - else if(strcasecmp(opt, "never") == 0) - return never_use; - else - return unknown_value; -} size_t jconf::GetThreadCount() { @@ -165,54 +147,12 @@ size_t jconf::GetThreadCount() return 0; } -bool jconf::NeedsAutoconf() -{ - return !prv->configValues[aCpuThreadsConf]->IsArray(); -} - -bool jconf::NiceHashMode() -{ - return prv->configValues[bNiceHashMode]->GetBool(); -} - -void jconf::cpuid(uint32_t eax, int32_t ecx, int32_t val[4]) -{ - memset(val, 0, sizeof(int32_t)*4); - -#ifdef _WIN32 - __cpuidex(val, eax, ecx); -#else - __cpuid_count(eax, ecx, val[0], val[1], val[2], val[3]); -#endif -} - -bool jconf::check_cpu_features() -{ - constexpr int AESNI_BIT = 1 << 25; - constexpr int SSE2_BIT = 1 << 26; - int32_t cpu_info[4]; - bool bHaveSse2; - - cpuid(1, 0, cpu_info); - - bHaveAes = (cpu_info[2] & AESNI_BIT) != 0; - bHaveSse2 = (cpu_info[3] & SSE2_BIT) != 0; - - return bHaveSse2; -} - bool jconf::parse_config(const char* sFilename) { FILE * pFile; char * buffer; size_t flen; - if(!check_cpu_features()) - { - printer::inst()->print_msg(L0, "CPU support of SSE2 is required."); - return false; - } - pFile = fopen(sFilename, "rb"); if (pFile == NULL) { @@ -310,36 +250,6 @@ bool jconf::parse_config(const char* sFilename) } } - if(NiceHashMode() && GetThreadCount() >= 32) - { - printer::inst()->print_msg(L0, "You need to use less than 32 threads in NiceHash mode."); - return false; - } - - if(GetSlowMemSetting() == unknown_value) - { - printer::inst()->print_msg(L0, - "Invalid config file. use_slow_memory must be \"always\", \"no_mlck\", \"warn\" or \"never\""); - return false; - } - -#ifdef _WIN32 - if(GetSlowMemSetting() == no_mlck) - { - printer::inst()->print_msg(L0, "On Windows large pages need mlock. Please use another option."); - return false; - } -#endif // _WIN32 - - //if(NeedsAutoconf()) - // return true; - - if(prv->configValues[bAesOverride]->IsBool()) - bHaveAes = prv->configValues[bAesOverride]->GetBool(); - - if(!bHaveAes) - printer::inst()->print_msg(L0, "Your CPU doesn't support hardware AES. Don't expect high hashrates."); - return true; } diff --git a/backend/cpu/jconf.h b/backend/cpu/jconf.h index 39fe6d9..9b46552 100644 --- a/backend/cpu/jconf.h +++ b/backend/cpu/jconf.h @@ -24,35 +24,19 @@ public: long long iCpuAff; }; - enum slow_mem_cfg { - always_use, - no_mlck, - print_warning, - never_use, - unknown_value - }; - size_t GetThreadCount(); bool GetThreadConfig(size_t id, thd_cfg &cfg); bool NeedsAutoconf(); - slow_mem_cfg GetSlowMemSetting(); + - bool NiceHashMode(); - - inline bool HaveHardwareAes() { return bHaveAes; } - - static void cpuid(uint32_t eax, int32_t ecx, int32_t val[4]); private: jconf(); static jconf* oInst; - bool check_cpu_features(); struct opaque_private; opaque_private* prv; - - bool bHaveAes; }; } // namespace cpu diff --git a/backend/cpu/minethd.cpp b/backend/cpu/minethd.cpp index e6d1bd6..7991d86 100644 --- a/backend/cpu/minethd.cpp +++ b/backend/cpu/minethd.cpp @@ -31,6 +31,7 @@ #include "../IBackend.hpp" #include "../GlobalStates.hpp" #include "../../ConfigEditor.hpp" +#include "../../jconf.h" #include "../../executor.h" #include "minethd.h" @@ -129,21 +130,21 @@ cryptonight_ctx* minethd::minethd_alloc_ctx() cryptonight_ctx* ctx; alloc_msg msg = { 0 }; - switch (jconf::inst()->GetSlowMemSetting()) + switch (::jconf::inst()->GetSlowMemSetting()) { - case jconf::never_use: + case ::jconf::never_use: ctx = cryptonight_alloc_ctx(1, 1, &msg); if (ctx == NULL) printer::inst()->print_msg(L0, "MEMORY ALLOC FAILED: %s", msg.warning); return ctx; - case jconf::no_mlck: + case ::jconf::no_mlck: ctx = cryptonight_alloc_ctx(1, 0, &msg); if (ctx == NULL) printer::inst()->print_msg(L0, "MEMORY ALLOC FAILED: %s", msg.warning); return ctx; - case jconf::print_warning: + case ::jconf::print_warning: ctx = cryptonight_alloc_ctx(1, 1, &msg); if (msg.warning != NULL) printer::inst()->print_msg(L0, "MEMORY ALLOC FAILED: %s", msg.warning); @@ -151,10 +152,10 @@ cryptonight_ctx* minethd::minethd_alloc_ctx() ctx = cryptonight_alloc_ctx(0, 0, NULL); return ctx; - case jconf::always_use: + case ::jconf::always_use: return cryptonight_alloc_ctx(0, 0, NULL); - case jconf::unknown_value: + case ::jconf::unknown_value: return NULL; //Shut up compiler } @@ -167,27 +168,27 @@ bool minethd::self_test() size_t res; bool fatal = false; - switch (jconf::inst()->GetSlowMemSetting()) + switch (::jconf::inst()->GetSlowMemSetting()) { - case jconf::never_use: + case ::jconf::never_use: res = cryptonight_init(1, 1, &msg); fatal = true; break; - case jconf::no_mlck: + case ::jconf::no_mlck: res = cryptonight_init(1, 0, &msg); fatal = true; break; - case jconf::print_warning: + case ::jconf::print_warning: res = cryptonight_init(1, 1, &msg); break; - case jconf::always_use: + case ::jconf::always_use: res = cryptonight_init(0, 0, &msg); break; - case jconf::unknown_value: + case ::jconf::unknown_value: default: return false; //Shut up compiler } @@ -214,20 +215,20 @@ bool minethd::self_test() cn_hash_fun hashf; cn_hash_fun_dbl hashdf; - hashf = func_selector(jconf::inst()->HaveHardwareAes(), false); + hashf = func_selector(::jconf::inst()->HaveHardwareAes(), false); hashf("This is a test", 14, out, ctx0); bResult = memcmp(out, "\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 32) == 0; - hashf = func_selector(jconf::inst()->HaveHardwareAes(), true); + hashf = func_selector(::jconf::inst()->HaveHardwareAes(), true); hashf("This is a test", 14, out, ctx0); bResult &= memcmp(out, "\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 32) == 0; - hashdf = func_dbl_selector(jconf::inst()->HaveHardwareAes(), false); + hashdf = func_dbl_selector(::jconf::inst()->HaveHardwareAes(), false); hashdf("The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy log", 43, out, ctx0, ctx1); bResult &= memcmp(out, "\x3e\xbb\x7f\x9f\x7d\x27\x3d\x7c\x31\x8d\x86\x94\x77\x55\x0c\xc8\x00\xcf\xb1\x1b\x0c\xad\xb7\xff\xbd\xf6\xf8\x9f\x3a\x47\x1c\x59" "\xb4\x77\xd5\x02\xe4\xd8\x48\x7f\x42\xdf\xe3\x8e\xed\x73\x81\x7a\xda\x91\xb7\xe2\x63\xd2\x91\x71\xb6\x5c\x44\x3a\x01\x2a\x41\x22", 64) == 0; - hashdf = func_dbl_selector(jconf::inst()->HaveHardwareAes(), true); + hashdf = func_dbl_selector(::jconf::inst()->HaveHardwareAes(), true); hashdf("The quick brown fox jumps over the lazy dogThe quick brown fox jumps over the lazy log", 43, out, ctx0, ctx1); bResult &= memcmp(out, "\x3e\xbb\x7f\x9f\x7d\x27\x3d\x7c\x31\x8d\x86\x94\x77\x55\x0c\xc8\x00\xcf\xb1\x1b\x0c\xad\xb7\xff\xbd\xf6\xf8\x9f\x3a\x47\x1c\x59" "\xb4\x77\xd5\x02\xe4\xd8\x48\x7f\x42\xdf\xe3\x8e\xed\x73\x81\x7a\xda\x91\xb7\xe2\x63\xd2\x91\x71\xb6\x5c\x44\x3a\x01\x2a\x41\x22", 64) == 0; @@ -284,9 +285,9 @@ std::vector minethd::thread_starter(uint32_t threadOffset, miner_work void minethd::consume_work() { - memcpy(&oWork, &GlobalStates::oGlobalWork, sizeof(miner_work)); + memcpy(&oWork, &GlobalStates::inst().inst().oGlobalWork, sizeof(miner_work)); iJobNo++; - GlobalStates::iConsumeCnt++; + GlobalStates::inst().inst().iConsumeCnt++; } minethd::cn_hash_fun minethd::func_selector(bool bHaveAes, bool bNoPrefetch) @@ -336,12 +337,12 @@ void minethd::work_main() uint32_t* piNonce; job_result result; - hash_fun = func_selector(jconf::inst()->HaveHardwareAes(), bNoPrefetch); + hash_fun = func_selector(::jconf::inst()->HaveHardwareAes(), bNoPrefetch); ctx = minethd_alloc_ctx(); piHashVal = (uint64_t*)(result.bResult + 24); piNonce = (uint32_t*)(oWork.bWorkBlob + 39); - GlobalStates::iConsumeCnt++; + GlobalStates::inst().inst().iConsumeCnt++; while (bQuit == 0) { @@ -351,7 +352,7 @@ void minethd::work_main() either because of network latency, or a socket problem. Since we are raison d'etre of this software it us sensible to just wait until we have something*/ - while (GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while (GlobalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) std::this_thread::sleep_for(std::chrono::milliseconds(100)); consume_work(); @@ -366,7 +367,7 @@ void minethd::work_main() assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); memcpy(result.sJobID, oWork.sJobID, sizeof(job_result::sJobID)); - while(GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while(GlobalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) { if ((iCount & 0xF) == 0) //Store stats every 16 hashes { @@ -430,7 +431,7 @@ void minethd::double_work_main() uint32_t iNonce; job_result res; - hash_fun = func_dbl_selector(jconf::inst()->HaveHardwareAes(), bNoPrefetch); + hash_fun = func_dbl_selector(::jconf::inst()->HaveHardwareAes(), bNoPrefetch); ctx0 = minethd_alloc_ctx(); ctx1 = minethd_alloc_ctx(); @@ -439,7 +440,7 @@ void minethd::double_work_main() piNonce0 = (uint32_t*)(bDoubleWorkBlob + 39); piNonce1 = nullptr; - GlobalStates::iConsumeCnt++; + GlobalStates::inst().inst().iConsumeCnt++; while (bQuit == 0) { @@ -449,7 +450,7 @@ void minethd::double_work_main() either because of network latency, or a socket problem. Since we are raison d'etre of this software it us sensible to just wait until we have something*/ - while (GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while (GlobalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) std::this_thread::sleep_for(std::chrono::milliseconds(100)); consume_work(); @@ -466,7 +467,7 @@ void minethd::double_work_main() assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); - while (GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while (GlobalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) { if ((iCount & 0x7) == 0) //Store stats every 16 hashes { diff --git a/backend/cpu/minethd.h b/backend/cpu/minethd.h index 44b216c..40383cf 100644 --- a/backend/cpu/minethd.h +++ b/backend/cpu/minethd.h @@ -40,13 +40,13 @@ private: // Bottom 22 bits allow for an hour of work at 1000 H/s inline uint32_t calc_start_nonce(uint32_t resume) { - return reverseBits(static_cast(iThreadNo + GlobalStates::iThreadCount * resume)); + return reverseBits(static_cast(iThreadNo + GlobalStates::inst().iThreadCount * resume)); } // Limited version of the nonce calc above inline uint32_t calc_nicehash_nonce(uint32_t start, uint32_t resume) { - return start | ( ( reverseBits(static_cast(iThreadNo + GlobalStates::iThreadCount * resume)) >> 4u ) ); + return start | ( ( reverseBits(static_cast(iThreadNo + GlobalStates::inst().iThreadCount * resume)) >> 4u ) ); } void work_main(); diff --git a/backend/miner_work.h b/backend/miner_work.h index b922f4a..8349fda 100644 --- a/backend/miner_work.h +++ b/backend/miner_work.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace xmrstak { diff --git a/backend/nvidia/minethd.cpp b/backend/nvidia/minethd.cpp index d62728d..554ea69 100644 --- a/backend/nvidia/minethd.cpp +++ b/backend/nvidia/minethd.cpp @@ -30,12 +30,12 @@ #include "../../console.h" #include "../../crypto/cryptonight_aesni.h" #include "../cpu/minethd.h" -#include "../cpu/jconf.h" #include "../../executor.h" #include "minethd.h" #include "../../jconf.h" #include "../../crypto/cryptonight.h" +#include "../../Environment.hpp" #include "autoAdjust.hpp" @@ -85,7 +85,7 @@ bool minethd::self_test() bool bResult = true; ctx0 = new cryptonight_ctx; - if(cpu::jconf::inst()->HaveHardwareAes()) + if(::jconf::inst()->HaveHardwareAes()) { //cryptonight_hash_ctx("This is a test", 14, out, ctx0); bResult = memcmp(out, "\xa0\x84\xf0\x1d\x14\x37\xa0\x9c\x69\x85\x40\x1b\x60\xd4\x35\x54\xae\x10\x58\x02\xc5\xf5\xd8\xa9\xb3\x25\x36\x49\xc0\xbe\x66\x05", 32) == 0; @@ -110,8 +110,9 @@ extern "C" #ifdef WIN32 __declspec(dllexport) #endif -std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork) +std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork, Environment& env) { + Environment::inst() = env; return nvidia::minethd::thread_starter(threadOffset, pWork); } } // extern "C" @@ -173,19 +174,19 @@ void minethd::switch_work(miner_work& pWork) // faster than threads can consume them. This should never happen in real life. // Pool cant physically send jobs faster than every 250ms or so due to net latency. - while (GlobalStates::iConsumeCnt.load(std::memory_order_seq_cst) < GlobalStates::iThreadCount) + while (GlobalStates::inst().iConsumeCnt.load(std::memory_order_seq_cst) < GlobalStates::inst().iThreadCount) std::this_thread::sleep_for(std::chrono::milliseconds(100)); - GlobalStates::oGlobalWork = pWork; - GlobalStates::iConsumeCnt.store(0, std::memory_order_seq_cst); - GlobalStates::iGlobalJobNo++; + GlobalStates::inst().oGlobalWork = pWork; + GlobalStates::inst().iConsumeCnt.store(0, std::memory_order_seq_cst); + GlobalStates::inst().iGlobalJobNo++; } void minethd::consume_work() { - memcpy(&oWork, &GlobalStates::oGlobalWork, sizeof(miner_work)); + memcpy(&oWork, &GlobalStates::inst().oGlobalWork, sizeof(miner_work)); iJobNo++; - GlobalStates::iConsumeCnt++; + GlobalStates::inst().iConsumeCnt++; } void minethd::work_main() @@ -194,9 +195,9 @@ void minethd::work_main() uint32_t iNonce; cryptonight_ctx* cpu_ctx; cpu_ctx = cpu::minethd::minethd_alloc_ctx(); - cn_hash_fun hash_fun = cpu::minethd::func_selector(cpu::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/); + cn_hash_fun hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/); - GlobalStates::iConsumeCnt++; + GlobalStates::inst().iConsumeCnt++; if(/*cuda_get_deviceinfo(&ctx) != 1 ||*/ cryptonight_extra_cpu_init(&ctx) != 1) { @@ -212,7 +213,7 @@ void minethd::work_main() either because of network latency, or a socket problem. Since we are raison d'etre of this software it us sensible to just wait until we have something*/ - while (GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while (GlobalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) std::this_thread::sleep_for(std::chrono::milliseconds(100)); consume_work(); @@ -224,7 +225,7 @@ void minethd::work_main() assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); - while(GlobalStates::iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while(GlobalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) { uint32_t foundNonce[10]; diff --git a/backend/nvidia/minethd.h b/backend/nvidia/minethd.h index a4b095e..9f3993e 100644 --- a/backend/nvidia/minethd.h +++ b/backend/nvidia/minethd.h @@ -7,6 +7,7 @@ #include "../../jconf.h" #include "./jconf.h" #include "../IBackend.hpp" +#include "../../Environment.hpp" #include namespace xmrstak @@ -33,13 +34,13 @@ private: // Bottom 22 bits allow for an hour of work at 1000 H/s inline uint32_t calc_start_nonce(uint32_t resume) { - return reverseBits(iThreadNo + GlobalStates::iThreadCount * resume); + return reverseBits(iThreadNo + GlobalStates::inst().iThreadCount * resume); } // Limited version of the nonce calc above inline uint32_t calc_nicehash_nonce(uint32_t start, uint32_t resume) { - return start | ( ( reverseBits(iThreadNo + GlobalStates::iThreadCount * resume) >> 4u ) ); + return start | ( ( reverseBits(iThreadNo + GlobalStates::inst().iThreadCount * resume) >> 4u ) ); } void work_main(); diff --git a/cli/cli-miner.cpp b/cli/cli-miner.cpp index 3129f34..e5c5863 100644 --- a/cli/cli-miner.cpp +++ b/cli/cli-miner.cpp @@ -195,7 +195,7 @@ void do_benchmark() std::this_thread::sleep_for(std::chrono::seconds(60)); oWork = xmrstak::miner_work(); - xmrstak::GlobalStates::switch_work(oWork); + xmrstak::GlobalStates::inst().switch_work(oWork); double fTotalHps = 0.0; for (uint32_t i = 0; i < pvThreads->size(); i++) diff --git a/config.txt b/config.txt index 781f505..888b655 100644 --- a/config.txt +++ b/config.txt @@ -1,16 +1,3 @@ -/* - * TLS Settings - * If you need real security, make sure tls_secure_algo is enabled (otherwise MITM attack can downgrade encryption - * to trivially breakable stuff like DES and MD5), and verify the server's fingerprint through a trusted channel. - * - * use_tls - This option will make us connect using Transport Layer Security. - * tls_secure_algo - Use only secure algorithms. This will make us quit with an error if we can't negotiate a secure algo. - * tls_fingerprint - Server's SHA256 fingerprint. If this string is non-empty then we will check the server's cert against it. - */ -"use_tls" : false, -"tls_secure_algo" : true, -"tls_fingerprint" : "", - /* * pool_address - Pool address should be in the form "pool.supportxmr.com:3333". Only stratum pools are supported. * wallet_address - Your wallet, or pool login. @@ -47,11 +34,11 @@ * performance monitors, there is very little reason to spew out pages of text instead of concise reports. * Press 'h' (hashrate), 'r' (results) or 'c' (connection) to print reports. * - * verbose_level - 0 - Don't print anything. + * verbose_level - 0 - Don't print anything. * 1 - Print intro, connection event, disconnect event * 2 - All of level 1, and new job (block) event if the difficulty is different from the last job * 3 - All of level 1, and new job (block) event in all cases, result submission event. - * 4 - All of level 3, and automatic hashrate report printing + * 4 - All of level 3, and automatic hashrate report printing */ "verbose_level" : 3, @@ -63,6 +50,80 @@ */ "h_print_time" : 60, +/* + * Manual hardware AES override + * + * Some VMs don't report AES capability correctly. You can set this value to true to enforce hardware AES or + * to false to force disable AES or null to let the miner decide if AES is used. + * + * WARNING: setting this to true on a CPU that doesn't support hardware AES will crash the miner. + */ +"aes_override" : null, + +/* + * LARGE PAGE SUPPORT + * Large pages need a properly set up OS. It can be difficult if you are not used to systems administration, + * but the performance results are worth the trouble - you will get around 20% boost. Slow memory mode is + * meant as a backup, you won't get stellar results there. If you are running into trouble, especially + * on Windows, please read the common issues in the README. + * + * By default we will try to allocate large pages. This means you need to "Run As Administrator" on Windows. + * You need to edit your system's group policies to enable locking large pages. Here are the steps from MSDN + * + * 1. On the Start menu, click Run. In the Open box, type gpedit.msc. + * 2. On the Local Group Policy Editor console, expand Computer Configuration, and then expand Windows Settings. + * 3. Expand Security Settings, and then expand Local Policies. + * 4. Select the User Rights Assignment folder. + * 5. The policies will be displayed in the details pane. + * 6. In the pane, double-click Lock pages in memory. + * 7. In the Local Security Setting – Lock pages in memory dialog box, click Add User or Group. + * 8. In the Select Users, Service Accounts, or Groups dialog box, add an account that you will run the miner on + * 9. Reboot for change to take effect. + * + * Windows also tends to fragment memory a lot. If you are running on a system with 4-8GB of RAM you might need + * to switch off all the auto-start applications and reboot to have a large enough chunk of contiguous memory. + * + * On Linux you will need to configure large page support "sudo sysctl -w vm.nr_hugepages=128" and increase your + * ulimit -l. To do do this you need to add following lines to /etc/security/limits.conf - "* soft memlock 262144" + * and "* hard memlock 262144". You can also do it Windows-style and simply run-as-root, but this is NOT + * recommended for security reasons. + * + * Memory locking means that the kernel can't swap out the page to disk - something that is unlikely to happen on a + * command line system that isn't starved of memory. I haven't observed any difference on a CLI Linux system between + * locked and unlocked memory. If that is your setup see option "no_mlck". + */ + +/* + * use_slow_memory defines our behavior with regards to large pages. There are three possible options here: + * always - Don't even try to use large pages. Always use slow memory. + * warn - We will try to use large pages, but fall back to slow memory if that fails. + * no_mlck - This option is only relevant on Linux, where we can use large pages without locking memory. + * It will never use slow memory, but it won't attempt to mlock + * never - If we fail to allocate large pages we will print an error and exit. + */ +"use_slow_memory" : "warn", + +/* + * NiceHash mode + * nicehash_nonce - Limit the nonce to 3 bytes as required by nicehash. This cuts all the safety margins, and + * if a block isn't found within 30 minutes then you might run into nonce collisions. Number + * of threads in this mode is hard-limited to 32. + */ +"nicehash_nonce" : false, + +/* + * TLS Settings + * If you need real security, make sure tls_secure_algo is enabled (otherwise MITM attack can downgrade encryption + * to trivially breakable stuff like DES and MD5), and verify the server's fingerprint through a trusted channel. + * + * use_tls - This option will make us connect using Transport Layer Security. + * tls_secure_algo - Use only secure algorithms. This will make us quit with an error if we can't negotiate a secure algo. + * tls_fingerprint - Server's SHA256 fingerprint. If this string is non-empty then we will check the server's cert against it. + */ +"use_tls" : false, +"tls_secure_algo" : true, +"tls_fingerprint" : "", + /* * Daemon mode * diff --git a/console.cpp b/console.cpp index c6b7d4d..0c73b1d 100644 --- a/console.cpp +++ b/console.cpp @@ -151,8 +151,6 @@ inline void comp_localtime(const time_t* ctime, tm* stime) #endif // __WIN32 } -printer* printer::oInst = nullptr; - printer::printer() { verbose_level = LINF; diff --git a/console.h b/console.h index 51efaef..ac2ed3c 100644 --- a/console.h +++ b/console.h @@ -1,5 +1,6 @@ #pragma once #include +#include "Environment.hpp" enum out_colours { K_RED, K_GREEN, K_BLUE, K_YELLOW, K_CYAN, K_MAGENTA, K_WHITE, K_NONE }; @@ -24,8 +25,10 @@ class printer public: static inline printer* inst() { - if (oInst == nullptr) oInst = new printer; - return oInst; + auto& env = xmrstak::Environment::inst(); + if(env.pPrinter == nullptr) + env.pPrinter = new printer; + return env.pPrinter; }; inline void set_verbose_level(size_t level) { verbose_level = (verbosity)level; } @@ -35,7 +38,6 @@ public: private: printer(); - static printer* oInst; std::mutex print_mutex; verbosity verbose_level; diff --git a/executor.cpp b/executor.cpp index 99f7ad5..0dd9cd7 100644 --- a/executor.cpp +++ b/executor.cpp @@ -122,7 +122,7 @@ void executor::sched_reconnect() rt, int_port(iReconnectAttempts)); auto work = xmrstak::miner_work(); - xmrstak::GlobalStates::switch_work(work); + xmrstak::GlobalStates::inst().switch_work(work); push_timed_event(ex_event(EV_RECONNECT, usr_pool_id), rt); } @@ -240,7 +240,7 @@ void executor::on_pool_have_job(size_t pool_id, pool_job& oPoolJob) oWork.iTarget32 = oPoolJob.iTarget32; - xmrstak::GlobalStates::switch_work(oWork); + xmrstak::GlobalStates::inst().switch_work(oWork); if(pool_id == dev_pool_id) return; @@ -362,7 +362,7 @@ void executor::on_switch_pool(size_t pool_id) oWork.iTarget32 = oPoolJob.iTarget32; - xmrstak::GlobalStates::switch_work(oWork); + xmrstak::GlobalStates::inst().switch_work(oWork); if(dev_pool->is_running()) push_timed_event(ex_event(EV_DEV_POOL_EXIT), 5); diff --git a/jconf.cpp b/jconf.cpp index f5fb3bc..00c34f1 100644 --- a/jconf.cpp +++ b/jconf.cpp @@ -48,7 +48,7 @@ using namespace rapidjson; enum configEnum { bTlsMode, bTlsSecureAlgo, sTlsFingerprint, sPoolAddr, sWalletAddr, sPoolPwd, iCallTimeout, iNetRetry, iGiveUpLimit, iVerboseLevel, iAutohashTime, - bDaemonMode, sOutputFile, iHttpdPort, bPreferIpv4 }; + bDaemonMode, sOutputFile, iHttpdPort, bPreferIpv4, bNiceHashMode, bAesOverride, sUseSlowMem }; struct configVal { configEnum iName; @@ -73,7 +73,10 @@ configVal oConfigValues[] = { { bDaemonMode, "daemon_mode", kTrueType }, { sOutputFile, "output_file", kStringType }, { iHttpdPort, "httpd_port", kNumberType }, - { bPreferIpv4, "prefer_ipv4", kTrueType } + { bPreferIpv4, "prefer_ipv4", kTrueType }, + { bNiceHashMode, "nicehash_nonce", kTrueType }, + { bAesOverride, "aes_override", kNullType }, + { sUseSlowMem, "use_slow_memory", kStringType } }; constexpr size_t iConfigCnt = (sizeof(oConfigValues)/sizeof(oConfigValues[0])); @@ -102,8 +105,6 @@ struct jconf::opaque_private } }; -jconf* jconf::oInst = nullptr; - jconf::jconf() { prv = new opaque_private(); @@ -184,12 +185,66 @@ const char* jconf::GetOutputFile() return prv->configValues[sOutputFile]->GetString(); } +bool jconf::NiceHashMode() +{ + return prv->configValues[bNiceHashMode]->GetBool(); +} + + +void jconf::cpuid(uint32_t eax, int32_t ecx, int32_t val[4]) +{ + memset(val, 0, sizeof(int32_t)*4); + +#ifdef _WIN32 + __cpuidex(val, eax, ecx); +#else + __cpuid_count(eax, ecx, val[0], val[1], val[2], val[3]); +#endif +} + +bool jconf::check_cpu_features() +{ + constexpr int AESNI_BIT = 1 << 25; + constexpr int SSE2_BIT = 1 << 26; + int32_t cpu_info[4]; + bool bHaveSse2; + + cpuid(1, 0, cpu_info); + + bHaveAes = (cpu_info[2] & AESNI_BIT) != 0; + bHaveSse2 = (cpu_info[3] & SSE2_BIT) != 0; + + return bHaveSse2; +} + +jconf::slow_mem_cfg jconf::GetSlowMemSetting() +{ + const char* opt = prv->configValues[sUseSlowMem]->GetString(); + + if(strcasecmp(opt, "always") == 0) + return always_use; + else if(strcasecmp(opt, "no_mlck") == 0) + return no_mlck; + else if(strcasecmp(opt, "warn") == 0) + return print_warning; + else if(strcasecmp(opt, "never") == 0) + return never_use; + else + return unknown_value; +} + bool jconf::parse_config(const char* sFilename) { FILE * pFile; char * buffer; size_t flen; + if(!check_cpu_features()) + { + printer::inst()->print_msg(L0, "CPU support of SSE2 is required."); + return false; + } + pFile = fopen(sFilename, "rb"); if (pFile == NULL) { @@ -310,8 +365,37 @@ bool jconf::parse_config(const char* sFilename) } #endif // CONF_NO_TLS + /* \todo check in the cpu backend if we have more than 32 worker + * keep in mined that we have change the why how the nonce is calculated (reverse thread index) + if(NiceHashMode() && GetThreadCount() >= 32) + { + printer::inst()->print_msg(L0, "You need to use less than 32 threads in NiceHash mode."); + return false; + } + */ + + if(prv->configValues[bAesOverride]->IsBool()) + bHaveAes = prv->configValues[bAesOverride]->GetBool(); + + if(!bHaveAes) + printer::inst()->print_msg(L0, "Your CPU doesn't support hardware AES. Don't expect high hashrates."); printer::inst()->set_verbose_level(prv->configValues[iVerboseLevel]->GetUint64()); + if(GetSlowMemSetting() == unknown_value) + { + printer::inst()->print_msg(L0, + "Invalid config file. use_slow_memory must be \"always\", \"no_mlck\", \"warn\" or \"never\""); + return false; + } + +#ifdef _WIN32 + if(GetSlowMemSetting() == no_mlck) + { + printer::inst()->print_msg(L0, "On Windows large pages need mlock. Please use another option."); + return false; + } +#endif // _WIN32 + return true; } diff --git a/jconf.h b/jconf.h index dd6a010..2865652 100644 --- a/jconf.h +++ b/jconf.h @@ -1,14 +1,17 @@ #pragma once #include #include +#include "Environment.hpp" class jconf { public: static jconf* inst() { - if (oInst == nullptr) oInst = new jconf; - return oInst; + auto& env = xmrstak::Environment::inst(); + if(env.pJconfConfig == nullptr) + env.pJconfConfig = new jconf; + return env.pJconfConfig; }; bool parse_config(const char* sFilename); @@ -51,9 +54,16 @@ public: bool PreferIpv4(); + bool NiceHashMode(); + + inline bool HaveHardwareAes() { return bHaveAes; } + + static void cpuid(uint32_t eax, int32_t ecx, int32_t val[4]); + + slow_mem_cfg GetSlowMemSetting(); + private: jconf(); - static jconf* oInst; bool check_cpu_features(); struct opaque_private; From 9e7efd40bc3206aad7b6d1e531dbe6d335575aac Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Wed, 27 Sep 2017 17:13:41 +0200 Subject: [PATCH 14/42] fix bugs - add excecutor to the singleton export list --- Environment.hpp | 4 ++++ backend/BackendConnector.cpp | 1 + cli/cli-miner.cpp | 2 +- executor.cpp | 2 -- executor.h | 8 +++++--- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Environment.hpp b/Environment.hpp index 9f887a1..01090a4 100644 --- a/Environment.hpp +++ b/Environment.hpp @@ -2,6 +2,7 @@ class printer; class jconf; +class executor; namespace xmrstak { @@ -22,6 +23,7 @@ struct Environment this->pPrinter = env.pPrinter; this->pGlobalStates = env.pGlobalStates; this->pJconfConfig = env.pJconfConfig; + this->pExecutor = env.pExecutor; return *this; } @@ -37,6 +39,8 @@ struct Environment jconf* pJconfConfig; + executor* pExecutor; + }; } // namepsace xmrstak diff --git a/backend/BackendConnector.cpp b/backend/BackendConnector.cpp index 194cb5c..0ef69f1 100644 --- a/backend/BackendConnector.cpp +++ b/backend/BackendConnector.cpp @@ -44,6 +44,7 @@ #include "Plugin.hpp" #include "../Environment.hpp" +#include "../console.h" namespace xmrstak { diff --git a/cli/cli-miner.cpp b/cli/cli-miner.cpp index e5c5863..9cd9825 100644 --- a/cli/cli-miner.cpp +++ b/cli/cli-miner.cpp @@ -122,7 +122,7 @@ int main(int argc, char *argv[]) #endif printer::inst()->print_str("-------------------------------------------------------------------\n"); - printer::inst()->print_str( XMR_STAK_NAME" " XMR_STAK_VERSION " mining software, CPU Version.\n"); + printer::inst()->print_str( XMR_STAK_NAME" " XMR_STAK_VERSION " mining software.\n"); printer::inst()->print_str("Based on CPU mining code by wolf9466 (heavily optimized by fireice_uk).\n"); #ifndef CONF_NO_CUDA printer::inst()->print_str("NVIDIA mining code was written by KlausT and psychocrypt.\n"); diff --git a/executor.cpp b/executor.cpp index 0dd9cd7..64f3d40 100644 --- a/executor.cpp +++ b/executor.cpp @@ -44,8 +44,6 @@ #define strncasecmp _strnicmp #endif // _WIN32 -executor* executor::oInst = NULL; - executor::executor() { } diff --git a/executor.h b/executor.h index 57e435f..d7fa27d 100644 --- a/executor.h +++ b/executor.h @@ -7,6 +7,7 @@ #include #include "telemetry.h" #include "backend/IBackend.hpp" +#include "Environment.hpp" class jpsock; @@ -25,8 +26,10 @@ class executor public: static executor* inst() { - if (oInst == nullptr) oInst = new executor; - return oInst; + auto& env = xmrstak::Environment::inst(); + if(env.pExecutor == nullptr) + env.pExecutor = new executor; + return env.pExecutor; }; void ex_start(bool daemon) { daemon ? ex_main() : std::thread(&executor::ex_main, this).detach(); } @@ -73,7 +76,6 @@ private: bool is_dev_time; executor(); - static executor* oInst; void ex_main(); From 990c357cc97792e761f40adfbc6445fb30d04d30 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Wed, 27 Sep 2017 18:07:19 +0200 Subject: [PATCH 15/42] improve auto suggestion - amd/nvidia add hard limit that 64MiB memory keeps free - improve nvidia auto suggestion (take care of lmem) - add c++11 flag to nvidia compiler --- CMakeLists.txt | 5 +++ backend/amd/autoAdjust.hpp | 12 +++--- backend/nvidia/autoAdjust.hpp | 6 ++- backend/nvidia/nvcc_code/cryptonight.h | 4 ++ backend/nvidia/nvcc_code/cuda_extra.cu | 52 ++++++++++++++++++-------- 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8871951..cf776e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,6 +108,11 @@ if(CUDA_ENABLE) endforeach() elseif("${CUDA_COMPILER}" STREQUAL "nvcc") + # add c++11 for cuda + if(NOT "${CMAKE_CXX_FLAGS}" MATCHES "-std=c\\+\\+11") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + endif() + # avoid that nvcc in CUDA < 8 tries to use libc `memcpy` within the kernel if(CUDA_VERSION VERSION_LESS 8.0) add_definitions(-D_FORCE_INLINES) diff --git a/backend/amd/autoAdjust.hpp b/backend/amd/autoAdjust.hpp index de67456..e6e4015 100644 --- a/backend/amd/autoAdjust.hpp +++ b/backend/amd/autoAdjust.hpp @@ -83,13 +83,15 @@ private: int i = 0; for(auto& ctx : devVec) { - // use 90% of available memory - size_t availableMem = (ctx.freeMem * 100u) / 110; - size_t units = ctx.computeUnits; + // keep 64MiB memory free (value is randomly chosen) + size_t availableMem = ctx.freeMem - (64u * 1024 * 1024); + // 224byte extra memory is used per thread for meta data size_t perThread = (size_t(1u)<<21) + 224u; size_t max_intensity = availableMem / perThread; + // 1000 is a magic selected limit \todo select max intensity depending of the gpu type size_t intensity = std::min( size_t(1000u) , max_intensity ); - conf += std::string(" // gpu: ") + ctx.name + "\n"; + conf += std::string(" // gpu: ") + ctx.name + "\n"; + // set 8 threads per block (this is a good value for the most gpus) conf += std::string(" { \"index\" : ") + std::to_string(ctx.deviceIdx) + ",\n" + " \"intensity\" : " + std::to_string(intensity) + ", \"worksize\" : " + std::to_string(8) + ",\n" + " \"affine_to_cpu\" : false, \n" @@ -101,7 +103,7 @@ private: configTpl.replace("NUMGPUS",std::to_string(devVec.size())); configTpl.replace("GPUCONFIG",conf); configTpl.write("amd.txt"); - printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", "amd.txt"); + printer::inst()->print_msg(L0, "AMD: GPU configuration stored in file '%s'", "amd.txt"); } std::vector devVec; diff --git a/backend/nvidia/autoAdjust.hpp b/backend/nvidia/autoAdjust.hpp index 0e6c40f..659bd08 100644 --- a/backend/nvidia/autoAdjust.hpp +++ b/backend/nvidia/autoAdjust.hpp @@ -85,11 +85,13 @@ private: ConfigEditor configTpl{}; configTpl.set( std::string(tpl) ); + constexpr size_t byte2mib = 1024u * 1024u; std::string conf; int i = 0; for(auto& ctx : nvidCtxVec) { - + conf += std::string(" // gpu: ") + ctx.name + " architecture: " + std::to_string(ctx.device_arch[0] * 10 + ctx.device_arch[1]) + "\n"; + conf += std::string(" // memory: ") + std::to_string(ctx.free_device_memory / byte2mib) + "/" + std::to_string(ctx.total_device_memory / byte2mib) + " MiB\n"; conf += std::string(" { \"index\" : ") + std::to_string(ctx.device_id) + ",\n" + " \"threads\" : " + std::to_string(ctx.device_threads) + ", \"blocks\" : " + std::to_string(ctx.device_blocks) + ",\n" + " \"bfactor\" : " + std::to_string(ctx.device_bfactor) + ", \"bsleep\" : " + std::to_string(ctx.device_bsleep) + ",\n" + @@ -100,7 +102,7 @@ private: configTpl.replace("GPUCONFIG",conf); configTpl.write("nvidia.txt"); - printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", "nvidia.txt"); + printer::inst()->print_msg(L0, "NVIDIA: GPU configuration stored in file '%s'", "nvidia.txt"); } std::vector nvidCtxVec; diff --git a/backend/nvidia/nvcc_code/cryptonight.h b/backend/nvidia/nvcc_code/cryptonight.h index bec9997..784c38d 100644 --- a/backend/nvidia/nvcc_code/cryptonight.h +++ b/backend/nvidia/nvcc_code/cryptonight.h @@ -1,6 +1,7 @@ #pragma once #include +#include typedef struct { int device_id; @@ -23,6 +24,9 @@ typedef struct { uint32_t *d_ctx_key1; uint32_t *d_ctx_key2; uint32_t *d_ctx_text; + std::string name; + size_t free_device_memory; + size_t total_device_memory; } nvid_ctx; extern "C" { diff --git a/backend/nvidia/nvcc_code/cuda_extra.cu b/backend/nvidia/nvcc_code/cuda_extra.cu index 94a4adb..7052bc8 100644 --- a/backend/nvidia/nvcc_code/cuda_extra.cu +++ b/backend/nvidia/nvcc_code/cuda_extra.cu @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef __CUDACC__ __constant__ @@ -301,6 +302,8 @@ extern "C" int cuda_get_deviceinfo(nvid_ctx* ctx) ctx->device_arch[0] = props.major; ctx->device_arch[1] = props.minor; + ctx->name = std::string(props.name); + // set all evice option those marked as auto (-1) to a valid value if(ctx->device_blocks == -1) { @@ -318,27 +321,46 @@ extern "C" int cuda_get_deviceinfo(nvid_ctx* ctx) * `8 * ctx->device_threads` threads per block */ ctx->device_threads = 64; + constexpr size_t byte2mib = 1024u * 1024u; + + // no limit by default 1TiB + size_t maxMemUsage = byte2mib * byte2mib; if(props.major < 6) { - // try to stay under 950 threads ( 1900MiB memory per for hashes ) - while(ctx->device_blocks * ctx->device_threads >= 950 && ctx->device_threads > 2) - { - ctx->device_threads /= 2; - } + // limit memory usage for GPUs before pascal + maxMemUsage = size_t(2048u) * byte2mib; + } + if(props.major == 2) + { + // limit memory usage for sm 20 GPUs + maxMemUsage = size_t(1024u) * byte2mib; } - // stay within 85% of the available RAM - while(ctx->device_threads > 2) + size_t freeMemory = 0; + size_t totalMemory = 0; + CUDA_CHECK(ctx->device_id, cudaMemGetInfo(&freeMemory, &totalMemory)); + + ctx->total_device_memory = totalMemory; + ctx->free_device_memory = freeMemory; + + // keep 64MiB memory free (value is randomly chosen) + // 200byte are meta data memory (result nonce, ...) + size_t availableMem = freeMemory - (64u * 1024 * 1024) - 200u; + size_t limitedMemory = std::min(availableMem, maxMemUsage); + // up to 920bytes extra memory is used per thread for some kernel (lmem/local memory) + // 680bytes are extra meta data memory per hash + size_t perThread = size_t(MEMORY) + 740u + 680u; + size_t max_intensity = limitedMemory / perThread; + ctx->device_threads = max_intensity / ctx->device_blocks; + // use only odd number of threads + ctx->device_threads = ctx->device_threads & 0xFFFFFFFE; + + if(props.major == 2 && ctx->device_threads > 64) { - size_t freeMemory = 0; - size_t totalMemory = 0; - CUDA_CHECK(ctx->device_id, cudaMemGetInfo(&freeMemory, &totalMemory)); - freeMemory = (freeMemory * size_t(85)) / 100; - if( freeMemory > (size_t(ctx->device_blocks) * size_t(ctx->device_threads) * size_t(2u * 1024u * 1024u)) ) - break; - else - ctx->device_threads /= 2; + // Fermi gpus only support 512 threads per block (we need start 4 * configured threads) + ctx->device_threads = 64; } + } return 1; From 0e4cbe2643e5069ab60c53cb2fa81e3afa8456ce Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Wed, 27 Sep 2017 21:30:43 +0200 Subject: [PATCH 16/42] move opencl files to amd backend - inlcude opencl source code during compile --- CMakeCache.txt | 38 ++++++++++++++++ CMakeFiles/cmake.check_cache | 1 + backend/amd/amd_gpu/gpu.cpp | 45 +++++++++++++------ .../amd/amd_gpu/opencl}/blake256.cl | 7 +-- .../amd/amd_gpu/opencl}/cryptonight.cl | 18 +++++--- .../amd/amd_gpu/opencl}/groestl256.cl | 3 ++ {opencl => backend/amd/amd_gpu/opencl}/jh.cl | 2 + .../amd/amd_gpu/opencl}/wolf-aes.cl | 3 ++ .../amd/amd_gpu/opencl}/wolf-skein.cl | 3 ++ 9 files changed, 97 insertions(+), 23 deletions(-) create mode 100644 CMakeCache.txt create mode 100644 CMakeFiles/cmake.check_cache rename {opencl => backend/amd/amd_gpu/opencl}/blake256.cl (99%) rename {opencl => backend/amd/amd_gpu/opencl}/cryptonight.cl (99%) rename {opencl => backend/amd/amd_gpu/opencl}/groestl256.cl (99%) rename {opencl => backend/amd/amd_gpu/opencl}/jh.cl (99%) rename {opencl => backend/amd/amd_gpu/opencl}/wolf-aes.cl (99%) rename {opencl => backend/amd/amd_gpu/opencl}/wolf-skein.cl (99%) diff --git a/CMakeCache.txt b/CMakeCache.txt new file mode 100644 index 0000000..3c42ff2 --- /dev/null +++ b/CMakeCache.txt @@ -0,0 +1,38 @@ +# This is the CMakeCache file. +# For build in directory: /home/psychocrypt/workspace/xmr-stak-cpu +# It was generated by CMake: /usr/bin/cmake +# You can edit this file to change values found and used by cmake. +# If you do not want to change any of the values, simply exit the editor. +# If you do want to change a value, simply edit, save, and exit the editor. +# The syntax for the file is as follows: +# KEY:TYPE=VALUE +# KEY is the name of a variable in the cache. +# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!. +# VALUE is the current value for the KEY. + +######################## +# EXTERNAL cache entries +######################## + + +######################## +# INTERNAL cache entries +######################## + +//This is the directory where this CMakeCache.txt was created +CMAKE_CACHEFILE_DIR:INTERNAL=/home/psychocrypt/workspace/xmr-stak-cpu +//Major version of cmake used to create the current loaded cache +CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3 +//Minor version of cmake used to create the current loaded cache +CMAKE_CACHE_MINOR_VERSION:INTERNAL=5 +//Patch version of cmake used to create the current loaded cache +CMAKE_CACHE_PATCH_VERSION:INTERNAL=1 +//Path to CMake executable. +CMAKE_COMMAND:INTERNAL=/usr/bin/cmake +//Path to cpack program executable. +CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack +//Path to ctest program executable. +CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest +//Path to CMake installation. +CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.5 + diff --git a/CMakeFiles/cmake.check_cache b/CMakeFiles/cmake.check_cache new file mode 100644 index 0000000..3dccd73 --- /dev/null +++ b/CMakeFiles/cmake.check_cache @@ -0,0 +1 @@ +# This file is generated by cmake for dependency checking of the CMakeCache.txt file diff --git a/backend/amd/amd_gpu/gpu.cpp b/backend/amd/amd_gpu/gpu.cpp index 30aa5a8..04e442a 100644 --- a/backend/amd/amd_gpu/gpu.cpp +++ b/backend/amd/amd_gpu/gpu.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -212,7 +213,7 @@ char* LoadTextFile(const char* filename) return out; } -size_t InitOpenCLGpu(cl_context opencl_ctx, GpuContext* ctx, char* source_code) +size_t InitOpenCLGpu(cl_context opencl_ctx, GpuContext* ctx, const char* source_code) { size_t MaximumWorkSize; cl_int ret; @@ -330,9 +331,9 @@ size_t InitOpenCLGpu(cl_context opencl_ctx, GpuContext* ctx, char* source_code) printer::inst()->print_msg(L1,"Error %s when calling clGetProgramBuildInfo for build log.", err_to_str(ret)); return ERR_OCL_API; } - + printer::inst()->print_str("Build log:\n"); - printer::inst()->print_str(BuildLog); + std::cerr<print_msg(L1,"WARNING: using non AMD device: %s", platformName.c_str()); - return ERR_STUPID_PARAMS; } free(platforms); @@ -607,22 +607,41 @@ size_t InitOpenCL(GpuContext* ctx, size_t num_gpus, size_t platform_idx) return ERR_OCL_API; } - char* source_code = LoadTextFile(sSourcePath); - if(source_code == NULL) - { - printer::inst()->print_msg(L1,"Couldn't locate GPU source code file at %s.", sSourcePath); - return ERR_STUPID_PARAMS; - } + //char* source_code = LoadTextFile(sSourcePath); + + const char *cryptonightCL = + #include "./opencl/cryptonight.cl" + ; + const char *blake256CL = + #include "./opencl/blake256.cl" + ; + const char *groestl256CL = + #include "./opencl/groestl256.cl" + ; + const char *jhCL = + #include "./opencl/jh.cl" + ; + const char *wolfAesCL = + #include "./opencl/wolf-aes.cl" + ; + const char *wolfSkeinCL = + #include "./opencl/wolf-skein.cl" + ; + + std::string source_code(cryptonightCL); + source_code = std::regex_replace(source_code, std::regex("XMRSTAK_INCLUDE_WOLF_AES"), wolfAesCL); + source_code = std::regex_replace(source_code, std::regex("XMRSTAK_INCLUDE_WOLF_SKEIN"), wolfSkeinCL); + source_code = std::regex_replace(source_code, std::regex("XMRSTAK_INCLUDE_JH"), jhCL); + source_code = std::regex_replace(source_code, std::regex("XMRSTAK_INCLUDE_BLAKE256"), blake256CL); + source_code = std::regex_replace(source_code, std::regex("XMRSTAK_INCLUDE_GROESTL256"), groestl256CL); for(int i = 0; i < num_gpus; ++i) { - if((ret = InitOpenCLGpu(opencl_ctx, &ctx[i], source_code)) != ERR_SUCCESS) + if((ret = InitOpenCLGpu(opencl_ctx, &ctx[i], source_code.c_str())) != ERR_SUCCESS) { - free(source_code); return ret; } } - free(source_code); return ERR_SUCCESS; } diff --git a/opencl/blake256.cl b/backend/amd/amd_gpu/opencl/blake256.cl similarity index 99% rename from opencl/blake256.cl rename to backend/amd/amd_gpu/opencl/blake256.cl index 6be0eb0..3d5fe3e 100644 --- a/opencl/blake256.cl +++ b/backend/amd/amd_gpu/opencl/blake256.cl @@ -1,3 +1,4 @@ +R"===( /* * blake256 kernel implementation. * @@ -89,8 +90,4 @@ __constant static const sph_u32 c_u256[16] = { v[b] ^= v[c]; \ v[b] = rotate(v[b], 25U); \ } - - - - - +)===" diff --git a/opencl/cryptonight.cl b/backend/amd/amd_gpu/opencl/cryptonight.cl similarity index 99% rename from opencl/cryptonight.cl rename to backend/amd/amd_gpu/opencl/cryptonight.cl index 0478160..4aae939 100644 --- a/opencl/cryptonight.cl +++ b/backend/amd/amd_gpu/opencl/cryptonight.cl @@ -1,3 +1,4 @@ +R"===( /* * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,11 +73,16 @@ inline int amd_bfe(const uint src0, const uint offset, const uint width) } #endif -#include "opencl/wolf-aes.cl" -#include "opencl/wolf-skein.cl" -#include "opencl/jh.cl" -#include "opencl/blake256.cl" -#include "opencl/groestl256.cl" +//#include "opencl/wolf-aes.cl" +XMRSTAK_INCLUDE_WOLF_AES +//#include "opencl/wolf-skein.cl" +XMRSTAK_INCLUDE_WOLF_SKEIN +//#include "opencl/jh.cl" +XMRSTAK_INCLUDE_JH +//#include "opencl/blake256.cl" +XMRSTAK_INCLUDE_BLAKE256 +//#include "opencl/groestl256.cl" +XMRSTAK_INCLUDE_GROESTL256 static const __constant ulong keccakf_rndc[24] = { @@ -968,3 +974,5 @@ __kernel void Groestl(__global ulong *states, __global uint *BranchBuf, __global //for(int i = 0; i < 4; ++i) output[i] = State[i + 4]; if(as_uint2(State[7]).s1 <= Target) output[atomic_inc(output + 0xFF)] = BranchBuf[idx] + get_global_offset(0); } + +)===" \ No newline at end of file diff --git a/opencl/groestl256.cl b/backend/amd/amd_gpu/opencl/groestl256.cl similarity index 99% rename from opencl/groestl256.cl rename to backend/amd/amd_gpu/opencl/groestl256.cl index 1139c4d..403820d 100644 --- a/opencl/groestl256.cl +++ b/backend/amd/amd_gpu/opencl/groestl256.cl @@ -1,3 +1,4 @@ +R"===( /* $Id: groestl.c 260 2011-07-21 01:02:38Z tp $ */ /* * Groestl256 @@ -287,3 +288,5 @@ static const __constant ulong T4_G[] = ROUND_SMALL_Q(a, r); \ } while (0) +)===" + \ No newline at end of file diff --git a/opencl/jh.cl b/backend/amd/amd_gpu/opencl/jh.cl similarity index 99% rename from opencl/jh.cl rename to backend/amd/amd_gpu/opencl/jh.cl index d034abc..fe70ea3 100644 --- a/opencl/jh.cl +++ b/backend/amd/amd_gpu/opencl/jh.cl @@ -1,3 +1,4 @@ +R"===( /* $Id: jh.c 255 2011-06-07 19:50:20Z tp $ */ /* * JH implementation. @@ -270,3 +271,4 @@ static const __constant ulong C[] = #endif +)===" diff --git a/opencl/wolf-aes.cl b/backend/amd/amd_gpu/opencl/wolf-aes.cl similarity index 99% rename from opencl/wolf-aes.cl rename to backend/amd/amd_gpu/opencl/wolf-aes.cl index 23a41a7..996944b 100644 --- a/opencl/wolf-aes.cl +++ b/backend/amd/amd_gpu/opencl/wolf-aes.cl @@ -1,3 +1,4 @@ +R"===( #ifndef WOLF_AES_CL #define WOLF_AES_CL @@ -85,3 +86,5 @@ uint4 AES_Round(const __local uint *AES0, const __local uint *AES1, const __loca } #endif + +)===" diff --git a/opencl/wolf-skein.cl b/backend/amd/amd_gpu/opencl/wolf-skein.cl similarity index 99% rename from opencl/wolf-skein.cl rename to backend/amd/amd_gpu/opencl/wolf-skein.cl index c5c2bd8..868757b 100644 --- a/opencl/wolf-skein.cl +++ b/backend/amd/amd_gpu/opencl/wolf-skein.cl @@ -1,3 +1,4 @@ +R"===( #ifndef WOLF_SKEIN_CL #define WOLF_SKEIN_CL @@ -109,3 +110,5 @@ ulong8 Skein512Block(ulong8 p, ulong8 h, ulong h8, const ulong *t) } #endif + +)===" From 085f8c25846119a3b33786d2f4b8989e07a8c26f Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Thu, 28 Sep 2017 20:32:40 +0200 Subject: [PATCH 17/42] command line parameter - store most importend parameter in a singleton - use config file parameter --- Environment.hpp | 6 +- Params.hpp | 45 ++++++++++++ backend/amd/autoAdjust.hpp | 5 +- backend/amd/jconf.h | 3 +- backend/amd/minethd.cpp | 11 +-- backend/cpu/autoAdjust.hpp | 5 +- backend/cpu/autoAdjustHwloc.hpp | 5 +- backend/cpu/jconf.h | 3 +- backend/cpu/minethd.cpp | 5 +- backend/nvidia/autoAdjust.hpp | 5 +- backend/nvidia/jconf.h | 3 +- backend/nvidia/minethd.cpp | 5 +- cli/cli-miner.cpp | 118 ++++++++++++++++++++++++++------ jconf.h | 3 +- 14 files changed, 174 insertions(+), 48 deletions(-) create mode 100644 Params.hpp diff --git a/Environment.hpp b/Environment.hpp index 01090a4..15f8cce 100644 --- a/Environment.hpp +++ b/Environment.hpp @@ -8,6 +8,7 @@ namespace xmrstak { class GlobalStates; +class Params; struct Environment { @@ -24,6 +25,7 @@ struct Environment this->pGlobalStates = env.pGlobalStates; this->pJconfConfig = env.pJconfConfig; this->pExecutor = env.pExecutor; + this->pParams = env.pParams; return *this; } @@ -34,12 +36,10 @@ struct Environment printer* pPrinter; - GlobalStates* pGlobalStates; - jconf* pJconfConfig; - executor* pExecutor; + Params* pParams; }; diff --git a/Params.hpp b/Params.hpp new file mode 100644 index 0000000..92d0da0 --- /dev/null +++ b/Params.hpp @@ -0,0 +1,45 @@ +#pragma once +#include +#include "Environment.hpp" + +namespace xmrstak +{ + +struct Params +{ + + static inline Params& inst() + { + auto& env = Environment::inst(); + if(env.pParams == nullptr) + env.pParams = new Params; + return *env.pParams; + } + + std::string executablePrefix; + bool useAMD; + bool useNVIDIA; + bool useCPU; + + std::string poolURL; + std::string poolPasswd; + std::string poolUsername; + + std::string configFile; + std::string configFileAMD; + std::string configFileNVIDIA; + std::string configFileCPU; + + Params() : + useAMD(true), + useNVIDIA(true), + useCPU(true), + configFile("config.txt"), + configFileAMD("amd.txt"), + configFileCPU("cpu.txt"), + configFileNVIDIA("nvidia.txt") + {} + +}; + +} // namepsace xmrstak diff --git a/backend/amd/autoAdjust.hpp b/backend/amd/autoAdjust.hpp index e6e4015..442d8f1 100644 --- a/backend/amd/autoAdjust.hpp +++ b/backend/amd/autoAdjust.hpp @@ -8,6 +8,7 @@ #include "../../console.h" #include "../../ConfigEditor.hpp" #include "amd_gpu/gpu.h" +#include "../../Params.hpp" #include #include @@ -102,8 +103,8 @@ private: configTpl.replace("PLATFORMINDEX",std::to_string(platformIndex)); configTpl.replace("NUMGPUS",std::to_string(devVec.size())); configTpl.replace("GPUCONFIG",conf); - configTpl.write("amd.txt"); - printer::inst()->print_msg(L0, "AMD: GPU configuration stored in file '%s'", "amd.txt"); + configTpl.write(Params::inst().configFileAMD); + printer::inst()->print_msg(L0, "AMD: GPU configuration stored in file '%s'", Params::inst().configFileAMD.c_str()); } std::vector devVec; diff --git a/backend/amd/jconf.h b/backend/amd/jconf.h index 463284a..9fef331 100644 --- a/backend/amd/jconf.h +++ b/backend/amd/jconf.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include "../../Params.hpp" namespace xmrstak { @@ -16,7 +17,7 @@ public: return oInst; }; - bool parse_config(const char* sFilename = "amd.txt"); + bool parse_config(const char* sFilename = Params::inst().configFileAMD.c_str()); struct thd_cfg { size_t index; diff --git a/backend/amd/minethd.cpp b/backend/amd/minethd.cpp index 0821c0e..b938f2d 100644 --- a/backend/amd/minethd.cpp +++ b/backend/amd/minethd.cpp @@ -40,6 +40,7 @@ #include "../../jconf.h" #include "../../crypto/cryptonight.h" #include "../../Environment.hpp" +#include "../../Params.hpp" #include "amd_gpu/gpu.h" @@ -97,19 +98,13 @@ std::vector* minethd::thread_starter(uint32_t threadOffset, miner_wor { std::vector* pvThreads = new std::vector(); - if(!ConfigEditor::file_exist("amd.txt")) + if(!ConfigEditor::file_exist(Params::inst().configFileAMD)) { autoAdjust adjust; if(!adjust.printConfig()) return pvThreads; } -/* - if(!ConfigEditor::file_exist("amd.txt")) - { - printer::inst()->print_msg(L0, "WARNING: missing config file 'amd.txt'"); - return pvThreads; - } -*/ + if(!jconf::inst()->parse_config()) { win_exit(); diff --git a/backend/cpu/autoAdjust.hpp b/backend/cpu/autoAdjust.hpp index 092f085..32c8576 100644 --- a/backend/cpu/autoAdjust.hpp +++ b/backend/cpu/autoAdjust.hpp @@ -3,6 +3,7 @@ #include "../../console.h" #include "../../jconf.h" #include "../../ConfigEditor.hpp" +#include "../../Params.hpp" #include #ifdef _WIN32 @@ -97,8 +98,8 @@ public: } configTpl.replace("CPUCONFIG",conf); - configTpl.write("cpu.txt"); - printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", "cpu.txt"); + configTpl.write(Params::inst().configFileCPU); + printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", Params::inst().configFileCPU.c_str()); return true; } diff --git a/backend/cpu/autoAdjustHwloc.hpp b/backend/cpu/autoAdjustHwloc.hpp index 161aa5c..e1916e0 100644 --- a/backend/cpu/autoAdjustHwloc.hpp +++ b/backend/cpu/autoAdjustHwloc.hpp @@ -3,6 +3,7 @@ #include "../../console.h" #include #include +#include "../../Params.hpp" #ifdef _WIN32 #include @@ -74,8 +75,8 @@ public: } configTpl.replace("CPUCONFIG",conf); - configTpl.write("cpu.txt"); - printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", "cpu.txt"); + configTpl.write(Params::inst().configFileCPU); + printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", Params::inst().configFileCPU.c_str()); /* Destroy topology object. */ hwloc_topology_destroy(topology); diff --git a/backend/cpu/jconf.h b/backend/cpu/jconf.h index 9b46552..1f92765 100644 --- a/backend/cpu/jconf.h +++ b/backend/cpu/jconf.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include "../../Params.hpp" namespace xmrstak { @@ -16,7 +17,7 @@ public: return oInst; }; - bool parse_config(const char* sFilename = "cpu.txt"); + bool parse_config(const char* sFilename = Params::inst().configFileCPU.c_str()); struct thd_cfg { bool bDoubleMode; diff --git a/backend/cpu/minethd.cpp b/backend/cpu/minethd.cpp index 7991d86..3ffdf99 100644 --- a/backend/cpu/minethd.cpp +++ b/backend/cpu/minethd.cpp @@ -31,6 +31,7 @@ #include "../IBackend.hpp" #include "../GlobalStates.hpp" #include "../../ConfigEditor.hpp" +#include "../../Params.hpp" #include "../../jconf.h" #include "../../executor.h" @@ -247,14 +248,14 @@ std::vector minethd::thread_starter(uint32_t threadOffset, miner_work { std::vector pvThreads; - if(!ConfigEditor::file_exist("cpu.txt")) + if(!ConfigEditor::file_exist(Params::inst().configFileCPU)) { autoAdjust adjust; if(!adjust.printConfig()) return pvThreads; } - if(!xmrstak::cpu::jconf::inst()->parse_config("cpu.txt")) + if(!jconf::inst()->parse_config()) { win_exit(); } diff --git a/backend/nvidia/autoAdjust.hpp b/backend/nvidia/autoAdjust.hpp index 659bd08..84c6dfc 100644 --- a/backend/nvidia/autoAdjust.hpp +++ b/backend/nvidia/autoAdjust.hpp @@ -7,6 +7,7 @@ #include "jconf.h" #include "../../console.h" #include "../../ConfigEditor.hpp" +#include "../../Params.hpp" #include #include @@ -101,8 +102,8 @@ private: } configTpl.replace("GPUCONFIG",conf); - configTpl.write("nvidia.txt"); - printer::inst()->print_msg(L0, "NVIDIA: GPU configuration stored in file '%s'", "nvidia.txt"); + configTpl.write(Params::inst().configFileNVIDIA); + printer::inst()->print_msg(L0, "NVIDIA: GPU configuration stored in file '%s'", Params::inst().configFileNVIDIA.c_str()); } std::vector nvidCtxVec; diff --git a/backend/nvidia/jconf.h b/backend/nvidia/jconf.h index e398f30..8959088 100644 --- a/backend/nvidia/jconf.h +++ b/backend/nvidia/jconf.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include "../../Params.hpp" namespace xmrstak { @@ -16,7 +17,7 @@ public: return oInst; }; - bool parse_config(const char* sFilename = "nvidia.txt"); + bool parse_config(const char* sFilename = Params::inst().configFileNVIDIA.c_str()); struct thd_cfg { uint32_t id; diff --git a/backend/nvidia/minethd.cpp b/backend/nvidia/minethd.cpp index 554ea69..227a2cf 100644 --- a/backend/nvidia/minethd.cpp +++ b/backend/nvidia/minethd.cpp @@ -30,6 +30,7 @@ #include "../../console.h" #include "../../crypto/cryptonight_aesni.h" #include "../cpu/minethd.h" +#include "../../Params.hpp" #include "../../executor.h" #include "minethd.h" @@ -121,14 +122,14 @@ std::vector* minethd::thread_starter(uint32_t threadOffset, miner_wor { std::vector* pvThreads = new std::vector(); - if(!ConfigEditor::file_exist("nvidia.txt")) + if(!ConfigEditor::file_exist(Params::inst().configFileNVIDIA)) { autoAdjust adjust; if(!adjust.printConfig()) return pvThreads; } - if(!jconf::inst()->parse_config("nvidia.txt")) + if(!jconf::inst()->parse_config()) { win_exit(); } diff --git a/cli/cli-miner.cpp b/cli/cli-miner.cpp index 9cd9825..df9432e 100644 --- a/cli/cli-miner.cpp +++ b/cli/cli-miner.cpp @@ -28,6 +28,7 @@ #include "../jconf.h" #include "../console.h" #include "../donate-level.h" +#include "../Params.hpp" #include "../version.h" @@ -37,7 +38,7 @@ #include #include -#include +#include #include @@ -66,32 +67,114 @@ int main(int argc, char *argv[]) srand(time(0)); - const char* sFilename = "config.txt"; - bool benchmark_mode = false; + using namespace xmrstak; - if(argc >= 2) + std::string pathWithName(argv[0]); + auto pos = pathWithName.rfind("/"); + if(pos == std::string::npos) { - if(strcmp(argv[1], "-h") == 0) + // try windows "\" + pos = pathWithName.rfind("\\"); + } + + Params::inst().executablePrefix = std::string(pathWithName, 0, pos); + + for(int i = 1; i < argc; ++i) + { + std::string opName(argv[i]); + if(opName.compare("-h") == 0 || opName.compare("--help") == 0) { - printer::inst()->print_msg(L0, "Usage %s [CONFIG FILE]", argv[0]); + printer::inst()->print_msg(L0, "Usage: %s [--help|-h] [--benchmark] [-c CONFIGFILE] [CONFIG FILE]", argv[0]); win_exit(); return 0; } - - if(argc >= 3 && strcasecmp(argv[1], "-c") == 0) + else if(opName.compare("--noCPU") == 0) { - sFilename = argv[2]; + Params::inst().useCPU = false; + return 0; } - else if(argc >= 3 && strcasecmp(argv[1], "benchmark_mode") == 0) + else if(opName.compare("--noAMD") == 0) { - sFilename = argv[2]; - benchmark_mode = true; + Params::inst().useAMD = false; + return 0; + } + else if(opName.compare("--noAMD") == 0) + { + Params::inst().useNVIDIA = false; + return 0; + } + else if(opName.compare("--cpu") == 0) + { + ++i; + if( i >=argc ) + { + printer::inst()->print_msg(L0, "No argument for opName '--cpu' given"); + win_exit(); + return 1; + } + Params::inst().configFileCPU = argv[i]; + } + else if(opName.compare("--amd") == 0) + { + ++i; + if( i >=argc ) + { + printer::inst()->print_msg(L0, "No argument for opName '--amd' given"); + win_exit(); + return 1; + } + Params::inst().configFileAMD = argv[i]; + } + else if(opName.compare("--nvidia") == 0) + { + ++i; + if( i >=argc ) + { + printer::inst()->print_msg(L0, "No argument for opName '--nvidia' given"); + win_exit(); + return 1; + } + Params::inst().configFileNVIDIA = argv[i]; + } + else if(opName.compare("-o") == 0 || opName.compare("--url") == 0) + { + ++i; + if( i >=argc ) + { + printer::inst()->print_msg(L0, "No argument for opName '-o/--url' given"); + win_exit(); + return 1; + } + Params::inst().poolURL = argv[i]; + } + else if(opName.compare("-u") == 0 || opName.compare("--user") == 0) + { + ++i; + if( i >=argc ) + { + printer::inst()->print_msg(L0, "No argument for opName '-u/--user' given"); + win_exit(); + return 1; + } + Params::inst().poolUsername = argv[i]; + } + else if(opName.compare("-p") == 0 || opName.compare("--pass") == 0) + { + ++i; + if( i >=argc ) + { + printer::inst()->print_msg(L0, "No argument for opName '-p/--pass' given"); + win_exit(); + return 1; + } + Params::inst().poolPasswd = argv[i]; } else - sFilename = argv[1]; + Params::inst().configFile = argv[i]; } + - if(!jconf::inst()->parse_config(sFilename)) + if(!jconf::inst()->parse_config(Params::inst().configFile.c_str())) { win_exit(); return 0; @@ -103,13 +186,6 @@ int main(int argc, char *argv[]) return 0; } - if(benchmark_mode) - { - do_benchmark(); - win_exit(); - return 0; - } - #ifndef CONF_NO_HTTPD if(jconf::inst()->GetHttpdPort() != 0) { diff --git a/jconf.h b/jconf.h index 2865652..934d6f8 100644 --- a/jconf.h +++ b/jconf.h @@ -2,6 +2,7 @@ #include #include #include "Environment.hpp" +#include "Params.hpp" class jconf { @@ -14,7 +15,7 @@ public: return env.pJconfConfig; }; - bool parse_config(const char* sFilename); + bool parse_config(const char* sFilename = xmrstak::Params::inst().configFile.c_str()); struct thd_cfg { bool bDoubleMode; From 0938fd98364f7265a827ee9ed7d7b3d5a6251dcb Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Thu, 28 Sep 2017 20:39:02 +0200 Subject: [PATCH 18/42] fix opencl for windows - splitt literal to smaller chunks (windows only support 16k literals) - remove copy command for opencl folder --- CMakeLists.txt | 3 - backend/amd/amd_gpu/opencl/cryptonight.cl | 129 +--------------------- backend/amd/amd_gpu/opencl/groestl256.cl | 3 + 3 files changed, 8 insertions(+), 127 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cf776e1..ade87b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -399,9 +399,6 @@ else() set(WIN_OUTPUT_RELEASE "/Release") endif() -install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/opencl" - DESTINATION "${CMAKE_INSTALL_PREFIX}/bin${WIN_OUTPUT_RELEASE}") - # avoid overwrite of user defined settings # install `config.txt`if file not exists in `${CMAKE_INSTALL_PREFIX}/bin` install(CODE " \ diff --git a/backend/amd/amd_gpu/opencl/cryptonight.cl b/backend/amd/amd_gpu/opencl/cryptonight.cl index 4aae939..1bb334a 100644 --- a/backend/amd/amd_gpu/opencl/cryptonight.cl +++ b/backend/amd/amd_gpu/opencl/cryptonight.cl @@ -364,6 +364,9 @@ void keccakf1600_2(ulong *st) } } +)===" +R"===( + void CNKeccak(ulong *output, ulong *input) { ulong st[25]; @@ -608,130 +611,8 @@ __kernel void cn2(__global uint4 *Scratchpad, __global ulong *states, __global u mem_fence(CLK_GLOBAL_MEM_FENCE); } -/* -__kernel void cryptonight(__global ulong *input, __global uint4 *Scratchpad, __global ulong *states, __global uint *Branch0, __global uint *Branch1, __global uint *Branch2, __global uint *Branch3, ulong ThreadCount) -{ - uchar State[200]; - __local uint AES0[256], AES1[256], AES2[256], AES3[256]; - uchar ExpandedKey1[256], ExpandedKey2[256]; - ulong inbuf[10], a[2], b[2]; - uint4 text[8]; - - for(int i = 0; i < 256; ++i) - { - const uint tmp = AES0_C[i]; - AES0[i] = tmp; - AES1[i] = rotate(tmp, 8U); - AES2[i] = rotate(tmp, 16U); - AES3[i] = rotate(tmp, 24U); - } - - ((ulong8 *)inbuf)[0] = vload8(0, input); - inbuf[8] = input[8]; - inbuf[9] = (ulong)((__global uint *)input)[18]; - - ((uint *)(((uchar *)inbuf) + 39))[0] = get_global_id(0); - CNKeccak((ulong *)State, inbuf); - - a[0] = ((ulong *)State)[0] ^ ((ulong *)State)[4]; - b[0] = ((ulong *)State)[2] ^ ((ulong *)State)[6]; - a[1] = ((ulong *)State)[1] ^ ((ulong *)State)[5]; - b[1] = ((ulong *)State)[3] ^ ((ulong *)State)[7]; - - for(uint i = 0; i < 8; ++i) text[i] = vload4(i + 4, (uint *)(State)); - - for(int i = 0; i < 4; ++i) ((ulong *)ExpandedKey1)[i] = ((ulong *)State)[i]; - for(int i = 0; i < 4; ++i) ((ulong *)ExpandedKey2)[i] = ((ulong *)State)[i + 4]; - - AESExpandKey256(ExpandedKey1); - AESExpandKey256(ExpandedKey2); - - mem_fence(CLK_LOCAL_MEM_FENCE); - - Scratchpad += ((1 << 17) * (get_global_id(0) - get_global_offset(0))); - - //#pragma unroll 1 - for(int i = 0; i < (1 << 17); i += 8) - { - #pragma unroll - for(int j = 0; j < 10; ++j) - { - #pragma unroll - for(int x = 0; x < 8; ++x) - text[x] = AES_Round(AES0, AES1, AES2, AES3, text[x], ((uint4 *)ExpandedKey1)[j]); - } - - for(int j = 0; j < 8; ++j) *(Scratchpad + i + j) = text[j]; - } - - - uint4 b_x = ((uint4 *)b)[0]; - - //#pragma unroll 1 - for(int i = 0; i < 0x80000; ++i) - { - ulong c[2]; - - ((uint4 *)c)[0] = Scratchpad[(a[0] & 0x1FFFF0) >> 4]; - ((uint4 *)c)[0] = AES_Round(AES0, AES1, AES2, AES3, ((uint4 *)c)[0], ((uint4 *)a)[0]); - b_x ^= ((uint4 *)c)[0]; - - Scratchpad[(a[0] & 0x1FFFF0) >> 4] = b_x; - - uint4 tmp; - tmp = Scratchpad[(c[0] & 0x1FFFF0) >> 4]; - - a[1] += c[0] * as_ulong2(tmp).s0; - a[0] += mul_hi(c[0], as_ulong2(tmp).s0); - - Scratchpad[(c[0] & 0x1FFFF0) >> 4] = ((uint4 *)a)[0]; - - ((uint4 *)a)[0] ^= tmp; - - b_x = ((uint4 *)c)[0]; - } - - for(uint i = 0; i < 8; ++i) text[i] = vload4(i + 4, (uint *)(State)); - - for(int i = 0; i < (1 << 17); i += 8) - { - #pragma unroll - for(int j = 0; j < 8; ++j) text[j] ^= Scratchpad[i + j]; - - #pragma unroll 1 - for(int j = 0; j < 10; ++j) - { - #pragma unroll - for(int x = 0; x < 8; ++x) - text[x] = AES_Round(AES0, AES1, AES2, AES3, text[x], ((uint4 *)ExpandedKey2)[j]); - } - } - - for(uint i = 0; i < 8; ++i) vstore4(text[i], i + 4, (uint *)(State)); - - keccakf1600((ulong *)State); - - states += (25 * (get_global_id(0) - get_global_offset(0))); - - for(int i = 0; i < 25; ++i) states[i] = ((ulong *)State)[i]; - - switch(State[0] & 3) - { - case 0: - Branch0[atomic_inc(Branch0 + ThreadCount)] = get_global_id(0) - get_global_offset(0); - break; - case 1: - Branch1[atomic_inc(Branch1 + ThreadCount)] = get_global_id(0) - get_global_offset(0); - break; - case 2: - Branch2[atomic_inc(Branch2 + ThreadCount)] = get_global_id(0) - get_global_offset(0); - break; - case 3: - Branch3[atomic_inc(Branch3 + ThreadCount)] = get_global_id(0) - get_global_offset(0); - break; - } -} -*/ +)===" +R"===( #define VSWAP8(x) (((x) >> 56) | (((x) >> 40) & 0x000000000000FF00UL) | (((x) >> 24) & 0x0000000000FF0000UL) \ | (((x) >> 8) & 0x00000000FF000000UL) | (((x) << 8) & 0x000000FF00000000UL) \ diff --git a/backend/amd/amd_gpu/opencl/groestl256.cl b/backend/amd/amd_gpu/opencl/groestl256.cl index 403820d..1a7c96f 100644 --- a/backend/amd/amd_gpu/opencl/groestl256.cl +++ b/backend/amd/amd_gpu/opencl/groestl256.cl @@ -124,6 +124,9 @@ static const __constant ulong T0_G[] = 0x7bcbf646cb463d7bUL, 0xa8fc4b1ffc1fb7a8UL, 0x6dd6da61d6610c6dUL, 0x2c3a584e3a4e622cUL }; +)===" +R"===( + static const __constant ulong T4_G[] = { 0xA5F432C6C6A597F4UL, 0x84976FF8F884EB97UL, 0x99B05EEEEE99C7B0UL, 0x8D8C7AF6F68DF78CUL, From 1fbd6f6b168ea66da38b3518b830a08e3af79e26 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Thu, 28 Sep 2017 20:45:19 +0200 Subject: [PATCH 19/42] use runtime enable/disable flag for backends --- backend/BackendConnector.cpp | 38 +++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/backend/BackendConnector.cpp b/backend/BackendConnector.cpp index 0ef69f1..1013f79 100644 --- a/backend/BackendConnector.cpp +++ b/backend/BackendConnector.cpp @@ -45,6 +45,7 @@ #include "Plugin.hpp" #include "../Environment.hpp" #include "../console.h" +#include "../Params.hpp" namespace xmrstak { @@ -65,26 +66,35 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) std::vector* pvThreads = new std::vector; #ifndef CONF_NO_CUDA - Plugin nvidiaPlugin("NVIDIA", "xmrstak_cuda_backend"); - std::vector* nvidiaThreads = nvidiaPlugin.startBackend(static_cast(pvThreads->size()), pWork, Environment::inst()); - pvThreads->insert(std::end(*pvThreads), std::begin(*nvidiaThreads), std::end(*nvidiaThreads)); - if(nvidiaThreads->size() == 0) - printer::inst()->print_msg(L0, "WARNING: backend NVIDIA disabled."); + if(Params::inst().useNVIDIA) + { + Plugin nvidiaPlugin("NVIDIA", "xmrstak_cuda_backend"); + std::vector* nvidiaThreads = nvidiaPlugin.startBackend(static_cast(pvThreads->size()), pWork, Environment::inst()); + pvThreads->insert(std::end(*pvThreads), std::begin(*nvidiaThreads), std::end(*nvidiaThreads)); + if(nvidiaThreads->size() == 0) + printer::inst()->print_msg(L0, "WARNING: backend NVIDIA disabled."); + } #endif #ifndef CONF_NO_OPENCL - Plugin amdPlugin("AMD", "xmrstak_opencl_backend"); - std::vector* amdThreads = amdPlugin.startBackend(static_cast(pvThreads->size()), pWork, Environment::inst()); - pvThreads->insert(std::end(*pvThreads), std::begin(*amdThreads), std::end(*amdThreads)); - if(amdThreads->size() == 0) - printer::inst()->print_msg(L0, "WARNING: backend AMD disabled."); + if(Params::inst().useAMD) + { + Plugin amdPlugin("AMD", "xmrstak_opencl_backend"); + std::vector* amdThreads = amdPlugin.startBackend(static_cast(pvThreads->size()), pWork, Environment::inst()); + pvThreads->insert(std::end(*pvThreads), std::begin(*amdThreads), std::end(*amdThreads)); + if(amdThreads->size() == 0) + printer::inst()->print_msg(L0, "WARNING: backend AMD disabled."); + } #endif #ifndef CONF_NO_CPU - auto cpuThreads = cpu::minethd::thread_starter(static_cast(pvThreads->size()), pWork); - pvThreads->insert(std::end(*pvThreads), std::begin(cpuThreads), std::end(cpuThreads)); - if(cpuThreads.size() == 0) - printer::inst()->print_msg(L0, "WARNING: backend CPU disabled."); + if(Params::inst().useCPU) + { + auto cpuThreads = cpu::minethd::thread_starter(static_cast(pvThreads->size()), pWork); + pvThreads->insert(std::end(*pvThreads), std::begin(cpuThreads), std::end(cpuThreads)); + if(cpuThreads.size() == 0) + printer::inst()->print_msg(L0, "WARNING: backend CPU disabled."); + } #endif GlobalStates::inst().iThreadCount = pvThreads->size(); From 4fb2b5efee2ca3b0a46d484e0ca35e3dcaeac1d2 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Thu, 28 Sep 2017 21:20:27 +0200 Subject: [PATCH 20/42] add command line poll/passwd/usename overwrite Use command line poolname, password and username if defined --- jconf.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/jconf.cpp b/jconf.cpp index 00c34f1..bfa2626 100644 --- a/jconf.cpp +++ b/jconf.cpp @@ -39,6 +39,7 @@ #include "rapidjson/error/en.h" #include "jext.h" #include "console.h" +#include "Params.hpp" using namespace rapidjson; @@ -127,17 +128,27 @@ const char* jconf::GetTlsFingerprint() const char* jconf::GetPoolAddress() { - return prv->configValues[sPoolAddr]->GetString(); + auto& poolURL = xmrstak::Params::inst().poolURL; + if(poolURL.empty()) + poolURL = prv->configValues[sPoolAddr]->GetString(); + return poolURL.c_str(); } const char* jconf::GetPoolPwd() { - return prv->configValues[sPoolPwd]->GetString(); + auto& poolPasswd = xmrstak::Params::inst().poolPasswd; + if(poolPasswd.empty()) + poolPasswd = prv->configValues[sPoolPwd]->GetString(); + return poolPasswd.c_str(); + } const char* jconf::GetWalletAddress() { - return prv->configValues[sWalletAddr]->GetString(); + auto& poolUsername = xmrstak::Params::inst().poolUsername; + if(poolUsername.empty()) + poolUsername = prv->configValues[sWalletAddr]->GetString(); + return poolUsername.c_str(); } bool jconf::PreferIpv4() From 82242501b02d19cf6549d35c5b8a8dd2a62a84d0 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Thu, 28 Sep 2017 21:31:02 +0200 Subject: [PATCH 21/42] remove wrong commited cmake files --- CMakeCache.txt | 38 ------------------------------------ CMakeFiles/cmake.check_cache | 1 - 2 files changed, 39 deletions(-) delete mode 100644 CMakeCache.txt delete mode 100644 CMakeFiles/cmake.check_cache diff --git a/CMakeCache.txt b/CMakeCache.txt deleted file mode 100644 index 3c42ff2..0000000 --- a/CMakeCache.txt +++ /dev/null @@ -1,38 +0,0 @@ -# This is the CMakeCache file. -# For build in directory: /home/psychocrypt/workspace/xmr-stak-cpu -# It was generated by CMake: /usr/bin/cmake -# You can edit this file to change values found and used by cmake. -# If you do not want to change any of the values, simply exit the editor. -# If you do want to change a value, simply edit, save, and exit the editor. -# The syntax for the file is as follows: -# KEY:TYPE=VALUE -# KEY is the name of a variable in the cache. -# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!. -# VALUE is the current value for the KEY. - -######################## -# EXTERNAL cache entries -######################## - - -######################## -# INTERNAL cache entries -######################## - -//This is the directory where this CMakeCache.txt was created -CMAKE_CACHEFILE_DIR:INTERNAL=/home/psychocrypt/workspace/xmr-stak-cpu -//Major version of cmake used to create the current loaded cache -CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3 -//Minor version of cmake used to create the current loaded cache -CMAKE_CACHE_MINOR_VERSION:INTERNAL=5 -//Patch version of cmake used to create the current loaded cache -CMAKE_CACHE_PATCH_VERSION:INTERNAL=1 -//Path to CMake executable. -CMAKE_COMMAND:INTERNAL=/usr/bin/cmake -//Path to cpack program executable. -CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack -//Path to ctest program executable. -CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest -//Path to CMake installation. -CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.5 - diff --git a/CMakeFiles/cmake.check_cache b/CMakeFiles/cmake.check_cache deleted file mode 100644 index 3dccd73..0000000 --- a/CMakeFiles/cmake.check_cache +++ /dev/null @@ -1 +0,0 @@ -# This file is generated by cmake for dependency checking of the CMakeCache.txt file From 39d144639f837ee4a49c25158c2385f007d01417 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Thu, 28 Sep 2017 23:12:53 +0200 Subject: [PATCH 22/42] config as template - create config on startup - remove copy `config.txt` on `make install` --- CMakeLists.txt | 9 -------- cli/cli-miner.cpp | 44 +++++++++++++++++++++++++++++++++++----- config.txt => config.tpl | 10 ++++++--- 3 files changed, 46 insertions(+), 17 deletions(-) rename config.txt => config.tpl (98%) diff --git a/CMakeLists.txt b/CMakeLists.txt index ade87b2..f818209 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -398,12 +398,3 @@ if( NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "${PROJECT_BINARY_DIR}" ) else() set(WIN_OUTPUT_RELEASE "/Release") endif() - -# avoid overwrite of user defined settings -# install `config.txt`if file not exists in `${CMAKE_INSTALL_PREFIX}/bin` -install(CODE " \ - if(NOT EXISTS ${CMAKE_INSTALL_PREFIX}/bin${WIN_OUTPUT_RELEASE}/config.txt)\n \ - file(INSTALL ${CMAKE_CURRENT_SOURCE_DIR}/config.txt \ - DESTINATION ${CMAKE_INSTALL_PREFIX}/bin${WIN_OUTPUT_RELEASE})\n \ - endif()" -) diff --git a/cli/cli-miner.cpp b/cli/cli-miner.cpp index df9432e..f2c5c1d 100644 --- a/cli/cli-miner.cpp +++ b/cli/cli-miner.cpp @@ -29,6 +29,7 @@ #include "../console.h" #include "../donate-level.h" #include "../Params.hpp" +#include "../ConfigEditor.hpp" #include "../version.h" @@ -39,6 +40,7 @@ #include #include #include +#include #include @@ -91,17 +93,14 @@ int main(int argc, char *argv[]) else if(opName.compare("--noCPU") == 0) { Params::inst().useCPU = false; - return 0; } else if(opName.compare("--noAMD") == 0) { Params::inst().useAMD = false; - return 0; } else if(opName.compare("--noAMD") == 0) { Params::inst().useNVIDIA = false; - return 0; } else if(opName.compare("--cpu") == 0) { @@ -172,7 +171,42 @@ int main(int argc, char *argv[]) else Params::inst().configFile = argv[i]; } - + + // check if we need a guided start + if(!ConfigEditor::file_exist(Params::inst().configFile)) + { + // load the template of the backend config into a char variable + const char *tpl = + #include "../config.tpl" + ; + ConfigEditor configTpl{}; + configTpl.set(std::string(tpl)); + auto& pool = Params::inst().poolURL; + if(pool.empty()) + { + std::cout<<"Please enter:\n- pool address: e.g. pool.usxmrpool.com:3333"<> pool; + } + auto& userName = Params::inst().poolUsername; + if(userName.empty()) + { + std::cout<<"- user name (wallet address or pool login):"<> userName; + } + auto& passwd = Params::inst().poolPasswd; + if(passwd.empty()) + { + // clear everything from stdin to allow an empty password + std::cin.clear(); std::cin.ignore(INT_MAX,'\n'); + std::cout<<"- password (mostly empty or x):"<parse_config(Params::inst().configFile.c_str())) { @@ -180,7 +214,7 @@ int main(int argc, char *argv[]) return 0; } - if (!xmrstak::BackendConnector::self_test()) + if (!BackendConnector::self_test()) { win_exit(); return 0; diff --git a/config.txt b/config.tpl similarity index 98% rename from config.txt rename to config.tpl index 888b655..60d85cd 100644 --- a/config.txt +++ b/config.tpl @@ -1,3 +1,4 @@ +R"===( /* * pool_address - Pool address should be in the form "pool.supportxmr.com:3333". Only stratum pools are supported. * wallet_address - Your wallet, or pool login. @@ -5,9 +6,9 @@ * * We feature pools up to 1MH/s. For a more complete list see M5M400's pool list at www.moneropools.com */ -"pool_address" : "pool.usxmrpool.com:3333", -"wallet_address" : "", -"pool_password" : "", +"pool_address" : "POOLURL", +"wallet_address" : "POOLUSER", +"pool_password" : "POOLPASSWD", /* * Network timeouts. @@ -155,3 +156,6 @@ * This setting will only be needed in 2020's. No need to worry about it now. */ "prefer_ipv4" : true, + +)===" + \ No newline at end of file From e5b0319d5a9f58762fa934ad700113908940cb31 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Thu, 28 Sep 2017 23:23:55 +0200 Subject: [PATCH 23/42] log invalid backend results - executor.h: expose log_`result_error()` - register wrong results --- backend/amd/minethd.cpp | 7 +------ backend/nvidia/minethd.cpp | 5 +---- executor.h | 2 +- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/backend/amd/minethd.cpp b/backend/amd/minethd.cpp index b938f2d..f2f5ff4 100644 --- a/backend/amd/minethd.cpp +++ b/backend/amd/minethd.cpp @@ -216,14 +216,9 @@ void minethd::work_main() hash_fun(bWorkBlob, oWork.iWorkSize, bResult, cpu_ctx); if ( (*((uint64_t*)(bResult + 24))) < oWork.iTarget) - { - std::cout<<"found AMD"<push_event(ex_event(job_result(oWork.sJobID, results[i], bResult), oWork.iPoolId)); - } else - std::cout<<"wrong AMD"<push_event(ex_event(job_result(oWork.sJobID, results[i], bResult), oWork.iPoolId)); + executor::inst()->log_result_error("AMD Invalid Result"); } iCount += pGpuCtx->rawIntensity; diff --git a/backend/nvidia/minethd.cpp b/backend/nvidia/minethd.cpp index 227a2cf..cbee219 100644 --- a/backend/nvidia/minethd.cpp +++ b/backend/nvidia/minethd.cpp @@ -249,12 +249,9 @@ void minethd::work_main() hash_fun(bWorkBlob, oWork.iWorkSize, bResult, cpu_ctx); if ( (*((uint64_t*)(bResult + 24))) < oWork.iTarget) - { - std::cout<<"found NVIDIA"<push_event(ex_event(job_result(oWork.sJobID, foundNonce[i], bResult), oWork.iPoolId)); - } else - std::cout<<"wrong NVIDIA"<log_result_error("NVIDIA Invalid Result"); } iCount += ctx.device_blocks * ctx.device_threads; diff --git a/executor.h b/executor.h index d7fa27d..a3a0828 100644 --- a/executor.h +++ b/executor.h @@ -38,6 +38,7 @@ public: inline void push_event(ex_event&& ev) { oEventQ.push(std::move(ev)); } void push_timed_event(ex_event&& ev, size_t sec); + void log_result_error(std::string&& sError); constexpr static size_t invalid_pool_id = 0; constexpr static size_t dev_pool_id = 1; @@ -169,7 +170,6 @@ private: double fHighestHps = 0.0; void log_socket_error(std::string&& sError); - void log_result_error(std::string&& sError); void log_result_ok(uint64_t iActualDiff); void sched_reconnect(); From cc429b68fadc502b981fd0acd64a5ff6e2ae1d15 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Fri, 29 Sep 2017 20:32:31 +0200 Subject: [PATCH 24/42] group files - move source code to `src` - categorize files and move to group folder - change upper case class files to lower case - change C++ header to `*.hpp` --- CMakeLists.txt | 22 ++- FREEBSDCOMPILE.md => doc/FREEBSDCOMPILE.md | 0 LINUXCOMPILE.md => doc/LINUXCOMPILE.md | 0 WINCOMPILE.md => doc/WINCOMPILE.md | 0 xmr-stak-cpu.cbp | 167 ------------------ .../backend}/amd/amd_gpu/gpu.cpp | 0 .../backend/amd/amd_gpu/gpu.hpp | 0 .../backend}/amd/amd_gpu/opencl/blake256.cl | 0 .../amd/amd_gpu/opencl/cryptonight.cl | 0 .../backend}/amd/amd_gpu/opencl/groestl256.cl | 0 .../backend}/amd/amd_gpu/opencl/jh.cl | 0 .../backend}/amd/amd_gpu/opencl/wolf-aes.cl | 0 .../backend}/amd/amd_gpu/opencl/wolf-skein.cl | 0 .../backend}/amd/autoAdjust.hpp | 0 {backend => xmrstak/backend}/amd/config.tpl | 0 {backend => xmrstak/backend}/amd/jconf.cpp | 0 .../jconf.h => xmrstak/backend/amd/jconf.hpp | 0 {backend => xmrstak/backend}/amd/minethd.cpp | 0 .../backend/amd/minethd.hpp | 0 .../backend/backendConnector.cpp | 0 .../backend/backendConnector.hpp | 0 .../backend}/cpu/autoAdjust.hpp | 0 .../backend}/cpu/autoAdjustHwloc.hpp | 0 {backend => xmrstak/backend}/cpu/config.tpl | 0 .../backend/cpu/crypto}/c_blake256.c | 0 .../backend/cpu/crypto}/c_blake256.h | 0 .../backend/cpu/crypto}/c_groestl.c | 0 .../backend/cpu/crypto}/c_groestl.h | 0 {crypto => xmrstak/backend/cpu/crypto}/c_jh.c | 0 {crypto => xmrstak/backend/cpu/crypto}/c_jh.h | 0 .../backend/cpu/crypto}/c_keccak.c | 0 .../backend/cpu/crypto}/c_keccak.h | 0 .../backend/cpu/crypto}/c_skein.c | 0 .../backend/cpu/crypto}/c_skein.h | 0 .../backend/cpu/crypto}/cryptonight.h | 0 .../backend/cpu/crypto}/cryptonight_aesni.h | 0 .../cpu/crypto}/cryptonight_common.cpp | 0 .../backend/cpu/crypto}/groestl_tables.h | 0 {crypto => xmrstak/backend/cpu/crypto}/hash.h | 0 .../backend/cpu/crypto}/int-util.h | 0 .../backend/cpu/crypto}/skein_port.h | 0 .../backend/cpu/crypto}/soft_aes.c | 0 .../backend/cpu/hwlocMemory.hpp | 0 {backend => xmrstak/backend}/cpu/jconf.cpp | 0 .../jconf.h => xmrstak/backend/cpu/jconf.hpp | 0 {backend => xmrstak/backend}/cpu/minethd.cpp | 0 .../backend/cpu/minethd.hpp | 0 .../backend/globalStates.cpp | 0 .../backend/globalStates.hpp | 0 .../backend/iBackend.hpp | 0 .../backend/miner_work.hpp | 0 .../backend}/nvidia/autoAdjust.hpp | 0 .../backend}/nvidia/config.tpl | 0 {backend => xmrstak/backend}/nvidia/jconf.cpp | 0 .../backend/nvidia/jconf.hpp | 0 .../backend}/nvidia/minethd.cpp | 0 .../backend/nvidia/minethd.hpp | 0 .../backend/nvidia/nvcc_code/cryptonight.hpp | 0 .../backend}/nvidia/nvcc_code/cuda_aes.hpp | 0 .../backend}/nvidia/nvcc_code/cuda_blake.hpp | 0 .../backend}/nvidia/nvcc_code/cuda_core.cu | 0 .../backend}/nvidia/nvcc_code/cuda_device.hpp | 0 .../backend}/nvidia/nvcc_code/cuda_extra.cu | 0 .../backend/nvidia/nvcc_code/cuda_extra.hpp | 0 .../nvidia/nvcc_code/cuda_groestl.hpp | 0 .../backend}/nvidia/nvcc_code/cuda_jh.hpp | 0 .../backend}/nvidia/nvcc_code/cuda_keccak.hpp | 0 .../backend}/nvidia/nvcc_code/cuda_skein.hpp | 0 .../Plugin.hpp => xmrstak/backend/plugin.hpp | 0 {cli => xmrstak/cli}/cli-miner.cpp | 0 config.tpl => xmrstak/config.tpl | 0 donate-level.h => xmrstak/donate-level.hpp | 0 httpd.cpp => xmrstak/http/httpd.cpp | 0 httpd.h => xmrstak/http/httpd.hpp | 0 webdesign.cpp => xmrstak/http/webdesign.cpp | 0 webdesign.h => xmrstak/http/webdesign.hpp | 0 jconf.cpp => xmrstak/jconf.cpp | 0 jconf.h => xmrstak/jconf.hpp | 0 .../misc/configEditor.hpp | 0 console.cpp => xmrstak/misc/console.cpp | 0 console.h => xmrstak/misc/console.hpp | 0 .../misc/environment.hpp | 0 executor.cpp => xmrstak/misc/executor.cpp | 0 executor.h => xmrstak/misc/executor.hpp | 0 jext.h => xmrstak/misc/jext.hpp | 0 telemetry.cpp => xmrstak/misc/telemetry.cpp | 0 telemetry.h => xmrstak/misc/telemetry.hpp | 0 thdq.hpp => xmrstak/misc/thdq.hpp | 0 jpsock.cpp => xmrstak/net/jpsock.cpp | 0 jpsock.h => xmrstak/net/jpsock.hpp | 0 msgstruct.h => xmrstak/net/msgstruct.hpp | 0 socket.cpp => xmrstak/net/socket.cpp | 0 socket.h => xmrstak/net/socket.hpp | 0 socks.h => xmrstak/net/socks.hpp | 0 Params.hpp => xmrstak/params.hpp | 0 {rapidjson => xmrstak/rapidjson}/allocators.h | 0 {rapidjson => xmrstak/rapidjson}/document.h | 0 .../rapidjson}/encodedstream.h | 0 {rapidjson => xmrstak/rapidjson}/encodings.h | 0 {rapidjson => xmrstak/rapidjson}/error/en.h | 0 .../rapidjson}/error/error.h | 0 .../rapidjson}/filereadstream.h | 0 .../rapidjson}/filewritestream.h | 0 {rapidjson => xmrstak/rapidjson}/fwd.h | 0 .../rapidjson}/internal/biginteger.h | 0 .../rapidjson}/internal/diyfp.h | 0 .../rapidjson}/internal/dtoa.h | 0 .../rapidjson}/internal/ieee754.h | 0 .../rapidjson}/internal/itoa.h | 0 .../rapidjson}/internal/meta.h | 0 .../rapidjson}/internal/pow10.h | 0 .../rapidjson}/internal/regex.h | 0 .../rapidjson}/internal/stack.h | 0 .../rapidjson}/internal/strfunc.h | 0 .../rapidjson}/internal/strtod.h | 0 .../rapidjson}/internal/swap.h | 0 .../rapidjson}/istreamwrapper.h | 0 .../rapidjson}/memorybuffer.h | 0 .../rapidjson}/memorystream.h | 0 .../rapidjson}/msinttypes/inttypes.h | 0 .../rapidjson}/msinttypes/stdint.h | 0 .../rapidjson}/ostreamwrapper.h | 0 {rapidjson => xmrstak/rapidjson}/pointer.h | 0 .../rapidjson}/prettywriter.h | 0 {rapidjson => xmrstak/rapidjson}/rapidjson.h | 0 {rapidjson => xmrstak/rapidjson}/reader.h | 0 {rapidjson => xmrstak/rapidjson}/schema.h | 0 {rapidjson => xmrstak/rapidjson}/stream.h | 0 .../rapidjson}/stringbuffer.h | 0 {rapidjson => xmrstak/rapidjson}/writer.h | 0 version.h => xmrstak/version.hpp | 0 131 files changed, 17 insertions(+), 172 deletions(-) rename FREEBSDCOMPILE.md => doc/FREEBSDCOMPILE.md (100%) rename LINUXCOMPILE.md => doc/LINUXCOMPILE.md (100%) rename WINCOMPILE.md => doc/WINCOMPILE.md (100%) delete mode 100644 xmr-stak-cpu.cbp rename {backend => xmrstak/backend}/amd/amd_gpu/gpu.cpp (100%) rename backend/amd/amd_gpu/gpu.h => xmrstak/backend/amd/amd_gpu/gpu.hpp (100%) rename {backend => xmrstak/backend}/amd/amd_gpu/opencl/blake256.cl (100%) rename {backend => xmrstak/backend}/amd/amd_gpu/opencl/cryptonight.cl (100%) rename {backend => xmrstak/backend}/amd/amd_gpu/opencl/groestl256.cl (100%) rename {backend => xmrstak/backend}/amd/amd_gpu/opencl/jh.cl (100%) rename {backend => xmrstak/backend}/amd/amd_gpu/opencl/wolf-aes.cl (100%) rename {backend => xmrstak/backend}/amd/amd_gpu/opencl/wolf-skein.cl (100%) rename {backend => xmrstak/backend}/amd/autoAdjust.hpp (100%) rename {backend => xmrstak/backend}/amd/config.tpl (100%) rename {backend => xmrstak/backend}/amd/jconf.cpp (100%) rename backend/amd/jconf.h => xmrstak/backend/amd/jconf.hpp (100%) rename {backend => xmrstak/backend}/amd/minethd.cpp (100%) rename backend/amd/minethd.h => xmrstak/backend/amd/minethd.hpp (100%) rename backend/BackendConnector.cpp => xmrstak/backend/backendConnector.cpp (100%) rename backend/BackendConnector.hpp => xmrstak/backend/backendConnector.hpp (100%) rename {backend => xmrstak/backend}/cpu/autoAdjust.hpp (100%) rename {backend => xmrstak/backend}/cpu/autoAdjustHwloc.hpp (100%) rename {backend => xmrstak/backend}/cpu/config.tpl (100%) rename {crypto => xmrstak/backend/cpu/crypto}/c_blake256.c (100%) rename {crypto => xmrstak/backend/cpu/crypto}/c_blake256.h (100%) rename {crypto => xmrstak/backend/cpu/crypto}/c_groestl.c (100%) rename {crypto => xmrstak/backend/cpu/crypto}/c_groestl.h (100%) rename {crypto => xmrstak/backend/cpu/crypto}/c_jh.c (100%) rename {crypto => xmrstak/backend/cpu/crypto}/c_jh.h (100%) rename {crypto => xmrstak/backend/cpu/crypto}/c_keccak.c (100%) rename {crypto => xmrstak/backend/cpu/crypto}/c_keccak.h (100%) rename {crypto => xmrstak/backend/cpu/crypto}/c_skein.c (100%) rename {crypto => xmrstak/backend/cpu/crypto}/c_skein.h (100%) rename {crypto => xmrstak/backend/cpu/crypto}/cryptonight.h (100%) rename {crypto => xmrstak/backend/cpu/crypto}/cryptonight_aesni.h (100%) rename {crypto => xmrstak/backend/cpu/crypto}/cryptonight_common.cpp (100%) rename {crypto => xmrstak/backend/cpu/crypto}/groestl_tables.h (100%) rename {crypto => xmrstak/backend/cpu/crypto}/hash.h (100%) rename {crypto => xmrstak/backend/cpu/crypto}/int-util.h (100%) rename {crypto => xmrstak/backend/cpu/crypto}/skein_port.h (100%) rename {crypto => xmrstak/backend/cpu/crypto}/soft_aes.c (100%) rename hwlocMemory.hpp => xmrstak/backend/cpu/hwlocMemory.hpp (100%) rename {backend => xmrstak/backend}/cpu/jconf.cpp (100%) rename backend/cpu/jconf.h => xmrstak/backend/cpu/jconf.hpp (100%) rename {backend => xmrstak/backend}/cpu/minethd.cpp (100%) rename backend/cpu/minethd.h => xmrstak/backend/cpu/minethd.hpp (100%) rename backend/GlobalStates.cpp => xmrstak/backend/globalStates.cpp (100%) rename backend/GlobalStates.hpp => xmrstak/backend/globalStates.hpp (100%) rename backend/IBackend.hpp => xmrstak/backend/iBackend.hpp (100%) rename backend/miner_work.h => xmrstak/backend/miner_work.hpp (100%) rename {backend => xmrstak/backend}/nvidia/autoAdjust.hpp (100%) rename {backend => xmrstak/backend}/nvidia/config.tpl (100%) rename {backend => xmrstak/backend}/nvidia/jconf.cpp (100%) rename backend/nvidia/jconf.h => xmrstak/backend/nvidia/jconf.hpp (100%) rename {backend => xmrstak/backend}/nvidia/minethd.cpp (100%) rename backend/nvidia/minethd.h => xmrstak/backend/nvidia/minethd.hpp (100%) rename backend/nvidia/nvcc_code/cryptonight.h => xmrstak/backend/nvidia/nvcc_code/cryptonight.hpp (100%) rename {backend => xmrstak/backend}/nvidia/nvcc_code/cuda_aes.hpp (100%) rename {backend => xmrstak/backend}/nvidia/nvcc_code/cuda_blake.hpp (100%) rename {backend => xmrstak/backend}/nvidia/nvcc_code/cuda_core.cu (100%) rename {backend => xmrstak/backend}/nvidia/nvcc_code/cuda_device.hpp (100%) rename {backend => xmrstak/backend}/nvidia/nvcc_code/cuda_extra.cu (100%) rename backend/nvidia/nvcc_code/cuda_extra.h => xmrstak/backend/nvidia/nvcc_code/cuda_extra.hpp (100%) rename {backend => xmrstak/backend}/nvidia/nvcc_code/cuda_groestl.hpp (100%) rename {backend => xmrstak/backend}/nvidia/nvcc_code/cuda_jh.hpp (100%) rename {backend => xmrstak/backend}/nvidia/nvcc_code/cuda_keccak.hpp (100%) rename {backend => xmrstak/backend}/nvidia/nvcc_code/cuda_skein.hpp (100%) rename backend/Plugin.hpp => xmrstak/backend/plugin.hpp (100%) rename {cli => xmrstak/cli}/cli-miner.cpp (100%) rename config.tpl => xmrstak/config.tpl (100%) rename donate-level.h => xmrstak/donate-level.hpp (100%) rename httpd.cpp => xmrstak/http/httpd.cpp (100%) rename httpd.h => xmrstak/http/httpd.hpp (100%) rename webdesign.cpp => xmrstak/http/webdesign.cpp (100%) rename webdesign.h => xmrstak/http/webdesign.hpp (100%) rename jconf.cpp => xmrstak/jconf.cpp (100%) rename jconf.h => xmrstak/jconf.hpp (100%) rename ConfigEditor.hpp => xmrstak/misc/configEditor.hpp (100%) rename console.cpp => xmrstak/misc/console.cpp (100%) rename console.h => xmrstak/misc/console.hpp (100%) rename Environment.hpp => xmrstak/misc/environment.hpp (100%) rename executor.cpp => xmrstak/misc/executor.cpp (100%) rename executor.h => xmrstak/misc/executor.hpp (100%) rename jext.h => xmrstak/misc/jext.hpp (100%) rename telemetry.cpp => xmrstak/misc/telemetry.cpp (100%) rename telemetry.h => xmrstak/misc/telemetry.hpp (100%) rename thdq.hpp => xmrstak/misc/thdq.hpp (100%) rename jpsock.cpp => xmrstak/net/jpsock.cpp (100%) rename jpsock.h => xmrstak/net/jpsock.hpp (100%) rename msgstruct.h => xmrstak/net/msgstruct.hpp (100%) rename socket.cpp => xmrstak/net/socket.cpp (100%) rename socket.h => xmrstak/net/socket.hpp (100%) rename socks.h => xmrstak/net/socks.hpp (100%) rename Params.hpp => xmrstak/params.hpp (100%) rename {rapidjson => xmrstak/rapidjson}/allocators.h (100%) rename {rapidjson => xmrstak/rapidjson}/document.h (100%) rename {rapidjson => xmrstak/rapidjson}/encodedstream.h (100%) rename {rapidjson => xmrstak/rapidjson}/encodings.h (100%) rename {rapidjson => xmrstak/rapidjson}/error/en.h (100%) rename {rapidjson => xmrstak/rapidjson}/error/error.h (100%) rename {rapidjson => xmrstak/rapidjson}/filereadstream.h (100%) rename {rapidjson => xmrstak/rapidjson}/filewritestream.h (100%) rename {rapidjson => xmrstak/rapidjson}/fwd.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/biginteger.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/diyfp.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/dtoa.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/ieee754.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/itoa.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/meta.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/pow10.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/regex.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/stack.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/strfunc.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/strtod.h (100%) rename {rapidjson => xmrstak/rapidjson}/internal/swap.h (100%) rename {rapidjson => xmrstak/rapidjson}/istreamwrapper.h (100%) rename {rapidjson => xmrstak/rapidjson}/memorybuffer.h (100%) rename {rapidjson => xmrstak/rapidjson}/memorystream.h (100%) rename {rapidjson => xmrstak/rapidjson}/msinttypes/inttypes.h (100%) rename {rapidjson => xmrstak/rapidjson}/msinttypes/stdint.h (100%) rename {rapidjson => xmrstak/rapidjson}/ostreamwrapper.h (100%) rename {rapidjson => xmrstak/rapidjson}/pointer.h (100%) rename {rapidjson => xmrstak/rapidjson}/prettywriter.h (100%) rename {rapidjson => xmrstak/rapidjson}/rapidjson.h (100%) rename {rapidjson => xmrstak/rapidjson}/reader.h (100%) rename {rapidjson => xmrstak/rapidjson}/schema.h (100%) rename {rapidjson => xmrstak/rapidjson}/stream.h (100%) rename {rapidjson => xmrstak/rapidjson}/stringbuffer.h (100%) rename {rapidjson => xmrstak/rapidjson}/writer.h (100%) rename version.h => xmrstak/version.hpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index f818209..5c97ca3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -313,14 +313,22 @@ if(CMAKE_LINK_STATIC) set(LIBS "-static-libgcc -static-libstdc++ ${LIBS}") endif() -file(GLOB SRCFILES_C "crypto/*.c") +file(GLOB SRCFILES_C "backend/cpu/crypto/*.c") add_library(xmr-stak-c STATIC ${SRCFILES_C} ) -file(GLOB BACKEND_CPP "*.cpp" "backend/cpu/*.cpp" "backend/*.cpp" "crypto/*.cpp") +file(GLOB BACKEND_CPP + "*.cpp" + "backend/cpu/*.cpp" + "backend/*.cpp" + "backend/cpu/crypto/*.cpp" + "http/*.cpp" + "misc/*.cpp" + "net/*.cpp") + add_library(xmr-stak-backend STATIC ${BACKEND_CPP} @@ -328,7 +336,9 @@ add_library(xmr-stak-backend target_link_libraries(xmr-stak-backend xmr-stak-c ${CMAKE_DL_LIBS}) if(CUDA_FOUND) - file(GLOB CUDASRCFILES "backend/nvidia/nvcc_code/*.cu" "backend/nvidia/*.cpp") + file(GLOB CUDASRCFILES + "backend/nvidia/nvcc_code/*.cu" + "backend/nvidia/*.cpp") # build device code with nvcc cuda_add_library(xmrstak_cuda_backend @@ -342,10 +352,12 @@ if(CUDA_FOUND) endif() if(OpenCL_FOUND) - file(GLOB OPENCLSRCFILES_C "backend/amd/amd_gpu/*.cpp" "backend/amd/*.cpp") + file(GLOB OPENCLSRCFILES + "backend/amd/amd_gpu/*.cpp" + "backend/amd/*.cpp") add_library(xmrstak_opencl_backend SHARED - ${OPENCLSRCFILES_C} + ${OPENCLSRCFILES} ) target_link_libraries(xmrstak_opencl_backend ${OpenCL_LIBRARY} ) if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") diff --git a/FREEBSDCOMPILE.md b/doc/FREEBSDCOMPILE.md similarity index 100% rename from FREEBSDCOMPILE.md rename to doc/FREEBSDCOMPILE.md diff --git a/LINUXCOMPILE.md b/doc/LINUXCOMPILE.md similarity index 100% rename from LINUXCOMPILE.md rename to doc/LINUXCOMPILE.md diff --git a/WINCOMPILE.md b/doc/WINCOMPILE.md similarity index 100% rename from WINCOMPILE.md rename to doc/WINCOMPILE.md diff --git a/xmr-stak-cpu.cbp b/xmr-stak-cpu.cbp deleted file mode 100644 index c2f3774..0000000 --- a/xmr-stak-cpu.cbp +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - diff --git a/backend/amd/amd_gpu/gpu.cpp b/xmrstak/backend/amd/amd_gpu/gpu.cpp similarity index 100% rename from backend/amd/amd_gpu/gpu.cpp rename to xmrstak/backend/amd/amd_gpu/gpu.cpp diff --git a/backend/amd/amd_gpu/gpu.h b/xmrstak/backend/amd/amd_gpu/gpu.hpp similarity index 100% rename from backend/amd/amd_gpu/gpu.h rename to xmrstak/backend/amd/amd_gpu/gpu.hpp diff --git a/backend/amd/amd_gpu/opencl/blake256.cl b/xmrstak/backend/amd/amd_gpu/opencl/blake256.cl similarity index 100% rename from backend/amd/amd_gpu/opencl/blake256.cl rename to xmrstak/backend/amd/amd_gpu/opencl/blake256.cl diff --git a/backend/amd/amd_gpu/opencl/cryptonight.cl b/xmrstak/backend/amd/amd_gpu/opencl/cryptonight.cl similarity index 100% rename from backend/amd/amd_gpu/opencl/cryptonight.cl rename to xmrstak/backend/amd/amd_gpu/opencl/cryptonight.cl diff --git a/backend/amd/amd_gpu/opencl/groestl256.cl b/xmrstak/backend/amd/amd_gpu/opencl/groestl256.cl similarity index 100% rename from backend/amd/amd_gpu/opencl/groestl256.cl rename to xmrstak/backend/amd/amd_gpu/opencl/groestl256.cl diff --git a/backend/amd/amd_gpu/opencl/jh.cl b/xmrstak/backend/amd/amd_gpu/opencl/jh.cl similarity index 100% rename from backend/amd/amd_gpu/opencl/jh.cl rename to xmrstak/backend/amd/amd_gpu/opencl/jh.cl diff --git a/backend/amd/amd_gpu/opencl/wolf-aes.cl b/xmrstak/backend/amd/amd_gpu/opencl/wolf-aes.cl similarity index 100% rename from backend/amd/amd_gpu/opencl/wolf-aes.cl rename to xmrstak/backend/amd/amd_gpu/opencl/wolf-aes.cl diff --git a/backend/amd/amd_gpu/opencl/wolf-skein.cl b/xmrstak/backend/amd/amd_gpu/opencl/wolf-skein.cl similarity index 100% rename from backend/amd/amd_gpu/opencl/wolf-skein.cl rename to xmrstak/backend/amd/amd_gpu/opencl/wolf-skein.cl diff --git a/backend/amd/autoAdjust.hpp b/xmrstak/backend/amd/autoAdjust.hpp similarity index 100% rename from backend/amd/autoAdjust.hpp rename to xmrstak/backend/amd/autoAdjust.hpp diff --git a/backend/amd/config.tpl b/xmrstak/backend/amd/config.tpl similarity index 100% rename from backend/amd/config.tpl rename to xmrstak/backend/amd/config.tpl diff --git a/backend/amd/jconf.cpp b/xmrstak/backend/amd/jconf.cpp similarity index 100% rename from backend/amd/jconf.cpp rename to xmrstak/backend/amd/jconf.cpp diff --git a/backend/amd/jconf.h b/xmrstak/backend/amd/jconf.hpp similarity index 100% rename from backend/amd/jconf.h rename to xmrstak/backend/amd/jconf.hpp diff --git a/backend/amd/minethd.cpp b/xmrstak/backend/amd/minethd.cpp similarity index 100% rename from backend/amd/minethd.cpp rename to xmrstak/backend/amd/minethd.cpp diff --git a/backend/amd/minethd.h b/xmrstak/backend/amd/minethd.hpp similarity index 100% rename from backend/amd/minethd.h rename to xmrstak/backend/amd/minethd.hpp diff --git a/backend/BackendConnector.cpp b/xmrstak/backend/backendConnector.cpp similarity index 100% rename from backend/BackendConnector.cpp rename to xmrstak/backend/backendConnector.cpp diff --git a/backend/BackendConnector.hpp b/xmrstak/backend/backendConnector.hpp similarity index 100% rename from backend/BackendConnector.hpp rename to xmrstak/backend/backendConnector.hpp diff --git a/backend/cpu/autoAdjust.hpp b/xmrstak/backend/cpu/autoAdjust.hpp similarity index 100% rename from backend/cpu/autoAdjust.hpp rename to xmrstak/backend/cpu/autoAdjust.hpp diff --git a/backend/cpu/autoAdjustHwloc.hpp b/xmrstak/backend/cpu/autoAdjustHwloc.hpp similarity index 100% rename from backend/cpu/autoAdjustHwloc.hpp rename to xmrstak/backend/cpu/autoAdjustHwloc.hpp diff --git a/backend/cpu/config.tpl b/xmrstak/backend/cpu/config.tpl similarity index 100% rename from backend/cpu/config.tpl rename to xmrstak/backend/cpu/config.tpl diff --git a/crypto/c_blake256.c b/xmrstak/backend/cpu/crypto/c_blake256.c similarity index 100% rename from crypto/c_blake256.c rename to xmrstak/backend/cpu/crypto/c_blake256.c diff --git a/crypto/c_blake256.h b/xmrstak/backend/cpu/crypto/c_blake256.h similarity index 100% rename from crypto/c_blake256.h rename to xmrstak/backend/cpu/crypto/c_blake256.h diff --git a/crypto/c_groestl.c b/xmrstak/backend/cpu/crypto/c_groestl.c similarity index 100% rename from crypto/c_groestl.c rename to xmrstak/backend/cpu/crypto/c_groestl.c diff --git a/crypto/c_groestl.h b/xmrstak/backend/cpu/crypto/c_groestl.h similarity index 100% rename from crypto/c_groestl.h rename to xmrstak/backend/cpu/crypto/c_groestl.h diff --git a/crypto/c_jh.c b/xmrstak/backend/cpu/crypto/c_jh.c similarity index 100% rename from crypto/c_jh.c rename to xmrstak/backend/cpu/crypto/c_jh.c diff --git a/crypto/c_jh.h b/xmrstak/backend/cpu/crypto/c_jh.h similarity index 100% rename from crypto/c_jh.h rename to xmrstak/backend/cpu/crypto/c_jh.h diff --git a/crypto/c_keccak.c b/xmrstak/backend/cpu/crypto/c_keccak.c similarity index 100% rename from crypto/c_keccak.c rename to xmrstak/backend/cpu/crypto/c_keccak.c diff --git a/crypto/c_keccak.h b/xmrstak/backend/cpu/crypto/c_keccak.h similarity index 100% rename from crypto/c_keccak.h rename to xmrstak/backend/cpu/crypto/c_keccak.h diff --git a/crypto/c_skein.c b/xmrstak/backend/cpu/crypto/c_skein.c similarity index 100% rename from crypto/c_skein.c rename to xmrstak/backend/cpu/crypto/c_skein.c diff --git a/crypto/c_skein.h b/xmrstak/backend/cpu/crypto/c_skein.h similarity index 100% rename from crypto/c_skein.h rename to xmrstak/backend/cpu/crypto/c_skein.h diff --git a/crypto/cryptonight.h b/xmrstak/backend/cpu/crypto/cryptonight.h similarity index 100% rename from crypto/cryptonight.h rename to xmrstak/backend/cpu/crypto/cryptonight.h diff --git a/crypto/cryptonight_aesni.h b/xmrstak/backend/cpu/crypto/cryptonight_aesni.h similarity index 100% rename from crypto/cryptonight_aesni.h rename to xmrstak/backend/cpu/crypto/cryptonight_aesni.h diff --git a/crypto/cryptonight_common.cpp b/xmrstak/backend/cpu/crypto/cryptonight_common.cpp similarity index 100% rename from crypto/cryptonight_common.cpp rename to xmrstak/backend/cpu/crypto/cryptonight_common.cpp diff --git a/crypto/groestl_tables.h b/xmrstak/backend/cpu/crypto/groestl_tables.h similarity index 100% rename from crypto/groestl_tables.h rename to xmrstak/backend/cpu/crypto/groestl_tables.h diff --git a/crypto/hash.h b/xmrstak/backend/cpu/crypto/hash.h similarity index 100% rename from crypto/hash.h rename to xmrstak/backend/cpu/crypto/hash.h diff --git a/crypto/int-util.h b/xmrstak/backend/cpu/crypto/int-util.h similarity index 100% rename from crypto/int-util.h rename to xmrstak/backend/cpu/crypto/int-util.h diff --git a/crypto/skein_port.h b/xmrstak/backend/cpu/crypto/skein_port.h similarity index 100% rename from crypto/skein_port.h rename to xmrstak/backend/cpu/crypto/skein_port.h diff --git a/crypto/soft_aes.c b/xmrstak/backend/cpu/crypto/soft_aes.c similarity index 100% rename from crypto/soft_aes.c rename to xmrstak/backend/cpu/crypto/soft_aes.c diff --git a/hwlocMemory.hpp b/xmrstak/backend/cpu/hwlocMemory.hpp similarity index 100% rename from hwlocMemory.hpp rename to xmrstak/backend/cpu/hwlocMemory.hpp diff --git a/backend/cpu/jconf.cpp b/xmrstak/backend/cpu/jconf.cpp similarity index 100% rename from backend/cpu/jconf.cpp rename to xmrstak/backend/cpu/jconf.cpp diff --git a/backend/cpu/jconf.h b/xmrstak/backend/cpu/jconf.hpp similarity index 100% rename from backend/cpu/jconf.h rename to xmrstak/backend/cpu/jconf.hpp diff --git a/backend/cpu/minethd.cpp b/xmrstak/backend/cpu/minethd.cpp similarity index 100% rename from backend/cpu/minethd.cpp rename to xmrstak/backend/cpu/minethd.cpp diff --git a/backend/cpu/minethd.h b/xmrstak/backend/cpu/minethd.hpp similarity index 100% rename from backend/cpu/minethd.h rename to xmrstak/backend/cpu/minethd.hpp diff --git a/backend/GlobalStates.cpp b/xmrstak/backend/globalStates.cpp similarity index 100% rename from backend/GlobalStates.cpp rename to xmrstak/backend/globalStates.cpp diff --git a/backend/GlobalStates.hpp b/xmrstak/backend/globalStates.hpp similarity index 100% rename from backend/GlobalStates.hpp rename to xmrstak/backend/globalStates.hpp diff --git a/backend/IBackend.hpp b/xmrstak/backend/iBackend.hpp similarity index 100% rename from backend/IBackend.hpp rename to xmrstak/backend/iBackend.hpp diff --git a/backend/miner_work.h b/xmrstak/backend/miner_work.hpp similarity index 100% rename from backend/miner_work.h rename to xmrstak/backend/miner_work.hpp diff --git a/backend/nvidia/autoAdjust.hpp b/xmrstak/backend/nvidia/autoAdjust.hpp similarity index 100% rename from backend/nvidia/autoAdjust.hpp rename to xmrstak/backend/nvidia/autoAdjust.hpp diff --git a/backend/nvidia/config.tpl b/xmrstak/backend/nvidia/config.tpl similarity index 100% rename from backend/nvidia/config.tpl rename to xmrstak/backend/nvidia/config.tpl diff --git a/backend/nvidia/jconf.cpp b/xmrstak/backend/nvidia/jconf.cpp similarity index 100% rename from backend/nvidia/jconf.cpp rename to xmrstak/backend/nvidia/jconf.cpp diff --git a/backend/nvidia/jconf.h b/xmrstak/backend/nvidia/jconf.hpp similarity index 100% rename from backend/nvidia/jconf.h rename to xmrstak/backend/nvidia/jconf.hpp diff --git a/backend/nvidia/minethd.cpp b/xmrstak/backend/nvidia/minethd.cpp similarity index 100% rename from backend/nvidia/minethd.cpp rename to xmrstak/backend/nvidia/minethd.cpp diff --git a/backend/nvidia/minethd.h b/xmrstak/backend/nvidia/minethd.hpp similarity index 100% rename from backend/nvidia/minethd.h rename to xmrstak/backend/nvidia/minethd.hpp diff --git a/backend/nvidia/nvcc_code/cryptonight.h b/xmrstak/backend/nvidia/nvcc_code/cryptonight.hpp similarity index 100% rename from backend/nvidia/nvcc_code/cryptonight.h rename to xmrstak/backend/nvidia/nvcc_code/cryptonight.hpp diff --git a/backend/nvidia/nvcc_code/cuda_aes.hpp b/xmrstak/backend/nvidia/nvcc_code/cuda_aes.hpp similarity index 100% rename from backend/nvidia/nvcc_code/cuda_aes.hpp rename to xmrstak/backend/nvidia/nvcc_code/cuda_aes.hpp diff --git a/backend/nvidia/nvcc_code/cuda_blake.hpp b/xmrstak/backend/nvidia/nvcc_code/cuda_blake.hpp similarity index 100% rename from backend/nvidia/nvcc_code/cuda_blake.hpp rename to xmrstak/backend/nvidia/nvcc_code/cuda_blake.hpp diff --git a/backend/nvidia/nvcc_code/cuda_core.cu b/xmrstak/backend/nvidia/nvcc_code/cuda_core.cu similarity index 100% rename from backend/nvidia/nvcc_code/cuda_core.cu rename to xmrstak/backend/nvidia/nvcc_code/cuda_core.cu diff --git a/backend/nvidia/nvcc_code/cuda_device.hpp b/xmrstak/backend/nvidia/nvcc_code/cuda_device.hpp similarity index 100% rename from backend/nvidia/nvcc_code/cuda_device.hpp rename to xmrstak/backend/nvidia/nvcc_code/cuda_device.hpp diff --git a/backend/nvidia/nvcc_code/cuda_extra.cu b/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu similarity index 100% rename from backend/nvidia/nvcc_code/cuda_extra.cu rename to xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu diff --git a/backend/nvidia/nvcc_code/cuda_extra.h b/xmrstak/backend/nvidia/nvcc_code/cuda_extra.hpp similarity index 100% rename from backend/nvidia/nvcc_code/cuda_extra.h rename to xmrstak/backend/nvidia/nvcc_code/cuda_extra.hpp diff --git a/backend/nvidia/nvcc_code/cuda_groestl.hpp b/xmrstak/backend/nvidia/nvcc_code/cuda_groestl.hpp similarity index 100% rename from backend/nvidia/nvcc_code/cuda_groestl.hpp rename to xmrstak/backend/nvidia/nvcc_code/cuda_groestl.hpp diff --git a/backend/nvidia/nvcc_code/cuda_jh.hpp b/xmrstak/backend/nvidia/nvcc_code/cuda_jh.hpp similarity index 100% rename from backend/nvidia/nvcc_code/cuda_jh.hpp rename to xmrstak/backend/nvidia/nvcc_code/cuda_jh.hpp diff --git a/backend/nvidia/nvcc_code/cuda_keccak.hpp b/xmrstak/backend/nvidia/nvcc_code/cuda_keccak.hpp similarity index 100% rename from backend/nvidia/nvcc_code/cuda_keccak.hpp rename to xmrstak/backend/nvidia/nvcc_code/cuda_keccak.hpp diff --git a/backend/nvidia/nvcc_code/cuda_skein.hpp b/xmrstak/backend/nvidia/nvcc_code/cuda_skein.hpp similarity index 100% rename from backend/nvidia/nvcc_code/cuda_skein.hpp rename to xmrstak/backend/nvidia/nvcc_code/cuda_skein.hpp diff --git a/backend/Plugin.hpp b/xmrstak/backend/plugin.hpp similarity index 100% rename from backend/Plugin.hpp rename to xmrstak/backend/plugin.hpp diff --git a/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp similarity index 100% rename from cli/cli-miner.cpp rename to xmrstak/cli/cli-miner.cpp diff --git a/config.tpl b/xmrstak/config.tpl similarity index 100% rename from config.tpl rename to xmrstak/config.tpl diff --git a/donate-level.h b/xmrstak/donate-level.hpp similarity index 100% rename from donate-level.h rename to xmrstak/donate-level.hpp diff --git a/httpd.cpp b/xmrstak/http/httpd.cpp similarity index 100% rename from httpd.cpp rename to xmrstak/http/httpd.cpp diff --git a/httpd.h b/xmrstak/http/httpd.hpp similarity index 100% rename from httpd.h rename to xmrstak/http/httpd.hpp diff --git a/webdesign.cpp b/xmrstak/http/webdesign.cpp similarity index 100% rename from webdesign.cpp rename to xmrstak/http/webdesign.cpp diff --git a/webdesign.h b/xmrstak/http/webdesign.hpp similarity index 100% rename from webdesign.h rename to xmrstak/http/webdesign.hpp diff --git a/jconf.cpp b/xmrstak/jconf.cpp similarity index 100% rename from jconf.cpp rename to xmrstak/jconf.cpp diff --git a/jconf.h b/xmrstak/jconf.hpp similarity index 100% rename from jconf.h rename to xmrstak/jconf.hpp diff --git a/ConfigEditor.hpp b/xmrstak/misc/configEditor.hpp similarity index 100% rename from ConfigEditor.hpp rename to xmrstak/misc/configEditor.hpp diff --git a/console.cpp b/xmrstak/misc/console.cpp similarity index 100% rename from console.cpp rename to xmrstak/misc/console.cpp diff --git a/console.h b/xmrstak/misc/console.hpp similarity index 100% rename from console.h rename to xmrstak/misc/console.hpp diff --git a/Environment.hpp b/xmrstak/misc/environment.hpp similarity index 100% rename from Environment.hpp rename to xmrstak/misc/environment.hpp diff --git a/executor.cpp b/xmrstak/misc/executor.cpp similarity index 100% rename from executor.cpp rename to xmrstak/misc/executor.cpp diff --git a/executor.h b/xmrstak/misc/executor.hpp similarity index 100% rename from executor.h rename to xmrstak/misc/executor.hpp diff --git a/jext.h b/xmrstak/misc/jext.hpp similarity index 100% rename from jext.h rename to xmrstak/misc/jext.hpp diff --git a/telemetry.cpp b/xmrstak/misc/telemetry.cpp similarity index 100% rename from telemetry.cpp rename to xmrstak/misc/telemetry.cpp diff --git a/telemetry.h b/xmrstak/misc/telemetry.hpp similarity index 100% rename from telemetry.h rename to xmrstak/misc/telemetry.hpp diff --git a/thdq.hpp b/xmrstak/misc/thdq.hpp similarity index 100% rename from thdq.hpp rename to xmrstak/misc/thdq.hpp diff --git a/jpsock.cpp b/xmrstak/net/jpsock.cpp similarity index 100% rename from jpsock.cpp rename to xmrstak/net/jpsock.cpp diff --git a/jpsock.h b/xmrstak/net/jpsock.hpp similarity index 100% rename from jpsock.h rename to xmrstak/net/jpsock.hpp diff --git a/msgstruct.h b/xmrstak/net/msgstruct.hpp similarity index 100% rename from msgstruct.h rename to xmrstak/net/msgstruct.hpp diff --git a/socket.cpp b/xmrstak/net/socket.cpp similarity index 100% rename from socket.cpp rename to xmrstak/net/socket.cpp diff --git a/socket.h b/xmrstak/net/socket.hpp similarity index 100% rename from socket.h rename to xmrstak/net/socket.hpp diff --git a/socks.h b/xmrstak/net/socks.hpp similarity index 100% rename from socks.h rename to xmrstak/net/socks.hpp diff --git a/Params.hpp b/xmrstak/params.hpp similarity index 100% rename from Params.hpp rename to xmrstak/params.hpp diff --git a/rapidjson/allocators.h b/xmrstak/rapidjson/allocators.h similarity index 100% rename from rapidjson/allocators.h rename to xmrstak/rapidjson/allocators.h diff --git a/rapidjson/document.h b/xmrstak/rapidjson/document.h similarity index 100% rename from rapidjson/document.h rename to xmrstak/rapidjson/document.h diff --git a/rapidjson/encodedstream.h b/xmrstak/rapidjson/encodedstream.h similarity index 100% rename from rapidjson/encodedstream.h rename to xmrstak/rapidjson/encodedstream.h diff --git a/rapidjson/encodings.h b/xmrstak/rapidjson/encodings.h similarity index 100% rename from rapidjson/encodings.h rename to xmrstak/rapidjson/encodings.h diff --git a/rapidjson/error/en.h b/xmrstak/rapidjson/error/en.h similarity index 100% rename from rapidjson/error/en.h rename to xmrstak/rapidjson/error/en.h diff --git a/rapidjson/error/error.h b/xmrstak/rapidjson/error/error.h similarity index 100% rename from rapidjson/error/error.h rename to xmrstak/rapidjson/error/error.h diff --git a/rapidjson/filereadstream.h b/xmrstak/rapidjson/filereadstream.h similarity index 100% rename from rapidjson/filereadstream.h rename to xmrstak/rapidjson/filereadstream.h diff --git a/rapidjson/filewritestream.h b/xmrstak/rapidjson/filewritestream.h similarity index 100% rename from rapidjson/filewritestream.h rename to xmrstak/rapidjson/filewritestream.h diff --git a/rapidjson/fwd.h b/xmrstak/rapidjson/fwd.h similarity index 100% rename from rapidjson/fwd.h rename to xmrstak/rapidjson/fwd.h diff --git a/rapidjson/internal/biginteger.h b/xmrstak/rapidjson/internal/biginteger.h similarity index 100% rename from rapidjson/internal/biginteger.h rename to xmrstak/rapidjson/internal/biginteger.h diff --git a/rapidjson/internal/diyfp.h b/xmrstak/rapidjson/internal/diyfp.h similarity index 100% rename from rapidjson/internal/diyfp.h rename to xmrstak/rapidjson/internal/diyfp.h diff --git a/rapidjson/internal/dtoa.h b/xmrstak/rapidjson/internal/dtoa.h similarity index 100% rename from rapidjson/internal/dtoa.h rename to xmrstak/rapidjson/internal/dtoa.h diff --git a/rapidjson/internal/ieee754.h b/xmrstak/rapidjson/internal/ieee754.h similarity index 100% rename from rapidjson/internal/ieee754.h rename to xmrstak/rapidjson/internal/ieee754.h diff --git a/rapidjson/internal/itoa.h b/xmrstak/rapidjson/internal/itoa.h similarity index 100% rename from rapidjson/internal/itoa.h rename to xmrstak/rapidjson/internal/itoa.h diff --git a/rapidjson/internal/meta.h b/xmrstak/rapidjson/internal/meta.h similarity index 100% rename from rapidjson/internal/meta.h rename to xmrstak/rapidjson/internal/meta.h diff --git a/rapidjson/internal/pow10.h b/xmrstak/rapidjson/internal/pow10.h similarity index 100% rename from rapidjson/internal/pow10.h rename to xmrstak/rapidjson/internal/pow10.h diff --git a/rapidjson/internal/regex.h b/xmrstak/rapidjson/internal/regex.h similarity index 100% rename from rapidjson/internal/regex.h rename to xmrstak/rapidjson/internal/regex.h diff --git a/rapidjson/internal/stack.h b/xmrstak/rapidjson/internal/stack.h similarity index 100% rename from rapidjson/internal/stack.h rename to xmrstak/rapidjson/internal/stack.h diff --git a/rapidjson/internal/strfunc.h b/xmrstak/rapidjson/internal/strfunc.h similarity index 100% rename from rapidjson/internal/strfunc.h rename to xmrstak/rapidjson/internal/strfunc.h diff --git a/rapidjson/internal/strtod.h b/xmrstak/rapidjson/internal/strtod.h similarity index 100% rename from rapidjson/internal/strtod.h rename to xmrstak/rapidjson/internal/strtod.h diff --git a/rapidjson/internal/swap.h b/xmrstak/rapidjson/internal/swap.h similarity index 100% rename from rapidjson/internal/swap.h rename to xmrstak/rapidjson/internal/swap.h diff --git a/rapidjson/istreamwrapper.h b/xmrstak/rapidjson/istreamwrapper.h similarity index 100% rename from rapidjson/istreamwrapper.h rename to xmrstak/rapidjson/istreamwrapper.h diff --git a/rapidjson/memorybuffer.h b/xmrstak/rapidjson/memorybuffer.h similarity index 100% rename from rapidjson/memorybuffer.h rename to xmrstak/rapidjson/memorybuffer.h diff --git a/rapidjson/memorystream.h b/xmrstak/rapidjson/memorystream.h similarity index 100% rename from rapidjson/memorystream.h rename to xmrstak/rapidjson/memorystream.h diff --git a/rapidjson/msinttypes/inttypes.h b/xmrstak/rapidjson/msinttypes/inttypes.h similarity index 100% rename from rapidjson/msinttypes/inttypes.h rename to xmrstak/rapidjson/msinttypes/inttypes.h diff --git a/rapidjson/msinttypes/stdint.h b/xmrstak/rapidjson/msinttypes/stdint.h similarity index 100% rename from rapidjson/msinttypes/stdint.h rename to xmrstak/rapidjson/msinttypes/stdint.h diff --git a/rapidjson/ostreamwrapper.h b/xmrstak/rapidjson/ostreamwrapper.h similarity index 100% rename from rapidjson/ostreamwrapper.h rename to xmrstak/rapidjson/ostreamwrapper.h diff --git a/rapidjson/pointer.h b/xmrstak/rapidjson/pointer.h similarity index 100% rename from rapidjson/pointer.h rename to xmrstak/rapidjson/pointer.h diff --git a/rapidjson/prettywriter.h b/xmrstak/rapidjson/prettywriter.h similarity index 100% rename from rapidjson/prettywriter.h rename to xmrstak/rapidjson/prettywriter.h diff --git a/rapidjson/rapidjson.h b/xmrstak/rapidjson/rapidjson.h similarity index 100% rename from rapidjson/rapidjson.h rename to xmrstak/rapidjson/rapidjson.h diff --git a/rapidjson/reader.h b/xmrstak/rapidjson/reader.h similarity index 100% rename from rapidjson/reader.h rename to xmrstak/rapidjson/reader.h diff --git a/rapidjson/schema.h b/xmrstak/rapidjson/schema.h similarity index 100% rename from rapidjson/schema.h rename to xmrstak/rapidjson/schema.h diff --git a/rapidjson/stream.h b/xmrstak/rapidjson/stream.h similarity index 100% rename from rapidjson/stream.h rename to xmrstak/rapidjson/stream.h diff --git a/rapidjson/stringbuffer.h b/xmrstak/rapidjson/stringbuffer.h similarity index 100% rename from rapidjson/stringbuffer.h rename to xmrstak/rapidjson/stringbuffer.h diff --git a/rapidjson/writer.h b/xmrstak/rapidjson/writer.h similarity index 100% rename from rapidjson/writer.h rename to xmrstak/rapidjson/writer.h diff --git a/version.h b/xmrstak/version.hpp similarity index 100% rename from version.h rename to xmrstak/version.hpp From 4526840bb6347eaed7d80a807357f969f9c68a40 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Fri, 29 Sep 2017 20:48:33 +0200 Subject: [PATCH 25/42] update xmake file --- CMakeLists.txt | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c97ca3..8eff475 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -293,6 +293,8 @@ endif() # Compile & Link ################################################################################ +include_directories(BEFORE .) + if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") # remove warnings that f_open() is not save and f_open_s should be used add_definitions(-D_CRT_SECURE_NO_DEPRECATE) @@ -313,7 +315,7 @@ if(CMAKE_LINK_STATIC) set(LIBS "-static-libgcc -static-libstdc++ ${LIBS}") endif() -file(GLOB SRCFILES_C "backend/cpu/crypto/*.c") +file(GLOB SRCFILES_C "xmrstak/backend/cpu/crypto/*.c") add_library(xmr-stak-c STATIC @@ -321,13 +323,13 @@ add_library(xmr-stak-c ) file(GLOB BACKEND_CPP - "*.cpp" - "backend/cpu/*.cpp" - "backend/*.cpp" - "backend/cpu/crypto/*.cpp" - "http/*.cpp" - "misc/*.cpp" - "net/*.cpp") + "xmrstak/*.cpp" + "xmrstak/backend/cpu/*.cpp" + "xmrstak/backend/*.cpp" + "xmrstak/backend/cpu/crypto/*.cpp" + "xmrstak/http/*.cpp" + "xmrstak/misc/*.cpp" + "xmrstak/net/*.cpp") add_library(xmr-stak-backend STATIC @@ -337,8 +339,8 @@ target_link_libraries(xmr-stak-backend xmr-stak-c ${CMAKE_DL_LIBS}) if(CUDA_FOUND) file(GLOB CUDASRCFILES - "backend/nvidia/nvcc_code/*.cu" - "backend/nvidia/*.cpp") + "xmrstak/backend/nvidia/nvcc_code/*.cu" + "xmrstak/backend/nvidia/*.cpp") # build device code with nvcc cuda_add_library(xmrstak_cuda_backend @@ -353,8 +355,8 @@ endif() if(OpenCL_FOUND) file(GLOB OPENCLSRCFILES - "backend/amd/amd_gpu/*.cpp" - "backend/amd/*.cpp") + "xmrstak/backend/amd/amd_gpu/*.cpp" + "xmrstak/backend/amd/*.cpp") add_library(xmrstak_opencl_backend SHARED ${OPENCLSRCFILES} @@ -365,7 +367,7 @@ if(OpenCL_FOUND) endif() endif() -file(GLOB SRCFILES_CPP "cli/*.cpp") +file(GLOB SRCFILES_CPP "xmrstak/cli/*.cpp") set_source_files_properties(${SRCFILES_CPP} PROPERTIES LANGUAGE CXX) set_property(TARGET xmr-stak-c PROPERTY C_STANDARD 99) From 8babae3156430f5aa6b804f7c352ffb178097963 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Fri, 29 Sep 2017 21:43:43 +0200 Subject: [PATCH 26/42] cleanup includes --- README.md | 2 +- xmrstak/backend/amd/amd_gpu/gpu.cpp | 4 +- xmrstak/backend/amd/amd_gpu/gpu.hpp | 3 +- xmrstak/backend/amd/autoAdjust.hpp | 11 +++--- xmrstak/backend/amd/jconf.cpp | 16 ++++---- xmrstak/backend/amd/jconf.hpp | 4 +- xmrstak/backend/amd/minethd.cpp | 31 +++++++--------- xmrstak/backend/amd/minethd.hpp | 11 +++--- xmrstak/backend/backendConnector.cpp | 37 +++++++++---------- xmrstak/backend/backendConnector.hpp | 7 +++- xmrstak/backend/cpu/autoAdjust.hpp | 12 +++--- xmrstak/backend/cpu/autoAdjustHwloc.hpp | 12 +++--- xmrstak/backend/cpu/hwlocMemory.hpp | 2 +- xmrstak/backend/cpu/jconf.cpp | 12 +++--- xmrstak/backend/cpu/jconf.hpp | 4 +- xmrstak/backend/cpu/minethd.cpp | 24 ++++++------ xmrstak/backend/cpu/minethd.hpp | 12 +++--- xmrstak/backend/globalStates.cpp | 6 +-- xmrstak/backend/globalStates.hpp | 7 +++- xmrstak/backend/miner_work.hpp | 1 + xmrstak/backend/nvidia/autoAdjust.hpp | 10 ++--- xmrstak/backend/nvidia/jconf.cpp | 8 ++-- xmrstak/backend/nvidia/jconf.hpp | 2 +- xmrstak/backend/nvidia/minethd.cpp | 23 ++++++------ xmrstak/backend/nvidia/minethd.hpp | 18 +++++---- xmrstak/backend/nvidia/nvcc_code/cuda_core.cu | 4 +- .../backend/nvidia/nvcc_code/cuda_extra.cu | 4 +- xmrstak/backend/plugin.hpp | 22 ++++++----- xmrstak/cli/cli-miner.cpp | 24 ++++++------ xmrstak/http/httpd.cpp | 16 ++++---- xmrstak/http/httpd.hpp | 2 + xmrstak/jconf.cpp | 13 +++---- xmrstak/jconf.hpp | 7 +++- xmrstak/misc/console.cpp | 3 +- xmrstak/misc/console.hpp | 5 ++- xmrstak/misc/executor.cpp | 25 +++++++------ xmrstak/misc/executor.hpp | 12 +++--- xmrstak/misc/jext.hpp | 3 ++ xmrstak/misc/telemetry.cpp | 4 +- xmrstak/misc/telemetry.hpp | 1 + xmrstak/net/jpsock.cpp | 16 ++++---- xmrstak/net/jpsock.hpp | 4 +- xmrstak/net/msgstruct.hpp | 1 + xmrstak/net/socket.cpp | 10 ++--- xmrstak/net/socket.hpp | 4 +- xmrstak/net/socks.hpp | 2 + xmrstak/params.hpp | 4 +- 47 files changed, 250 insertions(+), 215 deletions(-) diff --git a/README.md b/README.md index 690b1cd..d127bb6 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Performance is nearly identical to the closed source paid miners. Here are some * **Dual E5640** - 365 H/s (same as above) ## Default dev donation -By default the miner will donate 2% of the hashpower (2 minute in 100 minutes) to my pool. If you want to change that, edit **donate-level.h** before you build the binaries. +By default the miner will donate 2% of the hashpower (2 minute in 100 minutes) to my pool. If you want to change that, edit **xmrstak/donate-level.hpp** before you build the binaries. If you want to donate directly to support further development, here is my wallet diff --git a/xmrstak/backend/amd/amd_gpu/gpu.cpp b/xmrstak/backend/amd/amd_gpu/gpu.cpp index 04e442a..deb0fc7 100644 --- a/xmrstak/backend/amd/amd_gpu/gpu.cpp +++ b/xmrstak/backend/amd/amd_gpu/gpu.cpp @@ -23,7 +23,6 @@ #ifdef _WIN32 #include -const char* sSourcePath = "opencl\\cryptonight.cl"; static inline void port_sleep(size_t sec) { @@ -31,7 +30,6 @@ static inline void port_sleep(size_t sec) } #else #include -const char* sSourcePath = "opencl/cryptonight.cl"; static inline void port_sleep(size_t sec) { @@ -46,7 +44,7 @@ static inline long long unsigned int int_port(size_t i) } #endif -#include "gpu.h" +#include "gpu.hpp" const char* err_to_str(cl_int ret) { diff --git a/xmrstak/backend/amd/amd_gpu/gpu.hpp b/xmrstak/backend/amd/amd_gpu/gpu.hpp index 8a71cfa..5ff7ea1 100644 --- a/xmrstak/backend/amd/amd_gpu/gpu.hpp +++ b/xmrstak/backend/amd/amd_gpu/gpu.hpp @@ -1,5 +1,7 @@ #pragma once +#include "xmrstak/misc/console.hpp" + #if defined(__APPLE__) #include #else @@ -8,7 +10,6 @@ #include #include -#include "../../../console.h" #define ERR_SUCCESS (0) #define ERR_OCL_API (2) diff --git a/xmrstak/backend/amd/autoAdjust.hpp b/xmrstak/backend/amd/autoAdjust.hpp index 442d8f1..84541ae 100644 --- a/xmrstak/backend/amd/autoAdjust.hpp +++ b/xmrstak/backend/amd/autoAdjust.hpp @@ -1,14 +1,13 @@ #pragma once +#include "amd_gpu/gpu.hpp" #include "autoAdjust.hpp" +#include "jconf.hpp" - -#include "jconf.h" -#include "../../console.h" -#include "../../ConfigEditor.hpp" -#include "amd_gpu/gpu.h" -#include "../../Params.hpp" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/misc/configEditor.hpp" +#include "xmrstak/params.hpp" #include #include diff --git a/xmrstak/backend/amd/jconf.cpp b/xmrstak/backend/amd/jconf.cpp index f8a551e..2132ebf 100644 --- a/xmrstak/backend/amd/jconf.cpp +++ b/xmrstak/backend/amd/jconf.cpp @@ -22,11 +22,9 @@ */ -#include "jconf.h" - -#include -#include -#include +#include "jconf.hpp" +#include "xmrstak/misc/jext.hpp" +#include "xmrstak/misc/console.hpp" #ifdef _WIN32 #define strcasecmp _stricmp @@ -35,10 +33,10 @@ #include #endif -#include "../../rapidjson/document.h" -#include "../../rapidjson/error/en.h" -#include "../../jext.h" -#include "../../console.h" +#include +#include +#include + namespace xmrstak { diff --git a/xmrstak/backend/amd/jconf.hpp b/xmrstak/backend/amd/jconf.hpp index 9fef331..db41dff 100644 --- a/xmrstak/backend/amd/jconf.hpp +++ b/xmrstak/backend/amd/jconf.hpp @@ -1,7 +1,9 @@ #pragma once + +#include "xmrstak/params.hpp" + #include #include -#include "../../Params.hpp" namespace xmrstak { diff --git a/xmrstak/backend/amd/minethd.cpp b/xmrstak/backend/amd/minethd.cpp index f2f5ff4..b2f5620 100644 --- a/xmrstak/backend/amd/minethd.cpp +++ b/xmrstak/backend/amd/minethd.cpp @@ -21,28 +21,25 @@ * */ +#include "minethd.hpp" +#include "autoAdjust.hpp" +#include "amd_gpu/gpu.hpp" + +#include "xmrstak/backend/cpu/crypto/cryptonight_aesni.h" +#include "xmrstak/backend/cpu/crypto/cryptonight.h" +#include "xmrstak/misc/configEditor.hpp" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/backend/cpu/minethd.hpp" +#include "xmrstak/jconf.hpp" +#include "xmrstak/misc/executor.hpp" +#include "xmrstak/misc/environment.hpp" +#include "xmrstak/params.hpp" + #include #include #include #include - -#include "../../ConfigEditor.hpp" -#include "autoAdjust.hpp" - #include -#include "../../console.h" -#include "../../crypto/cryptonight_aesni.h" -#include "../cpu/minethd.h" -#include "../../jconf.h" - -#include "../../executor.h" -#include "minethd.h" -#include "../../jconf.h" -#include "../../crypto/cryptonight.h" -#include "../../Environment.hpp" -#include "../../Params.hpp" -#include "amd_gpu/gpu.h" - namespace xmrstak { diff --git a/xmrstak/backend/amd/minethd.hpp b/xmrstak/backend/amd/minethd.hpp index 4fb3b13..7e71082 100644 --- a/xmrstak/backend/amd/minethd.hpp +++ b/xmrstak/backend/amd/minethd.hpp @@ -1,11 +1,12 @@ #pragma once + +#include "amd_gpu/gpu.hpp" +#include "jconf.hpp" +#include "xmrstak/backend/iBackend.hpp" +#include "xmrstak/misc/environment.hpp" + #include #include -#include "./jconf.h" -#include "../IBackend.hpp" -#include "../../Environment.hpp" - -#include "amd_gpu/gpu.h" namespace xmrstak { diff --git a/xmrstak/backend/backendConnector.cpp b/xmrstak/backend/backendConnector.cpp index 1013f79..d07b54d 100644 --- a/xmrstak/backend/backendConnector.cpp +++ b/xmrstak/backend/backendConnector.cpp @@ -21,6 +21,24 @@ * */ +#include "iBackend.hpp" +#include "backendConnector.hpp" +#include "miner_work.hpp" +#include "globalStates.hpp" +#include "plugin.hpp" +#include "xmrstak/misc/environment.hpp" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/params.hpp" + +#include "cpu/minethd.hpp" +#ifndef CONF_NO_CUDA +# include "nvidia/minethd.hpp" +#endif +#ifndef CONF_NO_OPENCL +# include "amd/minethd.hpp" +#endif + +#include #include #include #include @@ -28,29 +46,10 @@ #include #include -#include "IBackend.hpp" -#include "BackendConnector.hpp" - -#include "cpu/minethd.h" -#ifndef CONF_NO_CUDA -# include "nvidia/minethd.h" -#endif -#ifndef CONF_NO_OPENCL -# include "amd/minethd.h" -#endif -#include "miner_work.h" -#include "GlobalStates.hpp" - #include - -#include "Plugin.hpp" -#include "../Environment.hpp" -#include "../console.h" -#include "../Params.hpp" namespace xmrstak { - bool BackendConnector::self_test() { diff --git a/xmrstak/backend/backendConnector.hpp b/xmrstak/backend/backendConnector.hpp index 024d9b1..f573abc 100644 --- a/xmrstak/backend/backendConnector.hpp +++ b/xmrstak/backend/backendConnector.hpp @@ -1,10 +1,13 @@ #pragma once + +#include "iBackend.hpp" +#include "miner_work.hpp" + #include #include #include #include -#include "IBackend.hpp" -#include "miner_work.h" + namespace xmrstak { diff --git a/xmrstak/backend/cpu/autoAdjust.hpp b/xmrstak/backend/cpu/autoAdjust.hpp index 32c8576..f686224 100644 --- a/xmrstak/backend/cpu/autoAdjust.hpp +++ b/xmrstak/backend/cpu/autoAdjust.hpp @@ -1,9 +1,11 @@ #pragma once -#include "jconf.h" -#include "../../console.h" -#include "../../jconf.h" -#include "../../ConfigEditor.hpp" -#include "../../Params.hpp" + +#include "jconf.hpp" + +#include "xmrstak/misc/console.hpp" +#include "xmrstak/jconf.hpp" +#include "xmrstak/misc/configEditor.hpp" +#include "xmrstak/params.hpp" #include #ifdef _WIN32 diff --git a/xmrstak/backend/cpu/autoAdjustHwloc.hpp b/xmrstak/backend/cpu/autoAdjustHwloc.hpp index e1916e0..055a7f5 100644 --- a/xmrstak/backend/cpu/autoAdjustHwloc.hpp +++ b/xmrstak/backend/cpu/autoAdjustHwloc.hpp @@ -1,9 +1,8 @@ #pragma once -#include "../../console.h" -#include -#include -#include "../../Params.hpp" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/misc/configEditor.hpp" +#include "xmrstak/params.hpp" #ifdef _WIN32 #include @@ -12,7 +11,10 @@ #endif // _WIN32 #include -#include "../../ConfigEditor.hpp" + +#include +#include + namespace xmrstak { diff --git a/xmrstak/backend/cpu/hwlocMemory.hpp b/xmrstak/backend/cpu/hwlocMemory.hpp index f471951..719c1bb 100644 --- a/xmrstak/backend/cpu/hwlocMemory.hpp +++ b/xmrstak/backend/cpu/hwlocMemory.hpp @@ -1,6 +1,6 @@ #pragma once -#include "console.h" +#include "xmrstak/misc/console.hpp" #ifndef CONF_NO_HWLOC diff --git a/xmrstak/backend/cpu/jconf.cpp b/xmrstak/backend/cpu/jconf.cpp index 021d607..2ded8c0 100644 --- a/xmrstak/backend/cpu/jconf.cpp +++ b/xmrstak/backend/cpu/jconf.cpp @@ -21,13 +21,14 @@ * */ -#include "jconf.h" -#include "../../console.h" -#include +#include "jconf.hpp" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/misc/jext.hpp" +#include #include #include -#include +#include #ifdef _WIN32 #define strcasecmp _stricmp @@ -36,9 +37,6 @@ #include #endif -#include "../../rapidjson/document.h" -#include "../../rapidjson/error/en.h" -#include "../../jext.h" namespace xmrstak { diff --git a/xmrstak/backend/cpu/jconf.hpp b/xmrstak/backend/cpu/jconf.hpp index 1f92765..03dfcc1 100644 --- a/xmrstak/backend/cpu/jconf.hpp +++ b/xmrstak/backend/cpu/jconf.hpp @@ -1,7 +1,9 @@ #pragma once + +#include "xmrstak/params.hpp" + #include #include -#include "../../Params.hpp" namespace xmrstak { diff --git a/xmrstak/backend/cpu/minethd.cpp b/xmrstak/backend/cpu/minethd.cpp index 3ffdf99..6037161 100644 --- a/xmrstak/backend/cpu/minethd.cpp +++ b/xmrstak/backend/cpu/minethd.cpp @@ -27,19 +27,19 @@ #include #include #include -#include "../../console.h" -#include "../IBackend.hpp" -#include "../GlobalStates.hpp" -#include "../../ConfigEditor.hpp" -#include "../../Params.hpp" -#include "../../jconf.h" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/backend/iBackend.hpp" +#include "xmrstak/backend//globalStates.hpp" +#include "xmrstak/misc/configEditor.hpp" +#include "xmrstak/params.hpp" +#include "xmrstak/jconf.hpp" -#include "../../executor.h" -#include "minethd.h" -#include "./jconf.h" -#include "../../crypto/cryptonight_aesni.h" -#include "../../hwlocMemory.hpp" -#include "../miner_work.h" +#include "xmrstak/misc/executor.hpp" +#include "minethd.hpp" +#include "xmrstak/jconf.hpp" +#include "xmrstak/backend/crypto/cryptonight_aesni.h" +#include "hwlocMemory.hpp" +#include "xmrstak/backend/miner_work.hpp" #ifndef CONF_NO_HWLOC # include "autoAdjustHwloc.hpp" diff --git a/xmrstak/backend/cpu/minethd.hpp b/xmrstak/backend/cpu/minethd.hpp index 40383cf..1dcca86 100644 --- a/xmrstak/backend/cpu/minethd.hpp +++ b/xmrstak/backend/cpu/minethd.hpp @@ -1,13 +1,15 @@ #pragma once + +#include "crypto/cryptonight.h" +#include "xmrstak/backend/miner_work.hpp" +#include "xmrstak/backend/iBackend.hpp" +#include "xmrstak/backend/globalStates.hpp" + +#include #include #include #include #include -#include "../../crypto/cryptonight.h" -#include "../miner_work.h" -#include "../IBackend.hpp" -#include "../GlobalStates.hpp" -#include namespace xmrstak { diff --git a/xmrstak/backend/globalStates.cpp b/xmrstak/backend/globalStates.cpp index 5251da8..ef582c1 100644 --- a/xmrstak/backend/globalStates.cpp +++ b/xmrstak/backend/globalStates.cpp @@ -21,15 +21,15 @@ * */ +#include "miner_work.hpp" +#include "globalStates.hpp" + #include #include #include #include -#include "miner_work.h" -#include "GlobalStates.hpp" - namespace xmrstak { diff --git a/xmrstak/backend/globalStates.hpp b/xmrstak/backend/globalStates.hpp index a9818ba..58248bd 100644 --- a/xmrstak/backend/globalStates.hpp +++ b/xmrstak/backend/globalStates.hpp @@ -1,7 +1,10 @@ #pragma once + +#include "miner_work.hpp" +#include "xmrstak/misc/environment.hpp" + #include -#include "miner_work.h" -#include "../Environment.hpp" + namespace xmrstak { diff --git a/xmrstak/backend/miner_work.hpp b/xmrstak/backend/miner_work.hpp index 8349fda..c471546 100644 --- a/xmrstak/backend/miner_work.hpp +++ b/xmrstak/backend/miner_work.hpp @@ -1,4 +1,5 @@ #pragma once + #include #include #include diff --git a/xmrstak/backend/nvidia/autoAdjust.hpp b/xmrstak/backend/nvidia/autoAdjust.hpp index 84c6dfc..4107510 100644 --- a/xmrstak/backend/nvidia/autoAdjust.hpp +++ b/xmrstak/backend/nvidia/autoAdjust.hpp @@ -3,11 +3,11 @@ #include "autoAdjust.hpp" -#include "nvcc_code/cryptonight.h" -#include "jconf.h" -#include "../../console.h" -#include "../../ConfigEditor.hpp" -#include "../../Params.hpp" +#include "nvcc_code/cryptonight.hpp" +#include "jconf.hpp" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/misc/configEditor.hpp" +#include "xmrstak/params.hpp" #include #include diff --git a/xmrstak/backend/nvidia/jconf.cpp b/xmrstak/backend/nvidia/jconf.cpp index 2184acd..7a94d19 100644 --- a/xmrstak/backend/nvidia/jconf.cpp +++ b/xmrstak/backend/nvidia/jconf.cpp @@ -21,7 +21,9 @@ * */ -#include "jconf.h" +#include "jconf.hpp" +#include "xmrstak/miscjext.hpp" +#include "xmrstak/misc/console.hpp" #include #include @@ -34,10 +36,6 @@ #include #endif -#include "../../rapidjson/document.h" -#include "../../rapidjson/error/en.h" -#include "../../jext.h" -#include "../../console.h" namespace xmrstak { diff --git a/xmrstak/backend/nvidia/jconf.hpp b/xmrstak/backend/nvidia/jconf.hpp index 8959088..2093408 100644 --- a/xmrstak/backend/nvidia/jconf.hpp +++ b/xmrstak/backend/nvidia/jconf.hpp @@ -1,7 +1,7 @@ #pragma once #include #include -#include "../../Params.hpp" +#include "xmrstak/params.hpp" namespace xmrstak { diff --git a/xmrstak/backend/nvidia/minethd.cpp b/xmrstak/backend/nvidia/minethd.cpp index cbee219..7718d34 100644 --- a/xmrstak/backend/nvidia/minethd.cpp +++ b/xmrstak/backend/nvidia/minethd.cpp @@ -21,24 +21,23 @@ * */ +#include "minethd.hpp" +#include "autoAdjust.hpp" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/backend/cpu/crypto/cryptonight_aesni.h" +#include "xmrstak/backend/cpu/crypto/cryptonight.h" +#include "xmrstak/backend/cpu//cpu/minethd.hpp" +#include "xmrstak/params.hpp" +#include "xmrstak/misc/executor.hpp" +#include "xmrstak/jconf.hpp" +#include "xmrstak/misc/environment.hpp" + #include #include #include #include #include #include -#include "../../console.h" -#include "../../crypto/cryptonight_aesni.h" -#include "../cpu/minethd.h" -#include "../../Params.hpp" - -#include "../../executor.h" -#include "minethd.h" -#include "../../jconf.h" -#include "../../crypto/cryptonight.h" -#include "../../Environment.hpp" -#include "autoAdjust.hpp" - #ifndef USE_PRECOMPILED_HEADERS #ifdef WIN32 diff --git a/xmrstak/backend/nvidia/minethd.hpp b/xmrstak/backend/nvidia/minethd.hpp index 9f3993e..ecf189a 100644 --- a/xmrstak/backend/nvidia/minethd.hpp +++ b/xmrstak/backend/nvidia/minethd.hpp @@ -1,14 +1,18 @@ #pragma once + +#include "xmrstak/jconf.hpp" +#include "jconf.hpp" +#include "nvcc_code/cryptonight.h" + +#include "xmrstak/bakcend/cpu/crypto/cryptonight.h" +#include "xmrstak/backend/iBackend.hpp" +#include "xmrstak/misc/environment.hpp" + +#include #include #include #include -#include "nvcc_code/cryptonight.h" -#include "../../crypto/cryptonight.h" -#include "../../jconf.h" -#include "./jconf.h" -#include "../IBackend.hpp" -#include "../../Environment.hpp" -#include + namespace xmrstak { diff --git a/xmrstak/backend/nvidia/nvcc_code/cuda_core.cu b/xmrstak/backend/nvidia/nvcc_code/cuda_core.cu index 7590cf5..0c086e8 100644 --- a/xmrstak/backend/nvidia/nvcc_code/cuda_core.cu +++ b/xmrstak/backend/nvidia/nvcc_code/cuda_core.cu @@ -49,8 +49,8 @@ extern "C" void compat_usleep(uint64_t waitTime) } #endif -#include "cryptonight.h" -#include "cuda_extra.h" +#include "cryptonight.hpp" +#include "cuda_extra.hpp" #include "cuda_aes.hpp" #include "cuda_device.hpp" diff --git a/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu b/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu index 7052bc8..7734473 100644 --- a/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu +++ b/xmrstak/backend/nvidia/nvcc_code/cuda_extra.cu @@ -25,8 +25,8 @@ uint64_t keccakf_rndc[24] ={ typedef unsigned char BitSequence; typedef unsigned long long DataLength; -#include "cryptonight.h" -#include "cuda_extra.h" +#include "cryptonight.hpp" +#include "cuda_extra.hpp" #include "cuda_keccak.hpp" #include "cuda_blake.hpp" #include "cuda_groestl.hpp" diff --git a/xmrstak/backend/plugin.hpp b/xmrstak/backend/plugin.hpp index 9ba9716..38f8e53 100644 --- a/xmrstak/backend/plugin.hpp +++ b/xmrstak/backend/plugin.hpp @@ -1,21 +1,23 @@ #pragma once + +#include "xmrstak/misc/environment.hpp" + #include #include #include #include -#include "IBackend.hpp" +#include "iBackend.hpp" #include -#include "../Environment.hpp" #ifndef USE_PRECOMPILED_HEADERS -#ifdef WIN32 -#include -#include -#else -#include -#include -#endif -#include +# ifdef WIN32 +# include +# include +# else +# include +# include +# endif +# include #endif namespace xmrstak diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index f2c5c1d..2941792 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -21,27 +21,25 @@ * */ -#include "../executor.h" -#include "../backend/miner_work.h" -#include "../backend/GlobalStates.hpp" -#include "../backend/BackendConnector.hpp" -#include "../jconf.h" -#include "../console.h" -#include "../donate-level.h" -#include "../Params.hpp" -#include "../ConfigEditor.hpp" - -#include "../version.h" +#include "xmrstak/misc/executor.hpp" +#include "xmrstak/backend/miner_work.hpp" +#include "xmrstak/backend/globalStates.hpp" +#include "xmrstak/backend/backendConnector.hpp" +#include "xmrstak/jconf.hpp" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/donate-level.hpp" +#include "xmrstak/params.hpp" +#include "xmrstak/misc/configEditor.hpp" +#include "xmrstak/version.hpp" #ifndef CONF_NO_HTTPD -# include "../httpd.h" +# include "xmrstak/http//httpd.hpp" #endif #include #include #include #include - #include #ifndef CONF_NO_TLS diff --git a/xmrstak/http/httpd.cpp b/xmrstak/http/httpd.cpp index 53b73f1..a112bbb 100644 --- a/xmrstak/http/httpd.cpp +++ b/xmrstak/http/httpd.cpp @@ -23,19 +23,19 @@ #ifndef CONF_NO_HTTPD + +#include "httpd.hpp" +#include "webdesign.hpp" +#include "xmrstak/net/msgstruct.hpp" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/misc/executor.hpp" +#include "xmrstak/jconf.hpp" + #include #include #include #include -#include "msgstruct.h" -#include "httpd.h" -#include "console.h" -#include "executor.h" -#include "jconf.h" - -#include "webdesign.h" - #include #ifdef _WIN32 #define strcasecmp _stricmp diff --git a/xmrstak/http/httpd.hpp b/xmrstak/http/httpd.hpp index bc8bcf6..3836968 100644 --- a/xmrstak/http/httpd.hpp +++ b/xmrstak/http/httpd.hpp @@ -1,5 +1,7 @@ #pragma once +#include + struct MHD_Daemon; struct MHD_Connection; diff --git a/xmrstak/jconf.cpp b/xmrstak/jconf.cpp index bfa2626..cb90feb 100644 --- a/xmrstak/jconf.cpp +++ b/xmrstak/jconf.cpp @@ -21,8 +21,12 @@ * */ -#include "jconf.h" -#include "console.h" +#include "jconf.hpp" +#include "params.hpp" + +#include "xmrstak/misc/console.hpp" +#include "xmrstak/misc/jext.hpp" +#include "xmrstak/misc/console.hpp" #include #include @@ -35,11 +39,6 @@ #include #endif -#include "rapidjson/document.h" -#include "rapidjson/error/en.h" -#include "jext.h" -#include "console.h" -#include "Params.hpp" using namespace rapidjson; diff --git a/xmrstak/jconf.hpp b/xmrstak/jconf.hpp index 934d6f8..41c7712 100644 --- a/xmrstak/jconf.hpp +++ b/xmrstak/jconf.hpp @@ -1,8 +1,11 @@ #pragma once + +#include "xmrstak/misc/environment.hpp" +#include "params.hpp" + #include #include -#include "Environment.hpp" -#include "Params.hpp" + class jconf { diff --git a/xmrstak/misc/console.cpp b/xmrstak/misc/console.cpp index 0c73b1d..ba34bb3 100644 --- a/xmrstak/misc/console.cpp +++ b/xmrstak/misc/console.cpp @@ -21,7 +21,8 @@ * */ -#include "console.h" +#include "xmrstak/misc/console.hpp" + #include #include #include diff --git a/xmrstak/misc/console.hpp b/xmrstak/misc/console.hpp index ac2ed3c..c68bba3 100644 --- a/xmrstak/misc/console.hpp +++ b/xmrstak/misc/console.hpp @@ -1,6 +1,9 @@ #pragma once + +#include "xmrstak/misc/environment.hpp" + #include -#include "Environment.hpp" + enum out_colours { K_RED, K_GREEN, K_BLUE, K_YELLOW, K_CYAN, K_MAGENTA, K_WHITE, K_NONE }; diff --git a/xmrstak/misc/executor.cpp b/xmrstak/misc/executor.cpp index 64f3d40..455412e 100644 --- a/xmrstak/misc/executor.cpp +++ b/xmrstak/misc/executor.cpp @@ -21,24 +21,25 @@ * */ +#include "executor.hpp" +#include "xmrstak/net/jpsock.hpp" + +#include "telemetry.hpp" +#include "xmrstak/backend/miner_work.hpp" +#include "xmrstak/backend/globalStates.hpp" +#include "xmrstak/backend/backendConnector.hpp" + +#include "xmrstak/jconf.hpp" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/donate-level.hpp" +#include "xmrstak/http/webdesign.hpp" + #include #include #include #include #include #include -#include "executor.h" -#include "jpsock.h" - -#include "telemetry.h" -#include "backend/miner_work.h" -#include "backend/GlobalStates.hpp" -#include "backend/BackendConnector.hpp" - -#include "jconf.h" -#include "console.h" -#include "donate-level.h" -#include "webdesign.h" #ifdef _WIN32 #define strncasecmp _strnicmp diff --git a/xmrstak/misc/executor.hpp b/xmrstak/misc/executor.hpp index a3a0828..8be5f56 100644 --- a/xmrstak/misc/executor.hpp +++ b/xmrstak/misc/executor.hpp @@ -1,17 +1,19 @@ #pragma once + #include "thdq.hpp" -#include "msgstruct.h" +#include "telemetry.hpp" +#include "xmrstak/backend/iBackend.hpp" +#include "xmrstak/misc/environment.hpp" +#include "xmrstak/net/msgstruct.hpp" + #include #include #include #include -#include "telemetry.h" -#include "backend/IBackend.hpp" -#include "Environment.hpp" + class jpsock; - namespace xmrstak { namespace cpu diff --git a/xmrstak/misc/jext.hpp b/xmrstak/misc/jext.hpp index dce73a0..f4a333c 100644 --- a/xmrstak/misc/jext.hpp +++ b/xmrstak/misc/jext.hpp @@ -1,5 +1,8 @@ #pragma once +#include "xmrstak/rapidjson/document.h" +#include "xmrstak/rapidjson/error/en.h" + using namespace rapidjson; /* This macro brings rapidjson more in line with other libs */ diff --git a/xmrstak/misc/telemetry.cpp b/xmrstak/misc/telemetry.cpp index fafccd5..c5cce23 100644 --- a/xmrstak/misc/telemetry.cpp +++ b/xmrstak/misc/telemetry.cpp @@ -21,10 +21,12 @@ * */ +#include "telemetry.hpp" + #include #include #include -#include "telemetry.h" + namespace xmrstak { diff --git a/xmrstak/misc/telemetry.hpp b/xmrstak/misc/telemetry.hpp index 0538090..b35bbbf 100644 --- a/xmrstak/misc/telemetry.hpp +++ b/xmrstak/misc/telemetry.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace xmrstak { diff --git a/xmrstak/net/jpsock.cpp b/xmrstak/net/jpsock.cpp index d287375..ae20e52 100644 --- a/xmrstak/net/jpsock.cpp +++ b/xmrstak/net/jpsock.cpp @@ -24,15 +24,15 @@ #include #include -#include "jpsock.h" -#include "executor.h" -#include "jconf.h" +#include "jpsock.hpp" +#include "socks.hpp" +#include "socket.hpp" + +#include "xmrstak/misc/executor.hpp" +#include "xmrstak/jconf.hpp" +#include "xmrstak/misc/jext.hpp" +#include "xmrstak/version.hpp" -#include "rapidjson/document.h" -#include "jext.h" -#include "socks.h" -#include "socket.h" -#include "version.h" #define AGENTID_STR XMR_STAK_NAME "/" XMR_STAK_VERSION diff --git a/xmrstak/net/jpsock.hpp b/xmrstak/net/jpsock.hpp index 4baaade..c2194ad 100644 --- a/xmrstak/net/jpsock.hpp +++ b/xmrstak/net/jpsock.hpp @@ -1,11 +1,13 @@ #pragma once + +#include "msgstruct.hpp" + #include #include #include #include #include -#include "msgstruct.h" /* Our pool can have two kinds of errors: - Parsing or connection error diff --git a/xmrstak/net/msgstruct.hpp b/xmrstak/net/msgstruct.hpp index f3a39b2..05d15fe 100644 --- a/xmrstak/net/msgstruct.hpp +++ b/xmrstak/net/msgstruct.hpp @@ -1,4 +1,5 @@ #pragma once + #include #include #include diff --git a/xmrstak/net/socket.cpp b/xmrstak/net/socket.cpp index 52f46b5..b93376e 100644 --- a/xmrstak/net/socket.cpp +++ b/xmrstak/net/socket.cpp @@ -21,11 +21,11 @@ * */ -#include "socket.h" -#include "jpsock.h" -#include "jconf.h" -#include "console.h" -#include "executor.h" +#include "socket.hpp" +#include "jpsock.hpp" +#include "xmrstak/jconf.hpp" +#include "xmrstak/misc/console.hpp" +#include "xmrstak/misc/executor.hpp" #ifndef CONF_NO_TLS #include diff --git a/xmrstak/net/socket.hpp b/xmrstak/net/socket.hpp index 94bbf03..192a32c 100644 --- a/xmrstak/net/socket.hpp +++ b/xmrstak/net/socket.hpp @@ -1,5 +1,7 @@ #pragma once -#include "socks.h" + +#include "socks.hpp" + class jpsock; class base_socket diff --git a/xmrstak/net/socks.hpp b/xmrstak/net/socks.hpp index 82bfa2f..1d25d3a 100644 --- a/xmrstak/net/socks.hpp +++ b/xmrstak/net/socks.hpp @@ -1,4 +1,5 @@ #pragma once + #ifdef _WIN32 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0601 /* Windows 7 */ @@ -7,6 +8,7 @@ #include #include + inline void sock_init() { static bool bWSAInit = false; diff --git a/xmrstak/params.hpp b/xmrstak/params.hpp index 92d0da0..3d6a0ab 100644 --- a/xmrstak/params.hpp +++ b/xmrstak/params.hpp @@ -1,6 +1,8 @@ #pragma once + +#include "xmrstak/misc/environment.hpp" + #include -#include "Environment.hpp" namespace xmrstak { From 855af1cf65de1fd3795de3c9a859fd9242625a84 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Fri, 29 Sep 2017 22:06:09 +0200 Subject: [PATCH 27/42] fix compile --- xmrstak/backend/amd/autoAdjust.hpp | 2 +- xmrstak/backend/amd/minethd.cpp | 28 ++++++++--------- xmrstak/backend/amd/minethd.hpp | 16 +++------- xmrstak/backend/backendConnector.cpp | 18 +++++------ xmrstak/backend/backendConnector.hpp | 2 +- xmrstak/backend/cpu/autoAdjust.hpp | 2 +- xmrstak/backend/cpu/autoAdjustHwloc.hpp | 2 +- xmrstak/backend/cpu/minethd.cpp | 41 +++++++++++++------------ xmrstak/backend/cpu/minethd.hpp | 21 ++----------- xmrstak/backend/globalStates.cpp | 2 +- xmrstak/backend/globalStates.hpp | 14 ++++----- xmrstak/backend/iBackend.hpp | 39 +++++++++++++++++++++-- xmrstak/backend/miner_work.hpp | 21 +------------ xmrstak/backend/nvidia/autoAdjust.hpp | 2 +- xmrstak/backend/nvidia/jconf.cpp | 2 +- xmrstak/backend/nvidia/minethd.cpp | 30 +++++++++--------- xmrstak/backend/nvidia/minethd.hpp | 24 +++------------ xmrstak/backend/plugin.hpp | 12 ++++---- xmrstak/cli/cli-miner.cpp | 8 ++--- xmrstak/jconf.hpp | 2 +- xmrstak/misc/configEditor.hpp | 4 +-- xmrstak/misc/console.hpp | 2 +- xmrstak/misc/environment.hpp | 16 +++++----- xmrstak/misc/executor.cpp | 6 ++-- xmrstak/misc/executor.hpp | 4 +-- xmrstak/params.hpp | 2 +- 26 files changed, 149 insertions(+), 173 deletions(-) diff --git a/xmrstak/backend/amd/autoAdjust.hpp b/xmrstak/backend/amd/autoAdjust.hpp index 84541ae..c936e30 100644 --- a/xmrstak/backend/amd/autoAdjust.hpp +++ b/xmrstak/backend/amd/autoAdjust.hpp @@ -76,7 +76,7 @@ private: #include "./config.tpl" ; - ConfigEditor configTpl{}; + configEditor configTpl{}; configTpl.set( std::string(tpl) ); std::string conf; diff --git a/xmrstak/backend/amd/minethd.cpp b/xmrstak/backend/amd/minethd.cpp index b2f5620..2b7ce77 100644 --- a/xmrstak/backend/amd/minethd.cpp +++ b/xmrstak/backend/amd/minethd.cpp @@ -63,9 +63,9 @@ extern "C" { #ifdef WIN32 __declspec(dllexport) #endif -std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork, Environment& env) +std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork, environment& env) { - Environment::inst() = env; + environment::inst() = env; return amd::minethd::thread_starter(threadOffset, pWork); } } // extern "C" @@ -91,11 +91,11 @@ bool minethd::init_gpus() std::vector minethd::vGpuData; -std::vector* minethd::thread_starter(uint32_t threadOffset, miner_work& pWork) +std::vector* minethd::thread_starter(uint32_t threadOffset, miner_work& pWork) { - std::vector* pvThreads = new std::vector(); + std::vector* pvThreads = new std::vector(); - if(!ConfigEditor::file_exist(Params::inst().configFileAMD)) + if(!configEditor::file_exist(Params::inst().configFileAMD)) { autoAdjust adjust; if(!adjust.printConfig()) @@ -148,19 +148,19 @@ void minethd::switch_work(miner_work& pWork) // faster than threads can consume them. This should never happen in real life. // Pool cant physically send jobs faster than every 250ms or so due to net latency. - while (GlobalStates::inst().iConsumeCnt.load(std::memory_order_seq_cst) < GlobalStates::inst().iThreadCount) + while (globalStates::inst().iConsumeCnt.load(std::memory_order_seq_cst) < globalStates::inst().iThreadCount) std::this_thread::sleep_for(std::chrono::milliseconds(100)); - GlobalStates::inst().oGlobalWork = pWork; - GlobalStates::inst().iConsumeCnt.store(0, std::memory_order_seq_cst); - GlobalStates::inst().iGlobalJobNo++; + globalStates::inst().oGlobalWork = pWork; + globalStates::inst().iConsumeCnt.store(0, std::memory_order_seq_cst); + globalStates::inst().iGlobalJobNo++; } void minethd::consume_work() { - memcpy(&oWork, &GlobalStates::inst().oGlobalWork, sizeof(miner_work)); + memcpy(&oWork, &globalStates::inst().oGlobalWork, sizeof(miner_work)); iJobNo++; - GlobalStates::inst().iConsumeCnt++; + globalStates::inst().iConsumeCnt++; } @@ -172,7 +172,7 @@ void minethd::work_main() cpu_ctx = cpu::minethd::minethd_alloc_ctx(); cn_hash_fun hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/); - GlobalStates::inst().iConsumeCnt++; + globalStates::inst().iConsumeCnt++; while (bQuit == 0) { @@ -182,7 +182,7 @@ void minethd::work_main() either because of network latency, or a socket problem. Since we are raison d'etre of this software it us sensible to just wait until we have something*/ - while (GlobalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while (globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) std::this_thread::sleep_for(std::chrono::milliseconds(100)); consume_work(); @@ -194,7 +194,7 @@ void minethd::work_main() uint32_t target = oWork.iTarget32; XMRSetJob(pGpuCtx, oWork.bWorkBlob, oWork.iWorkSize, target); - while(GlobalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while(globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) { cl_uint results[0x100]; memset(results,0,sizeof(cl_uint)*(0x100)); diff --git a/xmrstak/backend/amd/minethd.hpp b/xmrstak/backend/amd/minethd.hpp index 7e71082..21c2dd9 100644 --- a/xmrstak/backend/amd/minethd.hpp +++ b/xmrstak/backend/amd/minethd.hpp @@ -2,6 +2,8 @@ #include "amd_gpu/gpu.hpp" #include "jconf.hpp" +#include "xmrstak/backend/cpu/crypto/cryptonight.h" +#include "xmrstak/backend/miner_work.hpp" #include "xmrstak/backend/iBackend.hpp" #include "xmrstak/misc/environment.hpp" @@ -13,27 +15,18 @@ namespace xmrstak namespace amd { -class minethd : public IBackend +class minethd : public iBackend { public: static void switch_work(miner_work& pWork); - static std::vector* thread_starter(uint32_t threadOffset, miner_work& pWork); + static std::vector* thread_starter(uint32_t threadOffset, miner_work& pWork); static bool init_gpus(); private: typedef void (*cn_hash_fun)(const void*, size_t, void*, cryptonight_ctx*); minethd(miner_work& pWork, size_t iNo, GpuContext* ctx); - - // We use the top 8 bits of the nonce for thread and resume - // This allows us to resume up to 64 threads 4 times before - // we get nonce collisions - // Bottom 24 bits allow for an hour of work at 4000 H/s - inline uint32_t calc_start_nonce(uint32_t resume) - { - return reverseBits(static_cast(iThreadNo + GlobalStates::inst().iThreadCount * resume)); - } void work_main(); void double_work_main(); @@ -45,7 +38,6 @@ private: miner_work oWork; std::thread oWorkThd; - uint8_t iThreadNo; bool bQuit; bool bNoPrefetch; diff --git a/xmrstak/backend/backendConnector.cpp b/xmrstak/backend/backendConnector.cpp index d07b54d..e0ac85a 100644 --- a/xmrstak/backend/backendConnector.cpp +++ b/xmrstak/backend/backendConnector.cpp @@ -56,19 +56,19 @@ bool BackendConnector::self_test() return true; } -std::vector* BackendConnector::thread_starter(miner_work& pWork) +std::vector* BackendConnector::thread_starter(miner_work& pWork) { - GlobalStates::inst().iGlobalJobNo = 0; - GlobalStates::inst().iConsumeCnt = 0; + globalStates::inst().iGlobalJobNo = 0; + globalStates::inst().iConsumeCnt = 0; - std::vector* pvThreads = new std::vector; + std::vector* pvThreads = new std::vector; #ifndef CONF_NO_CUDA if(Params::inst().useNVIDIA) { - Plugin nvidiaPlugin("NVIDIA", "xmrstak_cuda_backend"); - std::vector* nvidiaThreads = nvidiaPlugin.startBackend(static_cast(pvThreads->size()), pWork, Environment::inst()); + plugin nvidiaplugin("NVIDIA", "xmrstak_cuda_backend"); + std::vector* nvidiaThreads = nvidiaplugin.startBackend(static_cast(pvThreads->size()), pWork, environment::inst()); pvThreads->insert(std::end(*pvThreads), std::begin(*nvidiaThreads), std::end(*nvidiaThreads)); if(nvidiaThreads->size() == 0) printer::inst()->print_msg(L0, "WARNING: backend NVIDIA disabled."); @@ -78,8 +78,8 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) #ifndef CONF_NO_OPENCL if(Params::inst().useAMD) { - Plugin amdPlugin("AMD", "xmrstak_opencl_backend"); - std::vector* amdThreads = amdPlugin.startBackend(static_cast(pvThreads->size()), pWork, Environment::inst()); + plugin amdplugin("AMD", "xmrstak_opencl_backend"); + std::vector* amdThreads = amdplugin.startBackend(static_cast(pvThreads->size()), pWork, environment::inst()); pvThreads->insert(std::end(*pvThreads), std::begin(*amdThreads), std::end(*amdThreads)); if(amdThreads->size() == 0) printer::inst()->print_msg(L0, "WARNING: backend AMD disabled."); @@ -96,7 +96,7 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) } #endif - GlobalStates::inst().iThreadCount = pvThreads->size(); + globalStates::inst().iThreadCount = pvThreads->size(); return pvThreads; } diff --git a/xmrstak/backend/backendConnector.hpp b/xmrstak/backend/backendConnector.hpp index f573abc..da3dc77 100644 --- a/xmrstak/backend/backendConnector.hpp +++ b/xmrstak/backend/backendConnector.hpp @@ -14,7 +14,7 @@ namespace xmrstak struct BackendConnector { - static std::vector* thread_starter(miner_work& pWork); + static std::vector* thread_starter(miner_work& pWork); static bool self_test(); }; diff --git a/xmrstak/backend/cpu/autoAdjust.hpp b/xmrstak/backend/cpu/autoAdjust.hpp index f686224..639c27b 100644 --- a/xmrstak/backend/cpu/autoAdjust.hpp +++ b/xmrstak/backend/cpu/autoAdjust.hpp @@ -39,7 +39,7 @@ public: bool printConfig() { - ConfigEditor configTpl{}; + configEditor configTpl{}; // load the template of the backend config into a char variable const char *tpl = diff --git a/xmrstak/backend/cpu/autoAdjustHwloc.hpp b/xmrstak/backend/cpu/autoAdjustHwloc.hpp index 055a7f5..8431956 100644 --- a/xmrstak/backend/cpu/autoAdjustHwloc.hpp +++ b/xmrstak/backend/cpu/autoAdjustHwloc.hpp @@ -37,7 +37,7 @@ public: hwloc_topology_load(topology); std::string conf; - ConfigEditor configTpl{}; + configEditor configTpl{}; // load the template of the backend config into a char variable const char *tpl = diff --git a/xmrstak/backend/cpu/minethd.cpp b/xmrstak/backend/cpu/minethd.cpp index 6037161..d786bee 100644 --- a/xmrstak/backend/cpu/minethd.cpp +++ b/xmrstak/backend/cpu/minethd.cpp @@ -21,23 +21,19 @@ * */ -#include -#include -#include -#include -#include -#include +#include "crypto/cryptonight_aesni.h" + #include "xmrstak/misc/console.hpp" #include "xmrstak/backend/iBackend.hpp" #include "xmrstak/backend//globalStates.hpp" #include "xmrstak/misc/configEditor.hpp" #include "xmrstak/params.hpp" -#include "xmrstak/jconf.hpp" +#include "jconf.hpp" #include "xmrstak/misc/executor.hpp" #include "minethd.hpp" #include "xmrstak/jconf.hpp" -#include "xmrstak/backend/crypto/cryptonight_aesni.h" + #include "hwlocMemory.hpp" #include "xmrstak/backend/miner_work.hpp" @@ -47,6 +43,13 @@ # include "autoAdjust.hpp" #endif +#include +#include +#include +#include +#include +#include + #ifdef _WIN32 #include @@ -244,11 +247,11 @@ bool minethd::self_test() return bResult; } -std::vector minethd::thread_starter(uint32_t threadOffset, miner_work& pWork) +std::vector minethd::thread_starter(uint32_t threadOffset, miner_work& pWork) { - std::vector pvThreads; + std::vector pvThreads; - if(!ConfigEditor::file_exist(Params::inst().configFileCPU)) + if(!configEditor::file_exist(Params::inst().configFileCPU)) { autoAdjust adjust; if(!adjust.printConfig()) @@ -286,9 +289,9 @@ std::vector minethd::thread_starter(uint32_t threadOffset, miner_work void minethd::consume_work() { - memcpy(&oWork, &GlobalStates::inst().inst().oGlobalWork, sizeof(miner_work)); + memcpy(&oWork, &globalStates::inst().inst().oGlobalWork, sizeof(miner_work)); iJobNo++; - GlobalStates::inst().inst().iConsumeCnt++; + globalStates::inst().inst().iConsumeCnt++; } minethd::cn_hash_fun minethd::func_selector(bool bHaveAes, bool bNoPrefetch) @@ -343,7 +346,7 @@ void minethd::work_main() piHashVal = (uint64_t*)(result.bResult + 24); piNonce = (uint32_t*)(oWork.bWorkBlob + 39); - GlobalStates::inst().inst().iConsumeCnt++; + globalStates::inst().inst().iConsumeCnt++; while (bQuit == 0) { @@ -353,7 +356,7 @@ void minethd::work_main() either because of network latency, or a socket problem. Since we are raison d'etre of this software it us sensible to just wait until we have something*/ - while (GlobalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while (globalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) std::this_thread::sleep_for(std::chrono::milliseconds(100)); consume_work(); @@ -368,7 +371,7 @@ void minethd::work_main() assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); memcpy(result.sJobID, oWork.sJobID, sizeof(job_result::sJobID)); - while(GlobalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while(globalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) { if ((iCount & 0xF) == 0) //Store stats every 16 hashes { @@ -441,7 +444,7 @@ void minethd::double_work_main() piNonce0 = (uint32_t*)(bDoubleWorkBlob + 39); piNonce1 = nullptr; - GlobalStates::inst().inst().iConsumeCnt++; + globalStates::inst().inst().iConsumeCnt++; while (bQuit == 0) { @@ -451,7 +454,7 @@ void minethd::double_work_main() either because of network latency, or a socket problem. Since we are raison d'etre of this software it us sensible to just wait until we have something*/ - while (GlobalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while (globalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) std::this_thread::sleep_for(std::chrono::milliseconds(100)); consume_work(); @@ -468,7 +471,7 @@ void minethd::double_work_main() assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); - while (GlobalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while (globalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) { if ((iCount & 0x7) == 0) //Store stats every 16 hashes { diff --git a/xmrstak/backend/cpu/minethd.hpp b/xmrstak/backend/cpu/minethd.hpp index 1dcca86..a091ee8 100644 --- a/xmrstak/backend/cpu/minethd.hpp +++ b/xmrstak/backend/cpu/minethd.hpp @@ -3,7 +3,6 @@ #include "crypto/cryptonight.h" #include "xmrstak/backend/miner_work.hpp" #include "xmrstak/backend/iBackend.hpp" -#include "xmrstak/backend/globalStates.hpp" #include #include @@ -16,10 +15,10 @@ namespace xmrstak namespace cpu { -class minethd : public IBackend +class minethd : public iBackend { public: - static std::vector thread_starter(uint32_t threadOffset, miner_work& pWork); + static std::vector thread_starter(uint32_t threadOffset, miner_work& pWork); static bool self_test(); typedef void (*cn_hash_fun)(const void*, size_t, void*, cryptonight_ctx*); @@ -36,21 +35,6 @@ private: minethd(miner_work& pWork, size_t iNo, bool double_work, bool no_prefetch, int64_t affinity); - // We use the top 10 bits of the nonce for thread and resume - // This allows us to resume up to 128 threads 4 times before - // we get nonce collisions - // Bottom 22 bits allow for an hour of work at 1000 H/s - inline uint32_t calc_start_nonce(uint32_t resume) - { - return reverseBits(static_cast(iThreadNo + GlobalStates::inst().iThreadCount * resume)); - } - - // Limited version of the nonce calc above - inline uint32_t calc_nicehash_nonce(uint32_t start, uint32_t resume) - { - return start | ( ( reverseBits(static_cast(iThreadNo + GlobalStates::inst().iThreadCount * resume)) >> 4u ) ); - } - void work_main(); void double_work_main(); void consume_work(); @@ -65,7 +49,6 @@ private: std::mutex work_thd_mtx; std::thread oWorkThd; - uint8_t iThreadNo; int64_t affinity; bool bQuit; diff --git a/xmrstak/backend/globalStates.cpp b/xmrstak/backend/globalStates.cpp index ef582c1..9104040 100644 --- a/xmrstak/backend/globalStates.cpp +++ b/xmrstak/backend/globalStates.cpp @@ -34,7 +34,7 @@ namespace xmrstak { -void GlobalStates::switch_work(miner_work& pWork) +void globalStates::switch_work(miner_work& pWork) { // iConsumeCnt is a basic lock-like polling mechanism just in case we happen to push work // faster than threads can consume them. This should never happen in real life. diff --git a/xmrstak/backend/globalStates.hpp b/xmrstak/backend/globalStates.hpp index 58248bd..73ccf74 100644 --- a/xmrstak/backend/globalStates.hpp +++ b/xmrstak/backend/globalStates.hpp @@ -9,15 +9,15 @@ namespace xmrstak { -struct GlobalStates +struct globalStates { - static inline GlobalStates& inst() + static inline globalStates& inst() { - auto& env = Environment::inst(); - if(env.pGlobalStates == nullptr) - env.pGlobalStates = new GlobalStates; - return *env.pGlobalStates; + auto& env = environment::inst(); + if(env.pglobalStates == nullptr) + env.pglobalStates = new globalStates; + return *env.pglobalStates; } void switch_work(miner_work& pWork); @@ -29,7 +29,7 @@ struct GlobalStates private: - GlobalStates() : iThreadCount(0) + globalStates() : iThreadCount(0) { } diff --git a/xmrstak/backend/iBackend.hpp b/xmrstak/backend/iBackend.hpp index 5037028..0be8f0a 100644 --- a/xmrstak/backend/iBackend.hpp +++ b/xmrstak/backend/iBackend.hpp @@ -1,18 +1,51 @@ #pragma once +#include "xmrstak/backend/globalStates.hpp" + #include #include +#include namespace xmrstak { - - struct IBackend + // only allowed for unsigned value \todo add static assert + template + T reverseBits(T value) { + /* init with value (to get LSB) */ + T result = value; + /* extra shift needed at end */ + int s = sizeof(T) * CHAR_BIT - 1; + for (value >>= 1; value; value >>= 1) + { + result <<= 1; + result |= value & 1; + s--; + } + /* shift when values highest bits are zero */ + result <<= s; + return result; + } + + struct iBackend + { + inline uint32_t calc_start_nonce(uint32_t resume) + { + return reverseBits(static_cast(iThreadNo + globalStates::inst().iThreadCount * resume)); + } + + // Limited version of the nonce calc above + inline uint32_t calc_nicehash_nonce(uint32_t start, uint32_t resume) + { + return start | ( calc_start_nonce(resume) >> 8u ); + } + std::atomic iHashCount; std::atomic iTimestamp; + uint32_t iThreadNo; - IBackend() : iHashCount(0), iTimestamp(0) + iBackend() : iHashCount(0), iTimestamp(0) { } }; diff --git a/xmrstak/backend/miner_work.hpp b/xmrstak/backend/miner_work.hpp index c471546..e9f9e07 100644 --- a/xmrstak/backend/miner_work.hpp +++ b/xmrstak/backend/miner_work.hpp @@ -4,31 +4,12 @@ #include #include #include -#include #include #include +#include namespace xmrstak { - // only allowed for unsigned value \todo add static assert - template - T reverseBits(T value) - { - /* init with value (to get LSB) */ - T result = value; - /* extra shift needed at end */ - int s = sizeof(T) * CHAR_BIT - 1; - for (value >>= 1; value; value >>= 1) - { - result <<= 1; - result |= value & 1; - s--; - } - /* shift when values highest bits are zero */ - result <<= s; - return result; - } - struct miner_work { char sJobID[64]; diff --git a/xmrstak/backend/nvidia/autoAdjust.hpp b/xmrstak/backend/nvidia/autoAdjust.hpp index 4107510..2354dec 100644 --- a/xmrstak/backend/nvidia/autoAdjust.hpp +++ b/xmrstak/backend/nvidia/autoAdjust.hpp @@ -83,7 +83,7 @@ private: #include "./config.tpl" ; - ConfigEditor configTpl{}; + configEditor configTpl{}; configTpl.set( std::string(tpl) ); constexpr size_t byte2mib = 1024u * 1024u; diff --git a/xmrstak/backend/nvidia/jconf.cpp b/xmrstak/backend/nvidia/jconf.cpp index 7a94d19..971ff05 100644 --- a/xmrstak/backend/nvidia/jconf.cpp +++ b/xmrstak/backend/nvidia/jconf.cpp @@ -22,7 +22,7 @@ */ #include "jconf.hpp" -#include "xmrstak/miscjext.hpp" +#include "xmrstak/misc/jext.hpp" #include "xmrstak/misc/console.hpp" #include diff --git a/xmrstak/backend/nvidia/minethd.cpp b/xmrstak/backend/nvidia/minethd.cpp index 7718d34..2e3ef01 100644 --- a/xmrstak/backend/nvidia/minethd.cpp +++ b/xmrstak/backend/nvidia/minethd.cpp @@ -26,7 +26,7 @@ #include "xmrstak/misc/console.hpp" #include "xmrstak/backend/cpu/crypto/cryptonight_aesni.h" #include "xmrstak/backend/cpu/crypto/cryptonight.h" -#include "xmrstak/backend/cpu//cpu/minethd.hpp" +#include "xmrstak/backend/cpu/minethd.hpp" #include "xmrstak/params.hpp" #include "xmrstak/misc/executor.hpp" #include "xmrstak/jconf.hpp" @@ -110,18 +110,18 @@ extern "C" #ifdef WIN32 __declspec(dllexport) #endif -std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork, Environment& env) +std::vector* xmrstak_start_backend(uint32_t threadOffset, miner_work& pWork, environment& env) { - Environment::inst() = env; + environment::inst() = env; return nvidia::minethd::thread_starter(threadOffset, pWork); } } // extern "C" -std::vector* minethd::thread_starter(uint32_t threadOffset, miner_work& pWork) +std::vector* minethd::thread_starter(uint32_t threadOffset, miner_work& pWork) { - std::vector* pvThreads = new std::vector(); + std::vector* pvThreads = new std::vector(); - if(!ConfigEditor::file_exist(Params::inst().configFileNVIDIA)) + if(!configEditor::file_exist(Params::inst().configFileNVIDIA)) { autoAdjust adjust; if(!adjust.printConfig()) @@ -174,19 +174,19 @@ void minethd::switch_work(miner_work& pWork) // faster than threads can consume them. This should never happen in real life. // Pool cant physically send jobs faster than every 250ms or so due to net latency. - while (GlobalStates::inst().iConsumeCnt.load(std::memory_order_seq_cst) < GlobalStates::inst().iThreadCount) + while (globalStates::inst().iConsumeCnt.load(std::memory_order_seq_cst) < globalStates::inst().iThreadCount) std::this_thread::sleep_for(std::chrono::milliseconds(100)); - GlobalStates::inst().oGlobalWork = pWork; - GlobalStates::inst().iConsumeCnt.store(0, std::memory_order_seq_cst); - GlobalStates::inst().iGlobalJobNo++; + globalStates::inst().oGlobalWork = pWork; + globalStates::inst().iConsumeCnt.store(0, std::memory_order_seq_cst); + globalStates::inst().iGlobalJobNo++; } void minethd::consume_work() { - memcpy(&oWork, &GlobalStates::inst().oGlobalWork, sizeof(miner_work)); + memcpy(&oWork, &globalStates::inst().oGlobalWork, sizeof(miner_work)); iJobNo++; - GlobalStates::inst().iConsumeCnt++; + globalStates::inst().iConsumeCnt++; } void minethd::work_main() @@ -197,7 +197,7 @@ void minethd::work_main() cpu_ctx = cpu::minethd::minethd_alloc_ctx(); cn_hash_fun hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/); - GlobalStates::inst().iConsumeCnt++; + globalStates::inst().iConsumeCnt++; if(/*cuda_get_deviceinfo(&ctx) != 1 ||*/ cryptonight_extra_cpu_init(&ctx) != 1) { @@ -213,7 +213,7 @@ void minethd::work_main() either because of network latency, or a socket problem. Since we are raison d'etre of this software it us sensible to just wait until we have something*/ - while (GlobalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while (globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) std::this_thread::sleep_for(std::chrono::milliseconds(100)); consume_work(); @@ -225,7 +225,7 @@ void minethd::work_main() assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID)); - while(GlobalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) + while(globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo) { uint32_t foundNonce[10]; diff --git a/xmrstak/backend/nvidia/minethd.hpp b/xmrstak/backend/nvidia/minethd.hpp index ecf189a..657ee6a 100644 --- a/xmrstak/backend/nvidia/minethd.hpp +++ b/xmrstak/backend/nvidia/minethd.hpp @@ -2,9 +2,9 @@ #include "xmrstak/jconf.hpp" #include "jconf.hpp" -#include "nvcc_code/cryptonight.h" +#include "nvcc_code/cryptonight.hpp" -#include "xmrstak/bakcend/cpu/crypto/cryptonight.h" +#include "xmrstak/backend/cpu/crypto/cryptonight.h" #include "xmrstak/backend/iBackend.hpp" #include "xmrstak/misc/environment.hpp" @@ -19,12 +19,12 @@ namespace xmrstak namespace nvidia { -class minethd : public IBackend +class minethd : public iBackend { public: static void switch_work(miner_work& pWork); - static std::vector* thread_starter(uint32_t threadOffset, miner_work& pWork); + static std::vector* thread_starter(uint32_t threadOffset, miner_work& pWork); static bool self_test(); private: @@ -32,21 +32,6 @@ private: minethd(miner_work& pWork, size_t iNo, const jconf::thd_cfg& cfg); - // We use the top 10 bits of the nonce for thread and resume - // This allows us to resume up to 128 threads 4 times before - // we get nonce collisions - // Bottom 22 bits allow for an hour of work at 1000 H/s - inline uint32_t calc_start_nonce(uint32_t resume) - { - return reverseBits(iThreadNo + GlobalStates::inst().iThreadCount * resume); - } - - // Limited version of the nonce calc above - inline uint32_t calc_nicehash_nonce(uint32_t start, uint32_t resume) - { - return start | ( ( reverseBits(iThreadNo + GlobalStates::inst().iThreadCount * resume) >> 4u ) ); - } - void work_main(); void consume_work(); @@ -59,7 +44,6 @@ private: miner_work oWork; std::thread oWorkThd; - uint8_t iThreadNo; nvid_ctx ctx; diff --git a/xmrstak/backend/plugin.hpp b/xmrstak/backend/plugin.hpp index 38f8e53..7a3e6f5 100644 --- a/xmrstak/backend/plugin.hpp +++ b/xmrstak/backend/plugin.hpp @@ -23,10 +23,10 @@ namespace xmrstak { -struct Plugin +struct plugin { - Plugin(const std::string backendName, const std::string libName) : fn_starterBackend(nullptr), m_backendName(backendName) + plugin(const std::string backendName, const std::string libName) : fn_starterBackend(nullptr), m_backendName(backendName) { #ifdef WIN32 libBackend = LoadLibrary(TEXT((libName + ".dll").c_str())); @@ -62,11 +62,11 @@ struct Plugin #endif } - std::vector* startBackend(uint32_t threadOffset, miner_work& pWork, Environment& env) + std::vector* startBackend(uint32_t threadOffset, miner_work& pWork, environment& env) { if(fn_starterBackend == nullptr) { - std::vector* pvThreads = new std::vector(); + std::vector* pvThreads = new std::vector(); std::cerr << "WARNING: " << m_backendName << " Backend disabled"<< std::endl; return pvThreads; } @@ -76,7 +76,7 @@ struct Plugin std::string m_backendName; - typedef std::vector* (*starterBackend_t)(uint32_t threadOffset, miner_work& pWork, Environment& env); + typedef std::vector* (*starterBackend_t)(uint32_t threadOffset, miner_work& pWork, environment& env); starterBackend_t fn_starterBackend; @@ -86,7 +86,7 @@ struct Plugin void *libBackend; #endif -/* \todo add unload to destructor and change usage of Plugin that libs keeped open until the miner endss +/* \todo add unload to destructor and change usage of plugin that libs keeped open until the miner endss #ifdef WIN32 FreeLibrary(libBackend); #else diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index 2941792..085bb80 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -171,13 +171,13 @@ int main(int argc, char *argv[]) } // check if we need a guided start - if(!ConfigEditor::file_exist(Params::inst().configFile)) + if(!configEditor::file_exist(Params::inst().configFile)) { // load the template of the backend config into a char variable const char *tpl = #include "../config.tpl" ; - ConfigEditor configTpl{}; + configEditor configTpl{}; configTpl.set(std::string(tpl)); auto& pool = Params::inst().poolURL; if(pool.empty()) @@ -290,7 +290,7 @@ int main(int argc, char *argv[]) void do_benchmark() { using namespace std::chrono; - std::vector* pvThreads; + std::vector* pvThreads; printer::inst()->print_msg(L0, "Running a 60 second benchmark..."); @@ -303,7 +303,7 @@ void do_benchmark() std::this_thread::sleep_for(std::chrono::seconds(60)); oWork = xmrstak::miner_work(); - xmrstak::GlobalStates::inst().switch_work(oWork); + xmrstak::globalStates::inst().switch_work(oWork); double fTotalHps = 0.0; for (uint32_t i = 0; i < pvThreads->size(); i++) diff --git a/xmrstak/jconf.hpp b/xmrstak/jconf.hpp index 41c7712..a133cb0 100644 --- a/xmrstak/jconf.hpp +++ b/xmrstak/jconf.hpp @@ -12,7 +12,7 @@ class jconf public: static jconf* inst() { - auto& env = xmrstak::Environment::inst(); + auto& env = xmrstak::environment::inst(); if(env.pJconfConfig == nullptr) env.pJconfConfig = new jconf; return env.pJconfConfig; diff --git a/xmrstak/misc/configEditor.hpp b/xmrstak/misc/configEditor.hpp index 80607ff..3960384 100644 --- a/xmrstak/misc/configEditor.hpp +++ b/xmrstak/misc/configEditor.hpp @@ -10,11 +10,11 @@ namespace xmrstak { -struct ConfigEditor +struct configEditor { std::string m_fileContent; - ConfigEditor() + configEditor() { } diff --git a/xmrstak/misc/console.hpp b/xmrstak/misc/console.hpp index c68bba3..4d5be78 100644 --- a/xmrstak/misc/console.hpp +++ b/xmrstak/misc/console.hpp @@ -28,7 +28,7 @@ class printer public: static inline printer* inst() { - auto& env = xmrstak::Environment::inst(); + auto& env = xmrstak::environment::inst(); if(env.pPrinter == nullptr) env.pPrinter = new printer; return env.pPrinter; diff --git a/xmrstak/misc/environment.hpp b/xmrstak/misc/environment.hpp index 15f8cce..af4c12a 100644 --- a/xmrstak/misc/environment.hpp +++ b/xmrstak/misc/environment.hpp @@ -7,22 +7,22 @@ class executor; namespace xmrstak { -class GlobalStates; +class globalStates; class Params; -struct Environment +struct environment { - static Environment& inst() + static environment& inst() { - static Environment env; + static environment env; return env; } - Environment& operator=(const Environment& env) + environment& operator=(const environment& env) { this->pPrinter = env.pPrinter; - this->pGlobalStates = env.pGlobalStates; + this->pglobalStates = env.pglobalStates; this->pJconfConfig = env.pJconfConfig; this->pExecutor = env.pExecutor; this->pParams = env.pParams; @@ -30,13 +30,13 @@ struct Environment } - Environment() : pPrinter(nullptr), pGlobalStates(nullptr) + environment() : pPrinter(nullptr), pglobalStates(nullptr) { } printer* pPrinter; - GlobalStates* pGlobalStates; + globalStates* pglobalStates; jconf* pJconfConfig; executor* pExecutor; Params* pParams; diff --git a/xmrstak/misc/executor.cpp b/xmrstak/misc/executor.cpp index 455412e..ce5fbb2 100644 --- a/xmrstak/misc/executor.cpp +++ b/xmrstak/misc/executor.cpp @@ -121,7 +121,7 @@ void executor::sched_reconnect() rt, int_port(iReconnectAttempts)); auto work = xmrstak::miner_work(); - xmrstak::GlobalStates::inst().switch_work(work); + xmrstak::globalStates::inst().switch_work(work); push_timed_event(ex_event(EV_RECONNECT, usr_pool_id), rt); } @@ -239,7 +239,7 @@ void executor::on_pool_have_job(size_t pool_id, pool_job& oPoolJob) oWork.iTarget32 = oPoolJob.iTarget32; - xmrstak::GlobalStates::inst().switch_work(oWork); + xmrstak::globalStates::inst().switch_work(oWork); if(pool_id == dev_pool_id) return; @@ -361,7 +361,7 @@ void executor::on_switch_pool(size_t pool_id) oWork.iTarget32 = oPoolJob.iTarget32; - xmrstak::GlobalStates::inst().switch_work(oWork); + xmrstak::globalStates::inst().switch_work(oWork); if(dev_pool->is_running()) push_timed_event(ex_event(EV_DEV_POOL_EXIT), 5); diff --git a/xmrstak/misc/executor.hpp b/xmrstak/misc/executor.hpp index 8be5f56..d705c27 100644 --- a/xmrstak/misc/executor.hpp +++ b/xmrstak/misc/executor.hpp @@ -28,7 +28,7 @@ class executor public: static executor* inst() { - auto& env = xmrstak::Environment::inst(); + auto& env = xmrstak::environment::inst(); if(env.pExecutor == nullptr) env.pExecutor = new executor; return env.pExecutor; @@ -67,7 +67,7 @@ private: thdq oEventQ; xmrstak::telemetry* telem; - std::vector* pvThreads; + std::vector* pvThreads; size_t current_pool_id; diff --git a/xmrstak/params.hpp b/xmrstak/params.hpp index 3d6a0ab..2a51ad4 100644 --- a/xmrstak/params.hpp +++ b/xmrstak/params.hpp @@ -12,7 +12,7 @@ struct Params static inline Params& inst() { - auto& env = Environment::inst(); + auto& env = environment::inst(); if(env.pParams == nullptr) env.pParams = new Params; return *env.pParams; From a3c034e46ab933fe07d0c6e829074d79866dd4b5 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Fri, 29 Sep 2017 22:08:17 +0200 Subject: [PATCH 28/42] rename binary to xmr-stak - add pseudo install rule to CMake --- CMakeLists.txt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8eff475..5c60292 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -373,14 +373,14 @@ set_source_files_properties(${SRCFILES_CPP} PROPERTIES LANGUAGE CXX) set_property(TARGET xmr-stak-c PROPERTY C_STANDARD 99) target_link_libraries(xmr-stak-c ${LIBS}) -add_executable(xmr-stak-cpu +add_executable(xmr-stak ${SRCFILES_CPP} ) set(EXECUTABLE_OUTPUT_PATH "bin") set(LIBRARY_OUTPUT_PATH "bin") -target_link_libraries(xmr-stak-cpu ${LIBS} xmr-stak-c xmr-stak-backend) +target_link_libraries(xmr-stak ${LIBS} xmr-stak-c xmr-stak-backend) ################################################################################ # Install @@ -389,7 +389,7 @@ target_link_libraries(xmr-stak-cpu ${LIBS} xmr-stak-c xmr-stak-backend) # do not install the binary if the project and install are equal if( NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "${PROJECT_BINARY_DIR}" ) - install(TARGETS xmr-stak-cpu + install(TARGETS xmr-stak RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") if(CUDA_FOUND) if(WIN32) @@ -410,5 +410,6 @@ if( NOT "${CMAKE_INSTALL_PREFIX}" STREQUAL "${PROJECT_BINARY_DIR}" ) endif() endif() else() - set(WIN_OUTPUT_RELEASE "/Release") + # this rule is used if the install prefix is the build directory + install(CODE "MESSAGE(\"xmr-stak installed to folder 'bin'\")") endif() From d80cc9061d2459130dae6608cb29765055c44906 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Fri, 29 Sep 2017 22:25:56 +0200 Subject: [PATCH 29/42] rename `Params` to `params` --- xmrstak/backend/amd/autoAdjust.hpp | 4 +-- xmrstak/backend/amd/jconf.hpp | 2 +- xmrstak/backend/amd/minethd.cpp | 2 +- xmrstak/backend/backendConnector.cpp | 6 ++-- xmrstak/backend/cpu/autoAdjust.hpp | 4 +-- xmrstak/backend/cpu/autoAdjustHwloc.hpp | 4 +-- xmrstak/backend/cpu/jconf.hpp | 2 +- xmrstak/backend/cpu/minethd.cpp | 2 +- xmrstak/backend/nvidia/autoAdjust.hpp | 4 +-- xmrstak/backend/nvidia/jconf.hpp | 2 +- xmrstak/backend/nvidia/minethd.cpp | 2 +- xmrstak/cli/cli-miner.cpp | 47 +++++++++++++++---------- xmrstak/jconf.cpp | 6 ++-- xmrstak/jconf.hpp | 2 +- xmrstak/misc/environment.hpp | 4 +-- xmrstak/params.hpp | 8 ++--- 16 files changed, 55 insertions(+), 46 deletions(-) diff --git a/xmrstak/backend/amd/autoAdjust.hpp b/xmrstak/backend/amd/autoAdjust.hpp index c936e30..c6f2ed7 100644 --- a/xmrstak/backend/amd/autoAdjust.hpp +++ b/xmrstak/backend/amd/autoAdjust.hpp @@ -102,8 +102,8 @@ private: configTpl.replace("PLATFORMINDEX",std::to_string(platformIndex)); configTpl.replace("NUMGPUS",std::to_string(devVec.size())); configTpl.replace("GPUCONFIG",conf); - configTpl.write(Params::inst().configFileAMD); - printer::inst()->print_msg(L0, "AMD: GPU configuration stored in file '%s'", Params::inst().configFileAMD.c_str()); + configTpl.write(params::inst().configFileAMD); + printer::inst()->print_msg(L0, "AMD: GPU configuration stored in file '%s'", params::inst().configFileAMD.c_str()); } std::vector devVec; diff --git a/xmrstak/backend/amd/jconf.hpp b/xmrstak/backend/amd/jconf.hpp index db41dff..da024a4 100644 --- a/xmrstak/backend/amd/jconf.hpp +++ b/xmrstak/backend/amd/jconf.hpp @@ -19,7 +19,7 @@ public: return oInst; }; - bool parse_config(const char* sFilename = Params::inst().configFileAMD.c_str()); + bool parse_config(const char* sFilename = params::inst().configFileAMD.c_str()); struct thd_cfg { size_t index; diff --git a/xmrstak/backend/amd/minethd.cpp b/xmrstak/backend/amd/minethd.cpp index 2b7ce77..5f36428 100644 --- a/xmrstak/backend/amd/minethd.cpp +++ b/xmrstak/backend/amd/minethd.cpp @@ -95,7 +95,7 @@ std::vector* minethd::thread_starter(uint32_t threadOffset, miner_wor { std::vector* pvThreads = new std::vector(); - if(!configEditor::file_exist(Params::inst().configFileAMD)) + if(!configEditor::file_exist(params::inst().configFileAMD)) { autoAdjust adjust; if(!adjust.printConfig()) diff --git a/xmrstak/backend/backendConnector.cpp b/xmrstak/backend/backendConnector.cpp index e0ac85a..6106267 100644 --- a/xmrstak/backend/backendConnector.cpp +++ b/xmrstak/backend/backendConnector.cpp @@ -65,7 +65,7 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) std::vector* pvThreads = new std::vector; #ifndef CONF_NO_CUDA - if(Params::inst().useNVIDIA) + if(params::inst().useNVIDIA) { plugin nvidiaplugin("NVIDIA", "xmrstak_cuda_backend"); std::vector* nvidiaThreads = nvidiaplugin.startBackend(static_cast(pvThreads->size()), pWork, environment::inst()); @@ -76,7 +76,7 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) #endif #ifndef CONF_NO_OPENCL - if(Params::inst().useAMD) + if(params::inst().useAMD) { plugin amdplugin("AMD", "xmrstak_opencl_backend"); std::vector* amdThreads = amdplugin.startBackend(static_cast(pvThreads->size()), pWork, environment::inst()); @@ -87,7 +87,7 @@ std::vector* BackendConnector::thread_starter(miner_work& pWork) #endif #ifndef CONF_NO_CPU - if(Params::inst().useCPU) + if(params::inst().useCPU) { auto cpuThreads = cpu::minethd::thread_starter(static_cast(pvThreads->size()), pWork); pvThreads->insert(std::end(*pvThreads), std::begin(cpuThreads), std::end(cpuThreads)); diff --git a/xmrstak/backend/cpu/autoAdjust.hpp b/xmrstak/backend/cpu/autoAdjust.hpp index 639c27b..294bc6f 100644 --- a/xmrstak/backend/cpu/autoAdjust.hpp +++ b/xmrstak/backend/cpu/autoAdjust.hpp @@ -100,8 +100,8 @@ public: } configTpl.replace("CPUCONFIG",conf); - configTpl.write(Params::inst().configFileCPU); - printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", Params::inst().configFileCPU.c_str()); + configTpl.write(params::inst().configFileCPU); + printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", params::inst().configFileCPU.c_str()); return true; } diff --git a/xmrstak/backend/cpu/autoAdjustHwloc.hpp b/xmrstak/backend/cpu/autoAdjustHwloc.hpp index 8431956..ad3b863 100644 --- a/xmrstak/backend/cpu/autoAdjustHwloc.hpp +++ b/xmrstak/backend/cpu/autoAdjustHwloc.hpp @@ -77,8 +77,8 @@ public: } configTpl.replace("CPUCONFIG",conf); - configTpl.write(Params::inst().configFileCPU); - printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", Params::inst().configFileCPU.c_str()); + configTpl.write(params::inst().configFileCPU); + printer::inst()->print_msg(L0, "CPU configuration stored in file '%s'", params::inst().configFileCPU.c_str()); /* Destroy topology object. */ hwloc_topology_destroy(topology); diff --git a/xmrstak/backend/cpu/jconf.hpp b/xmrstak/backend/cpu/jconf.hpp index 03dfcc1..3c7da49 100644 --- a/xmrstak/backend/cpu/jconf.hpp +++ b/xmrstak/backend/cpu/jconf.hpp @@ -19,7 +19,7 @@ public: return oInst; }; - bool parse_config(const char* sFilename = Params::inst().configFileCPU.c_str()); + bool parse_config(const char* sFilename = params::inst().configFileCPU.c_str()); struct thd_cfg { bool bDoubleMode; diff --git a/xmrstak/backend/cpu/minethd.cpp b/xmrstak/backend/cpu/minethd.cpp index d786bee..b02540a 100644 --- a/xmrstak/backend/cpu/minethd.cpp +++ b/xmrstak/backend/cpu/minethd.cpp @@ -251,7 +251,7 @@ std::vector minethd::thread_starter(uint32_t threadOffset, miner_work { std::vector pvThreads; - if(!configEditor::file_exist(Params::inst().configFileCPU)) + if(!configEditor::file_exist(params::inst().configFileCPU)) { autoAdjust adjust; if(!adjust.printConfig()) diff --git a/xmrstak/backend/nvidia/autoAdjust.hpp b/xmrstak/backend/nvidia/autoAdjust.hpp index 2354dec..4f74abf 100644 --- a/xmrstak/backend/nvidia/autoAdjust.hpp +++ b/xmrstak/backend/nvidia/autoAdjust.hpp @@ -102,8 +102,8 @@ private: } configTpl.replace("GPUCONFIG",conf); - configTpl.write(Params::inst().configFileNVIDIA); - printer::inst()->print_msg(L0, "NVIDIA: GPU configuration stored in file '%s'", Params::inst().configFileNVIDIA.c_str()); + configTpl.write(params::inst().configFileNVIDIA); + printer::inst()->print_msg(L0, "NVIDIA: GPU configuration stored in file '%s'", params::inst().configFileNVIDIA.c_str()); } std::vector nvidCtxVec; diff --git a/xmrstak/backend/nvidia/jconf.hpp b/xmrstak/backend/nvidia/jconf.hpp index 2093408..b09a162 100644 --- a/xmrstak/backend/nvidia/jconf.hpp +++ b/xmrstak/backend/nvidia/jconf.hpp @@ -17,7 +17,7 @@ public: return oInst; }; - bool parse_config(const char* sFilename = Params::inst().configFileNVIDIA.c_str()); + bool parse_config(const char* sFilename = params::inst().configFileNVIDIA.c_str()); struct thd_cfg { uint32_t id; diff --git a/xmrstak/backend/nvidia/minethd.cpp b/xmrstak/backend/nvidia/minethd.cpp index 2e3ef01..b4080fe 100644 --- a/xmrstak/backend/nvidia/minethd.cpp +++ b/xmrstak/backend/nvidia/minethd.cpp @@ -121,7 +121,7 @@ std::vector* minethd::thread_starter(uint32_t threadOffset, miner_wor { std::vector* pvThreads = new std::vector(); - if(!configEditor::file_exist(Params::inst().configFileNVIDIA)) + if(!configEditor::file_exist(params::inst().configFileNVIDIA)) { autoAdjust adjust; if(!adjust.printConfig()) diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index 085bb80..7e0fc9b 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #ifndef CONF_NO_TLS #include @@ -54,6 +55,14 @@ void do_benchmark(); +void help() +{ + using namespace std; + using namespace xmrstak; + + cout<<"Usage: "<print_msg(L0, "Usage: %s [--help|-h] [--benchmark] [-c CONFIGFILE] [CONFIG FILE]", argv[0]); + help(); win_exit(); return 0; } else if(opName.compare("--noCPU") == 0) { - Params::inst().useCPU = false; + params::inst().useCPU = false; } else if(opName.compare("--noAMD") == 0) { - Params::inst().useAMD = false; + params::inst().useAMD = false; } else if(opName.compare("--noAMD") == 0) { - Params::inst().useNVIDIA = false; + params::inst().useNVIDIA = false; } else if(opName.compare("--cpu") == 0) { @@ -109,7 +118,7 @@ int main(int argc, char *argv[]) win_exit(); return 1; } - Params::inst().configFileCPU = argv[i]; + params::inst().configFileCPU = argv[i]; } else if(opName.compare("--amd") == 0) { @@ -120,7 +129,7 @@ int main(int argc, char *argv[]) win_exit(); return 1; } - Params::inst().configFileAMD = argv[i]; + params::inst().configFileAMD = argv[i]; } else if(opName.compare("--nvidia") == 0) { @@ -131,7 +140,7 @@ int main(int argc, char *argv[]) win_exit(); return 1; } - Params::inst().configFileNVIDIA = argv[i]; + params::inst().configFileNVIDIA = argv[i]; } else if(opName.compare("-o") == 0 || opName.compare("--url") == 0) { @@ -142,7 +151,7 @@ int main(int argc, char *argv[]) win_exit(); return 1; } - Params::inst().poolURL = argv[i]; + params::inst().poolURL = argv[i]; } else if(opName.compare("-u") == 0 || opName.compare("--user") == 0) { @@ -153,7 +162,7 @@ int main(int argc, char *argv[]) win_exit(); return 1; } - Params::inst().poolUsername = argv[i]; + params::inst().poolUsername = argv[i]; } else if(opName.compare("-p") == 0 || opName.compare("--pass") == 0) { @@ -164,14 +173,14 @@ int main(int argc, char *argv[]) win_exit(); return 1; } - Params::inst().poolPasswd = argv[i]; + params::inst().poolPasswd = argv[i]; } else - Params::inst().configFile = argv[i]; + params::inst().configFile = argv[i]; } // check if we need a guided start - if(!configEditor::file_exist(Params::inst().configFile)) + if(!configEditor::file_exist(params::inst().configFile)) { // load the template of the backend config into a char variable const char *tpl = @@ -179,19 +188,19 @@ int main(int argc, char *argv[]) ; configEditor configTpl{}; configTpl.set(std::string(tpl)); - auto& pool = Params::inst().poolURL; + auto& pool = params::inst().poolURL; if(pool.empty()) { std::cout<<"Please enter:\n- pool address: e.g. pool.usxmrpool.com:3333"<> pool; } - auto& userName = Params::inst().poolUsername; + auto& userName = params::inst().poolUsername; if(userName.empty()) { std::cout<<"- user name (wallet address or pool login):"<> userName; } - auto& passwd = Params::inst().poolPasswd; + auto& passwd = params::inst().poolPasswd; if(passwd.empty()) { // clear everything from stdin to allow an empty password @@ -202,11 +211,11 @@ int main(int argc, char *argv[]) configTpl.replace("POOLURL", pool); configTpl.replace("POOLUSER", userName); configTpl.replace("POOLPASSWD", passwd); - configTpl.write(Params::inst().configFile); - std::cout<<"Configuration stored in file '"<parse_config(Params::inst().configFile.c_str())) + if(!jconf::inst()->parse_config(params::inst().configFile.c_str())) { win_exit(); return 0; diff --git a/xmrstak/jconf.cpp b/xmrstak/jconf.cpp index cb90feb..c033e66 100644 --- a/xmrstak/jconf.cpp +++ b/xmrstak/jconf.cpp @@ -127,7 +127,7 @@ const char* jconf::GetTlsFingerprint() const char* jconf::GetPoolAddress() { - auto& poolURL = xmrstak::Params::inst().poolURL; + auto& poolURL = xmrstak::params::inst().poolURL; if(poolURL.empty()) poolURL = prv->configValues[sPoolAddr]->GetString(); return poolURL.c_str(); @@ -135,7 +135,7 @@ const char* jconf::GetPoolAddress() const char* jconf::GetPoolPwd() { - auto& poolPasswd = xmrstak::Params::inst().poolPasswd; + auto& poolPasswd = xmrstak::params::inst().poolPasswd; if(poolPasswd.empty()) poolPasswd = prv->configValues[sPoolPwd]->GetString(); return poolPasswd.c_str(); @@ -144,7 +144,7 @@ const char* jconf::GetPoolPwd() const char* jconf::GetWalletAddress() { - auto& poolUsername = xmrstak::Params::inst().poolUsername; + auto& poolUsername = xmrstak::params::inst().poolUsername; if(poolUsername.empty()) poolUsername = prv->configValues[sWalletAddr]->GetString(); return poolUsername.c_str(); diff --git a/xmrstak/jconf.hpp b/xmrstak/jconf.hpp index a133cb0..688ffe1 100644 --- a/xmrstak/jconf.hpp +++ b/xmrstak/jconf.hpp @@ -18,7 +18,7 @@ public: return env.pJconfConfig; }; - bool parse_config(const char* sFilename = xmrstak::Params::inst().configFile.c_str()); + bool parse_config(const char* sFilename = xmrstak::params::inst().configFile.c_str()); struct thd_cfg { bool bDoubleMode; diff --git a/xmrstak/misc/environment.hpp b/xmrstak/misc/environment.hpp index af4c12a..6140d7d 100644 --- a/xmrstak/misc/environment.hpp +++ b/xmrstak/misc/environment.hpp @@ -8,7 +8,7 @@ namespace xmrstak { class globalStates; -class Params; +class params; struct environment { @@ -39,7 +39,7 @@ struct environment globalStates* pglobalStates; jconf* pJconfConfig; executor* pExecutor; - Params* pParams; + params* pParams; }; diff --git a/xmrstak/params.hpp b/xmrstak/params.hpp index 2a51ad4..4f161c8 100644 --- a/xmrstak/params.hpp +++ b/xmrstak/params.hpp @@ -7,14 +7,14 @@ namespace xmrstak { -struct Params +struct params { - static inline Params& inst() + static inline params& inst() { auto& env = environment::inst(); if(env.pParams == nullptr) - env.pParams = new Params; + env.pParams = new params; return *env.pParams; } @@ -32,7 +32,7 @@ struct Params std::string configFileNVIDIA; std::string configFileCPU; - Params() : + params() : useAMD(true), useNVIDIA(true), useCPU(true), From 21463c59c77f463d04a32c9d0a275452452e3f5a Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Fri, 29 Sep 2017 22:37:22 +0200 Subject: [PATCH 30/42] use call prefix to load backends --- xmrstak/backend/plugin.hpp | 3 ++- xmrstak/cli/cli-miner.cpp | 8 +++++--- xmrstak/params.hpp | 3 +++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/xmrstak/backend/plugin.hpp b/xmrstak/backend/plugin.hpp index 7a3e6f5..ff7c9d8 100644 --- a/xmrstak/backend/plugin.hpp +++ b/xmrstak/backend/plugin.hpp @@ -1,6 +1,7 @@ #pragma once #include "xmrstak/misc/environment.hpp" +#include "xmrstak/params.hpp" #include #include @@ -36,7 +37,7 @@ struct plugin return; } #else - libBackend = dlopen((std::string("./lib") + libName + ".so").c_str(), RTLD_LAZY); + libBackend = dlopen((params::inst().executablePrefix + "/lib" + libName + ".so").c_str(), RTLD_LAZY); if(!libBackend) { std::cerr << "WARNING: "<< m_backendName <<" cannot load backend library: " << dlerror() << std::endl; diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index 7e0fc9b..71a1af3 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -60,7 +60,8 @@ void help() using namespace std; using namespace xmrstak; - cout<<"Usage: "< Date: Fri, 29 Sep 2017 23:05:10 +0200 Subject: [PATCH 31/42] add help message --- xmrstak/cli/cli-miner.cpp | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index 71a1af3..4846d08 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -60,8 +60,30 @@ void help() using namespace std; using namespace xmrstak; - cout<<"Usage: "<> userName; } auto& passwd = params::inst().poolPasswd; - if(passwd.empty()) + if(passwd.empty() && (!userSetPasswd)) { // clear everything from stdin to allow an empty password std::cin.clear(); std::cin.ignore(INT_MAX,'\n'); From 75fa2c7ec014c89812ae26e200f7083560bea372 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Fri, 29 Sep 2017 23:46:11 +0200 Subject: [PATCH 32/42] fix clang CUDA compile - add clang compile section - cleanup CMake file - fix missing return value --- CMakeLists.txt | 33 +++++++++++++++++++++++++-------- xmrstak/backend/amd/jconf.cpp | 2 +- xmrstak/cli/cli-miner.cpp | 2 +- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c60292..9a24885 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -315,13 +315,17 @@ if(CMAKE_LINK_STATIC) set(LIBS "-static-libgcc -static-libstdc++ ${LIBS}") endif() +# compile C files file(GLOB SRCFILES_C "xmrstak/backend/cpu/crypto/*.c") add_library(xmr-stak-c STATIC ${SRCFILES_C} ) +set_property(TARGET xmr-stak-c PROPERTY C_STANDARD 99) +target_link_libraries(xmr-stak-c ${LIBS}) +# compile generic backend files file(GLOB BACKEND_CPP "xmrstak/*.cpp" "xmrstak/backend/cpu/*.cpp" @@ -337,22 +341,37 @@ add_library(xmr-stak-backend ) target_link_libraries(xmr-stak-backend xmr-stak-c ${CMAKE_DL_LIBS}) +# compile CUDA backend if(CUDA_FOUND) file(GLOB CUDASRCFILES "xmrstak/backend/nvidia/nvcc_code/*.cu" "xmrstak/backend/nvidia/*.cpp") - # build device code with nvcc - cuda_add_library(xmrstak_cuda_backend - SHARED - ${CUDASRCFILES} - ) + if("${CUDA_COMPILER}" STREQUAL "clang") + # build device code with clang + add_library( + xmrstak_cuda_backend + SHARED + ${CUDASRCFILES} + ) + set_target_properties(xmrstak_cuda_backend PROPERTIES COMPILE_FLAGS ${CLANG_BUILD_FLAGS}) + set_target_properties(xmrstak_cuda_backend PROPERTIES LINKER_LANGUAGE CXX) + set_source_files_properties(${CUDASRCFILES} PROPERTIES LANGUAGE CXX) + else() + # build device code with nvcc + cuda_add_library( + xmrstak_cuda_backend + SHARED + ${CUDASRCFILES} + ) + endif() target_link_libraries(xmrstak_cuda_backend ${CUDA_LIBRARIES}) if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") target_link_libraries(xmrstak_cuda_backend xmr-stak-backend) endif() endif() +# compile AMD backend if(OpenCL_FOUND) file(GLOB OPENCLSRCFILES "xmrstak/backend/amd/amd_gpu/*.cpp" @@ -367,12 +386,10 @@ if(OpenCL_FOUND) endif() endif() +# compile final binary file(GLOB SRCFILES_CPP "xmrstak/cli/*.cpp") set_source_files_properties(${SRCFILES_CPP} PROPERTIES LANGUAGE CXX) -set_property(TARGET xmr-stak-c PROPERTY C_STANDARD 99) -target_link_libraries(xmr-stak-c ${LIBS}) - add_executable(xmr-stak ${SRCFILES_CPP} ) diff --git a/xmrstak/backend/amd/jconf.cpp b/xmrstak/backend/amd/jconf.cpp index 2132ebf..c2bf1fa 100644 --- a/xmrstak/backend/amd/jconf.cpp +++ b/xmrstak/backend/amd/jconf.cpp @@ -252,7 +252,7 @@ bool jconf::parse_config(const char* sFilename) return false; } } - + return true; } } // namespace amd diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index 4846d08..66adaf1 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -130,7 +130,7 @@ int main(int argc, char *argv[]) { params::inst().useAMD = false; } - else if(opName.compare("--noAMD") == 0) + else if(opName.compare("--noNVIDIA") == 0) { params::inst().useNVIDIA = false; } From bb3e8840d795b5e419276d3eda759fa4babe5382 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sat, 30 Sep 2017 18:33:27 +0200 Subject: [PATCH 33/42] fix windows compile - string literal can only be 16kbyte --- xmrstak/backend/amd/amd_gpu/opencl/cryptonight.cl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xmrstak/backend/amd/amd_gpu/opencl/cryptonight.cl b/xmrstak/backend/amd/amd_gpu/opencl/cryptonight.cl index 1bb334a..dd0ebcb 100644 --- a/xmrstak/backend/amd/amd_gpu/opencl/cryptonight.cl +++ b/xmrstak/backend/amd/amd_gpu/opencl/cryptonight.cl @@ -235,7 +235,8 @@ void keccakf1600_1(ulong *st) st[0] ^= keccakf_rndc[round]; } } - +)===" +R"===( void keccakf1600_2(ulong *st) { int i, round; From 2c060c978f331aeaeb2a30a43ac8024945b78af5 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sat, 30 Sep 2017 18:36:54 +0200 Subject: [PATCH 34/42] remove auto conf from json --- xmrstak/backend/nvidia/jconf.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/xmrstak/backend/nvidia/jconf.cpp b/xmrstak/backend/nvidia/jconf.cpp index 971ff05..4208145 100644 --- a/xmrstak/backend/nvidia/jconf.cpp +++ b/xmrstak/backend/nvidia/jconf.cpp @@ -262,8 +262,6 @@ bool jconf::parse_config(const char* sFilename) return false; } } - if(NeedsAutoconf()) - return true; return true; } From 94b7327acc7649db611a315dc75a1ace925cccf4 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sat, 30 Sep 2017 20:37:41 +0200 Subject: [PATCH 35/42] documentation - add more documentation - split documentation into different files --- INSTALL.md | 201 ++++++++++++++++++ README.md | 170 ++------------- doc/FAQ.md | 61 ++++++ doc/compile.md | 81 +++++++ doc/{FREEBSDCOMPILE.md => compile_FreeBSD.md} | 6 +- doc/{LINUXCOMPILE.md => compile_Linux.md} | 6 +- doc/{WINCOMPILE.md => compile_Windows.md} | 3 +- doc/tuning.md | 67 ++++++ doc/usage.md | 54 +++++ 9 files changed, 490 insertions(+), 159 deletions(-) create mode 100644 INSTALL.md create mode 100644 doc/FAQ.md create mode 100644 doc/compile.md rename doc/{FREEBSDCOMPILE.md => compile_FreeBSD.md} (53%) rename doc/{LINUXCOMPILE.md => compile_Linux.md} (94%) rename doc/{WINCOMPILE.md => compile_Windows.md} (95%) create mode 100644 doc/tuning.md create mode 100644 doc/usage.md diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..d127bb6 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,201 @@ +# XMR-Stak-CPU - Monero mining software + +XMR-Stak is a universal Stratum pool miner. This is the CPU-mining version; there is also an [AMD GPU version](https://github.com/fireice-uk/xmr-stak-amd) and an [NVIDA GPU version](https://github.com/fireice-uk/xmr-stak-nvidia) + +## HTML reports + + +## HTML and JSON API report configuraton + +To configure the reports shown above you need to edit the httpd_port variable. Then enable wifi on your phone and navigate to [miner ip address]:[httpd_port] in your phone browser. If you want to use the data in scripts, you can get the JSON version of the data at url [miner ip address]:[httpd_port]/api.json + +## Usage on Windows +1) Edit the config.txt file to enter your pool login and password. +2) Double click the exe file. + +XMR-Stak should compile on any C++11 compliant compiler. +``` +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +sha1sum +d34a0ba0dd7b3b1f900a7e02772e197e974b4a73 libeay32.dll +2ee9966a0fc163da58408d91be36b84fa287c10b ssleay32.dll +e4d8a974e58985214de163df0c1ed0f54250d7ee xmr-stak-cpu.exe +ae0153ff98df82022b2c392d6a17c5f3614f6a50 xmr-stak-cpu-notls.exe + +sha3sum +05003137a87313c81d6c348c9b96411c95d48dc22c35f36c39129747 libeay32.dll +133c065d9ef2c93396382e2ba5d8c3ca8c6a57c6beb0159cb9a4b6c5 ssleay32.dll +7bfc30b06524dc9139a3157e2661d2a6f5720738dde8e490f05cc8e2 xmr-stak-cpu.exe +005fb81fc3711a97b2ce65bad0ca97318d878dc793a8cba99c7d1f6f xmr-stak-cpu-notls.exe + +date +Wed 19 Jul 21:18:58 BST 2017 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iQEcBAEBCAAGBQJZb77XAAoJEPsk95p+1Bw0GU4H/26sBwJzYSeWoLwo0LdmOPk3 +19n+svFYnz6NlxAjs+fvuTK992ilLMy2pa4PHKhot2oyZIgt2rRaFsvRADcHVraG +nsIh4Oq31T9epZI0WxIH5FJlDx30fdGkpMTu9xt6ta2JXsmkDiCoZxmETuljB7Rw +xvnKeHiuTccp73C6Nd7dkuiemsOw0FZA7XXS/Kmwqm7n8BtCztY70R6SVN7QFbCz +C49s0A9cT4UbAUPuu8KvxFozmJHA/wDBYHgkq95Y6n/q116+Sc9BpdF8j+qK4YzZ +uM+B10XY0g7Qv376UoJRYKokpVaBxF08nD+JXLdL+zfQvnEfKgrhTnjaTkWFfEY= +=jpgE +-----END PGP SIGNATURE----- +``` +## Compile guides + +- [Free BSD](FREEBSDCOMPILE.md) +- [Linux](LINUXCOMPILE.md) +- [Windows](WINCOMPILE.md) + + +#### CPU mining performance + +Performance is nearly identical to the closed source paid miners. Here are some numbers: + +* **I7-2600K** - 266 H/s +* **I7-6700** - 276 H/s (with a separate GPU miner) +* **Dual X5650** - 466 H/s (depends on NUMA) +* **Dual E5640** - 365 H/s (same as above) + +## Default dev donation +By default the miner will donate 2% of the hashpower (2 minute in 100 minutes) to my pool. If you want to change that, edit **xmrstak/donate-level.hpp** before you build the binaries. + +If you want to donate directly to support further development, here is my wallet + +fireice-uk: +``` +4581HhZkQHgZrZjKeCfCJxZff9E3xCgHGF25zABZz7oR71TnbbgiS7sK9jveE6Dx6uMs2LwszDuvQJgRZQotdpHt1fTdDhk +``` + +psychocrypt: +``` +43NoJVEXo21hGZ6tDG6Z3g4qimiGdJPE6GRxAmiWwm26gwr62Lqo7zRiCJFSBmbkwTGNuuES9ES5TgaVHceuYc4Y75txCTU +``` + +## Common Issues + +**SeLockMemoryPrivilege failed** + +Please see [config.txt](config.txt) under section **LARGE PAGE SUPPORT** + +For Windows 7 pro, or Windows 8 and above see [this article](https://msdn.microsoft.com/en-gb/library/ms190730.aspx) (make sure to reboot afterwards!). + +For Windows 7 Home : + +1) Download and install [Windows Server 2003 Resource Kit Tools](https://www.microsoft.com/en-us/download/details.aspx?id=17657). Ignore incompatiablity warning during installation. + +2) In cmd or power shell: `ntrights -u %USERNAME% +r SeLockMemoryPrivilege` (where %USERNAME% is the user that will be running the program. This command needs to be run as admin) + +3) Reboot. + +Reference: http://rybkaforum.net/cgi-bin/rybkaforum/topic_show.pl?pid=259791#pid259791 + +*Warning: do not download ntrights.exe from any other site other then the offical Microsoft download page.* + +**VirtualAlloc failed** + +If you set up the user rights properly (see above), and your system has 4-8GB of RAM (50%+ use), there is a significant chance that there simply won't be a large enough chunk of contiguous memory because Windows is fairly bad at mitigating memory fragmentation. + +If that happens, disable all auto-staring applications and run the miner after a reboot. + +**msvcp140.dll and vcruntime140.dll not available errors** + +Download and install this [runtime package](https://go.microsoft.com/fwlink/?LinkId=746572) from Microsoft. *Warning: Do NOT use "missing dll" sites - dll's are exe files with another name, and it is a fairly safe bet that any dll on a shady site like that will be trojaned. Please download offical runtimes from Microsoft above.* + + +**Error: MEMORY ALLOC FAILED: mmap failed** + +From [config.txt](config.txt): + +On Linux you will need to configure large page support `sudo sysctl -w vm.nr_hugepages=128` and increase your +ulimit -l. To do this you need to add following lines to /etc/security/limits.conf: + + * soft memlock 262144 + * hard memlock 262144 + +Save file. You WILL need to log out and log back in for these settings to take affect on your user (no need to reboot, just relogin in your session). + +You can also do it Windows-style and simply run-as-root, but this is NOT recommended for security reasons. + +**Illegal instruction (core dumped)** + +This typically means you are trying to run it on a CPU that does not have [AES](https://en.wikipedia.org/wiki/AES_instruction_set). This only happens on older version of miner, new version gives better error message (but still wont' work since your CPU doesn't support the required instructions). + + +## Advanced Compile Options + +The build system is CMake, if you are not familiar with CMake you can learn more [here](https://cmake.org/runningcmake/). + +### Short Description + +There are two easy ways to set variables for `cmake` to configure *xmr-stak-cpu* +- use the ncurses GUI + - `ccmake .` + - edit your options + - end the GUI by pressing the key `c`(create) and than `g`(generate) +- set Options on the command line + - enable a option: `cmake . -DNAME_OF_THE_OPTION=ON` + - disable a option `cmake . -DNAME_OF_THE_OPTION=OFF` + - set a value `cmake . -DNAME_OF_THE_OPTION=value` + +After the configuration you need to call +`make install` for slow sequential build +or +`make -j install` for faster parallel build +and install. + +### xmr-stak-cpu Compile Options +- `CMAKE_INSTALL_PREFIX` install miner to the home folder + - `cmake . -DCMAKE_INSTALL_PREFIX=$HOME/xmr-stak-cpu` + - you can find the binary and the `config.txt` file after `make install` in `$HOME/xmr-stak-cpu/bin` +- `CMAKE_LINK_STATIC` link libgcc and libstdc++ libraries static (default OFF) + - disable with `cmake . -DCMAKE_LINK_STATIC=ON` +-`CMAKE_BUILD_TYPE` set the build type + - valid options: `Release` or `Debug` + - you should always keep `Release` for your productive miners +- `MICROHTTPD_ENABLE` allow to disable/enable the dependency *microhttpd* + - by default enabled + - there is no *http* interface available if option is disabled: `cmake . -DMICROHTTPD_ENABLE=OFF` +- `OpenSSL_ENABLE` allow to disable/enable the dependency *OpenSSL* + - by default enabled + - it is not possible to connect to a *https* secured pool if option is disabled: `cmake . -DOpenSSL_ENABLE=OFF` +- `HWLOC_ENABLE` allow to disable/enable the dependency *hwloc* + - by default enabled + - the config suggestion is not optimal if option is disabled: `cmake . -DHWLOC_ENABLE=OFF` + +## PGP Key +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2 + +mQENBFhYUmUBCAC6493W5y1MMs38ApRbI11jWUqNdFm686XLkZWGDfYImzL6pEYk +RdWkyt9ziCyA6NUeWFQYniv/z10RxYKq8ulVVJaKb9qPGMU0ESfdxlFNJkU/pf28 +sEVBagGvGw8uFxjQONnBJ7y7iNRWMN7qSRS636wN5ryTHNsmqI4ClXPHkXkDCDUX +QvhXZpG9RRM6jsE3jBGz/LJi3FyZLo/vB60OZBODJ2IA0wSR41RRiOq01OqDueva +9jPoAokNglJfn/CniQ+lqUEXj1vjAZ1D5Mn9fISzA/UPen5Z7Sipaa9aAtsDBOfP +K9iPKOsWa2uTafoyXgiwEVXCCeMMUjCGaoFBABEBAAG0ImZpcmVpY2VfdWsgPGZp +cmVpY2UueG1yQGdtYWlsLmNvbT6JATcEEwEIACEFAlhYUmUCGwMFCwkIBwIGFQgJ +CgsCBBYCAwECHgECF4AACgkQ+yT3mn7UHDTEcQf8CMhqaZ0IOBxeBnsq5HZr2X6z +E5bODp5cPs6ha1tjH3CWpk1AFeykNtXH7kPW9hcDt/e4UQtcHs+lu6YU59X7xLJQ +udOkpWdmooJMXRWS/zeeon4ivT9d69jNnwubh8EJOyw8xm/se6n48BcewfHekW/6 +mVrbhLbF1dnuUGXzRN1WxsUZx3uJd2UvrkJhAtHtX92/qIVhT0+3PXV0bmpHURlK +YKhhm8dPLV9jPX8QVRHQXCOHSMqy/KoWEe6CnT0Isbkq3JtS3K4VBVeTX9gkySRc +IFxrNJdXsI9BxKv4O8yajP8DohpoGLMDKZKSO0yq0BRMgMh0cw6Lk22uyulGALkB +DQRYWFJlAQgAqikfViOmIccCZKVMZfNHjnigKtQqNrbJpYZCOImql4FqbZu9F7TD +9HIXA43SPcwziWlyazSy8Pa9nCpc6PuPPO1wxAaNIc5nt+w/x2EGGTIFGjRoubmP +3i5jZzOFYsvR2W3PgVa3/ujeYYJYo1oeVeuGmmJRejs0rp1mbvBSKw1Cq6C4cI0x +GTY1yXFGLIgdfYNMmiLsTy1Qwq8YStbFKeUYAMMG3128SAIaT3Eet911f5Jx4tC8 +6kWUr6PX1rQ0LQJqyIsLq9U53XybUksRfJC9IEfgvgBxRBHSD8WfqEhHjhW1VsZG +dcYgr7A1PIneWsCEY+5VUnqTlt2HPaKweQARAQABiQEfBBgBCAAJBQJYWFJlAhsM +AAoJEPsk95p+1Bw0Pr8H/0vZ6U2zaih03jOHOvsrYxRfDXSmgudOp1VS45aHIREd +2nrJ+drleeFVyb14UQqO/6iX9GuDX2yBEHdCg2aljeP98AaMU//RiEtebE6CUWsL +HPVXHIkxwBCBe0YkJINHUQqLz/5f6qLsNUp1uTH2++zhdBWvg+gErTYbx8aFMFYH +0GoOtqE5rtlAh5MTvDZm+UcDwKJCxhrLaN3R3dDoyrDNRTgHQQuX5/opJBiUnVNK +d+vugnxzpMIJQP11yCZkz/KxV8zQ2QPMuZdAoh3znd/vGCJcp0rWphn4pqxA4vDp +c4hC0Yg9Dha1OoE5CJCqVL+ic4vAyB1urAwBlsd/wH8= +=B5I+ +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/README.md b/README.md index d127bb6..0ce9e74 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,34 @@ -# XMR-Stak-CPU - Monero mining software +# XMR-Stak - Monero All-in-One Mining Software -XMR-Stak is a universal Stratum pool miner. This is the CPU-mining version; there is also an [AMD GPU version](https://github.com/fireice-uk/xmr-stak-amd) and an [NVIDA GPU version](https://github.com/fireice-uk/xmr-stak-nvidia) +XMR-Stak is a universal Stratum pool miner. This miner supports CPUs, AMD and NVIDIA gpus. ## HTML reports -## HTML and JSON API report configuraton +## Content Overview +* [Features](#features) +* [Download](#download) +* [Usage](doc/usage.md) +* [HowTo Compile](doc/compile.md) +* [FAQ](doc/FAQ.md) +* [Developer Donation](#default-developer-donation) +* [PGP Key](#pgp-key) -To configure the reports shown above you need to edit the httpd_port variable. Then enable wifi on your phone and navigate to [miner ip address]:[httpd_port] in your phone browser. If you want to use the data in scripts, you can get the JSON version of the data at url [miner ip address]:[httpd_port]/api.json +## Features -## Usage on Windows -1) Edit the config.txt file to enter your pool login and password. -2) Double click the exe file. +- support all common backends (CPU/x86, AMD-GPU and NVIDIA-GPU) +- support all common OS (Linux, Windows and MacOS) +- easy to use + - guided start (no need to edit a config file for the first start) + - auto configuration for each backend +- open source software (GPLv3) +- TLS support +- HTML statistics +- JSON API for monitoring -XMR-Stak should compile on any C++11 compliant compiler. -``` ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA256 +## Download -sha1sum -d34a0ba0dd7b3b1f900a7e02772e197e974b4a73 libeay32.dll -2ee9966a0fc163da58408d91be36b84fa287c10b ssleay32.dll -e4d8a974e58985214de163df0c1ed0f54250d7ee xmr-stak-cpu.exe -ae0153ff98df82022b2c392d6a17c5f3614f6a50 xmr-stak-cpu-notls.exe - -sha3sum -05003137a87313c81d6c348c9b96411c95d48dc22c35f36c39129747 libeay32.dll -133c065d9ef2c93396382e2ba5d8c3ca8c6a57c6beb0159cb9a4b6c5 ssleay32.dll -7bfc30b06524dc9139a3157e2661d2a6f5720738dde8e490f05cc8e2 xmr-stak-cpu.exe -005fb81fc3711a97b2ce65bad0ca97318d878dc793a8cba99c7d1f6f xmr-stak-cpu-notls.exe - -date -Wed 19 Jul 21:18:58 BST 2017 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2 - -iQEcBAEBCAAGBQJZb77XAAoJEPsk95p+1Bw0GU4H/26sBwJzYSeWoLwo0LdmOPk3 -19n+svFYnz6NlxAjs+fvuTK992ilLMy2pa4PHKhot2oyZIgt2rRaFsvRADcHVraG -nsIh4Oq31T9epZI0WxIH5FJlDx30fdGkpMTu9xt6ta2JXsmkDiCoZxmETuljB7Rw -xvnKeHiuTccp73C6Nd7dkuiemsOw0FZA7XXS/Kmwqm7n8BtCztY70R6SVN7QFbCz -C49s0A9cT4UbAUPuu8KvxFozmJHA/wDBYHgkq95Y6n/q116+Sc9BpdF8j+qK4YzZ -uM+B10XY0g7Qv376UoJRYKokpVaBxF08nD+JXLdL+zfQvnEfKgrhTnjaTkWFfEY= -=jpgE ------END PGP SIGNATURE----- -``` -## Compile guides - -- [Free BSD](FREEBSDCOMPILE.md) -- [Linux](LINUXCOMPILE.md) -- [Windows](WINCOMPILE.md) - - -#### CPU mining performance - -Performance is nearly identical to the closed source paid miners. Here are some numbers: - -* **I7-2600K** - 266 H/s -* **I7-6700** - 276 H/s (with a separate GPU miner) -* **Dual X5650** - 466 H/s (depends on NUMA) -* **Dual E5640** - 365 H/s (same as above) - -## Default dev donation -By default the miner will donate 2% of the hashpower (2 minute in 100 minutes) to my pool. If you want to change that, edit **xmrstak/donate-level.hpp** before you build the binaries. - -If you want to donate directly to support further development, here is my wallet +You can find the latest releases and precompiled binaries on GitHub under [Releases](https://github.com/xmr-stak/xmr-stak/releases). fireice-uk: ``` @@ -75,97 +40,6 @@ psychocrypt: 43NoJVEXo21hGZ6tDG6Z3g4qimiGdJPE6GRxAmiWwm26gwr62Lqo7zRiCJFSBmbkwTGNuuES9ES5TgaVHceuYc4Y75txCTU ``` -## Common Issues - -**SeLockMemoryPrivilege failed** - -Please see [config.txt](config.txt) under section **LARGE PAGE SUPPORT** - -For Windows 7 pro, or Windows 8 and above see [this article](https://msdn.microsoft.com/en-gb/library/ms190730.aspx) (make sure to reboot afterwards!). - -For Windows 7 Home : - -1) Download and install [Windows Server 2003 Resource Kit Tools](https://www.microsoft.com/en-us/download/details.aspx?id=17657). Ignore incompatiablity warning during installation. - -2) In cmd or power shell: `ntrights -u %USERNAME% +r SeLockMemoryPrivilege` (where %USERNAME% is the user that will be running the program. This command needs to be run as admin) - -3) Reboot. - -Reference: http://rybkaforum.net/cgi-bin/rybkaforum/topic_show.pl?pid=259791#pid259791 - -*Warning: do not download ntrights.exe from any other site other then the offical Microsoft download page.* - -**VirtualAlloc failed** - -If you set up the user rights properly (see above), and your system has 4-8GB of RAM (50%+ use), there is a significant chance that there simply won't be a large enough chunk of contiguous memory because Windows is fairly bad at mitigating memory fragmentation. - -If that happens, disable all auto-staring applications and run the miner after a reboot. - -**msvcp140.dll and vcruntime140.dll not available errors** - -Download and install this [runtime package](https://go.microsoft.com/fwlink/?LinkId=746572) from Microsoft. *Warning: Do NOT use "missing dll" sites - dll's are exe files with another name, and it is a fairly safe bet that any dll on a shady site like that will be trojaned. Please download offical runtimes from Microsoft above.* - - -**Error: MEMORY ALLOC FAILED: mmap failed** - -From [config.txt](config.txt): - -On Linux you will need to configure large page support `sudo sysctl -w vm.nr_hugepages=128` and increase your -ulimit -l. To do this you need to add following lines to /etc/security/limits.conf: - - * soft memlock 262144 - * hard memlock 262144 - -Save file. You WILL need to log out and log back in for these settings to take affect on your user (no need to reboot, just relogin in your session). - -You can also do it Windows-style and simply run-as-root, but this is NOT recommended for security reasons. - -**Illegal instruction (core dumped)** - -This typically means you are trying to run it on a CPU that does not have [AES](https://en.wikipedia.org/wiki/AES_instruction_set). This only happens on older version of miner, new version gives better error message (but still wont' work since your CPU doesn't support the required instructions). - - -## Advanced Compile Options - -The build system is CMake, if you are not familiar with CMake you can learn more [here](https://cmake.org/runningcmake/). - -### Short Description - -There are two easy ways to set variables for `cmake` to configure *xmr-stak-cpu* -- use the ncurses GUI - - `ccmake .` - - edit your options - - end the GUI by pressing the key `c`(create) and than `g`(generate) -- set Options on the command line - - enable a option: `cmake . -DNAME_OF_THE_OPTION=ON` - - disable a option `cmake . -DNAME_OF_THE_OPTION=OFF` - - set a value `cmake . -DNAME_OF_THE_OPTION=value` - -After the configuration you need to call -`make install` for slow sequential build -or -`make -j install` for faster parallel build -and install. - -### xmr-stak-cpu Compile Options -- `CMAKE_INSTALL_PREFIX` install miner to the home folder - - `cmake . -DCMAKE_INSTALL_PREFIX=$HOME/xmr-stak-cpu` - - you can find the binary and the `config.txt` file after `make install` in `$HOME/xmr-stak-cpu/bin` -- `CMAKE_LINK_STATIC` link libgcc and libstdc++ libraries static (default OFF) - - disable with `cmake . -DCMAKE_LINK_STATIC=ON` --`CMAKE_BUILD_TYPE` set the build type - - valid options: `Release` or `Debug` - - you should always keep `Release` for your productive miners -- `MICROHTTPD_ENABLE` allow to disable/enable the dependency *microhttpd* - - by default enabled - - there is no *http* interface available if option is disabled: `cmake . -DMICROHTTPD_ENABLE=OFF` -- `OpenSSL_ENABLE` allow to disable/enable the dependency *OpenSSL* - - by default enabled - - it is not possible to connect to a *https* secured pool if option is disabled: `cmake . -DOpenSSL_ENABLE=OFF` -- `HWLOC_ENABLE` allow to disable/enable the dependency *hwloc* - - by default enabled - - the config suggestion is not optimal if option is disabled: `cmake . -DHWLOC_ENABLE=OFF` - ## PGP Key ``` -----BEGIN PGP PUBLIC KEY BLOCK----- diff --git a/doc/FAQ.md b/doc/FAQ.md new file mode 100644 index 0000000..995a421 --- /dev/null +++ b/doc/FAQ.md @@ -0,0 +1,61 @@ +# FAQ + +## Content Overview +* [SeLockMemoryPrivilege failed](#selockmemoryprivilege-failed) +* [VirtualAlloc failed](#virtualalloc-failed) +* [Error msvcp140.dll and vcruntime140.dll not available](#error-msvcp140dll-and-vcruntime140dll-not-available) +* [Error: MEMORY ALLOC FAILED: mmap failed](#error-memory-alloc-failed-mmap-failed) +* [Illegal instruction (core dumped)](#illegal-instruction) +* [Virus Protection Alert](#virus-protection-alert) + +## SeLockMemoryPrivilege failed + +Please see [config.txt](config.txt) under section **LARGE PAGE SUPPORT** + +For Windows 7 pro, or Windows 8 and above see [this article](https://msdn.microsoft.com/en-gb/library/ms190730.aspx) (make sure to reboot afterwards!). + +For Windows 7 Home : + +1) Download and install [Windows Server 2003 Resource Kit Tools](https://www.microsoft.com/en-us/download/details.aspx?id=17657). Ignore incompatiablity warning during installation. + +2) In cmd or power shell: `ntrights -u %USERNAME% +r SeLockMemoryPrivilege` (where %USERNAME% is the user that will be running the program. This command needs to be run as admin) + +3) Reboot. + +Reference: http://rybkaforum.net/cgi-bin/rybkaforum/topic_show.pl?pid=259791#pid259791 + +*Warning: do not download ntrights.exe from any other site other then the offical Microsoft download page.* + +## VirtualAlloc failed + +If you set up the user rights properly (see above), and your system has 4-8GB of RAM (50%+ use), there is a significant chance that there simply won't be a large enough chunk of contiguous memory because Windows is fairly bad at mitigating memory fragmentation. + +If that happens, disable all auto-staring applications and run the miner after a reboot. + +## Error msvcp140.dll and vcruntime140.dll not available + +Download and install this [runtime package](https://go.microsoft.com/fwlink/?LinkId=746572) from Microsoft. *Warning: Do NOT use "missing dll" sites - dll's are exe files with another name, and it is a fairly safe bet that any dll on a shady site like that will be trojaned. Please download offical runtimes from Microsoft above.* + + +## Error: MEMORY ALLOC FAILED: mmap failed + +On Linux you will need to configure large page support `sudo sysctl -w vm.nr_hugepages=128` and increase your +ulimit -l. To do this you need to add following lines to /etc/security/limits.conf: + + * soft memlock 262144 + * hard memlock 262144 + +Save file. You WILL need to log out and log back in for these settings to take affect on your user (no need to reboot, just relogin in your session). + +You can also do it Windows-style and simply run-as-root, but this is NOT recommended for security reasons. + +## Illegal Instruction + +This typically means you are trying to run it on a CPU that does not have [AES](https://en.wikipedia.org/wiki/AES_instruction_set). This only happens on older version of miner, new version gives better error message (but still wont' work since your CPU doesn't support the required instructions). + +## Virus Protection Alert + +Some Virus protection software flag the miner binary as *Male Ware*. +In this case the binary is moved to the quarantine area of the protection software. +This is a wrong alert and not avoid by use. +Add the binary to to protection software white list to solve this issue.s diff --git a/doc/compile.md b/doc/compile.md new file mode 100644 index 0000000..04b1fe4 --- /dev/null +++ b/doc/compile.md @@ -0,0 +1,81 @@ +# Compile xmr-stak + +## Content Overview +* [Build System](#build-system) +* [Generic Build Options](#generic-build-options) +* [CPU Build Options](#cpu-build-options) +* [AMD Build Options](#amd-build-options) +* [NVIDIA Build Options](#nvidia-build-options) +* [Compile in Windows](compile_Windows.md) +* [Compile in Linux](compile_Linux.md) +* [Compile in FreeBSD](compile_FreeBSD.md) + +## Build System + +The build system is CMake, if you are not familiar with CMake you can learn more [here](https://cmake.org/runningcmake/). + +By default the miner will be build with all dependencies. Each optional dependency can be disabled (this will reduce the miner features). + +There are two easy ways to set variables for `cmake` to configure *xmr-stak* +- use the ncurses GUI + - `ccmake .` + - edit your options + - end the GUI by pressing the key `c`(create) and than `g`(generate) +- set Options on the command line + - enable a option: `cmake . -DNAME_OF_THE_OPTION=ON` + - disable a option `cmake . -DNAME_OF_THE_OPTION=OFF` + - set a value `cmake . -DNAME_OF_THE_OPTION=value` + +After the configuration you need to compile the miner, follow the guide for your platform: +* [Compile in Windows](compile_Windows.md) +* [Compile in Linux](compile_Linux.md) +* [Compile in FreeBSD](compile_FreeBSD.md) + +## Generic Build Options +- `CMAKE_INSTALL_PREFIX` install miner to the home folder + - `cmake . -DCMAKE_INSTALL_PREFIX=$HOME/xmr-stak-cpu` + - you can find the binary and the `config.txt` file after `make install` in `$HOME/xmr-stak-cpu/bin` +- `CMAKE_LINK_STATIC` link libgcc and libstdc++ libraries static (default OFF) + - disable with `cmake . -DCMAKE_LINK_STATIC=ON` +- `CMAKE_BUILD_TYPE` set the build type + - valid options: `Release` or `Debug` + - you should always keep `Release` for your productive miners +- `MICROHTTPD_ENABLE` allow to disable/enable the dependency *microhttpd* + - there is no *http* interface available if option is disabled: `cmake . -DMICROHTTPD_ENABLE=OFF` +- `OpenSSL_ENABLE` allow to disable/enable the dependency *OpenSSL* + - it is not possible to connect to a *https* secured pool if option is disabled: `cmake . -DOpenSSL_ENABLE=OFF` + +## CPU Build Options + +- `CPU_ENABLE` allow to disable/enable the CPU backend of the miner +- `HWLOC_ENABLE` allow to disable/enable the dependency *hwloc* + - the config suggestion is not optimal if option is disabled: `cmake . -DHWLOC_ENABLE=OFF` + - disabling can be reduce the miner performance + +## AMD Build Options + +- `OpenCL_ENABLE` allow to disable/enable the AMD backend of the miner + +## NVIDIA Build Options + +- `CUDA_ENABLE` allow to disable/enable the NVIDIA backend of the miner +- `CUDA_ARCH` build for a certain compute architecture + - this option needs a semicolon separated list + - `cmake . -DCUDA_ARCH=61` or `cmake . -DCUDA_ARCH=20;61` + - [list](https://developer.nvidia.com/cuda-gpus) with NVIDIA compute architectures + - by default the miner is created for all currently available compute architectures +- `CUDA_COMPILER` select the compiler for the device code + - valid options: `nvcc` or `clang` if clang 3.9+ is installed +``` + # compile host and device code with clang + export CC=/usr/bin/clang + export CXX=/usr/bin/clang++ + cmake . -DCUDA_COMPILER=clang +``` +- `XMR-STAK_LARGEGRID` use `32` or `64` bit integer for on device indices + - default is enabled + - on old GPUs it can increase the hash rate if disabled: `cmake . -DXMR-STAK_LARGEGRID=OFF` + - if disabled it is not allowed to use more than `1000` threads on the device +- `XMR-STAK_THREADS` give the compiler information which value for `threads` is used at runtime + - default is `0` (compile time optimization) + - if the miner is compiled and used at runtime with the some value it can increase the hash rate: `cmake . -DXMR-STAK_THREADS=32` diff --git a/doc/FREEBSDCOMPILE.md b/doc/compile_FreeBSD.md similarity index 53% rename from doc/FREEBSDCOMPILE.md rename to doc/compile_FreeBSD.md index 230ce73..6dd1165 100644 --- a/doc/FREEBSDCOMPILE.md +++ b/doc/compile_FreeBSD.md @@ -13,8 +13,6 @@ Type 'y' and hit enter to proceed with installing the packages. git clone https://github.com/fireice-uk/xmr-stak-cpu.git cd xmr-stak-cpu cmake . - make + make install -Now you have the binary located at "bin/xmr-stak-cpu". Either move this file to your desired location or run "make install" to install it to your path. - -You can edit the prebuilt [config.txt](config.txt) file found in the root of the repository or you can make your own. This file is required to run xmr-stak-cpu. +Now you have the binary located at "bin/xmr-stak" and the needed shared libraries. diff --git a/doc/LINUXCOMPILE.md b/doc/compile_Linux.md similarity index 94% rename from doc/LINUXCOMPILE.md rename to doc/compile_Linux.md index 4486081..4947fd2 100644 --- a/doc/LINUXCOMPILE.md +++ b/doc/compile_Linux.md @@ -37,8 +37,7 @@ make install ``` -- g++ version 5.1 or higher is required for full C++11 support. CMake release compile scripts, as well as CodeBlocks build environment for debug builds is included. - +- g++ version 5.1 or higher is required for full C++11 support. If you want to compile the binary without installing libraries / compiler or just compile binary for some other distribution, please check the [build_xmr-stak_docker.sh script](scripts/build_xmr-stak_docker/build_xmr-stak_docker.sh). ### To do a static build for a system without gcc 5.1+ @@ -47,6 +46,3 @@ If you want to compile the binary without installing libraries / compiler or jus make install ``` Note - cmake caches variables, so if you want to do a dynamic build later you need to specify '-DCMAKE_LINK_STATIC=OFF' - - - diff --git a/doc/WINCOMPILE.md b/doc/compile_Windows.md similarity index 95% rename from doc/WINCOMPILE.md rename to doc/compile_Windows.md index f70ecff..dec1e75 100644 --- a/doc/WINCOMPILE.md +++ b/doc/compile_Windows.md @@ -58,7 +58,7 @@ ## Compile -- download and unzip `xmr-stak-cpu` +- download and unzip `xmr-stak - open the command line terminal `cmd` - `cd` to your unzipped source code directory - execute the following commands (NOTE: path to VS2017 can be different) @@ -71,4 +71,3 @@ cmake --build . --config Release --target install cd bin\Release ``` -- customize your `config.txt` file by adding the pool, username and password diff --git a/doc/tuning.md b/doc/tuning.md new file mode 100644 index 0000000..820fab5 --- /dev/null +++ b/doc/tuning.md @@ -0,0 +1,67 @@ +# Tuning Guide + +## Content Overview +* [NVIDIA Backend](#nvidia-backend) + * [Choose Value for `threads` and `blocks`](#choose-value-for-threads-and-blocks) + * [Add more GPUs](#add-more-gpus) +* [AMD Backend](#amd-backend) + * [Choose `intensity` and `worksize`](#choose-intensity-and-worksize) + * [Add more GPUs](#add-more-gpus) + +## NVIDIA Backend + +By default the NVIDIA backend can be tuned in the config file `nvidia.txt` + +### Choose Value for `threads` and `blocks` + +The optimal parameter for the `threads` and `blocks` option in `config.txt` depend on your GPU. +For all GPU's with a compute capability `>=2.0` and `<6.0` there is a restriction of the amount of RAM that can be used for the mining algorithm. +The maximum RAM that can be used must be less than 2GB (e.g. GTX TITAN) or 1GB (e.g. GTX 750-TI). +The amount of RAM used for mining can be changed with `"threads" : T, "blocks : B"`. + - `T` = threads used per block + - `B` = CUDA blocks started (should be a multiple of the multiprocessors `M` on the GPU) + +For the 2GB limit the equations must be full filled: `T * B * 2 <= 1900` and ` B mod M == 0`. +The value `1900` is used because there is a little data overhead for administration. +The GTX Titan X has 24 multiprocessors `M`, this means a valid and good starting configuration is `"threads" : 16, "blocks : 48"` +and full fill all restrictions `16 * 48 * 2 = 1536` and `48 mod 24 = 0`. + +The memory limit for NVIDIA Pascal GPUs is `16` GiB if the newest CUDA driver is used. + +### Add More GPUs + +To add a new GPU you need to add a new config set to `gpu_threads_conf`. +`index` is the number of the gpu, the index order not follow the order from `nvidia-smi` or the order shown in windows. + +``` +"gpu_threads_conf" : +[ + { "index" : 0, "threads" : 17, "blocks" : 60, "bfactor" : 0, "bsleep" : 0, "affine_to_cpu" : false}, + { "index" : 1, "threads" : 17, "blocks" : 60, "bfactor" : 0, "bsleep" : 0, "affine_to_cpu" : false}, +], +``` + +## AMD Backend + +By default the NVIDIA backend can be tuned in the config file `nvidia.txt` + +### Choose `intensity` and `worksize` + +Intensity means the number of threads used to mine. +`worksize` is the number of threads working together to increase the miner performance. +In the most cases a `worksize` of `16` or `8` is optimal. + +### Add More GPUs + +To add a new GPU you need to add a new config set to `gpu_threads_conf` and increase `gpu_thread_num"` to the number of gpus (entries in `gpu_threads_conf`). +`index` is the number of the gpu. + +``` +"gpu_thread_num" : 2, + +"gpu_threads_conf" : +[ + { "index" : 0, "intensity" : 1000, "worksize" : 8, "affine_to_cpu" : false }, + { "index" : 1, "intensity" : 1000, "worksize" : 8, "affine_to_cpu" : false }, +], +``` \ No newline at end of file diff --git a/doc/usage.md b/doc/usage.md new file mode 100644 index 0000000..dfebf21 --- /dev/null +++ b/doc/usage.md @@ -0,0 +1,54 @@ +# HowTo Use xmr-stak + +## Content Overview +* [Configuration](#configuration) +* [Usage on Windows](#usage-on-windows) +* [Usage on Linux](#usage-on-linux) +* [Command Line Options](#command-line-options) +* [HTML and JSON API report configuraton](#xx) + +## Configurations + +Before you started the miner the first time there are no config files available. +Config files will be created at the first start. +The number of files depends on the available backends. +`config.txt` contains the common miner settings. +`amd.txt`, `cpu.txt` and `nvidia.txt` contains miner backend specific settings and can be used for further tuning ([Tuning Guide](tuning.md)). + + +## Usage on Windows +1) Double click the `xmr-stak.exe` file +2) Fill in the pool url, username and password + +## Usage on Linux +1) Open a terminal within the folder with the binary +2) Start the miner with `./xmr-stak` + +## Command Line Options + +The miner allow to overwrite some of the settings via command line options. + +``` +Usage: xmr-stak [OPTION]... [CONFIGFILE] + + -c, --config common miner configuration file + -h, --help show this help + --noCPU disable the CPU miner backend + --cpu FILE CPU backend miner config file + --noAMD disable the AMD miner backend + --amd FILE AMD backend miner config file + +The Following options temporary overwrites the config file settings: + -o, --url URL pool url and port, e.g. pool.usxmrpool.com:3333 + -u, --user USERNAME pool user name or wallet address + -p, --pass PASSWD pool password, in the most cases x or empty "" + +## HTML and JSON API report configuraton + +To configure the reports shown on the [README](README.md) side you need to edit the httpd_port variable. Then enable wifi on your phone and navigate to [miner ip address]:[httpd_port] in your phone browser. If you want to use the data in scripts, you can get the JSON version of the data at url [miner ip address]:[httpd_port]/api.json + +## Default Developer Donation +By default the miner will donate 2% of the hashpower (2 minute in 100 minutes) to my pool. If you want to change that, edit **xmrstak/donate-level.hpp** before you build the binaries. + +If you want to donate directly to support further development, here is my wallet +``` From c30c258b91b95021443fdfd40d3075cd259a3cef Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sat, 30 Sep 2017 21:33:11 +0200 Subject: [PATCH 36/42] nvidia: fix return value if no device is found --- xmrstak/backend/amd/autoAdjust.hpp | 6 ++---- xmrstak/backend/nvidia/autoAdjust.hpp | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/xmrstak/backend/amd/autoAdjust.hpp b/xmrstak/backend/amd/autoAdjust.hpp index c6f2ed7..dac0cfb 100644 --- a/xmrstak/backend/amd/autoAdjust.hpp +++ b/xmrstak/backend/amd/autoAdjust.hpp @@ -44,7 +44,6 @@ public: */ bool printConfig() { - int platformIndex = getAMDPlatformIdx(); if(platformIndex == -1) @@ -58,13 +57,12 @@ public: int deviceCount = devVec.size(); - if(deviceCount == 0) + if(deviceCount == 0) return false; - + generateThreadConfig(platformIndex); return true; - } private: diff --git a/xmrstak/backend/nvidia/autoAdjust.hpp b/xmrstak/backend/nvidia/autoAdjust.hpp index 4f74abf..87787fa 100644 --- a/xmrstak/backend/nvidia/autoAdjust.hpp +++ b/xmrstak/backend/nvidia/autoAdjust.hpp @@ -38,7 +38,7 @@ public: { int deviceCount = 0; if(cuda_get_devicecount(&deviceCount) == 0) - std::exit(0); + return false; // evaluate config parameter for if auto adjustment is needed // evaluate config parameter for if auto adjustment is needed for(int i = 0; i < deviceCount; i++) From 1d1eff2d8f60a9df2793d76b7307545434034c5f Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sat, 30 Sep 2017 21:55:24 +0200 Subject: [PATCH 37/42] fix CI tests --- .appveyor.yml | 11 +++++------ .travis.yml | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 381e544..2c32279 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -5,7 +5,7 @@ image: Visual Studio 2017 platform: x64 # clone directory -clone_folder: c:\xmr-stak-cpu +clone_folder: c:\xmr-stak install: - mkdir c:\xmr-stak-dep @@ -14,15 +14,14 @@ install: build_script: - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsMSBuildCmd.bat" - - cd c:\xmr-stak-cpu + - cd c:\xmr-stak - mkdir build - cd build - set CMAKE_PREFIX_PATH=C:\xmr-stak-dep\hwloc;C:\xmr-stak-dep\libmicrohttpd;C:\xmr-stak-dep\openssl; - - cmake -G "Visual Studio 15 2017 Win64" -T v141,host=x64 .. - - msbuild xmr-stak-cpu.sln /p:Configuration=Release + - cmake -G "Visual Studio 15 2017 Win64" -T v140,host=x64 -DCUDA_ENABLE=OFF -DOpenCL_ENABLE=OFF .. + - cmake --build . --config Release --target install test_script: - cd c:\xmr-stak-cpu\build\bin\Release - dir - - copy ..\..\..\config.txt . -# - xmr-stak-cpu.exe +# - xmr-stak.exe diff --git a/.travis.yml b/.travis.yml index 37b7749..07d64da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -67,9 +67,9 @@ before_install: script: - if [ $TRAVIS_OS_NAME = osx ]; then brew install hwloc; - cmake -DMICROHTTPD_ENABLE=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl .; + cmake -DMICROHTTPD_ENABLE=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DCUDA_ENABLE=OFF -DOpenCL_ENABLE=OFF .; else - cmake -D CMAKE_C_COMPILER=${CMAKE_C_COMPILER} -D CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} .; + cmake -D CMAKE_C_COMPILER=${CMAKE_C_COMPILER} -D CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCUDA_ENABLE=OFF -DOpenCL_ENABLE=OFF .; fi; - make VERBOSE=1 - ./bin/xmr-stak-cpu -c ./config.txt From b1ee3d2184fd1aaad60d22c2bad7e7e2a6f66cdb Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sat, 30 Sep 2017 22:19:06 +0200 Subject: [PATCH 38/42] fix CI - fix windows CI - add CUDA to linux CI --- .appveyor.yml | 2 +- .travis.yml | 38 ++++++++++++++++++++++++++++++++++---- CMakeLists.txt | 2 ++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 2c32279..02ce827 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -22,6 +22,6 @@ build_script: - cmake --build . --config Release --target install test_script: - - cd c:\xmr-stak-cpu\build\bin\Release + - cd c:\xmr-stak\build\bin\Release - dir # - xmr-stak.exe diff --git a/.travis.yml b/.travis.yml index 07d64da..975afda 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,11 @@ sudo: false language: cpp +cache: + apt: true + directories: + - $HOME/.cache/cuda + addons: apt: packages: &default_packages @@ -14,6 +19,10 @@ addons: - libssl-dev - libhwloc-dev +env: + global: + - CUDA_ROOT: $HOME/.cache/cuda + matrix: include: - os: linux @@ -29,6 +38,7 @@ matrix: env: - CMAKE_CXX_COMPILER=g++-5 - CMAKE_C_COMPILER=gcc-5 + - XMRSTAK_CMAKE_FLAGS="-DCUDA_ARCH=30 -DOpenCL_ENABLE=OFF" - os: linux compiler: gcc @@ -43,6 +53,7 @@ matrix: env: - CMAKE_CXX_COMPILER=g++-6 - CMAKE_C_COMPILER=gcc-6 + - XMRSTAK_CMAKE_FLAGS="-DCUDA_ENABLE=OFF -DOpenCL_ENABLE=OFF" - os: linux compiler: gcc @@ -57,19 +68,38 @@ matrix: env: - CMAKE_CXX_COMPILER=g++-7 - CMAKE_C_COMPILER=gcc-7 + - XMRSTAK_CMAKE_FLAGS="-DCUDA_ENABLE=OFF -DOpenCL_ENABLE=OFF" - os: osx compiler: gcc + env: + - XMRSTAK_CMAKE_FLAGS="-DCUDA_ENABLE=OFF -DOpenCL_ENABLE=OFF" before_install: - if [ $TRAVIS_OS_NAME = osx ]; then brew tap homebrew/science; fi + - export PATH=$CUDA_ROOT/bin:$PATH + +install: + + # CUDA + - NVCC_FOUND=$(which nvcc >/dev/null && { echo 0; } || { echo 1; }) + - if [ $NVCC_FOUND -ne 0 ]; then + mkdir -p $CUDA_ROOT && + cd $CUDA_ROOT && + travis_retry wget https://developer.nvidia.com/compute/cuda/8.0/prod/local_installers/cuda_8.0.44_linux-run && + ls -la && + chmod u+x *-run && + ./cuda_8.0.44_linux-run --silent --toolkit --toolkitpath=$CUDA_ROOT && + rm -rf ./cuda_8.0.44_linux-run $CUDA_ROOT/{samples,jre,doc,share} && + cd -; + fi script: - if [ $TRAVIS_OS_NAME = osx ]; then brew install hwloc; - cmake -DMICROHTTPD_ENABLE=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl -DCUDA_ENABLE=OFF -DOpenCL_ENABLE=OFF .; - else - cmake -D CMAKE_C_COMPILER=${CMAKE_C_COMPILER} -D CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCUDA_ENABLE=OFF -DOpenCL_ENABLE=OFF .; + cmake -DMICROHTTPD_ENABLE=OFF -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl ${XMRSTAK_CMAKE_FLAGS} .; + else + cmake -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} ${XMRSTAK_CMAKE_FLAGS} .; fi; - make VERBOSE=1 - - ./bin/xmr-stak-cpu -c ./config.txt + - ./bin/xmr-stak --help diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a24885..dc35c3d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,8 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE PATH "install prefix" FORCE) endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) +# help to find cuda on systems with a software module system +list(APPEND CMAKE_PREFIX_PATH "$ENV{CUDA_ROOT}") # allow user to extent CMAKE_PREFIX_PATH via environment variable list(APPEND CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH}") From 42cc3c3a9566cd2e21bb7e6e7218b7860e081b08 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sat, 30 Sep 2017 23:57:55 +0200 Subject: [PATCH 39/42] add -c option for config file --- doc/usage.md | 4 ++-- xmrstak/cli/cli-miner.cpp | 33 ++++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/doc/usage.md b/doc/usage.md index dfebf21..42a29fd 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -29,9 +29,9 @@ The number of files depends on the available backends. The miner allow to overwrite some of the settings via command line options. ``` -Usage: xmr-stak [OPTION]... [CONFIGFILE] +Usage: xmr-stak [OPTION]... - -c, --config common miner configuration file + -c, --config FILE common miner configuration file -h, --help show this help --noCPU disable the CPU miner backend --cpu FILE CPU backend miner config file diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index 66adaf1..585b114 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -60,9 +60,9 @@ void help() using namespace std; using namespace xmrstak; - cout<<"Usage: "<=argc ) { - printer::inst()->print_msg(L0, "No argument for opName '--cpu' given"); + printer::inst()->print_msg(L0, "No argument for parameter '--cpu' given"); win_exit(); return 1; } @@ -150,7 +150,7 @@ int main(int argc, char *argv[]) ++i; if( i >=argc ) { - printer::inst()->print_msg(L0, "No argument for opName '--amd' given"); + printer::inst()->print_msg(L0, "No argument for parameter '--amd' given"); win_exit(); return 1; } @@ -161,7 +161,7 @@ int main(int argc, char *argv[]) ++i; if( i >=argc ) { - printer::inst()->print_msg(L0, "No argument for opName '--nvidia' given"); + printer::inst()->print_msg(L0, "No argument for parameter '--nvidia' given"); win_exit(); return 1; } @@ -172,7 +172,7 @@ int main(int argc, char *argv[]) ++i; if( i >=argc ) { - printer::inst()->print_msg(L0, "No argument for opName '-o/--url' given"); + printer::inst()->print_msg(L0, "No argument for parameter '-o/--url' given"); win_exit(); return 1; } @@ -183,7 +183,7 @@ int main(int argc, char *argv[]) ++i; if( i >=argc ) { - printer::inst()->print_msg(L0, "No argument for opName '-u/--user' given"); + printer::inst()->print_msg(L0, "No argument for parameter '-u/--user' given"); win_exit(); return 1; } @@ -194,15 +194,30 @@ int main(int argc, char *argv[]) ++i; if( i >=argc ) { - printer::inst()->print_msg(L0, "No argument for opName '-p/--pass' given"); + printer::inst()->print_msg(L0, "No argument for parameter '-p/--pass' given"); win_exit(); return 1; } userSetPasswd = true; params::inst().poolPasswd = argv[i]; } - else + else if(opName.compare("-c") == 0 || opName.compare("--config") == 0) + { + ++i; + if( i >=argc ) + { + printer::inst()->print_msg(L0, "No argument for parameter '-c/--config' given"); + win_exit(); + return 1; + } params::inst().configFile = argv[i]; + } + else + { + printer::inst()->print_msg(L0, "Parameter unknown '%s'",argv[i]); + win_exit(); + return 1; + } } // check if we need a guided start From 8fd095e97a5e6e04cdb3121f15d462c478153f45 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 1 Oct 2017 00:02:24 +0200 Subject: [PATCH 40/42] enable C++11 for nvcc --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc35c3d..3c7a585 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,7 +112,7 @@ if(CUDA_ENABLE) elseif("${CUDA_COMPILER}" STREQUAL "nvcc") # add c++11 for cuda if(NOT "${CMAKE_CXX_FLAGS}" MATCHES "-std=c\\+\\+11") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -std=c++11") endif() # avoid that nvcc in CUDA < 8 tries to use libc `memcpy` within the kernel From 2558a70c731c7b338b7d7e18922dcecac6fdf091 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 1 Oct 2017 00:10:12 +0200 Subject: [PATCH 41/42] return 0 if help is called - add CIvariables to debug cuda build --- .travis.yml | 4 +++- xmrstak/cli/cli-miner.cpp | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 975afda..f9e01ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -83,6 +83,8 @@ install: # CUDA - NVCC_FOUND=$(which nvcc >/dev/null && { echo 0; } || { echo 1; }) + - which nvcc + - echo $NVCC_FOUND - if [ $NVCC_FOUND -ne 0 ]; then mkdir -p $CUDA_ROOT && cd $CUDA_ROOT && @@ -101,5 +103,5 @@ script: else cmake -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} ${XMRSTAK_CMAKE_FLAGS} .; fi; - - make VERBOSE=1 + - make VERBOSE=1 install - ./bin/xmr-stak --help diff --git a/xmrstak/cli/cli-miner.cpp b/xmrstak/cli/cli-miner.cpp index 585b114..ff31d2c 100644 --- a/xmrstak/cli/cli-miner.cpp +++ b/xmrstak/cli/cli-miner.cpp @@ -119,7 +119,8 @@ int main(int argc, char *argv[]) if(opName.compare("-h") == 0 || opName.compare("--help") == 0) { help(); - win_exit(); + // \todo give return code to win_exit to allow passing CI + //win_exit(); return 0; } else if(opName.compare("--noCPU") == 0) From 2c8d64abfa1c989f260dd4fcaa5c6d7707a5f668 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Sun, 1 Oct 2017 00:24:36 +0200 Subject: [PATCH 42/42] disable cuda install for MacOS --- .travis.yml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index f9e01ec..def7fee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -82,19 +82,19 @@ before_install: install: # CUDA - - NVCC_FOUND=$(which nvcc >/dev/null && { echo 0; } || { echo 1; }) - - which nvcc - - echo $NVCC_FOUND - - if [ $NVCC_FOUND -ne 0 ]; then - mkdir -p $CUDA_ROOT && - cd $CUDA_ROOT && - travis_retry wget https://developer.nvidia.com/compute/cuda/8.0/prod/local_installers/cuda_8.0.44_linux-run && - ls -la && - chmod u+x *-run && - ./cuda_8.0.44_linux-run --silent --toolkit --toolkitpath=$CUDA_ROOT && - rm -rf ./cuda_8.0.44_linux-run $CUDA_ROOT/{samples,jre,doc,share} && - cd -; - fi + - if [ $TRAVIS_OS_NAME != osx ]; then + NVCC_FOUND=$(which nvcc >/dev/null && { echo 0; } || { echo 1; }); + if [ $NVCC_FOUND -ne 0 ]; then + mkdir -p $CUDA_ROOT && + cd $CUDA_ROOT && + travis_retry wget https://developer.nvidia.com/compute/cuda/8.0/prod/local_installers/cuda_8.0.44_linux-run && + ls -la && + chmod u+x *-run && + ./cuda_8.0.44_linux-run --silent --toolkit --toolkitpath=$CUDA_ROOT && + rm -rf ./cuda_8.0.44_linux-run $CUDA_ROOT/{samples,jre,doc,share} && + cd -; + fi + fi; script: - if [ $TRAVIS_OS_NAME = osx ]; then
Thread ID2.5s60s15mH/s
Thread ID10s60s15mH/s
%u%s%s%s