[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