2 Replies Latest reply on May 8, 2015 3:06 PM by astylinski

    Issues with AMD libM

    astylinski

      I wasn't sure if this was the correct place to post this, as I couldn't find a libM specific forum.  I'm currently using in Windows the amd_vrd2_sincos() function by dynamically linking to libM with the MSVC100 compiler (I tried forcing static, it didn't seem to change my results).  For whatever reason the sincos values appear incorrect and the same for some number of calls into amd_vrd2_sincos().  I call amd_vrd2_sin & cos on the same angles separately and I get the correct results for all calls that I perform the sincos function for.  In Linux, I do not seem to have this issue.  Please let me know what I can provide to help debug the issue further.

        • Re: Issues with AMD libM
          astylinski

          An example:

          #define _USE_MATH_DEFINES

          #include <math.h>

          #include <amdlibm.h>

          #include <stdlib.h>

          #include <stdio.h>

           

           

          #define NUM_ANGLES 80

          #define VEC_SIZE 2

           

           

          int main(void)

          {

              __m128d *angles = (__m128d*)_mm_malloc(sizeof(double)*(NUM_ANGLES + 1), 16);

              double *anglesDbl = (double*)angles;

           

           

              for (size_t i = 0; i < NUM_ANGLES; ++i) {

                  double x = (float)rand()/(float)(RAND_MAX/(M_PI*2));

                  anglesDbl[i] = x;

              }

           

           

              size_t nIterations = (NUM_ANGLES % VEC_SIZE == 0) ?

                  NUM_ANGLES / VEC_SIZE : NUM_ANGLES / VEC_SIZE + 1;

           

           

              for (size_t i = 0; i < nIterations; ++i) {

                  __m128d sinVal, cosVal;

                  __m128d sinVal2, cosVal2;

                  amd_vrd2_sincos(angles[i], &sinVal, &cosVal);

                  sinVal2 = amd_vrd2_sin(angles[i]);

                  cosVal2 = amd_vrd2_cos(angles[i]);

           

           

                  double *svDbl = (double*)&sinVal;

                  double *cvDbl = (double*)&cosVal;

                  double *sv2Dbl = (double*)&sinVal2;

                  double *cv2Dbl = (double*)&cosVal2;

           

           

                  printf("sincos(with sincos) = [(%lf, %lf), (%lf, %lf)], sincos = [(%lf, %lf), (%lf, %lf)]\n",

                      svDbl[0], cvDbl[0], svDbl[1],  cvDbl[1], sv2Dbl[0], cv2Dbl[0], sv2Dbl[1], cv2Dbl[1]);

              }

           

           

              return 0;

          }

           

          edit: ahhh actually I can't reproduce this for my trivial test case.  It is definitely incorrect when called correctly in my code, though, so the issue may be more nuanced than first anticipated.  I'll add to this once I produce a test case that reliably reproduces my issue.

            • Re: Issues with AMD libM
              astylinski

              Ok so it's seeming to fail after 70 something calls:

               

              #define _USE_MATH_DEFINES

              #include <math.h>

              #include <amdlibm.h>

              #include <stdlib.h>

              #include <stdio.h>

              #include <assert.h>

               

               

              #define NUM_ANGLES 8000

              #define VEC_SIZE 2

               

               

              int main(void)

              {

                  __m128d *angles = (__m128d*)_mm_malloc(sizeof(double)*(NUM_ANGLES + 1), 16);

                  double *anglesDbl = (double*)angles;

               

               

                  for (size_t i = 0; i < NUM_ANGLES; ++i) {

                      double x = (float)rand()/(float)(RAND_MAX/(M_PI*2));

                      anglesDbl[i] = x;

                      //if (i == 72) printf("angle[72] = %lf, %lf\n", anglesDbl[72], anglesDbl[73]);

                  }

               

               

               

               

               

               

                  size_t nIterations = (NUM_ANGLES % VEC_SIZE == 0) ?

                      NUM_ANGLES / VEC_SIZE : NUM_ANGLES / VEC_SIZE + 1;

               

               

                  for (size_t i = 0; i < nIterations; ++i) {

                      __m128d sinVal, cosVal;

                      __m128d sinVal2, cosVal2;

                      amd_vrd2_sincos(angles[i], &sinVal, &cosVal);

                      sinVal2 = amd_vrd2_sin(angles[i]);

                      cosVal2 = amd_vrd2_cos(angles[i]);

               

               

                      double *svDbl = (double*)&sinVal;

                      double *cvDbl = (double*)&cosVal;

                      double *sv2Dbl = (double*)&sinVal2;

                      double *cv2Dbl = (double*)&cosVal2;

               

               

               

               

                      if (i == 72) fprintf(stderr,"sincos(with sincos) = [(%lf, %lf), (%lf, %lf)], sincos = [(%lf, %lf), (%lf, %lf)]\n",

                          svDbl[0], cvDbl[0], svDbl[1],  cvDbl[1], sv2Dbl[0], cv2Dbl[0], sv2Dbl[1], cv2Dbl[1]);

                      fprintf(stderr, "i = %ld, angle[i] = %lf, %lf\n", i, anglesDbl[2*i], anglesDbl[2*i + 1]);

                      assert(svDbl[0] == sv2Dbl[0]);

                      assert(svDbl[1] == sv2Dbl[1]);

                      assert(cvDbl[0] == cv2Dbl[0]);

                      assert(cvDbl[1] == cv2Dbl[1]);

                  }

               

               

                  return 0;

              }