forked from tpruvot/ccminer
-
Notifications
You must be signed in to change notification settings - Fork 38
/
myriadgroestl.cu
140 lines (112 loc) · 4.09 KB
/
myriadgroestl.cu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <string.h>
#include <stdint.h>
#include <cuda_runtime.h>
#include <openssl/sha.h>
#include "sph/sph_groestl.h"
#include "miner.h"
#include "cuda_helper.h"
#define NBN 2
//#define NPT 2
static uint32_t *d_resNonce[MAX_GPUS];
static uint32_t *h_resNonce[MAX_GPUS];
void myriadgroestl_cpu_init(int thr_id, uint32_t threads);
void myriadgroestl_cpu_free(int thr_id);
void myriadgroestl_cpu_setBlock(int thr_id, void *data);
void myriadgroestl_cpu_hash(int thr_id, uint32_t threads, uint32_t startNounce, uint32_t *d_resNounce, const uint64_t target);
void myriadhash(void *state, const void *input)
{
uint32_t _ALIGN(64) hash[16];
sph_groestl512_context ctx_groestl;
SHA256_CTX sha256;
sph_groestl512_init(&ctx_groestl);
sph_groestl512(&ctx_groestl, input, 80);
sph_groestl512_close(&ctx_groestl, hash);
SHA256_Init(&sha256);
SHA256_Update(&sha256,(unsigned char *)hash, 64);
SHA256_Final((unsigned char *)hash, &sha256);
memcpy(state, hash, 32);
}
static bool init[MAX_GPUS] = { 0 };
int scanhash_myriad(int thr_id, struct work *work, uint32_t max_nonce, unsigned long *hashes_done)
{
uint32_t _ALIGN(64) endiandata[32];
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
uint32_t first_nonce = pdata[19];
int dev_id = device_map[thr_id];
int intensity = 23;//(device_sm[dev_id] >= 600) ? 20 : 18;
uint32_t throughput = cuda_default_throughput(thr_id, 1U << intensity);
if (init[thr_id]) throughput = min(throughput, max_nonce - first_nonce);
if (opt_benchmark)
ptarget[7] = 0x00000000;
// init
if(!init[thr_id])
{
cudaSetDevice(dev_id);
if (opt_cudaschedule == -1 && gpu_threads == 1) {
cudaDeviceReset();
// reduce cpu usage
cudaSetDeviceFlags(cudaDeviceScheduleBlockingSync);
cudaDeviceSetCacheConfig(cudaFuncCachePreferL1);
CUDA_LOG_ERROR();
}
gpulog(LOG_INFO,thr_id, "Intensity set to %g, %u cuda threads", throughput2intensity(throughput), throughput);
myriadgroestl_cpu_init(thr_id, throughput);
CUDA_SAFE_CALL(cudaMalloc(&d_resNonce[thr_id], NBN * sizeof(uint32_t)));
CUDA_SAFE_CALL(cudaMallocHost(&h_resNonce[thr_id], NBN * sizeof(uint32_t)));
init[thr_id] = true;
}
for (int k=0; k < 20; k++)
be32enc(&endiandata[k], pdata[k]);
myriadgroestl_cpu_setBlock(thr_id, endiandata);
cudaMemset(d_resNonce[thr_id], 0xff, NBN*sizeof(uint32_t));
int rc = 0;
do {
myriadgroestl_cpu_hash(thr_id, throughput, pdata[19], d_resNonce[thr_id], *(uint64_t*)&ptarget[6]);
cudaMemcpy(h_resNonce[thr_id], d_resNonce[thr_id], NBN*sizeof(uint32_t), cudaMemcpyDeviceToHost);
if (h_resNonce[thr_id][0] != UINT32_MAX){
uint32_t _ALIGN(64) vhash64[8];
endiandata[19] = swab32(h_resNonce[thr_id][0]);
myriadhash(vhash64, endiandata);
if (vhash64[7] <= ptarget[7] && fulltest(vhash64, ptarget)) {
*hashes_done = pdata[19] - first_nonce + throughput + 1;
rc = 1;
work_set_target_ratio(work, vhash64);
pdata[19] = h_resNonce[thr_id][0];
work->nonces[0] = pdata[19];
if (h_resNonce[thr_id][1] != UINT32_MAX) {
// if(!opt_quiet)
// gpulog(LOG_BLUE,dev_id,"Found 2nd nonce: %08x", swab32(h_resNonce[thr_id][1]));
endiandata[19] = swab32(h_resNonce[thr_id][1]);
myriadhash(vhash64, endiandata);
pdata[21] = h_resNonce[thr_id][1];
work->nonces[1] = pdata[21];
if (bn_hash_target_ratio(vhash64, ptarget) > work->shareratio[0]){
work_set_target_ratio(work, vhash64);
xchg(pdata[19],pdata[21]);
xchg(work->nonces[ 0],work->nonces[ 1]);
}
rc=2;
}
return rc;
} else {
gpulog(LOG_WARNING, thr_id, "result for %08x does not validate on CPU!", h_resNonce[thr_id][0]);
cudaMemset(d_resNonce[thr_id], 0xff, NBN*sizeof(uint32_t));
}
}
pdata[19] += throughput;
} while (!work_restart[thr_id].restart && (uint64_t)max_nonce > (uint64_t)throughput + (uint64_t)pdata[19]);
*hashes_done = pdata[19] - first_nonce + 1;
return rc;
}
// cleanup
void free_myriad(int thr_id){
if (!init[thr_id])
return;
cudaDeviceSynchronize();
cudaFreeHost(h_resNonce[thr_id]);
cudaFree(d_resNonce[thr_id]);
myriadgroestl_cpu_free(thr_id);
init[thr_id] = false;
cudaDeviceSynchronize();
}