cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

notooth
Journeyman III

Problem with 64 bit memory

Hello,

I have the following code which does not work with bit field larger than 32. Please help.

__kernel void Generate21(__global ulong* out)

{

          int num = get_global_id(0);

          out[num] = 1<<32 ^ 1<<22; // any number larger than 31 returned wrong result

}

unsigned long Matrix[64];

cl_mem cl_Matrix = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(Matrix[63]), NULL, NULL);

cl_kernel Genrerate21 = clCreateKernel(program, "Generate21", NULL);

status = clSetKernelArg(Genrerate21, 0, sizeof(cl_mem), (void *)&cl_Matrix);

*global_work_size = 1;

status = clEnqueueNDRangeKernel(commandQueue, Genrerate21, 1, NULL, global_work_size, NULL, 0, NULL, NULL);

status = clEnqueueReadBuffer(commandQueue, cl_Matrix, CL_TRUE, 0, sizeof(Matrix[63]), &Matrix[63], 0, NULL, NULL);

for (char i=63; i>=0; i--)

  printf("%d", (Matrix[63]>>i)&1);

0 Likes
7 Replies
himanshu_gautam
Grandmaster

Try using "cl_ulong" in your host code. Thats the right way to do it.

Also, "%d" may not be the right thing to do for printing a 64-bit number.

I am not sure,. You may want to cross check this

0 Likes

Check out this code, i wrote using hello world.It seems to be working fine for me.

0 Likes

This is the result of the code. The number 4194304 (equal to 1<<22) is not expected. It should be equal to 1<<32 ^ 1<<22;

input string:

0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22

  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42

  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62

  63  output string:

4194304  4194304  4194304  4194304  4194304  4194304  4194304  4194304  4194304

4194304  4194304  4194304  4194304  4194304  4194304  4194304  4194304  4194304

  4194304  4194304  4194304  4194304  4194304  4194304  4194304  4194304  419430

4  4194304  4194304  4194304  4194304  4194304  4194304  4194304  4194304  41943

04  4194304  4194304  4194304  4194304  4194304  4194304  4194304  4194304  4194

304  4194304  4194304  4194304  4194304  4194304  4194304  4194304  4194304  419

4304  4194304  4194304 

0 Likes

Try the expression like this: " (unsigned long)1<<32 ^ 1<<22;"

I tried a plain vanilla C++ program. This does not work. Gives same output as above. The compiler emits a warning.

#include <iostream>

int main()
{
    unsigned long value = 1<<32 ^ 1<<22;
    std::cout << "size of ulong = " << sizeof(unsigned long) << std::endl;
    std::cout << "Value = " << value << std::endl;
    return 0;
}
~

However, when I change the CPP program to be like the one below, it worked.

#include <iostream>

int main()
{
    unsigned long value = (unsigned long)1<<32 ^ 1<<22;
    std::cout << "size of ulong = " << sizeof(unsigned long) << std::endl;
    std::cout << "Value = " << value << std::endl;
    return 0;
}
~

0 Likes

This is the output of the code:

size of ulong = 4

Value = 4194304

I am using VS 2012 on Windows 7 64bit. It is weird that VS said "unsigned long" a 4 bytes data type. When I changed "unsigned long" to "__int64", it returned the correct output.

size of ulong = 8

Value = 4299161600

0 Likes

I think you are in a 32-bit platform.

Try using "cl_ulong" and you will get 64-bit ulong in host code.

Refer chapter 6 in OpenCL spec, the Built-in scalar type section.

"ulong" in the kernel is 64-bit and its corresponding host usage is "cl_ulong"

This is platform independent.

Hi notooth,

As per Operator Precendence table (http://www.difranco.net/compsci/C_Operator_Precedence_Table.htm)

The bit shift operation will be done first and then the XOR. The first bit shift "1<<32" will evaluate to 0, as "1" would be stored in a 32-bit integer type. So final result would be 1<<22 which is 4194304 as printed in the testcase attached.

0 Likes