- update Example05 to use FFTW to check the answer

- update clFFT installation instructions
This commit is contained in:
Dakota St. Laurent
2015-08-12 16:34:10 -04:00
parent 3af7ec6c3b
commit bff9fd6443
5 changed files with 70 additions and 31 deletions

View File

@@ -1,26 +1,25 @@
CXX = gcc CXX = gcc
# clFFT lib & inc # clFFT lib & inc
CLFFT_LIB = -lOpenCL -L./clFFT/build/package/lib64 -lclFFT CLFFT_LIB = -lOpenCL -L./usr/local/lib64 -lclFFT
CLFFT_INCLUDE = -I./clFFT/build/package/include CLFFT_INCLUDE = -I./clFFT/build/package/include
# standard math library # standard math library
CXXFLAGS = -c $(CLFFT_INCLUDE) CXXFLAGS = -c $(CLFFT_INCLUDE)
LDFLAGS = -lm $(CLFFT_LIB) LDFLAGS = -lm $(CLFFT_LIB) -lfftw3 -lm
EXE = Example EXE = Example
all: ex04 ex05 all: ex04 ex05
# entire process
ex04: example04/build/main.o ex04: example04/build/main.o
@if [ ! -d "./example04/bin" ]; then mkdir ./example04/bin; fi @if [ ! -d "./example04/bin" ]; then mkdir ./example04/bin; fi
$(CXX) $< $(LDFLAGS) -o example04/bin/$(EXE) $(CXX) $< $(LDFLAGS) -o example04/bin/$(EXE)
# create object file (compile without linking)
example04/build/main.o: example04/main.c example04/build/main.o: example04/main.c
@if [ ! -d "./example04/build" ]; then mkdir ./example04/build; fi @if [ ! -d "./example04/build" ]; then mkdir ./example04/build; fi
$(CXX) $(CXXFLAGS) $< -o $@ $(CXX) $(CXXFLAGS) $< -o $@
ex05: example05/build/main.o ex05: example05/build/main.o
@if [ ! -d "./example05/bin" ]; then mkdir ./example05/bin; fi @if [ ! -d "./example05/bin" ]; then mkdir ./example05/bin; fi
$(CXX) $< $(LDFLAGS) -o example05/bin/$(EXE) $(CXX) $< $(LDFLAGS) -o example05/bin/$(EXE)

View File

@@ -22,8 +22,8 @@ gcc main.c -o main.out -lOpenCL
For examples 04 and 05, you can run For examples 04 and 05, you can run
```bash ```bash
make ex04 make ex04 # executable is ./example04/bin/Example
make ex05 make ex05 # executable is ./example05/bin/Example
make # makes both! make # makes both!
``` ```
@@ -54,10 +54,17 @@ Demonstrates that one array can be modified several times without having to re-r
A simple example using the `cl_khr_fp64` extension which allows for usage of doubles instead of floats. A simple example using the `cl_khr_fp64` extension which allows for usage of doubles instead of floats.
## example 04 ## example 04
An example of the CLFFT library for an in-place complex-planar transform. There is also Python code to check the answer, which requires numpy / scipy. The C code requires the CLFFT library to be installed in the root of the repository. See more details in the folder's readme. An example of the CLFFT library for an in-place complex-planar transform. There is also Python code to check the answer; FFTW code will be added later, probably.
- clFFT is required; installation instructions can be found inside example04/README.md
- for Python, numpy and scipy are required
## example 05 ## example 05
Another CLFFT example where an in-place real transform is performed. There's also Python code for checking the answer, which requires numpy / scipy. The C code requires the CLFFT library to be installed in the root of the repository. For instructions on doing this, check out the readme of example04. Another CLFFT example where an in-place real transform is performed. There's also FFTW code and Python code for checking the answer.
- clFFT is required; installation instructions can be found inside example04/README.md
- FFTW is required; installation is as simple as extracting FFTW's tar file, then running `./configure && sudo make && sudo make install`
- for Python, numpy and scipy are required
## Some Notes ## Some Notes
From the [guide on programming OpenCL for NVIDIA](http://www.nvidia.com/content/cudazone/download/OpenCL/NVIDIA_OpenCL_ProgrammingGuide.pdf): From the [guide on programming OpenCL for NVIDIA](http://www.nvidia.com/content/cudazone/download/OpenCL/NVIDIA_OpenCL_ProgrammingGuide.pdf):

View File

@@ -10,17 +10,10 @@ mkdir build
cd build cd build
cmake ../src cmake ../src
make make
make install sudo make install
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
``` ```
and then
```
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/clFFT/build/package/lib64
```
(`pwd` should give the path to the top-level of the repository!).
## Running it ## Running it
In the top-level directory, run In the top-level directory, run
@@ -30,3 +23,4 @@ make ex04
``` ```
and it should print out a vector! :hamburger: and it should print out a vector! :hamburger:

View File

@@ -2,6 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#include <clFFT.h> #include <clFFT.h>
#include <fftw3.h>
const char *kernelSource = const char *kernelSource =
"#pragma OPENCL EXTENSION cl_khr_fp64 : enable \n" \ "#pragma OPENCL EXTENSION cl_khr_fp64 : enable \n" \
@@ -45,7 +46,7 @@ int main( int argc, char* argv[] ) {
* by 2 (192). The kernel will operate on zeros, but it should be faster * by 2 (192). The kernel will operate on zeros, but it should be faster
* than the scenario with warp divergence. */ * than the scenario with warp divergence. */
unsigned int N = 128; unsigned int N = 2048;
unsigned int N_pad = 2*roundUpToNearest( (N+2)/2, 32 ); unsigned int N_pad = 2*roundUpToNearest( (N+2)/2, 32 );
size_t N_bytes = N_pad * sizeof(double); size_t N_bytes = N_pad * sizeof(double);
@@ -66,14 +67,13 @@ int main( int argc, char* argv[] ) {
clfftSetup(&fftSetup); clfftSetup(&fftSetup);
// host version of v // host version of v
double *h_v; // real & imaginary parts double *h_v;
h_v = (double*) malloc(N_bytes); h_v = (double*) malloc(N_bytes);
// initialize v on host // initialize v on host (GPU and CPU)
int i; int i;
for (i = 0; i < N; i++) { for (i = 0; i < N; i++)
h_v[i] = i; h_v[i] = i;
}
// global & local number of threads // global & local number of threads
size_t globalSize, localSize; size_t globalSize, localSize;
@@ -121,29 +121,67 @@ int main( int argc, char* argv[] ) {
clfftSetResultLocation(planHandleBackward, CLFFT_INPLACE); clfftSetResultLocation(planHandleBackward, CLFFT_INPLACE);
clfftBakePlan(planHandleBackward, 1, &queue, NULL, NULL); clfftBakePlan(planHandleBackward, 1, &queue, NULL, NULL);
// set all of ze kernel args...
err = clSetKernelArg(k_mult, 0, sizeof(cl_mem), &d_v); err = clSetKernelArg(k_mult, 0, sizeof(cl_mem), &d_v);
// FFT data, apply psi, IFFT data // FFT data, multiply elements, IFFT data
clfftEnqueueTransform(planHandleForward, CLFFT_FORWARD, 1, &queue, 0, NULL, NULL, &d_v, NULL, NULL); clfftEnqueueTransform(planHandleForward, CLFFT_FORWARD, 1, &queue, 0, NULL, NULL, &d_v, NULL, NULL);
clFinish(queue); clFinish(queue);
err = clEnqueueNDRangeKernel(queue, k_mult, 1, NULL, &globalSize, &localSize, 0, NULL, NULL); err = clEnqueueNDRangeKernel(queue, k_mult, 1, NULL, &globalSize, &localSize, 0, NULL, NULL);
clFinish(queue); clFinish(queue);
//clfftEnqueueTransform(planHandleBackward, CLFFT_BACKWARD, 1, &queue, 0, NULL, NULL, &d_v, NULL, NULL); clfftEnqueueTransform(planHandleBackward, CLFFT_BACKWARD, 1, &queue, 0, NULL, NULL, &d_v, NULL, NULL);
clFinish(queue); clFinish(queue);
// transfer back // transfer back
clEnqueueReadBuffer(queue, d_v, CL_TRUE, 0, N_bytes, h_v, 0, NULL, NULL ); clEnqueueReadBuffer(queue, d_v, CL_TRUE, 0, N_bytes, h_v, 0, NULL, NULL );
clFinish(queue); clFinish(queue);
printf("[ "); // do CPU equivalent
for (i=0; i<N; i++) double *v;
printf("%f ", h_v[i]); fftw_complex *V;
printf("]\n"); int N_COMPLEX = N/2 + 1;
int REAL = 0;
int IMAG = 1;
// release clFFT stuff v = (double*) malloc(N * sizeof(double));
V = (fftw_complex*) malloc(N_COMPLEX * sizeof(fftw_complex));
fftw_plan fft = fftw_plan_dft_r2c_1d(N, v, V, FFTW_MEASURE);
fftw_plan ifft = fftw_plan_dft_c2r_1d(N, V, v, FFTW_MEASURE);
// initialize v here because otherwise fftw_execute will run before
// we initialize the plan... for some reason.
for (i=0; i<N; i++)
v[i] = i;
fftw_execute(fft);
for (i=0; i<N_COMPLEX; i++) {
V[i][REAL] = 2 * V[i][REAL];
V[i][IMAG] = 4 * V[i][IMAG];
}
fftw_execute(ifft);
// scale array as FFTW doesn't automatically do this for back transform
for (i=0; i<N; i++)
v[i] = v[i]/N;
double epsilon = 0.0;
int arrays_equal = 1;
for (i=0; i<N; i++) {
printf("[%f %f] ", h_v[i], v[i]);
if (abs(v[i] - h_v[i]) > epsilon)
arrays_equal = 0;
}
if (arrays_equal)
printf("Arrays are equal!\n");
else
printf("Arrays are NOT equal!\n");
// release FFT stuff
fftw_free(V);
clfftDestroyPlan( &planHandleForward ); clfftDestroyPlan( &planHandleForward );
clfftDestroyPlan( &planHandleBackward ); clfftDestroyPlan( &planHandleBackward );
clfftTeardown(); clfftTeardown();
@@ -156,6 +194,7 @@ int main( int argc, char* argv[] ) {
clReleaseContext(context); clReleaseContext(context);
//release host memory //release host memory
free(v);
free(h_v); free(h_v);
return 0; return 0;

View File

@@ -1,7 +1,7 @@
import numpy as np import numpy as np
import scipy.fftpack as fft import scipy.fftpack as fft
N = 128 N = 2048
v = np.arange(N) v = np.arange(N)
v_fft = fft.fft(v) v_fft = fft.fft(v)