3 Replies Latest reply on Nov 13, 2009 11:29 AM by AIF Bob

    float4 == float4 bug. Different result between Flash and toolkit

    Andy Li onthewings

      I used the following pb:

       

      <languageVersion: 1.0;>
      kernel NewKernel
      <
          namespace: "Namespace";
          vendor: "Vendor";
          version: 1;
          description: "Your Description";
      >
      {
          input image4 src;
          output pixel4 dst;

       

          void evaluatePixel()
          {       
              float4 B = float4(0.1,0.2,0.3,1.0);
              float4 C = float4(0.1,0.2,0.3,1.0);
              if (B == C){
                  //it should be here
                  dst = float4(1.0,1.0,1.0,1.0);//white
              } else {
                  //but in Flash, it goes here
                  dst = float4(1.0,0.0,0.0,1.0);//red
              }
          }
      }

       


      In the toolkit (1.5.1) it produces a white image, which is what I expected.

      But when I export to pbj and used in Flash, it produces a red image.

      Funny enough, if both B and C in the code are changed to float4(1.0,1.0,1.0,1.0), it produce white (B==C is true again).

       

      With a few simple testings, float2 and float3 have the same bug too, but float is ok...

       

      Testing-use Flex project with pbk is attached.

        • 1. Re: float4 == float4 bug. Different result between Flash and toolkit
          souldreamer

          It's actually a common problem in programming. You should never directly test two floats for equality (due to internal representation artifacts, (a=1.0)!=1.0 could very well happen). Instead of "if (f1 == f2)," you could use "if (abs(length(f1 - f2)) < EPSILON)," where EPSILON is a constant you define as something really small. usually 0.000001 works well.

           

          Another solution would be using the "if (all(equal(f1, f2)))" syntax (which only works for float2, float3 and float4, not for single float scalars). I'm not sure which is faster, and would probably need to be tested in the optimization stage on the specific platform you're developing for (especially see what the CPU/GPU difference is)

          1 person found this helpful
          • 2. Re: float4 == float4 bug. Different result between Flash and toolkit
            Andy Li onthewings Level 1

            Actually I don't mind if the equality of the two variables should or should not be true, although I find it more logical and usful if it is true, but at least the PB toolkit and the Flash Player should result the same.

             

            And I used the same workaround as your second suggestion (all(equal(a, b)), which works, but looks more complex and harder to maintain than a == b.

            • 3. Re: float4 == float4 bug. Different result between Flash and toolkit
              AIF Bob Level 3

              There's more than one thing going on here.

               

              First, there is a bug in the Flash Player runtime which means that comparing two float4s does not work properly. We've logged it, it will get fixed. In the meantime, the workaround is the one that souldreamer suggested - use all(equal(f1, f2)).

               

              Having said that, as souldreamer also stated, in the general case, floating point equality comparisons are a bad idea. In the particular case of the original post the comparison should have worked because the exact same value was being assigned to both variables, in the more general case at least one of the variables will have been set from a computation. Rounding errors, optimzation differences and the fact that not all decimal numbers are exactly representable in the IEEE floating point format mean that it's unlikely you'll get exact results from a floating point computation. Again, as souldreamer suggested, comparing values to be within some epsilon is the usual workaround.

               

              Finally, on the more general point of whether the Flash Player runtime should match the toolkit runtime (and remember that the toolkit has a choice of CPU and GPU, and not all GPUs handle things in exactly the same manner). We would love it if all our runtimes matched exactly, however that's extremely difficult to do and would result in us losing performance. Floating point calculation is the big culprit, there are also issues such as dividing by zero, and do a search though the documentation for the word "undefined". Anything that's undefined is a candidate for being different on different platforms.