#pragma once
#if !defined( CLFFT_repo_H )
#define CLFFT_repo_H
#include <map>
#include "private.h"
#include "plan.h"
#include "lock.h"
#include "../statTimer/statisticalTimer.GPU.h"
class FFTRepo
{
struct FFTRepoKey
{
clfftGenerators gen;
const FFTKernelSignatureHeader * data;
cl_context context;
cl_device_id device;
bool dataIsPrivate;
FFTRepoKey(clfftGenerators gen_, const FFTKernelSignatureHeader * data_, cl_context context_, cl_device_id device_)
: gen(gen_), data(data_), context(context_), device(device_), dataIsPrivate(false)
{
}
void privatizeData()
{
char * tmp = new char[data->datasize];
::memcpy(tmp, data, data->datasize);
this->data = (FFTKernelSignatureHeader*) tmp;
dataIsPrivate = true;
}
void deleteData()
{
if ( dataIsPrivate && (this->data != NULL) )
{
char *tmp = (char *)(this->data);
delete[] tmp;
this->data = 0;
}
}
bool operator<(const FFTRepoKey & b) const
{
const FFTRepoKey & a = *this;
if (a.gen != b.gen)
{
return a.gen < b.gen;
}
else if (a.data->datasize != b.data->datasize)
{
return a.data->datasize < b.data->datasize;
}
else if (a.context != b.context)
{
return a.context < b.context;
}
else if (a.device != b.device)
{
return a.device < b.device;
}
else
{
return ::memcmp(a.data, b.data, a.data->datasize) < 0;
}
}
};
struct fftRepoValue {
std::string ProgramString;
std::string EntryPoint_fwd;
std::string EntryPoint_back;
cl_program clProgram;
fftRepoValue ()
: clProgram (NULL)
{}
};
typedef std::map< FFTRepoKey, fftRepoValue > fftRepoType;
typedef fftRepoType::iterator fftRepo_iterator;
fftRepoType mapFFTs;
struct fftKernels {
cl_kernel kernel_fwd;
cl_kernel kernel_back;
lockRAII* kernel_fwd_lock;
lockRAII* kernel_back_lock;
fftKernels ()
: kernel_fwd (NULL)
, kernel_back (NULL)
, kernel_fwd_lock(NULL)
, kernel_back_lock(NULL)
{}
};
typedef std::map< cl_program, fftKernels > mapKernelType;
typedef mapKernelType::iterator Kernel_iterator;
mapKernelType mapKernels;
typedef std::pair< FFTPlan*, lockRAII* > repoPlansValue;
typedef std::map< clfftPlanHandle, repoPlansValue > repoPlansType;
repoPlansType repoPlans;
static size_t planCount;
FFTRepo( )
{}
FFTRepo( const FFTRepo& );
FFTRepo& operator=( const FFTRepo& );
~FFTRepo( )
{
if( (!mapKernels.empty( )) || (!mapFFTs.empty( )) )
{
terr << _T( "Warning: Program terminating, but clFFT resources not freed." ) << std::endl;
terr << _T( "Please consider explicitly calling clfftTeardown( )." ) << std::endl;
}
};
public:
static lockRAII lockRepo;
static void* timerHandle;
static GpuStatTimer* pStatTimer;
clfftSetupData setupData;
static FFTRepo& getInstance( )
{
static FFTRepo fftRepo;
return fftRepo;
};
clfftStatus releaseResources( );
clfftStatus setProgramCode( const clfftGenerators gen, const FFTKernelSignatureHeader * data, const std::string& kernel, const cl_device_id &device, const cl_context& planContext );
clfftStatus getProgramCode( const clfftGenerators gen, const FFTKernelSignatureHeader * data, std::string& kernel, const cl_device_id &device, const cl_context& planContext );
clfftStatus setProgramEntryPoints( const clfftGenerators gen, const FFTKernelSignatureHeader * data, const char * kernel_fwd, const char * kernel_back, const cl_device_id &device, const cl_context& planContext );
clfftStatus getProgramEntryPoint( const clfftGenerators gen, const FFTKernelSignatureHeader * data, clfftDirection dir, std::string& kernel , const cl_device_id &device, const cl_context& planContext );
clfftStatus setclProgram( const clfftGenerators gen, const FFTKernelSignatureHeader * data, const cl_program& prog, const cl_device_id &device, const cl_context& planContext );
clfftStatus getclProgram( const clfftGenerators gen, const FFTKernelSignatureHeader * data, cl_program& prog, const cl_device_id &device, const cl_context& planContext );
clfftStatus setclKernel ( cl_program prog, clfftDirection dir, const cl_kernel& kernel );
clfftStatus getclKernel ( cl_program prog, clfftDirection dir, cl_kernel& kernel, lockRAII*& kernelLock);
clfftStatus createPlan( clfftPlanHandle* plHandle, FFTPlan*& fftPlan );
clfftStatus getPlan( clfftPlanHandle plHandle, FFTPlan*& fftPlan, lockRAII*& planLock );
clfftStatus deletePlan( clfftPlanHandle* plHandle );
};
#endif