5 Replies Latest reply on Sep 15, 2009 12:05 AM by Gipsel

    Is it possible to do the same in kernel code?

    Raistmer
      brook gives error...

      I need to zero last few bits in float number before int cast (last bits contain noise that should be eliminated before type conversion).

      In CPU code I use:

      float tmp=thresh_x *(float) sqrt((float)2.0 *(float) ncb);
      unsigned tmp1=((*(unsigned*)(&tmp))&0xFFFFF000);
      thresh_tbl = ncb + (int)( *((float*)(&tmp1)) );

      But this gives error inside kernel:

      Operator not supported in kernel: variable address(&)
      Statement: &tmp in tmp1 = *((uint *) &tmp) & 0xfffff000
      and

      Operator not supported in kernel: pointer dereference(*)
      Statement: *((uint *) &tmp) in tmp1 = *((uint *) &tmp) & 0xfffff000

      and

      ERROR--3: In Binary expression: implicit conversion from right type to left type
      Statement: *((uint *) &tmp) & 0xfffff000 in tmp1 = *((uint *) &tmp) & 0xfffff000
      Expression : *((uint *) &tmp), Type : uint
      Expression : 0xfffff000, Type : int

      Is it possible to do such bit zeroing inside GPU kernel?
      Maybe some another way ?
        • Is it possible to do the same in kernel code?
          Gipsel

           

          Originally posted by: Raistmer I need to zero last few bits in float number before int cast (last bits contain noise that should be eliminated before type conversion). In CPU code I use: float tmp=thresh_x *(float) sqrt((float)2.0 *(float) ncb); unsigned tmp1=((*(unsigned*)(&tmp))&0xFFFFF000); thresh_tbl = ncb + (int)( *((float*)(&tmp1)) ); But this gives error inside kernel: Operator not supported in kernel: variable address(& Statement: &tmp in tmp1 = *((uint *) &tmp) & 0xfffff000 and Operator not supported in kernel: pointer dereference(*) Statement: *((uint *) &tmp) in tmp1 = *((uint *) &tmp) & 0xfffff000 and ERROR--3: In Binary expression: implicit conversion from right type to left type Statement: *((uint *) &tmp) & 0xfffff000 in tmp1 = *((uint *) &tmp) & 0xfffff000 Expression : *((uint *) &tmp), Type : uint Expression : 0xfffff000, Type : int Is it possible to do such bit zeroing inside GPU kernel? Maybe some another way ?


          Isn't it working if you disable strong type checking (it's a bit annoying at times) just omit all those type conversion and simply do the binary AND?

          float temp = some_value_or_expression;

          tresh_tbl = ncb + (int)(temp & 0xfffff000);

          Looks much simpler to me and for the hardware it shouldn't matter.

            • Is it possible to do the same in kernel code?
              gaurav.garg

              Brook+ doesn't support pointers. As mentioned in error, you are using variable addressing and pointer dereference, both are invalid.

                • Is it possible to do the same in kernel code?
                  Raistmer
                  Originally posted by: gaurav.garg

                  Brook+ doesn't support pointers. As mentioned in error, you are using variable addressing and pointer dereference, both are invalid.



                  I understand this.
                  I use pointer type conversion just to make float number be treated as integer for bitwise and do work.
                  If any other way exist to do same thing it would be very nice to know it...
                • Is it possible to do the same in kernel code?
                  Raistmer
                  Originally posted by: Gipsel

                  Originally posted by: Raistmer I need to zero last few bits in float number before int cast (last bits contain noise that should be eliminated before type conversion). In CPU code I use: float tmp=thresh_x *(float) sqrt((float)2.0 *(float) ncb); unsigned tmp1=((*(unsigned*)(&tmp))&0xFFFFF000); thresh_tbl = ncb + (int)( *((float*)(&tmp1)) ); But this gives error inside kernel: Operator not supported in kernel: variable address(&) Statement: &tmp in tmp1 = *((uint *) &tmp) & 0xfffff000 and Operator not supported in kernel: pointer dereference(*) Statement: *((uint *) &tmp) in tmp1 = *((uint *) &tmp) & 0xfffff000 and ERROR--3: In Binary expression: implicit conversion from right type to left type Statement: *((uint *) &tmp) & 0xfffff000 in tmp1 = *((uint *) &tmp) & 0xfffff000 Expression : *((uint *) &tmp), Type : uint Expression : 0xfffff000, Type : int Is it possible to do such bit zeroing inside GPU kernel? Maybe some another way ?





                  Isn't it working if you disable strong type checking (it's a bit annoying at times) just omit all those type conversion and simply do the binary AND?




                  float temp = some_value_or_expression;




                  tresh_tbl = ncb + (int)(temp & 0xfffff000);




                  Looks much simpler to me and for the hardware it shouldn't matter.




                  It seems it not work....
                  Maybe I did something wrong?

                  Error:
                  ERROR--1: : left operand is not a Integer type
                  Statement: tmp & 0xfffffff0 in thresh_tbl = ncb + (int ) tmp & 0xfffffff0
                  Expression : tmp, Type : float
                  Expression : 0xfffffff0, Type : int
                  ***Semantic check found 1 errors

                  Code:
                  float thresh_x;
                  float tmp;
                  //unsigned tmp1;
                  nfb=nfb<<ttidx_pre;
                  thresh_x = (float)thresh_x_intercept + (float)thresh_x_slope * (float)nfb;
                  tmp=thresh_x *(float) sqrt((float)2.0 *(float) ncb);
                  //tmp1=((*(unsigned*)(&tmp))&0xFFFFF000);
                  thresh_tbl = ncb + (int)( tmp&0xFFFFFFF0 );

                  command line:

                  mkdir brookgenfiles | "$(BROOKROOT)\sdk\bin\brcc.exe" -a -o "$(ProjectDir)\..\..\brookgenfiles\$(InputName)" "$(InputPath)"

                  More ideas, please?
                    • Is it possible to do the same in kernel code?
                      Gipsel

                       

                      Originally posted by: RaistmerMore ideas, please?


                      If you have some knowledge about the size of the values, it may be possible just to omit the AND, as the last bits are truncated either way by the float to int conversion (maybe you need to shift your values to an appropriate range first).

                      If not, from my experience it would be the easiest just to write a placeholder subkernel and edit the Brook generated IL to do what you want (equivalent of my non-working version, just do the AND without any conversions). IL is untyped, so it would work on that level

                      But it is quite late here already, maybe there is a more elegant solution.