cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

riza_guntur
Journeyman III

What is the parameter of domainOffset and domainSize?

I try the exec_domain example, I wonder why:

    // Offset from the top-left corner
    writePos.domainOffset(uint4(1, 1, 0, 0));

    // Size of domain of execution
    writePos.domainSize(uint4(5, 5, 1, 1));

The domainOffset has double zero at z and w posotion of uint4 while the domainSize z and w filled with double 1. I expect z and w for 3D and 4D coordinates (if 4D exist).

At first I change domainOffset to (0,0,0,0) and it start from 0,0 with width 5 and height 5 and then I change the domainSize to width 5 and height 6, it still starts from 0,0 and heigth increase. At this point I understand.

After that I change domainOffset to else (1,1,2,2) and domainSize to (5,5,0,0) but the output remains the same. Why? What the z and w in domainOffset and domainSize supposed to be? Why those z and w different at examples?

Help.

0 Likes
4 Replies
riza_guntur
Journeyman III

Help anybody

0 Likes
Gipsel
Adept I

Originally posted by: riza.guntur I try the exec_domain example, I wonder why:

    // Offset from the top-left corner     writePos.domainOffset(uint4(1, 1, 0, 0));     // Size of domain of execution     writePos.domainSize(uint4(5, 5, 1, 1));

The domainOffset has double zero at z and w posotion of uint4 while the domainSize z and w filled with double 1. I expect z and w for 3D and 4D coordinates (if 4D exist).

At first I change domainOffset to (0,0,0,0) and it start from 0,0 with width 5 and height 5 and then I change the domainSize to width 5 and height 6, it still starts from 0,0 and heigth increase. At this point I understand.

After that I change domainOffset to else (1,1,2,2) and domainSize to (5,5,0,0) but the output remains the same. Why? What the z and w in domainOffset and domainSize supposed to be? Why those z and w different at examples?

Help.



What help do you need? Actually the whole domain stuff is working like it should (at least with SDK1.3). You only have to remember that the total number of threads in the domain is domainSize.x*domainSize.y*domainSize.z*domainSize.w, even when there are fewer dimensions used. So one has to put a 1 in every unused dimension for the size (and a zero for the offset) to get the right behaviour.

0 Likes
Ceq
Journeyman III

When you declare a stream object you can use up to four dimensions, (altough optimal performance usually is obtained with 2D streams), that's why you have to use a uint4 value to specify domains.

Supose you declare a Stream of size (DimX, DimY, DimZ, DimW). By default the starting position to process data is (0, 0, 0, 0), so that's the default domainOffset. If you increase it you'll be processing beginning in another point. If you change unused dimensions the result will be the same.

The other parameter is the domainSize, wich defines the number of elements to process, so by default it must be (DimX, DimY, DimZ, DimW). If your domain is bigger than your output stream the elements out of bound won't be processed.

Now supose you have a 2D texture, your default domainOffset continues to be (0, 0, 0, 0), but now your domainSize in Z and W coordinates is 1, so domain size is now (DimX, DimY, 1, 1).

Using domain operators is useful to process only a small rectangle of a stream or to control the number of threads to use in a scatter kernel.

Here is a small example if you still have doubts, it will copy a rectangular subdomain of the input stream (each element is initialized to its position) to the output stream leaving the rest of the output stream unchanged (value = 0).

 

kernel void copy(float i<> , out float o<> ) { o = i; }

 

int main(int argc, char *argv[ ] ) {
    const int DIMX = 8;
    const int DIMY = 8;
    float v_data[DIMY ][DIMX ];
    float result[DIMY ][DIMX ];

    // Initialize arrays
    for(int y = 0; y < DIMY; y++ ) {
        for(int x = 0; x < DIMX; x++ ) {
            v_data[ y ][ x ] = (float)y + 0.1f * x;
            result[ y ][ x ] = 0.0f;
        }
    }
    
    // Initialize streams
    unsigned int dims[ ] = { DIMX, DIMY, 0, 0 };
    brook:: Stream<float> s_data(2, dims );
    brook:: Stream<float> s_res(2, dims );
    s_data.read(v_data );
    s_res.read(result );

    // Sets copy operation domain
    uint4 pos_ini(1, 1, 0, 0 );
    uint4 num_dat(4, 4, 1, 1 );
    copy.domainOffset(pos_ini );
    copy.domainSize(num_dat );

    // Copy a subdomain of s_data to s_res
    copy(s_data, s_res );

    // Print results
    s_res.write(result );
    for(int y = 0; y < DIMY; y++ ) {
        for(int x = 0; x < DIMX; x++ )
            printf("%4.1f ", result[ y ][ x ]);
        printf("\n" );
    }

    return 0;
}

 

 

// Sample output, starting at (1, 1) we copy (4, 4) elements

0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  1.1  1.2  1.3  1.4  0.0  0.0  0.0
0.0  2.1  2.2  2.3  2.4  0.0  0.0  0.0
0.0  3.1  3.2  3.3  3.4  0.0  0.0  0.0
0.0  4.1  4.2  4.3  4.4  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0

0 Likes

Using domain operators is useful to process only a small rectangle of a stream or to control the number of threads to use in a scatter kernel.


Please give this example. This particular topic I dont understand.

If you dont mind perhaps the Stream::Domain function too, what is it for if we already have domainOffset and domainSize?

Thank you for your kindness 🙂

0 Likes