Advertisement
image28

ethash.cl nvidia 3050 LHR possible unlock

Feb 27th, 2022 (edited)
533
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 17.85 KB | None | 0 0
  1. /*
  2. Let me know if it works
  3. Happy to accept donations to 0x5a5db084cc2ac543d39961a12926be7cfa02913a
  4. (Nicehash ethereum wallet) 36,000 recommended gas limit.
  5. I'm getting improvements on my Radeon rt 5500 xt sapphire pulse,
  6. Went up from 24Mh/s to 39-42MH/s, But don't have a LHR card to test on.
  7.  
  8. Cheers,
  9. image28/imagekiwi
  10.  
  11. p.s could improve dag generation speed but wouldn't be worth the effort right now
  12. Dag compression would be more interesting. The unlock works by removing unions which use the
  13. largest variable type in the union 64bit, which has the speed clamped on LHR gpu's, some other LHR
  14. gpu's also clamp 16bit performance, so I adjusted most of the code to work on 32bit values.
  15. Still room for more improvements.
  16. */
  17.  
  18. #define OPENCL_PLATFORM_UNKNOWN 0
  19. #define OPENCL_PLATFORM_AMD 1
  20. #define OPENCL_PLATFORM_CLOVER 2
  21. #define OPENCL_PLATFORM_NVIDIA 3
  22. #define OPENCL_PLATFORM_INTEL 4
  23. /*
  24. #define WORKSIZE 256
  25. #define MAX_OUTPUTS 4
  26. #define ACCESSES 64
  27. #define PLATFORM 1
  28. #define COMPUTE 1
  29. */
  30.  
  31. #define CHUNKSIZE 64
  32.  
  33. #ifdef cl_clang_storage_class_specifiers
  34. #pragma OPENCL EXTENSION cl_clang_storage_class_specifiers : enable
  35. #endif
  36.  
  37. #if defined(cl_amd_media_ops)
  38.     #if PLATFORM == OPENCL_PLATFORM_CLOVER
  39.         uint2 amd_bitalign(uint2 src0, uint2 src1, uint2 src2)
  40.         {
  41.             uint2 dst;
  42.             __asm(
  43.                 "v_alignbit_b32 %0, %2, %3, %4\n"
  44.                 "v_alignbit_b32 %1, %5, %6, %7"
  45.                 : "=v"(dst.x), "=v"(dst.y)
  46.                 : "v"(src0.x), "v"(src1.x), "v"(src2.x), "v"(src0.y), "v"(src1.y), "v"(src2.y));
  47.             return dst;
  48.         }
  49.     #endif
  50.  
  51.     #pragma OPENCL EXTENSION cl_amd_media_ops : enable
  52. #elif defined(cl_nv_pragma_unroll)
  53.     uint amd_bitalign(uint src0, uint src1, uint src2)
  54.     {
  55.         uint dest;
  56.         asm("shf.r.wrap.b32 %0, %2, %1, %3;" : "=r"(dest) : "r"(src0), "r"(src1), "r"(src2));
  57.         return dest;
  58.     }
  59. #else
  60.     #define amd_bitalign(src0, src1, src2) \
  61.         ((uint)(((((ulong)(src0)) << 32) | (ulong)(src1)) >> ((src2)&31)))
  62. #endif
  63.  
  64. #define EndianSwap(n) (rotate(n & 0x00FF00FF, 24U)|(rotate(n, 8U) & 0x00FF00FF)
  65.  
  66. #if WORKSIZE % 4 != 0
  67.     #error "WORKSIZE has to be a multiple of 4"
  68. #endif
  69.  
  70. #define FNV_PRIME 0x01000193U // 2^24+403
  71.  
  72. static __constant uint2 const Keccak_f1600_RC[24] = {
  73.     (uint2)(0x00000001, 0x00000000),
  74.     (uint2)(0x00008082, 0x00000000),
  75.     (uint2)(0x0000808a, 0x80000000),
  76.     (uint2)(0x80008000, 0x80000000),
  77.     (uint2)(0x0000808b, 0x00000000),
  78.     (uint2)(0x80000001, 0x00000000),
  79.     (uint2)(0x80008081, 0x80000000),
  80.     (uint2)(0x00008009, 0x80000000),
  81.     (uint2)(0x0000008a, 0x00000000),
  82.     (uint2)(0x00000088, 0x00000000),
  83.     (uint2)(0x80008009, 0x00000000),
  84.     (uint2)(0x8000000a, 0x00000000),
  85.     (uint2)(0x8000808b, 0x00000000),
  86.     (uint2)(0x0000008b, 0x80000000),
  87.     (uint2)(0x00008089, 0x80000000),
  88.     (uint2)(0x00008003, 0x80000000),
  89.     (uint2)(0x00008002, 0x80000000),
  90.     (uint2)(0x00000080, 0x80000000),
  91.     (uint2)(0x0000800a, 0x00000000),
  92.     (uint2)(0x8000000a, 0x80000000),
  93.     (uint2)(0x80008081, 0x80000000),
  94.     (uint2)(0x00008080, 0x80000000),
  95.     (uint2)(0x80000001, 0x00000000),
  96.     (uint2)(0x80008008, 0x80000000),
  97. };
  98.  
  99. #ifdef cl_amd_media_ops
  100.     #define ROTL32_1(x, y) amd_bitalign((x), (x).s10, 32 - (y))
  101.     #define ROTL32_2(x, y) amd_bitalign((x).s10, (x), 32 - (y))
  102. #else
  103.     #define ROTL32_1(x, y) rotate(x, y)
  104.     #define ROTL32_2(x, y) ROTL32_1(x, (y) + 32)
  105. #endif
  106.  
  107. #define KECCAKF_1600_RND(a, i, outsz)                                      \
  108.     do                                                                     \
  109.     {                                                                      \
  110.         const uint2 m0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20] ^             \
  111.                          ROTL32_1(a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22], 1); \
  112.         const uint2 m1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21] ^             \
  113.                          ROTL32_1(a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23], 1); \
  114.         const uint2 m2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22] ^             \
  115.                          ROTL32_1(a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24], 1); \
  116.         const uint2 m3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23] ^             \
  117.                          ROTL32_1(a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20], 1); \
  118.         const uint2 m4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24] ^             \
  119.                          ROTL32_1(a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21], 1); \
  120.                                                                            \
  121.         const uint2 tmp = a[1] ^ m0;                                       \
  122.                                                                            \
  123.         a[0] ^= m4;                                                        \
  124.         a[5] ^= m4;                                                        \
  125.         a[10] ^= m4;                                                       \
  126.         a[15] ^= m4;                                                       \
  127.         a[20] ^= m4;                                                       \
  128.                                                                            \
  129.         a[6] ^= m0;                                                        \
  130.         a[11] ^= m0;                                                       \
  131.         a[16] ^= m0;                                                       \
  132.         a[21] ^= m0;                                                       \
  133.                                                                            \
  134.         a[2] ^= m1;                                                        \
  135.         a[7] ^= m1;                                                        \
  136.         a[12] ^= m1;                                                       \
  137.         a[17] ^= m1;                                                       \
  138.         a[22] ^= m1;                                                       \
  139.                                                                            \
  140.         a[3] ^= m2;                                                        \
  141.         a[8] ^= m2;                                                        \
  142.         a[13] ^= m2;                                                       \
  143.         a[18] ^= m2;                                                       \
  144.         a[23] ^= m2;                                                       \
  145.                                                                            \
  146.         a[4] ^= m3;                                                        \
  147.         a[9] ^= m3;                                                        \
  148.         a[14] ^= m3;                                                       \
  149.         a[19] ^= m3;                                                       \
  150.         a[24] ^= m3;                                                       \
  151.                                                                            \
  152.         a[1] = ROTL32_2(a[6], 12);                                         \
  153.         a[6] = ROTL32_1(a[9], 20);                                         \
  154.         a[9] = ROTL32_2(a[22], 29);                                        \
  155.         a[22] = ROTL32_2(a[14], 7);                                        \
  156.         a[14] = ROTL32_1(a[20], 18);                                       \
  157.         a[20] = ROTL32_2(a[2], 30);                                        \
  158.         a[2] = ROTL32_2(a[12], 11);                                        \
  159.         a[12] = ROTL32_1(a[13], 25);                                       \
  160.         a[13] = ROTL32_1(a[19], 8);                                        \
  161.         a[19] = ROTL32_2(a[23], 24);                                       \
  162.         a[23] = ROTL32_2(a[15], 9);                                        \
  163.         a[15] = ROTL32_1(a[4], 27);                                        \
  164.         a[4] = ROTL32_1(a[24], 14);                                        \
  165.         a[24] = ROTL32_1(a[21], 2);                                        \
  166.         a[21] = ROTL32_2(a[8], 23);                                        \
  167.         a[8] = ROTL32_2(a[16], 13);                                        \
  168.         a[16] = ROTL32_2(a[5], 4);                                         \
  169.         a[5] = ROTL32_1(a[3], 28);                                         \
  170.         a[3] = ROTL32_1(a[18], 21);                                        \
  171.         a[18] = ROTL32_1(a[17], 15);                                       \
  172.         a[17] = ROTL32_1(a[11], 10);                                       \
  173.         a[11] = ROTL32_1(a[7], 6);                                         \
  174.         a[7] = ROTL32_1(a[10], 3);                                         \
  175.         a[10] = ROTL32_1(tmp, 1);                                          \
  176.                                                                            \
  177.         uint2 m5 = a[0];                                                   \
  178.         uint2 m6 = a[1];                                                   \
  179.         a[0] = bitselect(a[0] ^ a[2], a[0], a[1]);                         \
  180.         a[0] ^= as_uint2(Keccak_f1600_RC[i]);                              \
  181.         if (outsz > 1)                                                     \
  182.         {                                                                  \
  183.             a[1] = bitselect(a[1] ^ a[3], a[1], a[2]);                     \
  184.             a[2] = bitselect(a[2] ^ a[4], a[2], a[3]);                     \
  185.             a[3] = bitselect(a[3] ^ m5, a[3], a[4]);                       \
  186.             a[4] = bitselect(a[4] ^ m6, a[4], m5);                         \
  187.             if (outsz > 4)                                                 \
  188.             {                                                              \
  189.                 m5 = a[5];                                                 \
  190.                 m6 = a[6];                                                 \
  191.                 a[5] = bitselect(a[5] ^ a[7], a[5], a[6]);                 \
  192.                 a[6] = bitselect(a[6] ^ a[8], a[6], a[7]);                 \
  193.                 a[7] = bitselect(a[7] ^ a[9], a[7], a[8]);                 \
  194.                 a[8] = bitselect(a[8] ^ m5, a[8], a[9]);                   \
  195.                 a[9] = bitselect(a[9] ^ m6, a[9], m5);                     \
  196.                 if (outsz > 8)                                             \
  197.                 {                                                          \
  198.                     m5 = a[10];                                            \
  199.                     m6 = a[11];                                            \
  200.                     a[10] = bitselect(a[10] ^ a[12], a[10], a[11]);        \
  201.                     a[11] = bitselect(a[11] ^ a[13], a[11], a[12]);        \
  202.                     a[12] = bitselect(a[12] ^ a[14], a[12], a[13]);        \
  203.                     a[13] = bitselect(a[13] ^ m5, a[13], a[14]);           \
  204.                     a[14] = bitselect(a[14] ^ m6, a[14], m5);              \
  205.                     m5 = a[15];                                            \
  206.                     m6 = a[16];                                            \
  207.                     a[15] = bitselect(a[15] ^ a[17], a[15], a[16]);        \
  208.                     a[16] = bitselect(a[16] ^ a[18], a[16], a[17]);        \
  209.                     a[17] = bitselect(a[17] ^ a[19], a[17], a[18]);        \
  210.                     a[18] = bitselect(a[18] ^ m5, a[18], a[19]);           \
  211.                     a[19] = bitselect(a[19] ^ m6, a[19], m5);              \
  212.                     m5 = a[20];                                            \
  213.                     m6 = a[21];                                            \
  214.                     a[20] = bitselect(a[20] ^ a[22], a[20], a[21]);        \
  215.                     a[21] = bitselect(a[21] ^ a[23], a[21], a[22]);        \
  216.                     a[22] = bitselect(a[22] ^ a[24], a[22], a[23]);        \
  217.                     a[23] = bitselect(a[23] ^ m5, a[23], a[24]);           \
  218.                     a[24] = bitselect(a[24] ^ m6, a[24], m5);              \
  219.                 }                                                          \
  220.             }                                                              \
  221.         }                                                                  \
  222.     } while (0)
  223.  
  224.  
  225. #define KECCAK_PROCESS(st, in_size, out_size)    \
  226.     do                                           \
  227.     {                                            \
  228.         short r=0;                               \
  229.         short os=0;                              \
  230.                                                  \
  231.         do                                       \
  232.         {                                        \
  233.             os=(r < 23 ? 25 : (out_size));       \
  234.             KECCAKF_1600_RND(st, r, os);         \
  235.             r++;                                 \
  236.         }while(r<24);                            \
  237.     } while (0)
  238.  
  239. #define fnv(x, y) ((x)*FNV_PRIME ^ (y))
  240. #define fnv_reduce(v) fnv(fnv(fnv(v.x, v.y), v.z), v.w)
  241.  
  242. #define MIX(x)                                                          \
  243.     do                                                                  \
  244.     {                                                                   \
  245.         *(local_buffer) = fnv(init0 ^ (a + x), *(imix+x)) % dag_size;   \
  246.         mix = fnv(mix, g_dag_uint[(buffer[lane_idx]*4)+ids[1]]);        \
  247.         mem_fence(CLK_LOCAL_MEM_FENCE);                                 \
  248.     } while (0)
  249.  
  250. // NOTE: This struct must match the one defined in CLMiner.cpp
  251. struct __attribute__((packed)) __attribute__((aligned(128))) SearchResults
  252. {
  253.     uint count;
  254.     uint hashCount;
  255.     volatile uint abort;
  256.     uint gid[MAX_OUTPUTS];
  257. };
  258.  
  259. __attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) __kernel void search(
  260.     __global struct SearchResults* g_output, __constant uint2 const* g_header,
  261.     __global ulong8 const* _g_dag0, __global ulong8 const* _g_dag1, uint dag_size,
  262.     ulong start_nonce, ulong target)
  263. {
  264.     if (g_output->abort)
  265.         return;
  266.  
  267.     const ushort ids[] = {          \
  268.     (ushort) get_local_id(0),       \
  269.     (ushort)(get_local_id(0) & 3),      \
  270.     (ushort)(get_local_id(0) >> 2),     \
  271.     (ushort)(get_local_id(0) >> 2 << 2)};
  272.     const uint gid = get_global_id(0);
  273.     __global uint8 const* g_dag_uint = (__global uint8 const*)_g_dag0;
  274.  
  275.     __local uint sharebuf[1024];
  276.     __local uint buffer[256];
  277.     __local uint *local_buffer=&buffer[ids[0]];
  278.     __local ulong8 *ulong8_buffer=&sharebuf[ids[2]*16]; // (write buffer 64 bytes )
  279.     __local ulong4 *ulong4_buffer=&sharebuf[ids[2]*16]; // (read buffer 32 bytes )
  280.     __local uint8 *uint8_buffer=(uint)&sharebuf[ids[2]*16]; // (read buffer 32 bytes )
  281.     __local uint2 *uint2_buffer=(uint)&sharebuf[ids[2]*16]; // (write buffer 16 bytes )
  282.     __local uint *uint_buffer=(uint)&sharebuf[ids[2]*16]; // ( read buffer )
  283.  
  284.     uint2 state[25];
  285.     ulong8 *convert=&state;
  286.     ulong4 *convert2=&state;
  287.     uchar a,x,lane;
  288.     char tid=0;
  289.     uint init0;
  290.     uint8 mix;
  291.     uint *imix=&mix;
  292.  
  293.     *(convert)=(ulong8)(0);
  294.     *(convert+1)=*(convert);
  295.     *(convert+2)=*(convert);
  296.     state[0] = g_header[0];
  297.     state[1] = g_header[1];
  298.     state[2] = g_header[2];
  299.     state[3] = g_header[3];
  300.     state[4] = as_uint2(start_nonce + gid);
  301.     state[5] = as_uint2(0x0000000000000001UL);
  302.     state[8] = as_uint2(0x8000000000000000UL);
  303.     state[24] = state[23];
  304.  
  305.     KECCAK_PROCESS(state,5, 8);
  306.  
  307.     for(tid=0; tid < 4; tid++)
  308.     {
  309.         barrier(CLK_LOCAL_MEM_FENCE);
  310.         if ( ids[1] == tid-1 )
  311.             *(convert2+2) = *(ulong4_buffer);
  312.  
  313.         if ( tid == ids[1])
  314.             *(ulong8_buffer)=*(convert);
  315.         barrier(CLK_LOCAL_MEM_FENCE);
  316.  
  317.         mix = *(uint8_buffer+(ids[1]&1));
  318.         init0 = *(uint_buffer);
  319.  
  320.         a=0;lane=0;
  321.         barrier(CLK_LOCAL_MEM_FENCE);
  322.         #pragma unroll 1
  323.         do
  324.         {
  325.             const uchar lane_idx = ids[3] + lane;
  326.             #pragma unroll 8
  327.             for (x = 0; x < 8; ++x)
  328.                 MIX(x);
  329.  
  330.             lane=(lane+1)&3;
  331.             a += 8;
  332.         }while(a < ACCESSES);
  333.  
  334.         barrier(CLK_LOCAL_MEM_FENCE);
  335.         *(uint2_buffer+ids[1]) = (uint2)(fnv_reduce(mix.lo), fnv_reduce(mix.hi));
  336.     }
  337.  
  338.     if ( ids[1] == 3 )
  339.         *(convert2+2) = *(ulong4_buffer);
  340.  
  341.     *(convert2+3)=(ulong4)(0);
  342.     *(convert2+4)=*(convert2+3);
  343.     *(convert2+5)=*(convert2+3);
  344.     state[12] = as_uint2(0x0000000000000001UL);
  345.     state[16] = as_uint2(0x8000000000000000UL);
  346.     state[24] = state[23];
  347.  
  348.     KECCAK_PROCESS(state,12, 1);
  349.  
  350.     if (get_local_id(0) == 0)
  351.     {
  352.         atomic_inc(&g_output->hashCount);
  353.     }
  354.  
  355.     // weird
  356.     if (as_ulong(as_uchar8(state[0]).s76543210) <= target)
  357.     {
  358.         atomic_inc(&g_output->abort);
  359.         uint slot = min(MAX_OUTPUTS - 1u, atomic_inc(&g_output->count));
  360.         g_output->gid[slot] = gid;
  361.     }
  362. }
  363.  
  364. typedef union _Node
  365. {
  366.     uint dwords[16];
  367.     uint2 qwords[8];
  368.     uint4 dqwords[4];
  369. } Node;
  370.  
  371. static void SHA3_512(uint2* s)
  372. {
  373.     uint2 state[25];
  374.     ulong8 *convert=&state;
  375.     ulong8 *result=s;
  376.  
  377.     *(convert)=*(result);
  378.     *(convert+1)=(ulong8)(0);
  379.     *(convert+2)=(ulong8)(0);
  380.     state[8] = (uint2)(0x00000001, 0x80000000);
  381.     state[24] = (uint2)(0);
  382.  
  383.     KECCAK_PROCESS(state,8, 8);
  384.  
  385.     *(result)=*(convert);
  386. }
  387.  
  388. __kernel void GenerateDAG(uint start, __global const uint16* _Cache, __global uint16* _DAG0,
  389.     __global uint16* _DAG1, uint light_size)
  390. {
  391.     __global const Node* Cache = (__global const Node*)_Cache;
  392.     const uint gid = get_global_id(0);
  393.     uint NodeIdx = start + gid;
  394.     const uint thread_id = gid & 3;
  395.  
  396.     __local Node sharebuf[WORKSIZE];
  397.     __local uint indexbuf[WORKSIZE];
  398.     __local Node* dagNode = sharebuf + (get_local_id(0) / 4) * 4;
  399.     __local uint* indexes = indexbuf + (get_local_id(0) / 4) * 4;
  400.     __global const Node* parentNode;
  401.  
  402.     Node DAGNode = Cache[NodeIdx % light_size];
  403.  
  404.     DAGNode.dwords[0] ^= NodeIdx;
  405.     SHA3_512(DAGNode.qwords);
  406.  
  407.     dagNode[thread_id] = DAGNode;
  408.     barrier(CLK_LOCAL_MEM_FENCE);
  409.  
  410.     for (uint i = 0; i < 256; ++i)
  411.     {
  412.         uint ParentIdx = fnv(NodeIdx ^ i, dagNode[thread_id].dwords[i & 15]) % light_size;
  413.         indexes[thread_id] = ParentIdx;
  414.         barrier(CLK_LOCAL_MEM_FENCE);
  415.  
  416.         for (uint t = 0; t < 4; ++t)
  417.         {
  418.             uint parentIndex = indexes[t];
  419.             parentNode = Cache + parentIndex;
  420.  
  421.             dagNode[t].dqwords[thread_id] = fnv(dagNode[t].dqwords[thread_id], parentNode->dqwords[thread_id]);
  422.             barrier(CLK_LOCAL_MEM_FENCE);
  423.         }
  424.     }
  425.     DAGNode = dagNode[thread_id];
  426.  
  427.     SHA3_512(DAGNode.qwords);
  428.  
  429.     __global Node* DAG;
  430.     DAG = (__global Node *) _DAG0;
  431.     DAG[NodeIdx] = DAGNode;
  432. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement