Last active
February 26, 2018 11:12
-
-
Save AmatsuZero/d8010a0d2748fb640e37204fd4342960 to your computer and use it in GitHub Desktop.
Study OpenCL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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