Skip to content

Instantly share code, notes, and snippets.

@mattn
Created June 1, 2018 11:26
Show Gist options
  • Save mattn/4284808246d3c4923d9d284a168c7f7f to your computer and use it in GitHub Desktop.
Save mattn/4284808246d3c4923d9d284a168c7f7f to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"log"
"unsafe"
"github.com/jgillich/go-opencl/cl"
)
func main() {
platforms, err := cl.GetPlatforms()
if err != nil {
log.Fatal(err)
}
var device *cl.Device
loop:
for _, platform := range platforms {
devices, err := cl.GetDevices(platform, cl.DeviceTypeDefault)
if err != nil {
continue
}
for _, d := range devices {
if d.Available() && d.CompilerAvailable() {
device = d
break loop
}
}
}
if device == nil {
log.Fatal("cannot find device")
}
context, err := cl.CreateContext([]*cl.Device{device})
if err != nil {
log.Fatal(err)
}
defer context.Release()
queue, err := context.CreateCommandQueue(device, 0)
if err != nil {
log.Fatal(err)
}
defer queue.Release()
program, err := context.CreateProgramWithSource([]string{`
float _fib(float n) {
if(n <= 0) return 0;
if(n > 0 && n < 3) return 1;
float r = 0, n1 = 1, n2 = 1;
for (int i = 2; i < n; i++) {
r = n1 + n2;
n1 = n2;
n2 = r;
}
return r;
}
kernel void fib(
global const float *a,
global float *r) {
unsigned int id = get_global_id(0);
r[id] = _fib(a[id]);
}
`})
if err != nil {
log.Fatal(err)
}
defer program.Release()
err = program.BuildProgram([]*cl.Device{device}, "")
if err != nil {
log.Fatal(err)
}
kernel, err := program.CreateKernel("fib")
if err != nil {
log.Fatal(err)
}
defer kernel.Release()
a := []float32{32}
r := []float32{0}
buf1, err := context.CreateEmptyBuffer(cl.MemReadWrite, 4)
if err != nil {
log.Fatal(err)
}
defer buf1.Release()
buf2, err := context.CreateEmptyBuffer(cl.MemReadWrite, 4)
if err != nil {
log.Fatal(err)
}
defer buf2.Release()
event, err := queue.EnqueueWriteBuffer(buf1, true, 0, 4, unsafe.Pointer(&a[0]), nil)
if err != nil {
log.Fatal(err)
}
defer event.Release()
event, err = queue.EnqueueWriteBuffer(buf2, true, 0, 4, unsafe.Pointer(&r[0]), nil)
if err != nil {
log.Fatal(err)
}
defer event.Release()
err = kernel.SetArg(0, buf1)
if err != nil {
log.Fatal(err)
}
err = kernel.SetArg(1, buf2)
if err != nil {
log.Fatal(err)
}
event, err = queue.EnqueueNDRangeKernel(kernel, nil, []int{1, 1}, []int{1, 1}, nil)
if err != nil {
log.Fatal(err)
}
defer event.Release()
event, err = queue.EnqueueReadBuffer(buf2, true, 0, 4, unsafe.Pointer(&r[0]), nil)
if err != nil {
log.Fatal(err)
}
defer event.Release()
v := int64(r[0])
fmt.Println(v)
}
@fukitall
Copy link

  • kernel void fib(
    global const float *a,
    global float *r) {
    unsigned int id = get_global_id(0);
    r[id] = _fib(a[id]);
    }
    `})
    if err != nil {
    log.Fatal(err)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment