mirror of
https://github.com/GOSTSec/ccminer
synced 2025-01-25 14:04:34 +00:00
e50556b637
small fixes to handle better the multi thread per gpu explicitly report than quark is not compatible with SM 2.1 (compact shuffle)
208 lines
6.2 KiB
Plaintext
208 lines
6.2 KiB
Plaintext
extern "C" {
|
|
#include "sph/sph_blake.h"
|
|
#include "sph/sph_bmw.h"
|
|
#include "sph/sph_skein.h"
|
|
#include "sph/sph_keccak.h"
|
|
#include "sph/sph_cubehash.h"
|
|
#include "lyra2/Lyra2.h"
|
|
}
|
|
|
|
#include "miner.h"
|
|
#include "cuda_helper.h"
|
|
|
|
|
|
static uint64_t *d_hash[MAX_GPUS];
|
|
static uint64_t* d_matrix[MAX_GPUS];
|
|
|
|
extern void blake256_cpu_init(int thr_id, uint32_t threads);
|
|
extern void blake256_cpu_hash_80(const int thr_id, const uint32_t threads, const uint32_t startNonce, uint64_t *Hash, int order);
|
|
extern void blake256_cpu_setBlock_80(uint32_t *pdata);
|
|
extern void keccak256_cpu_hash_32(int thr_id, uint32_t threads, uint32_t startNonce, uint64_t *d_outputHash, int order);
|
|
extern void keccak256_cpu_init(int thr_id, uint32_t threads);
|
|
extern void keccak256_cpu_free(int thr_id);
|
|
extern void skein256_cpu_hash_32(int thr_id, uint32_t threads, uint32_t startNonce, uint64_t *d_outputHash, int order);
|
|
extern void skein256_cpu_init(int thr_id, uint32_t threads);
|
|
extern void cubehash256_cpu_hash_32(int thr_id, uint32_t threads, uint32_t startNounce, uint64_t *d_hash, int order);
|
|
|
|
extern void lyra2v2_cpu_hash_32(int thr_id, uint32_t threads, uint32_t startNonce, uint64_t *d_outputHash, int order);
|
|
extern void lyra2v2_cpu_init(int thr_id, uint32_t threads, uint64_t* d_matrix);
|
|
|
|
extern void bmw256_setTarget(const void *ptarget);
|
|
extern void bmw256_cpu_init(int thr_id, uint32_t threads);
|
|
extern void bmw256_cpu_free(int thr_id);
|
|
extern void bmw256_cpu_hash_32(int thr_id, uint32_t threads, uint32_t startNounce, uint64_t *g_hash, uint32_t *resultnonces);
|
|
|
|
void lyra2v2_hash(void *state, const void *input)
|
|
{
|
|
uint32_t hashA[8], hashB[8];
|
|
|
|
sph_blake256_context ctx_blake;
|
|
sph_keccak256_context ctx_keccak;
|
|
sph_skein256_context ctx_skein;
|
|
sph_bmw256_context ctx_bmw;
|
|
sph_cubehash256_context ctx_cube;
|
|
|
|
sph_blake256_set_rounds(14);
|
|
|
|
sph_blake256_init(&ctx_blake);
|
|
sph_blake256(&ctx_blake, input, 80);
|
|
sph_blake256_close(&ctx_blake, hashA);
|
|
|
|
sph_keccak256_init(&ctx_keccak);
|
|
sph_keccak256(&ctx_keccak, hashA, 32);
|
|
sph_keccak256_close(&ctx_keccak, hashB);
|
|
|
|
sph_cubehash256_init(&ctx_cube);
|
|
sph_cubehash256(&ctx_cube, hashB, 32);
|
|
sph_cubehash256_close(&ctx_cube, hashA);
|
|
|
|
LYRA2(hashB, 32, hashA, 32, hashA, 32, 1, 4, 4);
|
|
|
|
sph_skein256_init(&ctx_skein);
|
|
sph_skein256(&ctx_skein, hashB, 32);
|
|
sph_skein256_close(&ctx_skein, hashA);
|
|
|
|
sph_cubehash256_init(&ctx_cube);
|
|
sph_cubehash256(&ctx_cube, hashA, 32);
|
|
sph_cubehash256_close(&ctx_cube, hashB);
|
|
|
|
sph_bmw256_init(&ctx_bmw);
|
|
sph_bmw256(&ctx_bmw, hashB, 32);
|
|
sph_bmw256_close(&ctx_bmw, hashA);
|
|
|
|
memcpy(state, hashA, 32);
|
|
}
|
|
|
|
static bool init[MAX_GPUS] = { 0 };
|
|
|
|
extern "C" int scanhash_lyra2v2(int thr_id, struct work* work, uint32_t max_nonce, unsigned long *hashes_done)
|
|
{
|
|
uint32_t *pdata = work->data;
|
|
uint32_t *ptarget = work->target;
|
|
const uint32_t first_nonce = pdata[19];
|
|
int dev_id = device_map[thr_id];
|
|
int intensity = (device_sm[dev_id] > 500 && !is_windows()) ? 20 : 18;
|
|
uint32_t throughput = cuda_default_throughput(dev_id, 1UL << intensity);
|
|
if (init[thr_id]) throughput = min(throughput, max_nonce - first_nonce);
|
|
|
|
if (opt_benchmark)
|
|
ptarget[7] = 0x000f;
|
|
|
|
if (!init[thr_id])
|
|
{
|
|
size_t matrix_sz = 16 * sizeof(uint64_t) * 4 * 3;
|
|
cudaSetDevice(dev_id);
|
|
if (opt_cudaschedule == -1 && gpu_threads == 1) {
|
|
cudaDeviceReset();
|
|
// reduce cpu usage
|
|
cudaSetDeviceFlags(cudaDeviceScheduleBlockingSync);
|
|
CUDA_LOG_ERROR();
|
|
}
|
|
|
|
blake256_cpu_init(thr_id, throughput);
|
|
keccak256_cpu_init(thr_id,throughput);
|
|
skein256_cpu_init(thr_id, throughput);
|
|
bmw256_cpu_init(thr_id, throughput);
|
|
|
|
// SM 3 implentation requires a bit more memory
|
|
if (device_sm[dev_id] < 500 || cuda_arch[dev_id] < 500)
|
|
matrix_sz = 16 * sizeof(uint64_t) * 4 * 4;
|
|
|
|
CUDA_SAFE_CALL(cudaMalloc(&d_matrix[thr_id], matrix_sz * throughput));
|
|
lyra2v2_cpu_init(thr_id, throughput, d_matrix[thr_id]);
|
|
|
|
CUDA_SAFE_CALL(cudaMalloc(&d_hash[thr_id], (size_t)32 * throughput));
|
|
|
|
if (device_sm[dev_id] < 300) {
|
|
gpulog(LOG_ERR, thr_id, "Device SM 3.0 or more recent required!");
|
|
proper_exit(1);
|
|
return -1;
|
|
}
|
|
|
|
api_set_throughput(thr_id, throughput);
|
|
init[thr_id] = true;
|
|
}
|
|
|
|
uint32_t endiandata[20];
|
|
for (int k=0; k < 20; k++)
|
|
be32enc(&endiandata[k], pdata[k]);
|
|
|
|
blake256_cpu_setBlock_80(pdata);
|
|
bmw256_setTarget(ptarget);
|
|
|
|
do {
|
|
int order = 0;
|
|
uint32_t foundNonces[2] = { 0, 0 };
|
|
|
|
blake256_cpu_hash_80(thr_id, throughput, pdata[19], d_hash[thr_id], order++);
|
|
keccak256_cpu_hash_32(thr_id, throughput, pdata[19], d_hash[thr_id], order++);
|
|
cubehash256_cpu_hash_32(thr_id, throughput, pdata[19], d_hash[thr_id], order++);
|
|
lyra2v2_cpu_hash_32(thr_id, throughput, pdata[19], d_hash[thr_id], order++);
|
|
skein256_cpu_hash_32(thr_id, throughput, pdata[19], d_hash[thr_id], order++);
|
|
cubehash256_cpu_hash_32(thr_id, throughput,pdata[19], d_hash[thr_id], order++);
|
|
|
|
bmw256_cpu_hash_32(thr_id, throughput, pdata[19], d_hash[thr_id], foundNonces);
|
|
|
|
*hashes_done = pdata[19] - first_nonce + throughput;
|
|
|
|
if (foundNonces[0] != 0)
|
|
{
|
|
uint32_t vhash64[8];
|
|
be32enc(&endiandata[19], foundNonces[0]);
|
|
lyra2v2_hash(vhash64, endiandata);
|
|
if (vhash64[7] <= ptarget[7] && fulltest(vhash64, ptarget))
|
|
{
|
|
int res = 1;
|
|
work_set_target_ratio(work, vhash64);
|
|
pdata[19] = foundNonces[0];
|
|
// check if there was another one...
|
|
if (foundNonces[1] != 0)
|
|
{
|
|
be32enc(&endiandata[19], foundNonces[1]);
|
|
lyra2v2_hash(vhash64, endiandata);
|
|
pdata[21] = foundNonces[1];
|
|
if (bn_hash_target_ratio(vhash64, ptarget) > work->shareratio) {
|
|
work_set_target_ratio(work, vhash64);
|
|
xchg(pdata[19], pdata[21]);
|
|
}
|
|
res++;
|
|
}
|
|
return res;
|
|
}
|
|
else
|
|
{
|
|
gpulog(LOG_WARNING, thr_id, "result for %08x does not validate on CPU!", foundNonces[0]);
|
|
}
|
|
}
|
|
|
|
if ((uint64_t)throughput + pdata[19] >= max_nonce) {
|
|
pdata[19] = max_nonce;
|
|
break;
|
|
}
|
|
pdata[19] += throughput;
|
|
|
|
} while (!work_restart[thr_id].restart);
|
|
|
|
*hashes_done = pdata[19] - first_nonce;
|
|
return 0;
|
|
}
|
|
|
|
// cleanup
|
|
extern "C" void free_lyra2v2(int thr_id)
|
|
{
|
|
if (!init[thr_id])
|
|
return;
|
|
|
|
cudaThreadSynchronize();
|
|
|
|
cudaFree(d_hash[thr_id]);
|
|
cudaFree(d_matrix[thr_id]);
|
|
|
|
bmw256_cpu_free(thr_id);
|
|
keccak256_cpu_free(thr_id);
|
|
|
|
init[thr_id] = false;
|
|
|
|
cudaDeviceSynchronize();
|
|
}
|