Ceq

Brook 1.4 gather bug?

Discussion created by Ceq on May 27, 2009
Latest reply on Jun 15, 2009 by Ceq

I think there is a bug that affects gather operations when using big 1D streams. The following example takes two streams and merges their data in a interleaved way, for example:

SIZE = 4

vIn1 = { 0, 1, 2, 3 }

vIn2 = { -0, -1, -2, -3}

vOut = { 0 , -0, 1, -1, 2, -2, 3, -3}

 

However if you use big stream, like 2^20:

- Using Catalyst 9.2, Brook+ 1.4, MSVC 2005, Radeon 3870x2 or Radeon 4850, WinXP 64 or WinXP 32

SIZE = 1 << 20;

vIn1 = { 0, 1, 2, 3, ... }

vIn2 = { -0, -1, -2, -3, ...}

vOut = { 0 , 0, 1, 0, 2, 0, 3, 0, ...}

- Using Catalyst 9.5, Radeon 4850 and WinXP 64 returns undefined values instead of 0, usually previous memory data.

- Using Catalyst 9.5, Radeon 3870x2 and WinXP 32 aborts the program.

 

Test case:

#include <  stdio.h >
#include < stdlib.h >

kernel void
ker(float in1[ ], float in2[ ], out float out1< > )
{
    int pos_x = instance().x;
    int i = pos_x >> 1;
    float t;
    if(pos_x & 0x01) {
        t = in2[i ];
    } else {
        t = in1[i ];
    }
    // Some operations with t
    out1 = t;
}


int main(int argc, char** argv) {
    const int SIZE = 1 << 20; // *** Wrong result using big sizes ***
    // const int SIZE = 1 << 10; // *** Right using small streams ***
    const int DSIZE = 2 * SIZE;
    unsigned int i;

    // Memory arrays
    float vIn1[SIZE ],  vIn2[SIZE ];
    float vOut[DSIZE ];

    // Init
    for(i = 0; i < SIZE; ++i) {
        vIn1[i ] =  (float)i;
        vIn2[i ] = -(float)i;
    }

    {
        // Stream arrays
        float sIn1<SIZE >,  sIn2<SIZE >;
        float sOut<DSIZE >;
        // Load
        streamRead(sIn1, vIn1 );
        streamRead(sIn2, vIn2 );
        // Kernel
        ker(sIn1, sIn2, sOut );
        // Save
        streamWrite(sOut, vOut );
    }

    // Print
    for(i = 0; i < 8; i++)
        printf("vOut[%i] = (%7.3f);\n", i, vOut[i ] );
}

Outcomes