Petr Schreiber
25-09-2012, 17:22
The third strange new word from OpenCL world is "context". We already learned there can be 1 or more OpenCL platforms (http://www.thinbasic.com/community/showthread.php?11863-Chapter-2-example-1-Testing-platform-extensions)on your PC, each containing 1 or more hardware devices (http://www.thinbasic.com/community/showthread.php?11869-Chapter-2-example-2-Testing-device-extensions&p=87208#post87208).
When we prepare calculation using OpenCL, we can select which devices will be used for it.
It is like picking fruit in shop to basket. You could buy all the fruit in theory, but sometimes apples and oranges are just fine for a little snack (this is the deepest thought of day :p).
The basket is called context.
The bad news is that one context can contain devices from single platform.
So if you have PC with 4 NVIDIA GPUs, and 4 Intel CPUs, you can:
Create context containing 1-4 Nvidia GPUs
Create context containing 1-4 Intel CPUs
But you cannot:
Create context containing 1-4 Nvidia GPUs and 1-4 Intel CPUs
This is most probably due to major architectural differences between the platforms.
The example below picks first platform, first device, and examines reference count.
Wait what? Another new word?
In a way ... yes. Context reference count says, on how many places in your computation do you use the context.
This is typical for case, when you have main code, and some 3rd party library, which relies on the same context as well.
To keep track of how many computations share the reference to given context, you can manually increase/decrease the reference count using clRetainContext/clReleaseContext.
So what I learn?
How to check reference count of OpenCL context.
So what I need to run it?
You will need the latest ThinBASIC and OpenCL headers (http://www.thinbasic.com/community/showthread.php?10159-OpenCL-Headers-Updated-Sep-15-2011) to run it + of course modern GPU or CPU (http://www.thinbasic.com/community/showthread.php?10161-OpenCL-Supported-hardware).
Code listing (full code in attachement!)
Uses "Console"
#INCLUDE "%APP_INCLUDEPATH%/cl/cl.tBasicU"
Function TBMain()
/* Host/device data structures */
tcl_platform_id platform
tcl_device_id device
tcl_context context
tcl_int ErrCl
tcl_uint ref_count
/* Access the first installed platform */
ErrCl = clGetPlatformIDs(1, platform, Byval Null)
if (ErrCl < 0) Then
pError("Couldn't find any platforms")
APP_SetReturnCode(1) : WaitKey : Exit Function
End If
/* Access the first available device */
ErrCl = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, device, ByVal NULL)
If (ErrCl = CL_DEVICE_NOT_FOUND) Then
ErrCl = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, device, ByVal NULL)
End If
if (ErrCl < 0) Then
pError("Couldn't find any devices")
APP_SetReturnCode(1) : WaitKey : Exit Function
End If
/* Create the context */
context = clCreateContext(ByVal NULL, 1, device, ByVal NULL, ByVal NULL, ErrCl)
if (ErrCl < 0) Then
pError("Couldn't create a context")
APP_SetReturnCode(1) : WaitKey : Exit Function
End If
/* Determine the reference count */
ErrCl = clGetContextInfo(context, CL_CONTEXT_REFERENCE_COUNT,
SizeOf(ref_count), VarPtr(ref_count), ByVal NULL)
If (ErrCl < 0) Then
pError("Couldn't read the reference count.")
APP_SetReturnCode(1) : WaitKey : Exit Function
End If
PrintL StrFormat$("Initial reference count: {1}", ref_count)
/* Update and display the reference count */
clRetainContext(context)
clGetContextInfo(context, CL_CONTEXT_REFERENCE_COUNT,
SizeOf(ref_count), VarPtr(ref_count), ByVal NULL)
PrintL StrFormat$("Reference count: {1}", ref_count)
clReleaseContext(context)
clGetContextInfo(context, CL_CONTEXT_REFERENCE_COUNT,
SizeOf(ref_count), VarPtr(ref_count), ByVal NULL)
PrintL StrFormat$("Reference count: {1}", ref_count)
clReleaseContext(context)
PrintL "Press any key to continue..."
WaitKey
APP_SetReturnCode(0)
End Function
Function pError( sError As String )
Console_SetTextAttribute(%CONSOLE_FOREGROUND_RED | %CONSOLE_FOREGROUND_INTENSITY)
PrintL sError
Console_SetTextAttribute(%CONSOLE_FOREGROUND_RED | %CONSOLE_FOREGROUND_GREEN | %CONSOLE_FOREGROUND_BLUE)
End Function
Petr
When we prepare calculation using OpenCL, we can select which devices will be used for it.
It is like picking fruit in shop to basket. You could buy all the fruit in theory, but sometimes apples and oranges are just fine for a little snack (this is the deepest thought of day :p).
The basket is called context.
The bad news is that one context can contain devices from single platform.
So if you have PC with 4 NVIDIA GPUs, and 4 Intel CPUs, you can:
Create context containing 1-4 Nvidia GPUs
Create context containing 1-4 Intel CPUs
But you cannot:
Create context containing 1-4 Nvidia GPUs and 1-4 Intel CPUs
This is most probably due to major architectural differences between the platforms.
The example below picks first platform, first device, and examines reference count.
Wait what? Another new word?
In a way ... yes. Context reference count says, on how many places in your computation do you use the context.
This is typical for case, when you have main code, and some 3rd party library, which relies on the same context as well.
To keep track of how many computations share the reference to given context, you can manually increase/decrease the reference count using clRetainContext/clReleaseContext.
So what I learn?
How to check reference count of OpenCL context.
So what I need to run it?
You will need the latest ThinBASIC and OpenCL headers (http://www.thinbasic.com/community/showthread.php?10159-OpenCL-Headers-Updated-Sep-15-2011) to run it + of course modern GPU or CPU (http://www.thinbasic.com/community/showthread.php?10161-OpenCL-Supported-hardware).
Code listing (full code in attachement!)
Uses "Console"
#INCLUDE "%APP_INCLUDEPATH%/cl/cl.tBasicU"
Function TBMain()
/* Host/device data structures */
tcl_platform_id platform
tcl_device_id device
tcl_context context
tcl_int ErrCl
tcl_uint ref_count
/* Access the first installed platform */
ErrCl = clGetPlatformIDs(1, platform, Byval Null)
if (ErrCl < 0) Then
pError("Couldn't find any platforms")
APP_SetReturnCode(1) : WaitKey : Exit Function
End If
/* Access the first available device */
ErrCl = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, device, ByVal NULL)
If (ErrCl = CL_DEVICE_NOT_FOUND) Then
ErrCl = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, device, ByVal NULL)
End If
if (ErrCl < 0) Then
pError("Couldn't find any devices")
APP_SetReturnCode(1) : WaitKey : Exit Function
End If
/* Create the context */
context = clCreateContext(ByVal NULL, 1, device, ByVal NULL, ByVal NULL, ErrCl)
if (ErrCl < 0) Then
pError("Couldn't create a context")
APP_SetReturnCode(1) : WaitKey : Exit Function
End If
/* Determine the reference count */
ErrCl = clGetContextInfo(context, CL_CONTEXT_REFERENCE_COUNT,
SizeOf(ref_count), VarPtr(ref_count), ByVal NULL)
If (ErrCl < 0) Then
pError("Couldn't read the reference count.")
APP_SetReturnCode(1) : WaitKey : Exit Function
End If
PrintL StrFormat$("Initial reference count: {1}", ref_count)
/* Update and display the reference count */
clRetainContext(context)
clGetContextInfo(context, CL_CONTEXT_REFERENCE_COUNT,
SizeOf(ref_count), VarPtr(ref_count), ByVal NULL)
PrintL StrFormat$("Reference count: {1}", ref_count)
clReleaseContext(context)
clGetContextInfo(context, CL_CONTEXT_REFERENCE_COUNT,
SizeOf(ref_count), VarPtr(ref_count), ByVal NULL)
PrintL StrFormat$("Reference count: {1}", ref_count)
clReleaseContext(context)
PrintL "Press any key to continue..."
WaitKey
APP_SetReturnCode(0)
End Function
Function pError( sError As String )
Console_SetTextAttribute(%CONSOLE_FOREGROUND_RED | %CONSOLE_FOREGROUND_INTENSITY)
PrintL sError
Console_SetTextAttribute(%CONSOLE_FOREGROUND_RED | %CONSOLE_FOREGROUND_GREEN | %CONSOLE_FOREGROUND_BLUE)
End Function
Petr