Skip to content

Instantly share code, notes, and snippets.

@AmatsuZero
Last active February 26, 2018 11:12
Show Gist options
  • Save AmatsuZero/d8010a0d2748fb640e37204fd4342960 to your computer and use it in GitHub Desktop.
Save AmatsuZero/d8010a0d2748fb640e37204fd4342960 to your computer and use it in GitHub Desktop.
Study OpenCL
import Foundation
import OpenCL
func contextCount() throws {
var platform: cl_platform_id?
guard clGetPlatformIDs(1, &platform, nil) >= 0 else {
fatalError("找不到任何平台")
}
var devices = [cl_device_id?]()
if clGetDeviceIDs(platform,
cl_device_type(CL_DEVICE_TYPE_GPU),
1,
&devices,
nil) == CL_DEVICE_NOT_FOUND {
guard clGetDeviceIDs(platform,
cl_device_type(CL_DEVICE_TYPE_CPU),
1,
&devices,
nil) >= 0 else {
fatalError("未能找到任何设备")
}
}
var err: cl_int = 0
let context = clCreateContext(nil, 1, &devices, nil, nil, &err)
defer {
clReleaseContext(context)
}
guard err >= 0 else {
fatalError("未能创建上下文")
}
var refCount: cl_uint = 0
guard clGetContextInfo(context,
cl_context_info(CL_CONTEXT_REFERENCE_COUNT),
MemoryLayout.size(ofValue: refCount),
&refCount,
nil) >= 0 else {
fatalError("未能读取引用计数")
}
print("初始引用计数为:\(refCount)")
clRetainContext(context)
clGetContextInfo(context,
cl_context_info(CL_CONTEXT_REFERENCE_COUNT),
MemoryLayout.size(ofValue: refCount),
&refCount,
nil)
print("当前引用计数为:\(refCount)")
clReleaseContext(context)
clGetContextInfo(context,
cl_context_info(CL_CONTEXT_REFERENCE_COUNT),
MemoryLayout.size(ofValue: refCount),
&refCount,
nil)
print("当前引用计数为:\(refCount)")
}
import Foundation
import OpenCL
func deviceInfo() throws -> [String: Any] {
var platform: cl_platform_id?
guard clGetPlatformIDs(1, &platform, nil) >= 0 else {
fatalError("没有找到任何平台")
}
var num_devices: cl_uint = 0
guard clGetDeviceIDs(platform,
cl_device_type(CL_DEVICE_TYPE_ALL), 1,
nil,
&num_devices) >= 0 else {
fatalError("没有找到任何设备")
}
var devices: [cl_device_id?] = Array(repeating: nil, count: Int(num_devices))
clGetDeviceIDs(platform,
cl_device_type(CL_DEVICE_TYPE_ALL),
num_devices,
&devices,
nil)
let namePtr = UnsafeMutablePointer<cl_char>.allocate(capacity: 48)
let extDataPtr = UnsafeMutablePointer<cl_char>.allocate(capacity: 4096)
var addrDataPtr: cl_uint = 0
defer {
namePtr.deallocate()
extDataPtr.deallocate()
}
devices.forEach { device in
guard clGetDeviceInfo(device,
cl_device_info(CL_DEVICE_NAME),
MemoryLayout<cl_char>.stride*48,
namePtr,
nil) >= 0 else {
fatalError("无法读取扩展数据")
}
let size = MemoryLayout<Int>.stride*4096
clGetDeviceInfo(device,
cl_device_info(CL_DEVICE_ADDRESS_BITS),
size,
addrDataPtr,
nil)
clGetDeviceInfo(device,
cl_device_info(CL_DEVICE_EXTENSIONS),
size,
extDataPtr,
nil)
clReleaseDevice(device)
}
let name = String(cString: namePtr)
let ext_data = String(cString: extDataPtr).components(separatedBy: " ").filter { !$0.isEmpty }
return [
"name": name,
"addressWidth": addrDataPtr,
"extensions": ext_data
]
}
import Foundation
import OpenCL
func programBuild() throws {
var platform: cl_platform_id?
guard clGetPlatformIDs(1, &platform, nil) >= 0 else {
fatalError("未能找到任何平台")
}
var err: cl_int = 0
var devices:[cl_device_id?] = Array(repeating: nil, count: 1)
err = clGetDeviceIDs(platform,
cl_device_type(CL_DEVICE_TYPE_GPU),
1,
&devices,
nil)
if err == CL_DEVICE_NOT_FOUND {
err = clGetDeviceIDs(platform,
cl_device_type(CL_DEVICE_TYPE_CPU),
1,
&devices,
nil)
}
guard err >= 0 else {
fatalError("未能找到任何设备")
}
let context = clCreateContext(nil, 1, &devices, nil, nil, &err)
defer {
clReleaseContext(context)
}
guard err >= 0 else {
fatalError("未能创建上下文")
}
// 这里如果直接扔进去cl文件,Xcode会因为函数名相同而无法通过编译
var good = """
__kernel void good(__global float *a,
__global float *b,
__global float *c) {
*c = *a + *b;
}
"""
// 如果想要成功,改一个不同的函数名
var bad = """
__kernel void good(__global float *a,
__global float *b,
__global float *c) {
*c = *a + *b;
}
"""
var programBuffer = [good, bad]
.map { ($0 as NSString).utf8String }
var program_size = programBuffer.reduce(0) { (size, next) -> Int in
return size + MemoryLayout.size(ofValue: next)
}
let program = clCreateProgramWithSource(context,
cl_uint(programBuffer.count),
&programBuffer,
nil,
&err)
defer {
clReleaseProgram(program)
}
guard err >= 0 else {
fatalError("未能创建CL程序(progrram)")
}
let options = "-cl-finite-math-only -cl-no-signed-zeros"
err = clBuildProgram(program, 1, &devices, options, nil, nil)
if err < 0 {
var program_log = [cl_char]()
clGetProgramBuildInfo(program,
devices.first!,
cl_program_build_info(CL_PROGRAM_BUILD_LOG),
0,
&program_log,
nil)
print(String(cString: &program_log, encoding: .utf8) ?? "Empty")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment