forked from Dadido3/blackcl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdevice.go
152 lines (130 loc) · 4.53 KB
/
device.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package highCL
import (
"errors"
constants "github.com/opencl-pure/constantsCL"
pure "github.com/opencl-pure/pureCL"
"strings"
"unsafe"
)
// 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
type Device struct {
id []pure.Device
ctx pure.Context
queue pure.CommandQueue
programs []pure.Program // only one
platform *Platform
}
// Release releases the device
func (d *Device) Release() error {
var result error
for _, p := range d.programs {
if err := pure.StatusToErr(pure.ReleaseProgram(p)); err != nil {
result = pure.ErrJoin(result, err)
}
}
if err := pure.StatusToErr(pure.ReleaseCommandQueue(d.queue)); err != nil {
result = pure.ErrJoin(result, err)
}
if err := pure.StatusToErr(pure.ReleaseContext(d.ctx)); err != nil {
result = pure.ErrJoin(result, err)
}
return pure.ErrJoin(result, pure.StatusToErr(pure.ReleaseDevice(d.id[0])))
}
func (d *Device) GetInfoString(param pure.DeviceInfo) (string, error) {
strC := make([]byte, 1024)
var strN pure.Size
err := pure.StatusToErr(pure.GetDeviceInfo(d.id[0], param, 1024, strC, &strN))
if err != nil {
return "", err
}
return strings.TrimSpace(string(strC[:int(strN)-1])), nil
}
func (d *Device) String() (string, error) {
name, err := d.Name()
vendor, err2 := d.Vendor()
return name + " " + vendor, pure.ErrJoin(err, err2)
}
// Name device info - name
func (d *Device) Name() (string, error) {
return d.GetInfoString(constants.CL_DEVICE_NAME)
}
// Vendor device info - vendor
func (d *Device) Vendor() (string, error) {
return d.GetInfoString(constants.CL_DEVICE_VENDOR)
}
// Extensions device info - extensions
func (d *Device) Extensions() (string, error) {
return d.GetInfoString(constants.CL_DEVICE_EXTENSIONS)
}
// OpenCLCVersion device info - OpenCL C Version
func (d *Device) OpenCLCVersion() (string, error) {
return d.GetInfoString(constants.CL_DEVICE_OPENCL_C_VERSION)
}
// Profile device info - profile
func (d *Device) Profile() (string, error) {
return d.GetInfoString(constants.CL_DEVICE_PROFILE)
}
// Version device info - version
func (d *Device) Version() (string, error) {
return d.GetInfoString(constants.CL_DEVICE_VERSION)
}
// DriverVersion device info - driver version
func (d *Device) DriverVersion() (string, error) {
return d.GetInfoString(constants.CL_DRIVER_VERSION)
}
func (d *Device) PlatformName() (string, error) {
return d.platform.GetName()
}
func (d *Device) PlatformProfile() (string, error) {
return d.platform.GetProfile()
}
func (d *Device) PlatformOpenCLCVersion() (string, error) {
return d.platform.GetVersion()
}
func (d *Device) PlatformDriverVersion() (string, error) {
return d.platform.GetVersion()
}
func (d *Device) PlatformVendor() (string, error) {
return d.platform.GetVendor()
}
func (d *Device) PlatformExtensions() ([]pure.Extension, error) {
return d.platform.GetExtensions()
}
// AddProgram compiles program source, this function is very sensitive to strings coding,
// and more then 3 programs, so I recommend all kernels put in one string
func (d *Device) AddProgram(source string) (*Program, error) {
return d.AddMultipleProgramWithBuildingFlags([]string{source}, "")
}
// AddMultipleProgram compiles programs sources, this function is very sensitive to strings coding
func (d *Device) AddMultipleProgram(sources []string) (*Program, error) {
return d.AddMultipleProgramWithBuildingFlags(sources, "")
}
// AddMultipleProgramWithBuildingFlags compiles programs sources with flags, this function is very sensitive to strings coding
// add flags only when you know what you do
func (d *Device) AddMultipleProgramWithBuildingFlags(sources []string, flags string) (*Program, error) {
var ret pure.Status
p := pure.CreateProgramWithSource(d.ctx, pure.Size(len(sources)), sources, nil, &ret)
err := pure.StatusToErr(ret)
if err != nil {
return nil, err
}
flagsB := []byte{'\x00'}
if len(flags) > 0 {
flagsB = append([]byte(flags), byte('\x00'))
}
ret = pure.BuildProgram(p, 1, d.id, flagsB, nil, nil)
if ret != constants.CL_SUCCESS {
if ret == constants.CL_BUILD_PROGRAM_FAILURE {
var n pure.Size
pure.GetProgramBuildInfo(p, d.id[0], constants.CL_PROGRAM_BUILD_LOG, 0, nil, &n)
log := make([]byte, int(n))
pure.GetProgramBuildInfo(p, d.id[0], constants.CL_PROGRAM_BUILD_LOG, n, unsafe.Pointer(&log[0]), nil)
return nil, errors.New(string(log[:int(n)-1]))
}
return nil, pure.StatusToErr(ret)
}
d.programs = append(d.programs, p)
return &Program{program: p}, nil
}