blackcl

package module
v0.0.0-...-2c95478 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 18, 2019 License: MIT Imports: 6 Imported by: 0

README

BlackCL

Black magic with OpenCL. These are highly opinionated OpenCL bindings for Go. It tries to make GPU computing easy, with some sugar abstraction, Go's concurency and channels.

//Do not create platforms/devices/contexts/queues/...
//Just get the GPU
d, err := blackcl.GetDefaultDevice()
if err != nil {
	panic("no opencl device")
}
defer d.Release()

//BlackCL has several kinds of device memory object: Bytes, Vector, Image
//allocate buffer on the device (16 elems of float32)
v, err := d.NewVector(16)
if err != nil {
	panic("could not allocate buffer")
}
defer v.Release()

//copy data to the vector (it's async)
data := []float32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
err = <-v.Copy(data)
if err != nil {
	panic("could not copy data to buffer")
}

//an complicated kernel
const kernelSource = `
__kernel void addOne(__global float* data) {
	const int i = get_global_id (0);
	data[i] += 1;
}
`

//Add program source to device, get kernel
d.AddProgram(kernelSource)
k := d.Kernel("addOne")
//run kernel (global work size 16 and local work size 1)
err = <-k.Global(16).Local(1).Run(v)
if err != nil {
	panic("could not run kernel")
}

//Get data from vector
newData, err := v.Data()
if err != nil {
	panic("could not get data from buffer")
}

//prints out [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
fmt.Println(newData)

BlackCL also supports the image.Image interface, for image manipulation:

const invertColorKernel = `
__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;

__kernel void invert(__read_only image2d_t src, __write_only image2d_t dest) {
	const int2 pos = {get_global_id(0), get_global_id(1)};
	float4 pixel = read_imagef(src, sampler, pos);
	pixel.x = 1 - pixel.x;
	pixel.y = 1 - pixel.y;
	pixel.z = 1 - pixel.z;
	write_imagef(dest, pos, pixel);
}`

//read image file
imgFile, err := os.Open("test_data/opencl.png")
if err != nil {
	log.Fatal(err)
}
i, _, err := image.Decode(imgFile)
if err != nil {
	log.Fatal(err)
}
//create image buffer
img, err := d.NewImageFromImage(i)
if err != nil {
	log.Fatal(err)
}
defer img.Release()
//allocate an empty image for the result
invertedImg, err := d.NewImage(blackcl.ImageTypeRGBA, img.Bounds())
if err != nil {
	log.Fatal(err)
}
defer invertedImg.Release()
d.AddProgram(invertColorKernel)
//invert colors of the image
k := d.Kernel("invert")
err = <-k.Global(img.Bounds().Dx(), img.Bounds().Dy()).Local(1, 1).Run(img, invertedImg)
if err != nil {
	log.Fatal(err)
}
//get the inverted image data and save it to a file
inverted, err := invertedImg.Data()
if err != nil {
	log.Fatal(err)
}
f, err := os.Create("inverted.png")
if err != nil {
	log.Fatal(err)
}
png.Encode(f, inverted)

Documentation

Index

Constants

View Source
const (
	ImageTypeGray = ImageType(C.CL_INTENSITY)
	ImageTypeRGBA = ImageType(C.CL_RGBA)
)

available image types

Variables

View Source
var (
	ErrDeviceNotFound                     = "cl: Device Not Found"
	ErrDeviceNotAvailable                 = "cl: Device Not Available"
	ErrCompilerNotAvailable               = "cl: Compiler Not Available"
	ErrMemObjectAllocationFailure         = "cl: Mem Object Allocation Failure"
	ErrOutOfResources                     = "cl: Out Of Resources"
	ErrOutOfHostMemory                    = "cl: Out Of Host Memory"
	ErrProfilingInfoNotAvailable          = "cl: Profiling Info Not Available"
	ErrMemCopyOverlap                     = "cl: Mem Copy Overlap"
	ErrImageFormatMismatch                = "cl: Image Format Mismatch"
	ErrImageFormatNotSupported            = "cl: Image Format Not Supported"
	ErrBuildProgramFailure                = "cl: Build Program Failure"
	ErrMapFailure                         = "cl: Map Failure"
	ErrMisalignedSubBufferOffset          = "cl: Misaligned Sub Buffer Offset"
	ErrExecStatusErrorForEventsInWaitList = "cl: Exec Status Error For Events In Wait List"
	ErrCompileProgramFailure              = "cl: Compile Program Failure"
	ErrLinkerNotAvailable                 = "cl: Linker Not Available"
	ErrLinkProgramFailure                 = "cl: Link Program Failure"
	ErrDevicePartitionFailed              = "cl: Device Partition Failed"
	ErrKernelArgInfoNotAvailable          = "cl: Kernel Arg Info Not Available"
	ErrInvalidValue                       = "cl: Invalid Value"
	ErrInvalidDeviceType                  = "cl: Invalid Device Type"
	ErrInvalidPlatform                    = "cl: Invalid Platform"
	ErrInvalidDevice                      = "cl: Invalid Device"
	ErrInvalidContext                     = "cl: Invalid Context"
	ErrInvalidQueueProperties             = "cl: Invalid Queue Properties"
	ErrInvalidCommandQueue                = "cl: Invalid Command Queue"
	ErrInvalidHostPtr                     = "cl: Invalid Host Ptr"
	ErrInvalidMemObject                   = "cl: Invalid Mem Object"
	ErrInvalidImageFormatDescriptor       = "cl: Invalid Image Format Descriptor"
	ErrInvalidImageSize                   = "cl: Invalid Image Size"
	ErrInvalidSampler                     = "cl: Invalid Sampler"
	ErrInvalidBinary                      = "cl: Invalid Binary"
	ErrInvalidBuildOptions                = "cl: Invalid Build Options"
	ErrInvalidProgram                     = "cl: Invalid Program"
	ErrInvalidProgramExecutable           = "cl: Invalid Program Executable"
	ErrInvalidKernelName                  = "cl: Invalid Kernel Name"
	ErrInvalidKernelDefinition            = "cl: Invalid Kernel Definition"
	ErrInvalidKernel                      = "cl: Invalid Kernel"
	ErrInvalidArgIndex                    = "cl: Invalid Arg Index"
	ErrInvalidArgValue                    = "cl: Invalid Arg Value"
	ErrInvalidArgSize                     = "cl: Invalid Arg Size"
	ErrInvalidKernelArgs                  = "cl: Invalid Kernel Args"
	ErrInvalidWorkDimension               = "cl: Invalid Work Dimension"
	ErrInvalidWorkGroupSize               = "cl: Invalid Work Group Size"
	ErrInvalidWorkItemSize                = "cl: Invalid Work Item Size"
	ErrInvalidGlobalOffset                = "cl: Invalid Global Offset"
	ErrInvalidEventWaitList               = "cl: Invalid Event Wait List"
	ErrInvalidEvent                       = "cl: Invalid Event"
	ErrInvalidOperation                   = "cl: Invalid Operation"
	ErrInvalidGlObject                    = "cl: Invalid Gl Object"
	ErrInvalidBufferSize                  = "cl: Invalid Buffer Size"
	ErrInvalidMipLevel                    = "cl: Invalid Mip Level"
	ErrInvalidGlobalWorkSize              = "cl: Invalid Global Work Size"
	ErrInvalidProperty                    = "cl: Invalid Property"
	ErrInvalidImageDescriptor             = "cl: Invalid Image Descriptor"
	ErrInvalidCompilerOptions             = "cl: Invalid Compiler Options"
	ErrInvalidLinkerOptions               = "cl: Invalid Linker Options"
	ErrInvalidDevicePartitionCount        = "cl: Invalid Device Partition Count"
)

Common OpenCl errors

View Source
var (
	//ErrUnknown Generally an unexpected result from an OpenCL function (e.g. CL_SUCCESS but null pointer)
	ErrUnknown = errors.New("cl: unknown error")
)

Functions

This section is empty.

Types

type Bytes

type Bytes struct {
	// contains filtered or unexported fields
}

Bytes is a memory buffer on the device that holds []byte

func (*Bytes) Copy

func (b *Bytes) Copy(data []byte) <-chan error

Copy copies the data from host data to device buffer it's a non-blocking call, channel will return an error or nil if the data transfer is complete

func (*Bytes) Data

func (b *Bytes) Data() ([]byte, error)

Data gets data from device, it's a blocking call

func (*Bytes) Map

func (b *Bytes) Map(k *Kernel) <-chan error

Map applies an map kernel on all elements of the buffer

func (*Bytes) Release

func (b *Bytes) Release() error

Release releases the buffer on the device

func (*Bytes) Size

func (b *Bytes) Size() int

Size the size of the bytes buffer

type Device

type Device struct {
	// contains filtered or unexported fields
}

Device the only needed entrence for the BlackCL represents the device on which memory can be allocated and kernels run it abstracts away all the complexity of contexts/platforms/queues

func GetDefaultDevice

func GetDefaultDevice() (*Device, error)

GetDefaultDevice ...

func GetDevices

func GetDevices(deviceType DeviceType) ([]*Device, error)

GetDevices returns all devices of all platforms with specified type

func (*Device) AddProgram

func (d *Device) AddProgram(source string)

AddProgram copiles program source if an error ocurres in building the program the AddProgram will panic

func (*Device) DriverVersion

func (d *Device) DriverVersion() string

DriverVersion device info - driver version

func (*Device) Extensions

func (d *Device) Extensions() string

Extensions device info - extensions

func (*Device) Kernel

func (d *Device) Kernel(name string) *Kernel

Kernel returns an kernel if retrieving the kernel didn't complete the function will panic

func (*Device) Name

func (d *Device) Name() string

Name device info - name

func (*Device) NewBytes

func (d *Device) NewBytes(size int) (*Bytes, error)

NewBytes allocates new memory buffer with specified size on device

func (*Device) NewImage

func (d *Device) NewImage(imageType ImageType, bounds image.Rectangle) (*Image, error)

NewImage allocates an image buffer

func (*Device) NewImageFromImage

func (d *Device) NewImageFromImage(img image.Image) (*Image, error)

NewImageFromImage creates new Image and copies data from image.Image

func (*Device) NewVector

func (d *Device) NewVector(length int) (*Vector, error)

NewVector allocates new vector buffer with specified length

func (*Device) OpenCLCVersion

func (d *Device) OpenCLCVersion() string

OpenCLCVersion device info - OpenCL C Version

func (*Device) Profile

func (d *Device) Profile() string

Profile device info - profile

func (*Device) Release

func (d *Device) Release() error

Release releases the device

func (*Device) String

func (d *Device) String() string

func (*Device) Vendor

func (d *Device) Vendor() string

Vendor device info - vendor

func (*Device) Version

func (d *Device) Version() string

Version device info - version

type DeviceType

type DeviceType uint

DeviceType is an enum of device types

const (
	DeviceTypeCPU         DeviceType = C.CL_DEVICE_TYPE_CPU
	DeviceTypeGPU         DeviceType = C.CL_DEVICE_TYPE_GPU
	DeviceTypeAccelerator DeviceType = C.CL_DEVICE_TYPE_ACCELERATOR
	DeviceTypeDefault     DeviceType = C.CL_DEVICE_TYPE_DEFAULT
	DeviceTypeAll         DeviceType = C.CL_DEVICE_TYPE_ALL
)

All values of DeviceType

type ErrBlackCL

type ErrBlackCL C.cl_int

ErrBlackCL converts the OpenCL error code to an go error

func (ErrBlackCL) Error

func (e ErrBlackCL) Error() string

type ErrUnsupportedArgumentType

type ErrUnsupportedArgumentType struct {
	Index int
	Value interface{}
}

ErrUnsupportedArgumentType error

func (ErrUnsupportedArgumentType) Error

type Image

type Image struct {
	// contains filtered or unexported fields
}

Image memory buffer on the device with image data

func (*Image) Bounds

func (img *Image) Bounds() image.Rectangle

Bounds returns the image size

func (*Image) Copy

func (img *Image) Copy(i image.Image) <-chan error

Copy writes the image data to the buffer

func (*Image) Data

func (img *Image) Data() (image.Image, error)

Data gets data from an image buffer and returns an image.Image

func (*Image) Release

func (img *Image) Release() error

Release releases the buffer on the device

type ImageType

type ImageType int

ImageType type of the image enum

type Kernel

type Kernel struct {
	// contains filtered or unexported fields
}

Kernel represent an single kernel

func (*Kernel) Global

func (k *Kernel) Global(globalWorkSizes ...int) KernelWithGlobal

Global returns an kernel with global size set

type KernelCall

type KernelCall struct {
	// contains filtered or unexported fields
}

KernelCall is a kernel with global and local work sizes set and it's ready to be run

func (KernelCall) Run

func (kc KernelCall) Run(args ...interface{}) <-chan error

Run calls the kernel on its device with specified global and local work sizes and arguments it's a non-blocking call, so it returns a channel that will send an error value when the kernel is done or nil if the call was successful

type KernelWithGlobal

type KernelWithGlobal struct {
	// contains filtered or unexported fields
}

KernelWithGlobal is a kernel with the global size set to run the kernel it must also set the local size

func (KernelWithGlobal) Local

func (kg KernelWithGlobal) Local(localWorkSizes ...int) KernelCall

Local sets the local work sizes and returns an KernelCall which takes kernel arguments and runs the kernel

type Vector

type Vector struct {
	// contains filtered or unexported fields
}

Vector is a memory buffer on device that holds []float32

func (*Vector) Copy

func (v *Vector) Copy(data []float32) <-chan error

Copy copies the float32 data from host data to device buffer it's a non-blocking call, channel will return an error or nil if the data transfer is complete

func (*Vector) Data

func (v *Vector) Data() ([]float32, error)

Data gets float32 data from device, it's a blocking call

func (*Vector) Length

func (v *Vector) Length() int

Length the length of the vector

func (*Vector) Map

func (v *Vector) Map(k *Kernel) <-chan error

Map applies an map kernel on all elements of the vector

func (*Vector) Release

func (v *Vector) Release() error

Release releases the buffer on the device

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL