Skip to content

Commit

Permalink
helper-lib -> src/inc. unified error checking.
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Werner authored and Matthias Werner committed May 30, 2016
1 parent 9c242d1 commit de7d20d
Show file tree
Hide file tree
Showing 23 changed files with 392 additions and 519 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Expand Up @@ -27,5 +27,4 @@ message(">> Setting up ${CMAKE_BUILD_TYPE} build")
# or
#add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1)

add_subdirectory(lib/helper/src)
add_subdirectory(src)
78 changes: 39 additions & 39 deletions inc/clfft.hpp
Expand Up @@ -64,17 +64,17 @@ namespace ClFFT
findClDevice(CL_DEVICE_TYPE_GPU, &platform, &device);
props[1] = (cl_context_properties)platform;
ctx = clCreateContext( props, 1, &device, nullptr, nullptr, &err );
clCheckError(err);
CHECK_CL(err);
clfftSetupData fftSetup;
clSafeCall(clfftInitSetupData(&fftSetup));
clSafeCall(clfftSetup(&fftSetup));
CHECK_CL(clfftInitSetupData(&fftSetup));
CHECK_CL(clfftSetup(&fftSetup));

}
void destroy() {
if(ctx) {
std::cout << "Destroying clFFT and OpenCL Context ..." << std::endl;
clSafeCall( clfftTeardown( ) );
clSafeCall(clReleaseContext( ctx ));
CHECK_CL( clfftTeardown( ) );
CHECK_CL(clReleaseContext( ctx ));
ctx = 0;
}
}
Expand All @@ -90,7 +90,7 @@ namespace ClFFT
template<clfftDim FFTDim, size_t Ndim>
constexpr void makePlan(clfftPlanHandle& plan, const std::array<unsigned,Ndim>& e){
size_t clLengths[3] = {e[0], Ndim==2?e[1]:1, Ndim==3?e[2]:1};
clSafeCall(clfftCreateDefaultPlan(&plan, context.ctx, FFTDim, clLengths));
CHECK_CL(clfftCreateDefaultPlan(&plan, context.ctx, FFTDim, clLengths));
}

/**
Expand Down Expand Up @@ -141,7 +141,7 @@ namespace ClFFT
if(context.ctx==0)
context.create();
queue_ = clCreateCommandQueue( context.ctx, context.device, 0, &err );
clCheckError(err);
CHECK_CL(err);


n_ = std::accumulate(extents_.begin(), extents_.end(), 1, std::multiplies<unsigned>());
Expand Down Expand Up @@ -180,10 +180,10 @@ namespace ClFFT
size_t size1 = 0;
size_t size2 = 0;
init_forward();
clSafeCall(clfftGetTmpBufSize( plan_, &size1 ));
CHECK_CL(clfftGetTmpBufSize( plan_, &size1 ));
init_backward();
clSafeCall(clfftGetTmpBufSize( plan_, &size2 ));
clSafeCall(clfftDestroyPlan( &plan_ ));
CHECK_CL(clfftGetTmpBufSize( plan_, &size2 ));
CHECK_CL(clfftDestroyPlan( &plan_ ));
return std::max(size1,size2);
}

Expand All @@ -210,17 +210,17 @@ namespace ClFFT
// create FFT plan handle
void init_forward() {
makePlan<FFTDim>(plan_, extents_);
clSafeCall(clfftSetPlanPrecision(plan_, traits::FFTPrecision<TPrecision>::value));
clSafeCall(clfftSetLayout(plan_,
CHECK_CL(clfftSetPlanPrecision(plan_, traits::FFTPrecision<TPrecision>::value));
CHECK_CL(clfftSetLayout(plan_,
traits::FFTLayout<IsComplex>::value,
traits::FFTLayout<IsComplex>::value_transformed));
clSafeCall(clfftSetResultLocation(plan_, traits::FFTInplace<IsInplace>::value));
CHECK_CL(clfftSetResultLocation(plan_, traits::FFTInplace<IsInplace>::value));
if(Padding){
clSafeCall(clfftSetPlanInStride(plan_, FFTDim, strides));
clSafeCall(clfftSetPlanOutStride(plan_, FFTDim, transform_strides));
clSafeCall(clfftSetPlanDistance(plan_, dist, transform_dist));
CHECK_CL(clfftSetPlanInStride(plan_, FFTDim, strides));
CHECK_CL(clfftSetPlanOutStride(plan_, FFTDim, transform_strides));
CHECK_CL(clfftSetPlanDistance(plan_, dist, transform_dist));
}
clSafeCall(clfftBakePlan(plan_,
CHECK_CL(clfftBakePlan(plan_,
1, // number of queues
&queue_,
nullptr, // callback
Expand All @@ -230,16 +230,16 @@ namespace ClFFT
// recreates plan if needed
void init_backward() {
if(IsComplex==false){
clSafeCall(clfftSetLayout(plan_,
CHECK_CL(clfftSetLayout(plan_,
traits::FFTLayout<IsComplex>::value_transformed,
traits::FFTLayout<IsComplex>::value));
if(Padding){
clSafeCall(clfftSetPlanOutStride(plan_, FFTDim, strides));
clSafeCall(clfftSetPlanInStride(plan_, FFTDim, transform_strides));
clSafeCall(clfftSetPlanDistance(plan_, transform_dist, dist));
CHECK_CL(clfftSetPlanOutStride(plan_, FFTDim, strides));
CHECK_CL(clfftSetPlanInStride(plan_, FFTDim, transform_strides));
CHECK_CL(clfftSetPlanDistance(plan_, transform_dist, dist));
}

clSafeCall(clfftBakePlan(plan_,
CHECK_CL(clfftBakePlan(plan_,
1, // number of queues
&queue_,
0, // callback
Expand All @@ -248,7 +248,7 @@ namespace ClFFT
}

void execute_forward() {
clSafeCall(clfftEnqueueTransform(plan_,
CHECK_CL(clfftEnqueueTransform(plan_,
CLFFT_FORWARD,
1, // numQueuesAndEvents
&queue_,
Expand All @@ -258,10 +258,10 @@ namespace ClFFT
&data_, // input
IsInplace ? &data_ : &data_transform_, // output
0)); // tmpBuffer
clSafeCall(clFinish(queue_));
CHECK_CL(clFinish(queue_));
}
void execute_backward() {
clSafeCall(clfftEnqueueTransform(plan_,
CHECK_CL(clfftEnqueueTransform(plan_,
CLFFT_BACKWARD,
1, // numQueuesAndEvents
&queue_,
Expand All @@ -271,14 +271,14 @@ namespace ClFFT
IsInplace ? &data_ : &data_transform_, // input
IsInplace ? &data_ : &data_, // output
nullptr)); // tmpBuffer
clSafeCall(clFinish(queue_));
CHECK_CL(clFinish(queue_));
}
template<typename THostData>
void upload(THostData* input) {
if(Padding && NDim>1)
{
//printf("pitch=%zu w=%zu h=%zu\n", pitch, w, h);
clSafeCall(clEnqueueWriteBufferRect( queue_,
CHECK_CL(clEnqueueWriteBufferRect( queue_,
data_,
CL_TRUE, // blocking_write
offset, // buffer origin
Expand All @@ -293,7 +293,7 @@ namespace ClFFT
nullptr, // event_wait_list
nullptr )); // event
}else{
clSafeCall(clEnqueueWriteBuffer( queue_,
CHECK_CL(clEnqueueWriteBuffer( queue_,
data_,
CL_TRUE, // blocking_write
0, // offset
Expand All @@ -308,7 +308,7 @@ namespace ClFFT
void download(THostData* output) {
if(Padding && NDim>1)
{
clSafeCall(clEnqueueReadBufferRect( queue_,
CHECK_CL(clEnqueueReadBufferRect( queue_,
data_,
CL_TRUE, // blocking_write
offset, // buffer origin
Expand All @@ -323,7 +323,7 @@ namespace ClFFT
nullptr, // event_wait_list
nullptr )); // event
}else{
clSafeCall(clEnqueueReadBuffer( queue_,
CHECK_CL(clEnqueueReadBuffer( queue_,
data_,
CL_TRUE, // blocking_write
0, // offset
Expand All @@ -336,24 +336,24 @@ namespace ClFFT
}

void destroy() {
clSafeCall( clFinish(queue_) );
clSafeCall( clReleaseMemObject( data_ ) );
CHECK_CL( clFinish(queue_) );
CHECK_CL( clReleaseMemObject( data_ ) );
if(IsInplace==false)
clSafeCall( clReleaseMemObject( data_transform_ ) );
CHECK_CL( clReleaseMemObject( data_transform_ ) );

clSafeCall(clfftDestroyPlan( &plan_ ));
clSafeCall( clReleaseCommandQueue( queue_ ) );
CHECK_CL(clfftDestroyPlan( &plan_ ));
CHECK_CL( clReleaseCommandQueue( queue_ ) );
data_ = 0;
data_transform_ = 0;
plan_ = 0;
queue_ = 0;
}
};

typedef gearshifft::FFT<gearshifft::FFT_Inplace_Real, ClFFTImpl, TimerCPU> Inplace_Real;
typedef gearshifft::FFT<gearshifft::FFT_Outplace_Real, ClFFTImpl, TimerCPU> Outplace_Real;
typedef gearshifft::FFT<gearshifft::FFT_Inplace_Complex, ClFFTImpl, TimerCPU> Inplace_Complex;
typedef gearshifft::FFT<gearshifft::FFT_Outplace_Complex, ClFFTImpl, TimerCPU> Outplace_Complex;
typedef gearshifft::FFT<gearshifft::FFT_Inplace_Real, ClFFTImpl, helper::TimerCPU> Inplace_Real;
typedef gearshifft::FFT<gearshifft::FFT_Outplace_Real, ClFFTImpl, helper::TimerCPU> Outplace_Real;
typedef gearshifft::FFT<gearshifft::FFT_Inplace_Complex, ClFFTImpl, helper::TimerCPU> Inplace_Complex;
typedef gearshifft::FFT<gearshifft::FFT_Outplace_Complex, ClFFTImpl, helper::TimerCPU> Outplace_Complex;

} // namespace ClFFT
} // gearshifft
Expand Down
13 changes: 6 additions & 7 deletions inc/clfft_helper.hpp
Expand Up @@ -8,9 +8,8 @@
#include <vector>
#include <utility> // pair

#define clSafeCall( err ) gearshifft::ClFFT::__clSafeCall( err, __FILE__, __LINE__ )
#define clFFTSafeCall( err ) gearshifft::ClFFT::__clSafeCall( err, __FILE__, __LINE__ )
#define clCheckError(err) gearshifft::ClFFT::__clSafeCall( err, __FILE__, __LINE__ )
#define CHECK_CL( err ) gearshifft::ClFFT::check_error( err, __FILE__, __LINE__ )

#define STRINGIFY(A) #A
#define clFFTStatusCase(s) case s: return STRINGIFY(s)

Expand Down Expand Up @@ -105,11 +104,11 @@ namespace gearshifft {
}
}
template<typename T>
inline void __clSafeCall( T err, const char *file, const int line )
inline void check_error( T err, const char *file, const int line )
{
if ( CL_SUCCESS != err )
{
fprintf( stderr, "clSafeCall() failed at %s:%i : %s\n",
fprintf( stderr, "OpenCL error at %s:%i : %s\n",
file, line, getOpenCLErrorString( err ) );

throw std::runtime_error("OpenCL Error: " + std::string(getOpenCLErrorString(err))+ " "+std::to_string(err));
Expand Down Expand Up @@ -189,8 +188,8 @@ namespace gearshifft {
break;
}
if(!found){
clSafeCall(clGetPlatformIDs( 1, platform, NULL ));
clSafeCall(clGetDeviceIDs( *platform, CL_DEVICE_TYPE_DEFAULT, 1, device, NULL ));
CHECK_CL(clGetPlatformIDs( 1, platform, NULL ));
CHECK_CL(clGetDeviceIDs( *platform, CL_DEVICE_TYPE_DEFAULT, 1, device, NULL ));
}
return 0;
}
Expand Down
26 changes: 13 additions & 13 deletions inc/cufft.hpp
Expand Up @@ -186,11 +186,11 @@ namespace CuFFT {

void malloc() {
if(IsInplace){
CHECK_ERROR(cudaMalloc(&data_, data_size_));
CHECK_CUDA(cudaMalloc(&data_, data_size_));
data_transform_ = reinterpret_cast<ComplexType*>(data_);
}else{
CHECK_ERROR(cudaMalloc(&data_, data_size_));
CHECK_ERROR(cudaMalloc(&data_transform_, data_transform_size_));
CHECK_CUDA(cudaMalloc(&data_, data_size_));
CHECK_CUDA(cudaMalloc(&data_transform_, data_transform_size_));
}
}

Expand Down Expand Up @@ -222,9 +222,9 @@ namespace CuFFT {
size_t w = extents_[NDim-1] * sizeof(THostData);
size_t h = n_ * sizeof(THostData) / w;
size_t pitch = (extents_[NDim-1]/2+1) * sizeof(ComplexType);
CHECK_ERROR(cudaMemcpy2D(data_, pitch, input, w, w, h, cudaMemcpyHostToDevice));
CHECK_CUDA(cudaMemcpy2D(data_, pitch, input, w, w, h, cudaMemcpyHostToDevice));
}else{
CHECK_ERROR(cudaMemcpy(data_, input, data_size_, cudaMemcpyHostToDevice));
CHECK_CUDA(cudaMemcpy(data_, input, data_size_, cudaMemcpyHostToDevice));
}
}

Expand All @@ -235,24 +235,24 @@ namespace CuFFT {
size_t w = extents_[NDim-1] * sizeof(THostData);
size_t h = n_ * sizeof(THostData) / w;
size_t pitch = (extents_[NDim-1]/2+1) * sizeof(ComplexType);
CHECK_ERROR(cudaMemcpy2D(output, w, data_, pitch, w, h, cudaMemcpyDeviceToHost));
CHECK_CUDA(cudaMemcpy2D(output, w, data_, pitch, w, h, cudaMemcpyDeviceToHost));
}else{
CHECK_ERROR(cudaMemcpy(output, data_, data_size_, cudaMemcpyDeviceToHost));
CHECK_CUDA(cudaMemcpy(output, data_, data_size_, cudaMemcpyDeviceToHost));
}
}

void destroy() {
CHECK_ERROR( cudaFree(data_) );
CHECK_CUDA( cudaFree(data_) );
if(IsInplace==false)
CHECK_ERROR( cudaFree(data_transform_) );
CHECK_CUDA( cudaFree(data_transform_) );
CHECK_CUFFT( cufftDestroy(plan_) );
}
};

typedef gearshifft::FFT<gearshifft::FFT_Inplace_Real, CuFFTImpl, TimerGPU> Inplace_Real;
typedef gearshifft::FFT<gearshifft::FFT_Outplace_Real, CuFFTImpl, TimerGPU> Outplace_Real;
typedef gearshifft::FFT<gearshifft::FFT_Inplace_Complex, CuFFTImpl, TimerGPU> Inplace_Complex;
typedef gearshifft::FFT<gearshifft::FFT_Outplace_Complex, CuFFTImpl, TimerGPU> Outplace_Complex;
typedef gearshifft::FFT<gearshifft::FFT_Inplace_Real, CuFFTImpl, helper::TimerGPU> Inplace_Real;
typedef gearshifft::FFT<gearshifft::FFT_Outplace_Real, CuFFTImpl, helper::TimerGPU> Outplace_Real;
typedef gearshifft::FFT<gearshifft::FFT_Inplace_Complex, CuFFTImpl, helper::TimerGPU> Inplace_Complex;
typedef gearshifft::FFT<gearshifft::FFT_Outplace_Complex, CuFFTImpl, helper::TimerGPU> Outplace_Complex;

} // namespace CuFFT
} // namespace gearshifft
Expand Down
41 changes: 37 additions & 4 deletions inc/cufft_helper.hpp
@@ -1,15 +1,47 @@
#ifndef CUFFT_HELPER_HPP_
#define CUFFT_HELPER_HPP_

#include "helper.h"

#include <cuda_runtime.h>
#include <stdio.h>
#include <stdlib.h>
#include <cufft.h>

#define CHECK_CUFFT(ans) gearshifft::CuFFT::check_error((ans), #ans, __FILE__, __LINE__)
#ifndef CUDA_DISABLE_ERROR_CHECKING
#define CHECK_CUDA(ans) gearshifft::CuFFT::check_cuda((ans), #ans, __FILE__, __LINE__)
#define CHECK_CUFFT(ans) gearshifft::CuFFT::check_cufft((ans), #ans, __FILE__, __LINE__)
#define CHECK_LAST(msg) gearshifft::CuFFT::check_cuda_last(msg, __FILE__, __LINE__)
#else
#define CHECK_CUDA(ans) {}
#define CHECK_CUFFT(ans) {}
#define CHECK_LAST(msg) {}
#endif

namespace gearshifft {
namespace CuFFT {

inline
void check_cuda(cudaError_t code, const char *func, const char *file, int line)
{
if (code != cudaSuccess)
{
fprintf(stderr,"CUDA Error '%s' at %s:%d (%s)\n", cudaGetErrorString(code), file, line, func);
cudaDeviceReset();
exit(static_cast<unsigned int>(code));
}
}
inline
void check_cuda_last(const char *msg, const char *file, int line)
{
cudaError_t code = cudaGetLastError();
if (code != cudaSuccess)
{
fprintf(stderr,"CUDA Error '%s' at %s:%d (%s)\n", cudaGetErrorString(code), file, line, msg);

cudaDeviceReset();
exit(static_cast<unsigned int>(code));
}
}

static const char* cufftResultToString(cufftResult error)
{
switch (error)
Expand Down Expand Up @@ -47,7 +79,8 @@ namespace CuFFT {

return "<unknown>";
}
void check_error(cufftResult code, const char *func, const char *file, int line)
inline
void check_cufft(cufftResult code, const char *func, const char *file, int line)
{
if (code)
{
Expand Down
6 changes: 3 additions & 3 deletions inc/fft_abstract.hpp
Expand Up @@ -59,10 +59,10 @@ namespace gearshifft
using TPrecision = typename Precision<typename TVector::value_type,
TFFT::IsComplex >::type;
assert(vec.data());
Statistics& stats = results.stats;
helper::Statistics& stats = results.stats;

TimeStatistics<TDeviceTimer> timer_dev(&stats); // or OpenCL timer
TimeStatistics<TimerCPU> timer_cpu(&stats);
helper::TimeStatistics<TDeviceTimer> timer_dev(&stats);
helper::TimeStatistics<helper::TimerCPU> timer_cpu(&stats);
int i_gpu = timer_dev.append("Device Runtime");
int i_cpu_alloc = timer_cpu.append("CPU Alloc");
int i_gpu_upload = timer_dev.append("Device Upload");
Expand Down
2 changes: 1 addition & 1 deletion inc/fixture_benchmark.hpp
Expand Up @@ -32,7 +32,7 @@ namespace gearshifft
{
struct Results
{
Statistics stats;
helper::Statistics stats;
size_t alloc_mem_in_bytes = 0;
size_t plan_mem_in_bytes = 0;
};
Expand Down

0 comments on commit de7d20d

Please sign in to comment.