4 Replies Latest reply on Dec 3, 2015 4:04 AM by dipak

    openCL Overflow

    stephenheron

      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

        • Re: openCL Overflow
          pinform

          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

          • Re: openCL Overflow
            nibal

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

            • Re: openCL Overflow
              Ono-Sendai

              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)

              • Re: openCL Overflow
                dipak

                Could you please check with the latest Crimson 15.11 driver?

                 

                Regards,