Hi,
I posted this question on stackoverflow but I thought this might be a good place to ask as well. integer overflow - openCL Long Overflowing - Stack Overflow
Before I start I am a C beginner and I am trying to do some openCL work which might have been a mistake. Below is my kernel code:
__kernel void collatz(__global int* in, __global int* out)
{
uint id = get_global_id(0);
unsigned long n = (unsigned long)id;
uint count = 0;
while (n > 1) {
if (n % 2 == 0) {
n = n / 2;
} else {
if(n == 1572066143) {
unsigned long test = n;
printf("BEFORE - %lu\n", n);
test = (3 * test) + 1;
printf("AFTER - %lu\n", test);
n = (3 * n) + 1;
} else {
n = (3 * n) + 1;
}
}
count = count + 1;
}
out[id] = count;
}
and the output:
BEFORE - 1572066143
AFTER - 421231134
To me it looks like n is overflowing but I can't figure out why it is happening.
The interesting thing is if I create a new variable to store the same value as n then it seems to work correctly.
unsigned long test = 1572066143;
printf("BEFORE - %lu\n", test);
test = (3 * test) + 1; p
printf("AFTER - %lu\n", test);
Output:
BEFORE - 1572066143
AFTER - 4716198430
As I said I am a C beginner so I could be doing something very stupid!
Any help would be appreciated as I have been pulling my hair out for hours now!
Thanks,
Stephen
Hi Stephen,
Welcome and thanks for posting.
I have white-listed you, so you should be able to directly post in the relevant forum. As this post is related to OpenCL, I am moving it to the OpenCL forum.
Happy posting!
--Prasad
stephenheron wrote:
BEFORE - 1572066143
AFTER - 421231134
To me it looks like n is overflowing but I can't figure out why it is happening.
The interesting thing is if I create a new variable to store the same value as n then it seems to work correctly.
unsigned long test = 1572066143;
printf("BEFORE - %lu\n", test);
test = (3 * test) + 1; p
printf("AFTER - %lu\n", test);
Output:
BEFORE - 1572066143
AFTER - 4716198430
As I said I am a C beginner so I could be doing something very stupid!
Any help would be appreciated as I have been pulling my hair out for hours now!
The code is definitely weird, but valid nevertheless. It's not an overflow problem, as shown in your 2nd example, but a compiler one. Seems you came across an ocl bug.
BTW you shouldn't pass "in" as an argument, if you don't use it. If you generate a binary image, there is a disassembler available, that you can check what the compiler is doing...
Interesting. Looks like the compiler is using a 32-bit unsigned variable for 'test', when it should be using a 64-bit variable (as unsigned long is 64-bit).
421231134 is (1572066143 *3 + 1) % (2^32)
Could you please check with the latest Crimson 15.11 driver?
Regards,