diff --git a/Makefile.am b/Makefile.am
index 8f33d48728..5d5652ce15 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -81,7 +81,7 @@ ccminer_SOURCES = elist.h miner.h compat.h \
x16/cuda_x16_shabal512.cu x16/cuda_x16_simd512_80.cu \
x16/cuda_x16_echo512_64.cu \
x17/x17.cu x17/hmq17.cu x17/cuda_x17_haval256.cu x17/cuda_x17_sha512.cu \
- x11/phi.cu x11/cuda_streebog_maxwell.cu \
+ phi/phi.cu phi/phi2.cu phi/cuda_phi2.cu x11/cuda_streebog_maxwell.cu \
x11/c11.cu x11/s3.cu x11/sib.cu x11/veltor.cu x11/cuda_streebog.cu
# scrypt
diff --git a/algos.h b/algos.h
index f141086db8..229d8e98a4 100644
--- a/algos.h
+++ b/algos.h
@@ -39,6 +39,7 @@ enum sha_algos {
ALGO_NIST5,
ALGO_PENTABLAKE,
ALGO_PHI,
+ ALGO_PHI2,
ALGO_POLYTIMOS,
ALGO_QUARK,
ALGO_QUBIT,
@@ -112,6 +113,7 @@ static const char *algo_names[] = {
"nist5",
"penta",
"phi",
+ "phi2",
"polytimos",
"quark",
"qubit",
diff --git a/ccminer.cpp b/ccminer.cpp
index a48b194b5b..c1567a1b50 100644
--- a/ccminer.cpp
+++ b/ccminer.cpp
@@ -269,7 +269,8 @@ Options:\n\
neoscrypt FeatherCoin, Phoenix, UFO...\n\
nist5 NIST5 (TalkCoin)\n\
penta Pentablake hash (5x Blake 512)\n\
- phi BHCoin\n\
+ phi LUX initial algo\n\
+ phi2 LUX v2 with lyra2\n\
polytimos Politimos\n\
quark Quark\n\
qubit Qubit\n\
@@ -1708,6 +1709,7 @@ static bool stratum_gen_work(struct stratum_ctx *sctx, struct work *work)
case ALGO_LBRY:
case ALGO_LYRA2v2:
case ALGO_LYRA2Z:
+ case ALGO_PHI2:
case ALGO_TIMETRAVEL:
case ALGO_BITCORE:
case ALGO_X16R:
@@ -2245,6 +2247,7 @@ static void *miner_thread(void *userdata)
case ALGO_HSR:
case ALGO_LYRA2v2:
case ALGO_PHI:
+ case ALGO_PHI2:
case ALGO_POLYTIMOS:
case ALGO_S3:
case ALGO_SKUNK:
@@ -2436,6 +2439,9 @@ static void *miner_thread(void *userdata)
case ALGO_PHI:
rc = scanhash_phi(thr_id, &work, max_nonce, &hashes_done);
break;
+ case ALGO_PHI2:
+ rc = scanhash_phi2(thr_id, &work, max_nonce, &hashes_done);
+ break;
case ALGO_POLYTIMOS:
rc = scanhash_polytimos(thr_id, &work, max_nonce, &hashes_done);
break;
diff --git a/ccminer.vcxproj b/ccminer.vcxproj
index 1db063e2fd..f20449a513 100644
--- a/ccminer.vcxproj
+++ b/ccminer.vcxproj
@@ -525,6 +525,7 @@
+
@@ -537,6 +538,9 @@
48
+
+
+
compute_50,sm_50;compute_52,sm_52
@@ -567,7 +571,6 @@
-
diff --git a/ccminer.vcxproj.filters b/ccminer.vcxproj.filters
index b2ee4535d5..96220ae43c 100644
--- a/ccminer.vcxproj.filters
+++ b/ccminer.vcxproj.filters
@@ -115,7 +115,10 @@
{1e548d79-c217-4203-989a-a592fe2b2de3}
-
+
+ {311e8d79-1612-4f0f-8591-23a592f2b2d3}
+
+
{xde48d89-fx12-1323-129a-b592fe2b2de3}
@@ -545,6 +548,9 @@
Source Files\CUDA\lyra2
+
+ Source Files\CUDA\lyra2
+
Source Files\CUDA\lyra2
@@ -781,6 +787,15 @@
Source Files\CUDA
+
+ Source Files\CUDA\phi
+
+
+ Source Files\CUDA\phi
+
+
+ Source Files\CUDA\phi
+
Source Files\CUDA\skunk
@@ -799,9 +814,6 @@
Source Files\CUDA\tribus
-
- Source Files\CUDA\x11
-
Source Files\CUDA\x11
diff --git a/lyra2/cuda_lyra2.cu b/lyra2/cuda_lyra2.cu
index a2802001e2..5cdb6ee3a3 100644
--- a/lyra2/cuda_lyra2.cu
+++ b/lyra2/cuda_lyra2.cu
@@ -1,6 +1,7 @@
/**
* Lyra2 (v1) cuda implementation based on djm34 work
* tpruvot@github 2015, Nanashi 08/2016 (from 1.8-r2)
+ * tpruvot@github 2018 for phi2 double lyra2-32 support
*/
#include
@@ -228,9 +229,7 @@ void reduceDuplex(uint2 state[4], uint32_t thread, const uint32_t threads)
{
uint2 state1[3];
-#if __CUDA_ARCH__ > 500
-#pragma unroll
-#endif
+ #pragma unroll
for (int i = 0; i < Nrow; i++)
{
ST4S(0, Ncol - i - 1, state, thread, threads);
@@ -305,7 +304,7 @@ void reduceDuplexRowt(const int rowIn, const int rowInOut, const int rowOut, uin
LD4S(state1, rowIn, i, thread, threads);
LD4S(state2, rowInOut, i, thread, threads);
-#pragma unroll
+ #pragma unroll
for (int j = 0; j < 3; j++)
state[j] ^= state1[j] + state2[j];
@@ -334,7 +333,7 @@ void reduceDuplexRowt(const int rowIn, const int rowInOut, const int rowOut, uin
LD4S(state1, rowOut, i, thread, threads);
-#pragma unroll
+ #pragma unroll
for (int j = 0; j < 3; j++)
state1[j] ^= state[j];
@@ -412,11 +411,9 @@ __global__ __launch_bounds__(64, 1)
void lyra2_gpu_hash_32_1(uint32_t threads, uint2 *g_hash)
{
const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
-
if (thread < threads)
{
uint2x4 state[4];
-
state[0].x = state[1].x = __ldg(&g_hash[thread + threads * 0]);
state[0].y = state[1].y = __ldg(&g_hash[thread + threads * 1]);
state[0].z = state[1].z = __ldg(&g_hash[thread + threads * 2]);
@@ -436,10 +433,9 @@ void lyra2_gpu_hash_32_1(uint32_t threads, uint2 *g_hash)
__global__
__launch_bounds__(TPB52, 1)
-void lyra2_gpu_hash_32_2(uint32_t threads, uint64_t *g_hash)
+void lyra2_gpu_hash_32_2(const uint32_t threads, uint64_t *g_hash)
{
const uint32_t thread = blockDim.y * blockIdx.x + threadIdx.y;
-
if (thread < threads)
{
uint2 state[4];
@@ -484,11 +480,9 @@ __global__ __launch_bounds__(64, 1)
void lyra2_gpu_hash_32_3(uint32_t threads, uint2 *g_hash)
{
const uint32_t thread = blockDim.x * blockIdx.x + threadIdx.x;
-
- uint28 state[4];
-
if (thread < threads)
{
+ uint2x4 state[4];
state[0] = __ldg4(&((uint2x4*)DMatrix)[threads * 0 + thread]);
state[1] = __ldg4(&((uint2x4*)DMatrix)[threads * 1 + thread]);
state[2] = __ldg4(&((uint2x4*)DMatrix)[threads * 2 + thread]);
@@ -501,7 +495,57 @@ void lyra2_gpu_hash_32_3(uint32_t threads, uint2 *g_hash)
g_hash[thread + threads * 1] = state[0].y;
g_hash[thread + threads * 2] = state[0].z;
g_hash[thread + threads * 3] = state[0].w;
+ }
+}
+
+__global__ __launch_bounds__(64, 1)
+void lyra2_gpu_hash_64_1(uint32_t threads, uint2* const d_hash_512, const uint32_t round)
+{
+ const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
+ if (thread < threads)
+ {
+ uint2x4 state[4];
+ const size_t offset = (size_t)8 * thread + (round * 4U);
+ uint2 *psrc = (uint2*)(&d_hash_512[offset]);
+ state[0].x = state[1].x = __ldg(&psrc[0]);
+ state[0].y = state[1].y = __ldg(&psrc[1]);
+ state[0].z = state[1].z = __ldg(&psrc[2]);
+ state[0].w = state[1].w = __ldg(&psrc[3]);
+ state[2] = blake2b_IV[0];
+ state[3] = blake2b_IV[1];
+ for (int i = 0; i<24; i++)
+ round_lyra(state);
+
+ ((uint2x4*)DMatrix)[threads * 0 + thread] = state[0];
+ ((uint2x4*)DMatrix)[threads * 1 + thread] = state[1];
+ ((uint2x4*)DMatrix)[threads * 2 + thread] = state[2];
+ ((uint2x4*)DMatrix)[threads * 3 + thread] = state[3];
+ }
+}
+
+__global__ __launch_bounds__(64, 1)
+void lyra2_gpu_hash_64_3(uint32_t threads, uint2 *d_hash_512, const uint32_t round)
+{
+ // This kernel outputs 2x 256-bits hashes in 512-bits chain offsets in 2 rounds
+ const uint32_t thread = blockDim.x * blockIdx.x + threadIdx.x;
+ if (thread < threads)
+ {
+ uint2x4 state[4];
+ state[0] = __ldg4(&((uint2x4*)DMatrix)[threads * 0 + thread]);
+ state[1] = __ldg4(&((uint2x4*)DMatrix)[threads * 1 + thread]);
+ state[2] = __ldg4(&((uint2x4*)DMatrix)[threads * 2 + thread]);
+ state[3] = __ldg4(&((uint2x4*)DMatrix)[threads * 3 + thread]);
+
+ for (int i = 0; i < 12; i++)
+ round_lyra(state);
+
+ const size_t offset = (size_t)8 * thread + (round * 4U);
+ uint2 *pdst = (uint2*)(&d_hash_512[offset]);
+ pdst[0] = state[0].x;
+ pdst[1] = state[0].y;
+ pdst[2] = state[0].z;
+ pdst[3] = state[0].w;
}
}
#else
@@ -513,6 +557,8 @@ __device__ void* DMatrix;
__global__ void lyra2_gpu_hash_32_1(uint32_t threads, uint2 *g_hash) {}
__global__ void lyra2_gpu_hash_32_2(uint32_t threads, uint64_t *g_hash) {}
__global__ void lyra2_gpu_hash_32_3(uint32_t threads, uint2 *g_hash) {}
+__global__ void lyra2_gpu_hash_64_1(uint32_t threads, uint2* const d_hash_512, const uint32_t round) {}
+__global__ void lyra2_gpu_hash_64_3(uint32_t threads, uint2 *d_hash_512, const uint32_t round) {}
#endif
__host__
@@ -545,9 +591,7 @@ void lyra2_cpu_hash_32(int thr_id, uint32_t threads, uint64_t *d_hash, bool gtx7
if (cuda_arch[dev_id] >= 520)
{
lyra2_gpu_hash_32_1 <<< grid2, block2 >>> (threads, (uint2*)d_hash);
-
lyra2_gpu_hash_32_2 <<< grid1, block1, 24 * (8 - 0) * sizeof(uint2) * tpb >>> (threads, d_hash);
-
lyra2_gpu_hash_32_3 <<< grid2, block2 >>> (threads, (uint2*)d_hash);
}
else if (cuda_arch[dev_id] >= 500)
@@ -562,11 +606,57 @@ void lyra2_cpu_hash_32(int thr_id, uint32_t threads, uint64_t *d_hash, bool gtx7
shared_mem = 6144;
lyra2_gpu_hash_32_1_sm5 <<< grid2, block2 >>> (threads, (uint2*)d_hash);
-
lyra2_gpu_hash_32_2_sm5 <<< grid1, block1, shared_mem >>> (threads, (uint2*)d_hash);
-
lyra2_gpu_hash_32_3_sm5 <<< grid2, block2 >>> (threads, (uint2*)d_hash);
}
else
lyra2_gpu_hash_32_sm2 <<< grid3, block3 >>> (threads, d_hash);
}
+
+__host__
+void lyra2_cuda_hash_64(int thr_id, const uint32_t threads, uint64_t* d_hash_256, uint32_t* d_hash_512, bool gtx750ti)
+{
+ int dev_id = device_map[thr_id % MAX_GPUS];
+ uint32_t tpb = TPB52;
+ if (cuda_arch[dev_id] >= 520) tpb = TPB52;
+ else if (cuda_arch[dev_id] >= 500) tpb = TPB50;
+ else if (cuda_arch[dev_id] >= 200) tpb = TPB20;
+
+ dim3 grid1((size_t(threads) * 4 + tpb - 1) / tpb);
+ dim3 block1(4, tpb >> 2);
+
+ dim3 grid2((threads + 64 - 1) / 64);
+ dim3 block2(64);
+
+ if (cuda_arch[dev_id] >= 520)
+ {
+ const size_t shared_mem = sizeof(uint2) * tpb * 192; // 49152;
+ lyra2_gpu_hash_64_1 <<< grid2, block2 >>> (threads, (uint2*)d_hash_512, 0);
+ lyra2_gpu_hash_32_2 <<< grid1, block1, shared_mem >>> (threads, d_hash_256);
+ lyra2_gpu_hash_64_3 <<< grid2, block2 >>> (threads, (uint2*)d_hash_512, 0);
+
+ lyra2_gpu_hash_64_1 <<< grid2, block2 >>> (threads, (uint2*)d_hash_512, 1);
+ lyra2_gpu_hash_32_2 <<< grid1, block1, shared_mem >>> (threads, d_hash_256);
+ lyra2_gpu_hash_64_3 <<< grid2, block2 >>> (threads, (uint2*)d_hash_512, 1);
+ }
+ else if (cuda_arch[dev_id] >= 500)
+ {
+ size_t shared_mem = gtx750ti ? 8192 : 6144; // 8 or 10 warps
+ lyra2_gpu_hash_64_1_sm5 <<< grid2, block2 >>> (threads, (uint2*)d_hash_512, 0);
+ lyra2_gpu_hash_32_2_sm5 <<< grid1, block1, shared_mem >>> (threads, (uint2*)d_hash_256);
+ lyra2_gpu_hash_64_3_sm5 <<< grid2, block2 >>> (threads, (uint2*)d_hash_512, 0);
+
+ lyra2_gpu_hash_64_1_sm5 <<< grid2, block2 >>> (threads, (uint2*)d_hash_512, 1);
+ lyra2_gpu_hash_32_2_sm5 <<< grid1, block1, shared_mem >>> (threads, (uint2*)d_hash_256);
+ lyra2_gpu_hash_64_3_sm5 <<< grid2, block2 >>> (threads, (uint2*)d_hash_512, 1);
+ }
+ else {
+ // alternative method for SM 3.x
+ hash64_to_lyra32(thr_id, threads, d_hash_512, d_hash_256, 0);
+ lyra2_cpu_hash_32(thr_id, threads, d_hash_256, gtx750ti);
+ hash64_from_lyra32(thr_id, threads, d_hash_512, d_hash_256, 0);
+ hash64_to_lyra32(thr_id, threads, d_hash_512, d_hash_256, 1);
+ lyra2_cpu_hash_32(thr_id, threads, d_hash_256, gtx750ti);
+ hash64_from_lyra32(thr_id, threads, d_hash_512, d_hash_256, 1);
+ }
+}
diff --git a/lyra2/cuda_lyra2_sm2.cuh b/lyra2/cuda_lyra2_sm2.cuh
index da621d021a..cc0bd82d76 100644
--- a/lyra2/cuda_lyra2_sm2.cuh
+++ b/lyra2/cuda_lyra2_sm2.cuh
@@ -3,7 +3,7 @@
#ifdef __INTELLISENSE__
/* just for vstudio code colors, only uncomment that temporary, dont commit it */
//#undef __CUDA_ARCH__
-//#define __CUDA_ARCH__ 500
+//#define __CUDA_ARCH__ 300
#endif
#include "cuda_helper.h"
@@ -226,3 +226,66 @@ void lyra2_gpu_hash_32_sm2(uint32_t threads, uint64_t *g_hash)
/* if __CUDA_ARCH__ < 200 .. host */
__global__ void lyra2_gpu_hash_32_sm2(uint32_t threads, uint64_t *g_hash) {}
#endif
+
+// -------------------------------------------------------------------------------------------------------------------------
+
+// lyra2 cant be used as-is in 512-bits hash chains, tx to djm for these weird offsets since first lyra2 algo...
+
+#if __CUDA_ARCH__ >= 200 && __CUDA_ARCH__ <= 350
+
+__global__ __launch_bounds__(128, 8)
+void hash64_to_lyra32_gpu(const uint32_t threads, const uint32_t* d_hash64, uint2* d_hash_lyra, const uint32_t round)
+{
+ const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
+ if (thread < threads)
+ {
+ const size_t offset = (size_t) 16 * thread + (round * 8U);
+ uint2 *psrc = (uint2*) (&d_hash64[offset]);
+ uint2 *pdst = (uint2*) (&d_hash_lyra[thread]);
+ pdst[threads*0] = __ldg(&psrc[0]);
+ pdst[threads*1] = __ldg(&psrc[1]);
+ pdst[threads*2] = __ldg(&psrc[2]);
+ pdst[threads*3] = __ldg(&psrc[3]);
+ }
+}
+
+__global__ __launch_bounds__(128, 8)
+void hash64_from_lyra32_gpu(const uint32_t threads, const uint32_t* d_hash64, uint2* d_hash_lyra, const uint32_t round)
+{
+ const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
+ if (thread < threads)
+ {
+ const size_t offset = (size_t) 16 * thread + (round * 8U);
+ uint2 *psrc = (uint2*) (&d_hash_lyra[thread]);
+ uint2 *pdst = (uint2*) (&d_hash64[offset]);
+ pdst[0] = psrc[0];
+ pdst[1] = psrc[threads*1];
+ pdst[2] = psrc[threads*2];
+ pdst[3] = psrc[threads*3];
+ }
+}
+#else
+/* if __CUDA_ARCH__ < 200 .. host */
+__global__ void hash64_to_lyra32_gpu(const uint32_t threads, const uint32_t* d_hash64, uint2* d_hash_lyra, const uint32_t round) {}
+__global__ void hash64_from_lyra32_gpu(const uint32_t threads, const uint32_t* d_hash64, uint2* d_hash_lyra, const uint32_t round) {}
+#endif
+
+__host__
+void hash64_to_lyra32(int thr_id, const uint32_t threads, uint32_t* d_hash64, uint64_t* d_hash_lyra, const uint32_t round)
+{
+ const uint32_t threadsperblock = 128;
+ dim3 grid((threads + threadsperblock - 1) / threadsperblock);
+ dim3 block(threadsperblock);
+
+ hash64_to_lyra32_gpu <<>> (threads, d_hash64, (uint2*) d_hash_lyra, round);
+}
+
+__host__
+void hash64_from_lyra32(int thr_id, const uint32_t threads, uint32_t* d_hash64, uint64_t* d_hash_lyra, const uint32_t round)
+{
+ const uint32_t threadsperblock = 128;
+ dim3 grid((threads + threadsperblock - 1) / threadsperblock);
+ dim3 block(threadsperblock);
+
+ hash64_from_lyra32_gpu <<>> (threads, d_hash64, (uint2*) d_hash_lyra, round);
+}
diff --git a/lyra2/cuda_lyra2_sm5.cuh b/lyra2/cuda_lyra2_sm5.cuh
index 4a3caebbac..85adfd91fc 100644
--- a/lyra2/cuda_lyra2_sm5.cuh
+++ b/lyra2/cuda_lyra2_sm5.cuh
@@ -591,13 +591,12 @@ void reduceDuplexRowV50_8(const int rowInOut, uint2 state[4], const uint32_t thr
__global__ __launch_bounds__(64, 1)
void lyra2_gpu_hash_32_1_sm5(uint32_t threads, uint2 *g_hash)
{
- const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
-
const uint2x4 blake2b_IV[2] = {
{ { 0xf3bcc908, 0x6a09e667 }, { 0x84caa73b, 0xbb67ae85 }, { 0xfe94f82b, 0x3c6ef372 }, { 0x5f1d36f1, 0xa54ff53a } },
{ { 0xade682d1, 0x510e527f }, { 0x2b3e6c1f, 0x9b05688c }, { 0xfb41bd6b, 0x1f83d9ab }, { 0x137e2179, 0x5be0cd19 } }
};
+ const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
if (thread < threads)
{
uint2x4 state[4];
@@ -629,7 +628,6 @@ void lyra2_gpu_hash_32_2_sm5(uint32_t threads, uint2 *g_hash)
if (thread < threads)
{
uint2 state[4];
-
state[0] = __ldg(&DMatrix[(0 * threads + thread)*blockDim.x + threadIdx.x]);
state[1] = __ldg(&DMatrix[(1 * threads + thread)*blockDim.x + threadIdx.x]);
state[2] = __ldg(&DMatrix[(2 * threads + thread)*blockDim.x + threadIdx.x]);
@@ -669,7 +667,6 @@ void lyra2_gpu_hash_32_3_sm5(uint32_t threads, uint2 *g_hash)
if (thread < threads)
{
uint2x4 state[4];
-
state[0] = __ldg4(&((uint2x4*)DMatrix)[0 * threads + thread]);
state[1] = __ldg4(&((uint2x4*)DMatrix)[1 * threads + thread]);
state[2] = __ldg4(&((uint2x4*)DMatrix)[2 * threads + thread]);
@@ -685,9 +682,68 @@ void lyra2_gpu_hash_32_3_sm5(uint32_t threads, uint2 *g_hash)
}
}
+__global__ __launch_bounds__(64, 1)
+void lyra2_gpu_hash_64_1_sm5(uint32_t threads, uint2* const d_hash_512, const uint32_t round)
+{
+ const uint2x4 blake2b_IV[2] = {
+ { { 0xf3bcc908, 0x6a09e667 }, { 0x84caa73b, 0xbb67ae85 }, { 0xfe94f82b, 0x3c6ef372 }, { 0x5f1d36f1, 0xa54ff53a } },
+ { { 0xade682d1, 0x510e527f }, { 0x2b3e6c1f, 0x9b05688c }, { 0xfb41bd6b, 0x1f83d9ab }, { 0x137e2179, 0x5be0cd19 } }
+ };
+ // This kernel loads 2x 256-bits hashes from 512-bits chain offsets in 2 steps
+ const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
+ if (thread < threads)
+ {
+ uint2x4 state[4];
+ const size_t offset = (size_t)8 * thread + (round * 4U);
+ uint2 *psrc = (uint2*)(&d_hash_512[offset]);
+ state[0].x = state[1].x = __ldg(&psrc[0]);
+ state[0].y = state[1].y = __ldg(&psrc[1]);
+ state[0].z = state[1].z = __ldg(&psrc[2]);
+ state[0].w = state[1].w = __ldg(&psrc[3]);
+
+ state[1] = state[0];
+ state[2] = blake2b_IV[0];
+ state[3] = blake2b_IV[1];
+
+ for (int i = 0; i<24; i++)
+ round_lyra(state);
+
+ ((uint2x4*)DMatrix)[threads * 0 + thread] = state[0];
+ ((uint2x4*)DMatrix)[threads * 1 + thread] = state[1];
+ ((uint2x4*)DMatrix)[threads * 2 + thread] = state[2];
+ ((uint2x4*)DMatrix)[threads * 3 + thread] = state[3];
+ }
+}
+
+__global__ __launch_bounds__(64, 1)
+void lyra2_gpu_hash_64_3_sm5(uint32_t threads, uint2 *d_hash_512, const uint32_t round)
+{
+ // This kernel outputs 2x 256-bits hashes in 512-bits chain offsets in 2 steps
+ const uint32_t thread = blockDim.x * blockIdx.x + threadIdx.x;
+ if (thread < threads)
+ {
+ uint2x4 state[4];
+ state[0] = __ldg4(&((uint2x4*)DMatrix)[threads * 0 + thread]);
+ state[1] = __ldg4(&((uint2x4*)DMatrix)[threads * 1 + thread]);
+ state[2] = __ldg4(&((uint2x4*)DMatrix)[threads * 2 + thread]);
+ state[3] = __ldg4(&((uint2x4*)DMatrix)[threads * 3 + thread]);
+
+ for (int i = 0; i < 12; i++)
+ round_lyra(state);
+
+ const size_t offset = (size_t)8 * thread + (round * 4U);
+ uint2 *pdst = (uint2*)(&d_hash_512[offset]);
+ pdst[0] = state[0].x;
+ pdst[1] = state[0].y;
+ pdst[2] = state[0].z;
+ pdst[3] = state[0].w;
+ }
+}
#else
/* if __CUDA_ARCH__ != 500 .. host */
__global__ void lyra2_gpu_hash_32_1_sm5(uint32_t threads, uint2 *g_hash) {}
__global__ void lyra2_gpu_hash_32_2_sm5(uint32_t threads, uint2 *g_hash) {}
__global__ void lyra2_gpu_hash_32_3_sm5(uint32_t threads, uint2 *g_hash) {}
+__global__ void lyra2_gpu_hash_64_1_sm5(uint32_t threads, uint2* const d_hash_512, const uint32_t round) {}
+__global__ void lyra2_gpu_hash_64_3_sm5(uint32_t threads, uint2 *d_hash_512, const uint32_t round) {}
#endif
diff --git a/miner.h b/miner.h
index 16f57ab9de..d3118dca79 100644
--- a/miner.h
+++ b/miner.h
@@ -303,6 +303,7 @@ extern int scanhash_neoscrypt(int thr_id, struct work *work, uint32_t max_nonce,
extern int scanhash_nist5(int thr_id, struct work *work, uint32_t max_nonce, unsigned long *hashes_done);
extern int scanhash_pentablake(int thr_id, struct work *work, uint32_t max_nonce, unsigned long *hashes_done);
extern int scanhash_phi(int thr_id, struct work* work, uint32_t max_nonce, unsigned long *hashes_done);
+extern int scanhash_phi2(int thr_id, struct work* work, uint32_t max_nonce, unsigned long *hashes_done);
extern int scanhash_polytimos(int thr_id, struct work* work, uint32_t max_nonce, unsigned long *hashes_done);
extern int scanhash_quark(int thr_id, struct work *work, uint32_t max_nonce, unsigned long *hashes_done);
extern int scanhash_qubit(int thr_id, struct work* work, uint32_t max_nonce, unsigned long *hashes_done);
@@ -371,6 +372,7 @@ extern void free_neoscrypt(int thr_id);
extern void free_nist5(int thr_id);
extern void free_pentablake(int thr_id);
extern void free_phi(int thr_id);
+extern void free_phi2(int thr_id);
extern void free_polytimos(int thr_id);
extern void free_quark(int thr_id);
extern void free_qubit(int thr_id);
@@ -918,7 +920,8 @@ void myriadhash(void *state, const void *input);
void neoscrypt(uchar *output, const uchar *input, uint32_t profile);
void nist5hash(void *state, const void *input);
void pentablakehash(void *output, const void *input);
-void phihash(void *output, const void *input);
+void phi_hash(void *output, const void *input);
+void phi2_hash(void *output, const void *input);
void polytimos_hash(void *output, const void *input);
void quarkhash(void *state, const void *input);
void qubithash(void *state, const void *input);
diff --git a/phi/cuda_phi2.cu b/phi/cuda_phi2.cu
new file mode 100644
index 0000000000..a0bcf6d42f
--- /dev/null
+++ b/phi/cuda_phi2.cu
@@ -0,0 +1,89 @@
+#include
+#include
+
+#include "cuda_helper.h"
+
+__global__ __launch_bounds__(128, 8)
+void phi_filter_gpu(const uint32_t threads, const uint32_t* d_hash, uint32_t* d_branch2, uint32_t* d_NonceBranch)
+{
+ const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
+ if (thread < threads)
+ {
+ const uint32_t offset = thread * 16U; // 64U / sizeof(uint32_t);
+ uint4 *psrc = (uint4*) (&d_hash[offset]);
+ d_NonceBranch[thread] = ((uint8_t*)psrc)[0] & 1;
+ if (d_NonceBranch[thread]) return;
+ if (d_branch2) {
+ uint4 *pdst = (uint4*)(&d_branch2[offset]);
+ uint4 data;
+ data = psrc[0]; pdst[0] = data;
+ data = psrc[1]; pdst[1] = data;
+ data = psrc[2]; pdst[2] = data;
+ data = psrc[3]; pdst[3] = data;
+ }
+ }
+}
+
+__global__ __launch_bounds__(128, 8)
+void phi_merge_gpu(const uint32_t threads, uint32_t* d_hash, uint32_t* d_branch2, uint32_t* const d_NonceBranch)
+{
+ const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
+ if (thread < threads && !d_NonceBranch[thread])
+ {
+ const uint32_t offset = thread * 16U;
+ uint4 *psrc = (uint4*) (&d_branch2[offset]);
+ uint4 *pdst = (uint4*) (&d_hash[offset]);
+ uint4 data;
+ data = psrc[0]; pdst[0] = data;
+ data = psrc[1]; pdst[1] = data;
+ data = psrc[2]; pdst[2] = data;
+ data = psrc[3]; pdst[3] = data;
+ }
+}
+
+__global__
+void phi_final_compress_gpu(const uint32_t threads, uint32_t* d_hash)
+{
+ const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
+ if (thread < threads)
+ {
+ const uint32_t offset = thread * 16U;
+ uint2 *psrc = (uint2*) (&d_hash[offset]);
+ uint2 *pdst = (uint2*) (&d_hash[offset]);
+ uint2 data;
+ data = psrc[4]; pdst[0] ^= data;
+ data = psrc[5]; pdst[1] ^= data;
+ data = psrc[6]; pdst[2] ^= data;
+ data = psrc[7]; pdst[3] ^= data;
+ }
+}
+
+__host__
+uint32_t phi_filter_cuda(const int thr_id, const uint32_t threads, const uint32_t *inpHashes, uint32_t* d_br2, uint32_t* d_nonces)
+{
+ const uint32_t threadsperblock = 128;
+ dim3 grid((threads + threadsperblock - 1) / threadsperblock);
+ dim3 block(threadsperblock);
+ // extract algo permution hashes to a second branch buffer
+ phi_filter_gpu <<>> (threads, inpHashes, d_br2, d_nonces);
+ return threads;
+}
+
+__host__
+void phi_merge_cuda(const int thr_id, const uint32_t threads, uint32_t *outpHashes, uint32_t* d_br2, uint32_t* d_nonces)
+{
+ const uint32_t threadsperblock = 128;
+ dim3 grid((threads + threadsperblock - 1) / threadsperblock);
+ dim3 block(threadsperblock);
+ // put back second branch hashes to the common buffer d_hash
+ phi_merge_gpu <<>> (threads, outpHashes, d_br2, d_nonces);
+}
+
+__host__
+void phi_final_compress_cuda(const int thr_id, const uint32_t threads, uint32_t *d_hashes)
+{
+ const uint32_t threadsperblock = 128;
+ dim3 grid((threads + threadsperblock - 1) / threadsperblock);
+ dim3 block(threadsperblock);
+ phi_final_compress_gpu <<>> (threads, d_hashes);
+}
diff --git a/x11/phi.cu b/phi/phi.cu
similarity index 97%
rename from x11/phi.cu
rename to phi/phi.cu
index ab1f30833c..ba2a9677b6 100644
--- a/x11/phi.cu
+++ b/phi/phi.cu
@@ -19,7 +19,7 @@ extern "C" {
#include "miner.h"
#include "cuda_helper.h"
-#include "cuda_x11.h"
+#include "x11/cuda_x11.h"
extern void skein512_cpu_setBlock_80(void *pdata);
extern void skein512_cpu_hash_80(int thr_id, uint32_t threads, uint32_t startNonce, uint32_t *d_hash, int swap);
@@ -38,7 +38,7 @@ extern void tribus_echo512_final(int thr_id, uint32_t threads, uint32_t *d_hash,
static uint32_t *d_hash[MAX_GPUS];
static uint32_t *d_resNonce[MAX_GPUS];
-extern "C" void phihash(void *output, const void *input)
+extern "C" void phi_hash(void *output, const void *input)
{
unsigned char _ALIGN(128) hash[128] = { 0 };
@@ -162,7 +162,7 @@ extern "C" int scanhash_phi(int thr_id, struct work* work, uint32_t max_nonce, u
uint32_t _ALIGN(64) vhash[8];
if (!use_compat_kernels[thr_id]) work->nonces[0] += startNonce;
be32enc(&endiandata[19], work->nonces[0]);
- phihash(vhash, endiandata);
+ phi_hash(vhash, endiandata);
if (vhash[7] <= Htarg && fulltest(vhash, ptarget)) {
work->valid_nonces = 1;
@@ -173,7 +173,7 @@ extern "C" int scanhash_phi(int thr_id, struct work* work, uint32_t max_nonce, u
if (work->nonces[1] != UINT32_MAX) {
work->nonces[1] += startNonce;
be32enc(&endiandata[19], work->nonces[1]);
- phihash(vhash, endiandata);
+ phi_hash(vhash, endiandata);
bn_set_target_ratio(work, vhash, 1);
work->valid_nonces++;
pdata[19] = max(work->nonces[0], work->nonces[1]) + 1;
diff --git a/phi/phi2.cu b/phi/phi2.cu
new file mode 100644
index 0000000000..537217fb16
--- /dev/null
+++ b/phi/phi2.cu
@@ -0,0 +1,255 @@
+//
+// PHI2 algo
+// CubeHash + Lyra2 x2 + JH + Gost or Echo + Skein
+//
+// Implemented by tpruvot in May 2018
+//
+
+extern "C" {
+#include "sph/sph_skein.h"
+#include "sph/sph_jh.h"
+#include "sph/sph_cubehash.h"
+#include "sph/sph_streebog.h"
+#include "sph/sph_echo.h"
+#include "lyra2/Lyra2.h"
+}
+
+#include "miner.h"
+#include "cuda_helper.h"
+#include "x11/cuda_x11.h"
+
+#include
+#include
+
+extern void cubehash512_setBlock_80(int thr_id, uint32_t* endiandata);
+extern void cubehash512_cuda_hash_80(const int thr_id, const uint32_t threads, const uint32_t startNounce, uint32_t *d_hash);
+
+extern void lyra2_cpu_init(int thr_id, uint32_t threads, uint64_t *d_matrix);
+extern void lyra2_cuda_hash_64(int thr_id, const uint32_t threads, uint64_t* d_hash_256, uint32_t* d_hash_512, bool gtx750ti);
+
+extern void streebog_cpu_hash_64(int thr_id, uint32_t threads, uint32_t *d_hash);
+extern void phi_streebog_hash_64_filtered(int thr_id, const uint32_t threads, uint32_t *g_hash, uint32_t *d_filter);
+extern void phi_echo512_cpu_hash_64_filtered(int thr_id, const uint32_t threads, uint32_t* g_hash, uint32_t* d_filter);
+
+extern uint32_t phi_filter_cuda(const int thr_id, const uint32_t threads, const uint32_t *inpHashes, uint32_t* d_br2, uint32_t* d_nonces);
+extern void phi_merge_cuda(const int thr_id, const uint32_t threads, uint32_t *outpHashes, uint32_t* d_br2, uint32_t* d_nonces);
+extern void phi_final_compress_cuda(const int thr_id, const uint32_t threads, uint32_t *d_hashes);
+
+static uint64_t* d_matrix[MAX_GPUS];
+static uint32_t* d_hash_512[MAX_GPUS];
+static uint64_t* d_hash_256[MAX_GPUS];
+static uint32_t* d_hash_br2[MAX_GPUS];
+static uint32_t* d_nonce_br[MAX_GPUS];
+
+extern "C" void phi2_hash(void *output, const void *input)
+{
+ unsigned char _ALIGN(128) hash[128] = { 0 };
+ unsigned char _ALIGN(128) hashA[64] = { 0 };
+ unsigned char _ALIGN(128) hashB[64] = { 0 };
+
+ sph_cubehash512_context ctx_cubehash;
+ sph_jh512_context ctx_jh;
+ sph_gost512_context ctx_gost;
+ sph_echo512_context ctx_echo;
+ sph_skein512_context ctx_skein;
+
+ sph_cubehash512_init(&ctx_cubehash);
+ sph_cubehash512(&ctx_cubehash, input, 80);
+ sph_cubehash512_close(&ctx_cubehash, (void*)hashB);
+
+ LYRA2(&hashA[ 0], 32, &hashB[ 0], 32, &hashB[ 0], 32, 1, 8, 8);
+ LYRA2(&hashA[32], 32, &hashB[32], 32, &hashB[32], 32, 1, 8, 8);
+
+ sph_jh512_init(&ctx_jh);
+ sph_jh512(&ctx_jh, (const void*)hashA, 64);
+ sph_jh512_close(&ctx_jh, (void*)hash);
+
+ if (hash[0] & 1) {
+ sph_gost512_init(&ctx_gost);
+ sph_gost512(&ctx_gost, (const void*)hash, 64);
+ sph_gost512_close(&ctx_gost, (void*)hash);
+ } else {
+ sph_echo512_init(&ctx_echo);
+ sph_echo512(&ctx_echo, (const void*)hash, 64);
+ sph_echo512_close(&ctx_echo, (void*)hash);
+
+ sph_echo512_init(&ctx_echo);
+ sph_echo512(&ctx_echo, (const void*)hash, 64);
+ sph_echo512_close(&ctx_echo, (void*)hash);
+ }
+
+ sph_skein512_init(&ctx_skein);
+ sph_skein512(&ctx_skein, (const void*)hash, 64);
+ sph_skein512_close(&ctx_skein, (void*)hash);
+
+ for (int i=0; i<32; i++)
+ hash[i] ^= hash[i+32];
+
+ memcpy(output, hash, 32);
+}
+
+//#define _DEBUG
+#define _DEBUG_PREFIX "phi-"
+#include "cuda_debug.cuh"
+
+static bool init[MAX_GPUS] = { 0 };
+static bool use_compat_kernels[MAX_GPUS] = { 0 };
+static __thread bool gtx750ti = false;
+
+extern "C" int scanhash_phi2(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];
+ const int dev_id = device_map[thr_id];
+
+ int intensity = (device_sm[dev_id] > 500 && !is_windows()) ? 17 : 16;
+ if (device_sm[dev_id] == 500) intensity = 15;
+ if (device_sm[dev_id] == 600) intensity = 17;
+
+ uint32_t throughput = cuda_default_throughput(thr_id, 1U << intensity);
+ if (init[thr_id]) throughput = min(throughput, max_nonce - first_nonce);
+ if (init[thr_id]) throughput = max(throughput & 0xffffff80, 128); // for shared mem
+
+ if (opt_benchmark)
+ ptarget[7] = 0xff;
+
+ if (!init[thr_id])
+ {
+ cudaSetDevice(dev_id);
+ if (opt_cudaschedule == -1 && gpu_threads == 1) {
+ cudaDeviceReset();
+ cudaSetDeviceFlags(cudaDeviceScheduleBlockingSync);
+ }
+ gpulog(LOG_INFO, thr_id, "Intensity set to %g, %u cuda threads", throughput2intensity(throughput), throughput);
+
+ cuda_get_arch(thr_id);
+ use_compat_kernels[thr_id] = (cuda_arch[dev_id] < 500);
+ gtx750ti = (strstr(device_name[dev_id], "GTX 750 Ti") != NULL);
+
+ size_t matrix_sz = device_sm[dev_id] > 500 ? sizeof(uint64_t) * 16 : sizeof(uint64_t) * 8 * 8 * 3 * 4;
+ CUDA_CALL_OR_RET_X(cudaMalloc(&d_matrix[thr_id], matrix_sz * throughput), -1);
+ CUDA_CALL_OR_RET_X(cudaMalloc(&d_hash_256[thr_id], (size_t)32 * throughput), -1);
+ CUDA_CALL_OR_RET_X(cudaMalloc(&d_hash_512[thr_id], (size_t)64 * throughput), -1);
+ CUDA_CALL_OR_RET_X(cudaMalloc(&d_nonce_br[thr_id], sizeof(uint32_t) * throughput), -1);
+ if (use_compat_kernels[thr_id]) {
+ CUDA_CALL_OR_RET_X(cudaMalloc(&d_hash_br2[thr_id], (size_t)64 * throughput), -1);
+ }
+
+ x11_cubehash512_cpu_init(thr_id, throughput);
+ lyra2_cpu_init(thr_id, throughput, d_matrix[thr_id]);
+ quark_jh512_cpu_init(thr_id, throughput);
+ quark_skein512_cpu_init(thr_id, throughput);
+ if (use_compat_kernels[thr_id]) x11_echo512_cpu_init(thr_id, throughput);
+
+ cuda_check_cpu_init(thr_id, throughput);
+ init[thr_id] = true;
+ }
+
+ uint32_t endiandata[20];
+ for (int k = 0; k < 20; k++)
+ be32enc(&endiandata[k], pdata[k]);
+
+ cuda_check_cpu_setTarget(ptarget);
+ cubehash512_setBlock_80(thr_id, endiandata);
+
+ do {
+ int order = 0;
+
+ cubehash512_cuda_hash_80(thr_id, throughput, pdata[19], d_hash_512[thr_id]); order++;
+ TRACE("cube ");
+
+ lyra2_cuda_hash_64(thr_id, throughput, d_hash_256[thr_id], d_hash_512[thr_id], gtx750ti);
+ order++;
+ TRACE("lyra ");
+
+ quark_jh512_cpu_hash_64(thr_id, throughput, pdata[19], NULL, d_hash_512[thr_id], order++);
+ TRACE("jh ");
+
+ order++;
+ if (!use_compat_kernels[thr_id]) {
+ phi_filter_cuda(thr_id, throughput, d_hash_512[thr_id], NULL, d_nonce_br[thr_id]);
+ phi_streebog_hash_64_filtered(thr_id, throughput, d_hash_512[thr_id], d_nonce_br[thr_id]);
+ phi_echo512_cpu_hash_64_filtered(thr_id, throughput, d_hash_512[thr_id], d_nonce_br[thr_id]);
+ phi_echo512_cpu_hash_64_filtered(thr_id, throughput, d_hash_512[thr_id], d_nonce_br[thr_id]);
+ } else {
+ // todo: nonces vector to reduce amount of hashes to compute
+ phi_filter_cuda(thr_id, throughput, d_hash_512[thr_id], d_hash_br2[thr_id], d_nonce_br[thr_id]);
+ streebog_cpu_hash_64(thr_id, throughput, d_hash_512[thr_id]);
+ x11_echo512_cpu_hash_64(thr_id, throughput, pdata[19], NULL, d_hash_br2[thr_id], order);
+ x11_echo512_cpu_hash_64(thr_id, throughput, pdata[19], NULL, d_hash_br2[thr_id], order);
+ phi_merge_cuda(thr_id, throughput, d_hash_512[thr_id], d_hash_br2[thr_id], d_nonce_br[thr_id]);
+ }
+ TRACE("mix ");
+
+ quark_skein512_cpu_hash_64(thr_id, throughput, pdata[19], NULL, d_hash_512[thr_id], order++);
+ TRACE("skein ");
+
+ phi_final_compress_cuda(thr_id, throughput, d_hash_512[thr_id]);
+ TRACE("xor ");
+
+ work->nonces[0] = cuda_check_hash(thr_id, throughput, pdata[19], d_hash_512[thr_id]);
+ if (work->nonces[0] != UINT32_MAX)
+ {
+ const uint32_t Htarg = ptarget[7];
+ uint32_t _ALIGN(64) vhash[8];
+ be32enc(&endiandata[19], work->nonces[0]);
+ phi2_hash(vhash, endiandata);
+
+ if (vhash[7] <= Htarg && fulltest(vhash, ptarget)) {
+ work->valid_nonces = 1;
+ work_set_target_ratio(work, vhash);
+ *hashes_done = pdata[19] - first_nonce + throughput;
+ work->nonces[1] = cuda_check_hash_suppl(thr_id, throughput, pdata[19], d_hash_512[thr_id], 1);
+ if (work->nonces[1] != 0) {
+ be32enc(&endiandata[19], work->nonces[1]);
+ phi2_hash(vhash, endiandata);
+ bn_set_target_ratio(work, vhash, 1);
+ work->valid_nonces++;
+ pdata[19] = max(work->nonces[0], work->nonces[1]) + 1;
+ } else {
+ pdata[19] = work->nonces[0] + 1; // cursor
+ }
+ if (pdata[19] > max_nonce) pdata[19] = max_nonce;
+ return work->valid_nonces;
+ }
+ else if (vhash[7] > Htarg) {
+ gpu_increment_reject(thr_id);
+ if (!opt_quiet)
+ gpulog(LOG_WARNING, thr_id, "result for %08x does not validate on CPU! thr=%x", work->nonces[0], throughput);
+ pdata[19] = work->nonces[0] + 1;
+ continue;
+ }
+ }
+
+ 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_phi2(int thr_id)
+{
+ if (!init[thr_id])
+ return;
+
+ cudaThreadSynchronize();
+ cudaFree(d_matrix[thr_id]);
+ cudaFree(d_hash_512[thr_id]);
+ cudaFree(d_hash_256[thr_id]);
+ cudaFree(d_nonce_br[thr_id]);
+ if (use_compat_kernels[thr_id]) cudaFree(d_hash_br2[thr_id]);
+
+ cuda_check_cpu_free(thr_id);
+ init[thr_id] = false;
+
+ cudaDeviceSynchronize();
+}
diff --git a/util.cpp b/util.cpp
index 70dc6264a5..ee1c1ee415 100644
--- a/util.cpp
+++ b/util.cpp
@@ -2250,7 +2250,7 @@ void print_hash_tests(void)
pentablakehash(&hash[0], &buf[0]);
printpfx("pentablake", hash);
- phihash(&hash[0], &buf[0]);
+ phi2_hash(&hash[0], &buf[0]);
printpfx("phi", hash);
polytimos_hash(&hash[0], &buf[0]);
diff --git a/x11/cuda_streebog_maxwell.cu b/x11/cuda_streebog_maxwell.cu
index 6a06332933..4ff580b15e 100644
--- a/x11/cuda_streebog_maxwell.cu
+++ b/x11/cuda_streebog_maxwell.cu
@@ -207,7 +207,7 @@ __launch_bounds__(TPB, 3)
#else
__launch_bounds__(TPB, 3)
#endif
-void streebog_gpu_hash_64_maxwell(uint64_t *g_hash)
+void streebog_gpu_hash_64_sm5(uint64_t *g_hash, uint32_t* const d_filter, const uint32_t filter_val)
{
const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
uint2 buf[8], t[8], temp[8], K0[8], hash[8];
@@ -222,13 +222,16 @@ void streebog_gpu_hash_64_maxwell(uint64_t *g_hash)
shared[6][threadIdx.x] = __ldg(&T62[threadIdx.x]);
shared[7][threadIdx.x] = __ldg(&T72[threadIdx.x]);
+ //__threadfence_block();
+ __syncthreads();
+
+ if (d_filter && d_filter[thread] != filter_val) return;
+
uint64_t* inout = &g_hash[thread<<3];
*(uint2x4*)&hash[0] = __ldg4((uint2x4*)&inout[0]);
*(uint2x4*)&hash[4] = __ldg4((uint2x4*)&inout[4]);
- __threadfence_block();
-
K0[0] = vectorize(0x74a5d4ce2efc83b3);
#pragma unroll 8
@@ -301,9 +304,17 @@ void streebog_gpu_hash_64_maxwell(uint64_t *g_hash)
}
__host__
-void streebog_hash_64_maxwell(int thr_id, uint32_t threads, uint32_t *d_hash)
+void streebog_hash_64_maxwell(int thr_id, uint32_t threads, uint32_t *g_hash)
+{
+ dim3 grid((threads + TPB-1) / TPB);
+ dim3 block(TPB);
+ streebog_gpu_hash_64_sm5 <<>> ((uint64_t*)g_hash, NULL, 0);
+}
+
+__host__
+void phi_streebog_hash_64_filtered(int thr_id, const uint32_t threads, uint32_t *g_hash, uint32_t *d_filter)
{
dim3 grid((threads + TPB-1) / TPB);
dim3 block(TPB);
- streebog_gpu_hash_64_maxwell <<>> ((uint64_t*)d_hash);
+ streebog_gpu_hash_64_sm5 <<>> ((uint64_t*)g_hash, d_filter, 1);
}
diff --git a/x16/cuda_x16_echo512_64.cu b/x16/cuda_x16_echo512_64.cu
index ac18ff6885..3a0f268725 100644
--- a/x16/cuda_x16_echo512_64.cu
+++ b/x16/cuda_x16_echo512_64.cu
@@ -79,11 +79,12 @@ static void echo_round_alexis(const uint32_t sharedMemory[4][256], uint32_t *W,
}
__global__ __launch_bounds__(128, 5) /* will force 80 registers */
-static void x16_echo512_gpu_hash_64(uint32_t threads, uint32_t *g_hash)
+static void x16_echo512_gpu_hash_64(uint32_t threads, uint32_t* g_hash, uint32_t* const d_filter, const uint32_t filter_val)
{
__shared__ uint32_t sharedMemory[4][256];
aes_gpu_init128(sharedMemory);
+ __syncthreads();
const uint32_t thread = (blockDim.x * blockIdx.x + threadIdx.x);
uint32_t k0;
@@ -91,6 +92,9 @@ static void x16_echo512_gpu_hash_64(uint32_t threads, uint32_t *g_hash)
uint32_t hash[16];
if (thread < threads)
{
+ // phi2 filter (2 hash chain branches)
+ if (d_filter && d_filter[thread] != filter_val) return;
+
uint32_t *Hash = &g_hash[thread<<4];
*(uint2x4*)&h[ 0] = __ldg4((uint2x4*)&Hash[ 0]);
@@ -99,8 +103,6 @@ static void x16_echo512_gpu_hash_64(uint32_t threads, uint32_t *g_hash)
*(uint2x4*)&hash[ 0] = *(uint2x4*)&h[ 0];
*(uint2x4*)&hash[ 8] = *(uint2x4*)&h[ 8];
- __syncthreads();
-
const uint32_t P[48] = {
0xe7e9f5f5, 0xf5e7e9f5, 0xb3b36b23, 0xb3dbe7af, 0xa4213d7e, 0xf5e7e9f5, 0xb3b36b23, 0xb3dbe7af,
//8-12
@@ -217,7 +219,6 @@ static void x16_echo512_gpu_hash_64(uint32_t threads, uint32_t *g_hash)
W[48 + i + 4] = a ^ cd ^ bcx;
W[48 + i + 8] = d ^ ab ^ cdx;
W[48 + i + 12] = c ^ ab ^ abx ^ bcx ^ cdx;
-
}
for (int k = 1; k < 10; k++)
@@ -237,12 +238,23 @@ static void x16_echo512_gpu_hash_64(uint32_t threads, uint32_t *g_hash)
}
__host__
-void x16_echo512_cpu_hash_64(int thr_id, uint32_t threads, uint32_t *d_hash){
-
+void x16_echo512_cpu_hash_64(int thr_id, uint32_t threads, uint32_t *d_hash)
+{
const uint32_t threadsperblock = 128;
dim3 grid((threads + threadsperblock-1)/threadsperblock);
dim3 block(threadsperblock);
- x16_echo512_gpu_hash_64<<>>(threads, d_hash);
+ x16_echo512_gpu_hash_64 <<>> (threads, d_hash, NULL, 0);
}
+
+__host__
+void phi_echo512_cpu_hash_64_filtered(int thr_id, const uint32_t threads, uint32_t* g_hash, uint32_t* d_filter)
+{
+ const uint32_t threadsperblock = 128;
+
+ dim3 grid((threads + threadsperblock - 1) / threadsperblock);
+ dim3 block(threadsperblock);
+
+ x16_echo512_gpu_hash_64 <<>> (threads, g_hash, d_filter, 0);
+}
\ No newline at end of file