Skip to content

Random function defined multiple times in kernels. #16

Description

@cianciosa

To support random numbers, a random state struct type and random function need to be defined in the kernel preamble.

struct mt_state {
    array<uint32_t, 624> array;
    uint16_t index;
};

float random(mt_state &state) {
    const uint16_t k = state.index;
    unit16_t j = (k + 1) % 624;
    uint32_t x = (state.array[k] & 0x80000000U) | (state.array[j] & 0x7fffffffU);
    uint32_t xA = x >> 1;
    if (x & 0x00000001U) {
        xA ^= 0x9908b0dfU;
    }
    j = (k + 397) % 624;
    x = state.array[j]^xA;
    state.array[k] = x;
    state.index = (k + 1) % 624;
    uint32_t y = x^(x >> 11);
    y = y^((y << 7) & 0x9d2c5680U);
    y = y^((y << 15) & 0xefc60000U);
    return static_cast<float> (y^(y >> 18));
}

Due to the nature of random numbers a random 'r1' + 'r2' cannot be reduced. As a consequence is_match needs to always return false. However, as a consequence, multiple random_nodes get generated. In the compile_preamble the check for if node has already been generated fails since is_match was false and multiple random_nodes were stored in the cache. The results in multiple definitions of the random function in the kernel preamble. This will need to be refactored so the preamble is only generated once.

A possible way to fix this is by moving the code that generates the kernel preamble to a static function. This function is only called once for a single kernel source once the first instance of random is generated. Subsequent kernels need to be check a flag in the GPU context to see if this was already added.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions