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);
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
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
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;
}
~
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
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.