static struct rfftw_plan_list *get_plan(int size) { struct rfftw_plan_list *plan; float *spare_storage; /* 1. Look for a plan; if we have it, return it. */ for (plan = plans; plan; plan = plan->next) if (plan->size == size) return plan; /* 2. We lose. Create a new plan. */ plan = malloc(sizeof(struct rfftw_plan_list)); plan->size = size; plan->next = plans; plans = plan; plan->buff = malloc(size * sizeof(float)); spare_storage = malloc(size * sizeof(float)); plan->rtoc_plan = rfftw_create_plan_specific (size, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE | FFTW_OUT_OF_PLACE | FFTW_USE_WISDOM, spare_storage, 1, plan->buff, 1); plan->ctor_plan = rfftw_create_plan_specific (size, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE | FFTW_OUT_OF_PLACE | FFTW_USE_WISDOM, plan->buff, 1, spare_storage, 1); free(spare_storage); return plan; }
/* * Class: jfftw_real_Plan * Method: createPlanSpecific * Signature: (III[DI[DI)V */ JNIEXPORT void JNICALL Java_jfftw_real_Plan_createPlanSpecific( JNIEnv *env, jobject obj, jint n, jint dir, jint flags, jdoubleArray in, jint idist, jdoubleArray out, jint odist) { jclass clazz; jfieldID id; jbyteArray arr; unsigned char* carr; double *cin, *cout; if( sizeof( jdouble ) != sizeof( fftw_real ) ) { (*env)->ThrowNew( env, (*env)->FindClass( env, "java/lang/RuntimeException" ), "jdouble and fftw_real are incompatible" ); return; } clazz = (*env)->GetObjectClass( env, obj ); id = (*env)->GetFieldID( env, clazz, "plan", "[B" ); arr = (*env)->NewByteArray( env, sizeof( rfftw_plan ) ); carr = (*env)->GetByteArrayElements( env, arr, 0 ); cin = (*env)->GetDoubleArrayElements( env, in, 0 ); cout = (*env)->GetDoubleArrayElements( env, out, 0 ); (*env)->MonitorEnter( env, (*env)->FindClass( env, "jfftw/Plan" ) ); *(rfftw_plan*)carr = rfftw_create_plan_specific( n, dir, flags, cin, idist, cout, odist ); (*env)->MonitorExit( env, (*env)->FindClass( env, "jfftw/Plan" ) ); (*env)->ReleaseDoubleArrayElements( env, in, cin, 0 ); (*env)->ReleaseDoubleArrayElements( env, out, cout, 0 ); (*env)->ReleaseByteArrayElements( env, arr, carr, 0 ); (*env)->SetObjectField( env, obj, id, arr ); }
void test_speed_aux(int n, fftw_direction dir, int flags, int specific) { fftw_real *in, *out; fftw_plan plan; double t; fftw_time begin, end; in = (fftw_real *) fftw_malloc(n * howmany_fields * sizeof(fftw_real)); out = (fftw_real *) fftw_malloc(n * howmany_fields * sizeof(fftw_real)); if (specific) { begin = fftw_get_time(); plan = rfftw_create_plan_specific(n, dir, speed_flag | flags | wisdom_flag | no_vector_flag, in, howmany_fields, out, howmany_fields); end = fftw_get_time(); } else { begin = fftw_get_time(); plan = rfftw_create_plan(n, dir, speed_flag | flags | wisdom_flag | no_vector_flag); end = fftw_get_time(); } CHECK(plan != NULL, "can't create plan"); t = fftw_time_to_sec(fftw_time_diff(end, begin)); WHEN_VERBOSE(2, printf("time for planner: %f s\n", t)); WHEN_VERBOSE(2, rfftw_print_plan(plan)); FFTW_TIME_FFT(rfftw(plan, howmany_fields, in, howmany_fields, 1, out, howmany_fields, 1), in, n * howmany_fields, t); rfftw_destroy_plan(plan); WHEN_VERBOSE(1, printf("time for one fft: %s", smart_sprint_time(t))); WHEN_VERBOSE(1, printf(" (%s/point)\n", smart_sprint_time(t / n))); WHEN_VERBOSE(1, printf("\"mflops\" = 5/2 (n log2 n) / (t in microseconds)" " = %f\n", 0.5 * howmany_fields * mflops(t, n))); fftw_free(in); fftw_free(out); WHEN_VERBOSE(1, printf("\n")); }
void test_in_place(int n, int istride, int howmany, fftw_direction dir, fftw_plan validated_plan, int specific) { fftw_complex *in2, *out2; fftw_real *in1, *out1, *out3; fftw_plan plan; int i, j; int ostride = istride; int flags = measure_flag | wisdom_flag | FFTW_IN_PLACE; if (coinflip()) flags |= FFTW_THREADSAFE; in1 = (fftw_real *) fftw_malloc(istride * n * sizeof(fftw_real) * howmany); in2 = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex)); out1 = in1; out2 = (fftw_complex *) fftw_malloc(n * sizeof(fftw_complex)); out3 = (fftw_real *) fftw_malloc(n * sizeof(fftw_real)); if (!specific) plan = rfftw_create_plan(n, dir, flags); else plan = rfftw_create_plan_specific(n, dir, flags, in1, istride, out1, ostride); CHECK(plan != NULL, "can't create plan"); /* generate random inputs */ fill_random(in1, n, istride); for (j = 1; j < howmany; ++j) for (i = 0; i < n; ++i) in1[(j * n + i) * istride] = in1[i * istride]; /* copy random inputs to complex array for comparison with fftw: */ if (dir == FFTW_REAL_TO_COMPLEX) for (i = 0; i < n; ++i) { c_re(in2[i]) = in1[i * istride]; c_im(in2[i]) = 0.0; } else { int n2 = (n + 1) / 2; c_re(in2[0]) = in1[0]; c_im(in2[0]) = 0.0; for (i = 1; i < n2; ++i) { c_re(in2[i]) = in1[i * istride]; c_im(in2[i]) = in1[(n - i) * istride]; } if (n2 * 2 == n) { c_re(in2[n2]) = in1[n2 * istride]; c_im(in2[n2]) = 0.0; ++i; } for (; i < n; ++i) { c_re(in2[i]) = c_re(in2[n - i]); c_im(in2[i]) = -c_im(in2[n - i]); } } /* * fill in other positions of the array, to make sure that * rfftw doesn't overwrite them */ for (j = 1; j < istride; ++j) for (i = 0; i < n * howmany; ++i) in1[i * istride + j] = i * istride + j; WHEN_VERBOSE(2, rfftw_print_plan(plan)); /* fft-ize */ if (howmany != 1 || istride != 1 || coinflip()) rfftw(plan, howmany, in1, istride, n * istride, 0, 0, 0); else rfftw_one(plan, in1, NULL); rfftw_destroy_plan(plan); /* check for overwriting */ for (j = 1; j < ostride; ++j) for (i = 0; i < n * howmany; ++i) CHECK(out1[i * ostride + j] == i * ostride + j, "output has been overwritten"); fftw(validated_plan, 1, in2, 1, n, out2, 1, n); if (dir == FFTW_REAL_TO_COMPLEX) { int n2 = (n + 1) / 2; out3[0] = c_re(out2[0]); for (i = 1; i < n2; ++i) { out3[i] = c_re(out2[i]); out3[n - i] = c_im(out2[i]); } if (n2 * 2 == n) out3[n2] = c_re(out2[n2]); } else { for (i = 0; i < n; ++i) out3[i] = c_re(out2[i]); } for (j = 0; j < howmany; ++j) CHECK(compute_error(out1 + j * n * ostride, ostride, out3, 1, n) < TOLERANCE, "test_in_place: wrong answer"); WHEN_VERBOSE(2, printf("OK\n")); fftw_free(in1); fftw_free(in2); fftw_free(out2); fftw_free(out3); }