コード例 #1
0
ファイル: program.go プロジェクト: jackscan/go-opencl
func (p *Program) BuildProgram(devices []*Device, options string) error {
	var cOptions *C.char
	if options != "" {
		cOptions = C.CString(options)
		defer C.free(unsafe.Pointer(cOptions))
	}
	var deviceList []C.cl_device_id
	var deviceListPtr *C.cl_device_id
	if devices != nil && len(devices) > 0 {
		deviceList = buildDeviceIdList(devices)
		deviceListPtr = &deviceList[0]
	}
	numDevices := C.cl_uint(len(deviceList))

	if err := C.clBuildProgram(p.clProgram, numDevices, deviceListPtr, cOptions, nil, nil); err != C.CL_SUCCESS {
		if err != C.CL_BUILD_PROGRAM_FAILURE {
			return toError(err)
		}
		var bLen C.size_t
		var err C.cl_int
		err = C.clGetProgramBuildInfo(p.clProgram, p.devices[0].id, C.CL_PROGRAM_BUILD_LOG, 0, nil, &bLen)
		if err != C.CL_SUCCESS {
			return toError(err)
		}
		buffer := make([]byte, bLen)
		err = C.clGetProgramBuildInfo(p.clProgram, p.devices[0].id, C.CL_PROGRAM_BUILD_LOG, C.size_t(len(buffer)), unsafe.Pointer(&buffer[0]), &bLen)
		if err != C.CL_SUCCESS {
			return toError(err)
		}
		return BuildError(string(buffer[:bLen-1]))
	}
	return nil
}
コード例 #2
0
ファイル: program.go プロジェクト: snipsnipsnip/go-opencl
func (p *Program) Property(dev Device, prop BuildProperty) string {
	var count C.size_t
	if ret := C.clGetProgramBuildInfo(p.id, dev.id, C.cl_program_build_info(prop), 0, nil, &count); ret != C.CL_SUCCESS || count < 1 {
		return ""
	}

	buf := make([]C.char, count)
	if ret := C.clGetProgramBuildInfo(p.id, dev.id, C.cl_program_build_info(prop), count, unsafe.Pointer(&buf[0]), &count); ret != C.CL_SUCCESS || count < 1 {
		return ""
	}
	return C.GoStringN(&buf[0], C.int(count-1))
}
コード例 #3
0
ファイル: program.go プロジェクト: aa1214808834/go-opencl-1
func (p *Program) BuildProgram(devices []*Device, options string) error {
	var cOptions *C.char
	if options != "" {
		cOptions = C.CString(options)
		defer C.free(unsafe.Pointer(cOptions))
	}
	var deviceList []C.cl_device_id
	var deviceListPtr *C.cl_device_id
	numDevices := C.cl_uint(0)
	if devices != nil && len(devices) > 0 {
		deviceList = buildDeviceIdList(devices)
		deviceListPtr = &deviceList[0]
	}
	if err := C.clBuildProgram(p.clProgram, numDevices, deviceListPtr, cOptions, nil, nil); err != C.CL_SUCCESS {
		buffer := make([]byte, 4096)
		var bLen C.size_t
		var err C.cl_int
		for i := 2; i >= 0; i-- {
			err = C.clGetProgramBuildInfo(p.clProgram, p.devices[0].id, C.CL_PROGRAM_BUILD_LOG, C.size_t(len(buffer)), unsafe.Pointer(&buffer[0]), &bLen)
			if err == C.CL_INVALID_VALUE && i > 0 && bLen < 1024*1024 {
				// INVALID_VALUE probably means our buffer isn't large enough
				buffer = make([]byte, bLen)
			} else {
				break
			}
		}
		if err != C.CL_SUCCESS {
			return toError(err)
		}
		return BuildError(string(buffer[:bLen]))
	}
	return nil
}
コード例 #4
0
ファイル: program.go プロジェクト: xfong/tmpCL
func (p *Program) CompileProgramWithCallback(devices []*Device, options string, program_headers []*ProgramHeaders, user_data unsafe.Pointer) error {
	var cOptions *C.char
	if options != "" {
		cOptions = C.CString(options)
		defer C.free(unsafe.Pointer(cOptions))
	}
	var deviceList []C.cl_device_id
	var deviceListPtr *C.cl_device_id
	numDevices := C.cl_uint(len(devices))
	if devices != nil && len(devices) > 0 {
		deviceList = buildDeviceIdList(devices)
		deviceListPtr = &deviceList[0]
	}
	num_headers := len(program_headers)
	cHeaders := make([]C.cl_program, num_headers)
	cHeader_names := make([]*C.char, num_headers)
	for idx, ph := range program_headers {
		chs := ph.codes
		chn := C.CString(ph.names)
		cHeaders[idx] = chs.clProgram
		cHeader_names[idx] = chn
		defer C.free(chs)
		defer C.free(chn)
	}
	err := C.CLCompileProgram(p.clProgram, numDevices, deviceListPtr, cOptions, C.cl_uint(num_headers), &cHeaders[0], &cHeader_names[0], user_data)
	if err != C.CL_SUCCESS {
		buffer := make([]byte, 4096)
		var bLen C.size_t
		var err C.cl_int

		for _, dev := range p.devices {
			for i := 2; i >= 0; i-- {
				err = C.clGetProgramBuildInfo(p.clProgram, dev.id, C.CL_PROGRAM_BUILD_LOG, C.size_t(len(buffer)), unsafe.Pointer(&buffer[0]), &bLen)
				if err == C.CL_INVALID_VALUE && i > 0 && bLen < 1024*1024 {
					// INVALID_VALUE probably means our buffer isn't large enough
					buffer = make([]byte, bLen)
				} else {
					break
				}
			}
			if err != C.CL_SUCCESS {
				return toError(err)
			}

			if bLen > 1 {
				return BuildError{
					Device:  dev,
					Message: string(buffer[:bLen-1]),
				}
			}
		}

		return BuildError{
			Device:  nil,
			Message: "build failed and produced no log entries",
		}
	}
	return nil
}
コード例 #5
0
ファイル: program.go プロジェクト: snipsnipsnip/go-opencl
func (p *Program) BuildStatus(dev Device) BuildStatus {
	var c_status C.cl_build_status
	var count C.size_t
	if ret := C.clGetProgramBuildInfo(p.id, dev.id, C.CL_PROGRAM_BUILD_STATUS, C.size_t(unsafe.Sizeof(c_status)), unsafe.Pointer(&c_status), &count); ret != C.CL_SUCCESS {
		return BUILD_ERROR
	}
	return BuildStatus(c_status)

}
コード例 #6
0
ファイル: program.go プロジェクト: xfong/tmpCL
func (ctx *Context) LinkProgramWithCallback(programs []*Program, devices []*Device, options string, user_data unsafe.Pointer) (*Program, error) {
	var cOptions *C.char
	if options != "" {
		cOptions = C.CString(options)
		defer C.free(unsafe.Pointer(cOptions))
	}
	var deviceList []C.cl_device_id
	var deviceListPtr *C.cl_device_id
	numDevices := C.cl_uint(len(devices))
	if devices != nil && len(devices) > 0 {
		deviceList = buildDeviceIdList(devices)
		deviceListPtr = &deviceList[0]
	}
	programList := make([]C.cl_program, len(programs))
	for idx, progId := range programs {
		programList[idx] = progId.clProgram
	}
	var err C.cl_int
	programExe := C.CLLinkProgram(ctx.clContext, numDevices, deviceListPtr, cOptions, C.cl_uint(len(programs)), &programList[0], user_data, &err)
	p := &Program{clProgram: programExe, devices: devices}
	if err != C.CL_SUCCESS {
		buffer := make([]byte, 4096)
		var bLen C.size_t
		var err C.cl_int

		for _, dev := range p.devices {
			for i := 2; i >= 0; i-- {
				err = C.clGetProgramBuildInfo(p.clProgram, dev.id, C.CL_PROGRAM_BUILD_LOG, C.size_t(len(buffer)), unsafe.Pointer(&buffer[0]), &bLen)
				if err == C.CL_INVALID_VALUE && i > 0 && bLen < 1024*1024 {
					// INVALID_VALUE probably means our buffer isn't large enough
					buffer = make([]byte, bLen)
				} else {
					break
				}
			}
			if err != C.CL_SUCCESS {
				return nil, toError(err)
			}

			if bLen > 1 {
				return nil, BuildError{
					Device:  dev,
					Message: string(buffer[:bLen-1]),
				}
			}
		}

		return nil, BuildError{
			Device:  nil,
			Message: "build failed and produced no log entries",
		}
	}
	return p, nil
}
コード例 #7
0
ファイル: program.go プロジェクト: xfong/tmpCL
func (p *Program) GetBuildLog(device *Device) (string, error) {
	var strC [1024]C.char
	var strN C.size_t
	if err := C.clGetProgramBuildInfo(p.clProgram, device.id, C.CL_PROGRAM_BUILD_LOG, 1024, unsafe.Pointer(&strC), &strN); err != C.CL_SUCCESS {
		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
}
コード例 #8
0
ファイル: program.go プロジェクト: xfong/tmpCL
func (p *Program) BuildProgram(devices []*Device, options string) error {
	var optBuffer bytes.Buffer
	optBuffer.WriteString("-cl-std=CL1.2 -cl-kernel-arg-info ")
	var cOptions *C.char
	if options != "" {
		optBuffer.WriteString(options)
	}
	cOptions = C.CString(optBuffer.String())
	defer C.free(unsafe.Pointer(cOptions))

	var deviceList []C.cl_device_id
	var deviceListPtr *C.cl_device_id
	numDevices := C.cl_uint(len(devices))
	if devices != nil && len(devices) > 0 {
		deviceList = buildDeviceIdList(devices)
		deviceListPtr = &deviceList[0]
	}
	if err := C.clBuildProgram(p.clProgram, numDevices, deviceListPtr, cOptions, nil, nil); err != C.CL_SUCCESS {
		buffer := make([]byte, 4096)
		var bLen C.size_t
		var err C.cl_int

		for _, dev := range p.devices {
			for i := 2; i >= 0; i-- {
				err = C.clGetProgramBuildInfo(p.clProgram, dev.id, C.CL_PROGRAM_BUILD_LOG, C.size_t(len(buffer)), unsafe.Pointer(&buffer[0]), &bLen)
				if err == C.CL_INVALID_VALUE && i > 0 && bLen < 1024*1024 {
					// INVALID_VALUE probably means our buffer isn't large enough
					buffer = make([]byte, bLen)
				} else {
					break
				}
			}
			if err != C.CL_SUCCESS {
				return toError(err)
			}

			if bLen > 1 {
				return BuildError{
					Device:  dev,
					Message: string(buffer[:bLen-1]),
				}
			}
		}

		return BuildError{
			Device:  nil,
			Message: "build failed and produced no log entries",
		}
	}
	return nil
}
コード例 #9
0
ファイル: package.go プロジェクト: mantyr/cl
// see https://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clGetProgramBuildInfo.html
func GetProgramBuildInfo(prog Program, device DeviceId, paramName ProgramBuildInfo, paramValueSize uint64, paramValue unsafe.Pointer, paramValueSizeRet *uint64) ErrorCode {
	return ErrorCode(C.clGetProgramBuildInfo(prog, device, C.cl_program_build_info(paramName), C.size_t(paramValueSize), paramValue, (*C.size_t)(paramValueSizeRet)))
}
コード例 #10
0
ファイル: program.go プロジェクト: Dirbaio/gominer
func CLGetProgramBuildInfo(program CL_program,
	device CL_device_id,
	param_name CL_program_build_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.clGetProgramBuildInfo(program.cl_program,
				device.cl_device_id,
				C.cl_program_build_info(param_name),
				C.size_t(param_value_size),
				nil,
				&c_param_value_size_ret)
		} else {
			switch param_name {
			case CL_PROGRAM_BUILD_STATUS:
				var value C.cl_build_status

				c_errcode_ret = C.clGetProgramBuildInfo(program.cl_program,
					device.cl_device_id,
					C.cl_program_build_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_build_status(value)

			case CL_PROGRAM_BUILD_OPTIONS,
				CL_PROGRAM_BUILD_LOG:

				value := make([]C.char, param_value_size)
				c_errcode_ret = C.clGetProgramBuildInfo(program.cl_program,
					device.cl_device_id,
					C.cl_program_build_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_PROGRAM_BINARY_TYPE:
				var value C.cl_program_binary_type

				c_errcode_ret = C.clGetProgramBuildInfo(program.cl_program,
					device.cl_device_id,
					C.cl_program_build_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_program_binary_type(value)

			case CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE:
				var value C.size_t

				c_errcode_ret = C.clGetProgramBuildInfo(program.cl_program,
					device.cl_device_id,
					C.cl_program_build_info(param_name),
					C.size_t(param_value_size),
					unsafe.Pointer(&value),
					&c_param_value_size_ret)

				*param_value = CL_size_t(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)
	}
}
コード例 #11
0
ファイル: program.go プロジェクト: xfong/tmpCL
func (p *Program) GetProgramBinaryType(device *Device) (ProgramBinaryTypes, error) {
	var binType C.cl_program_binary_type
	err := C.clGetProgramBuildInfo(p.clProgram, device.id, C.CL_PROGRAM_BINARY_TYPE, C.size_t(unsafe.Sizeof(binType)), unsafe.Pointer(&binType), nil)
	return ProgramBinaryTypes(binType), toError(err)
}
コード例 #12
0
ファイル: program.go プロジェクト: xfong/tmpCL
func (p *Program) GetBuildStatus(device *Device) (BuildStatus, error) {
	var buildStatus C.cl_build_status
	err := C.clGetProgramBuildInfo(p.clProgram, device.id, C.CL_PROGRAM_BUILD_STATUS, C.size_t(unsafe.Sizeof(buildStatus)), unsafe.Pointer(&buildStatus), nil)
	return BuildStatus(buildStatus), toError(err)
}