Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Unified Diff: third_party/openmax_dl/dl/sp/src/test/test_fft_time.c

Issue 12317152: Add openmax dl routines for review. MUST NOT BE LANDED (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/openmax_dl/dl/sp/src/test/test_fft_time.c
diff --git a/third_party/openmax_dl/dl/sp/src/test/test_fft_time.c b/third_party/openmax_dl/dl/sp/src/test/test_fft_time.c
new file mode 100644
index 0000000000000000000000000000000000000000..a401594b5137a3e19a96a895dc637e83af2fd10d
--- /dev/null
+++ b/third_party/openmax_dl/dl/sp/src/test/test_fft_time.c
@@ -0,0 +1,1075 @@
+/*
+ * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "dl/sp/api/armSP.h"
+#include "dl/sp/api/omxSP.h"
+#include "dl/sp/src/test/aligned_ptr.h"
+#include "dl/sp/src/test/gensig.h"
+
+#define MAX_FFT_ORDER TWIDDLE_TABLE_ORDER
+#define MAX_FFT_ORDER_FIXED_POINT 12
+
+void TimeOneFloatFFT(int count, int fft_log_size, float signal_value,
+ int signal_type);
+void TimeFloatFFT(int count, float signal_value, int signal_type);
+void TimeOneFloatRFFT(int count, int fft_log_size, float signal_value,
+ int signal_type);
+void TimeFloatRFFT(int count, float signal_value, int signal_type);
+void TimeOneSC32FFT(int count, int fft_log_size, float signal_value,
+ int signal_type);
+void TimeSC32FFT(int count, float signal_value, int signal_type);
+void TimeOneRFFT16(int count, int fft_log_size, float signal_value,
+ int signal_type);
+void TimeRFFT16(int count, float signal_value, int signal_type);
+void TimeOneRFFT32(int count, int fft_log_size, float signal_value,
+ int signal_type);
+void TimeRFFT32(int count, float signal_value, int signal_type);
+
+static int verbose = 1;
+static int include_conversion = 0;
+static int adapt_count = 1;
+static int do_forward_test = 1;
+static int do_inverse_test = 1;
+static int min_fft_order = 2;
+static int max_fft_order = MAX_FFT_ORDER;
+
+void TimeFFTUsage(const char* prog) {
+ fprintf(stderr,
+ "%s: [-hTFICA] [-f fft] [-c count] [-n logsize] [-s scale]\n"
+ " [-g signal-type] [-S signal value]\n"
+ " [-m minFFTsize] [-M maxFFTsize]\n",
+ ProgramName(prog));
+ fprintf(stderr,
+ "Simple FFT timing tests\n"
+ " -h This help\n"
+ " -v level Verbose output level (default = 1)\n"
+ " -F Skip forward FFT tests\n"
+ " -I Skip inverse FFT tests\n"
+ " -C Include float-to-fixed and fixed-to-float cost for"
+ " real\n"
+ " 16-bit FFT (forward and inverse)\n"
+ " -c count Number of FFTs to compute for timing. This is a"
+ " lower\n"
+ " lower limit; shorter FFTs will do more FFTs such"
+ " that the\n"
+ " elapsed time is very roughly constant, if -A is"
+ " not given.\n"
+ " -A Don't adapt the count given by -c; use specified"
+ " value\n"
+ " -m min Mininum FFT order to test\n"
+ " -M max Maximum FFT order to test\n"
+ " -T Run just one FFT timing test\n"
+ " -f FFT type:\n"
+ " 0 - Complex Float\n"
+ " 1 - Real Float\n"
+ " 2 - Complex 32-bit\n"
+ " 3 - Real 16-bit\n"
+ " 4 - Real 32-bit\n"
+ " -n logsize Log2 of FFT size\n"
+ " -s scale Scale factor for forward FFT (default = 0)\n"
+ " -S signal Base value for the test signal (default = 1024)\n"
+ " -g type Input signal type:\n"
+ " 0 - Constant signal S + i*S. (Default value.)\n"
+ " 1 - Real ramp starting at S/N, N = FFT size\n"
+ " 2 - Sine wave of amplitude S\n"
+ " 3 - Complex signal whose transform is a sine wave.\n"
+ "\n"
+ "Use -v 0 in combination with -F or -I to get output that can\n"
+ "be pasted into a spreadsheet.\n"
+ "\n"
+ "Most of the options listed after -T above are only applicable\n"
+ "when -T is given to test just one FFT size and FFT type.\n"
+ "\n");
+ exit(0);
+}
+
+void main(int argc, char* argv[]) {
+ int fft_log_size = 4;
+ float signal_value = 1024;
+ int signal_type = 0;
+ int test_mode = 1;
+ int count = 100;
+ int fft_type = 0;
+ int fft_type_given = 0;
+
+ int opt;
+
+ while ((opt = getopt(argc, argv, "hTFICAc:n:s:S:g:v:f:m:M:")) != -1) {
+ switch (opt) {
+ case 'h':
+ TimeFFTUsage(argv[0]);
+ break;
+ case 'T':
+ test_mode = 0;
+ break;
+ case 'C':
+ include_conversion = 1;
+ break;
+ case 'F':
+ do_forward_test = 0;
+ break;
+ case 'I':
+ do_inverse_test = 0;
+ break;
+ case 'A':
+ adapt_count = 0;
+ break;
+ case 'c':
+ count = atoi(optarg);
+ break;
+ case 'n':
+ fft_log_size = atoi(optarg);
+ break;
+ case 'S':
+ signal_value = atof(optarg);
+ break;
+ case 'g':
+ signal_type = atoi(optarg);
+ break;
+ case 'v':
+ verbose = atoi(optarg);
+ break;
+ case 'f':
+ fft_type = atoi(optarg);
+ fft_type_given = 1;
+ break;
+ case 'm':
+ min_fft_order = atoi(optarg);
+ if (min_fft_order <= 2) {
+ fprintf(stderr, "Setting min FFT order to 2 (from %d)\n",
+ min_fft_order);
+ min_fft_order = 2;
+ }
+ break;
+ case 'M':
+ max_fft_order = atoi(optarg);
+ if (max_fft_order > MAX_FFT_ORDER) {
+ fprintf(stderr, "Setting max FFT order to %d (from %d)\n",
+ MAX_FFT_ORDER, max_fft_order);
+ max_fft_order = MAX_FFT_ORDER;
+ }
+ break;
+ default:
+ TimeFFTUsage(argv[0]);
+ break;
+ }
+ }
+
+ if (test_mode && fft_type_given)
+ printf("Warning: -f ignored when -T not specified\n");
+
+ if (test_mode) {
+ TimeFloatFFT(count, signal_value, signal_type);
+ TimeFloatRFFT(count, signal_value, signal_type);
+ TimeSC32FFT(count, signal_value, signal_type);
+ TimeRFFT16(count, signal_value, signal_type);
+ TimeRFFT32(count, signal_value, signal_type);
+ } else {
+ switch (fft_type) {
+ case 0:
+ TimeOneFloatFFT(count, fft_log_size, signal_value, signal_type);
+ break;
+ case 1:
+ TimeOneFloatRFFT(count, fft_log_size, signal_value, signal_type);
+ break;
+ case 2:
+ TimeOneSC32FFT(count, fft_log_size, signal_value, signal_type);
+ break;
+ case 3:
+ TimeOneRFFT16(count, fft_log_size, signal_value, signal_type);
+ break;
+ case 4:
+ TimeOneRFFT32(count, fft_log_size, signal_value, signal_type);
+ break;
+ default:
+ fprintf(stderr, "Unknown FFT type: %d\n", fft_type);
+ break;
+ }
+ }
+}
+
+void GetUserTime(struct timeval* time) {
+ struct rusage usage;
+ getrusage(RUSAGE_SELF, &usage);
+ memcpy(time, &usage.ru_utime, sizeof(*time));
+}
+
+double TimeDifference(const struct timeval * start,
+ const struct timeval * end) {
+ double start_time;
+ double end_time;
+ start_time = start->tv_sec + start->tv_usec * 1e-6;
+ end_time = end->tv_sec + end->tv_usec * 1e-6;
+
+ return end_time - start_time;
+}
+
+void PrintResult(const char* prefix, int fft_log_size, double elapsed_time,
+ int count) {
+ if (verbose == 0) {
+ printf("%2d\t%8.4f\t%8d\t%.4e\n",
+ fft_log_size, elapsed_time, count, 1000 * elapsed_time / count);
+ } else {
+ printf("%-18s: order %2d: %8.4f sec for %8d FFTs: %.4e msec/FFT\n",
+ prefix, fft_log_size, elapsed_time, count,
+ 1000 * elapsed_time / count);
+ }
+}
+
+int ComputeCount(int nominal_count, int fft_log_size) {
+ /*
+ * Try to figure out how many repetitions to do for a given FFT
+ * order (fft_log_size) given that we want a repetition of
+ * nominal_count for order 15 FFTs to be the approsimate amount of
+ * time we want to for all tests.
+ */
+
+ int count;
+ if (adapt_count) {
+ double maxTime = ((double) nominal_count) * (1 << MAX_FFT_ORDER)
+ * MAX_FFT_ORDER;
+ double c = maxTime / ((1 << fft_log_size) * fft_log_size);
+ const int max_count = 10000000;
+
+ count = (c > max_count) ? max_count : c;
+ } else {
+ count = nominal_count;
+ }
+
+ return count;
+}
+
+void TimeOneFloatFFT(int count, int fft_log_size, float signal_value,
+ int signal_type) {
+ struct AlignedPtr* x_aligned;
+ struct AlignedPtr* y_aligned;
+ struct AlignedPtr* z_aligned;
+
+ struct ComplexFloat* x;
+ struct ComplexFloat* y;
+ OMX_FC32* z;
+
+ struct ComplexFloat* y_true;
+
+ OMX_INT n, fft_spec_buffer_size;
+ OMXFFTSpec_C_FC32 * fft_fwd_spec = NULL;
+ OMXFFTSpec_C_FC32 * fft_inv_spec = NULL;
+ int fft_size;
+ struct timeval start_time;
+ struct timeval end_time;
+ double elapsed_time;
+
+ fft_size = 1 << fft_log_size;
+
+ x_aligned = AllocAlignedPointer(32, sizeof(*x) * fft_size);
+ y_aligned = AllocAlignedPointer(32, sizeof(*y) * (fft_size + 2));
+ z_aligned = AllocAlignedPointer(32, sizeof(*z) * fft_size);
+
+ y_true = (struct ComplexFloat*) malloc(sizeof(*y_true) * fft_size);
+
+ x = x_aligned->aligned_pointer_;
+ y = y_aligned->aligned_pointer_;
+ z = z_aligned->aligned_pointer_;
+
+ GenerateTestSignalAndFFT(x, y_true, fft_size, signal_type, signal_value, 0);
+
+ omxSP_FFTGetBufSize_C_FC32(fft_log_size, &fft_spec_buffer_size);
+
+ fft_fwd_spec = (OMXFFTSpec_C_FC32*) malloc(fft_spec_buffer_size);
+ fft_inv_spec = (OMXFFTSpec_C_FC32*) malloc(fft_spec_buffer_size);
+ omxSP_FFTInit_C_FC32(fft_fwd_spec, fft_log_size);
+ omxSP_FFTInit_C_FC32(fft_inv_spec, fft_log_size);
+
+ if (do_forward_test) {
+ GetUserTime(&start_time);
+ for (n = 0; n < count; ++n) {
+ omxSP_FFTFwd_CToC_FC32_Sfs(x, y, fft_fwd_spec);
+ }
+ GetUserTime(&end_time);
+
+ elapsed_time = TimeDifference(&start_time, &end_time);
+
+ PrintResult("Forward Float FFT", fft_log_size, elapsed_time, count);
+ }
+
+ if (do_inverse_test) {
+ GetUserTime(&start_time);
+ for (n = 0; n < count; ++n) {
+ omxSP_FFTInv_CToC_FC32_Sfs(y, z, fft_inv_spec);
+ }
+ GetUserTime(&end_time);
+
+ elapsed_time = TimeDifference(&start_time, &end_time);
+
+ PrintResult("Inverse Float FFT", fft_log_size, elapsed_time, count);
+ }
+
+ FreeAlignedPointer(x_aligned);
+ FreeAlignedPointer(y_aligned);
+ FreeAlignedPointer(z_aligned);
+ free(y_true);
+ free(fft_fwd_spec);
+ free(fft_inv_spec);
+}
+
+void TimeFloatFFT(int count, float signal_value, int signal_type) {
+ int k;
+
+ if (verbose == 0)
+ printf("Float FFT\n");
+
+ for (k = min_fft_order; k <= max_fft_order; ++k) {
+ int testCount = ComputeCount(count, k);
+ TimeOneFloatFFT(testCount, k, signal_value, signal_type);
+ }
+}
+
+void GenerateRealFloatSignal(OMX_F32* x, OMX_FC32* fft, int size,
+ int signal_type, float signal_value)
+{
+ int k;
+ struct ComplexFloat *test_signal;
+ struct ComplexFloat *true_fft;
+
+ test_signal = (struct ComplexFloat*) malloc(sizeof(*test_signal) * size);
+ true_fft = (struct ComplexFloat*) malloc(sizeof(*true_fft) * size);
+ GenerateTestSignalAndFFT(test_signal, true_fft, size, signal_type,
+ signal_value, 1);
+
+ /*
+ * Convert the complex result to what we want
+ */
+
+ for (k = 0; k < size; ++k) {
+ x[k] = test_signal[k].Re;
+ }
+
+ for (k = 0; k < size / 2 + 1; ++k) {
+ fft[k].Re = true_fft[k].Re;
+ fft[k].Im = true_fft[k].Im;
+ }
+
+ free(test_signal);
+ free(true_fft);
+}
+
+void TimeOneFloatRFFT(int count, int fft_log_size, float signal_value,
+ int signal_type) {
+ OMX_F32* x; /* Source */
+ OMX_F32* y; /* Transform */
+ OMX_F32* z; /* Inverse transform */
+
+ OMX_F32* y_true; /* True FFT */
+
+ struct AlignedPtr* x_aligned;
+ struct AlignedPtr* y_aligned;
+ struct AlignedPtr* z_aligned;
+
+
+ OMX_INT n, fft_spec_buffer_size;
+ OMXResult status;
+ OMXFFTSpec_R_F32 * fft_fwd_spec = NULL;
+ OMXFFTSpec_R_F32 * fft_inv_spec = NULL;
+ int fft_size;
+ struct timeval start_time;
+ struct timeval end_time;
+ double elapsed_time;
+
+ fft_size = 1 << fft_log_size;
+
+ x_aligned = AllocAlignedPointer(32, sizeof(*x) * fft_size);
+ /* The transformed value is in CCS format and is has fft_size + 2 values */
+ y_aligned = AllocAlignedPointer(32, sizeof(*y) * (fft_size + 2));
+ z_aligned = AllocAlignedPointer(32, sizeof(*z) * fft_size);
+
+ x = x_aligned->aligned_pointer_;
+ y = y_aligned->aligned_pointer_;
+ z = z_aligned->aligned_pointer_;
+
+ y_true = (OMX_F32*) malloc(sizeof(*y_true) * (fft_size + 2));
+
+ GenerateRealFloatSignal(x, (OMX_FC32*) y_true, fft_size, signal_type,
+ signal_value);
+
+ status = omxSP_FFTGetBufSize_R_F32(fft_log_size, &fft_spec_buffer_size);
+
+ fft_fwd_spec = (OMXFFTSpec_R_F32*) malloc(fft_spec_buffer_size);
+ fft_inv_spec = (OMXFFTSpec_R_F32*) malloc(fft_spec_buffer_size);
+ status = omxSP_FFTInit_R_F32(fft_fwd_spec, fft_log_size);
+
+ status = omxSP_FFTInit_R_F32(fft_inv_spec, fft_log_size);
+
+ if (do_forward_test) {
+ GetUserTime(&start_time);
+ for (n = 0; n < count; ++n) {
+ omxSP_FFTFwd_RToCCS_F32_Sfs(x, y, fft_fwd_spec);
+ }
+ GetUserTime(&end_time);
+
+ elapsed_time = TimeDifference(&start_time, &end_time);
+
+ PrintResult("Forward Float RFFT", fft_log_size, elapsed_time, count);
+ }
+
+ if (do_inverse_test) {
+ GetUserTime(&start_time);
+ for (n = 0; n < count; ++n) {
+ omxSP_FFTInv_CCSToR_F32_Sfs(y, z, fft_inv_spec);
+ }
+ GetUserTime(&end_time);
+
+ elapsed_time = TimeDifference(&start_time, &end_time);
+
+ PrintResult("Inverse Float RFFT", fft_log_size, elapsed_time, count);
+ }
+
+ FreeAlignedPointer(x_aligned);
+ FreeAlignedPointer(y_aligned);
+ FreeAlignedPointer(z_aligned);
+ free(fft_fwd_spec);
+ free(fft_inv_spec);
+}
+
+void TimeFloatRFFT(int count, float signal_value, int signal_type) {
+ int k;
+
+ if (verbose == 0)
+ printf("Float RFFT\n");
+
+ for (k = min_fft_order; k <= max_fft_order; ++k) {
+ int testCount = ComputeCount(count, k);
+ TimeOneFloatRFFT(testCount, k, signal_value, signal_type);
+ }
+}
+
+void generateSC32Signal(OMX_SC32* x, OMX_SC32* fft, int size, int signal_type,
+ float signal_value) {
+ int k;
+ struct ComplexFloat *test_signal;
+ struct ComplexFloat *true_fft;
+
+ test_signal = (struct ComplexFloat*) malloc(sizeof(*test_signal) * size);
+ true_fft = (struct ComplexFloat*) malloc(sizeof(*true_fft) * size);
+ GenerateTestSignalAndFFT(test_signal, true_fft, size, signal_type,
+ signal_value, 0);
+
+ /*
+ * Convert the complex result to what we want
+ */
+
+ for (k = 0; k < size; ++k) {
+ x[k].Re = 0.5 + test_signal[k].Re;
+ x[k].Im = 0.5 + test_signal[k].Im;
+ fft[k].Re = 0.5 + true_fft[k].Re;
+ fft[k].Im = 0.5 + true_fft[k].Im;
+ }
+
+ free(test_signal);
+ free(true_fft);
+}
+
+void TimeOneSC32FFT(int count, int fft_log_size, float signal_value,
+ int signal_type) {
+ OMX_SC32* x;
+ OMX_SC32* y;
+ OMX_SC32* z;
+
+ struct AlignedPtr* x_aligned;
+ struct AlignedPtr* y_aligned;
+ struct AlignedPtr* z_aligned;
+
+ OMX_SC32* y_true;
+ OMX_SC32* temp32a;
+ OMX_SC32* temp32b;
+
+ OMX_INT n, fft_spec_buffer_size;
+ OMXResult status;
+ OMXFFTSpec_C_SC32 * fft_fwd_spec = NULL;
+ OMXFFTSpec_C_SC32 * fft_inv_spec = NULL;
+ int fft_size;
+ struct timeval start_time;
+ struct timeval end_time;
+ double elapsed_time;
+
+ fft_size = 1 << fft_log_size;
+
+ x_aligned = AllocAlignedPointer(32, sizeof(*x) * fft_size);
+ y_aligned = AllocAlignedPointer(32, sizeof(*y) * fft_size);
+ z_aligned = AllocAlignedPointer(32, sizeof(*z) * fft_size);
+ y_true = (OMX_SC32*) malloc(sizeof(*y_true) * fft_size);
+ temp32a = (OMX_SC32*) malloc(sizeof(*temp32a) * fft_size);
+ temp32b = (OMX_SC32*) malloc(sizeof(*temp32b) * fft_size);
+
+ x = x_aligned->aligned_pointer_;
+ y = y_aligned->aligned_pointer_;
+ z = z_aligned->aligned_pointer_;
+
+ generateSC32Signal(x, y_true, fft_size, signal_type, signal_value);
+
+ status = omxSP_FFTGetBufSize_C_SC32(fft_log_size, &fft_spec_buffer_size);
+
+ fft_fwd_spec = (OMXFFTSpec_C_SC32*) malloc(fft_spec_buffer_size);
+ fft_inv_spec = (OMXFFTSpec_C_SC32*) malloc(fft_spec_buffer_size);
+ status = omxSP_FFTInit_C_SC32(fft_fwd_spec, fft_log_size);
+
+ status = omxSP_FFTInit_C_SC32(fft_inv_spec, fft_log_size);
+
+ if (do_forward_test) {
+ if (include_conversion) {
+ int k;
+ float factor = -1;
+
+ GetUserTime(&start_time);
+ for (k = 0; k < count; ++k) {
+ for (n = 0; n < fft_size; ++n) {
+ if (fabs(x[n].Re) > factor) {
+ factor = fabs(x[n].Re);
+ }
+ if (fabs(x[n].Im) > factor) {
+ factor = fabs(x[n].Im);
+ }
+ }
+
+ factor = ((1 << 18) - 1) / factor;
+ for (n = 0; n < fft_size; ++n) {
+ temp32a[n].Re = factor * x[n].Re;
+ temp32a[n].Im = factor * x[n].Im;
+ }
+
+ omxSP_FFTFwd_CToC_SC32_Sfs(x, y, fft_fwd_spec, 0);
+
+ factor = 1 / factor;
+ for (n = 0; n < fft_size; ++n) {
+ temp32b[n].Re = y[n].Re * factor;
+ temp32b[n].Im = y[n].Im * factor;
+ }
+ }
+ GetUserTime(&end_time);
+ } else {
+ GetUserTime(&start_time);
+ for (n = 0; n < count; ++n) {
+ omxSP_FFTFwd_CToC_SC32_Sfs(x, y, fft_fwd_spec, 0);
+ }
+ GetUserTime(&end_time);
+ }
+
+ elapsed_time = TimeDifference(&start_time, &end_time);
+
+ PrintResult("Forward SC32 FFT", fft_log_size, elapsed_time, count);
+ }
+
+ if (do_inverse_test) {
+ if (include_conversion) {
+ int k;
+ float factor = -1;
+
+ GetUserTime(&start_time);
+ for (k = 0; k < count; ++k) {
+ for (n = 0; n < fft_size; ++n) {
+ if (fabs(x[n].Re) > factor) {
+ factor = fabs(x[n].Re);
+ }
+ if (fabs(x[n].Im) > factor) {
+ factor = fabs(x[n].Im);
+ }
+ }
+ factor = ((1 << 18) - 1) / factor;
+ for (n = 0; n < fft_size; ++n) {
+ temp32a[n].Re = factor * x[n].Re;
+ temp32a[n].Im = factor * x[n].Im;
+ }
+
+ status = omxSP_FFTInv_CToC_SC32_Sfs(y, z, fft_inv_spec, 0);
+
+ factor = 1 / factor;
+ for (n = 0; n < fft_size; ++n) {
+ temp32b[n].Re = y[n].Re * factor;
+ temp32b[n].Im = y[n].Im * factor;
+ }
+ }
+ GetUserTime(&end_time);
+ } else {
+ GetUserTime(&start_time);
+ for (n = 0; n < count; ++n) {
+ status = omxSP_FFTInv_CToC_SC32_Sfs(y, z, fft_inv_spec, 0);
+ }
+ GetUserTime(&end_time);
+ }
+
+ elapsed_time = TimeDifference(&start_time, &end_time);
+
+ PrintResult("Inverse SC32 FFT", fft_log_size, elapsed_time, count);
+ }
+
+ FreeAlignedPointer(x_aligned);
+ FreeAlignedPointer(y_aligned);
+ FreeAlignedPointer(z_aligned);
+ free(temp32a);
+ free(temp32b);
+ free(fft_fwd_spec);
+ free(fft_inv_spec);
+}
+
+void TimeSC32FFT(int count, float signal_value, int signal_type) {
+ int k;
+ int max_order = (max_fft_order > MAX_FFT_ORDER_FIXED_POINT)
+ ? MAX_FFT_ORDER_FIXED_POINT : max_fft_order;
+
+ if (verbose == 0)
+ printf("SC32 FFT\n");
+
+ for (k = min_fft_order; k <= max_order; ++k) {
+ int testCount = ComputeCount(count, k);
+ TimeOneSC32FFT(testCount, k, signal_value, signal_type);
+ }
+}
+
+void GenerateRFFT16Signal(OMX_S16* x, OMX_SC32* fft, int size, int signal_type,
+ float signal_value) {
+ int k;
+ struct ComplexFloat *test_signal;
+ struct ComplexFloat *true_fft;
+
+ test_signal = (struct ComplexFloat*) malloc(sizeof(*test_signal) * size);
+ true_fft = (struct ComplexFloat*) malloc(sizeof(*true_fft) * size);
+ GenerateTestSignalAndFFT(test_signal, true_fft, size, signal_type,
+ signal_value, 1);
+
+ /*
+ * Convert the complex result to what we want
+ */
+
+ for (k = 0; k < size; ++k) {
+ x[k] = test_signal[k].Re;
+ }
+
+ for (k = 0; k < size / 2 + 1; ++k) {
+ fft[k].Re = true_fft[k].Re;
+ fft[k].Im = true_fft[k].Im;
+ }
+
+ free(test_signal);
+ free(true_fft);
+}
+
+void TimeOneRFFT16(int count, int fft_log_size, float signal_value,
+ int signal_type) {
+ OMX_S16* x;
+ OMX_S32* y;
+ OMX_S16* z;
+ OMX_S32* y_true;
+ OMX_F32* xr;
+ OMX_F32* yrTrue;
+
+ struct AlignedPtr* x_aligned;
+ struct AlignedPtr* y_aligned;
+ struct AlignedPtr* z_aligned;
+ struct AlignedPtr* y_trueAligned;
+ struct AlignedPtr* xr_aligned;
+ struct AlignedPtr* yr_true_aligned;
+
+
+ OMX_S16* temp16;
+ OMX_S32* temp32;
+
+
+ OMX_INT n, fft_spec_buffer_size;
+ OMXResult status;
+ OMXFFTSpec_R_S16S32 * fft_fwd_spec = NULL;
+ OMXFFTSpec_R_S16S32 * fft_inv_spec = NULL;
+ int fft_size;
+ struct timeval start_time;
+ struct timeval end_time;
+ double elapsed_time;
+ int scaleFactor;
+
+ fft_size = 1 << fft_log_size;
+ scaleFactor = fft_log_size;
+
+ x_aligned = AllocAlignedPointer(32, sizeof(*x) * fft_size);
+ y_aligned = AllocAlignedPointer(32, sizeof(*y) * (fft_size + 2));
+ z_aligned = AllocAlignedPointer(32, sizeof(*z) * fft_size);
+
+ y_trueAligned = AllocAlignedPointer(32, sizeof(*y_true) * (fft_size + 2));
+
+ xr_aligned = AllocAlignedPointer(32, sizeof(*xr) * fft_size);
+ yr_true_aligned = AllocAlignedPointer(32, sizeof(*yrTrue) * (fft_size + 2));
+
+ x = x_aligned->aligned_pointer_;
+ y = y_aligned->aligned_pointer_;
+ z = z_aligned->aligned_pointer_;
+ y_true = y_trueAligned->aligned_pointer_;
+ xr = xr_aligned->aligned_pointer_;
+ yrTrue = yr_true_aligned->aligned_pointer_;
+
+ temp16 = (OMX_S16*) malloc(sizeof(*temp16) * fft_size);
+ temp32 = (OMX_S32*) malloc(sizeof(*temp32) * fft_size);
+
+
+ GenerateRFFT16Signal(x, (OMX_SC32*) y_true, fft_size, signal_type,
+ signal_value);
+ /*
+ * Generate a real version so we can measure scaling costs
+ */
+ GenerateRealFloatSignal(xr, (OMX_FC32*) yrTrue, fft_size, signal_type,
+ signal_value);
+
+ status = omxSP_FFTGetBufSize_R_S16S32(fft_log_size, &fft_spec_buffer_size);
+
+ fft_fwd_spec = (OMXFFTSpec_R_S16S32*) malloc(fft_spec_buffer_size);
+ fft_inv_spec = (OMXFFTSpec_R_S16S32*) malloc(fft_spec_buffer_size);
+ status = omxSP_FFTInit_R_S16S32(fft_fwd_spec, fft_log_size);
+
+ status = omxSP_FFTInit_R_S16S32(fft_inv_spec, fft_log_size);
+
+ if (do_forward_test) {
+ if (include_conversion) {
+ int k;
+ float factor = -1;
+
+ GetUserTime(&start_time);
+ for (k = 0; k < count; ++k) {
+ /*
+ * Spend some time computing the max of the signal, and then scaling it.
+ */
+ for (n = 0; n < fft_size; ++n) {
+ if (fabs(xr[n]) > factor) {
+ factor = fabs(xr[n]);
+ }
+ }
+
+ factor = 32767 / factor;
+ for (n = 0; n < fft_size; ++n) {
+ temp16[n] = factor * xr[n];
+ }
+
+ status = omxSP_FFTFwd_RToCCS_S16S32_Sfs(x, y, fft_fwd_spec,
+ (OMX_INT) scaleFactor);
+
+ /*
+ * Now spend some time converting the fixed-point FFT back to float.
+ */
+ factor = 1 / factor;
+ for (n = 0; n < fft_size + 2; ++n) {
+ xr[n] = y[n] * factor;
+ }
+ }
+ GetUserTime(&end_time);
+ } else {
+ float factor = -1;
+
+ GetUserTime(&start_time);
+ for (n = 0; n < count; ++n) {
+ status = omxSP_FFTFwd_RToCCS_S16S32_Sfs(x, y, fft_fwd_spec,
+ (OMX_INT) scaleFactor);
+ }
+ GetUserTime(&end_time);
+ }
+
+ elapsed_time = TimeDifference(&start_time, &end_time);
+
+ PrintResult("Forward RFFT16", fft_log_size, elapsed_time, count);
+ }
+
+ if (do_inverse_test) {
+ if (include_conversion) {
+ int k;
+ float factor = -1;
+
+ GetUserTime(&start_time);
+ for (k = 0; k < count; ++k) {
+ /*
+ * Spend some time scaling the FFT signal to fixed point.
+ */
+ for (n = 0; n < fft_size; ++n) {
+ if (fabs(yrTrue[n]) > factor) {
+ factor = fabs(yrTrue[n]);
+ }
+ }
+ for (n = 0; n < fft_size; ++n) {
+ temp32[n] = factor * yrTrue[n];
+ }
+
+ status = omxSP_FFTFwd_RToCCS_S16S32_Sfs(x, y, fft_fwd_spec,
+ (OMX_INT) scaleFactor);
+
+ /*
+ * Spend some time converting the result back to float
+ */
+ factor = 1 / factor;
+ for (n = 0; n < fft_size; ++n) {
+ xr[n] = factor * z[n];
+ }
+ }
+ GetUserTime(&end_time);
+ } else {
+ GetUserTime(&start_time);
+ for (n = 0; n < count; ++n) {
+ status = omxSP_FFTInv_CCSToR_S32S16_Sfs(y, z, fft_inv_spec, 0);
+ }
+ GetUserTime(&end_time);
+ }
+
+ elapsed_time = TimeDifference(&start_time, &end_time);
+
+ PrintResult("Inverse RFFT16", fft_log_size, elapsed_time, count);
+ }
+
+ FreeAlignedPointer(x_aligned);
+ FreeAlignedPointer(y_aligned);
+ FreeAlignedPointer(z_aligned);
+ FreeAlignedPointer(y_trueAligned);
+ FreeAlignedPointer(xr_aligned);
+ FreeAlignedPointer(yr_true_aligned);
+ free(fft_fwd_spec);
+ free(fft_inv_spec);
+}
+
+void TimeRFFT16(int count, float signal_value, int signal_type) {
+ int k;
+ int max_order = (max_fft_order > MAX_FFT_ORDER_FIXED_POINT)
+ ? MAX_FFT_ORDER_FIXED_POINT : max_fft_order;
+
+ if (verbose == 0)
+ printf("RFFT16\n");
+
+ for (k = min_fft_order; k <= max_order; ++k) {
+ int testCount = ComputeCount(count, k);
+ TimeOneRFFT16(testCount, k, signal_value, signal_type);
+ }
+}
+
+void GenerateRFFT32Signal(OMX_S32* x, OMX_SC32* fft, int size, int signal_type,
+ float signal_value) {
+ int k;
+ struct ComplexFloat *test_signal;
+ struct ComplexFloat *true_fft;
+
+ test_signal = (struct ComplexFloat*) malloc(sizeof(*test_signal) * size);
+ true_fft = (struct ComplexFloat*) malloc(sizeof(*true_fft) * size);
+ GenerateTestSignalAndFFT(test_signal, true_fft, size, signal_type,
+ signal_value, 1);
+
+ /*
+ * Convert the complex result to what we want
+ */
+
+ for (k = 0; k < size; ++k) {
+ x[k] = test_signal[k].Re;
+ }
+
+ for (k = 0; k < size / 2 + 1; ++k) {
+ fft[k].Re = true_fft[k].Re;
+ fft[k].Im = true_fft[k].Im;
+ }
+
+ free(test_signal);
+ free(true_fft);
+}
+
+void TimeOneRFFT32(int count, int fft_log_size, float signal_value,
+ int signal_type) {
+ OMX_S32* x;
+ OMX_S32* y;
+ OMX_S32* z;
+ OMX_S32* y_true;
+ OMX_F32* xr;
+ OMX_F32* yrTrue;
+
+ struct AlignedPtr* x_aligned;
+ struct AlignedPtr* y_aligned;
+ struct AlignedPtr* z_aligned;
+ struct AlignedPtr* y_true_aligned;
+
+ OMX_S32* temp1;
+ OMX_S32* temp2;
+
+ OMX_INT n, fft_spec_buffer_size;
+ OMXResult status;
+ OMXFFTSpec_R_S16S32 * fft_fwd_spec = NULL;
+ OMXFFTSpec_R_S16S32 * fft_inv_spec = NULL;
+ int fft_size;
+ struct timeval start_time;
+ struct timeval end_time;
+ double elapsed_time;
+ int scaleFactor;
+
+ fft_size = 1 << fft_log_size;
+
+ x_aligned = AllocAlignedPointer(32, sizeof(*x) * fft_size);
+ y_aligned = AllocAlignedPointer(32, sizeof(*y) * (fft_size + 2));
+ z_aligned = AllocAlignedPointer(32, sizeof(*z) * fft_size);
+
+ y_true_aligned = AllocAlignedPointer(32, sizeof(*y_true) * (fft_size + 2));
+
+ x = x_aligned->aligned_pointer_;
+ y = y_aligned->aligned_pointer_;
+ z = z_aligned->aligned_pointer_;
+ y_true = y_true_aligned->aligned_pointer_;
+
+ if (verbose > 3) {
+ printf("x = %p\n", (void*)x);
+ printf("y = %p\n", (void*)y);
+ printf("z = %p\n", (void*)z);
+ }
+
+ xr = (OMX_F32*) malloc(sizeof(*x) * fft_size);
+ yrTrue = (OMX_F32*) malloc(sizeof(*y) * (fft_size + 2));
+ temp1 = (OMX_S32*) malloc(sizeof(*temp1) * fft_size);
+ temp2 = (OMX_S32*) malloc(sizeof(*temp2) * (fft_size + 2));
+
+ GenerateRFFT32Signal(x, (OMX_SC32*) y_true, fft_size, signal_type,
+ signal_value);
+
+ if (verbose > 63) {
+ printf("Signal\n");
+ printf("n\tx[n]\n");
+ for (n = 0; n < fft_size; ++n) {
+ printf("%4d\t%d\n", n, x[n]);
+ }
+ }
+
+ status = omxSP_FFTGetBufSize_R_S32(fft_log_size, &fft_spec_buffer_size);
+ if (verbose > 3) {
+ printf("fft_spec_buffer_size = %d\n", fft_spec_buffer_size);
+ }
+
+ fft_fwd_spec = (OMXFFTSpec_R_S32*) malloc(fft_spec_buffer_size);
+ fft_inv_spec = (OMXFFTSpec_R_S32*) malloc(fft_spec_buffer_size);
+ status = omxSP_FFTInit_R_S32(fft_fwd_spec, fft_log_size);
+ if (status) {
+ printf("Failed to init forward FFT: status = %d\n", status);
+ }
+
+ status = omxSP_FFTInit_R_S32(fft_inv_spec, fft_log_size);
+ if (status) {
+ printf("Failed to init backward FFT: status = %d\n", status);
+ }
+
+ if (do_forward_test) {
+ if (include_conversion) {
+ int k;
+ float factor = -1;
+
+ GetUserTime(&start_time);
+ for (k = 0; k < count; ++k) {
+ /*
+ * Spend some time computing the max of the signal, and then scaling it.
+ */
+ for (n = 0; n < fft_size; ++n) {
+ if (fabs(xr[n]) > factor) {
+ factor = fabs(xr[n]);
+ }
+ }
+
+ factor = (1 << 20) / factor;
+ for (n = 0; n < fft_size; ++n) {
+ temp1[n] = factor * xr[n];
+ }
+
+ status = omxSP_FFTFwd_RToCCS_S32_Sfs(x, y, fft_fwd_spec,
+ (OMX_INT) scaleFactor);
+
+ /*
+ * Now spend some time converting the fixed-point FFT back to float.
+ */
+ factor = 1 / factor;
+ for (n = 0; n < fft_size + 2; ++n) {
+ xr[n] = y[n] * factor;
+ }
+ }
+ GetUserTime(&end_time);
+ } else {
+ float factor = -1;
+
+ GetUserTime(&start_time);
+ for (n = 0; n < count; ++n) {
+ status = omxSP_FFTFwd_RToCCS_S32_Sfs(x, y, fft_fwd_spec,
+ (OMX_INT) scaleFactor);
+ }
+ GetUserTime(&end_time);
+ }
+
+ elapsed_time = TimeDifference(&start_time, &end_time);
+
+ PrintResult("Forward RFFT32", fft_log_size, elapsed_time, count);
+ }
+
+ if (do_inverse_test) {
+ if (include_conversion) {
+ int k;
+ float factor = -1;
+
+ GetUserTime(&start_time);
+ for (k = 0; k < count; ++k) {
+ /*
+ * Spend some time scaling the FFT signal to fixed point.
+ */
+ for (n = 0; n < fft_size + 2; ++n) {
+ if (fabs(yrTrue[n]) > factor) {
+ factor = fabs(yrTrue[n]);
+ }
+ }
+ for (n = 0; n < fft_size + 2; ++n) {
+ temp2[n] = factor * yrTrue[n];
+ }
+
+ status = omxSP_FFTInv_CCSToR_S32_Sfs(y, z, fft_inv_spec, 0);
+
+ /*
+ * Spend some time converting the result back to float
+ */
+ factor = 1 / factor;
+ for (n = 0; n < fft_size; ++n) {
+ xr[n] = factor * z[n];
+ }
+ }
+ GetUserTime(&end_time);
+ } else {
+ GetUserTime(&start_time);
+ for (n = 0; n < count; ++n) {
+ status = omxSP_FFTInv_CCSToR_S32_Sfs(y, z, fft_inv_spec, 0);
+ }
+ GetUserTime(&end_time);
+ }
+
+ elapsed_time = TimeDifference(&start_time, &end_time);
+
+ PrintResult("Inverse RFFT32", fft_log_size, elapsed_time, count);
+ }
+
+ FreeAlignedPointer(x_aligned);
+ FreeAlignedPointer(y_aligned);
+ FreeAlignedPointer(z_aligned);
+ FreeAlignedPointer(y_true_aligned);
+ free(fft_fwd_spec);
+ free(fft_inv_spec);
+}
+
+void TimeRFFT32(int count, float signal_value, int signal_type) {
+ int k;
+ int max_order = (max_fft_order > MAX_FFT_ORDER_FIXED_POINT)
+ ? MAX_FFT_ORDER_FIXED_POINT : max_fft_order;
+
+ if (verbose == 0)
+ printf("RFFT32\n");
+
+ for (k = min_fft_order; k <= max_order; ++k) {
+ int testCount = ComputeCount(count, k);
+ TimeOneRFFT32(testCount, k, signal_value, signal_type);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698