| 131 | // distribution. Each output takes a fixed number of samples. |
| 132 | template <class Distribution> |
| 133 | PHILOX_DEVICE_INLINE void FillPhiloxRandomKernel<Distribution, false>::Run( |
| 134 | random::PhiloxRandom gen, T* data, int64 size, Distribution dist) { |
| 135 | const int kGroupSize = Distribution::kResultElementCount; |
| 136 | |
| 137 | const int32 thread_id = blockIdx.x * blockDim.x + threadIdx.x; |
| 138 | const int32 total_thread_count = gridDim.x * blockDim.x; |
| 139 | int64 offset = thread_id * kGroupSize; |
| 140 | gen.Skip(thread_id); |
| 141 | |
| 142 | const SampleCopier<T, kGroupSize> copier; |
| 143 | while (offset + kGroupSize <= size) { |
| 144 | const typename Distribution::ResultType samples = dist(&gen); |
| 145 | copier(&data[offset], samples); |
| 146 | |
| 147 | offset += total_thread_count * kGroupSize; |
| 148 | gen.Skip(total_thread_count - 1); |
| 149 | } |
| 150 | |
| 151 | typename Distribution::ResultType samples = dist(&gen); |
| 152 | for (int i = 0; i < kGroupSize; ++i) { |
| 153 | if (offset >= size) { |
| 154 | return; |
| 155 | } |
| 156 | data[offset] = samples[i]; |
| 157 | ++offset; |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | // A cuda kernel to fill the data with random numbers from the specified |
| 162 | // distribution. Each output takes a variable number of samples. |