| 974 | |
| 975 | template<typename T> |
| 976 | __global__ void normalMersenne(T *const out, uint *const gState, |
| 977 | const uint *const pos_tbl, |
| 978 | const uint *const sh1_tbl, |
| 979 | const uint *const sh2_tbl, uint mask, |
| 980 | const uint *const g_recursion_table, |
| 981 | const uint *const g_temper_table, |
| 982 | uint elementsPerBlock, uint elements) { |
| 983 | __shared__ uint state[STATE_SIZE]; |
| 984 | __shared__ uint recursion_table[TABLE_SIZE]; |
| 985 | __shared__ uint temper_table[TABLE_SIZE]; |
| 986 | uint start = blockIdx.x * elementsPerBlock; |
| 987 | uint end = start + elementsPerBlock; |
| 988 | end = (end > elements) ? elements : end; |
| 989 | int iter = divup((end - start) * sizeof(T), blockDim.x * 4 * sizeof(uint)); |
| 990 | |
| 991 | uint pos = pos_tbl[blockIdx.x]; |
| 992 | uint sh1 = sh1_tbl[blockIdx.x]; |
| 993 | uint sh2 = sh2_tbl[blockIdx.x]; |
| 994 | state_read(state, gState); |
| 995 | read_table(recursion_table, g_recursion_table); |
| 996 | read_table(temper_table, g_temper_table); |
| 997 | __syncthreads(); |
| 998 | |
| 999 | uint index = start; |
| 1000 | int elementsPerBlockIteration = blockDim.x * 4 * sizeof(uint) / sizeof(T); |
| 1001 | uint o[4]; |
| 1002 | int offsetX1 = (STATE_SIZE - N + threadIdx.x) % STATE_SIZE; |
| 1003 | int offsetX2 = (STATE_SIZE - N + threadIdx.x + 1) % STATE_SIZE; |
| 1004 | int offsetY = (STATE_SIZE - N + threadIdx.x + pos) % STATE_SIZE; |
| 1005 | int offsetT = (STATE_SIZE - N + threadIdx.x + pos - 1) % STATE_SIZE; |
| 1006 | int offsetO = threadIdx.x; |
| 1007 | |
| 1008 | for (int i = 0; i < iter; ++i) { |
| 1009 | for (int ii = 0; ii < 4; ++ii) { |
| 1010 | uint r = recursion(recursion_table, mask, sh1, sh2, state[offsetX1], |
| 1011 | state[offsetX2], state[offsetY]); |
| 1012 | state[offsetO] = r; |
| 1013 | o[ii] = temper(temper_table, r, state[offsetT]); |
| 1014 | offsetX1 = (offsetX1 + blockDim.x) % STATE_SIZE; |
| 1015 | offsetX2 = (offsetX2 + blockDim.x) % STATE_SIZE; |
| 1016 | offsetY = (offsetY + blockDim.x) % STATE_SIZE; |
| 1017 | offsetT = (offsetT + blockDim.x) % STATE_SIZE; |
| 1018 | offsetO = (offsetO + blockDim.x) % STATE_SIZE; |
| 1019 | __syncthreads(); |
| 1020 | } |
| 1021 | if (i == iter - 1) { |
| 1022 | partialBoxMullerWriteOut128Bytes(out, index + threadIdx.x, o[0], |
| 1023 | o[1], o[2], o[3], elements); |
| 1024 | } else { |
| 1025 | boxMullerWriteOut128Bytes(out, index + threadIdx.x, o[0], o[1], |
| 1026 | o[2], o[3]); |
| 1027 | } |
| 1028 | index += elementsPerBlockIteration; |
| 1029 | } |
| 1030 | state_write(gState, state); |
| 1031 | } |
| 1032 | |
| 1033 | template<typename T> |
nothing calls this directly
no test coverage detected