Files
pip/libs/main/opencl/piopencl.h

284 lines
7.3 KiB
C++

/*
PIP - Platform Independent Primitives
OpenCL wrappers
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIOPENCL_H
#define PIOPENCL_H
#include "pip_opencl_export.h"
#include "pivariant.h"
class PIP_OPENCL_EXPORT PIOpenCL {
public:
struct KernelArg;
struct Device;
struct Platform;
class Context;
class Buffer;
class Program;
class Kernel;
typedef PIVector<Device> DeviceList;
enum AddressQualifier {
AddressGlobal,
AddressLocal,
AddressConstant,
AddressPrivate,
};
enum AccessQualifier {
AccessReadOnly,
AccessWriteOnly,
AccessReadWrite,
AccessNone,
};
enum Direction {
Input = 0x01,
Output = 0x02,
InputOutput = Input | Output,
};
enum TypeQualifier {
TypeConst,
TypeRestrict,
TypeVolatile,
TypeNone,
};
enum ArgType {
Char = 1,
UChar,
Short,
UShort,
Int,
UInt,
Long,
ULong,
Float,
Double,
};
struct PIP_OPENCL_EXPORT KernelArg {
KernelArg();
AddressQualifier address_qualifier;
AccessQualifier access_qualifier;
Direction direction;
TypeQualifier type_qualifier;
PIString arg_name;
PIString type_name;
PIString base_type_name;
bool is_pointer;
ArgType arg_type;
int dims;
private:
friend class Kernel;
void init(void * _k, uint index);
};
struct PIP_OPENCL_EXPORT Device {
Device() {id = platform_id = 0; max_compute_units = max_clock_frequency = 0; max_memory_size = 0;}
bool isValid() const {return id != 0;}
PIString displayText() const {return name.trimmed() + " (" + device_version.trimmed() + ")";}
void * id;
void * platform_id;
PIString name;
PIString vendor;
PIString device_version;
PIString driver_version;
int max_compute_units;
int max_clock_frequency;
ullong max_memory_size;
};
struct PIP_OPENCL_EXPORT Platform {
Platform() {id = 0;}
bool isValid() const {return id != 0;}
PIString displayText() const {return name.trimmed() + " (" + version.trimmed() + ", " + profile.trimmed() + ")";}
void * id;
PIString name;
PIString vendor;
PIString profile;
PIString version;
PIStringList extensions;
PIVector<Device> devices;
};
class PIP_OPENCL_EXPORT Context {
friend class Buffer;
friend class Program;
friend class Kernel;
public:
~Context();
void * handle();
void * queue();
static Context * create(const DeviceList & dl);
static Context * create(const Device & d) {return create(DeviceList() << d);}
static Context * create(const PIString & part_name);
Program * createProgram(const PIString & source, const PIStringList & args = PIStringList(), PIString * error = 0);
template <typename T> Buffer * createBuffer(PIOpenCL::Direction dir, PIVector <T> & container) {
T def = T();
return createBuffer(dir, &container, Buffer::cVector , PIByteArray(&def, sizeof(T)), container.size());
}
template <typename T> Buffer * createBuffer(PIOpenCL::Direction dir, PIDeque <T> & container) {
T def = T();
return createBuffer(dir, &container, Buffer::cDeque , PIByteArray(&def, sizeof(T)), container.size());
}
template <typename T> Buffer * createBuffer(PIOpenCL::Direction dir, PIVector2D<T> & container) {
T def = T();
return createBuffer(dir, &container, Buffer::cVector2D, PIByteArray(&def, sizeof(T)), container.size());
}
template <typename T> Buffer * createBuffer(PIOpenCL::Direction dir, uint elements) {
T def = T();
Buffer * ret = createBuffer(dir, 0, Buffer::cNone, PIByteArray(&def, sizeof(T)), elements);
if (ret)
ret->clear();
return ret;
}
private:
Context();
void zero();
void deletePrograms();
void deleteBuffers();
Buffer * createBuffer(PIOpenCL::Direction dir, void * container, int type, PIByteArray def, uint elements);
PIVector<Program * > programs_;
PIVector<Buffer * > buffers_;
PRIVATE_DECLARATION(PIP_OPENCL_EXPORT)
};
class PIP_OPENCL_EXPORT Buffer {
friend class Context;
friend class Kernel;
public:
~Buffer();
void * handle();
bool resize(uint new_elements);
void clear();
void copyToContainer();
void copyTo(void * data);
void copyFromContainer();
void copyFrom(void * data);
uint elementsCount() const {return elements;}
private:
enum Container {
cNone,
cVector,
cDeque,
cVector2D,
};
Buffer();
void zero();
bool init();
void * containerData();
Context * context_;
Direction dir;
Container type;
void * container;
PIByteArray def;
uint elements;
PRIVATE_DECLARATION(PIP_OPENCL_EXPORT)
};
class PIP_OPENCL_EXPORT Program {
friend class Context;
friend class Kernel;
friend class Buffer;
public:
~Program();
Context * context() const {return context_;}
const PIString & sourceCode() const {return source_;}
Kernel * kernel(int index = 0) const {return kernels_[index];}
const PIVector<Kernel * > & kernels() const {return kernels_;}
private:
Program();
void zero();
bool initKernels(PIVector<void*> kerns);
Context * context_;
PIString source_;
PIVector<Kernel * > kernels_;
PRIVATE_DECLARATION(PIP_OPENCL_EXPORT)
};
class PIP_OPENCL_EXPORT Kernel {
friend class Program;
friend class Buffer;
public:
Program * program() const {return program_;}
bool execute();
void setExecuteRange(int size) {setExecuteRanges(PIVector<int>() << size);}
void setExecuteRanges(const PIVector<int> & ranges);
const PIString & name() const {return name_;}
const PIVector<KernelArg> & args() const {return args_;}
template <typename T> bool setArgValue(int index, const T & value) {return setArgValueS(index, PIVariant::fromValue(value));}
template <typename T> bool setArgValue(const PIString & arg, const T & value) {return setArgValue(argIndex(arg), value);}
bool setArgValue(const PIString & arg, const PIVariant & value) {return setArgValueS(argIndex(arg), value);}
bool bindArgValue(int index, Buffer * buffer);
bool bindArgValue(const PIString & arg, Buffer * buffer) {return bindArgValue(argIndex(arg), buffer);}
private:
Kernel();
~Kernel();
void zero();
bool init();
bool setArgValueS(int index, const PIVariant & value);
int argIndex(const PIString & an) const;
KernelArg argByName(const PIString & an) const;
Context * context_;
Program * program_;
PIString name_;
PIVector<KernelArg> args_;
PIVector<size_t> dims;
PRIVATE_DECLARATION(PIP_OPENCL_EXPORT)
};
static void init();
static const PIVector<Platform> & platforms();
static const PIVector<Device> devices();
static Device deviceByID(void * id);
static PIString prepareProgram(const PIString & prog);
private:
static PIString prog_header;
PIOpenCL() {;}
class PIP_OPENCL_EXPORT Initializer {
public:
Initializer();
static Initializer * instance();
void init();
PIVector<Platform> platforms_;
bool inited_;
};
};
PIP_OPENCL_EXPORT PICout operator <<(PICout s, const PIOpenCL::KernelArg & v);
#endif // PIOPENCL_H