/** * Fresh algorithm */ extern "C" { #include "sph/sph_shavite.h" #include "sph/sph_simd.h" #include "sph/sph_echo.h" } #include "miner.h" #include "cuda_helper.h" // to test gpu hash on a null buffer #define NULLTEST 0 static uint32_t *d_hash[8]; extern void x11_shavite512_cpu_init(int thr_id, int threads); extern void x11_shavite512_setBlock_80(void *pdata); extern void x11_shavite512_cpu_hash_80(int thr_id, int threads, uint32_t startNounce, uint32_t *d_hash, int order); extern void x11_shavite512_cpu_hash_64(int thr_id, int threads, uint32_t startNounce, uint32_t *d_nonceVector, uint32_t *d_hash, int order); extern int x11_simd512_cpu_init(int thr_id, int threads); extern void x11_simd512_cpu_hash_64(int thr_id, int threads, uint32_t startNounce, uint32_t *d_nonceVector, uint32_t *d_hash, int order); extern void x11_echo512_cpu_init(int thr_id, int threads); extern void x11_echo512_cpu_hash_64(int thr_id, int threads, uint32_t startNounce, uint32_t *d_nonceVector, uint32_t *d_hash, int order); extern void quark_compactTest_cpu_init(int thr_id, int threads); extern void quark_compactTest_cpu_hash_64(int thr_id, int threads, uint32_t startNounce, uint32_t *inpHashes, uint32_t *d_noncesTrue, size_t *nrmTrue, uint32_t *d_noncesFalse, size_t *nrmFalse, int order); // CPU Hash extern "C" void fresh_hash(void *state, const void *input) { // shavite-simd-shavite-simd-echo sph_shavite512_context ctx_shavite; sph_simd512_context ctx_simd; sph_echo512_context ctx_echo; unsigned char hash[128]; // uint32_t hashA[16], hashB[16]; #define hashA hash #define hashB hash+64 memset(hash, 0, sizeof hash); sph_shavite512_init(&ctx_shavite); sph_shavite512(&ctx_shavite, input, 80); sph_shavite512_close(&ctx_shavite, hashA); sph_simd512_init(&ctx_simd); sph_simd512(&ctx_simd, hashA, 64); sph_simd512_close(&ctx_simd, hashB); sph_shavite512_init(&ctx_shavite); sph_shavite512(&ctx_shavite, hashB, 64); sph_shavite512_close(&ctx_shavite, hashA); sph_simd512_init(&ctx_simd); sph_simd512(&ctx_simd, hashA, 64); sph_simd512_close(&ctx_simd, hashB); sph_echo512_init(&ctx_echo); sph_echo512(&ctx_echo, hashB, 64); sph_echo512_close(&ctx_echo, hashA); memcpy(state, hash, 32); } static bool init[8] = { 0 }; extern "C" int scanhash_fresh(int thr_id, uint32_t *pdata, const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done) { const uint32_t first_nonce = pdata[19]; uint32_t endiandata[20]; int throughput = opt_work_size ? opt_work_size : (1 << 19); // 256*256*8; throughput = min(throughput, (int) (max_nonce - first_nonce)); if (opt_benchmark) ((uint32_t*)ptarget)[7] = 0x00ff; if (!init[thr_id]) { cudaSetDevice(device_map[thr_id]); x11_shavite512_cpu_init(thr_id, throughput); x11_simd512_cpu_init(thr_id, throughput); x11_echo512_cpu_init(thr_id, throughput); CUDA_CALL_OR_RET_X(cudaMalloc(&d_hash[thr_id], 16 * sizeof(uint32_t) * throughput + 4), 0); cuda_check_cpu_init(thr_id, throughput); init[thr_id] = true; } for (int k=0; k < 20; k++) be32enc(&endiandata[k], ((uint32_t*)pdata)[k]); x11_shavite512_setBlock_80((void*)endiandata); cuda_check_cpu_setTarget(ptarget); do { uint32_t Htarg = ptarget[7]; uint32_t foundNonce; int order = 0; // GPU Hash x11_shavite512_cpu_hash_80(thr_id, throughput, pdata[19], d_hash[thr_id], order++); x11_simd512_cpu_hash_64(thr_id, throughput, pdata[19], NULL, d_hash[thr_id], order++); x11_shavite512_cpu_hash_64(thr_id, throughput, pdata[19], NULL, d_hash[thr_id], order++); x11_simd512_cpu_hash_64(thr_id, throughput, pdata[19], NULL, d_hash[thr_id], order++); x11_echo512_cpu_hash_64(thr_id, throughput, pdata[19], NULL, d_hash[thr_id], order++); #if NULLTEST uint32_t buf[8]; memset(buf, 0, sizeof buf); CUDA_SAFE_CALL(cudaMemcpy(buf, d_hash[thr_id], sizeof buf, cudaMemcpyDeviceToHost)); CUDA_SAFE_CALL(cudaThreadSynchronize()); print_hash((unsigned char*)buf); printf("\n"); #endif foundNonce = cuda_check_cpu_hash_64(thr_id, throughput, pdata[19], NULL, d_hash[thr_id], order++); if (foundNonce != 0xffffffff) { uint32_t vhash64[8]; be32enc(&endiandata[19], foundNonce); fresh_hash(vhash64, endiandata); if (vhash64[7] <= Htarg && fulltest(vhash64, ptarget)) { pdata[19] = foundNonce; *hashes_done = foundNonce - first_nonce + 1; return 1; } else if (vhash64[7] > Htarg) { applog(LOG_INFO, "GPU #%d: result for %08x is not in range: %x > %x", thr_id, foundNonce, vhash64[7], Htarg); } else { applog(LOG_INFO, "GPU #%d: result for %08x does not validate on CPU!", thr_id, foundNonce); } } pdata[19] += throughput; } while (pdata[19] < max_nonce && !work_restart[thr_id].restart); *hashes_done = pdata[19] - first_nonce + 1; return 0; }