4 Replies Latest reply on Jul 2, 2010 8:50 AM by foofel

    reusing variables

    foofel

      Hi, i am currently starting to experiment with opencl and found a (for me) strange behavior.  If i try to jump through a 1D Buffer, and reuse variables, i get wrong values.

      An Example:

      __global uint *root = octree;
      uint nodeSize = GetNodeSize(root);
      uint nodeNumber = 0;

      /* get L1 child node */
      uint childOffset = root[0];
      __global uint *node = root + (childOffset * nodeSize) + (nodeNumber * nodeSize);

      /* get L2 child node */
      childOffset = node[0];
      *node = root + (childOffset * nodeSize) + (nodeNumber * nodeSize);

       

      If i try to read the value from childOffset after the last line (*node = root + ...), its 255. if i comment the last line out, it is 9 as expected (in my memory layout). But how is the last line changing a value in childOffset? (Btw. why do i get a build error for // comments in kernels? :/)

       

      If I use different variable names  names for each "step" i also get the right result (just continued for the next levels)

      uint childOffset3 = node2[0];
        __global uint *node3 = root + (childOffset3 * nodeSize) + (nodeNumber * nodeSize);

        /* get L4 child node */ 
      uint childOffset4 = node3[0];
      __global uint *node4 = root + (childOffset4 * nodeSize) + (nodeNumber * nodeSize);

       If i now access childOffset1 - childOffset4 i have the right values. Any idead of what kind of stupid error i did?

       

      Thanks

       

       

        • reusing variables
          malcolm3141

          I would guess the issue is aliasing. The childOffset variable aliases both the root[0] memory and the node[0] memory.

          I believe that the default optimisations in most OpenCL compilers assume no aliasing. You can probably get around this issue using a memory barrier between the last two lines (between the read and write). Otherwise, just try not to alias the pointers, or enable strict aliasing with a compiler option.

           

          Malcolm

           

            • reusing variables
              foofel

              Hey, thanks for your idea but unfortunately it didn't work. Maybe i need to think about another approach if this doesn't fit with the way opencl works.

                • reusing variables
                  LeeHowes

                  Try sticking a memory fence between childOsset = node[0] and *node = root...

                  Looking at your code it looks like you intended node = without the *? You've not updated node, you've set the value in the tree at address node. So given the difference between that and the very last line I think you have a bug in your code anyway, though that doesn't immediately explain the problem.

                  This write will change the value of childOffset IF childOffset = node[0] is performed AFTER the write to node. In the absense of a memory fence and given the relaxed memory consistency model of OpenCL this is probably a valid compiler transformation. If you put a memory fence in there you guarantee that the compiler won't reorder across it and the read should be performed before the write. It would be worth checking the memory consistency model if the fences fixes it for you to see if this is right.

                   

                   

                   

                  ETA: malcolm basically said the fence thing. I should read more carefully before I post.

                    • reusing variables
                      foofel

                       

                      Originally posted by: LeeHowes ...Looking at your code it looks like you intended node = without the *? You've not updated node, you've set the value in the tree at address node. So given the difference between that and the very last line I think you have a bug in your code anyway,...


                      Thanks, it works! Sometimes I am just blind