Exemple #1
0
// Describes the OPTIONAL half precision floating-point capability of the OpenCL device
func (d *Device) HalfFPConfig() FPConfig {
	var fpConfig C.cl_device_fp_config
	if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_HALF_FP_CONFIG, C.size_t(unsafe.Sizeof(fpConfig)), unsafe.Pointer(&fpConfig), nil); err != C.CL_SUCCESS {
		return FPConfig(0)
	}
	return FPConfig(fpConfig)
}
Exemple #2
0
func (d *Device) Platform() *Platform {
	var devicePlatform C.cl_platform_id
	if err := C.clGetDeviceInfo(d.nullableId(), C.CL_DEVICE_PLATFORM, C.size_t(unsafe.Sizeof(devicePlatform)), unsafe.Pointer(&devicePlatform), nil); err != C.CL_SUCCESS {
		panic("Failed to get device platform")
	}
	return &Platform{id: devicePlatform}
}
Exemple #3
0
// Describes double precision floating-point capability of the OpenCL device
func (d *Device) DoubleFPConfig() FPConfig {
	var fpConfig C.cl_device_fp_config
	if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_DOUBLE_FP_CONFIG, C.size_t(unsafe.Sizeof(fpConfig)), unsafe.Pointer(&fpConfig), nil); err != C.CL_SUCCESS {
		panic("Failed to get double FP config")
	}
	return FPConfig(fpConfig)
}
Exemple #4
0
// Describes the execution capabilities of the device. The mandated minimum capability is CL_EXEC_KERNEL.
func (d *Device) ExecutionCapabilities() ExecCapability {
	var execCap C.cl_device_exec_capabilities
	if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_EXECUTION_CAPABILITIES, C.size_t(unsafe.Sizeof(execCap)), unsafe.Pointer(&execCap), nil); err != C.CL_SUCCESS {
		panic("Failed to get execution capabilities")
	}
	return ExecCapability(execCap)
}
Exemple #5
0
// Type of local memory supported. This can be set to CL_LOCAL implying dedicated
// local memory storage such as SRAM, or CL_GLOBAL. For custom devices, CL_NONE
// can also be returned indicating no local memory support.
func (d *Device) LocalMemType() LocalMemType {
	var memType C.cl_device_local_mem_type
	if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_LOCAL_MEM_TYPE, C.size_t(unsafe.Sizeof(memType)), unsafe.Pointer(&memType), nil); err != C.CL_SUCCESS {
		return LocalMemType(C.CL_NONE)
	}
	return LocalMemType(memType)
}
Exemple #6
0
func (d *Device) GlobalMemCacheType() MemCacheType {
	var memType C.cl_device_mem_cache_type
	if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, C.size_t(unsafe.Sizeof(memType)), unsafe.Pointer(&memType), nil); err != C.CL_SUCCESS {
		return MemCacheType(C.CL_NONE)
	}
	return MemCacheType(memType)
}
Exemple #7
0
// Describes single precision floating-point capability of the OpenCL device
func (d *Device) SingleFPConfig() FPConfig {
	var fpConfig C.cl_device_fp_config
	if err := C.clGetDeviceInfo(d.nullableId(), C.CL_DEVICE_SINGLE_FP_CONFIG, C.size_t(unsafe.Sizeof(fpConfig)), unsafe.Pointer(&fpConfig), nil); err != C.CL_SUCCESS {
		panic("Failed to get single FP config")
	}
	return FPConfig(fpConfig)
}
Exemple #8
0
func (d *Device) Type() DeviceType {
	var deviceType C.cl_device_type
	if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_TYPE, C.size_t(unsafe.Sizeof(deviceType)), unsafe.Pointer(&deviceType), nil); err != C.CL_SUCCESS {
		panic("Failed to get device type")
	}
	return DeviceType(deviceType)
}
Exemple #9
0
func (d *Device) QueueProperties() CommandQueueProperty {
	var val C.cl_command_queue_properties
	if err := C.clGetDeviceInfo(d.nullableId(), C.CL_DEVICE_QUEUE_PROPERTIES, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
		panic("Should never fail")
		return 0
	}
	return CommandQueueProperty(val)
}
Exemple #10
0
func (d *Device) getInfoUlong(param C.cl_device_info, panicOnError bool) (int64, error) {
	var val C.cl_ulong
	if err := C.clGetDeviceInfo(d.id, param, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
		if panicOnError {
			panic("Should never fail")
		}
		return 0, toError(err)
	}
	return int64(val), nil
}
Exemple #11
0
func (d *Device) getInfoBool(param C.cl_device_info, panicOnError bool) (bool, error) {
	var val C.cl_bool
	if err := C.clGetDeviceInfo(d.id, param, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
		if panicOnError {
			panic("Should never fail")
		}
		return false, toError(err)
	}
	return val == C.CL_TRUE, nil
}
Exemple #12
0
func (d *Device) getInfoUint(param C.cl_device_info, panicOnError bool) (uint, error) {
	var val C.cl_uint
	if err := C.clGetDeviceInfo(d.nullableId(), param, C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), nil); err != C.CL_SUCCESS {
		if panicOnError {
			panic("Should never fail")
		}
		return 0, toError(err)
	}
	return uint(val), nil
}
Exemple #13
0
func (d *Device) ParentDevice() *Device {
	var deviceId C.cl_device_id
	if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_PARENT_DEVICE, C.size_t(unsafe.Sizeof(deviceId)), unsafe.Pointer(&deviceId), nil); err != C.CL_SUCCESS {
		panic("ParentDevice failed")
	}
	if deviceId == nil {
		return nil
	}
	return &Device{id: deviceId}
}
Exemple #14
0
func (d *Device) getInfoString(param C.cl_device_info, panicOnError bool) (string, error) {
	var strC [1024]C.char
	var strN C.size_t
	if err := C.clGetDeviceInfo(d.id, param, 1024, unsafe.Pointer(&strC), &strN); err != C.CL_SUCCESS || strN < 1 {
		if panicOnError {
			panic("Should never fail")
		}
		return "", toError(err)
	}
	return C.GoStringN((*C.char)(unsafe.Pointer(&strC)), C.int(strN-1)), nil
}
Exemple #15
0
// Maximum number of work-items that can be specified in each dimension of the work-group to clEnqueueNDRangeKernel.
//
// Returns n size_t entries, where n is the value returned by the query for CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS.
//
// The minimum value is (1, 1, 1) for devices that are not of type CL_DEVICE_TYPE_CUSTOM.
func (d *Device) MaxWorkItemSizes() []int {
	dims := d.MaxWorkItemDimensions()
	sizes := make([]C.size_t, dims)
	if err := C.clGetDeviceInfo(d.id, C.CL_DEVICE_MAX_WORK_ITEM_SIZES, C.size_t(int(unsafe.Sizeof(sizes[0]))*dims), unsafe.Pointer(&sizes[0]), nil); err != C.CL_SUCCESS {
		panic("Failed to get max work item sizes")
	}
	intSizes := make([]int, dims)
	for i, s := range sizes {
		intSizes[i] = int(s)
	}
	return intSizes
}
Exemple #16
0
func (d *Device) GetInfoString(param C.cl_device_info, panicOnError bool) (string, error) {
	var strC [1024]C.char
	var strN C.size_t
	if err := C.clGetDeviceInfo(d.id, param, 1024, unsafe.Pointer(&strC), &strN); err != C.CL_SUCCESS {
		if panicOnError {
			panic("Should never fail")
		}
		return "", toError(err)
	}

	// OpenCL strings are NUL-terminated, and the terminator is included in strN
	// Go strings aren't NUL-terminated, so subtract 1 from the length
	return C.GoStringN((*C.char)(unsafe.Pointer(&strC)), C.int(strN-1)), nil
}
Exemple #17
0
// see https://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetDeviceInfo.html
func GetDeviceInfo(did DeviceId, paramName DeviceInfo, paramValueSize uint64, data unsafe.Pointer, paramValueSizeRet *uint64) ErrorCode {
	return ErrorCode(C.clGetDeviceInfo(did, C.cl_device_info(paramName), C.size_t(paramValueSize), data, (*C.size_t)(paramValueSizeRet)))
}
Exemple #18
0
	localMemorySize   uint64
	maxComputeUnits   int
	maxConstantArgs   int
	name              string
	nativeKernels     bool
	openclCVersion    string
	profile           string
	typeMask          int
	unifiedMemory     bool
	vendor            string
	vendorID          int
	version           string
}

var getDeviceInfo = makeGetInfo(func(id interface{}, info interface{}, size C.size_t, ptr unsafe.Pointer, retSize *C.size_t) C.cl_int {
	return C.clGetDeviceInfo(id.(C.cl_device_id), info.(C.cl_device_info), size, ptr, retSize)
})

func getDeviceByID(id C.cl_device_id) (d *Device, err error) {
	var cl_uint C.cl_uint
	var cl_ulong C.cl_ulong
	var cl_device_type C.cl_device_type
	var cl_bool C.cl_bool
	var str [4096]byte

	d = &Device{
		id: id,
	}

	getMap := []struct {
		info C.cl_device_info
Exemple #19
0
func CLGetDeviceInfo(device CL_device_id,
	param_name CL_device_info,
	param_value_size CL_size_t,
	param_value *interface{},
	param_value_size_ret *CL_size_t) CL_int {

	if (param_value_size == 0 || param_value == nil) && param_value_size_ret == nil {
		return CL_INVALID_VALUE
	} else {
		var c_param_value_size_ret C.size_t
		var c_errcode_ret C.cl_int

		if param_value_size == 0 || param_value == nil {
			c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
				C.cl_device_info(param_name),
				C.size_t(param_value_size),
				nil,
				&c_param_value_size_ret)
		} else {
			switch param_name {

			case CL_DEVICE_AVAILABLE,
				CL_DEVICE_COMPILER_AVAILABLE,
				CL_DEVICE_ENDIAN_LITTLE,
				CL_DEVICE_ERROR_CORRECTION_SUPPORT,
				CL_DEVICE_HOST_UNIFIED_MEMORY,
				CL_DEVICE_IMAGE_SUPPORT,
				CL_DEVICE_LINKER_AVAILABLE,
				CL_DEVICE_PREFERRED_INTEROP_USER_SYNC:

				var value C.cl_bool
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)
				*param_value = value == C.CL_TRUE

			case CL_DEVICE_ADDRESS_BITS,
				CL_DEVICE_MAX_CLOCK_FREQUENCY,
				CL_DEVICE_MAX_COMPUTE_UNITS,
				CL_DEVICE_MAX_CONSTANT_ARGS,
				CL_DEVICE_MAX_READ_IMAGE_ARGS,
				CL_DEVICE_MAX_SAMPLERS,
				CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS,
				CL_DEVICE_MAX_WRITE_IMAGE_ARGS,
				CL_DEVICE_MEM_BASE_ADDR_ALIGN,
				CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE,
				CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR,
				CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT,
				CL_DEVICE_NATIVE_VECTOR_WIDTH_INT,
				CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG,
				CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT,
				CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE,
				CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF,
				CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR,
				CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT,
				CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT,
				CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG,
				CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT,
				CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE,
				CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF,
				CL_DEVICE_VENDOR_ID,
				CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE,
				CL_DEVICE_PARTITION_MAX_SUB_DEVICES,
				CL_DEVICE_REFERENCE_COUNT,
				CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS,
				CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE,
				CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE,
				CL_DEVICE_MAX_ON_DEVICE_QUEUES,
				CL_DEVICE_MAX_ON_DEVICE_EVENTS,
				CL_DEVICE_MAX_PIPE_ARGS,
				CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS,
				CL_DEVICE_PIPE_MAX_PACKET_SIZE,
				CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT,
				CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT,
				CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT:

				var value C.cl_uint
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_uint(value)

			case CL_DEVICE_IMAGE2D_MAX_HEIGHT,
				CL_DEVICE_IMAGE2D_MAX_WIDTH,
				CL_DEVICE_IMAGE3D_MAX_DEPTH,
				CL_DEVICE_IMAGE3D_MAX_HEIGHT,
				CL_DEVICE_IMAGE3D_MAX_WIDTH,
				CL_DEVICE_MAX_PARAMETER_SIZE,
				CL_DEVICE_MAX_WORK_GROUP_SIZE,
				CL_DEVICE_PROFILING_TIMER_RESOLUTION,
				CL_DEVICE_IMAGE_MAX_BUFFER_SIZE,
				CL_DEVICE_IMAGE_MAX_ARRAY_SIZE,
				CL_DEVICE_PRINTF_BUFFER_SIZE,
				CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE,
				CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE:

				var value C.size_t
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_size_t(value)

			case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE,
				CL_DEVICE_GLOBAL_MEM_SIZE,
				CL_DEVICE_LOCAL_MEM_SIZE,
				CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE,
				CL_DEVICE_MAX_MEM_ALLOC_SIZE:

				var value C.cl_ulong
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_ulong(value)

			case CL_DEVICE_PLATFORM:

				var value C.cl_platform_id
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_platform_id{value}

			case CL_DEVICE_PARENT_DEVICE:
				var value C.cl_device_id

				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_device_id{value}

			case CL_DEVICE_TYPE:
				var value C.cl_device_type
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_device_type(value)

			case CL_DEVICE_EXTENSIONS,
				CL_DEVICE_NAME,
				CL_DEVICE_OPENCL_C_VERSION,
				CL_DEVICE_PROFILE,
				CL_DEVICE_VENDOR,
				CL_DEVICE_VERSION,
				CL_DRIVER_VERSION,
				CL_DEVICE_BUILT_IN_KERNELS:

				value := make([]C.char, param_value_size)
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value[0]),
					&c_param_value_size_ret)

				*param_value = C.GoStringN(&value[0], C.int(c_param_value_size_ret-1))

			case CL_DEVICE_SINGLE_FP_CONFIG,
				CL_DEVICE_DOUBLE_FP_CONFIG:
				var value C.cl_device_fp_config
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_device_fp_config(value)

			case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE:
				var value C.cl_device_mem_cache_type
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_device_mem_cache_type(value)

			case CL_DEVICE_LOCAL_MEM_TYPE:
				var value C.cl_device_local_mem_type
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_device_local_mem_type(value)

			case CL_DEVICE_EXECUTION_CAPABILITIES:
				var value C.cl_device_exec_capabilities
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_device_exec_capabilities(value)

			//case CL_DEVICE_QUEUE_PROPERTIES,//deprecated
			case CL_DEVICE_QUEUE_ON_HOST_PROPERTIES,
				CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES:
				var value C.cl_command_queue_properties
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_command_queue_properties(value)

			case CL_DEVICE_PARTITION_PROPERTIES,
				CL_DEVICE_PARTITION_TYPE:
				var param C.cl_device_partition_property
				length := int(C.size_t(param_value_size) / C.size_t(unsafe.Sizeof(param)))

				value1 := make([]C.cl_device_partition_property, length)
				value2 := make([]CL_device_partition_property, length)

				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value1[0]),
					&c_param_value_size_ret)

				for i := 0; i < length; i++ {
					value2[i] = CL_device_partition_property(value1[i])
				}

				*param_value = value2

			case CL_DEVICE_MAX_WORK_ITEM_SIZES:
				var param C.size_t
				length := int(C.size_t(param_value_size) / C.size_t(unsafe.Sizeof(param)))

				value1 := make([]C.size_t, length)
				value2 := make([]CL_size_t, length)

				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value1[0]),
					&c_param_value_size_ret)

				for i := 0; i < length; i++ {
					value2[i] = CL_size_t(value1[i])
				}

				*param_value = value2

			case CL_DEVICE_PARTITION_AFFINITY_DOMAIN:
				var value C.cl_device_affinity_domain
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_device_affinity_domain(value)

			case CL_DEVICE_SVM_CAPABILITIES:
				var value C.cl_bitfield //C.cl_device_svm_capabilities //use cl_bitfield to make darwin pass
				c_errcode_ret = C.clGetDeviceInfo(device.cl_device_id,
					C.cl_device_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_device_svm_capabilities(value)

			default:
				return CL_INVALID_VALUE
			}
		}

		if param_value_size_ret != nil {
			*param_value_size_ret = CL_size_t(c_param_value_size_ret)
		}

		return CL_int(c_errcode_ret)
	}
}
Exemple #20
0
func (d *Device) Property(prop DeviceProperty) interface{} {
	if value, ok := d.properties[prop]; ok {
		return value
	}

	var data interface{}
	var length C.size_t
	var ret C.cl_int

	switch prop {
	case DEVICE_AVAILABLE,
		DEVICE_COMPILER_AVAILABLE,
		DEVICE_ENDIAN_LITTLE,
		DEVICE_ERROR_CORRECTION_SUPPORT,
		DEVICE_HOST_UNIFIED_MEMORY,
		DEVICE_IMAGE_SUPPORT:
		//DEVICE_LINKER_AVAILABLE,
		//DEVICE_PREFERRED_INTEROP_USER_SYNC:
		var val C.cl_bool
		ret = C.clGetDeviceInfo(d.id, C.cl_device_info(prop), C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), &length)
		data = val == C.CL_TRUE

	case DEVICE_ADDRESS_BITS,
		DEVICE_MAX_CLOCK_FREQUENCY,
		DEVICE_MAX_COMPUTE_UNITS,
		DEVICE_MAX_CONSTANT_ARGS,
		DEVICE_MAX_READ_IMAGE_ARGS,
		DEVICE_MAX_SAMPLERS,
		DEVICE_MAX_WORK_ITEM_DIMENSIONS,
		DEVICE_MAX_WRITE_IMAGE_ARGS,
		DEVICE_MEM_BASE_ADDR_ALIGN,
		DEVICE_MIN_DATA_TYPE_ALIGN_SIZE,
		DEVICE_NATIVE_VECTOR_WIDTH_CHAR,
		DEVICE_NATIVE_VECTOR_WIDTH_SHORT,
		DEVICE_NATIVE_VECTOR_WIDTH_INT,
		DEVICE_NATIVE_VECTOR_WIDTH_LONG,
		DEVICE_NATIVE_VECTOR_WIDTH_FLOAT,
		DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE,
		DEVICE_NATIVE_VECTOR_WIDTH_HALF,
		//DEVICE_PARTITION_MAX_SUB_DEVICES,
		DEVICE_PREFERRED_VECTOR_WIDTH_CHAR,
		DEVICE_PREFERRED_VECTOR_WIDTH_SHORT,
		DEVICE_PREFERRED_VECTOR_WIDTH_INT,
		DEVICE_PREFERRED_VECTOR_WIDTH_LONG,
		DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT,
		DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE,
		DEVICE_PREFERRED_VECTOR_WIDTH_HALF,
		//DEVICE_REFERENCE_COUNT,
		DEVICE_VENDOR_ID:
		var val C.cl_uint
		ret = C.clGetDeviceInfo(d.id, C.cl_device_info(prop), C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), &length)
		data = val

	case DEVICE_IMAGE2D_MAX_HEIGHT,
		DEVICE_IMAGE2D_MAX_WIDTH,
		DEVICE_IMAGE3D_MAX_DEPTH,
		DEVICE_IMAGE3D_MAX_HEIGHT,
		DEVICE_IMAGE3D_MAX_WIDTH,
		//DEVICE_IMAGE_MAX_BUFFER_SIZE,
		//DEVICE_IMAGE_MAX_ARRAY_SIZE,
		DEVICE_MAX_PARAMETER_SIZE,
		DEVICE_MAX_WORK_GROUP_SIZE,
		//DEVICE_PRINTF_BUFFER_SIZE,
		DEVICE_PROFILING_TIMER_RESOLUTION:
		var val C.size_t
		ret = C.clGetDeviceInfo(d.id, C.cl_device_info(prop), C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), &length)
		data = val

	case DEVICE_GLOBAL_MEM_CACHE_SIZE,
		DEVICE_GLOBAL_MEM_SIZE,
		DEVICE_LOCAL_MEM_SIZE,
		DEVICE_MAX_CONSTANT_BUFFER_SIZE,
		DEVICE_MAX_MEM_ALLOC_SIZE:
		var val C.cl_ulong
		ret = C.clGetDeviceInfo(d.id, C.cl_device_info(prop), C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), &length)
		data = val

	/*case DEVICE_PLATFORM:
	var val C.cl_platform_id
	ret = C.clGetDeviceInfo(d.id, C.cl_device_info(prop), C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), &length)
	data = Platform{id: val}*/

	/*case DEVICE_PARENT_DEVICE:
	var val C.cl_device_id
	ret = C.clGetDeviceInfo(d.id, C.cl_device_info(prop), C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), &length)
	data = Device{id: val}*/

	case DEVICE_TYPE:
		var val C.cl_device_type
		ret = C.clGetDeviceInfo(d.id, C.cl_device_info(prop), C.size_t(unsafe.Sizeof(val)), unsafe.Pointer(&val), &length)
		data = DeviceType(val)

	case //DEVICE_BUILT_IN_KERNELS,
		DEVICE_EXTENSIONS,
		DEVICE_NAME,
		DEVICE_OPENCL_C_VERSION,
		DEVICE_PROFILE,
		DEVICE_VENDOR,
		DEVICE_VERSION,
		DRIVER_VERSION:
		if ret = C.clGetDeviceInfo(d.id, C.cl_device_info(prop), 0, nil, &length); ret != C.CL_SUCCESS || length < 1 {
			data = ""
			break
		}

		buf := make([]C.char, length)
		if ret = C.clGetDeviceInfo(d.id, C.cl_device_info(prop), length, unsafe.Pointer(&buf[0]), &length); ret != C.CL_SUCCESS || length < 1 {
			data = ""
			break
		}
		data = C.GoStringN(&buf[0], C.int(length-1))

	default:
		return nil
	}

	if ret != C.CL_SUCCESS {
		return nil
	}
	d.properties[prop] = data
	return d.properties[prop]
}