cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

stephenheron
Journeyman III

openCL Overflow

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

0 Likes
4 Replies
pinform
Staff

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

0 Likes
nibal
Challenger

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...

0 Likes
Ono-Sendai
Journeyman III

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)

0 Likes
dipak
Big Boss

Could you please check with the latest Crimson 15.11 driver?

Regards,

0 Likes