Commit d23f7968 by Philipp Adolf

Enable creating, building and releasing programs

parent 090941a5
...@@ -25,8 +25,8 @@ It is mainly developed and tested on Linux and with Intel and Nvidia GPUs. It sh ...@@ -25,8 +25,8 @@ It is mainly developed and tested on Linux and with Intel and Nvidia GPUs. It sh
- [x] reading buffers (blocking only for now) - [x] reading buffers (blocking only for now)
- [ ] querying info - [ ] querying info
- [ ] program objects - [ ] program objects
- [ ] creating and releasing program objects - [x] creating and releasing program objects
- [ ] building program executables - [x] building program executables
- [ ] separate compiling and linking (not planned for now) - [ ] separate compiling and linking (not planned for now)
- [ ] unloading the compiler - [ ] unloading the compiler
- [ ] querying program (build) info - [ ] querying program (build) info
......
...@@ -7,6 +7,8 @@ package opencl ...@@ -7,6 +7,8 @@ package opencl
#include <CL/cl.h> #include <CL/cl.h>
#endif #endif
#include <stdlib.h>
extern void contextCallback(char *, void *, size_t, void *); extern void contextCallback(char *, void *, size_t, void *);
*/ */
import "C" import "C"
...@@ -34,10 +36,7 @@ func contextCallback(errinfo *C.char, private_info unsafe.Pointer, cb C.size_t, ...@@ -34,10 +36,7 @@ func contextCallback(errinfo *C.char, private_info unsafe.Pointer, cb C.size_t,
func CreateContext(properties *ContextProperties, devices []*Device, notify func(string, unsafe.Pointer, uintptr, interface{}), userdata interface{}) (*Context, error) { func CreateContext(properties *ContextProperties, devices []*Device, notify func(string, unsafe.Pointer, uintptr, interface{}), userdata interface{}) (*Context, error) {
context := Context{nil, notify, userdata, devices} context := Context{nil, notify, userdata, devices}
ids := make([]C.cl_device_id, len(devices)) ids := asCLDeviceIDs(devices)
for i, d := range devices {
ids[i] = d.id
}
var callback *[0]byte var callback *[0]byte
var user unsafe.Pointer var user unsafe.Pointer
...@@ -73,3 +72,21 @@ func (c Context) CreateCommandQueue(device Device, properties *CommandQueuePrope ...@@ -73,3 +72,21 @@ func (c Context) CreateCommandQueue(device Device, properties *CommandQueuePrope
func (c Context) CreateBuffer(flags MemoryFlags, size uintptr, hostPtr unsafe.Pointer) (*Memory, error) { func (c Context) CreateBuffer(flags MemoryFlags, size uintptr, hostPtr unsafe.Pointer) (*Memory, error) {
return createBuffer(c, flags, size, hostPtr) return createBuffer(c, flags, size, hostPtr)
} }
func (c Context) CreateProgramWithSource(source []string) (*Program, error) {
clSource := make([]*C.char, len(source))
for i, s := range source {
clSource[i] = C.CString(s)
defer C.free(unsafe.Pointer(clSource[i]))
}
var clSourcePtr **C.char
if len(source) > 0 {
clSourcePtr = &clSource[0]
}
var err C.cl_int
program := C.clCreateProgramWithSource(c.context, C.cl_uint(len(source)), clSourcePtr, nil, &err)
if err != C.CL_SUCCESS {
return nil, fmt.Errorf("failed to create program: %d", err)
}
return &Program{program}, nil
}
...@@ -64,3 +64,11 @@ func getDevices(platform Platform, deviceType DeviceType) ([]Device, error) { ...@@ -64,3 +64,11 @@ func getDevices(platform Platform, deviceType DeviceType) ([]Device, error) {
return devices, nil return devices, nil
} }
func asCLDeviceIDs(devices []*Device) []C.cl_device_id {
ids := make([]C.cl_device_id, len(devices))
for i, d := range devices {
ids[i] = d.id
}
return ids
}
package opencl
/*
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif
#include <stdlib.h>
*/
import "C"
import (
"fmt"
"unsafe"
)
type Program struct {
program C.cl_program
}
func (p Program) Release() error {
err := C.clReleaseProgram(p.program)
if err != C.CL_SUCCESS {
return fmt.Errorf("failed to release program: %d", err)
}
return nil
}
func (p Program) Build(devices []*Device, options string) error {
var idPtr *C.cl_device_id
if len(devices) > 0 {
idPtr = &asCLDeviceIDs(devices)[0]
}
clOptions := C.CString(options)
defer C.free(unsafe.Pointer(clOptions))
err := C.clBuildProgram(p.program, C.cl_uint(len(devices)), idPtr, clOptions, nil, nil)
if err != C.CL_SUCCESS {
return fmt.Errorf("failed to build program: %d", err)
}
return nil
}
func (p Program) BuildLog(device Device) (string, error) {
var n C.size_t
err := C.clGetProgramBuildInfo(p.program, device.id, C.CL_PROGRAM_BUILD_LOG, C.size_t(0), nil, &n)
if err != C.CL_SUCCESS {
return "", fmt.Errorf("failed to get build log size: %d", err)
}
result := make([]C.char, n)
err = C.clGetProgramBuildInfo(p.program, device.id, C.CL_PROGRAM_BUILD_LOG, n, unsafe.Pointer(&result[0]), nil)
if err != C.CL_SUCCESS {
return "", fmt.Errorf("failed to get build log: %d", err)
}
return C.GoString(&result[0]), nil
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment