[test-suite] r289417 - [test-suite] fix beamformer for CFLAGS="-ffp-contract=on"

Sebastian Pop via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 11 20:27:52 PST 2016


Author: spop
Date: Sun Dec 11 22:27:51 2016
New Revision: 289417

URL: http://llvm.org/viewvc/llvm-project?rev=289417&view=rev
Log:
[test-suite] fix beamformer for CFLAGS="-ffp-contract=on"

This patch fixes MultiSource/Benchmarks/VersaBench/beamformer when compiled with
-ffp-contract=on.

Differential Revision: https://reviews.llvm.org/D25923

Modified:
    test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/CMakeLists.txt
    test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/Makefile
    test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/beamformer.c

Modified: test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/CMakeLists.txt?rev=289417&r1=289416&r2=289417&view=diff
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/CMakeLists.txt (original)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/CMakeLists.txt Sun Dec 11 22:27:51 2016
@@ -10,4 +10,5 @@ else()
   endif()
 endif()
 set(HASH_PROGRAM_OUTPUT 1)
+add_definitions(-DFP_ABSTOLERANCE=1e-5)
 llvm_multisource()

Modified: test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/Makefile
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/Makefile?rev=289417&r1=289416&r2=289417&view=diff
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/Makefile (original)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/Makefile Sun Dec 11 22:27:51 2016
@@ -1,5 +1,6 @@
 LEVEL = ../../../..
 LDFLAGS += -lm
+CFLAGS += -DFP_ABSTOLERANCE=1e-5
 
 PROG     = beamformer
 ifdef LARGE_PROBLEM_SIZE

Modified: test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/beamformer.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/beamformer.c?rev=289417&r1=289416&r2=289417&view=diff
==============================================================================
--- test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/beamformer.c (original)
+++ test-suite/trunk/MultiSource/Benchmarks/VersaBench/beamformer/beamformer.c Sun Dec 11 22:27:51 2016
@@ -86,6 +86,18 @@ void BeamForm(int beam, const float *wei
 void Magnitude(float *in, float *out, int n);
 void Detector(int beam, float *data, float *output);
 
+void begin_StrictFP(void);
+void InputGenerate_StrictFP(int channel, float *inputs, int n);
+void BeamFirSetup_StrictFP(struct BeamFirData *data, int n);
+void BeamFirFilter_StrictFP(struct BeamFirData *data,
+                            int input_length, int decimation_ratio,
+                            float *in, float *out);
+void BeamFormWeights_StrictFP(int beam, float *weights);
+void BeamForm_StrictFP(int beam, const float *weights, const float *input,
+                       float *output);
+void Magnitude_StrictFP(float *in, float *out, int n);
+void Detector_StrictFP(int beam, float *data, float *output);
+
 #define NUM_CHANNELS 12
 #define NUM_SAMPLES 1024
 #define NUM_BEAMS 4
@@ -109,6 +121,7 @@ void Detector(int beam, float *data, flo
 #define D_OVER_LAMBDA 0.5
 #define CFAR_THRESHOLD (0.95*D_OVER_LAMBDA*NUM_CHANNELS*0.5*PULSE_SIZE)
 
+float detector_out_StrictFP[NUM_BEAMS][NUM_POST_DEC_2];
 static int numiters = 100;
 
 int main(int argc, char **argv)
@@ -124,10 +137,25 @@ int main(int argc, char **argv)
     }
   }
 
+  begin_StrictFP();
   begin();
   return 0;
 }
 
+/* Return 0 when V1 and V2 do not match within the allowed FP_ABSTOLERANCE.  */
+static inline int
+check_FP(float V1, float V2) {
+  double AbsTolerance = FP_ABSTOLERANCE;
+  double Diff = fabs(V1 - V2);
+  if (Diff > AbsTolerance) {
+    fprintf(stderr, "A = %lf and B = %lf differ more than"
+                  " FP_ABSTOLERANCE = %lf\n", V1, V2, AbsTolerance);
+    return 0;
+  }
+
+  return 1;
+}
+
 /* What are the counts here?  Deriving:
  *
  * Detector takes TARGET_SAMPLE_POST_DEC inputs.
@@ -219,12 +247,15 @@ void begin(void)
       Detector(i, beam_fir_mag, detector_out[i]);
     }
     for (j = 0; j < NUM_POST_DEC_2; j++)
-      for (i = 0; i < NUM_BEAMS; i++)
+      for (i = 0; i < NUM_BEAMS; i++) {
+        if (!check_FP(detector_out[i][j], detector_out_StrictFP[i][j]))
+          exit(1);
 #ifdef AVOID_PRINTF
         result = detector_out[i][j];
 #else
-        printf("%f\n", detector_out[i][j]);
+        printf("%f\n", detector_out_StrictFP[i][j]);
 #endif
+      }
   }
 
   /*** VERSABENCH END ***/
@@ -383,6 +414,249 @@ void Detector(int beam, float *data, flo
   int sample;
   /* Should be exactly NUM_POST_DEC_2 samples. */
   for (sample = 0; sample < NUM_POST_DEC_2; sample++)
+  {
+    float outputVal;
+    if (beam == TARGET_BEAM && sample == TARGET_SAMPLE) {
+      if (data[sample] >= 0.1)
+        outputVal = beam+1;
+      else
+        outputVal = 0;
+    } else {
+      if (data[sample] >= 0.1)
+        outputVal = -(beam+1);
+      else
+        outputVal = 0;
+    }
+    outputVal = data[sample];
+    output[sample]= outputVal;
+  }
+}
+
+void begin_StrictFP(void)
+{
+#pragma STDC FP_CONTRACT OFF
+  struct BeamFirData coarse_fir_data[NUM_CHANNELS];
+  struct BeamFirData fine_fir_data[NUM_CHANNELS];
+  struct BeamFirData mf_fir_data[NUM_BEAMS];
+  float inputs[2*NUM_SAMPLES*NUM_CHANNELS];
+  float predec[2*NUM_POST_DEC_1*NUM_CHANNELS];
+  float postdec[NUM_CHANNELS][2*NUM_POST_DEC_2*NUM_CHANNELS];
+  float beam_weights[NUM_BEAMS][2*NUM_CHANNELS];
+  float beam_input[2*NUM_CHANNELS*NUM_POST_DEC_2];
+  float beam_output[2*NUM_POST_DEC_2];
+  float beam_fir_output[2*NUM_POST_DEC_2];
+  float beam_fir_mag[NUM_POST_DEC_2];
+  int i, j;
+
+  for (i = 0; i < NUM_CHANNELS; i++)
+  {
+    BeamFirSetup_StrictFP(&coarse_fir_data[i], NUM_COARSE_TAPS);
+    BeamFirSetup_StrictFP(&fine_fir_data[i], NUM_FINE_TAPS);
+  }
+  for (i = 0; i < NUM_BEAMS; i++)
+  {
+    BeamFirSetup_StrictFP(&mf_fir_data[i], MF_SIZE);
+    BeamFormWeights_StrictFP(i, beam_weights[i]);
+  }
+
+  for (i = 0; i < NUM_CHANNELS; i++) {
+    for (j = 0; j < NUM_CHANNELS; j++)
+      InputGenerate_StrictFP(i, inputs + j*NUM_SAMPLES*2,
+                             NUM_SAMPLES);
+    for (j = 0; j < NUM_POST_DEC_1; j++)
+      BeamFirFilter_StrictFP(&coarse_fir_data[i],
+                             NUM_SAMPLES, COARSE_DECIMATION_RATIO,
+                             inputs + j * COARSE_DECIMATION_RATIO*2,
+                             predec + j * 2);
+    for (j = 0; j < NUM_POST_DEC_2; j++)
+      BeamFirFilter_StrictFP(&fine_fir_data[i],
+                             NUM_POST_DEC_1, FINE_DECIMATION_RATIO,
+                             predec + j * FINE_DECIMATION_RATIO * 2,
+                             postdec[i] + j * 2);
+  }
+  /* Assemble beam-forming input: */
+  for (i = 0; i < NUM_CHANNELS; i++)
+    for (j = 0; j < NUM_POST_DEC_2; j++)
+      {
+        beam_input[j*NUM_CHANNELS*2+2*i] = postdec[i][2*j];
+        beam_input[j*NUM_CHANNELS*2+2*i+1] = postdec[i][2*j+1];
+      }
+  for (i = 0; i < NUM_BEAMS; i++)
+    {
+      /* Have now rearranged NUM_CHANNELS*NUM_POST_DEC_2 items.
+       * BeamForm takes NUM_CHANNELS inputs, 2 outputs. */
+      for (j = 0; j < NUM_POST_DEC_2; j++)
+        BeamForm_StrictFP(i, beam_weights[i],
+                          beam_input + j*NUM_CHANNELS*2,
+                          beam_output + j*2);
+      for (j = 0; j < NUM_POST_DEC_2; j++)
+        BeamFirFilter_StrictFP(&mf_fir_data[i],
+                               NUM_POST_DEC_2, 1,
+                               beam_output+j*2, beam_fir_output+j*2);
+      Magnitude_StrictFP(beam_fir_output, beam_fir_mag, NUM_POST_DEC_2);
+      Detector_StrictFP(i, beam_fir_mag, detector_out_StrictFP[i]);
+    }
+}
+
+void InputGenerate_StrictFP(int channel, float *inputs, int n)
+{
+#pragma STDC FP_CONTRACT OFF
+  int i;
+  for (i = 0; i < n; i++)
+  {
+    if (channel == TARGET_BEAM && i == TARGET_SAMPLE)
+    {
+#ifdef RANDOM_INPUTS
+      inputs[2*i] = sqrt(i*channel);
+      inputs[2*i+1] = sqrt(i*channel)+1;
+#else
+      inputs[2*i] = sqrt(CFAR_THRESHOLD);
+      inputs[2*i+1] = 0;
+#endif
+    } else {
+#ifdef RANDOM_INPUTS
+      float root = sqrt(i*channel);
+      inputs[2*i] = -root;
+      inputs[2*i+1] = -(root+1);
+#else
+      inputs[2*i] = 0;
+      inputs[2*i+1] = 0;
+#endif
+    }
+  }
+}
+
+void BeamFirSetup_StrictFP(struct BeamFirData *data, int n)
+{
+#pragma STDC FP_CONTRACT OFF
+  int i, j;
+
+  data->len = n;
+  data->count = 0;
+  data->pos = 0;
+  data->weight = malloc(sizeof(float)*2*n);
+  data->buffer = malloc(sizeof(float)*2*n);
+
+#ifdef RANDOM_WEIGHTS
+  for (j = 0; j < n; j++) {
+    int idx = j+1;
+    data->weight[j*2] = sin(idx) / ((float)idx);
+    data->weight[j*2+1] = cos(idx) / ((float)idx);
+    data->buffer[j*2] = 0.0;
+    data->buffer[j*2+1] = 0.0;
+  }
+#else
+  data->weight[0] = 1.0;
+  data->weight[1] = 0.0;
+  for (i = 1; i < 2*n; i++) {
+    data->weight[i] = 0.0;
+    data->buffer[i] = 0.0;
+  }
+#endif
+}
+
+void BeamFirFilter_StrictFP(struct BeamFirData *data,
+                            int input_length, int decimation_ratio,
+                            float *in, float *out)
+{
+#pragma STDC FP_CONTRACT OFF
+  /* Input must be exactly 2*decimation_ratio long; output must be
+   * exactly 2 long. */
+  float real_curr = 0;
+  float imag_curr = 0;
+  int i;
+  int modPos;
+  int len, mask, mask2;
+
+  len = data->len;
+  mask = len - 1;
+  mask2 = 2 * len - 1;
+  modPos = 2*(len - 1 - data->pos);
+  data->buffer[modPos] = in[0];
+  data->buffer[modPos+1] = in[1];
+
+  /* Profiling says: this is the single inner loop that matters! */
+  for (i = 0; i < 2*len; i+=2) {
+    float rd = data->buffer[modPos];
+    float id = data->buffer[modPos+1];
+    float rw = data->weight[i];
+    float iw = data->weight[i+1];
+    float rci = rd * rw + id * iw;
+    /* sign error?  this is consistent with StreamIt --dzm */
+    float ici = id * rw + rd * iw;
+    real_curr += rci;
+    imag_curr += ici;
+    modPos = (modPos + 2) & mask2;
+  }
+
+  data->pos = (data->pos + 1) & mask;
+  out[0] = real_curr;
+  out[1] = imag_curr;
+  data->count += decimation_ratio;
+  if (data->count == input_length)
+  {
+    data->count = 0;
+    data->pos = 0;
+    for (i = 0; i < 2*data->len; i++) {
+      data->buffer[i] = 0.0;
+    }
+  }
+}
+
+void BeamFormWeights_StrictFP(int beam, float *weights)
+{
+#pragma STDC FP_CONTRACT OFF
+  int i;
+  for (i = 0; i < NUM_CHANNELS; i++)
+  {
+#ifdef RANDOM_WEIGHTS
+    int idx = i+1;
+    weights[2*i] = sin(idx) / (float)(beam+idx);
+    weights[2*i+1] = cos(idx) / (float)(beam+idx);
+#else
+    if (i == beam) {
+      weights[2*i] = 1;
+      weights[2*i+1] = 0;
+    } else {
+      weights[2*i] = 0;
+      weights[2*i+1] = 0;
+    }
+#endif
+  }
+}
+
+void BeamForm_StrictFP(int beam, const float *weights, const float *input,
+                       float *output)
+{
+#pragma STDC FP_CONTRACT OFF
+  /* 2*NUM_CHANNELS inputs and weights; 2 outputs. */
+  float real_curr = 0;
+  float imag_curr = 0;
+  int i;
+  for (i = 0; i < NUM_CHANNELS; i++)
+  {
+    real_curr += weights[2*i] * input[2*i] - weights[2*i+1] * input[2*i+1];
+    imag_curr += weights[2*i] * input[2*i+1] + weights[2*i+1] * input[2*i];
+  }
+  output[0] = real_curr;
+  output[1] = imag_curr;
+}
+
+void Magnitude_StrictFP(float *in, float *out, int n)
+{
+#pragma STDC FP_CONTRACT OFF
+  int i;
+  /* Should be 2n inputs, n outputs. */
+  for (i = 0; i < n; i++)
+    out[i] = sqrt(in[2*i]*in[2*i] + in[2*i+1]*in[2*i+1]);
+}
+
+void Detector_StrictFP(int beam, float *data, float *output)
+{
+#pragma STDC FP_CONTRACT OFF
+  int sample;
+  /* Should be exactly NUM_POST_DEC_2 samples. */
+  for (sample = 0; sample < NUM_POST_DEC_2; sample++)
   {
     float outputVal;
     if (beam == TARGET_BEAM && sample == TARGET_SAMPLE) {




More information about the llvm-commits mailing list