diff options
Diffstat (limited to 'Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/context.go')
-rw-r--r-- | Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/context.go | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/context.go b/Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/context.go new file mode 100644 index 000000000..67441bb5f --- /dev/null +++ b/Godeps/_workspace/src/github.com/Gustav-Simonsson/go-opencl/cl/context.go @@ -0,0 +1,161 @@ +package cl + +// #include <stdlib.h> +// #ifdef __APPLE__ +// #include "OpenCL/opencl.h" +// #else +// #include "cl.h" +// #endif +import "C" + +import ( + "runtime" + "unsafe" +) + +const maxImageFormats = 256 + +type Context struct { + clContext C.cl_context + devices []*Device +} + +type MemObject struct { + clMem C.cl_mem + size int +} + +func releaseContext(c *Context) { + if c.clContext != nil { + C.clReleaseContext(c.clContext) + c.clContext = nil + } +} + +func releaseMemObject(b *MemObject) { + if b.clMem != nil { + C.clReleaseMemObject(b.clMem) + b.clMem = nil + } +} + +func newMemObject(mo C.cl_mem, size int) *MemObject { + memObject := &MemObject{clMem: mo, size: size} + runtime.SetFinalizer(memObject, releaseMemObject) + return memObject +} + +func (b *MemObject) Release() { + releaseMemObject(b) +} + +// TODO: properties +func CreateContext(devices []*Device) (*Context, error) { + deviceIds := buildDeviceIdList(devices) + var err C.cl_int + clContext := C.clCreateContext(nil, C.cl_uint(len(devices)), &deviceIds[0], nil, nil, &err) + if err != C.CL_SUCCESS { + return nil, toError(err) + } + if clContext == nil { + return nil, ErrUnknown + } + context := &Context{clContext: clContext, devices: devices} + runtime.SetFinalizer(context, releaseContext) + return context, nil +} + +func (ctx *Context) GetSupportedImageFormats(flags MemFlag, imageType MemObjectType) ([]ImageFormat, error) { + var formats [maxImageFormats]C.cl_image_format + var nFormats C.cl_uint + if err := C.clGetSupportedImageFormats(ctx.clContext, C.cl_mem_flags(flags), C.cl_mem_object_type(imageType), maxImageFormats, &formats[0], &nFormats); err != C.CL_SUCCESS { + return nil, toError(err) + } + fmts := make([]ImageFormat, nFormats) + for i, f := range formats[:nFormats] { + fmts[i] = ImageFormat{ + ChannelOrder: ChannelOrder(f.image_channel_order), + ChannelDataType: ChannelDataType(f.image_channel_data_type), + } + } + return fmts, nil +} + +func (ctx *Context) CreateCommandQueue(device *Device, properties CommandQueueProperty) (*CommandQueue, error) { + var err C.cl_int + clQueue := C.clCreateCommandQueue(ctx.clContext, device.id, C.cl_command_queue_properties(properties), &err) + if err != C.CL_SUCCESS { + return nil, toError(err) + } + if clQueue == nil { + return nil, ErrUnknown + } + commandQueue := &CommandQueue{clQueue: clQueue, device: device} + runtime.SetFinalizer(commandQueue, releaseCommandQueue) + return commandQueue, nil +} + +func (ctx *Context) CreateProgramWithSource(sources []string) (*Program, error) { + cSources := make([]*C.char, len(sources)) + for i, s := range sources { + cs := C.CString(s) + cSources[i] = cs + defer C.free(unsafe.Pointer(cs)) + } + var err C.cl_int + clProgram := C.clCreateProgramWithSource(ctx.clContext, C.cl_uint(len(sources)), &cSources[0], nil, &err) + if err != C.CL_SUCCESS { + return nil, toError(err) + } + if clProgram == nil { + return nil, ErrUnknown + } + program := &Program{clProgram: clProgram, devices: ctx.devices} + runtime.SetFinalizer(program, releaseProgram) + return program, nil +} + +func (ctx *Context) CreateBufferUnsafe(flags MemFlag, size int, dataPtr unsafe.Pointer) (*MemObject, error) { + var err C.cl_int + clBuffer := C.clCreateBuffer(ctx.clContext, C.cl_mem_flags(flags), C.size_t(size), dataPtr, &err) + if err != C.CL_SUCCESS { + return nil, toError(err) + } + if clBuffer == nil { + return nil, ErrUnknown + } + return newMemObject(clBuffer, size), nil +} + +func (ctx *Context) CreateEmptyBuffer(flags MemFlag, size int) (*MemObject, error) { + return ctx.CreateBufferUnsafe(flags, size, nil) +} + +func (ctx *Context) CreateEmptyBufferFloat32(flags MemFlag, size int) (*MemObject, error) { + return ctx.CreateBufferUnsafe(flags, 4*size, nil) +} + +func (ctx *Context) CreateBuffer(flags MemFlag, data []byte) (*MemObject, error) { + return ctx.CreateBufferUnsafe(flags, len(data), unsafe.Pointer(&data[0])) +} + +//float64 +func (ctx *Context) CreateBufferFloat32(flags MemFlag, data []float32) (*MemObject, error) { + return ctx.CreateBufferUnsafe(flags, 4*len(data), unsafe.Pointer(&data[0])) +} + +func (ctx *Context) CreateUserEvent() (*Event, error) { + var err C.cl_int + clEvent := C.clCreateUserEvent(ctx.clContext, &err) + if err != C.CL_SUCCESS { + return nil, toError(err) + } + return newEvent(clEvent), nil +} + +func (ctx *Context) Release() { + releaseContext(ctx) +} + +// http://www.khronos.org/registry/cl/sdk/1.2/docs/man/xhtml/clCreateSubBuffer.html +// func (memObject *MemObject) CreateSubBuffer(flags MemFlag, bufferCreateType BufferCreateType, ) |