void gmx_fft_destroy(gmx_fft_t fft) { int d; if(fft != NULL) { for(d=0;d<3;d++) { if(fft->inplace[d] != NULL) { DftiFreeDescriptor(&fft->inplace[d]); } if(fft->ooplace[d] != NULL) { DftiFreeDescriptor(&fft->ooplace[d]); } } if(fft->ooplace[3] != NULL) { DftiFreeDescriptor(&fft->ooplace[3]); } free(fft); } }
void fft_3d_destroy_plan(struct fft_plan_3d *plan) { if (plan->pre_plan) remap_3d_destroy_plan(plan->pre_plan); if (plan->mid1_plan) remap_3d_destroy_plan(plan->mid1_plan); if (plan->mid2_plan) remap_3d_destroy_plan(plan->mid2_plan); if (plan->post_plan) remap_3d_destroy_plan(plan->post_plan); if (plan->copy) free(plan->copy); if (plan->scratch) free(plan->scratch); #if defined(FFT_MKL) DftiFreeDescriptor(&(plan->handle_fast)); DftiFreeDescriptor(&(plan->handle_mid)); DftiFreeDescriptor(&(plan->handle_slow)); #elif defined(FFT_FFTW2) if (plan->plan_slow_forward != plan->plan_fast_forward && plan->plan_slow_forward != plan->plan_mid_forward) { fftw_destroy_plan(plan->plan_slow_forward); fftw_destroy_plan(plan->plan_slow_backward); } if (plan->plan_mid_forward != plan->plan_fast_forward) { fftw_destroy_plan(plan->plan_mid_forward); fftw_destroy_plan(plan->plan_mid_backward); } fftw_destroy_plan(plan->plan_fast_forward); fftw_destroy_plan(plan->plan_fast_backward); #elif defined(FFT_FFTW3) FFTW_API(destroy_plan)(plan->plan_slow_forward); FFTW_API(destroy_plan)(plan->plan_slow_backward); FFTW_API(destroy_plan)(plan->plan_mid_forward); FFTW_API(destroy_plan)(plan->plan_mid_backward); FFTW_API(destroy_plan)(plan->plan_fast_forward); FFTW_API(destroy_plan)(plan->plan_fast_backward); #else if (plan->cfg_slow_forward != plan->cfg_fast_forward && plan->cfg_slow_forward != plan->cfg_mid_forward) { free(plan->cfg_slow_forward); free(plan->cfg_slow_backward); } if (plan->cfg_mid_forward != plan->cfg_fast_forward) { free(plan->cfg_mid_forward); free(plan->cfg_mid_backward); } free(plan->cfg_fast_forward); free(plan->cfg_fast_backward); #endif free(plan); }
void FFT_MKL(double *inputSignal, double *outputSignal,int n) { DFTI_DESCRIPTOR_HANDLE handle; MKL_LONG status; status = DftiCreateDescriptor(&handle, DFTI_DOUBLE, DFTI_REAL, 1, n); status = DftiSetValue(handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE); status = DftiCommitDescriptor(handle); status = DftiComputeForward(handle, inputSignal, outputSignal); int k = n / 2; if (n % 2 != 0) { k++; } for (int i = n / 2 + 1; i < n; i++) { k--; outputSignal[2 * i] = outputSignal[2 * k]; outputSignal[2 * i + 1] = (-1) * outputSignal[2 * k + 1]; } status = DftiFreeDescriptor(&handle); }
// Basic destructor virtual ~N_UTL_IntelFFT_Interface() { // free the descriptor long status = DftiFreeDescriptor( &fftDescriptor ); checkAndTrapErrors( status ); }
int main(void) { /* Size of 1D transform */ int N = 1000000; /* Arbitrary harmonic */ int H = -N/2; /* Execution status */ MKL_LONG status = 0; int forward_ok = 1, backward_ok = 1; double time_start = 0, time_end = 0; double flops = 0; printf("Forward and backward 1D complex inplace transforms\n"); printf("Allocate space for data on the host\n"); x = (COMPLEX*)malloc( N * sizeof(COMPLEX) ); if (0 == x) { printf("Error: memory allocation on host failed\n"); exit(1); } printf("Preallocate memory on the target\n"); /* * SOLUTION: Use offload pragma to preallocate memory for x on the target. * (1) The lenght of x is N * (2) Make sure the memory of x is aligned on 64-byte boundary * (3) Make sure the allocated memory is not freed */ #pragma offload target(mic) in(x:length(N) align(64) alloc_if(1) free_if(0)) { } printf("Create handle for 1D single-precision forward and backward transforms\n"); /* * SOLUTION: Offload the call to DftiCreateDescriptor to the target. * (1) What would be the 'in' variables? * (2) What would be the 'out' variables? */ #pragma offload target(mic) in(N) nocopy(handle) out(status) { status = DftiCreateDescriptor(&handle, DFTI_SINGLE, DFTI_COMPLEX, 1, (MKL_LONG)N ); if (0 == status) { status = DftiCommitDescriptor(handle); } } if (status) { printf("Error: cannot create handle\n"); exit(1); } /* * SOLUTION: Offload the call to DftiComputeForward to the target. * (1) Make sure x is an 'inout' variable, because this is in-place * transform. * (2) Do not allocate memory for x because it was preallocated. * (3) Do not free momory of x because we will use it again for more * transforms. * (4) What would be the 'out' variables? */ // We do not time the first offload. #pragma offload target(mic) inout(x:length(N) alloc_if(0) free_if(0)) \ nocopy(handle) out(status) { status = DftiComputeForward(handle, x); } printf("Initialize input for forward transform\n"); init(x, N, H); printf("Offload forward FFT computation to the target\n"); time_start = dsecnd(); /* * SOLUTION: Offload the call to DftiComputeForward to the target. * This should be the same as the previous offload. */ #pragma offload target(mic) inout(x:length(N) alloc_if(0) free_if(0)) \ nocopy(handle) out(status) { status = DftiComputeForward(handle, x); } time_end = dsecnd(); if (status) { printf("Error: DftiComputeForward failed\n"); exit(1); } printf("Verify result of forward FFT\n"); forward_ok = verify(x, N, H); if (0 == forward_ok) { flops = 5 * N * log2((double)N) / (time_end - time_start); printf("\t Forward: size = %d, GFlops = %.3f \n", N, flops/1000000000); } printf("Initialize input for backward transform\n"); init(x, N, -H); printf("Offload backward FFT computation to the target\n"); time_start = dsecnd(); /* * SOLUTION: Offload the call to DftiComputeBackward to the target. * (1) Make sure x is an 'inout' variable, because this is in-place * transform. * (2) Do not allocate memory for x because it was preallocated. * (3) Do not free momory of x at this time. * (4) What would be the 'out' variables? */ #pragma offload target(mic) inout(x:length(N) alloc_if(0) free_if(0)) \ nocopy(handle) out(status) { status = DftiComputeBackward(handle, x); } time_end = dsecnd(); if (status) { printf("Error: DftiComputeBackward failed\n"); exit(1); } printf("Verify result of backward FFT\n"); backward_ok = verify(x, N, H); if (0 == backward_ok) { flops = 5 * N * log2((double)N) / (time_end - time_start); printf("\t Backward: size = %d, GFlops = %.3f \n", N, flops/1000000000 ); } printf("Destroy DFTI handle and free space on the target\n"); /* * SOLUTION: Use offload pragma to deallocate memory of x on the target. * (1) What would be 'in' variables? * (2) Do the 'in' variables need to be copied in? */ #pragma offload target(mic) nocopy(x:length(N) alloc_if(0) free_if(1)) \ nocopy(handle) { DftiFreeDescriptor(&handle); } printf("Free space on host\n"); free(x); printf("TEST %s\n",0==forward_ok ? "FORWARD FFT PASSED" : "FORWARD FFT FAILED"); printf("TEST %s\n",0==backward_ok ? "BACKWARD FFT PASSED" : "BACKWARD FFT FAILED"); return 0; }
int bi_entry(void * mdpv, int iproblemsize, double * dresults) { /* dstart, dend: the start and end time of the measurement */ /* dtime: the time for a single measurement in seconds */ double dstart = 0.0, dend = 0.0, dtime = 0.0, dinit = 0.0; /* flops stores the calculated FLOPS */ double flops = 0.0; /* ii is used for loop iterations */ myinttype ii, jj, imyproblemsize, numberOfRuns; /* cast void* pointer */ mydata_t* pmydata = (mydata_t*)mdpv; int invalid = 0; long status; /* calculate real problemsize */ imyproblemsize = (int)pow(2, (log2(pmydata->min) + (myinttype)iproblemsize - 1)); /* store the value for the x axis in results[0] */ dresults[0] = (double)imyproblemsize; /*** in place run ***/ /* malloc */ pmydata->inout = (float*)malloc(sizeof(float) * imyproblemsize * 2); /* create FFT plan */ status = DftiCreateDescriptor(&pmydata->my_desc_handle, DFTI_SINGLE, DFTI_COMPLEX, 1, imyproblemsize); status = DftiCommitDescriptor(pmydata->my_desc_handle); /* init stuff */ initData_ip(pmydata, imyproblemsize); numberOfRuns = 1; dstart = bi_gettime(); /* fft calculation */ status = DftiComputeForward(pmydata->my_desc_handle, pmydata->inout); dend = bi_gettime(); /* calculate the used time*/ dtime = dend - dstart; dtime -= dTimerOverhead; /* loop calculation if accuracy is insufficient */ while (dtime < 100 * dTimerGranularity) { numberOfRuns = numberOfRuns * 2; dstart = bi_gettime(); for (jj = 0; jj < numberOfRuns; jj++) { /* fft calculation */ status = DftiComputeForward(pmydata->my_desc_handle, pmydata->inout); } dend = bi_gettime(); dtime = dend - dstart; dtime -= dTimerOverhead; } /* check for overflows */ for (ii = 0; ii < imyproblemsize; ii++) { if (isnan(pmydata->inout[2 * ii]) || isnan(pmydata->inout[2 * ii + 1])) invalid = 1; if (isinf(pmydata->inout[2 * ii]) || isinf(pmydata->inout[2 * ii + 1])) invalid = 1; } /* if loop was necessary */ if (numberOfRuns > 1) dtime = dtime / numberOfRuns; /* calculate the used FLOPS */ flops = (double)(5.0 * imyproblemsize * (log2(1.0 * imyproblemsize)) / dtime); /* store the FLOPS in results[1] */ if (invalid == 1) dresults[1] = INVALID_MEASUREMENT; else dresults[1] = flops; status = DftiFreeDescriptor(&pmydata->my_desc_handle); /* free data */ free(pmydata->inout); /*** out of place run ***/ /* malloc */ pmydata->in = (float*)malloc(sizeof(float) * imyproblemsize * 2); pmydata->out = (float*)malloc(sizeof(float) * imyproblemsize * 2); /* create FFT plan */ status = DftiCreateDescriptor(&pmydata->my_desc_handle, DFTI_SINGLE, DFTI_COMPLEX, 1, imyproblemsize); status = DftiSetValue(pmydata->my_desc_handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE); status = DftiCommitDescriptor(pmydata->my_desc_handle); /* init stuff */ initData_oop(pmydata, imyproblemsize); numberOfRuns = 1; dstart = bi_gettime(); /* fft calculation */ status = DftiComputeForward(pmydata->my_desc_handle, pmydata->in, pmydata->out); dend = bi_gettime(); /* calculate the used time*/ dtime = dend - dstart; dtime -= dTimerOverhead; /* loop calculation if accuracy is insufficient */ while (dtime < 100 * dTimerGranularity) { numberOfRuns = numberOfRuns * 2; dstart = bi_gettime(); for (ii = 0; ii < numberOfRuns; ii++) { /* fft calculation */ status = DftiComputeForward(pmydata->my_desc_handle, pmydata->in, pmydata->out); } dend = bi_gettime(); /* calculate the used time*/ dtime = dend - dstart; dtime -= dTimerOverhead; } /* if loop was necessary */ if (numberOfRuns > 1) dtime = dtime / numberOfRuns; /* check for overflows */ for (ii = 0; ii < imyproblemsize; ii++) { if (isnan(pmydata->out[2 * ii]) || isnan(pmydata->out[2 * ii + 1])) invalid = 1; if (isinf(pmydata->out[2 * ii]) || isinf(pmydata->out[2 * ii + 1])) invalid = 1; } /* calculate the used FLOPS */ flops = (double)(5.0 * imyproblemsize * (log2(1.0 * imyproblemsize)) / dtime); /* store the FLOPS in results[2] */ if (invalid == 1) dresults[2] = INVALID_MEASUREMENT; else dresults[2] = flops; status = DftiFreeDescriptor(&pmydata->my_desc_handle); /* free data */ free(pmydata->in); free(pmydata->out); return 0; }
void ccmfft(complex *data, int n1, int n2, int ld1, int sign) { #if defined(HAVE_LIBSCS) int ntable, nwork, zero=0; static int isys, nprev=0; static float *work, *table, scale=1.0; #elif defined(ACML440) static int nprev=0; int nwork, zero=0, one=1, i, j, inpl; static int isys; static complex *work; REAL scl; complex *y; #elif defined(MKL) static DFTI_DESCRIPTOR_HANDLE handle[MAX_NUMTHREADS]; static int nprev[MAX_NUMTHREADS]; MKL_LONG Status; int j; #endif int id; #ifdef _OPENMP id = omp_get_thread_num(); #else id = 0; #endif #if defined(HAVE_LIBSCS) if (n1 != nprev) { isys = 0; ntable = 2*n1 + 30; nwork = 2*n1; if (work) free(work); work = (float *)malloc(nwork*sizeof(float)); if (work == NULL) fprintf(stderr,"ccmfft: memory allocation error\n"); if (table) free(table); table = (float *)malloc(ntable*sizeof(float)); if (table == NULL) fprintf(stderr,"ccmfft: memory allocation error\n"); ccfftm_(&zero, &n1, &n2, &scale, data, &ld1, data, &ld1, table, work, &isys); nprev = n1; } ccfftm_(&sign, &n1, &n2, &scale, data, &ld1, data, &ld1, table, work, &isys); #elif defined(ACML440) scl = 1.0; inpl = 1; if (n1 != nprev) { isys = 0; nwork = 5*n1 + 100; if (work) free(work); work = (complex *)malloc(nwork*sizeof(complex)); if (work == NULL) fprintf(stderr,"rc1fft: memory allocation error\n"); acmlccmfft(zero, scl, inpl, n2, n1, data, 1, ld1, y, 1, ld1, work, &isys); nprev = n1; } acmlccmfft(sign, scl, inpl, n2, n1, data, 1, ld1, y, 1, ld1, work, &isys); #elif defined(MKL) if (n1 != nprev[id]) { DftiFreeDescriptor(&handle[id]); Status = DftiCreateDescriptor(&handle[id], DFTI_SINGLE, DFTI_COMPLEX, 1, (MKL_LONG)n1); if(! DftiErrorClass(Status, DFTI_NO_ERROR)){ dfti_status_print(Status); printf(" DftiCreateDescriptor FAIL\n"); } Status = DftiCommitDescriptor(handle[id]); if(! DftiErrorClass(Status, DFTI_NO_ERROR)){ dfti_status_print(Status); printf(" DftiCommitDescriptor FAIL\n"); } nprev[id] = n1; } if (sign < 0) { for (j=0; j<n2; j++) { Status = DftiComputeBackward(handle[id], &data[j*ld1]); } } else { for (j=0; j<n2; j++) { Status = DftiComputeForward(handle[id], &data[j*ld1]); } } #else ccm_fft(data, n1, n2, ld1, sign); #endif return; }
~ifft_kernel() { DftiFreeDescriptor(&descriptor); }