| 873 | |
| 874 | template<typename T> |
| 875 | __global__ void uniformMersenne(T *const out, uint *const gState, |
| 876 | const uint *const pos_tbl, |
| 877 | const uint *const sh1_tbl, |
| 878 | const uint *const sh2_tbl, uint mask, |
| 879 | const uint *const g_recursion_table, |
| 880 | const uint *const g_temper_table, |
| 881 | uint elementsPerBlock, size_t elements) { |
| 882 | __shared__ uint state[STATE_SIZE]; |
| 883 | __shared__ uint recursion_table[TABLE_SIZE]; |
| 884 | __shared__ uint temper_table[TABLE_SIZE]; |
| 885 | uint start = blockIdx.x * elementsPerBlock; |
| 886 | uint end = start + elementsPerBlock; |
| 887 | end = (end > elements) ? elements : end; |
| 888 | int elementsPerBlockIteration = (blockDim.x * 4 * sizeof(uint)) / sizeof(T); |
| 889 | int iter = divup((end - start), elementsPerBlockIteration); |
| 890 | |
| 891 | uint pos = pos_tbl[blockIdx.x]; |
| 892 | uint sh1 = sh1_tbl[blockIdx.x]; |
| 893 | uint sh2 = sh2_tbl[blockIdx.x]; |
| 894 | state_read(state, gState); |
| 895 | read_table(recursion_table, g_recursion_table); |
| 896 | read_table(temper_table, g_temper_table); |
| 897 | __syncthreads(); |
| 898 | |
| 899 | uint index = start; |
| 900 | uint o[4]; |
| 901 | int offsetX1 = (STATE_SIZE - N + threadIdx.x) % STATE_SIZE; |
| 902 | int offsetX2 = (STATE_SIZE - N + threadIdx.x + 1) % STATE_SIZE; |
| 903 | int offsetY = (STATE_SIZE - N + threadIdx.x + pos) % STATE_SIZE; |
| 904 | int offsetT = (STATE_SIZE - N + threadIdx.x + pos - 1) % STATE_SIZE; |
| 905 | int offsetO = threadIdx.x; |
| 906 | |
| 907 | for (int i = 0; i < iter; ++i) { |
| 908 | for (int ii = 0; ii < 4; ++ii) { |
| 909 | uint r = recursion(recursion_table, mask, sh1, sh2, state[offsetX1], |
| 910 | state[offsetX2], state[offsetY]); |
| 911 | state[offsetO] = r; |
| 912 | o[ii] = temper(temper_table, r, state[offsetT]); |
| 913 | offsetX1 = (offsetX1 + blockDim.x) % STATE_SIZE; |
| 914 | offsetX2 = (offsetX2 + blockDim.x) % STATE_SIZE; |
| 915 | offsetY = (offsetY + blockDim.x) % STATE_SIZE; |
| 916 | offsetT = (offsetT + blockDim.x) % STATE_SIZE; |
| 917 | offsetO = (offsetO + blockDim.x) % STATE_SIZE; |
| 918 | __syncthreads(); |
| 919 | } |
| 920 | if (i == iter - 1) { |
| 921 | partialWriteOut128Bytes(out, index + threadIdx.x, o[0], o[1], o[2], |
| 922 | o[3], elements); |
| 923 | } else { |
| 924 | writeOut128Bytes(out, index + threadIdx.x, o[0], o[1], o[2], o[3]); |
| 925 | } |
| 926 | index += elementsPerBlockIteration; |
| 927 | } |
| 928 | state_write(gState, state); |
| 929 | } |
| 930 | |
| 931 | template<typename T> |
| 932 | __global__ void normalPhilox(T *out, uint hi, uint lo, uint hic, uint loc, |
nothing calls this directly
no test coverage detected