random.cl 2.4 KB
Newer Older
1
2
3
4
/**
 * Generate random numbers
 */

5
__kernel void generateRandomNumbers(int numValues, __global float4* restrict random, __global uint4* restrict seed) {
6
7
8
9
10
11
    int index = get_global_id(0);
    uint4 state = seed[index];
    unsigned int carry = 0;
    while (index < numValues) {
        float4 value;

12
        // Generate first two values.
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

        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;
28
        x1 = SQRT(-2.0f * LOG(x1));
29
30
31
32
33
34
35
        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);
36
        value.y = x1 * sin(2.0f * 3.14159265f * x2);
37

38
        // Generate next two values.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

        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;
54
        x3 = SQRT(-2.0f * LOG(x3));
55
56
57
58
59
60
        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;
61
62
        value.z = x3 * cos(2.0f * 3.14159265f * x4);
        value.w = x3 * sin(2.0f * 3.14159265f * x4);
63
64
65
66
67
68
69
70

        // Record the values.

        random[index] = value;
        index += get_global_size(0);
    }
    seed[get_global_id(0)] = state;
}