/** * Generate random numbers */ __kernel void generateRandomNumbers(int numValues, __global float4* restrict random, __global uint4* restrict seed) { int index = get_global_id(0); uint4 state = seed[index]; unsigned int carry = 0; while (index < numValues) { float4 value; // Generate first two values. state.x = state.x * 69069 + 1; state.y ^= state.y << 13; state.y ^= state.y >> 17; state.y ^= state.y << 5; unsigned int k = (state.z >> 2) + (state.w >> 3) + (carry >> 2); unsigned int m = state.w + state.w + state.z + carry; state.z = state.w; state.w = m; carry = k >> 30; float x1 = (float)max(state.x + state.y + state.w, 0x00000001u) / (float)0xffffffff; state.x = state.x * 69069 + 1; state.y ^= state.y << 13; state.y ^= state.y >> 17; state.y ^= state.y << 5; x1 = SQRT(-2.0f * LOG(x1)); k = (state.z >> 2) + (state.w >> 3) + (carry >> 2); m = state.w + state.w + state.z + carry; state.z = state.w; state.w = m; carry = k >> 30; float x2 = (float)(state.x + state.y + state.w) / (float)0xffffffff; value.x = x1 * cos(2.0f * 3.14159265f * x2); value.y = x1 * sin(2.0f * 3.14159265f * x2); // Generate next two values. state.x = state.x * 69069 + 1; state.y ^= state.y << 13; state.y ^= state.y >> 17; state.y ^= state.y << 5; k = (state.z >> 2) + (state.w >> 3) + (carry >> 2); m = state.w + state.w + state.z + carry; state.z = state.w; state.w = m; carry = k >> 30; float x3 = (float)max(state.x + state.y + state.w, 0x00000001u) / (float)0xffffffff; state.x = state.x * 69069 + 1; state.y ^= state.y << 13; state.y ^= state.y >> 17; state.y ^= state.y << 5; x3 = SQRT(-2.0f * LOG(x3)); k = (state.z >> 2) + (state.w >> 3) + (carry >> 2); m = state.w + state.w + state.z + carry; state.z = state.w; state.w = m; carry = k >> 30; float x4 = (float)(state.x + state.y + state.w) / (float)0xffffffff; value.z = x3 * cos(2.0f * 3.14159265f * x4); value.w = x3 * sin(2.0f * 3.14159265f * x4); // Record the values. random[index] = value; index += get_global_size(0); } seed[get_global_id(0)] = state; }