P4 to Git Change 1398097 by lmoriche@lmoriche_opencl_dev2 on 2017/04/13 13:01:56
SWDEV-102733 - [OCL-LC-ROCm] Cmake build Write CMakeLists.txt to enable building with and without the DK environment - Change the coding convention of the runtime files. Use Google's Style (https://google.github.io/styleguide/cppguide.html). Affected files ... ... //depot/stg/opencl/drivers/opencl/.clang-format#1 add ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_agent_amd.h#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_command.cpp#13 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_context.cpp#53 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_counter.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_d3d10.cpp#15 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_d3d11.cpp#22 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_d3d9.cpp#32 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_debugger_amd.cpp#8 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_debugger_amd.h#7 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_device.cpp#61 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_event.cpp#10 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_execute.cpp#23 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_gl.cpp#53 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_icd.cpp#27 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_icd_amd.h#18 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_kernel.h#24 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_kernel_info_amd.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_kernel_info_amd.h#4 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_lqdflash_amd.cpp#17 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_lqdflash_amd.h#6 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_memobj.cpp#81 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_object.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_pipe.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_platform_amd.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_platform_amd.h#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_profile_amd.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_profile_amd.h#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_program.cpp#41 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_sampler.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_sdi_amd.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_sdi_amd.h#2 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_semaphore_amd.h#3 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_svm.cpp#20 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_thread_trace_amd.cpp#8 edit ... //depot/stg/opencl/drivers/opencl/api/opencl/amdocl/cl_thread_trace_amd.h#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/appprofile.cpp#17 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/appprofile.hpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/blit.cpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/blit.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/blitcl.cpp#11 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpubinary.cpp#11 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpubinary.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpubuiltins.cpp#13 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpubuiltins.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpucommand.cpp#66 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpucommand.hpp#40 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpudevice.cpp#280 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpudevice.hpp#96 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpufeat.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpukernel.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpumapping.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpumapping.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuprogram.cpp#70 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuprogram.hpp#14 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpusettings.cpp#33 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpusettings.hpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cputables.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuvirtual.cpp#26 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/cpu/cpuvirtual.hpp#13 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/device.cpp#209 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/device.hpp#284 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuappprofile.cpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuappprofile.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpubinary.cpp#58 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpubinary.hpp#27 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpublit.cpp#126 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpublit.hpp#41 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpucompiler.cpp#156 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuconstbuf.cpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuconstbuf.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpucounters.cpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpucounters.hpp#9 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudebugger.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudebugmanager.cpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudebugmanager.hpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudefs.hpp#147 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudevice.cpp#567 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpudevice.hpp#163 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpukernel.cpp#318 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpukernel.hpp#126 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpumemory.cpp#131 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpumemory.hpp#50 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprintf.cpp#44 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprintf.hpp#15 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.cpp#232 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuprogram.hpp#69 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuresource.cpp#238 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuresource.hpp#87 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpusched.hpp#19 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuschedcl.cpp#35 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuscsi.cpp#37 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpusettings.cpp#350 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpusettings.hpp#98 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gputhreadtrace.cpp#9 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gputhreadtrace.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gputimestamp.cpp#27 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gputimestamp.hpp#16 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gputrap.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.cpp#410 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuvirtual.hpp#140 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuwavelimiter.cpp#13 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/gpu/gpuwavelimiter.hpp#9 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/hwdebug.cpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/hwdebug.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palappprofile.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palappprofile.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palbinary.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palbinary.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palblit.cpp#13 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palblit.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palcompiler.cpp#15 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palconstbuf.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palconstbuf.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palcounters.cpp#11 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palcounters.hpp#9 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldebugger.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldebugmanager.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldebugmanager.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldefs.hpp#16 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldevice.cpp#45 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldevice.hpp#16 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldeviced3d10.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldeviced3d11.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldeviced3d9.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paldevicegl.cpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palkernel.cpp#34 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palkernel.hpp#11 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palmemory.cpp#13 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palmemory.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprintf.cpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprintf.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.cpp#39 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palprogram.hpp#17 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palresource.cpp#28 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palresource.hpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palsched.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palschedcl.cpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palsettings.cpp#24 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palsettings.hpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palthreadtrace.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palthreadtrace.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paltimestamp.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paltimestamp.hpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/paltrap.hpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palvirtual.cpp#48 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palvirtual.hpp#21 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palwavelimiter.cpp#3 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/pal/palwavelimiter.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/mesa_glinterop.h#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocappprofile.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocappprofile.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocbinary.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocblit.cpp#17 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocblit.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompiler.cpp#32 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompilerlib.cpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/roccompilerlib.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdefs.hpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.cpp#48 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocdevice.hpp#20 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocglinterop.cpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocglinterop.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rockernel.cpp#22 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rockernel.hpp#16 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocmemory.cpp#15 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocmemory.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprintf.cpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprintf.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.cpp#64 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocprogram.hpp#23 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocregisters.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocsettings.cpp#17 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocsettings.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocvirtual.cpp#34 edit ... //depot/stg/opencl/drivers/opencl/runtime/device/rocm/rocvirtual.hpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/alloc.cpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/alloc.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/os.cpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/os.hpp#30 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/os_posix.cpp#42 edit ... //depot/stg/opencl/drivers/opencl/runtime/os/os_win32.cpp#47 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/agent.cpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/agent.hpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/command.cpp#78 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/command.hpp#83 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/commandqueue.cpp#23 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/commandqueue.hpp#18 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/context.cpp#42 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/context.hpp#26 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/counter.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/interop.hpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/kernel.cpp#23 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/kernel.hpp#18 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/memory.cpp#127 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/memory.hpp#100 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/ndrange.cpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/ndrange.hpp#9 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/object.cpp#2 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/object.hpp#17 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/perfctr.hpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/program.cpp#86 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/program.hpp#41 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/runtime.cpp#35 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/runtime.hpp#4 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/sampler.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/platform/threadtrace.hpp#6 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/atomic.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/monitor.cpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/monitor.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/semaphore.cpp#10 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/semaphore.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/thread.cpp#14 edit ... //depot/stg/opencl/drivers/opencl/runtime/thread/thread.hpp#15 edit ... //depot/stg/opencl/drivers/opencl/runtime/top.hpp#26 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/concurrent.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/debug.cpp#5 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/debug.hpp#7 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/flags.cpp#16 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/flags.hpp#271 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/macros.hpp#8 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/util.hpp#12 edit ... //depot/stg/opencl/drivers/opencl/runtime/utils/versions.hpp#2150 edit
This commit is contained in:
1 orang tua
a615e4fbb6
melakukan
465c1c0287
188 files changed
+68131
-78046
No files matched your search
@@ -15,516 +15,425 @@
|
||||
namespace amd {
|
||||
|
||||
|
||||
typedef cl_int (CL_CALLBACK * clAgent_OnLoad_fn)(cl_agent * agent);
|
||||
typedef void (CL_CALLBACK * clAgent_OnUnload_fn)(cl_agent * agent);
|
||||
typedef cl_int(CL_CALLBACK* clAgent_OnLoad_fn)(cl_agent* agent);
|
||||
typedef void(CL_CALLBACK* clAgent_OnUnload_fn)(cl_agent* agent);
|
||||
|
||||
Agent::Agent(const char* moduleName) :
|
||||
ready_(false)
|
||||
{
|
||||
::memset(&callbacks_, '\0', sizeof(callbacks_));
|
||||
::memset(&capabilities_, '\0', sizeof(capabilities_));
|
||||
Agent::Agent(const char* moduleName) : ready_(false) {
|
||||
::memset(&callbacks_, '\0', sizeof(callbacks_));
|
||||
::memset(&capabilities_, '\0', sizeof(capabilities_));
|
||||
|
||||
library_ = Os::loadLibrary(moduleName);
|
||||
if (library_ == NULL) {
|
||||
return;
|
||||
}
|
||||
library_ = Os::loadLibrary(moduleName);
|
||||
if (library_ == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
clAgent_OnLoad_fn onLoad = reinterpret_cast<clAgent_OnLoad_fn>(
|
||||
Os::getSymbol(library_, "clAgent_OnLoad"));
|
||||
if (onLoad == NULL) {
|
||||
return;
|
||||
}
|
||||
clAgent_OnLoad_fn onLoad =
|
||||
reinterpret_cast<clAgent_OnLoad_fn>(Os::getSymbol(library_, "clAgent_OnLoad"));
|
||||
if (onLoad == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
_cl_agent* agent = static_cast<_cl_agent*>(this);
|
||||
::memcpy(agent, &entryPoints_, sizeof(entryPoints_));
|
||||
_cl_agent* agent = static_cast<_cl_agent*>(this);
|
||||
::memcpy(agent, &entryPoints_, sizeof(entryPoints_));
|
||||
|
||||
// Register in the agents linked-list.
|
||||
next_ = list_;
|
||||
list_ = this;
|
||||
// Register in the agents linked-list.
|
||||
next_ = list_;
|
||||
list_ = this;
|
||||
|
||||
if (onLoad(agent) != CL_SUCCESS) {
|
||||
list_ = list_->next_;
|
||||
}
|
||||
if (onLoad(agent) != CL_SUCCESS) {
|
||||
list_ = list_->next_;
|
||||
}
|
||||
|
||||
// Mark this instance as ready for use.
|
||||
ready_ = true;
|
||||
// Mark this instance as ready for use.
|
||||
ready_ = true;
|
||||
}
|
||||
|
||||
Agent::~Agent()
|
||||
{
|
||||
if (library_ != NULL) {
|
||||
clAgent_OnUnload_fn onUnload = reinterpret_cast<clAgent_OnUnload_fn>(
|
||||
Os::getSymbol(library_, "clAgent_OnUnload"));
|
||||
Agent::~Agent() {
|
||||
if (library_ != NULL) {
|
||||
clAgent_OnUnload_fn onUnload =
|
||||
reinterpret_cast<clAgent_OnUnload_fn>(Os::getSymbol(library_, "clAgent_OnUnload"));
|
||||
|
||||
if (onUnload != NULL) {
|
||||
onUnload(static_cast<cl_agent*>(this));
|
||||
}
|
||||
|
||||
Os::unloadLibrary(library_);
|
||||
}
|
||||
}
|
||||
|
||||
cl_int
|
||||
Agent::setCallbacks(const cl_agent_callbacks *callbacks, size_t size)
|
||||
{
|
||||
// FIXME_lmoriche: check size
|
||||
memcpy(&callbacks_, callbacks, size);
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
cl_int
|
||||
Agent::getCapabilities(cl_agent_capabilities* caps)
|
||||
{
|
||||
if (caps == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
*caps = capabilities_;
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
static inline cl_agent_capabilities
|
||||
operator ~ (const cl_agent_capabilities& src)
|
||||
{
|
||||
cl_agent_capabilities result;
|
||||
|
||||
const char* a = reinterpret_cast<const char*>(&src);
|
||||
char *b = reinterpret_cast<char*>(&result);
|
||||
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
|
||||
*b++ = ~*a++;
|
||||
if (onUnload != NULL) {
|
||||
onUnload(static_cast<cl_agent*>(this));
|
||||
}
|
||||
|
||||
return result;
|
||||
Os::unloadLibrary(library_);
|
||||
}
|
||||
}
|
||||
|
||||
static inline cl_agent_capabilities
|
||||
operator | (const cl_agent_capabilities& lhs, const cl_agent_capabilities& rhs)
|
||||
{
|
||||
cl_agent_capabilities result;
|
||||
|
||||
const char* a = reinterpret_cast<const char*>(&lhs);
|
||||
const char* b = reinterpret_cast<const char*>(&rhs);
|
||||
char *c = reinterpret_cast<char*>(&result);
|
||||
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
|
||||
*c++ = *a++ | *b++;
|
||||
}
|
||||
|
||||
return result;
|
||||
cl_int Agent::setCallbacks(const cl_agent_callbacks* callbacks, size_t size) {
|
||||
// FIXME_lmoriche: check size
|
||||
memcpy(&callbacks_, callbacks, size);
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
static inline cl_agent_capabilities
|
||||
operator & (const cl_agent_capabilities& lhs, const cl_agent_capabilities& rhs)
|
||||
{
|
||||
cl_agent_capabilities result;
|
||||
|
||||
const char* a = reinterpret_cast<const char*>(&lhs);
|
||||
const char* b = reinterpret_cast<const char*>(&rhs);
|
||||
char *c = reinterpret_cast<char*>(&result);
|
||||
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
|
||||
*c++ = *a++ & *b++;
|
||||
}
|
||||
|
||||
return result;
|
||||
cl_int Agent::getCapabilities(cl_agent_capabilities* caps) {
|
||||
if (caps == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
*caps = capabilities_;
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
operator == (const cl_agent_capabilities& lhs, const cl_agent_capabilities& rhs)
|
||||
{
|
||||
const char* a = reinterpret_cast<const char*>(&lhs);
|
||||
const char* b = reinterpret_cast<const char*>(&rhs);
|
||||
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
|
||||
if (*a++ != *b++) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
static inline cl_agent_capabilities operator~(const cl_agent_capabilities& src) {
|
||||
cl_agent_capabilities result;
|
||||
|
||||
const char* a = reinterpret_cast<const char*>(&src);
|
||||
char* b = reinterpret_cast<char*>(&result);
|
||||
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
|
||||
*b++ = ~*a++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline cl_agent_capabilities operator|(const cl_agent_capabilities& lhs,
|
||||
const cl_agent_capabilities& rhs) {
|
||||
cl_agent_capabilities result;
|
||||
|
||||
const char* a = reinterpret_cast<const char*>(&lhs);
|
||||
const char* b = reinterpret_cast<const char*>(&rhs);
|
||||
char* c = reinterpret_cast<char*>(&result);
|
||||
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
|
||||
*c++ = *a++ | *b++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline cl_agent_capabilities operator&(const cl_agent_capabilities& lhs,
|
||||
const cl_agent_capabilities& rhs) {
|
||||
cl_agent_capabilities result;
|
||||
|
||||
const char* a = reinterpret_cast<const char*>(&lhs);
|
||||
const char* b = reinterpret_cast<const char*>(&rhs);
|
||||
char* c = reinterpret_cast<char*>(&result);
|
||||
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
|
||||
*c++ = *a++ & *b++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool operator==(const cl_agent_capabilities& lhs, const cl_agent_capabilities& rhs) {
|
||||
const char* a = reinterpret_cast<const char*>(&lhs);
|
||||
const char* b = reinterpret_cast<const char*>(&rhs);
|
||||
for (size_t i = 0; i < sizeof(cl_agent_capabilities); ++i) {
|
||||
if (*a++ != *b++) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool operator!=(const cl_agent_capabilities& lhs, const cl_agent_capabilities& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
cl_int Agent::setCapabilities(const cl_agent_capabilities* caps, bool install) {
|
||||
ScopedLock sl(capabilitiesLock_);
|
||||
|
||||
if (caps == NULL || *caps != (*caps & potentialCapabilities_)) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
if (install) {
|
||||
capabilities_ = capabilities_ | *caps;
|
||||
} else {
|
||||
capabilities_ = capabilities_ & ~*caps;
|
||||
}
|
||||
|
||||
memset(&enabledCapabilities_, '\0', sizeof(enabledCapabilities_));
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
enabledCapabilities_ = enabledCapabilities_ | agent->capabilities_;
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
bool Agent::init() {
|
||||
::memset(&potentialCapabilities_, '\0', sizeof(potentialCapabilities_));
|
||||
potentialCapabilities_.canGenerateContextEvents = 1;
|
||||
potentialCapabilities_.canGenerateCommandQueueEvents = 1;
|
||||
potentialCapabilities_.canGenerateEventEvents = 1;
|
||||
// potentialCapabilities_.canGenerateMemObjectEvents = 1;
|
||||
// potentialCapabilities_.canGenerateSamplerEvents = 1;
|
||||
// potentialCapabilities_.canGenerateProgramEvents = 1;
|
||||
// potentialCapabilities_.canGenerateKernelEvents = 1;
|
||||
|
||||
const char* envVar = ::getenv("CL_AGENT");
|
||||
if (envVar == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string token, modules = envVar;
|
||||
std::istringstream iss(modules);
|
||||
|
||||
while (getline(iss, token, ',')) {
|
||||
Agent* agent = new Agent(token.c_str());
|
||||
if (agent == NULL || !agent->isReady()) {
|
||||
delete agent;
|
||||
|
||||
// Only return an error if we failed the Agent allocation. Other
|
||||
// error (the agent is not ready) can be ignored.
|
||||
return agent != NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
operator != (const cl_agent_capabilities& lhs, const cl_agent_capabilities& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
cl_int
|
||||
Agent::setCapabilities(const cl_agent_capabilities* caps, bool install)
|
||||
{
|
||||
ScopedLock sl(capabilitiesLock_);
|
||||
|
||||
if (caps == NULL || *caps != (*caps & potentialCapabilities_)) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
if (install) {
|
||||
capabilities_ = capabilities_ | *caps;
|
||||
}
|
||||
else {
|
||||
capabilities_ = capabilities_ & ~*caps;
|
||||
}
|
||||
|
||||
memset(&enabledCapabilities_, '\0', sizeof(enabledCapabilities_));
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
enabledCapabilities_ = enabledCapabilities_ | agent->capabilities_;
|
||||
}
|
||||
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
bool
|
||||
Agent::init()
|
||||
{
|
||||
::memset(&potentialCapabilities_, '\0', sizeof(potentialCapabilities_));
|
||||
potentialCapabilities_.canGenerateContextEvents = 1;
|
||||
potentialCapabilities_.canGenerateCommandQueueEvents = 1;
|
||||
potentialCapabilities_.canGenerateEventEvents = 1;
|
||||
// potentialCapabilities_.canGenerateMemObjectEvents = 1;
|
||||
// potentialCapabilities_.canGenerateSamplerEvents = 1;
|
||||
// potentialCapabilities_.canGenerateProgramEvents = 1;
|
||||
// potentialCapabilities_.canGenerateKernelEvents = 1;
|
||||
|
||||
const char* envVar = ::getenv("CL_AGENT");
|
||||
if (envVar == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string token, modules = envVar;
|
||||
std::istringstream iss(modules);
|
||||
|
||||
while (getline(iss, token, ',')) {
|
||||
Agent* agent = new Agent(token.c_str());
|
||||
if (agent == NULL || !agent->isReady()) {
|
||||
delete agent;
|
||||
|
||||
// Only return an error if we failed the Agent allocation. Other
|
||||
// error (the agent is not ready) can be ignored.
|
||||
return agent != NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
Agent::tearDown()
|
||||
{
|
||||
while (list_ != NULL) {
|
||||
Agent* agent = list_;
|
||||
list_ = list_->next_;
|
||||
delete agent;
|
||||
}
|
||||
void Agent::tearDown() {
|
||||
while (list_ != NULL) {
|
||||
Agent* agent = list_;
|
||||
list_ = list_->next_;
|
||||
delete agent;
|
||||
}
|
||||
}
|
||||
|
||||
namespace agent {
|
||||
|
||||
static cl_int CL_API_CALL
|
||||
GetVersionNumber(
|
||||
cl_agent* agent, cl_int* version_ret)
|
||||
{
|
||||
if (version_ret == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
static cl_int CL_API_CALL GetVersionNumber(cl_agent* agent, cl_int* version_ret) {
|
||||
if (version_ret == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
*version_ret = CL_AGENT_VERSION_1_0;
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL GetPlatform(cl_agent* agent, cl_platform_id* platform_id_ret) {
|
||||
if (platform_id_ret == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
*platform_id_ret = AMD_PLATFORM;
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL GetTime(cl_agent* agent, cl_long* time_nanos) {
|
||||
if (time_nanos == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
*time_nanos = Os::timeNanos() + Os::offsetToEpochNanos();
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL SetCallbacks(cl_agent* agent, const cl_agent_callbacks* callbacks,
|
||||
size_t size) {
|
||||
return Agent::get(agent)->setCallbacks(callbacks, size);
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL GetPotentialCapabilities(cl_agent* agent,
|
||||
cl_agent_capabilities* capabilities) {
|
||||
if (capabilities == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
*capabilities = Agent::potentialCapabilities();
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL GetCapabilities(cl_agent* agent, cl_agent_capabilities* capabilities) {
|
||||
return Agent::get(agent)->getCapabilities(capabilities);
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL SetCapabilities(cl_agent* agent,
|
||||
const cl_agent_capabilities* capabilities,
|
||||
cl_agent_capability_action action) {
|
||||
return Agent::get(agent)->setCapabilities(capabilities, action == CL_AGENT_ADD_CAPABILITIES);
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL GetICDDispatchTable(cl_agent* agent, cl_icd_dispatch_table* table,
|
||||
size_t size) {
|
||||
// FIXME_lmoriche: check size
|
||||
memcpy(table, amd::ICDDispatchedObject::icdVendorDispatch_, size);
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL SetICDDispatchTable(cl_agent* agent, const cl_icd_dispatch_table* table,
|
||||
size_t size) {
|
||||
// FIXME_lmoriche: check size
|
||||
memcpy(amd::ICDDispatchedObject::icdVendorDispatch_, table, size);
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace agent
|
||||
|
||||
cl_agent Agent::entryPoints_ = {agent::GetVersionNumber,
|
||||
agent::GetPlatform,
|
||||
agent::GetTime,
|
||||
agent::SetCallbacks,
|
||||
agent::GetPotentialCapabilities,
|
||||
agent::GetCapabilities,
|
||||
agent::SetCapabilities,
|
||||
agent::GetICDDispatchTable,
|
||||
agent::SetICDDispatchTable};
|
||||
|
||||
void Agent::postContextCreate(cl_context context) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acContextCreate_fn callback = agent->callbacks_.ContextCreate;
|
||||
if (callback != NULL && agent->canGenerateContextEvents()) {
|
||||
callback(agent, context);
|
||||
}
|
||||
*version_ret = CL_AGENT_VERSION_1_0;
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL
|
||||
GetPlatform(
|
||||
cl_agent* agent, cl_platform_id* platform_id_ret)
|
||||
{
|
||||
if (platform_id_ret == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
|
||||
void Agent::postContextFree(cl_context context) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acContextFree_fn callback = agent->callbacks_.ContextFree;
|
||||
if (callback != NULL && agent->canGenerateContextEvents()) {
|
||||
callback(agent, context);
|
||||
}
|
||||
*platform_id_ret = AMD_PLATFORM;
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL
|
||||
GetTime(
|
||||
cl_agent* agent, cl_long* time_nanos)
|
||||
{
|
||||
if (time_nanos == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
|
||||
void Agent::postCommandQueueCreate(cl_command_queue queue) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acCommandQueueCreate_fn callback = agent->callbacks_.CommandQueueCreate;
|
||||
if (callback != NULL && agent->canGenerateCommandQueueEvents()) {
|
||||
callback(agent, queue);
|
||||
}
|
||||
*time_nanos = Os::timeNanos() + Os::offsetToEpochNanos();
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL
|
||||
SetCallbacks(
|
||||
cl_agent* agent,
|
||||
const cl_agent_callbacks* callbacks,
|
||||
size_t size)
|
||||
{
|
||||
return Agent::get(agent)->setCallbacks(callbacks, size);
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL
|
||||
GetPotentialCapabilities(
|
||||
cl_agent* agent, cl_agent_capabilities* capabilities)
|
||||
{
|
||||
if (capabilities == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
void Agent::postCommandQueueFree(cl_command_queue queue) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acCommandQueueFree_fn callback = agent->callbacks_.CommandQueueFree;
|
||||
if (callback != NULL && agent->canGenerateCommandQueueEvents()) {
|
||||
callback(agent, queue);
|
||||
}
|
||||
|
||||
*capabilities = Agent::potentialCapabilities();
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL
|
||||
GetCapabilities(
|
||||
cl_agent* agent, cl_agent_capabilities* capabilities)
|
||||
{
|
||||
return Agent::get(agent)->getCapabilities(capabilities);
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL
|
||||
SetCapabilities(
|
||||
cl_agent* agent,
|
||||
const cl_agent_capabilities* capabilities,
|
||||
cl_agent_capability_action action)
|
||||
{
|
||||
return Agent::get(agent)->setCapabilities(
|
||||
capabilities, action == CL_AGENT_ADD_CAPABILITIES);
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL
|
||||
GetICDDispatchTable(
|
||||
cl_agent* agent, cl_icd_dispatch_table* table, size_t size)
|
||||
{
|
||||
// FIXME_lmoriche: check size
|
||||
memcpy(table, amd::ICDDispatchedObject::icdVendorDispatch_, size);
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
static cl_int CL_API_CALL
|
||||
SetICDDispatchTable(
|
||||
cl_agent* agent, const cl_icd_dispatch_table* table, size_t size)
|
||||
{
|
||||
// FIXME_lmoriche: check size
|
||||
memcpy(amd::ICDDispatchedObject::icdVendorDispatch_, table, size);
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace agent
|
||||
|
||||
cl_agent
|
||||
Agent::entryPoints_ = {
|
||||
agent::GetVersionNumber,
|
||||
agent::GetPlatform,
|
||||
agent::GetTime,
|
||||
agent::SetCallbacks,
|
||||
agent::GetPotentialCapabilities,
|
||||
agent::GetCapabilities,
|
||||
agent::SetCapabilities,
|
||||
agent::GetICDDispatchTable,
|
||||
agent::SetICDDispatchTable
|
||||
};
|
||||
|
||||
void
|
||||
Agent::postContextCreate(cl_context context)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acContextCreate_fn callback = agent->callbacks_.ContextCreate;
|
||||
if (callback != NULL && agent->canGenerateContextEvents()) {
|
||||
callback(agent, context);
|
||||
}
|
||||
void Agent::postEventCreate(cl_event event, cl_command_type type) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acEventCreate_fn callback = agent->callbacks_.EventCreate;
|
||||
if (callback != NULL && agent->canGenerateEventEvents()) {
|
||||
callback(agent, event, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postContextFree(cl_context context)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acContextFree_fn callback = agent->callbacks_.ContextFree;
|
||||
if (callback != NULL && agent->canGenerateContextEvents()) {
|
||||
callback(agent, context);
|
||||
}
|
||||
void Agent::postEventFree(cl_event event) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acEventFree_fn callback = agent->callbacks_.EventFree;
|
||||
if (callback != NULL && agent->canGenerateEventEvents()) {
|
||||
callback(agent, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postCommandQueueCreate(cl_command_queue queue)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acCommandQueueCreate_fn callback = agent->callbacks_.CommandQueueCreate;
|
||||
if (callback != NULL && agent->canGenerateCommandQueueEvents()) {
|
||||
callback(agent, queue);
|
||||
}
|
||||
void Agent::postEventStatusChanged(cl_event event, cl_int status, cl_long ts) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acEventStatusChanged_fn callback = agent->callbacks_.EventStatusChanged;
|
||||
if (callback != NULL && agent->canGenerateEventEvents()) {
|
||||
callback(agent, event, status, ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postCommandQueueFree(cl_command_queue queue)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acCommandQueueFree_fn callback = agent->callbacks_.CommandQueueFree;
|
||||
if (callback != NULL && agent->canGenerateCommandQueueEvents()) {
|
||||
callback(agent, queue);
|
||||
}
|
||||
void Agent::postMemObjectCreate(cl_mem memobj) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acMemObjectCreate_fn callback = agent->callbacks_.MemObjectCreate;
|
||||
if (callback != NULL && agent->canGenerateMemObjectEvents()) {
|
||||
callback(agent, memobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postEventCreate(cl_event event, cl_command_type type)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acEventCreate_fn callback = agent->callbacks_.EventCreate;
|
||||
if (callback != NULL && agent->canGenerateEventEvents()) {
|
||||
callback(agent, event, type);
|
||||
}
|
||||
void Agent::postMemObjectFree(cl_mem memobj) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acMemObjectFree_fn callback = agent->callbacks_.MemObjectFree;
|
||||
if (callback != NULL && agent->canGenerateMemObjectEvents()) {
|
||||
callback(agent, memobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postEventFree(cl_event event)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acEventFree_fn callback = agent->callbacks_.EventFree;
|
||||
if (callback != NULL && agent->canGenerateEventEvents()) {
|
||||
callback(agent, event);
|
||||
}
|
||||
void Agent::postMemObjectAcquired(cl_mem memobj, cl_device_id device, cl_long elapsed) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acMemObjectAcquired_fn callback = agent->callbacks_.MemObjectAcquired;
|
||||
if (callback != NULL && agent->canGenerateMemObjectEvents()) {
|
||||
callback(agent, memobj, device, elapsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postEventStatusChanged(cl_event event, cl_int status, cl_long ts)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acEventStatusChanged_fn callback = agent->callbacks_.EventStatusChanged;
|
||||
if (callback != NULL && agent->canGenerateEventEvents()) {
|
||||
callback(agent, event, status, ts);
|
||||
}
|
||||
void Agent::postSamplerCreate(cl_sampler sampler) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acSamplerCreate_fn callback = agent->callbacks_.SamplerCreate;
|
||||
if (callback != NULL && agent->canGenerateSamplerEvents()) {
|
||||
callback(agent, sampler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postMemObjectCreate(cl_mem memobj)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acMemObjectCreate_fn callback = agent->callbacks_.MemObjectCreate;
|
||||
if (callback != NULL && agent->canGenerateMemObjectEvents()) {
|
||||
callback(agent, memobj);
|
||||
}
|
||||
void Agent::postSamplerFree(cl_sampler sampler) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acSamplerFree_fn callback = agent->callbacks_.SamplerFree;
|
||||
if (callback != NULL && agent->canGenerateSamplerEvents()) {
|
||||
callback(agent, sampler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postMemObjectFree(cl_mem memobj)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acMemObjectFree_fn callback = agent->callbacks_.MemObjectFree;
|
||||
if (callback != NULL && agent->canGenerateMemObjectEvents()) {
|
||||
callback(agent, memobj);
|
||||
}
|
||||
void Agent::postProgramCreate(cl_program program) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acProgramCreate_fn callback = agent->callbacks_.ProgramCreate;
|
||||
if (callback != NULL && agent->canGenerateProgramEvents()) {
|
||||
callback(agent, program);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postMemObjectAcquired(
|
||||
cl_mem memobj, cl_device_id device, cl_long elapsed)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acMemObjectAcquired_fn callback = agent->callbacks_.MemObjectAcquired;
|
||||
if (callback != NULL && agent->canGenerateMemObjectEvents()) {
|
||||
callback(agent, memobj, device, elapsed);
|
||||
}
|
||||
void Agent::postProgramFree(cl_program program) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acProgramFree_fn callback = agent->callbacks_.ProgramFree;
|
||||
if (callback != NULL && agent->canGenerateProgramEvents()) {
|
||||
callback(agent, program);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postSamplerCreate(cl_sampler sampler)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acSamplerCreate_fn callback = agent->callbacks_.SamplerCreate;
|
||||
if (callback != NULL && agent->canGenerateSamplerEvents()) {
|
||||
callback(agent, sampler);
|
||||
}
|
||||
void Agent::postProgramBuild(cl_program program) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acProgramBuild_fn callback = agent->callbacks_.ProgramBuild;
|
||||
if (callback != NULL && agent->canGenerateProgramEvents()) {
|
||||
callback(agent, program);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postSamplerFree(cl_sampler sampler)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acSamplerFree_fn callback = agent->callbacks_.SamplerFree;
|
||||
if (callback != NULL && agent->canGenerateSamplerEvents()) {
|
||||
callback(agent, sampler);
|
||||
}
|
||||
void Agent::postKernelCreate(cl_kernel kernel) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acKernelCreate_fn callback = agent->callbacks_.KernelCreate;
|
||||
if (callback != NULL && agent->canGenerateKernelEvents()) {
|
||||
callback(agent, kernel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postProgramCreate(cl_program program)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acProgramCreate_fn callback = agent->callbacks_.ProgramCreate;
|
||||
if (callback != NULL && agent->canGenerateProgramEvents()) {
|
||||
callback(agent, program);
|
||||
}
|
||||
void Agent::postKernelFree(cl_kernel kernel) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acKernelFree_fn callback = agent->callbacks_.KernelFree;
|
||||
if (callback != NULL && agent->canGenerateKernelEvents()) {
|
||||
callback(agent, kernel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postProgramFree(cl_program program)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acProgramFree_fn callback = agent->callbacks_.ProgramFree;
|
||||
if (callback != NULL && agent->canGenerateProgramEvents()) {
|
||||
callback(agent, program);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postProgramBuild(cl_program program)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acProgramBuild_fn callback = agent->callbacks_.ProgramBuild;
|
||||
if (callback != NULL && agent->canGenerateProgramEvents()) {
|
||||
callback(agent, program);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postKernelCreate(cl_kernel kernel)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acKernelCreate_fn callback = agent->callbacks_.KernelCreate;
|
||||
if (callback != NULL && agent->canGenerateKernelEvents()) {
|
||||
callback(agent, kernel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postKernelFree(cl_kernel kernel)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acKernelFree_fn callback = agent->callbacks_.KernelFree;
|
||||
if (callback != NULL && agent->canGenerateKernelEvents()) {
|
||||
callback(agent, kernel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Agent::postKernelSetArg(
|
||||
cl_kernel kernel, cl_int index, size_t size, const void* value_ptr)
|
||||
{
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acKernelSetArg_fn callback = agent->callbacks_.KernelSetArg;
|
||||
if (callback != NULL && agent->canGenerateKernelEvents()) {
|
||||
callback(agent, kernel, index, size, value_ptr);
|
||||
}
|
||||
void Agent::postKernelSetArg(cl_kernel kernel, cl_int index, size_t size, const void* value_ptr) {
|
||||
for (Agent* agent = list_; agent != NULL; agent = agent->next_) {
|
||||
acKernelSetArg_fn callback = agent->callbacks_.KernelSetArg;
|
||||
if (callback != NULL && agent->canGenerateKernelEvents()) {
|
||||
callback(agent, kernel, index, size, value_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Agent* Agent::list_ = NULL;
|
||||
Monitor Agent::capabilitiesLock_;
|
||||
cl_agent_capabilities Agent::enabledCapabilities_ = { 0 };
|
||||
cl_agent_capabilities Agent::potentialCapabilities_ = { 0 };
|
||||
cl_agent_capabilities Agent::enabledCapabilities_ = {0};
|
||||
cl_agent_capabilities Agent::potentialCapabilities_ = {0};
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
@@ -12,139 +12,131 @@
|
||||
|
||||
namespace amd {
|
||||
|
||||
class Agent : public _cl_agent
|
||||
{
|
||||
private:
|
||||
//! Linked list of agent instances
|
||||
static Agent* list_;
|
||||
//! Agent API entry points
|
||||
static cl_agent entryPoints_;
|
||||
//! Capabilities supported by this Agent implementation
|
||||
static cl_agent_capabilities potentialCapabilities_;
|
||||
//! Union of all agent's enabled capabilities
|
||||
static cl_agent_capabilities enabledCapabilities_;
|
||||
//! Monitor to protect the global capabilities
|
||||
static Monitor capabilitiesLock_;
|
||||
class Agent : public _cl_agent {
|
||||
private:
|
||||
//! Linked list of agent instances
|
||||
static Agent* list_;
|
||||
//! Agent API entry points
|
||||
static cl_agent entryPoints_;
|
||||
//! Capabilities supported by this Agent implementation
|
||||
static cl_agent_capabilities potentialCapabilities_;
|
||||
//! Union of all agent's enabled capabilities
|
||||
static cl_agent_capabilities enabledCapabilities_;
|
||||
//! Monitor to protect the global capabilities
|
||||
static Monitor capabilitiesLock_;
|
||||
|
||||
public:
|
||||
//! Initialize the OpenCL agent
|
||||
static bool init();
|
||||
//! Teardown the agent.
|
||||
static void tearDown();
|
||||
//! Return the capabilities supported by this agent.
|
||||
static cl_agent_capabilities potentialCapabilities() {
|
||||
return potentialCapabilities_;
|
||||
}
|
||||
public:
|
||||
//! Initialize the OpenCL agent
|
||||
static bool init();
|
||||
//! Teardown the agent.
|
||||
static void tearDown();
|
||||
//! Return the capabilities supported by this agent.
|
||||
static cl_agent_capabilities potentialCapabilities() { return potentialCapabilities_; }
|
||||
|
||||
#define AGENT_FLAG(name) \
|
||||
inline static bool shouldPost##name() { \
|
||||
return enabledCapabilities_.canGenerate##name != 0; \
|
||||
}
|
||||
#define AGENT_FLAG(name) \
|
||||
inline static bool shouldPost##name() { return enabledCapabilities_.canGenerate##name != 0; }
|
||||
|
||||
AGENT_FLAG(ContextEvents);
|
||||
AGENT_FLAG(CommandQueueEvents);
|
||||
AGENT_FLAG(EventEvents);
|
||||
AGENT_FLAG(MemObjectEvents);
|
||||
AGENT_FLAG(SamplerEvents);
|
||||
AGENT_FLAG(ProgramEvents);
|
||||
AGENT_FLAG(KernelEvents);
|
||||
AGENT_FLAG(ContextEvents);
|
||||
AGENT_FLAG(CommandQueueEvents);
|
||||
AGENT_FLAG(EventEvents);
|
||||
AGENT_FLAG(MemObjectEvents);
|
||||
AGENT_FLAG(SamplerEvents);
|
||||
AGENT_FLAG(ProgramEvents);
|
||||
AGENT_FLAG(KernelEvents);
|
||||
|
||||
#undef AGENT_FLAG
|
||||
|
||||
//! Post a context creation event
|
||||
static void postContextCreate(cl_context context);
|
||||
//! Post a context destruction event
|
||||
static void postContextFree(cl_context context);
|
||||
//! Post a context creation event
|
||||
static void postContextCreate(cl_context context);
|
||||
//! Post a context destruction event
|
||||
static void postContextFree(cl_context context);
|
||||
|
||||
//! Post a command queue creation event
|
||||
static void postCommandQueueCreate(cl_command_queue queue);
|
||||
//! Post a command queue destruction event
|
||||
static void postCommandQueueFree(cl_command_queue queue);
|
||||
//! Post a command queue creation event
|
||||
static void postCommandQueueCreate(cl_command_queue queue);
|
||||
//! Post a command queue destruction event
|
||||
static void postCommandQueueFree(cl_command_queue queue);
|
||||
|
||||
//! Post an event creation event
|
||||
static void postEventCreate(cl_event event, cl_command_type type);
|
||||
//! Post an event destruction event
|
||||
static void postEventFree(cl_event event);
|
||||
//! Post and event status change event.
|
||||
static void postEventStatusChanged(
|
||||
cl_event event, cl_int execution_status, cl_long epoch_timestamp);
|
||||
//! Post an event creation event
|
||||
static void postEventCreate(cl_event event, cl_command_type type);
|
||||
//! Post an event destruction event
|
||||
static void postEventFree(cl_event event);
|
||||
//! Post and event status change event.
|
||||
static void postEventStatusChanged(cl_event event, cl_int execution_status,
|
||||
cl_long epoch_timestamp);
|
||||
|
||||
//! Post a memory object creation event
|
||||
static void postMemObjectCreate(cl_mem memobj);
|
||||
//! Post a memory object destruction event
|
||||
static void postMemObjectFree(cl_mem memobj);
|
||||
//! Post a memory transfer (acquired by device) event
|
||||
static void postMemObjectAcquired(
|
||||
cl_mem memobj, cl_device_id device, cl_long elapsed_time);
|
||||
//! Post a memory object creation event
|
||||
static void postMemObjectCreate(cl_mem memobj);
|
||||
//! Post a memory object destruction event
|
||||
static void postMemObjectFree(cl_mem memobj);
|
||||
//! Post a memory transfer (acquired by device) event
|
||||
static void postMemObjectAcquired(cl_mem memobj, cl_device_id device, cl_long elapsed_time);
|
||||
|
||||
//! Post a sampler creation event
|
||||
static void postSamplerCreate(cl_sampler sampler);
|
||||
//! Post a sampler destruction event
|
||||
static void postSamplerFree(cl_sampler sampler);
|
||||
//! Post a sampler creation event
|
||||
static void postSamplerCreate(cl_sampler sampler);
|
||||
//! Post a sampler destruction event
|
||||
static void postSamplerFree(cl_sampler sampler);
|
||||
|
||||
//! Post a program creation event
|
||||
static void postProgramCreate(cl_program program);
|
||||
//! Post a program destruction event
|
||||
static void postProgramFree(cl_program program);
|
||||
//! Post a program build event
|
||||
static void postProgramBuild(cl_program program);
|
||||
//! Post a program creation event
|
||||
static void postProgramCreate(cl_program program);
|
||||
//! Post a program destruction event
|
||||
static void postProgramFree(cl_program program);
|
||||
//! Post a program build event
|
||||
static void postProgramBuild(cl_program program);
|
||||
|
||||
//! Post a kernel creation event
|
||||
static void postKernelCreate(cl_kernel kernel);
|
||||
//! Post a kernel destruction event
|
||||
static void postKernelFree(cl_kernel kernel);
|
||||
//! Post a kernel set argument event
|
||||
static void postKernelSetArg(
|
||||
cl_kernel kernel, cl_int arg_index, size_t size, const void* value_ptr);
|
||||
//! Post a kernel creation event
|
||||
static void postKernelCreate(cl_kernel kernel);
|
||||
//! Post a kernel destruction event
|
||||
static void postKernelFree(cl_kernel kernel);
|
||||
//! Post a kernel set argument event
|
||||
static void postKernelSetArg(cl_kernel kernel, cl_int arg_index, size_t size,
|
||||
const void* value_ptr);
|
||||
|
||||
private:
|
||||
Agent* next_; //!< Next agent in the linked-list.
|
||||
void* library_; //!< Handle to the loaded module.
|
||||
bool ready_; //!< Is this instance ready?
|
||||
private:
|
||||
Agent* next_; //!< Next agent in the linked-list.
|
||||
void* library_; //!< Handle to the loaded module.
|
||||
bool ready_; //!< Is this instance ready?
|
||||
|
||||
//! Callbacks vector.
|
||||
cl_agent_callbacks callbacks_;
|
||||
//! Capabilities for this agent.
|
||||
cl_agent_capabilities capabilities_;
|
||||
//! Callbacks vector.
|
||||
cl_agent_callbacks callbacks_;
|
||||
//! Capabilities for this agent.
|
||||
cl_agent_capabilities capabilities_;
|
||||
|
||||
#define AGENT_FLAG(name) \
|
||||
inline bool canGenerate##name() { \
|
||||
return capabilities_.canGenerate##name != 0; \
|
||||
}
|
||||
#define AGENT_FLAG(name) \
|
||||
inline bool canGenerate##name() { return capabilities_.canGenerate##name != 0; }
|
||||
|
||||
AGENT_FLAG(ContextEvents);
|
||||
AGENT_FLAG(CommandQueueEvents);
|
||||
AGENT_FLAG(EventEvents);
|
||||
AGENT_FLAG(MemObjectEvents);
|
||||
AGENT_FLAG(SamplerEvents);
|
||||
AGENT_FLAG(ProgramEvents);
|
||||
AGENT_FLAG(KernelEvents);
|
||||
AGENT_FLAG(ContextEvents);
|
||||
AGENT_FLAG(CommandQueueEvents);
|
||||
AGENT_FLAG(EventEvents);
|
||||
AGENT_FLAG(MemObjectEvents);
|
||||
AGENT_FLAG(SamplerEvents);
|
||||
AGENT_FLAG(ProgramEvents);
|
||||
AGENT_FLAG(KernelEvents);
|
||||
|
||||
#undef AGENT_FLAG
|
||||
|
||||
public:
|
||||
//! Construct a new agent.
|
||||
Agent(const char* moduleName);
|
||||
//! Destroy the agent
|
||||
~Agent();
|
||||
public:
|
||||
//! Construct a new agent.
|
||||
Agent(const char* moduleName);
|
||||
//! Destroy the agent
|
||||
~Agent();
|
||||
|
||||
//! Return true if this instance is ready for use.
|
||||
bool isReady() const { return ready_; }
|
||||
//! Return true if this instance is ready for use.
|
||||
bool isReady() const { return ready_; }
|
||||
|
||||
//! Set the callback vector for this agent
|
||||
cl_int setCallbacks(const cl_agent_callbacks *callbacks, size_t size);
|
||||
//! Set the callback vector for this agent
|
||||
cl_int setCallbacks(const cl_agent_callbacks* callbacks, size_t size);
|
||||
|
||||
//! Return the current capabilities.
|
||||
cl_int getCapabilities(cl_agent_capabilities* caps);
|
||||
//! Set the current capabilities.
|
||||
cl_int setCapabilities(const cl_agent_capabilities* caps, bool install);
|
||||
//! Return the current capabilities.
|
||||
cl_int getCapabilities(cl_agent_capabilities* caps);
|
||||
//! Set the current capabilities.
|
||||
cl_int setCapabilities(const cl_agent_capabilities* caps, bool install);
|
||||
|
||||
//! Return the Agent instance from the given cl_agent
|
||||
inline static Agent* get(cl_agent* agent) {
|
||||
return const_cast<Agent*>(static_cast<const Agent*>(agent));
|
||||
}
|
||||
//! Return the Agent instance from the given cl_agent
|
||||
inline static Agent* get(cl_agent* agent) {
|
||||
return const_cast<Agent*>(static_cast<const Agent*>(agent));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
|
||||
#endif // AGENT_HPP_
|
||||
#endif // AGENT_HPP_
|
||||
File diff suppressed because it is too large.
Load diff
+893
-1141
File diff suppressed because it is too large.
Load diff
@@ -17,173 +17,157 @@
|
||||
|
||||
namespace amd {
|
||||
|
||||
HostQueue::HostQueue(
|
||||
Context& context, Device& device,
|
||||
cl_command_queue_properties properties, uint queueRTCUs, Priority priority
|
||||
)
|
||||
: CommandQueue(context, device, properties, device.info().queueProperties_
|
||||
| CL_QUEUE_COMMAND_INTERCEPT_ENABLE_AMD, queueRTCUs, priority)
|
||||
{
|
||||
if (thread_.state() >= Thread::INITIALIZED) {
|
||||
ScopedLock sl(queueLock_);
|
||||
thread_.start(this);
|
||||
queueLock_.wait();
|
||||
}
|
||||
HostQueue::HostQueue(Context& context, Device& device, cl_command_queue_properties properties,
|
||||
uint queueRTCUs, Priority priority)
|
||||
: CommandQueue(context, device, properties,
|
||||
device.info().queueProperties_ | CL_QUEUE_COMMAND_INTERCEPT_ENABLE_AMD,
|
||||
queueRTCUs, priority) {
|
||||
if (thread_.state() >= Thread::INITIALIZED) {
|
||||
ScopedLock sl(queueLock_);
|
||||
thread_.start(this);
|
||||
queueLock_.wait();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
HostQueue::terminate()
|
||||
{
|
||||
if (Os::isThreadAlive(thread_)) {
|
||||
// Make sure all the commands are finished on the device.
|
||||
finish();
|
||||
bool HostQueue::terminate() {
|
||||
if (Os::isThreadAlive(thread_)) {
|
||||
// Make sure all the commands are finished on the device.
|
||||
finish();
|
||||
|
||||
// Kill the command queue loop.
|
||||
thread_.acceptingCommands_ = false;
|
||||
// Kill the command queue loop.
|
||||
thread_.acceptingCommands_ = false;
|
||||
|
||||
// Wake-up the command loop, so it can exit
|
||||
flush();
|
||||
// Wake-up the command loop, so it can exit
|
||||
flush();
|
||||
|
||||
// FIXME_lmoriche: fix termination handshake
|
||||
while (thread_.state() < Thread::FINISHED) {
|
||||
Os::yield();
|
||||
}
|
||||
// FIXME_lmoriche: fix termination handshake
|
||||
while (thread_.state() < Thread::FINISHED) {
|
||||
Os::yield();
|
||||
}
|
||||
}
|
||||
|
||||
if (Agent::shouldPostCommandQueueEvents()) {
|
||||
Agent::postCommandQueueFree(as_cl(this->asCommandQueue()));
|
||||
}
|
||||
if (Agent::shouldPostCommandQueueEvents()) {
|
||||
Agent::postCommandQueueFree(as_cl(this->asCommandQueue()));
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
HostQueue::finish()
|
||||
{
|
||||
// Send a finish to make sure we finished all commands
|
||||
Command* command = new Marker(*this, false);
|
||||
void HostQueue::finish() {
|
||||
// Send a finish to make sure we finished all commands
|
||||
Command* command = new Marker(*this, false);
|
||||
if (command == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
command->enqueue();
|
||||
command->awaitCompletion();
|
||||
command->release();
|
||||
}
|
||||
|
||||
void HostQueue::loop(device::VirtualDevice* virtualDevice) {
|
||||
cl_int(CL_CALLBACK * commandIntercept)(cl_event, cl_int*) =
|
||||
properties().test(CL_QUEUE_COMMAND_INTERCEPT_ENABLE_AMD) ? context().info().commandIntercept_
|
||||
: NULL;
|
||||
|
||||
// Notify the caller that the queue is ready to accept commands.
|
||||
{
|
||||
ScopedLock sl(queueLock_);
|
||||
thread_.acceptingCommands_ = true;
|
||||
queueLock_.notify();
|
||||
}
|
||||
// Create a command batch with all the commands present in the queue.
|
||||
Command* head = NULL;
|
||||
Command* tail = NULL;
|
||||
while (true) {
|
||||
// Get one command from the queue
|
||||
Command* command = queue_.dequeue();
|
||||
if (command == NULL) {
|
||||
return;
|
||||
ScopedLock sl(queueLock_);
|
||||
while ((command = queue_.dequeue()) == NULL) {
|
||||
if (!thread_.acceptingCommands_) {
|
||||
return;
|
||||
}
|
||||
queueLock_.wait();
|
||||
}
|
||||
}
|
||||
|
||||
command->enqueue();
|
||||
command->awaitCompletion();
|
||||
command->release();
|
||||
}
|
||||
command->retain();
|
||||
|
||||
void
|
||||
HostQueue::loop(device::VirtualDevice* virtualDevice)
|
||||
{
|
||||
cl_int (CL_CALLBACK * commandIntercept)(cl_event, cl_int *) =
|
||||
properties().test(CL_QUEUE_COMMAND_INTERCEPT_ENABLE_AMD)
|
||||
? context().info().commandIntercept_ : NULL;
|
||||
// Process the command's event wait list.
|
||||
const Command::EventWaitList& events = command->eventWaitList();
|
||||
Command::EventWaitList::const_iterator it;
|
||||
bool dependencyFailed = false;
|
||||
|
||||
// Notify the caller that the queue is ready to accept commands.
|
||||
{
|
||||
ScopedLock sl(queueLock_);
|
||||
thread_.acceptingCommands_ = true;
|
||||
queueLock_.notify();
|
||||
}
|
||||
// Create a command batch with all the commands present in the queue.
|
||||
Command* head = NULL;
|
||||
Command* tail = NULL;
|
||||
while (true) {
|
||||
// Get one command from the queue
|
||||
Command* command = queue_.dequeue();
|
||||
if (command == NULL) {
|
||||
ScopedLock sl(queueLock_);
|
||||
while ((command = queue_.dequeue()) == NULL) {
|
||||
|
||||
if (!thread_.acceptingCommands_) {
|
||||
return;
|
||||
}
|
||||
queueLock_.wait();
|
||||
}
|
||||
}
|
||||
|
||||
command->retain();
|
||||
|
||||
// Process the command's event wait list.
|
||||
const Command::EventWaitList& events = command->eventWaitList();
|
||||
Command::EventWaitList::const_iterator it;
|
||||
bool dependencyFailed = false;
|
||||
|
||||
for (it = events.begin(); it != events.end(); ++it) {
|
||||
// Only wait if the command is enqueued into another queue.
|
||||
if ((*it)->command().queue() != this) {
|
||||
virtualDevice->flush(head, true);
|
||||
tail = head = NULL;
|
||||
dependencyFailed |= !(*it)->awaitCompletion();
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the command to the linked list.
|
||||
if (NULL == head) { //if the list is empty
|
||||
head = tail = command;
|
||||
}
|
||||
else {
|
||||
tail->setNext(command);
|
||||
tail = command;
|
||||
}
|
||||
|
||||
if (dependencyFailed) {
|
||||
command->setStatus(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
|
||||
continue;
|
||||
}
|
||||
|
||||
command->setStatus(CL_SUBMITTED);
|
||||
|
||||
cl_int result;
|
||||
if ((commandIntercept != NULL) &&
|
||||
commandIntercept(as_cl<Event>(command), &result)) {
|
||||
// The command was handled by the callback.
|
||||
command->setStatus(CL_RUNNING, command->profilingInfo().submitted_);
|
||||
command->setStatus(result);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Submit to the device queue.
|
||||
command->submit(*virtualDevice);
|
||||
|
||||
//if we are in intercept mode or this is a user invisible marker command
|
||||
if ((0 == command->type()) || (commandIntercept != NULL)) {
|
||||
virtualDevice->flush(head);
|
||||
tail = head = NULL;
|
||||
}
|
||||
} // while (true) {
|
||||
}
|
||||
|
||||
void
|
||||
HostQueue::append(Command& command)
|
||||
{
|
||||
// We retain the command here. It will be released when its status
|
||||
// changes to CL_COMPLETE
|
||||
command.retain();
|
||||
command.setStatus(CL_QUEUED);
|
||||
queue_.enqueue(&command);
|
||||
}
|
||||
|
||||
DeviceQueue::~DeviceQueue()
|
||||
{
|
||||
delete virtualDevice_;
|
||||
ScopedLock lock(context().lock());
|
||||
context().removeDeviceQueue(device(), this);
|
||||
}
|
||||
|
||||
bool
|
||||
DeviceQueue::create()
|
||||
{
|
||||
static const bool InteropQueue = true;
|
||||
const bool defaultDeviceQueue = properties().test(CL_QUEUE_ON_DEVICE_DEFAULT);
|
||||
bool result = false;
|
||||
|
||||
virtualDevice_ = device().createVirtualDevice(this);
|
||||
if (virtualDevice_ != NULL) {
|
||||
result = true;
|
||||
context().addDeviceQueue(device(), this, defaultDeviceQueue);
|
||||
for (it = events.begin(); it != events.end(); ++it) {
|
||||
// Only wait if the command is enqueued into another queue.
|
||||
if ((*it)->command().queue() != this) {
|
||||
virtualDevice->flush(head, true);
|
||||
tail = head = NULL;
|
||||
dependencyFailed |= !(*it)->awaitCompletion();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
// Insert the command to the linked list.
|
||||
if (NULL == head) { // if the list is empty
|
||||
head = tail = command;
|
||||
} else {
|
||||
tail->setNext(command);
|
||||
tail = command;
|
||||
}
|
||||
|
||||
if (dependencyFailed) {
|
||||
command->setStatus(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
|
||||
continue;
|
||||
}
|
||||
|
||||
command->setStatus(CL_SUBMITTED);
|
||||
|
||||
cl_int result;
|
||||
if ((commandIntercept != NULL) && commandIntercept(as_cl<Event>(command), &result)) {
|
||||
// The command was handled by the callback.
|
||||
command->setStatus(CL_RUNNING, command->profilingInfo().submitted_);
|
||||
command->setStatus(result);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Submit to the device queue.
|
||||
command->submit(*virtualDevice);
|
||||
|
||||
// if we are in intercept mode or this is a user invisible marker command
|
||||
if ((0 == command->type()) || (commandIntercept != NULL)) {
|
||||
virtualDevice->flush(head);
|
||||
tail = head = NULL;
|
||||
}
|
||||
} // while (true) {
|
||||
}
|
||||
|
||||
} //namespace amd {
|
||||
void HostQueue::append(Command& command) {
|
||||
// We retain the command here. It will be released when its status
|
||||
// changes to CL_COMPLETE
|
||||
command.retain();
|
||||
command.setStatus(CL_QUEUED);
|
||||
queue_.enqueue(&command);
|
||||
}
|
||||
|
||||
DeviceQueue::~DeviceQueue() {
|
||||
delete virtualDevice_;
|
||||
ScopedLock lock(context().lock());
|
||||
context().removeDeviceQueue(device(), this);
|
||||
}
|
||||
|
||||
bool DeviceQueue::create() {
|
||||
static const bool InteropQueue = true;
|
||||
const bool defaultDeviceQueue = properties().test(CL_QUEUE_ON_DEVICE_DEFAULT);
|
||||
bool result = false;
|
||||
|
||||
virtualDevice_ = device().createVirtualDevice(this);
|
||||
if (virtualDevice_ != NULL) {
|
||||
result = true;
|
||||
context().addDeviceQueue(device(), this, defaultDeviceQueue);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace amd {
|
||||
@@ -28,231 +28,215 @@ namespace amd {
|
||||
class HostQueue;
|
||||
class DeviceQueue;
|
||||
|
||||
class CommandQueue : public RuntimeObject
|
||||
{
|
||||
public:
|
||||
static const uint RealTimeDisabled = 0xffffffff;
|
||||
enum class Priority : uint {
|
||||
Normal = 0,
|
||||
Medium
|
||||
};
|
||||
class CommandQueue : public RuntimeObject {
|
||||
public:
|
||||
static const uint RealTimeDisabled = 0xffffffff;
|
||||
enum class Priority : uint { Normal = 0, Medium };
|
||||
|
||||
struct Properties
|
||||
{
|
||||
typedef cl_command_queue_properties value_type;
|
||||
const value_type mask_;
|
||||
value_type value_;
|
||||
struct Properties {
|
||||
typedef cl_command_queue_properties value_type;
|
||||
const value_type mask_;
|
||||
value_type value_;
|
||||
|
||||
Properties(value_type mask, value_type value) :
|
||||
mask_(mask), value_(value & mask)
|
||||
{ }
|
||||
Properties(value_type mask, value_type value) : mask_(mask), value_(value & mask) {}
|
||||
|
||||
bool set(value_type bits) {
|
||||
if ((mask_ & bits) != bits) {
|
||||
return false;
|
||||
}
|
||||
value_ |= bits;
|
||||
return true;
|
||||
}
|
||||
bool set(value_type bits) {
|
||||
if ((mask_ & bits) != bits) {
|
||||
return false;
|
||||
}
|
||||
value_ |= bits;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool clear(value_type bits) {
|
||||
if ((mask_ & bits) != bits) {
|
||||
return false;
|
||||
}
|
||||
value_ &= ~bits;
|
||||
return true;
|
||||
}
|
||||
bool clear(value_type bits) {
|
||||
if ((mask_ & bits) != bits) {
|
||||
return false;
|
||||
}
|
||||
value_ &= ~bits;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test(value_type bits) const {
|
||||
return (value_ & bits) != 0;
|
||||
}
|
||||
};
|
||||
bool test(value_type bits) const { return (value_ & bits) != 0; }
|
||||
};
|
||||
|
||||
//! Return the context this command queue is part of.
|
||||
Context& context() const { return context_(); }
|
||||
//! Return the context this command queue is part of.
|
||||
Context& context() const { return context_(); }
|
||||
|
||||
//! Return the device for this command queue.
|
||||
Device& device() const { return device_; }
|
||||
//! Return the device for this command queue.
|
||||
Device& device() const { return device_; }
|
||||
|
||||
//! Return the command queue properties.
|
||||
Properties properties() const { return properties_; }
|
||||
Properties& properties() { return properties_; }
|
||||
//! Return the command queue properties.
|
||||
Properties properties() const { return properties_; }
|
||||
Properties& properties() { return properties_; }
|
||||
|
||||
//! Returns the base class object
|
||||
CommandQueue* asCommandQueue() { return this; }
|
||||
//! Returns the base class object
|
||||
CommandQueue* asCommandQueue() { return this; }
|
||||
|
||||
virtual ~CommandQueue() {}
|
||||
virtual ~CommandQueue() {}
|
||||
|
||||
//! Returns TRUE if the object was successfully created
|
||||
virtual bool create() = 0;
|
||||
//! Returns TRUE if the object was successfully created
|
||||
virtual bool create() = 0;
|
||||
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const { return ObjectTypeQueue; }
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const { return ObjectTypeQueue; }
|
||||
|
||||
//! Rturns HostQueue object
|
||||
virtual HostQueue* asHostQueue() { return NULL; }
|
||||
//! Rturns HostQueue object
|
||||
virtual HostQueue* asHostQueue() { return NULL; }
|
||||
|
||||
//! Returns DeviceQueue object
|
||||
virtual DeviceQueue* asDeviceQueue() { return NULL; }
|
||||
//! Returns DeviceQueue object
|
||||
virtual DeviceQueue* asDeviceQueue() { return NULL; }
|
||||
|
||||
//! Returns the number or requested real time CUs
|
||||
uint rtCUs() const { return rtCUs_; }
|
||||
//! Returns the number or requested real time CUs
|
||||
uint rtCUs() const { return rtCUs_; }
|
||||
|
||||
//! Returns the queue priority
|
||||
Priority priority() const { return priority_; }
|
||||
//! Returns the queue priority
|
||||
Priority priority() const { return priority_; }
|
||||
|
||||
protected:
|
||||
//! CommandQueue constructor is protected
|
||||
//! to keep the CommandQueue class as a virtual interface
|
||||
CommandQueue(
|
||||
Context& context, //!< Context object
|
||||
Device& device, //!< Device object
|
||||
cl_command_queue_properties properties, //!< Queue properties
|
||||
cl_command_queue_properties propMask, //!< Queue properties mask
|
||||
uint rtCUs = RealTimeDisabled, //!< Avaialble real time compute units
|
||||
Priority priority = Priority::Normal //!< Queue priority
|
||||
)
|
||||
: properties_(propMask, properties)
|
||||
, rtCUs_(rtCUs)
|
||||
, priority_(priority)
|
||||
, queueLock_("CommandQueue::queueLock")
|
||||
, device_(device)
|
||||
, context_(context) {}
|
||||
protected:
|
||||
//! CommandQueue constructor is protected
|
||||
//! to keep the CommandQueue class as a virtual interface
|
||||
CommandQueue(Context& context, //!< Context object
|
||||
Device& device, //!< Device object
|
||||
cl_command_queue_properties properties, //!< Queue properties
|
||||
cl_command_queue_properties propMask, //!< Queue properties mask
|
||||
uint rtCUs = RealTimeDisabled, //!< Avaialble real time compute units
|
||||
Priority priority = Priority::Normal //!< Queue priority
|
||||
)
|
||||
: properties_(propMask, properties),
|
||||
rtCUs_(rtCUs),
|
||||
priority_(priority),
|
||||
queueLock_("CommandQueue::queueLock"),
|
||||
device_(device),
|
||||
context_(context) {}
|
||||
|
||||
Properties properties_; //!< Queue properties
|
||||
uint rtCUs_; //!< The number of used RT compute units
|
||||
Priority priority_; //!< Queue priority
|
||||
Monitor queueLock_; //!< Lock protecting the queue
|
||||
Device& device_; //!< The device
|
||||
SharedReference<Context> context_; //!< The context of this command queue
|
||||
Properties properties_; //!< Queue properties
|
||||
uint rtCUs_; //!< The number of used RT compute units
|
||||
Priority priority_; //!< Queue priority
|
||||
Monitor queueLock_; //!< Lock protecting the queue
|
||||
Device& device_; //!< The device
|
||||
SharedReference<Context> context_; //!< The context of this command queue
|
||||
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
CommandQueue(const CommandQueue&);
|
||||
private:
|
||||
//! Disable copy constructor
|
||||
CommandQueue(const CommandQueue&);
|
||||
|
||||
//! Disable assignment
|
||||
CommandQueue& operator=(const CommandQueue&);
|
||||
//! Disable assignment
|
||||
CommandQueue& operator=(const CommandQueue&);
|
||||
};
|
||||
|
||||
|
||||
class HostQueue : public CommandQueue
|
||||
{
|
||||
class Thread : public amd::Thread
|
||||
{
|
||||
public:
|
||||
//! True if this command queue thread is accepting commands.
|
||||
volatile bool acceptingCommands_;
|
||||
class HostQueue : public CommandQueue {
|
||||
class Thread : public amd::Thread {
|
||||
public:
|
||||
//! True if this command queue thread is accepting commands.
|
||||
volatile bool acceptingCommands_;
|
||||
|
||||
//! Create a new thread
|
||||
Thread() : amd::Thread("Command Queue Thread", CQ_THREAD_STACK_SIZE),
|
||||
acceptingCommands_(false), virtualDevice_(NULL)
|
||||
{ }
|
||||
//! Create a new thread
|
||||
Thread()
|
||||
: amd::Thread("Command Queue Thread", CQ_THREAD_STACK_SIZE),
|
||||
acceptingCommands_(false),
|
||||
virtualDevice_(NULL) {}
|
||||
|
||||
//! The command queue thread entry point.
|
||||
void run(void *data) {
|
||||
HostQueue* queue = static_cast<HostQueue*>(data);
|
||||
virtualDevice_ = queue->device().createVirtualDevice(queue);
|
||||
if (virtualDevice_ != NULL) {
|
||||
queue->loop(virtualDevice_);
|
||||
if (virtualDevice_->terminate()) {
|
||||
delete virtualDevice_;
|
||||
}
|
||||
}
|
||||
else {
|
||||
acceptingCommands_ = false;
|
||||
queue->flush();
|
||||
}
|
||||
//! The command queue thread entry point.
|
||||
void run(void* data) {
|
||||
HostQueue* queue = static_cast<HostQueue*>(data);
|
||||
virtualDevice_ = queue->device().createVirtualDevice(queue);
|
||||
if (virtualDevice_ != NULL) {
|
||||
queue->loop(virtualDevice_);
|
||||
if (virtualDevice_->terminate()) {
|
||||
delete virtualDevice_;
|
||||
}
|
||||
} else {
|
||||
acceptingCommands_ = false;
|
||||
queue->flush();
|
||||
}
|
||||
}
|
||||
|
||||
//! Get virtual device for the current thread
|
||||
device::VirtualDevice* vdev() const { return virtualDevice_; }
|
||||
//! Get virtual device for the current thread
|
||||
device::VirtualDevice* vdev() const { return virtualDevice_; }
|
||||
|
||||
private:
|
||||
device::VirtualDevice* virtualDevice_; //!< Virtual device for this thread
|
||||
private:
|
||||
device::VirtualDevice* virtualDevice_; //!< Virtual device for this thread
|
||||
|
||||
} thread_; //!< The command queue thread instance.
|
||||
} thread_; //!< The command queue thread instance.
|
||||
|
||||
private:
|
||||
ConcurrentLinkedQueue<Command*> queue_; //!< The queue.
|
||||
private:
|
||||
ConcurrentLinkedQueue<Command*> queue_; //!< The queue.
|
||||
|
||||
//! Await commands and execute them as they become ready.
|
||||
void loop(device::VirtualDevice* virtualDevice);
|
||||
//! Await commands and execute them as they become ready.
|
||||
void loop(device::VirtualDevice* virtualDevice);
|
||||
|
||||
protected:
|
||||
virtual bool terminate();
|
||||
protected:
|
||||
virtual bool terminate();
|
||||
|
||||
public:
|
||||
/*! \brief Construct a new host queue.
|
||||
*
|
||||
* \note A new virtual device instance will be created from the
|
||||
* given device.
|
||||
*/
|
||||
HostQueue(
|
||||
Context& context,
|
||||
Device& device,
|
||||
cl_command_queue_properties properties,
|
||||
uint queueRTCUs = 0,
|
||||
Priority priority = Priority::Normal
|
||||
);
|
||||
public:
|
||||
/*! \brief Construct a new host queue.
|
||||
*
|
||||
* \note A new virtual device instance will be created from the
|
||||
* given device.
|
||||
*/
|
||||
HostQueue(Context& context, Device& device, cl_command_queue_properties properties,
|
||||
uint queueRTCUs = 0, Priority priority = Priority::Normal);
|
||||
|
||||
//! Returns TRUE if this command queue can accept commands.
|
||||
virtual bool create() { return thread_.acceptingCommands_; }
|
||||
//! Returns TRUE if this command queue can accept commands.
|
||||
virtual bool create() { return thread_.acceptingCommands_; }
|
||||
|
||||
//! Append the given command to the queue.
|
||||
void append(Command& command);
|
||||
//! Append the given command to the queue.
|
||||
void append(Command& command);
|
||||
|
||||
//! Return the thread object running the command loop.
|
||||
const Thread& thread() const { return thread_; }
|
||||
//! Return the thread object running the command loop.
|
||||
const Thread& thread() const { return thread_; }
|
||||
|
||||
//! Signal to start processing the commands in the queue.
|
||||
void flush () { ScopedLock sl(queueLock_); queueLock_.notify(); }
|
||||
//! Signal to start processing the commands in the queue.
|
||||
void flush() {
|
||||
ScopedLock sl(queueLock_);
|
||||
queueLock_.notify();
|
||||
}
|
||||
|
||||
//! Finish all queued commands
|
||||
void finish();
|
||||
//! Finish all queued commands
|
||||
void finish();
|
||||
|
||||
//! Get virtual device for the current command queue
|
||||
device::VirtualDevice* vdev() const { return thread_.vdev(); }
|
||||
//! Get virtual device for the current command queue
|
||||
device::VirtualDevice* vdev() const { return thread_.vdev(); }
|
||||
|
||||
//! Return the current queue as the HostQueue
|
||||
virtual HostQueue* asHostQueue() { return this; }
|
||||
//! Return the current queue as the HostQueue
|
||||
virtual HostQueue* asHostQueue() { return this; }
|
||||
};
|
||||
|
||||
|
||||
class DeviceQueue : public CommandQueue
|
||||
{
|
||||
public:
|
||||
DeviceQueue(
|
||||
Context& context, //!< Context object
|
||||
Device& device, //!< Device object
|
||||
cl_command_queue_properties properties, //!< Queue properties
|
||||
uint size //!< Device queue size
|
||||
)
|
||||
: CommandQueue(context, device, properties, device.info().queueOnDeviceProperties_
|
||||
| CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT)
|
||||
, size_(size)
|
||||
, virtualDevice_(NULL) {}
|
||||
class DeviceQueue : public CommandQueue {
|
||||
public:
|
||||
DeviceQueue(Context& context, //!< Context object
|
||||
Device& device, //!< Device object
|
||||
cl_command_queue_properties properties, //!< Queue properties
|
||||
uint size //!< Device queue size
|
||||
)
|
||||
: CommandQueue(context, device, properties, device.info().queueOnDeviceProperties_ |
|
||||
CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT),
|
||||
size_(size),
|
||||
virtualDevice_(NULL) {}
|
||||
|
||||
virtual ~DeviceQueue();
|
||||
virtual ~DeviceQueue();
|
||||
|
||||
//! Returns TRUE if device queue was successfully created
|
||||
virtual bool create();
|
||||
//! Returns TRUE if device queue was successfully created
|
||||
virtual bool create();
|
||||
|
||||
//! Return the current queue as the DeviceQueue
|
||||
virtual DeviceQueue* asDeviceQueue() { return this; }
|
||||
//! Return the current queue as the DeviceQueue
|
||||
virtual DeviceQueue* asDeviceQueue() { return this; }
|
||||
|
||||
//! Returns the size of device queue
|
||||
uint size() const { return size_; }
|
||||
//! Returns the size of device queue
|
||||
uint size() const { return size_; }
|
||||
|
||||
//! Returns virtual device for this device queue
|
||||
device::VirtualDevice* vDev() const { return virtualDevice_; }
|
||||
//! Returns virtual device for this device queue
|
||||
device::VirtualDevice* vDev() const { return virtualDevice_; }
|
||||
|
||||
//! Returns the queue lock
|
||||
Monitor& lock() { return queueLock_; }
|
||||
//! Returns the queue lock
|
||||
Monitor& lock() { return queueLock_; }
|
||||
|
||||
private:
|
||||
uint size_; //!< Device queue size
|
||||
device::VirtualDevice* virtualDevice_; //!< Virtual device for this queue
|
||||
private:
|
||||
uint size_; //!< Device queue size
|
||||
device::VirtualDevice* virtualDevice_; //!< Virtual device for this queue
|
||||
};
|
||||
} //namespace amd
|
||||
} // namespace amd
|
||||
|
||||
#endif //COMMAND_QUEUE_HPP_
|
||||
#endif // COMMAND_QUEUE_HPP_
|
||||
@@ -16,389 +16,345 @@
|
||||
#include "CL/cl_d3d10.h"
|
||||
#include "CL/cl_d3d11.h"
|
||||
#include "CL/cl_dx9_media_sharing.h"
|
||||
#endif //_WIN32
|
||||
#endif //_WIN32
|
||||
|
||||
namespace amd {
|
||||
|
||||
Context::Context(
|
||||
const std::vector<Device*>& devices,
|
||||
const Info& info)
|
||||
: devices_(devices)
|
||||
, info_(info)
|
||||
, properties_(NULL)
|
||||
, glenv_(NULL)
|
||||
, customHostAllocDevice_(NULL)
|
||||
{
|
||||
for (const auto& device : devices) {
|
||||
device->retain();
|
||||
if (customHostAllocDevice_ == NULL && device->customHostAllocator()) {
|
||||
customHostAllocDevice_ = device;
|
||||
}
|
||||
if (device->svmSupport()) {
|
||||
svmAllocDevice_.push_back(device);
|
||||
}
|
||||
Context::Context(const std::vector<Device*>& devices, const Info& info)
|
||||
: devices_(devices),
|
||||
info_(info),
|
||||
properties_(NULL),
|
||||
glenv_(NULL),
|
||||
customHostAllocDevice_(NULL) {
|
||||
for (const auto& device : devices) {
|
||||
device->retain();
|
||||
if (customHostAllocDevice_ == NULL && device->customHostAllocator()) {
|
||||
customHostAllocDevice_ = device;
|
||||
}
|
||||
if (svmAllocDevice_.size() > 1) {
|
||||
//make sure the CPU is the last device to do allocation.
|
||||
if ((svmAllocDevice_.front()->type() == CL_DEVICE_TYPE_CPU)) {
|
||||
std::swap(svmAllocDevice_.front(), svmAllocDevice_.back());
|
||||
}
|
||||
|
||||
uint isFirstDeviceFGSEnabled = svmAllocDevice_.front()->isFineGrainedSystem(true);
|
||||
for (auto& dev : svmAllocDevice_) {
|
||||
//allocation on fine - grained system incapable device first
|
||||
if (isFirstDeviceFGSEnabled && (dev->type() == CL_DEVICE_TYPE_GPU)
|
||||
&& (!(dev->isFineGrainedSystem(true)))) {
|
||||
std::swap(svmAllocDevice_.front(), dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (device->svmSupport()) {
|
||||
svmAllocDevice_.push_back(device);
|
||||
}
|
||||
}
|
||||
if (svmAllocDevice_.size() > 1) {
|
||||
// make sure the CPU is the last device to do allocation.
|
||||
if ((svmAllocDevice_.front()->type() == CL_DEVICE_TYPE_CPU)) {
|
||||
std::swap(svmAllocDevice_.front(), svmAllocDevice_.back());
|
||||
}
|
||||
|
||||
uint isFirstDeviceFGSEnabled = svmAllocDevice_.front()->isFineGrainedSystem(true);
|
||||
for (auto& dev : svmAllocDevice_) {
|
||||
// allocation on fine - grained system incapable device first
|
||||
if (isFirstDeviceFGSEnabled && (dev->type() == CL_DEVICE_TYPE_GPU) &&
|
||||
(!(dev->isFineGrainedSystem(true)))) {
|
||||
std::swap(svmAllocDevice_.front(), dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Context::~Context()
|
||||
{
|
||||
static const bool VALIDATE_ONLY = false;
|
||||
Context::~Context() {
|
||||
static const bool VALIDATE_ONLY = false;
|
||||
|
||||
// Dissociate OCL context with any external device
|
||||
if (info_.flags_ & (GLDeviceKhr | D3D10DeviceKhr | D3D11DeviceKhr)) {
|
||||
std::vector<Device *>::const_iterator it;
|
||||
// Loop through all devices
|
||||
for (it = devices_.begin(); it != devices_.end(); it++) {
|
||||
(*it)->unbindExternalDevice(info_.flags_, info_.hDev_, info_.hCtx_, VALIDATE_ONLY);
|
||||
}
|
||||
// Dissociate OCL context with any external device
|
||||
if (info_.flags_ & (GLDeviceKhr | D3D10DeviceKhr | D3D11DeviceKhr)) {
|
||||
std::vector<Device*>::const_iterator it;
|
||||
// Loop through all devices
|
||||
for (it = devices_.begin(); it != devices_.end(); it++) {
|
||||
(*it)->unbindExternalDevice(info_.flags_, info_.hDev_, info_.hCtx_, VALIDATE_ONLY);
|
||||
}
|
||||
}
|
||||
|
||||
if (properties_ != NULL) {
|
||||
delete [] properties_;
|
||||
}
|
||||
if (glenv_ != NULL) {
|
||||
delete glenv_;
|
||||
glenv_ = NULL;
|
||||
}
|
||||
if (properties_ != NULL) {
|
||||
delete[] properties_;
|
||||
}
|
||||
if (glenv_ != NULL) {
|
||||
delete glenv_;
|
||||
glenv_ = NULL;
|
||||
}
|
||||
|
||||
std::for_each(devices_.begin(), devices_.end(),
|
||||
std::mem_fun(&Device::release));
|
||||
std::for_each(devices_.begin(), devices_.end(), std::mem_fun(&Device::release));
|
||||
}
|
||||
|
||||
int
|
||||
Context::checkProperties(
|
||||
const cl_context_properties* properties,
|
||||
Context::Info* info)
|
||||
{
|
||||
cl_platform_id pfmId = 0;
|
||||
uint count = 0;
|
||||
int Context::checkProperties(const cl_context_properties* properties, Context::Info* info) {
|
||||
cl_platform_id pfmId = 0;
|
||||
uint count = 0;
|
||||
|
||||
const struct Element
|
||||
{
|
||||
intptr_t name;
|
||||
void* ptr;
|
||||
} *p = reinterpret_cast<const Element*>(properties);
|
||||
const struct Element {
|
||||
intptr_t name;
|
||||
void* ptr;
|
||||
}* p = reinterpret_cast<const Element*>(properties);
|
||||
|
||||
// Clear the context infor structure
|
||||
::memset(info, 0, sizeof(Context::Info));
|
||||
// Clear the context infor structure
|
||||
::memset(info, 0, sizeof(Context::Info));
|
||||
|
||||
if (properties == NULL) {
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
if (properties == NULL) {
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
// Process all properties
|
||||
while (p->name != 0) {
|
||||
switch (p->name) {
|
||||
case CL_CONTEXT_INTEROP_USER_SYNC:
|
||||
if (p->ptr == reinterpret_cast<void*>(CL_TRUE))
|
||||
{
|
||||
info->flags_ |= InteropUserSync;
|
||||
}
|
||||
break;
|
||||
// Process all properties
|
||||
while (p->name != 0) {
|
||||
switch (p->name) {
|
||||
case CL_CONTEXT_INTEROP_USER_SYNC:
|
||||
if (p->ptr == reinterpret_cast<void*>(CL_TRUE)) {
|
||||
info->flags_ |= InteropUserSync;
|
||||
}
|
||||
break;
|
||||
#ifdef _WIN32
|
||||
case CL_CONTEXT_D3D10_DEVICE_KHR:
|
||||
if (p->ptr == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
info->hDev_[D3D10DeviceKhrIdx] = p->ptr;
|
||||
info->flags_ |= D3D10DeviceKhr;
|
||||
break;
|
||||
case CL_CONTEXT_D3D11_DEVICE_KHR:
|
||||
if (p->ptr == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
info->hDev_[D3D11DeviceKhrIdx] = p->ptr;
|
||||
info->flags_ |= D3D11DeviceKhr;
|
||||
break;
|
||||
case CL_CONTEXT_ADAPTER_D3D9_KHR:
|
||||
if (p->ptr == NULL) { //not supported for xp
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
info->hDev_[D3D9DeviceKhrIdx] = p->ptr;
|
||||
info->flags_ |= D3D9DeviceKhr;
|
||||
break;
|
||||
case CL_CONTEXT_ADAPTER_D3D9EX_KHR:
|
||||
if (p->ptr == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
info->hDev_[D3D9DeviceEXKhrIdx] = p->ptr;
|
||||
info->flags_ |= D3D9DeviceEXKhr;
|
||||
break;
|
||||
case CL_CONTEXT_ADAPTER_DXVA_KHR:
|
||||
if (p->ptr == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
info->hDev_[D3D9DeviceVAKhrIdx] = p->ptr;
|
||||
info->flags_ |= D3D9DeviceVAKhr;
|
||||
break;
|
||||
#endif //_WIN32
|
||||
case CL_CONTEXT_D3D10_DEVICE_KHR:
|
||||
if (p->ptr == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
info->hDev_[D3D10DeviceKhrIdx] = p->ptr;
|
||||
info->flags_ |= D3D10DeviceKhr;
|
||||
break;
|
||||
case CL_CONTEXT_D3D11_DEVICE_KHR:
|
||||
if (p->ptr == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
info->hDev_[D3D11DeviceKhrIdx] = p->ptr;
|
||||
info->flags_ |= D3D11DeviceKhr;
|
||||
break;
|
||||
case CL_CONTEXT_ADAPTER_D3D9_KHR:
|
||||
if (p->ptr == NULL) { // not supported for xp
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
info->hDev_[D3D9DeviceKhrIdx] = p->ptr;
|
||||
info->flags_ |= D3D9DeviceKhr;
|
||||
break;
|
||||
case CL_CONTEXT_ADAPTER_D3D9EX_KHR:
|
||||
if (p->ptr == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
info->hDev_[D3D9DeviceEXKhrIdx] = p->ptr;
|
||||
info->flags_ |= D3D9DeviceEXKhr;
|
||||
break;
|
||||
case CL_CONTEXT_ADAPTER_DXVA_KHR:
|
||||
if (p->ptr == NULL) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
info->hDev_[D3D9DeviceVAKhrIdx] = p->ptr;
|
||||
info->flags_ |= D3D9DeviceVAKhr;
|
||||
break;
|
||||
#endif //_WIN32
|
||||
|
||||
case CL_EGL_DISPLAY_KHR:
|
||||
info->flags_ |= EGLDeviceKhr;
|
||||
case CL_EGL_DISPLAY_KHR:
|
||||
info->flags_ |= EGLDeviceKhr;
|
||||
|
||||
#ifdef _WIN32
|
||||
case CL_WGL_HDC_KHR:
|
||||
#endif //_WIN32
|
||||
case CL_WGL_HDC_KHR:
|
||||
#endif //_WIN32
|
||||
|
||||
#if defined(__linux__)
|
||||
case CL_GLX_DISPLAY_KHR:
|
||||
#endif //linux
|
||||
info->hDev_[GLDeviceKhrIdx] = p->ptr;
|
||||
case CL_GLX_DISPLAY_KHR:
|
||||
#endif // linux
|
||||
info->hDev_[GLDeviceKhrIdx] = p->ptr;
|
||||
|
||||
#if defined(__APPLE__) || defined(__MACOSX)
|
||||
case CL_CGL_SHAREGROUP_KHR:
|
||||
Unimplemented();
|
||||
break;
|
||||
#endif //__APPLE__ || MACOS
|
||||
case CL_CGL_SHAREGROUP_KHR:
|
||||
Unimplemented();
|
||||
break;
|
||||
#endif //__APPLE__ || MACOS
|
||||
|
||||
case CL_GL_CONTEXT_KHR:
|
||||
if (p->ptr == NULL) {
|
||||
return CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR;
|
||||
}
|
||||
if (p->name == CL_GL_CONTEXT_KHR) {
|
||||
info->hCtx_ = p->ptr;
|
||||
}
|
||||
info->flags_ |= GLDeviceKhr;
|
||||
break;
|
||||
case CL_CONTEXT_PLATFORM:
|
||||
pfmId = reinterpret_cast<cl_platform_id>(p->ptr);
|
||||
if ((NULL != pfmId) && (AMD_PLATFORM != pfmId)) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
break;
|
||||
case CL_CONTEXT_OFFLINE_DEVICES_AMD:
|
||||
if (p->ptr != reinterpret_cast<void*>(1)) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
// Set the offline device flag
|
||||
info->flags_ |= OfflineDevices;
|
||||
break;
|
||||
case CL_CONTEXT_COMMAND_INTERCEPT_CALLBACK_AMD:
|
||||
// Set the command intercept flag
|
||||
info->commandIntercept_ =
|
||||
(cl_int (CL_CALLBACK *)(cl_event, cl_int *)) p->ptr;
|
||||
info->flags_ |= CommandIntercept;
|
||||
break;
|
||||
default:
|
||||
return CL_INVALID_VALUE;
|
||||
case CL_GL_CONTEXT_KHR:
|
||||
if (p->ptr == NULL) {
|
||||
return CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR;
|
||||
}
|
||||
p++;
|
||||
count++;
|
||||
if (p->name == CL_GL_CONTEXT_KHR) {
|
||||
info->hCtx_ = p->ptr;
|
||||
}
|
||||
info->flags_ |= GLDeviceKhr;
|
||||
break;
|
||||
case CL_CONTEXT_PLATFORM:
|
||||
pfmId = reinterpret_cast<cl_platform_id>(p->ptr);
|
||||
if ((NULL != pfmId) && (AMD_PLATFORM != pfmId)) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
break;
|
||||
case CL_CONTEXT_OFFLINE_DEVICES_AMD:
|
||||
if (p->ptr != reinterpret_cast<void*>(1)) {
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
// Set the offline device flag
|
||||
info->flags_ |= OfflineDevices;
|
||||
break;
|
||||
case CL_CONTEXT_COMMAND_INTERCEPT_CALLBACK_AMD:
|
||||
// Set the command intercept flag
|
||||
info->commandIntercept_ = (cl_int(CL_CALLBACK*)(cl_event, cl_int*))p->ptr;
|
||||
info->flags_ |= CommandIntercept;
|
||||
break;
|
||||
default:
|
||||
return CL_INVALID_VALUE;
|
||||
}
|
||||
p++;
|
||||
count++;
|
||||
}
|
||||
|
||||
info->propertiesSize_ = count * sizeof(Element) + sizeof(intptr_t);
|
||||
return CL_SUCCESS;
|
||||
info->propertiesSize_ = count * sizeof(Element) + sizeof(intptr_t);
|
||||
return CL_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
Context::create(const intptr_t* properties)
|
||||
{
|
||||
static const bool VALIDATE_ONLY = false;
|
||||
int result = CL_SUCCESS;
|
||||
int Context::create(const intptr_t* properties) {
|
||||
static const bool VALIDATE_ONLY = false;
|
||||
int result = CL_SUCCESS;
|
||||
|
||||
if (properties != NULL) {
|
||||
properties_ = new cl_context_properties[
|
||||
info().propertiesSize_ / sizeof(cl_context_properties)];
|
||||
if (properties_ == NULL) {
|
||||
return CL_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
::memcpy(properties_, properties, info().propertiesSize_);
|
||||
if (properties != NULL) {
|
||||
properties_ = new cl_context_properties[info().propertiesSize_ / sizeof(cl_context_properties)];
|
||||
if (properties_ == NULL) {
|
||||
return CL_OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
// Check if OCL context can be associated with any external device
|
||||
if (info_.flags_ & (D3D10DeviceKhr | D3D11DeviceKhr | GLDeviceKhr |
|
||||
D3D9DeviceKhr | D3D9DeviceEXKhr | D3D9DeviceVAKhr)) {
|
||||
std::vector<Device *>::const_iterator it;
|
||||
// Loop through all devices
|
||||
for (it = devices_.begin(); it != devices_.end(); it++) {
|
||||
if (!(*it)->bindExternalDevice(
|
||||
info_.flags_, info_.hDev_, info_.hCtx_, VALIDATE_ONLY)) {
|
||||
result = CL_INVALID_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
::memcpy(properties_, properties, info().propertiesSize_);
|
||||
}
|
||||
|
||||
// Check if the device binding wasn't successful
|
||||
if (result != CL_SUCCESS) {
|
||||
if (info_.flags_ & GLDeviceKhr) {
|
||||
result = CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR;
|
||||
}
|
||||
else if (info_.flags_ & D3D10DeviceKhr) {
|
||||
//return CL_INVALID_VALUE; // FIXME_odintsov: CL_INVALID_D3D_INTEROP;
|
||||
}
|
||||
else if (info_.flags_ & D3D11DeviceKhr) {
|
||||
//return CL_INVALID_VALUE; // FIXME_odintsov: CL_INVALID_D3D_INTEROP;
|
||||
}
|
||||
else if (info_.flags_ & (D3D9DeviceKhr | D3D9DeviceEXKhr | D3D9DeviceVAKhr)) {
|
||||
//return CL_INVALID_DX9_MEDIA_ADAPTER_KHR;
|
||||
}
|
||||
// Check if OCL context can be associated with any external device
|
||||
if (info_.flags_ & (D3D10DeviceKhr | D3D11DeviceKhr | GLDeviceKhr | D3D9DeviceKhr |
|
||||
D3D9DeviceEXKhr | D3D9DeviceVAKhr)) {
|
||||
std::vector<Device*>::const_iterator it;
|
||||
// Loop through all devices
|
||||
for (it = devices_.begin(); it != devices_.end(); it++) {
|
||||
if (!(*it)->bindExternalDevice(info_.flags_, info_.hDev_, info_.hCtx_, VALIDATE_ONLY)) {
|
||||
result = CL_INVALID_VALUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (info_.flags_ & GLDeviceKhr) {
|
||||
// Init context for GL interop
|
||||
if(glenv_ == NULL) {
|
||||
HMODULE h = (HMODULE) Os::loadLibrary(
|
||||
}
|
||||
|
||||
// Check if the device binding wasn't successful
|
||||
if (result != CL_SUCCESS) {
|
||||
if (info_.flags_ & GLDeviceKhr) {
|
||||
result = CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR;
|
||||
} else if (info_.flags_ & D3D10DeviceKhr) {
|
||||
// return CL_INVALID_VALUE; // FIXME_odintsov: CL_INVALID_D3D_INTEROP;
|
||||
} else if (info_.flags_ & D3D11DeviceKhr) {
|
||||
// return CL_INVALID_VALUE; // FIXME_odintsov: CL_INVALID_D3D_INTEROP;
|
||||
} else if (info_.flags_ & (D3D9DeviceKhr | D3D9DeviceEXKhr | D3D9DeviceVAKhr)) {
|
||||
// return CL_INVALID_DX9_MEDIA_ADAPTER_KHR;
|
||||
}
|
||||
} else {
|
||||
if (info_.flags_ & GLDeviceKhr) {
|
||||
// Init context for GL interop
|
||||
if (glenv_ == NULL) {
|
||||
HMODULE h = (HMODULE)Os::loadLibrary(
|
||||
#ifdef _WIN32
|
||||
"OpenGL32.dll"
|
||||
#else //!_WIN32
|
||||
"libGL.so.1"
|
||||
#endif //!_WIN32
|
||||
);
|
||||
"OpenGL32.dll"
|
||||
#else //!_WIN32
|
||||
"libGL.so.1"
|
||||
#endif //!_WIN32
|
||||
);
|
||||
|
||||
if (h && (glenv_ = new GLFunctions(h, (info_.flags_ & Flags::EGLDeviceKhr) != 0))) {
|
||||
if (!glenv_->init(reinterpret_cast<intptr_t>(info_.hDev_[GLDeviceKhrIdx]),
|
||||
reinterpret_cast<intptr_t>(info_.hCtx_))) {
|
||||
delete glenv_;
|
||||
glenv_ = NULL;
|
||||
result = CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (h && (glenv_ = new GLFunctions(h, (info_.flags_ & Flags::EGLDeviceKhr) != 0))) {
|
||||
if (!glenv_->init(reinterpret_cast<intptr_t>(info_.hDev_[GLDeviceKhrIdx]),
|
||||
reinterpret_cast<intptr_t>(info_.hCtx_))) {
|
||||
delete glenv_;
|
||||
glenv_ = NULL;
|
||||
result = CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void*
|
||||
Context::hostAlloc(size_t size, size_t alignment, bool atomics) const
|
||||
{
|
||||
if (customHostAllocDevice_ != NULL) {
|
||||
return customHostAllocDevice_->hostAlloc(size, alignment, atomics);
|
||||
}
|
||||
void* Context::hostAlloc(size_t size, size_t alignment, bool atomics) const {
|
||||
if (customHostAllocDevice_ != NULL) {
|
||||
return customHostAllocDevice_->hostAlloc(size, alignment, atomics);
|
||||
}
|
||||
return AlignedMemory::allocate(size, alignment);
|
||||
}
|
||||
|
||||
void Context::hostFree(void* ptr) const {
|
||||
if (customHostAllocDevice_ != NULL) {
|
||||
customHostAllocDevice_->hostFree(ptr);
|
||||
return;
|
||||
}
|
||||
AlignedMemory::deallocate(ptr);
|
||||
}
|
||||
|
||||
void* Context::svmAlloc(size_t size, size_t alignment, cl_svm_mem_flags flags) {
|
||||
unsigned int numSVMDev = svmAllocDevice_.size();
|
||||
if (numSVMDev < 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (svmAllocDevice_.front()->type() == CL_DEVICE_TYPE_CPU) {
|
||||
return AlignedMemory::allocate(size, alignment);
|
||||
}
|
||||
|
||||
void
|
||||
Context::hostFree(void* ptr) const
|
||||
{
|
||||
if (customHostAllocDevice_ != NULL) {
|
||||
customHostAllocDevice_->hostFree(ptr);
|
||||
return;
|
||||
}
|
||||
AlignedMemory::deallocate(ptr);
|
||||
}
|
||||
|
||||
void*
|
||||
Context::svmAlloc(size_t size, size_t alignment, cl_svm_mem_flags flags)
|
||||
{
|
||||
unsigned int numSVMDev = svmAllocDevice_.size();
|
||||
if (numSVMDev < 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (svmAllocDevice_.front()->type() == CL_DEVICE_TYPE_CPU) {
|
||||
return AlignedMemory::allocate(size, alignment);
|
||||
}
|
||||
else {
|
||||
void* svmPtrAlloced = NULL;
|
||||
void* tempPtr = NULL;
|
||||
|
||||
for (const auto& dev : svmAllocDevice_) {
|
||||
if (dev->type() == CL_DEVICE_TYPE_GPU) {
|
||||
//check if the device support svm platform atomics,
|
||||
//skipped allocation for platform atomics if not supported by this device
|
||||
if ((flags & CL_MEM_SVM_ATOMICS) && !(dev->info().svmCapabilities_ & CL_DEVICE_SVM_ATOMICS)) {
|
||||
continue;
|
||||
}
|
||||
svmPtrAlloced = dev->svmAlloc(*this, size, alignment, flags, svmPtrAlloced);
|
||||
if (svmPtrAlloced == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return svmPtrAlloced;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Context::svmFree(void* ptr) const
|
||||
{
|
||||
if (svmAllocDevice_.front()->type() == CL_DEVICE_TYPE_CPU) {
|
||||
AlignedMemory::deallocate(ptr);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
void* svmPtrAlloced = NULL;
|
||||
void* tempPtr = NULL;
|
||||
|
||||
for (const auto& dev : svmAllocDevice_) {
|
||||
if (dev->type() == CL_DEVICE_TYPE_GPU) {
|
||||
dev->svmFree(ptr);
|
||||
if (dev->type() == CL_DEVICE_TYPE_GPU) {
|
||||
// check if the device support svm platform atomics,
|
||||
// skipped allocation for platform atomics if not supported by this device
|
||||
if ((flags & CL_MEM_SVM_ATOMICS) &&
|
||||
!(dev->info().svmCapabilities_ & CL_DEVICE_SVM_ATOMICS)) {
|
||||
continue;
|
||||
}
|
||||
svmPtrAlloced = dev->svmAlloc(*this, size, alignment, flags, svmPtrAlloced);
|
||||
if (svmPtrAlloced == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return svmPtrAlloced;
|
||||
}
|
||||
}
|
||||
|
||||
void Context::svmFree(void* ptr) const {
|
||||
if (svmAllocDevice_.front()->type() == CL_DEVICE_TYPE_CPU) {
|
||||
AlignedMemory::deallocate(ptr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Context::containsDevice(const Device* device) const
|
||||
{
|
||||
std::vector<Device *>::const_iterator it;
|
||||
|
||||
for (it = devices_.begin(); it != devices_.end(); ++it) {
|
||||
if (device == *it || (*it)->isAncestor(device)) {
|
||||
return true;
|
||||
}
|
||||
for (const auto& dev : svmAllocDevice_) {
|
||||
if (dev->type() == CL_DEVICE_TYPE_GPU) {
|
||||
dev->svmFree(ptr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceQueue*
|
||||
Context::defDeviceQueue(const Device& dev) const
|
||||
{
|
||||
std::map<const Device*, DeviceQueueInfo>::const_iterator it =
|
||||
deviceQueues_.find(&dev);
|
||||
if (it != deviceQueues_.end()) {
|
||||
return it->second.defDeviceQueue_;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
bool Context::containsDevice(const Device* device) const {
|
||||
std::vector<Device*>::const_iterator it;
|
||||
|
||||
for (it = devices_.begin(); it != devices_.end(); ++it) {
|
||||
if (device == *it || (*it)->isAncestor(device)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Context::isDevQueuePossible(const Device& dev)
|
||||
{
|
||||
return (deviceQueues_[&dev].deviceQueueCnt_ < dev.info().maxOnDeviceQueues_) ?
|
||||
true : false;
|
||||
DeviceQueue* Context::defDeviceQueue(const Device& dev) const {
|
||||
std::map<const Device*, DeviceQueueInfo>::const_iterator it = deviceQueues_.find(&dev);
|
||||
if (it != deviceQueues_.end()) {
|
||||
return it->second.defDeviceQueue_;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Context::addDeviceQueue(const Device& dev, DeviceQueue* queue, bool defDevQueue)
|
||||
{
|
||||
DeviceQueueInfo& info = deviceQueues_[&dev];
|
||||
info.deviceQueueCnt_++;
|
||||
if (defDevQueue) {
|
||||
info.defDeviceQueue_ = queue;
|
||||
}
|
||||
bool Context::isDevQueuePossible(const Device& dev) {
|
||||
return (deviceQueues_[&dev].deviceQueueCnt_ < dev.info().maxOnDeviceQueues_) ? true : false;
|
||||
}
|
||||
|
||||
void
|
||||
Context::removeDeviceQueue(const Device& dev, DeviceQueue* queue)
|
||||
{
|
||||
DeviceQueueInfo& info = deviceQueues_[&dev];
|
||||
assert((info.deviceQueueCnt_ != 0) && "The device queue map is empty!");
|
||||
info.deviceQueueCnt_--;
|
||||
if (info.defDeviceQueue_ == queue) {
|
||||
info.defDeviceQueue_ = NULL;
|
||||
}
|
||||
void Context::addDeviceQueue(const Device& dev, DeviceQueue* queue, bool defDevQueue) {
|
||||
DeviceQueueInfo& info = deviceQueues_[&dev];
|
||||
info.deviceQueueCnt_++;
|
||||
if (defDevQueue) {
|
||||
info.defDeviceQueue_ = queue;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace amd
|
||||
void Context::removeDeviceQueue(const Device& dev, DeviceQueue* queue) {
|
||||
DeviceQueueInfo& info = deviceQueues_[&dev];
|
||||
assert((info.deviceQueueCnt_ != 0) && "The device queue map is empty!");
|
||||
info.deviceQueueCnt_--;
|
||||
if (info.defDeviceQueue_ == queue) {
|
||||
info.defDeviceQueue_ = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace amd
|
||||
@@ -25,192 +25,182 @@ namespace amd {
|
||||
class GLFunctions;
|
||||
class DeviceQueue;
|
||||
|
||||
class Context : public RuntimeObject
|
||||
{
|
||||
std::vector<Device*> devices_;
|
||||
class Context : public RuntimeObject {
|
||||
std::vector<Device*> devices_;
|
||||
|
||||
public:
|
||||
enum DeviceFlagIdx
|
||||
{
|
||||
GLDeviceKhrIdx = 0, //!< GL
|
||||
D3D10DeviceKhrIdx, //!< D3D10
|
||||
OfflineDevicesIdx, //!< Offline devices
|
||||
CommandInterceptIdx, //!< Command intercept
|
||||
D3D11DeviceKhrIdx, //!< D3D11
|
||||
InteropUserSyncIdx, //!< Interop user sync enabled
|
||||
D3D9DeviceKhrIdx, //!< d3d9 device
|
||||
D3D9DeviceEXKhrIdx, //!< d3d9EX device
|
||||
D3D9DeviceVAKhrIdx, //!< d3d9VA device
|
||||
EGLDeviceKhrIdx, //!< EGL device
|
||||
LastDeviceFlagIdx
|
||||
};
|
||||
public:
|
||||
enum DeviceFlagIdx {
|
||||
GLDeviceKhrIdx = 0, //!< GL
|
||||
D3D10DeviceKhrIdx, //!< D3D10
|
||||
OfflineDevicesIdx, //!< Offline devices
|
||||
CommandInterceptIdx, //!< Command intercept
|
||||
D3D11DeviceKhrIdx, //!< D3D11
|
||||
InteropUserSyncIdx, //!< Interop user sync enabled
|
||||
D3D9DeviceKhrIdx, //!< d3d9 device
|
||||
D3D9DeviceEXKhrIdx, //!< d3d9EX device
|
||||
D3D9DeviceVAKhrIdx, //!< d3d9VA device
|
||||
EGLDeviceKhrIdx, //!< EGL device
|
||||
LastDeviceFlagIdx
|
||||
};
|
||||
|
||||
enum Flags
|
||||
{
|
||||
GLDeviceKhr = 1 << GLDeviceKhrIdx, //!< GL
|
||||
D3D10DeviceKhr = 1 << D3D10DeviceKhrIdx, //!< D3D10
|
||||
OfflineDevices = 1 << OfflineDevicesIdx, //!< Offline devices
|
||||
CommandIntercept = 1 << CommandInterceptIdx, //!< Command intercept
|
||||
D3D11DeviceKhr = 1 << D3D11DeviceKhrIdx, //!< D3D11
|
||||
InteropUserSync = 1 << InteropUserSyncIdx, //!< Interop user sync enabled
|
||||
D3D9DeviceKhr = 1 << D3D9DeviceKhrIdx, //!< d3d9 device
|
||||
D3D9DeviceEXKhr = 1 << D3D9DeviceEXKhrIdx, //!< d3d9EX device
|
||||
D3D9DeviceVAKhr = 1 << D3D9DeviceVAKhrIdx, //!< d3d9VA device
|
||||
EGLDeviceKhr = 1 << EGLDeviceKhrIdx, //!< EGL device
|
||||
};
|
||||
enum Flags {
|
||||
GLDeviceKhr = 1 << GLDeviceKhrIdx, //!< GL
|
||||
D3D10DeviceKhr = 1 << D3D10DeviceKhrIdx, //!< D3D10
|
||||
OfflineDevices = 1 << OfflineDevicesIdx, //!< Offline devices
|
||||
CommandIntercept = 1 << CommandInterceptIdx, //!< Command intercept
|
||||
D3D11DeviceKhr = 1 << D3D11DeviceKhrIdx, //!< D3D11
|
||||
InteropUserSync = 1 << InteropUserSyncIdx, //!< Interop user sync enabled
|
||||
D3D9DeviceKhr = 1 << D3D9DeviceKhrIdx, //!< d3d9 device
|
||||
D3D9DeviceEXKhr = 1 << D3D9DeviceEXKhrIdx, //!< d3d9EX device
|
||||
D3D9DeviceVAKhr = 1 << D3D9DeviceVAKhrIdx, //!< d3d9VA device
|
||||
EGLDeviceKhr = 1 << EGLDeviceKhrIdx, //!< EGL device
|
||||
};
|
||||
|
||||
//! Context info structure
|
||||
struct Info
|
||||
{
|
||||
uint flags_; //!< Context info flags
|
||||
void* hDev_[LastDeviceFlagIdx]; //!< Device object reference
|
||||
void* hCtx_; //!< Context object reference
|
||||
size_t propertiesSize_;//!< Size of the original properties in bytes
|
||||
cl_int (CL_CALLBACK * commandIntercept_)(cl_event, cl_int *);
|
||||
};
|
||||
//! Context info structure
|
||||
struct Info {
|
||||
uint flags_; //!< Context info flags
|
||||
void* hDev_[LastDeviceFlagIdx]; //!< Device object reference
|
||||
void* hCtx_; //!< Context object reference
|
||||
size_t propertiesSize_; //!< Size of the original properties in bytes
|
||||
cl_int(CL_CALLBACK* commandIntercept_)(cl_event, cl_int*);
|
||||
};
|
||||
|
||||
struct DeviceQueueInfo
|
||||
{
|
||||
DeviceQueue* defDeviceQueue_; //!< Default device queue
|
||||
uint deviceQueueCnt_; //!< The number of device queues
|
||||
DeviceQueueInfo(): defDeviceQueue_(NULL), deviceQueueCnt_(0) {}
|
||||
};
|
||||
struct DeviceQueueInfo {
|
||||
DeviceQueue* defDeviceQueue_; //!< Default device queue
|
||||
uint deviceQueueCnt_; //!< The number of device queues
|
||||
DeviceQueueInfo() : defDeviceQueue_(NULL), deviceQueueCnt_(0) {}
|
||||
};
|
||||
|
||||
private:
|
||||
// Copying a Context is not allowed
|
||||
Context(const Context&);
|
||||
Context& operator = (const Context&);
|
||||
private:
|
||||
// Copying a Context is not allowed
|
||||
Context(const Context&);
|
||||
Context& operator=(const Context&);
|
||||
|
||||
protected:
|
||||
bool terminate() {
|
||||
if (Agent::shouldPostContextEvents()) {
|
||||
Agent::postContextFree(as_cl(this));
|
||||
}
|
||||
return true;
|
||||
protected:
|
||||
bool terminate() {
|
||||
if (Agent::shouldPostContextEvents()) {
|
||||
Agent::postContextFree(as_cl(this));
|
||||
}
|
||||
//! Context destructor
|
||||
~Context();
|
||||
return true;
|
||||
}
|
||||
//! Context destructor
|
||||
~Context();
|
||||
|
||||
public:
|
||||
/*! \brief Helper function to check the context properties and initialize
|
||||
* context info structure
|
||||
*
|
||||
* \return An errcode if invalid, CL_SUCCESS if valid
|
||||
*/
|
||||
static int checkProperties(
|
||||
const cl_context_properties* properties, //!< Properties
|
||||
Info* info //!< Info structure
|
||||
);
|
||||
public:
|
||||
/*! \brief Helper function to check the context properties and initialize
|
||||
* context info structure
|
||||
*
|
||||
* \return An errcode if invalid, CL_SUCCESS if valid
|
||||
*/
|
||||
static int checkProperties(const cl_context_properties* properties, //!< Properties
|
||||
Info* info //!< Info structure
|
||||
);
|
||||
|
||||
//! Default constructor
|
||||
Context(
|
||||
const std::vector<Device*>& devices, //!< List of all devices
|
||||
const Info& info //!< Context info structure
|
||||
);
|
||||
//! Default constructor
|
||||
Context(const std::vector<Device*>& devices, //!< List of all devices
|
||||
const Info& info //!< Context info structure
|
||||
);
|
||||
|
||||
//! Compare two Context instances.
|
||||
bool operator == (const Context& rhs) const { return this == &rhs; }
|
||||
bool operator != (const Context& rhs) const { return !(*this == rhs); }
|
||||
//! Compare two Context instances.
|
||||
bool operator==(const Context& rhs) const { return this == &rhs; }
|
||||
bool operator!=(const Context& rhs) const { return !(*this == rhs); }
|
||||
|
||||
/*! Creates the context
|
||||
*
|
||||
* \return An errcode if runtime fails the context creation,
|
||||
* CL_SUCCESS otherwise
|
||||
*/
|
||||
int create(
|
||||
const intptr_t* properties //!< Original context properties
|
||||
);
|
||||
/*! Creates the context
|
||||
*
|
||||
* \return An errcode if runtime fails the context creation,
|
||||
* CL_SUCCESS otherwise
|
||||
*/
|
||||
int create(const intptr_t* properties //!< Original context properties
|
||||
);
|
||||
|
||||
/**
|
||||
* Allocate host memory using either a custom device allocator or a generic
|
||||
* OS allocator
|
||||
*
|
||||
* @param size Allocation size, in bytes
|
||||
* @param alignment Desired alignment, in bytes
|
||||
* @param atomics The buffer should support platform (SVM) atomics
|
||||
*/
|
||||
void* hostAlloc(size_t size, size_t alignment, bool atomics = false) const;
|
||||
/**
|
||||
* Allocate host memory using either a custom device allocator or a generic
|
||||
* OS allocator
|
||||
*
|
||||
* @param size Allocation size, in bytes
|
||||
* @param alignment Desired alignment, in bytes
|
||||
* @param atomics The buffer should support platform (SVM) atomics
|
||||
*/
|
||||
void* hostAlloc(size_t size, size_t alignment, bool atomics = false) const;
|
||||
|
||||
/**
|
||||
* Release host memory
|
||||
* @param ptr Pointer allocated using ::hostAlloc. If the pointer has been
|
||||
* allocated elsewhere, the behavior is undefined
|
||||
*/
|
||||
void hostFree(void* ptr) const;
|
||||
/**
|
||||
* Release host memory
|
||||
* @param ptr Pointer allocated using ::hostAlloc. If the pointer has been
|
||||
* allocated elsewhere, the behavior is undefined
|
||||
*/
|
||||
void hostFree(void* ptr) const;
|
||||
|
||||
/**
|
||||
* Allocate SVM buffer
|
||||
*
|
||||
* @param size Allocation size, in bytes
|
||||
* @param alignment Desired alignment, in bytes
|
||||
* @param flags The flags to create a svm space
|
||||
*/
|
||||
void* svmAlloc(size_t size, size_t alignment, cl_svm_mem_flags flags = CL_MEM_READ_WRITE);
|
||||
/**
|
||||
* Allocate SVM buffer
|
||||
*
|
||||
* @param size Allocation size, in bytes
|
||||
* @param alignment Desired alignment, in bytes
|
||||
* @param flags The flags to create a svm space
|
||||
*/
|
||||
void* svmAlloc(size_t size, size_t alignment, cl_svm_mem_flags flags = CL_MEM_READ_WRITE);
|
||||
|
||||
/**
|
||||
* Release SVM buffer
|
||||
* @param ptr Pointer allocated using ::svmAlloc. If the pointer has been
|
||||
* allocated elsewhere, the behavior is undefined
|
||||
*/
|
||||
void svmFree(void* ptr) const;
|
||||
/**
|
||||
* Release SVM buffer
|
||||
* @param ptr Pointer allocated using ::svmAlloc. If the pointer has been
|
||||
* allocated elsewhere, the behavior is undefined
|
||||
*/
|
||||
void svmFree(void* ptr) const;
|
||||
|
||||
//! Return the devices associated with this context.
|
||||
const std::vector<Device*>& devices() const { return devices_; }
|
||||
//! Return the devices associated with this context.
|
||||
const std::vector<Device*>& devices() const { return devices_; }
|
||||
|
||||
//! Return the SVM capable devices associated with this context.
|
||||
const std::vector<Device*>& svmDevices() const { return svmAllocDevice_; }
|
||||
//! Return the SVM capable devices associated with this context.
|
||||
const std::vector<Device*>& svmDevices() const { return svmAllocDevice_; }
|
||||
|
||||
//! Returns true if the given device is associated with this context.
|
||||
bool containsDevice(const Device* device) const;
|
||||
//! Returns true if the given device is associated with this context.
|
||||
bool containsDevice(const Device* device) const;
|
||||
|
||||
//! Returns the context info structure
|
||||
const Info& info() const { return info_; }
|
||||
//! Returns the context info structure
|
||||
const Info& info() const { return info_; }
|
||||
|
||||
//! Returns a pointer to the original properties
|
||||
const cl_context_properties* properties() const { return properties_; }
|
||||
//! Returns a pointer to the original properties
|
||||
const cl_context_properties* properties() const { return properties_; }
|
||||
|
||||
//! Returns a pointer to the OpenGL context
|
||||
GLFunctions* glenv() const { return glenv_; }
|
||||
//! Returns a pointer to the OpenGL context
|
||||
GLFunctions* glenv() const { return glenv_; }
|
||||
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const { return ObjectTypeContext; }
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const { return ObjectTypeContext; }
|
||||
|
||||
//! Returns context lock for the serialized access to the context
|
||||
Monitor& lock() { return ctxLock_; }
|
||||
//! Returns context lock for the serialized access to the context
|
||||
Monitor& lock() { return ctxLock_; }
|
||||
|
||||
//! Returns TRUE if runtime succesfully added a device queue
|
||||
DeviceQueue* defDeviceQueue(const Device& dev) const;
|
||||
//! Returns TRUE if runtime succesfully added a device queue
|
||||
DeviceQueue* defDeviceQueue(const Device& dev) const;
|
||||
|
||||
//! Returns TRUE if runtime succesfully added a device queue
|
||||
bool isDevQueuePossible(const Device& dev);
|
||||
//! Returns TRUE if runtime succesfully added a device queue
|
||||
bool isDevQueuePossible(const Device& dev);
|
||||
|
||||
//! Returns TRUE if runtime succesfully added a device queue
|
||||
void addDeviceQueue(
|
||||
const Device& dev, //!< Device object
|
||||
DeviceQueue* queue, //!< Device queue
|
||||
bool defDevQueue //!< Added device queue will be the default queue
|
||||
);
|
||||
//! Returns TRUE if runtime succesfully added a device queue
|
||||
void addDeviceQueue(const Device& dev, //!< Device object
|
||||
DeviceQueue* queue, //!< Device queue
|
||||
bool defDevQueue //!< Added device queue will be the default queue
|
||||
);
|
||||
|
||||
//! Removes a device queue from the list of queues
|
||||
void removeDeviceQueue(
|
||||
const Device& dev, //!< Device object
|
||||
DeviceQueue* queue //!< Device queue
|
||||
);
|
||||
//! Removes a device queue from the list of queues
|
||||
void removeDeviceQueue(const Device& dev, //!< Device object
|
||||
DeviceQueue* queue //!< Device queue
|
||||
);
|
||||
|
||||
private:
|
||||
const Info info_; //!< Context info structure
|
||||
cl_context_properties* properties_; //!< Original properties
|
||||
GLFunctions* glenv_; //!< OpenGL context
|
||||
Device* customHostAllocDevice_; //!< Device responsible for host allocations
|
||||
std::vector<Device*> svmAllocDevice_; //!< Devices can support SVM allocations
|
||||
std::map<const Device*, DeviceQueueInfo> deviceQueues_; //!< Device queues mapping
|
||||
Monitor ctxLock_; //!< Lock for the context access
|
||||
private:
|
||||
const Info info_; //!< Context info structure
|
||||
cl_context_properties* properties_; //!< Original properties
|
||||
GLFunctions* glenv_; //!< OpenGL context
|
||||
Device* customHostAllocDevice_; //!< Device responsible for host allocations
|
||||
std::vector<Device*> svmAllocDevice_; //!< Devices can support SVM allocations
|
||||
std::map<const Device*, DeviceQueueInfo> deviceQueues_; //!< Device queues mapping
|
||||
Monitor ctxLock_; //!< Lock for the context access
|
||||
};
|
||||
|
||||
/*! @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
|
||||
#endif /*CONTEXT_HPP_*/
|
||||
@@ -20,14 +20,13 @@ namespace amd {
|
||||
*
|
||||
* \brief The container class for the performance counters
|
||||
*/
|
||||
class Counter : public RuntimeObject
|
||||
{
|
||||
public:
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const {return ObjectTypeCounter;}
|
||||
class Counter : public RuntimeObject {
|
||||
public:
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const { return ObjectTypeCounter; }
|
||||
};
|
||||
|
||||
/*@}*/
|
||||
/*@}*/ } // namespace amd
|
||||
|
||||
#endif // COUNTERS_HPP_
|
||||
#endif // COUNTERS_HPP_
|
||||
@@ -15,36 +15,34 @@ class BufferGL;
|
||||
class D3D10Object;
|
||||
class D3D11Object;
|
||||
class D3D9Object;
|
||||
#endif //_WIN32
|
||||
#endif //_WIN32
|
||||
|
||||
//! Base object providing common map/unmap interface for interop objects
|
||||
class InteropObject
|
||||
{
|
||||
public:
|
||||
//! Virtual destructor to get rid of linux warning
|
||||
virtual ~InteropObject() {}
|
||||
class InteropObject {
|
||||
public:
|
||||
//! Virtual destructor to get rid of linux warning
|
||||
virtual ~InteropObject() {}
|
||||
|
||||
// Static cast functions for interop objects
|
||||
virtual GLObject* asGLObject() { return NULL; }
|
||||
virtual BufferGL* asBufferGL() { return NULL; }
|
||||
// Static cast functions for interop objects
|
||||
virtual GLObject* asGLObject() { return NULL; }
|
||||
virtual BufferGL* asBufferGL() { return NULL; }
|
||||
|
||||
#ifdef _WIN32
|
||||
virtual D3D10Object* asD3D10Object() { return NULL; }
|
||||
virtual D3D11Object* asD3D11Object() { return NULL; }
|
||||
virtual D3D9Object* asD3D9Object() { return NULL; }
|
||||
#endif //_WIN32
|
||||
virtual D3D10Object* asD3D10Object() { return NULL; }
|
||||
virtual D3D11Object* asD3D11Object() { return NULL; }
|
||||
virtual D3D9Object* asD3D9Object() { return NULL; }
|
||||
#endif //_WIN32
|
||||
|
||||
// On acquire copy data from original resource to shared resource
|
||||
virtual bool copyOrigToShared() { return true; }
|
||||
// On release copy data from shared copy to the original resource
|
||||
virtual bool copySharedToOrig() { return true; }
|
||||
// On acquire copy data from original resource to shared resource
|
||||
virtual bool copyOrigToShared() { return true; }
|
||||
// On release copy data from shared copy to the original resource
|
||||
virtual bool copySharedToOrig() { return true; }
|
||||
|
||||
//! Mapping functions for interop objects
|
||||
virtual bool mapExtObjectInCQThread() { return true; }
|
||||
virtual bool unmapExtObjectInCQThread() { return true; }
|
||||
//! Mapping functions for interop objects
|
||||
virtual bool mapExtObjectInCQThread() { return true; }
|
||||
virtual bool unmapExtObjectInCQThread() { return true; }
|
||||
};
|
||||
|
||||
} // namespace amd
|
||||
|
||||
#endif //!INTEROP_H_
|
||||
} // namespace amd
|
||||
|
||||
#endif //! INTEROP_H_
|
||||
@@ -12,240 +12,216 @@
|
||||
namespace amd {
|
||||
|
||||
Kernel::Kernel(Program& program, const Symbol& symbol, const std::string& name)
|
||||
: program_(program), symbol_(symbol), name_(name)
|
||||
{
|
||||
const KernelSignature& s = signature();
|
||||
size_t stackSize = s.paramsSize();
|
||||
parameters_ = new (s) KernelParameters(s);
|
||||
fixme_guarantee(parameters_ != NULL && "out of memory");
|
||||
name_ += '\0';
|
||||
: program_(program), symbol_(symbol), name_(name) {
|
||||
const KernelSignature& s = signature();
|
||||
size_t stackSize = s.paramsSize();
|
||||
parameters_ = new (s) KernelParameters(s);
|
||||
fixme_guarantee(parameters_ != NULL && "out of memory");
|
||||
name_ += '\0';
|
||||
}
|
||||
|
||||
Kernel::~Kernel()
|
||||
{
|
||||
// Release kernel object itself
|
||||
delete parameters_;
|
||||
Kernel::~Kernel() {
|
||||
// Release kernel object itself
|
||||
delete parameters_;
|
||||
}
|
||||
|
||||
const device::Kernel*
|
||||
Kernel::getDeviceKernel(const Device& device, bool noAlias) const
|
||||
{
|
||||
return symbol_.getDeviceKernel(device, noAlias);
|
||||
const device::Kernel* Kernel::getDeviceKernel(const Device& device, bool noAlias) const {
|
||||
return symbol_.getDeviceKernel(device, noAlias);
|
||||
}
|
||||
|
||||
const KernelSignature&
|
||||
Kernel::signature() const
|
||||
{
|
||||
return symbol_.signature();
|
||||
}
|
||||
|
||||
bool
|
||||
KernelParameters::check()
|
||||
{
|
||||
if (validated_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < signature_.numParameters(); ++i) {
|
||||
if (!test(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
validated_ = true;
|
||||
const KernelSignature& Kernel::signature() const { return symbol_.signature(); }
|
||||
|
||||
bool KernelParameters::check() {
|
||||
if (validated_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < signature_.numParameters(); ++i) {
|
||||
if (!test(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
validated_ = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
KernelParameters::localMemSize(size_t minDataTypeAlignment) const
|
||||
{
|
||||
size_t memSize = 0;
|
||||
size_t KernelParameters::localMemSize(size_t minDataTypeAlignment) const {
|
||||
size_t memSize = 0;
|
||||
|
||||
for (size_t i = 0; i < signature_.numParameters(); ++i) {
|
||||
const KernelParameterDescriptor& desc = signature_.at(i);
|
||||
if (desc.size_ == 0) {
|
||||
memSize = alignUp(memSize, minDataTypeAlignment)
|
||||
+ *reinterpret_cast<const size_t*>(values_ + desc.offset_);
|
||||
}
|
||||
for (size_t i = 0; i < signature_.numParameters(); ++i) {
|
||||
const KernelParameterDescriptor& desc = signature_.at(i);
|
||||
if (desc.size_ == 0) {
|
||||
memSize = alignUp(memSize, minDataTypeAlignment) +
|
||||
*reinterpret_cast<const size_t*>(values_ + desc.offset_);
|
||||
}
|
||||
return memSize;
|
||||
}
|
||||
return memSize;
|
||||
}
|
||||
|
||||
void
|
||||
KernelParameters::set(
|
||||
size_t index,
|
||||
size_t size,
|
||||
const void* value,
|
||||
bool svmBound)
|
||||
{
|
||||
const KernelParameterDescriptor& desc = signature_.at(index);
|
||||
void KernelParameters::set(size_t index, size_t size, const void* value, bool svmBound) {
|
||||
const KernelParameterDescriptor& desc = signature_.at(index);
|
||||
|
||||
void* param = values_ + desc.offset_;
|
||||
assert((desc.type_ == T_POINTER || value != NULL || desc.size_ == 0) &&
|
||||
"not a valid local mem arg");
|
||||
void* param = values_ + desc.offset_;
|
||||
assert((desc.type_ == T_POINTER || value != NULL || desc.size_ == 0) &&
|
||||
"not a valid local mem arg");
|
||||
|
||||
uint32_t uint32_value = 0;
|
||||
uint64_t uint64_value = 0;
|
||||
uint32_t uint32_value = 0;
|
||||
uint64_t uint64_value = 0;
|
||||
|
||||
if (desc.type_ == T_POINTER && desc.size_ != 0) {
|
||||
if (svmBound) {
|
||||
LP64_SWITCH(uint32_value, uint64_value) =
|
||||
(LP64_SWITCH(uint32_t, uint64_t)) value;
|
||||
svmBound_[index] = true;
|
||||
}
|
||||
else if ((value == NULL) || (static_cast<const cl_mem*>(value) == NULL)) {
|
||||
LP64_SWITCH(uint32_value, uint64_value) = 0;
|
||||
}
|
||||
else {
|
||||
// convert cl_mem to amd::Memory*
|
||||
LP64_SWITCH(uint32_value, uint64_value) =
|
||||
(uintptr_t) as_amd(*static_cast<const cl_mem*>(value));
|
||||
}
|
||||
if (desc.type_ == T_POINTER && desc.size_ != 0) {
|
||||
if (svmBound) {
|
||||
LP64_SWITCH(uint32_value, uint64_value) = (LP64_SWITCH(uint32_t, uint64_t))value;
|
||||
svmBound_[index] = true;
|
||||
} else if ((value == NULL) || (static_cast<const cl_mem*>(value) == NULL)) {
|
||||
LP64_SWITCH(uint32_value, uint64_value) = 0;
|
||||
} else {
|
||||
// convert cl_mem to amd::Memory*
|
||||
LP64_SWITCH(uint32_value, uint64_value) =
|
||||
(uintptr_t)as_amd(*static_cast<const cl_mem*>(value));
|
||||
}
|
||||
else if (desc.type_ == T_SAMPLER) {
|
||||
// convert cl_sampler to amd::Sampler*
|
||||
amd::Sampler *sampler = as_amd(*static_cast<const cl_sampler*>(value));
|
||||
LP64_SWITCH(uint32_value, uint64_value) = (uintptr_t) sampler;
|
||||
}
|
||||
else if (desc.type_ == T_QUEUE) {
|
||||
// convert cl_command_queue to amd::DeviceQueue*
|
||||
amd::DeviceQueue* queue =
|
||||
as_amd(*static_cast<const cl_command_queue*>(value))->asDeviceQueue();
|
||||
LP64_SWITCH(uint32_value, uint64_value) = (uintptr_t) queue;
|
||||
}
|
||||
else switch (desc.size_) {
|
||||
case 1: uint32_value = *static_cast<const uint8_t*>(value); break;
|
||||
case 2: uint32_value = *static_cast<const uint16_t*>(value); break;
|
||||
case 4: uint32_value = *static_cast<const uint32_t*>(value); break;
|
||||
case 8: uint64_value = *static_cast<const uint64_t*>(value); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
} else if (desc.type_ == T_SAMPLER) {
|
||||
// convert cl_sampler to amd::Sampler*
|
||||
amd::Sampler* sampler = as_amd(*static_cast<const cl_sampler*>(value));
|
||||
LP64_SWITCH(uint32_value, uint64_value) = (uintptr_t)sampler;
|
||||
} else if (desc.type_ == T_QUEUE) {
|
||||
// convert cl_command_queue to amd::DeviceQueue*
|
||||
amd::DeviceQueue* queue = as_amd(*static_cast<const cl_command_queue*>(value))->asDeviceQueue();
|
||||
LP64_SWITCH(uint32_value, uint64_value) = (uintptr_t)queue;
|
||||
} else
|
||||
switch (desc.size_) {
|
||||
case 0 /*local mem*/ : *static_cast<size_t*>(param) = size; break;
|
||||
case sizeof(uint32_t): *static_cast<uint32_t*>(param) = uint32_value; break;
|
||||
case sizeof(uint64_t): *static_cast<uint64_t*>(param) = uint64_value; break;
|
||||
default: ::memcpy(param, value, size); break;
|
||||
case 1:
|
||||
uint32_value = *static_cast<const uint8_t*>(value);
|
||||
break;
|
||||
case 2:
|
||||
uint32_value = *static_cast<const uint16_t*>(value);
|
||||
break;
|
||||
case 4:
|
||||
uint32_value = *static_cast<const uint32_t*>(value);
|
||||
break;
|
||||
case 8:
|
||||
uint64_value = *static_cast<const uint64_t*>(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
defined_[index] = true;
|
||||
switch (desc.size_) {
|
||||
case 0 /*local mem*/:
|
||||
*static_cast<size_t*>(param) = size;
|
||||
break;
|
||||
case sizeof(uint32_t):
|
||||
*static_cast<uint32_t*>(param) = uint32_value;
|
||||
break;
|
||||
case sizeof(uint64_t):
|
||||
*static_cast<uint64_t*>(param) = uint64_value;
|
||||
break;
|
||||
default:
|
||||
::memcpy(param, value, size);
|
||||
break;
|
||||
}
|
||||
|
||||
defined_[index] = true;
|
||||
}
|
||||
|
||||
address
|
||||
KernelParameters::capture(const Device& device)
|
||||
{
|
||||
const size_t stackSize = signature_.paramsSize();
|
||||
//! Information about which arguments are SVM pointers is stored after
|
||||
// the actual parameters, but only if the device has any SVM capability
|
||||
const size_t svmInfoSize = device.info().svmCapabilities_ ?
|
||||
signature_.numParameters() * sizeof(bool) : 0;
|
||||
const size_t execInfoSize = getNumberOfSvmPtr() * sizeof(void*);
|
||||
address mem = (address) AlignedMemory::allocate(
|
||||
stackSize + svmInfoSize + execInfoSize, PARAMETERS_MIN_ALIGNMENT);
|
||||
address KernelParameters::capture(const Device& device) {
|
||||
const size_t stackSize = signature_.paramsSize();
|
||||
//! Information about which arguments are SVM pointers is stored after
|
||||
// the actual parameters, but only if the device has any SVM capability
|
||||
const size_t svmInfoSize =
|
||||
device.info().svmCapabilities_ ? signature_.numParameters() * sizeof(bool) : 0;
|
||||
const size_t execInfoSize = getNumberOfSvmPtr() * sizeof(void*);
|
||||
address mem = (address)AlignedMemory::allocate(stackSize + svmInfoSize + execInfoSize,
|
||||
PARAMETERS_MIN_ALIGNMENT);
|
||||
|
||||
address last = mem + stackSize;
|
||||
if (mem != NULL) {
|
||||
::memcpy(mem, values_, stackSize);
|
||||
|
||||
for (size_t i = 0; i < signature_.numParameters(); ++i) {
|
||||
const KernelParameterDescriptor& desc = signature_.at(i);
|
||||
if (desc.type_ == T_POINTER && desc.size_ != 0 && !svmBound_[i]) {
|
||||
Memory* memArg = *(Memory**)(mem + desc.offset_);
|
||||
if (memArg != NULL) {
|
||||
memArg->retain();
|
||||
}
|
||||
}
|
||||
else if (desc.type_ == T_SAMPLER) {
|
||||
Sampler* samplerArg = *(Sampler**)(mem + desc.offset_);
|
||||
if (samplerArg != NULL) {
|
||||
samplerArg->retain();
|
||||
}
|
||||
}
|
||||
else if (desc.type_ == T_QUEUE) {
|
||||
DeviceQueue* queue = *(DeviceQueue**)(mem + desc.offset_);
|
||||
if (queue != NULL) {
|
||||
queue->retain();
|
||||
}
|
||||
}
|
||||
}
|
||||
::memcpy(last, svmBound_, svmInfoSize);
|
||||
last += svmInfoSize;
|
||||
|
||||
if (0 != execInfoSize) {
|
||||
::memcpy(last, &execSvmPtr_[0], execInfoSize);
|
||||
}
|
||||
execInfoOffset_ = stackSize + svmInfoSize;
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
bool
|
||||
KernelParameters::boundToSvmPointer(const Device& device,
|
||||
const_address capturedParameter,
|
||||
size_t index) const
|
||||
{
|
||||
if (!device.info().svmCapabilities_) {
|
||||
return false;
|
||||
}
|
||||
//! Information about which arguments are SVM pointers is stored after
|
||||
// actual parameters
|
||||
const bool* svmBound = reinterpret_cast<const bool*>(capturedParameter +
|
||||
signature_.paramsSize());
|
||||
return svmBound[index];
|
||||
}
|
||||
|
||||
void
|
||||
KernelParameters::release(address mem, const amd::Device& device) const
|
||||
{
|
||||
if (mem == NULL) {
|
||||
// nothing to do!
|
||||
return;
|
||||
}
|
||||
address last = mem + stackSize;
|
||||
if (mem != NULL) {
|
||||
::memcpy(mem, values_, stackSize);
|
||||
|
||||
for (size_t i = 0; i < signature_.numParameters(); ++i) {
|
||||
const KernelParameterDescriptor& desc = signature_.at(i);
|
||||
if (desc.type_ == T_POINTER && desc.size_ != 0 &&
|
||||
!boundToSvmPointer(device, mem, i)) {
|
||||
Memory* memArg = *(Memory**)(mem + desc.offset_);
|
||||
if (memArg != NULL) {
|
||||
memArg->release();
|
||||
}
|
||||
const KernelParameterDescriptor& desc = signature_.at(i);
|
||||
if (desc.type_ == T_POINTER && desc.size_ != 0 && !svmBound_[i]) {
|
||||
Memory* memArg = *(Memory**)(mem + desc.offset_);
|
||||
if (memArg != NULL) {
|
||||
memArg->retain();
|
||||
}
|
||||
else if (desc.type_ == T_SAMPLER) {
|
||||
Sampler* samplerArg = *(Sampler**)(mem + desc.offset_);
|
||||
if (samplerArg != NULL) {
|
||||
samplerArg->release();
|
||||
}
|
||||
} else if (desc.type_ == T_SAMPLER) {
|
||||
Sampler* samplerArg = *(Sampler**)(mem + desc.offset_);
|
||||
if (samplerArg != NULL) {
|
||||
samplerArg->retain();
|
||||
}
|
||||
else if (desc.type_ == T_QUEUE) {
|
||||
DeviceQueue* queue = *(DeviceQueue**)(mem + desc.offset_);
|
||||
if (queue != NULL) {
|
||||
queue->release();
|
||||
}
|
||||
} else if (desc.type_ == T_QUEUE) {
|
||||
DeviceQueue* queue = *(DeviceQueue**)(mem + desc.offset_);
|
||||
if (queue != NULL) {
|
||||
queue->retain();
|
||||
}
|
||||
}
|
||||
}
|
||||
::memcpy(last, svmBound_, svmInfoSize);
|
||||
last += svmInfoSize;
|
||||
|
||||
AlignedMemory::deallocate(mem);
|
||||
if (0 != execInfoSize) {
|
||||
::memcpy(last, &execSvmPtr_[0], execInfoSize);
|
||||
}
|
||||
execInfoOffset_ = stackSize + svmInfoSize;
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
bool KernelParameters::boundToSvmPointer(const Device& device, const_address capturedParameter,
|
||||
size_t index) const {
|
||||
if (!device.info().svmCapabilities_) {
|
||||
return false;
|
||||
}
|
||||
//! Information about which arguments are SVM pointers is stored after
|
||||
// actual parameters
|
||||
const bool* svmBound = reinterpret_cast<const bool*>(capturedParameter + signature_.paramsSize());
|
||||
return svmBound[index];
|
||||
}
|
||||
|
||||
void KernelParameters::release(address mem, const amd::Device& device) const {
|
||||
if (mem == NULL) {
|
||||
// nothing to do!
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < signature_.numParameters(); ++i) {
|
||||
const KernelParameterDescriptor& desc = signature_.at(i);
|
||||
if (desc.type_ == T_POINTER && desc.size_ != 0 && !boundToSvmPointer(device, mem, i)) {
|
||||
Memory* memArg = *(Memory**)(mem + desc.offset_);
|
||||
if (memArg != NULL) {
|
||||
memArg->release();
|
||||
}
|
||||
} else if (desc.type_ == T_SAMPLER) {
|
||||
Sampler* samplerArg = *(Sampler**)(mem + desc.offset_);
|
||||
if (samplerArg != NULL) {
|
||||
samplerArg->release();
|
||||
}
|
||||
} else if (desc.type_ == T_QUEUE) {
|
||||
DeviceQueue* queue = *(DeviceQueue**)(mem + desc.offset_);
|
||||
if (queue != NULL) {
|
||||
queue->release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AlignedMemory::deallocate(mem);
|
||||
}
|
||||
|
||||
|
||||
KernelSignature::KernelSignature(
|
||||
const std::vector<KernelParameterDescriptor>& params,
|
||||
const std::string& attrib)
|
||||
: params_(params), paramsSize_(0)
|
||||
, attributes_(attrib)
|
||||
{
|
||||
if (params.size() > 0) {
|
||||
KernelParameterDescriptor last = params.back();
|
||||
KernelSignature::KernelSignature(const std::vector<KernelParameterDescriptor>& params,
|
||||
const std::string& attrib)
|
||||
: params_(params), paramsSize_(0), attributes_(attrib) {
|
||||
if (params.size() > 0) {
|
||||
KernelParameterDescriptor last = params.back();
|
||||
|
||||
size_t lastSize = last.size_;
|
||||
if (lastSize == 0 /* local mem */) {
|
||||
lastSize = sizeof(cl_mem);
|
||||
}
|
||||
paramsSize_ = last.offset_ + alignUp(lastSize, sizeof(intptr_t));
|
||||
size_t lastSize = last.size_;
|
||||
if (lastSize == 0 /* local mem */) {
|
||||
lastSize = sizeof(cl_mem);
|
||||
}
|
||||
paramsSize_ = last.offset_ + alignUp(lastSize, sizeof(intptr_t));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace amd
|
||||
|
||||
} // namespace amd
|
||||
@@ -16,9 +16,9 @@
|
||||
#include "device/device.hpp"
|
||||
|
||||
enum FGSStatus {
|
||||
FGS_DEFAULT, //!< The default kernel fine-grained system pointer support
|
||||
FGS_NO, //!< no support of kernel fine-grained system pointer
|
||||
FGS_YES //!< have support of kernel fine-grained system pointer
|
||||
FGS_DEFAULT, //!< The default kernel fine-grained system pointer support
|
||||
FGS_NO, //!< no support of kernel fine-grained system pointer
|
||||
FGS_YES //!< have support of kernel fine-grained system pointer
|
||||
};
|
||||
|
||||
namespace amd {
|
||||
@@ -33,209 +33,199 @@ class Program;
|
||||
* @{
|
||||
*/
|
||||
|
||||
class KernelSignature : public HeapObject
|
||||
{
|
||||
private:
|
||||
std::vector<KernelParameterDescriptor> params_;
|
||||
size_t paramsSize_;
|
||||
std::string attributes_; //!< The kernel attributes
|
||||
class KernelSignature : public HeapObject {
|
||||
private:
|
||||
std::vector<KernelParameterDescriptor> params_;
|
||||
size_t paramsSize_;
|
||||
std::string attributes_; //!< The kernel attributes
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
KernelSignature() : paramsSize_(0) { }
|
||||
public:
|
||||
//! Default constructor
|
||||
KernelSignature() : paramsSize_(0) {}
|
||||
|
||||
//! Construct a new signature.
|
||||
KernelSignature(
|
||||
const std::vector<KernelParameterDescriptor>& params,
|
||||
const std::string& attrib
|
||||
);
|
||||
//! Construct a new signature.
|
||||
KernelSignature(const std::vector<KernelParameterDescriptor>& params, const std::string& attrib);
|
||||
|
||||
//! Return the number of parameters
|
||||
size_t numParameters() const { return params_.size(); }
|
||||
//! Return the number of parameters
|
||||
size_t numParameters() const { return params_.size(); }
|
||||
|
||||
//! Return the parameter descriptor at the given index.
|
||||
const KernelParameterDescriptor& at(size_t index) const
|
||||
{
|
||||
assert(index < params_.size() && "index is out of bounds");
|
||||
return params_[index];
|
||||
}
|
||||
//! Return the parameter descriptor at the given index.
|
||||
const KernelParameterDescriptor& at(size_t index) const {
|
||||
assert(index < params_.size() && "index is out of bounds");
|
||||
return params_[index];
|
||||
}
|
||||
|
||||
//! Return the size in bytes required for the arguments on the stack.
|
||||
size_t paramsSize() const { return paramsSize_; }
|
||||
//! Return the size in bytes required for the arguments on the stack.
|
||||
size_t paramsSize() const { return paramsSize_; }
|
||||
|
||||
//! Return the kernel attributes
|
||||
const std::string& attributes() const { return attributes_; }
|
||||
//! Return the kernel attributes
|
||||
const std::string& attributes() const { return attributes_; }
|
||||
};
|
||||
|
||||
// @todo: look into a copy-on-write model instead of copy-on-read.
|
||||
//
|
||||
class KernelParameters : protected HeapObject
|
||||
{
|
||||
private:
|
||||
//! The signature describing these parameters.
|
||||
const KernelSignature& signature_;
|
||||
class KernelParameters : protected HeapObject {
|
||||
private:
|
||||
//! The signature describing these parameters.
|
||||
const KernelSignature& signature_;
|
||||
|
||||
address values_; //!< pointer to the base of the values stack.
|
||||
bool* defined_; //!< pointer to the isDefined flags.
|
||||
bool* svmBound_; //!< True at 'i' if parameter 'i' is bound to SVM pointer
|
||||
size_t execInfoOffset_; //!< The offset of execInfo
|
||||
std::vector<void*> execSvmPtr_; //!< The non argument svm pointers for kernel
|
||||
FGSStatus svmSystemPointersSupport_; //!< The flag for the status of the kernel
|
||||
// support of fine-grain system sharing.
|
||||
struct
|
||||
{
|
||||
uint32_t validated_ : 1; //!< True if all parameters are defined.
|
||||
uint32_t execNewVcop_ : 1; //!< special new VCOP for kernel execution
|
||||
uint32_t execPfpaVcop_ : 1; //!< special PFPA VCOP for kernel execution
|
||||
uint32_t unused : 29; //!< unused
|
||||
};
|
||||
address values_; //!< pointer to the base of the values stack.
|
||||
bool* defined_; //!< pointer to the isDefined flags.
|
||||
bool* svmBound_; //!< True at 'i' if parameter 'i' is bound to SVM pointer
|
||||
size_t execInfoOffset_; //!< The offset of execInfo
|
||||
std::vector<void*> execSvmPtr_; //!< The non argument svm pointers for kernel
|
||||
FGSStatus svmSystemPointersSupport_; //!< The flag for the status of the kernel
|
||||
// support of fine-grain system sharing.
|
||||
struct {
|
||||
uint32_t validated_ : 1; //!< True if all parameters are defined.
|
||||
uint32_t execNewVcop_ : 1; //!< special new VCOP for kernel execution
|
||||
uint32_t execPfpaVcop_ : 1; //!< special PFPA VCOP for kernel execution
|
||||
uint32_t unused : 29; //!< unused
|
||||
};
|
||||
|
||||
public:
|
||||
public:
|
||||
//! Construct a new instance of parameters for the given signature.
|
||||
KernelParameters(const KernelSignature& signature)
|
||||
: signature_(signature),
|
||||
execInfoOffset_(0),
|
||||
svmSystemPointersSupport_(FGS_DEFAULT),
|
||||
validated_(0),
|
||||
execNewVcop_(0),
|
||||
execPfpaVcop_(0) {
|
||||
values_ = (address) this + alignUp(sizeof(KernelParameters), 16);
|
||||
defined_ = (bool*)(values_ + signature.paramsSize());
|
||||
svmBound_ = (bool*)((address)defined_ + signature.numParameters() * sizeof(bool));
|
||||
|
||||
//! Construct a new instance of parameters for the given signature.
|
||||
KernelParameters(const KernelSignature& signature) :
|
||||
signature_(signature), execInfoOffset_(0), svmSystemPointersSupport_(FGS_DEFAULT),
|
||||
validated_(0), execNewVcop_(0), execPfpaVcop_(0)
|
||||
{
|
||||
values_ = (address) this + alignUp(sizeof(KernelParameters), 16);
|
||||
defined_ = (bool*) (values_ + signature.paramsSize());
|
||||
svmBound_ = (bool*) ((address) defined_ + signature.numParameters() * sizeof(bool));
|
||||
address limit = (address)&svmBound_[signature.numParameters()];
|
||||
::memset(values_, '\0', limit - values_);
|
||||
}
|
||||
|
||||
address limit = (address) &svmBound_[signature.numParameters()];
|
||||
::memset(values_, '\0', limit - values_);
|
||||
//! Reset the parameter at the given \a index (becomes undefined).
|
||||
void reset(size_t index) {
|
||||
defined_[index] = false;
|
||||
svmBound_[index] = false;
|
||||
validated_ = 0;
|
||||
}
|
||||
//! Set the parameter at the given \a index to the value pointed by \a value
|
||||
// \a svmBound indicates that \a value is a SVM pointer.
|
||||
void set(size_t index, size_t size, const void* value, bool svmBound = false);
|
||||
|
||||
//! Return true if the parameter at the given \a index is defined.
|
||||
bool test(size_t index) const { return defined_[index]; }
|
||||
|
||||
//! Return true if all the parameters have been defined.
|
||||
bool check();
|
||||
|
||||
//! The amount of memory required for local memory needed
|
||||
size_t localMemSize(size_t minDataTypeAlignment) const;
|
||||
|
||||
//! Capture the state of the parameters and return the stack base pointer.
|
||||
address capture(const Device& device);
|
||||
//! Release the captured state of the parameters.
|
||||
void release(address parameters, const amd::Device& device) const;
|
||||
|
||||
//! Allocate memory for this instance as well as the required storage for
|
||||
// the values_, defined_, and svmBound_ arrays.
|
||||
void* operator new(size_t size, const KernelSignature& signature) {
|
||||
size_t requiredSize =
|
||||
alignUp(size, 16) + signature.paramsSize() + signature.numParameters() * sizeof(bool) * 2;
|
||||
return AlignedMemory::allocate(requiredSize, PARAMETERS_MIN_ALIGNMENT);
|
||||
}
|
||||
//! Deallocate the memory reserved for this instance.
|
||||
void operator delete(void* ptr) { AlignedMemory::deallocate(ptr); }
|
||||
|
||||
//! Deallocate the memory reserved for this instance,
|
||||
// matching overloaded operator new.
|
||||
void operator delete(void* ptr, const KernelSignature& signature) {
|
||||
AlignedMemory::deallocate(ptr);
|
||||
}
|
||||
|
||||
//! Returns raw kernel parameters without capture
|
||||
address values() const { return values_; }
|
||||
|
||||
//! Return true if the captured parameter at the given \a index is bound to
|
||||
// SVM pointer.
|
||||
bool boundToSvmPointer(const Device& device, const_address capturedAddress, size_t index) const;
|
||||
//! add the svmPtr execInfo into container
|
||||
void addSvmPtr(void* const* execInfoArray, size_t count) {
|
||||
execSvmPtr_.clear();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
execSvmPtr_.push_back(execInfoArray[i]);
|
||||
}
|
||||
}
|
||||
//! get the number of svmPtr in the execInfo container
|
||||
size_t getNumberOfSvmPtr() const { return execSvmPtr_.size(); }
|
||||
|
||||
//! Reset the parameter at the given \a index (becomes undefined).
|
||||
void reset(size_t index)
|
||||
{
|
||||
defined_[index] = false;
|
||||
svmBound_[index] = false;
|
||||
validated_ = 0;
|
||||
}
|
||||
//! Set the parameter at the given \a index to the value pointed by \a value
|
||||
// \a svmBound indicates that \a value is a SVM pointer.
|
||||
void set(size_t index, size_t size, const void* value, bool svmBound = false);
|
||||
//! get the number of svmPtr in the execInfo container
|
||||
size_t getExecInfoOffset() const { return execInfoOffset_; }
|
||||
|
||||
//! Return true if the parameter at the given \a index is defined.
|
||||
bool test(size_t index) const { return defined_[index]; }
|
||||
//! set the status of kernel support fine-grained SVM system pointer sharing
|
||||
void setSvmSystemPointersSupport(FGSStatus svmSystemSupport) {
|
||||
svmSystemPointersSupport_ = svmSystemSupport;
|
||||
}
|
||||
|
||||
//! Return true if all the parameters have been defined.
|
||||
bool check();
|
||||
//! return the status of kernel support fine-grained SVM system pointer sharing
|
||||
FGSStatus getSvmSystemPointersSupport() const { return svmSystemPointersSupport_; }
|
||||
|
||||
//! The amount of memory required for local memory needed
|
||||
size_t localMemSize(size_t minDataTypeAlignment) const;
|
||||
//! set the new VCOP in the execInfo container
|
||||
void setExecNewVcop(const bool newVcop) { execNewVcop_ = (newVcop == true); }
|
||||
|
||||
//! Capture the state of the parameters and return the stack base pointer.
|
||||
address capture(const Device& device);
|
||||
//! Release the captured state of the parameters.
|
||||
void release(address parameters, const amd::Device& device) const;
|
||||
//! set the PFPA VCOP in the execInfo container
|
||||
void setExecPfpaVcop(const bool pfpaVcop) { execPfpaVcop_ = (pfpaVcop == true); }
|
||||
|
||||
//! Allocate memory for this instance as well as the required storage for
|
||||
// the values_, defined_, and svmBound_ arrays.
|
||||
void* operator new(size_t size, const KernelSignature& signature)
|
||||
{
|
||||
size_t requiredSize = alignUp(size, 16)
|
||||
+ signature.paramsSize()
|
||||
+ signature.numParameters() * sizeof(bool) * 2;
|
||||
return AlignedMemory::allocate(requiredSize, PARAMETERS_MIN_ALIGNMENT);
|
||||
}
|
||||
//! Deallocate the memory reserved for this instance.
|
||||
void operator delete(void * ptr) { AlignedMemory::deallocate(ptr); }
|
||||
//! get the new VCOP in the execInfo container
|
||||
bool getExecNewVcop() const { return (execNewVcop_ == 1); }
|
||||
|
||||
//! Deallocate the memory reserved for this instance,
|
||||
// matching overloaded operator new.
|
||||
void operator delete(void * ptr, const KernelSignature& signature)
|
||||
{ AlignedMemory::deallocate(ptr); }
|
||||
|
||||
//! Returns raw kernel parameters without capture
|
||||
address values() const { return values_; }
|
||||
|
||||
//! Return true if the captured parameter at the given \a index is bound to
|
||||
// SVM pointer.
|
||||
bool boundToSvmPointer(const Device& device,
|
||||
const_address capturedAddress,
|
||||
size_t index) const;
|
||||
//! add the svmPtr execInfo into container
|
||||
void addSvmPtr(void* const* execInfoArray, size_t count)
|
||||
{
|
||||
execSvmPtr_.clear();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
execSvmPtr_.push_back(execInfoArray[i]);
|
||||
}
|
||||
}
|
||||
//! get the number of svmPtr in the execInfo container
|
||||
size_t getNumberOfSvmPtr() const {return execSvmPtr_.size();}
|
||||
|
||||
//! get the number of svmPtr in the execInfo container
|
||||
size_t getExecInfoOffset() const {return execInfoOffset_;}
|
||||
|
||||
//! set the status of kernel support fine-grained SVM system pointer sharing
|
||||
void setSvmSystemPointersSupport(FGSStatus svmSystemSupport) { svmSystemPointersSupport_ = svmSystemSupport; }
|
||||
|
||||
//! return the status of kernel support fine-grained SVM system pointer sharing
|
||||
FGSStatus getSvmSystemPointersSupport() const { return svmSystemPointersSupport_; }
|
||||
|
||||
//! set the new VCOP in the execInfo container
|
||||
void setExecNewVcop(const bool newVcop) { execNewVcop_ = (newVcop == true); }
|
||||
|
||||
//! set the PFPA VCOP in the execInfo container
|
||||
void setExecPfpaVcop(const bool pfpaVcop) { execPfpaVcop_ = (pfpaVcop == true); }
|
||||
|
||||
//! get the new VCOP in the execInfo container
|
||||
bool getExecNewVcop() const { return (execNewVcop_ == 1); }
|
||||
|
||||
//! get the PFPA VCOP in the execInfo container
|
||||
bool getExecPfpaVcop() const { return (execPfpaVcop_ == 1); }
|
||||
//! get the PFPA VCOP in the execInfo container
|
||||
bool getExecPfpaVcop() const { return (execPfpaVcop_ == 1); }
|
||||
};
|
||||
|
||||
/*! \brief Encapsulates a __kernel function and the argument values
|
||||
* to be used when invoking this function.
|
||||
*/
|
||||
class Kernel : public RuntimeObject
|
||||
{
|
||||
private:
|
||||
//! The program where this kernel is defined.
|
||||
SharedReference<Program> program_;
|
||||
class Kernel : public RuntimeObject {
|
||||
private:
|
||||
//! The program where this kernel is defined.
|
||||
SharedReference<Program> program_;
|
||||
|
||||
const Symbol& symbol_; //!< The symbol for this kernel.
|
||||
std::string name_; //!< The kernel's name.
|
||||
KernelParameters* parameters_; //!< The parameters.
|
||||
const Symbol& symbol_; //!< The symbol for this kernel.
|
||||
std::string name_; //!< The kernel's name.
|
||||
KernelParameters* parameters_; //!< The parameters.
|
||||
|
||||
protected:
|
||||
//! Destroy this kernel
|
||||
~Kernel();
|
||||
protected:
|
||||
//! Destroy this kernel
|
||||
~Kernel();
|
||||
|
||||
public:
|
||||
/*! \brief Construct a kernel object from the __kernel function
|
||||
* \a kernelName in the given \a program.
|
||||
*/
|
||||
Kernel(Program& program, const Symbol& symbol, const std::string& name);
|
||||
public:
|
||||
/*! \brief Construct a kernel object from the __kernel function
|
||||
* \a kernelName in the given \a program.
|
||||
*/
|
||||
Kernel(Program& program, const Symbol& symbol, const std::string& name);
|
||||
|
||||
//! Return the program containing this kernel.
|
||||
Program& program() const { return program_(); }
|
||||
//! Return the program containing this kernel.
|
||||
Program& program() const { return program_(); }
|
||||
|
||||
//! Return this kernel's signature.
|
||||
const KernelSignature& signature() const;
|
||||
//! Return this kernel's signature.
|
||||
const KernelSignature& signature() const;
|
||||
|
||||
//! Return the kernel entry point for the given device.
|
||||
const device::Kernel* getDeviceKernel(
|
||||
const Device& device, //!< Device object
|
||||
bool noAlias = true //!< Controls alias optimization
|
||||
) const;
|
||||
//! Return the kernel entry point for the given device.
|
||||
const device::Kernel* getDeviceKernel(const Device& device, //!< Device object
|
||||
bool noAlias = true //!< Controls alias optimization
|
||||
) const;
|
||||
|
||||
//! Return the parameters.
|
||||
KernelParameters& parameters() const { return *parameters_; }
|
||||
//! Return the parameters.
|
||||
KernelParameters& parameters() const { return *parameters_; }
|
||||
|
||||
//! Return the kernel's name.
|
||||
const std::string& name() const { return name_; }
|
||||
//! Return the kernel's name.
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
virtual ObjectType objectType() const {return ObjectTypeKernel;}
|
||||
virtual ObjectType objectType() const { return ObjectTypeKernel; }
|
||||
};
|
||||
|
||||
/*! @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
|
||||
#endif /*KERNEL_HPP_*/
|
||||
+1092
-1286
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -6,65 +6,47 @@
|
||||
|
||||
namespace amd {
|
||||
|
||||
NDRange::NDRange(size_t dimensions)
|
||||
: dimensions_(dimensions)
|
||||
{
|
||||
*this = 0;
|
||||
NDRange::NDRange(size_t dimensions) : dimensions_(dimensions) { *this = 0; }
|
||||
|
||||
NDRange::NDRange(const NDRange& space) : dimensions_(space.dimensions_) { *this = space; }
|
||||
|
||||
NDRange& NDRange::operator=(size_t x) {
|
||||
for (size_t i = 0; i < dimensions_; ++i) {
|
||||
data_[i] = x;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
NDRange::NDRange(const NDRange& space)
|
||||
: dimensions_(space.dimensions_)
|
||||
{
|
||||
*this = space;
|
||||
}
|
||||
NDRange::~NDRange() {}
|
||||
|
||||
NDRange&
|
||||
NDRange::operator = (size_t x)
|
||||
{
|
||||
for (size_t i = 0; i < dimensions_; ++i) {
|
||||
data_[i] = x;
|
||||
bool NDRange::operator==(const NDRange& x) const {
|
||||
assert(dimensions_ == x.dimensions_ && "dimensions mismatch");
|
||||
|
||||
for (size_t i = 0; i < dimensions_; ++i) {
|
||||
if (data_[i] != x.data_[i]) {
|
||||
return false;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NDRange::~NDRange()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
NDRange::operator == (const NDRange& x) const
|
||||
{
|
||||
assert(dimensions_ == x.dimensions_ && "dimensions mismatch");
|
||||
|
||||
for (size_t i = 0; i < dimensions_; ++i) {
|
||||
if (data_[i] != x.data_[i]) {
|
||||
return false;
|
||||
}
|
||||
bool NDRange::operator==(size_t x) const {
|
||||
for (size_t i = 0; i < dimensions_; ++i) {
|
||||
if (data_[i] != x) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
NDRange::operator == (size_t x) const
|
||||
{
|
||||
for (size_t i = 0; i < dimensions_; ++i) {
|
||||
if (data_[i] != x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
NDRange::printOn(FILE* file) const
|
||||
{
|
||||
fprintf(file, "[");
|
||||
for (size_t i = dimensions_ - 1; i > 0; --i) {
|
||||
fprintf(file, SIZE_T_FMT ", ", data_[i]);
|
||||
}
|
||||
fprintf(file, SIZE_T_FMT "]", data_[0]);
|
||||
void NDRange::printOn(FILE* file) const {
|
||||
fprintf(file, "[");
|
||||
for (size_t i = dimensions_ - 1; i > 0; --i) {
|
||||
fprintf(file, SIZE_T_FMT ", ", data_[i]);
|
||||
}
|
||||
fprintf(file, SIZE_T_FMT "]", data_[0]);
|
||||
}
|
||||
#endif // DEBUG
|
||||
#endif // DEBUG
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
@@ -10,8 +10,8 @@
|
||||
#include <valarray>
|
||||
|
||||
#ifdef DEBUG
|
||||
# include <cstdio>
|
||||
#endif // DEBUG
|
||||
#include <cstdio>
|
||||
#endif // DEBUG
|
||||
|
||||
namespace amd {
|
||||
|
||||
@@ -23,182 +23,159 @@ namespace amd {
|
||||
*/
|
||||
|
||||
//! An N-dimensions index space.
|
||||
class NDRange : public EmbeddedObject
|
||||
{
|
||||
private:
|
||||
class NDRange : public EmbeddedObject {
|
||||
private:
|
||||
const size_t dimensions_ : 2; //!< Number of dimensions [0-3]
|
||||
size_t data_[3]; //!< indexes array
|
||||
|
||||
const size_t dimensions_ : 2; //!< Number of dimensions [0-3]
|
||||
size_t data_[3]; //!< indexes array
|
||||
|
||||
private:
|
||||
|
||||
//! Construct a new index space for an array of elements (no-copy)
|
||||
NDRange(size_t dimensions, size_t* elements)
|
||||
: dimensions_(dimensions)
|
||||
{
|
||||
for (uint i = 0; i < dimensions_; ++i) {
|
||||
data_[i] = elements[i];
|
||||
}
|
||||
private:
|
||||
//! Construct a new index space for an array of elements (no-copy)
|
||||
NDRange(size_t dimensions, size_t* elements) : dimensions_(dimensions) {
|
||||
for (uint i = 0; i < dimensions_; ++i) {
|
||||
data_[i] = elements[i];
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
//! Construct a new index space of the given dimensions.
|
||||
explicit NDRange(size_t dimensions);
|
||||
public:
|
||||
//! Construct a new index space of the given dimensions.
|
||||
explicit NDRange(size_t dimensions);
|
||||
|
||||
//! Copy constructor.
|
||||
NDRange(const NDRange& space);
|
||||
//! Copy constructor.
|
||||
NDRange(const NDRange& space);
|
||||
|
||||
//! Destroy the index space.
|
||||
~NDRange();
|
||||
//! Destroy the index space.
|
||||
~NDRange();
|
||||
|
||||
//! Copy operator
|
||||
inline NDRange& operator = (const NDRange& space);
|
||||
//! Copy operator
|
||||
inline NDRange& operator=(const NDRange& space);
|
||||
|
||||
//! Make all elements of this space equal to x.
|
||||
NDRange& operator = (size_t x);
|
||||
//! Make all elements of this space equal to x.
|
||||
NDRange& operator=(size_t x);
|
||||
|
||||
//! Return the number of dimensions.
|
||||
size_t dimensions() const { return dimensions_; }
|
||||
//! Return the number of dimensions.
|
||||
size_t dimensions() const { return dimensions_; }
|
||||
|
||||
//! Return the element at the given \a index.
|
||||
size_t& operator [] (size_t index)
|
||||
{
|
||||
assert(index < dimensions_ && "index is out of bounds");
|
||||
return data_[index];
|
||||
}
|
||||
//! Return the element at the given \a index.
|
||||
size_t& operator[](size_t index) {
|
||||
assert(index < dimensions_ && "index is out of bounds");
|
||||
return data_[index];
|
||||
}
|
||||
|
||||
//! Return the element at the given \a index.
|
||||
size_t operator [] (size_t index) const
|
||||
{
|
||||
assert(index < dimensions_ && "index is out of bounds");
|
||||
return data_[index];
|
||||
}
|
||||
//! Return the element at the given \a index.
|
||||
size_t operator[](size_t index) const {
|
||||
assert(index < dimensions_ && "index is out of bounds");
|
||||
return data_[index];
|
||||
}
|
||||
|
||||
//! Return the sum of this index space elements.
|
||||
inline size_t sum() const;
|
||||
//! Return the sum of this index space elements.
|
||||
inline size_t sum() const;
|
||||
|
||||
//! Return the product of this index space elements (size)
|
||||
inline size_t product() const;
|
||||
//! Return the product of this index space elements (size)
|
||||
inline size_t product() const;
|
||||
|
||||
// Binary operators:
|
||||
inline friend NDRange operator + (const NDRange& x, const NDRange& y);
|
||||
inline friend NDRange operator - (const NDRange& x, const NDRange& y);
|
||||
inline friend NDRange operator * (const NDRange& x, const NDRange& y);
|
||||
inline friend NDRange operator / (const NDRange& x, const NDRange& y);
|
||||
inline friend NDRange operator % (const NDRange& x, const NDRange& y);
|
||||
// Binary operators:
|
||||
inline friend NDRange operator+(const NDRange& x, const NDRange& y);
|
||||
inline friend NDRange operator-(const NDRange& x, const NDRange& y);
|
||||
inline friend NDRange operator*(const NDRange& x, const NDRange& y);
|
||||
inline friend NDRange operator/(const NDRange& x, const NDRange& y);
|
||||
inline friend NDRange operator%(const NDRange& x, const NDRange& y);
|
||||
|
||||
//! Return true if this index space is identical to \a x.
|
||||
bool operator == (const NDRange& x) const;
|
||||
//! Return true if this index space is identical to \a x.
|
||||
bool operator==(const NDRange& x) const;
|
||||
|
||||
//! Return true if this index space and \a x are different.
|
||||
bool operator != (const NDRange& x) const { return !(*this == x); }
|
||||
//! Return true if this index space and \a x are different.
|
||||
bool operator!=(const NDRange& x) const { return !(*this == x); }
|
||||
|
||||
//! Return true if all elements are equal to \a x.
|
||||
bool operator == (size_t x) const;
|
||||
//! Return true if all elements are equal to \a x.
|
||||
bool operator==(size_t x) const;
|
||||
|
||||
//! Return true if one element of this space is not equal to \a x.
|
||||
bool operator != (size_t x) const { return !(*this == x); }
|
||||
//! Return true if one element of this space is not equal to \a x.
|
||||
bool operator!=(size_t x) const { return !(*this == x); }
|
||||
|
||||
#ifdef DEBUG
|
||||
//! Print this index space on the given stream.
|
||||
void printOn(FILE* file) const;
|
||||
#endif // DEBUG
|
||||
|
||||
//! Print this index space on the given stream.
|
||||
void printOn(FILE* file) const;
|
||||
#endif // DEBUG
|
||||
};
|
||||
|
||||
//! A container for the local and global worksizes.
|
||||
class NDRangeContainer : public HeapObject
|
||||
{
|
||||
private:
|
||||
const size_t dimensions_; //!< Number of dimensions.
|
||||
NDRange offset_; //!< Global work-item offset.
|
||||
NDRange global_; //!< Total number of work-items in N-dims
|
||||
NDRange local_; //!< Number of work-items in N-dims in a workgroup.
|
||||
class NDRangeContainer : public HeapObject {
|
||||
private:
|
||||
const size_t dimensions_; //!< Number of dimensions.
|
||||
NDRange offset_; //!< Global work-item offset.
|
||||
NDRange global_; //!< Total number of work-items in N-dims
|
||||
NDRange local_; //!< Number of work-items in N-dims in a workgroup.
|
||||
|
||||
public:
|
||||
/*! \brief Construct a new nd-range container with the given local
|
||||
* and global worksizes in \a nDimensions dimensions.
|
||||
*/
|
||||
NDRangeContainer(
|
||||
size_t dimensions,
|
||||
const size_t* globalWorkOffset,
|
||||
const size_t* globalWorkSize,
|
||||
const size_t* localWorkSize
|
||||
) : dimensions_(dimensions),
|
||||
offset_(dimensions), global_(dimensions), local_(dimensions)
|
||||
{
|
||||
for (size_t i = 0; i < dimensions; ++i) {
|
||||
offset_[i] = globalWorkOffset != NULL ? globalWorkOffset[i] : 0;
|
||||
global_[i] = globalWorkSize[i];
|
||||
local_[i] = localWorkSize[i];
|
||||
}
|
||||
public:
|
||||
/*! \brief Construct a new nd-range container with the given local
|
||||
* and global worksizes in \a nDimensions dimensions.
|
||||
*/
|
||||
NDRangeContainer(size_t dimensions, const size_t* globalWorkOffset, const size_t* globalWorkSize,
|
||||
const size_t* localWorkSize)
|
||||
: dimensions_(dimensions), offset_(dimensions), global_(dimensions), local_(dimensions) {
|
||||
for (size_t i = 0; i < dimensions; ++i) {
|
||||
offset_[i] = globalWorkOffset != NULL ? globalWorkOffset[i] : 0;
|
||||
global_[i] = globalWorkSize[i];
|
||||
local_[i] = localWorkSize[i];
|
||||
}
|
||||
}
|
||||
|
||||
//! Return the number of dimensions.
|
||||
size_t dimensions() const { return dimensions_; }
|
||||
//! Return the number of dimensions.
|
||||
size_t dimensions() const { return dimensions_; }
|
||||
|
||||
//! Return the global workoffset.
|
||||
const NDRange& offset() const { return offset_; }
|
||||
NDRange& offset() { return offset_; }
|
||||
//! Return the global worksize.
|
||||
const NDRange& global() const { return global_; }
|
||||
NDRange& global() { return global_; }
|
||||
//! Return the local worksize.
|
||||
const NDRange& local() const { return local_; }
|
||||
NDRange& local() { return local_; }
|
||||
//! Return the global workoffset.
|
||||
const NDRange& offset() const { return offset_; }
|
||||
NDRange& offset() { return offset_; }
|
||||
//! Return the global worksize.
|
||||
const NDRange& global() const { return global_; }
|
||||
NDRange& global() { return global_; }
|
||||
//! Return the local worksize.
|
||||
const NDRange& local() const { return local_; }
|
||||
NDRange& local() { return local_; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*! @}\
|
||||
* @}
|
||||
*/
|
||||
|
||||
inline size_t
|
||||
NDRange::sum() const
|
||||
{
|
||||
size_t result = data_[0];
|
||||
for (size_t i = 1; i < dimensions_; ++i) {
|
||||
result += data_[i];
|
||||
}
|
||||
return result;
|
||||
inline size_t NDRange::sum() const {
|
||||
size_t result = data_[0];
|
||||
for (size_t i = 1; i < dimensions_; ++i) {
|
||||
result += data_[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline size_t
|
||||
NDRange::product() const
|
||||
{
|
||||
size_t result = data_[0];
|
||||
for (size_t i = 1; i < dimensions_; ++i) {
|
||||
result *= data_[i];
|
||||
}
|
||||
return result;
|
||||
inline size_t NDRange::product() const {
|
||||
size_t result = data_[0];
|
||||
for (size_t i = 1; i < dimensions_; ++i) {
|
||||
result *= data_[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// This function is in this header file for performance improvements:
|
||||
inline NDRange&
|
||||
NDRange::operator = (const NDRange& space)
|
||||
{
|
||||
assert(dimensions_ == space.dimensions_ && "dimensions mismatch");
|
||||
for (size_t i = 0; i < sizeof(data_)/sizeof(*data_); ++i) {
|
||||
data_[i] = space.data_[i];
|
||||
}
|
||||
return *this;
|
||||
inline NDRange& NDRange::operator=(const NDRange& space) {
|
||||
assert(dimensions_ == space.dimensions_ && "dimensions mismatch");
|
||||
for (size_t i = 0; i < sizeof(data_) / sizeof(*data_); ++i) {
|
||||
data_[i] = space.data_[i];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
#define DEFINE_NDRANGE_BINARY_OP(op) \
|
||||
inline NDRange \
|
||||
operator op (const NDRange& x, const NDRange& y) \
|
||||
{ \
|
||||
assert(x.dimensions_ == y.dimensions_ && "dimensions mismatch"); \
|
||||
\
|
||||
size_t dimensions = x.dimensions_; \
|
||||
size_t result[3] = {0}; \
|
||||
for (size_t i = 0; i < dimensions; ++i) { \
|
||||
result[i] = x.data_[i] op y.data_[i]; \
|
||||
} \
|
||||
\
|
||||
return NDRange(dimensions, &result[0]); \
|
||||
}
|
||||
#define DEFINE_NDRANGE_BINARY_OP(op) \
|
||||
inline NDRange operator op(const NDRange& x, const NDRange& y) { \
|
||||
assert(x.dimensions_ == y.dimensions_ && "dimensions mismatch"); \
|
||||
\
|
||||
size_t dimensions = x.dimensions_; \
|
||||
size_t result[3] = {0}; \
|
||||
for (size_t i = 0; i < dimensions; ++i) { \
|
||||
result[i] = x.data_[i] op y.data_[i]; \
|
||||
} \
|
||||
\
|
||||
return NDRange(dimensions, &result[0]); \
|
||||
}
|
||||
|
||||
DEFINE_NDRANGE_BINARY_OP(+);
|
||||
DEFINE_NDRANGE_BINARY_OP(-);
|
||||
@@ -208,6 +185,6 @@ DEFINE_NDRANGE_BINARY_OP(%);
|
||||
|
||||
#undef DEFINE_NDRANGE_BINARY_OP
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
|
||||
#endif /*NDRANGE_HPP_*/
|
||||
@@ -8,81 +8,68 @@
|
||||
|
||||
namespace amd {
|
||||
|
||||
Atomic<ObjectMetadata::Key>
|
||||
ObjectMetadata::nextKey_ = 1;
|
||||
Atomic<ObjectMetadata::Key> ObjectMetadata::nextKey_ = 1;
|
||||
|
||||
|
||||
ObjectMetadata::Destructor
|
||||
ObjectMetadata::destructors_[OCL_MAX_KEYS] = { NULL };
|
||||
ObjectMetadata::Destructor ObjectMetadata::destructors_[OCL_MAX_KEYS] = {NULL};
|
||||
|
||||
|
||||
bool
|
||||
ObjectMetadata::check(Key key)
|
||||
{
|
||||
return key > 0 && key <= OCL_MAX_KEYS;
|
||||
bool ObjectMetadata::check(Key key) { return key > 0 && key <= OCL_MAX_KEYS; }
|
||||
|
||||
ObjectMetadata::Key ObjectMetadata::createKey(Destructor destructor) {
|
||||
Key key = nextKey_++;
|
||||
|
||||
if (!check(key)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
destructors_[key - 1] = destructor;
|
||||
return key;
|
||||
}
|
||||
|
||||
ObjectMetadata::Key
|
||||
ObjectMetadata::createKey(Destructor destructor)
|
||||
{
|
||||
Key key = nextKey_++;
|
||||
ObjectMetadata::~ObjectMetadata() {
|
||||
if (!values_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!check(key)) {
|
||||
return 0;
|
||||
for (size_t i = 0; i < OCL_MAX_KEYS; ++i) {
|
||||
if (values_[i] && destructors_[i]) {
|
||||
destructors_[i](values_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
destructors_[key-1] = destructor;
|
||||
return key;
|
||||
delete[] values_;
|
||||
}
|
||||
|
||||
ObjectMetadata::~ObjectMetadata()
|
||||
{
|
||||
if (!values_) {
|
||||
return;
|
||||
}
|
||||
void* ObjectMetadata::getValueForKey(Key key) const {
|
||||
if (!values_ || !check(key)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < OCL_MAX_KEYS; ++i) {
|
||||
if (values_[i] && destructors_[i]) {
|
||||
destructors_[i](values_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] values_;
|
||||
return values_[key - 1];
|
||||
}
|
||||
|
||||
void*
|
||||
ObjectMetadata::getValueForKey(Key key) const
|
||||
{
|
||||
if (!values_ || !check(key)) {
|
||||
return NULL;
|
||||
}
|
||||
bool ObjectMetadata::setValueForKey(Key key, Value value) {
|
||||
if (!check(key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return values_[key-1];
|
||||
while (!values_) {
|
||||
Value* values = new Value[OCL_MAX_KEYS];
|
||||
memset(values, '\0', sizeof(Value) * OCL_MAX_KEYS);
|
||||
|
||||
if (!values_.compareAndSet(NULL, values)) {
|
||||
delete[] values;
|
||||
}
|
||||
}
|
||||
|
||||
size_t index = key - 1;
|
||||
Value prev = AtomicOperation::swap(value, &values_[index]);
|
||||
if (prev && destructors_[index] != NULL) {
|
||||
destructors_[index](prev);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ObjectMetadata::setValueForKey(Key key, Value value)
|
||||
{
|
||||
if (!check(key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!values_) {
|
||||
Value* values = new Value[OCL_MAX_KEYS];
|
||||
memset(values, '\0', sizeof(Value) * OCL_MAX_KEYS);
|
||||
|
||||
if (!values_.compareAndSet(NULL, values)) {
|
||||
delete[] values;
|
||||
}
|
||||
}
|
||||
|
||||
size_t index = key-1;
|
||||
Value prev = AtomicOperation::swap(value, &values_[index]);
|
||||
if (prev && destructors_[index] != NULL) {
|
||||
destructors_[index](prev);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
@@ -10,27 +10,30 @@
|
||||
#include "thread/monitor.hpp"
|
||||
#include "utils/util.hpp"
|
||||
|
||||
#define CL_TYPES_DO(F) \
|
||||
/* OpenCL type Runtime type */ \
|
||||
F(cl_context, Context) \
|
||||
F(cl_event, Event) \
|
||||
F(cl_command_queue, CommandQueue) \
|
||||
F(cl_kernel, Kernel) \
|
||||
F(cl_program, Program) \
|
||||
F(cl_device_id, Device) \
|
||||
F(cl_mem, Memory) \
|
||||
F(cl_sampler, Sampler) \
|
||||
F(cl_counter_amd, Counter) \
|
||||
F(cl_perfcounter_amd, PerfCounter) \
|
||||
F(cl_threadtrace_amd, ThreadTrace) \
|
||||
F(cl_file_amd, LiquidFlashFile)
|
||||
#define CL_TYPES_DO(F) \
|
||||
/* OpenCL type Runtime type */ \
|
||||
F(cl_context, Context) \
|
||||
F(cl_event, Event) \
|
||||
F(cl_command_queue, CommandQueue) \
|
||||
F(cl_kernel, Kernel) \
|
||||
F(cl_program, Program) \
|
||||
F(cl_device_id, Device) \
|
||||
F(cl_mem, Memory) \
|
||||
F(cl_sampler, Sampler) \
|
||||
F(cl_counter_amd, Counter) \
|
||||
F(cl_perfcounter_amd, PerfCounter) \
|
||||
F(cl_threadtrace_amd, ThreadTrace) \
|
||||
F(cl_file_amd, LiquidFlashFile)
|
||||
|
||||
// Forward declare ::cl_* types and amd::Class types
|
||||
//
|
||||
|
||||
#define DECLARE_CL_TYPES(CL,AMD) \
|
||||
namespace amd { class AMD; } \
|
||||
typedef struct _##CL { } * CL;
|
||||
#define DECLARE_CL_TYPES(CL, AMD) \
|
||||
namespace amd { \
|
||||
class AMD; \
|
||||
} \
|
||||
typedef struct _##CL { \
|
||||
} * CL;
|
||||
|
||||
CL_TYPES_DO(DECLARE_CL_TYPES);
|
||||
|
||||
@@ -43,178 +46,127 @@ namespace amd {
|
||||
// Define the cl_*_type tokens for type checking.
|
||||
//
|
||||
|
||||
#define DEFINE_CL_TOKENS(CL,ignored) T##CL,
|
||||
#define DEFINE_CL_TOKENS(CL, ignored) T##CL,
|
||||
|
||||
enum cl_token
|
||||
{
|
||||
Tinvalid = 0,
|
||||
CL_TYPES_DO(DEFINE_CL_TOKENS)
|
||||
numTokens
|
||||
};
|
||||
enum cl_token { Tinvalid = 0, CL_TYPES_DO(DEFINE_CL_TOKENS) numTokens };
|
||||
|
||||
#undef DEFINE_CL_TOKENS
|
||||
|
||||
const size_t RuntimeObjectAlignment =
|
||||
NextPowerOfTwo<numTokens>::value;
|
||||
const size_t RuntimeObjectAlignment = NextPowerOfTwo<numTokens>::value;
|
||||
|
||||
//! \cond ignore
|
||||
template <typename T>
|
||||
struct as_internal
|
||||
{ typedef void type; };
|
||||
template <typename T> struct as_internal { typedef void type; };
|
||||
|
||||
template <typename T>
|
||||
struct as_external
|
||||
{ typedef void type; };
|
||||
template <typename T> struct as_external { typedef void type; };
|
||||
|
||||
template <typename T>
|
||||
struct class_token
|
||||
{ static const cl_token value = Tinvalid; };
|
||||
template <typename T> struct class_token { static const cl_token value = Tinvalid; };
|
||||
|
||||
#define DEFINE_CL_TRAITS(CL,AMD) \
|
||||
\
|
||||
template <> \
|
||||
struct class_token<AMD> \
|
||||
{ static const cl_token value = T##CL; }; \
|
||||
\
|
||||
template <> \
|
||||
struct as_internal<_##CL> \
|
||||
{ typedef AMD type; }; \
|
||||
template <> \
|
||||
struct as_internal<const _##CL> \
|
||||
{ typedef AMD const type; }; \
|
||||
\
|
||||
template <> \
|
||||
struct as_external<AMD> \
|
||||
{ typedef _##CL type; }; \
|
||||
template <> \
|
||||
struct as_external<const AMD> \
|
||||
{ typedef _##CL const type; };
|
||||
#define DEFINE_CL_TRAITS(CL, AMD) \
|
||||
\
|
||||
template <> struct class_token<AMD> { static const cl_token value = T##CL; }; \
|
||||
\
|
||||
template <> struct as_internal<_##CL> { typedef AMD type; }; \
|
||||
template <> struct as_internal<const _##CL> { typedef AMD const type; }; \
|
||||
\
|
||||
template <> struct as_external<AMD> { typedef _##CL type; }; \
|
||||
template <> struct as_external<const AMD> { typedef _##CL const type; };
|
||||
|
||||
CL_TYPES_DO(DEFINE_CL_TRAITS);
|
||||
|
||||
#undef DEFINE_CL_TRAITS
|
||||
//! \endcond
|
||||
|
||||
struct ICDDispatchedObject
|
||||
{
|
||||
static struct KHRicdVendorDispatchRec icdVendorDispatch_[];
|
||||
const struct KHRicdVendorDispatchRec* const dispatch_;
|
||||
struct ICDDispatchedObject {
|
||||
static struct KHRicdVendorDispatchRec icdVendorDispatch_[];
|
||||
const struct KHRicdVendorDispatchRec* const dispatch_;
|
||||
|
||||
protected:
|
||||
ICDDispatchedObject() : dispatch_(icdVendorDispatch_) { }
|
||||
protected:
|
||||
ICDDispatchedObject() : dispatch_(icdVendorDispatch_) {}
|
||||
|
||||
public:
|
||||
static bool isValidHandle(const void* handle)
|
||||
{
|
||||
return handle != NULL;
|
||||
}
|
||||
public:
|
||||
static bool isValidHandle(const void* handle) { return handle != NULL; }
|
||||
|
||||
const void* handle() const
|
||||
{
|
||||
return static_cast<const ICDDispatchedObject*>(this);
|
||||
}
|
||||
void* handle()
|
||||
{
|
||||
return static_cast<ICDDispatchedObject*>(this);
|
||||
}
|
||||
const void* handle() const { return static_cast<const ICDDispatchedObject*>(this); }
|
||||
void* handle() { return static_cast<ICDDispatchedObject*>(this); }
|
||||
|
||||
template<typename T>
|
||||
static const T* fromHandle(const void *handle)
|
||||
{
|
||||
return static_cast<const T*>(
|
||||
reinterpret_cast<const ICDDispatchedObject*>(handle));
|
||||
}
|
||||
template<typename T>
|
||||
static T* fromHandle(void *handle)
|
||||
{
|
||||
return static_cast<T*>(
|
||||
reinterpret_cast<ICDDispatchedObject*>(handle));
|
||||
}
|
||||
template <typename T> static const T* fromHandle(const void* handle) {
|
||||
return static_cast<const T*>(reinterpret_cast<const ICDDispatchedObject*>(handle));
|
||||
}
|
||||
template <typename T> static T* fromHandle(void* handle) {
|
||||
return static_cast<T*>(reinterpret_cast<ICDDispatchedObject*>(handle));
|
||||
}
|
||||
};
|
||||
|
||||
#define OCL_MAX_KEYS 8
|
||||
|
||||
/*! The object metadata container.
|
||||
*/
|
||||
class ObjectMetadata
|
||||
{
|
||||
class ObjectMetadata {
|
||||
public:
|
||||
typedef size_t Key;
|
||||
typedef void* Value;
|
||||
|
||||
public:
|
||||
typedef size_t Key;
|
||||
typedef void* Value;
|
||||
private:
|
||||
typedef void(CL_CALLBACK* Destructor)(Value);
|
||||
|
||||
private:
|
||||
typedef void (CL_CALLBACK * Destructor)(Value);
|
||||
static Atomic<Key> nextKey_;
|
||||
static Destructor destructors_[OCL_MAX_KEYS];
|
||||
|
||||
static Atomic<Key> nextKey_;
|
||||
static Destructor destructors_[OCL_MAX_KEYS];
|
||||
Atomic<Value*> values_;
|
||||
|
||||
Atomic<Value*> values_;
|
||||
public:
|
||||
static bool check(Key key);
|
||||
|
||||
public:
|
||||
static bool check(Key key);
|
||||
static Key createKey(Destructor destructor = NULL);
|
||||
|
||||
static Key createKey(Destructor destructor = NULL);
|
||||
ObjectMetadata() : values_(NULL) {}
|
||||
~ObjectMetadata();
|
||||
|
||||
ObjectMetadata() : values_(NULL) { }
|
||||
~ObjectMetadata();
|
||||
Value getValueForKey(Key key) const;
|
||||
|
||||
Value getValueForKey(Key key) const;
|
||||
|
||||
bool setValueForKey(Key key, Value value);
|
||||
bool setValueForKey(Key key, Value value);
|
||||
};
|
||||
|
||||
/*! \brief For all OpenCL/Runtime objects.
|
||||
*/
|
||||
class RuntimeObject : public ReferenceCountedObject, public ICDDispatchedObject
|
||||
{
|
||||
private:
|
||||
ObjectMetadata metadata_;
|
||||
class RuntimeObject : public ReferenceCountedObject, public ICDDispatchedObject {
|
||||
private:
|
||||
ObjectMetadata metadata_;
|
||||
|
||||
public:
|
||||
public:
|
||||
enum ObjectType {
|
||||
ObjectTypeContext = 0,
|
||||
ObjectTypeDevice = 1,
|
||||
ObjectTypeMemory = 2,
|
||||
ObjectTypeKernel = 3,
|
||||
ObjectTypeCounter = 4,
|
||||
ObjectTypePerfCounter = 5,
|
||||
ObjectTypeEvent = 6,
|
||||
ObjectTypeProgram = 7,
|
||||
ObjectTypeQueue = 8,
|
||||
ObjectTypeSampler = 9,
|
||||
ObjectTypeThreadTrace = 10,
|
||||
ObjectTypeLiquidFlashFile = 11
|
||||
};
|
||||
|
||||
enum ObjectType {
|
||||
ObjectTypeContext = 0,
|
||||
ObjectTypeDevice = 1,
|
||||
ObjectTypeMemory = 2,
|
||||
ObjectTypeKernel = 3,
|
||||
ObjectTypeCounter = 4,
|
||||
ObjectTypePerfCounter = 5,
|
||||
ObjectTypeEvent = 6,
|
||||
ObjectTypeProgram = 7,
|
||||
ObjectTypeQueue = 8,
|
||||
ObjectTypeSampler = 9,
|
||||
ObjectTypeThreadTrace = 10,
|
||||
ObjectTypeLiquidFlashFile = 11
|
||||
};
|
||||
|
||||
ObjectMetadata& metadata() { return metadata_; }
|
||||
virtual ObjectType objectType() const =0 ;
|
||||
ObjectMetadata& metadata() { return metadata_; }
|
||||
virtual ObjectType objectType() const = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class SharedReference : public EmbeddedObject
|
||||
{
|
||||
private:
|
||||
T& reference_;
|
||||
template <typename T> class SharedReference : public EmbeddedObject {
|
||||
private:
|
||||
T& reference_;
|
||||
|
||||
private:
|
||||
// do not copy shared references.
|
||||
SharedReference<T>& operator = (const SharedReference<T>& sref);
|
||||
private:
|
||||
// do not copy shared references.
|
||||
SharedReference<T>& operator=(const SharedReference<T>& sref);
|
||||
|
||||
public:
|
||||
explicit SharedReference(T& reference)
|
||||
: reference_(reference)
|
||||
{
|
||||
reference_.retain();
|
||||
}
|
||||
public:
|
||||
explicit SharedReference(T& reference) : reference_(reference) { reference_.retain(); }
|
||||
|
||||
~SharedReference()
|
||||
{
|
||||
reference_.release();
|
||||
}
|
||||
~SharedReference() { reference_.release(); }
|
||||
|
||||
T& operator ()() const { return reference_; }
|
||||
T& operator()() const { return reference_; }
|
||||
};
|
||||
|
||||
/*! \brief A 1,2 or 3D coordinate.
|
||||
@@ -223,48 +175,38 @@ public:
|
||||
*! of non-zero elements. (i.e. a 1D line is not the same as a 2D plane with width 1)
|
||||
*/
|
||||
|
||||
struct Coord3D
|
||||
{
|
||||
size_t c[3];
|
||||
struct Coord3D {
|
||||
size_t c[3];
|
||||
|
||||
Coord3D(size_t d0, size_t d1 = 0, size_t d2 = 0)
|
||||
{
|
||||
c[0]=d0; c[1]=d1; c[2]=d2;
|
||||
}
|
||||
const size_t& operator[] (size_t idx) const
|
||||
{
|
||||
assert(idx < 3);
|
||||
return c[idx];
|
||||
}
|
||||
bool operator== (const Coord3D& rhs) const
|
||||
{
|
||||
return c[0] == rhs.c[0] && c[1] == rhs.c[1] && c[2] == rhs.c[2];
|
||||
}
|
||||
Coord3D(size_t d0, size_t d1 = 0, size_t d2 = 0) {
|
||||
c[0] = d0;
|
||||
c[1] = d1;
|
||||
c[2] = d2;
|
||||
}
|
||||
const size_t& operator[](size_t idx) const {
|
||||
assert(idx < 3);
|
||||
return c[idx];
|
||||
}
|
||||
bool operator==(const Coord3D& rhs) const {
|
||||
return c[0] == rhs.c[0] && c[1] == rhs.c[1] && c[2] == rhs.c[2];
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
|
||||
template <typename CL>
|
||||
typename amd::as_internal<CL>::type*
|
||||
as_amd(CL* cl_obj)
|
||||
{
|
||||
return cl_obj == NULL ? NULL : amd::RuntimeObject::fromHandle<
|
||||
typename amd::as_internal<CL>::type>(static_cast<void*>(cl_obj));
|
||||
template <typename CL> typename amd::as_internal<CL>::type* as_amd(CL* cl_obj) {
|
||||
return cl_obj == NULL ? NULL
|
||||
: amd::RuntimeObject::fromHandle<typename amd::as_internal<CL>::type>(
|
||||
static_cast<void*>(cl_obj));
|
||||
}
|
||||
|
||||
template <typename AMD>
|
||||
typename amd::as_external<AMD>::type*
|
||||
as_cl(AMD* amd_obj)
|
||||
{
|
||||
return amd_obj == NULL ? NULL : static_cast<
|
||||
typename amd::as_external<AMD>::type*>(amd_obj->handle());
|
||||
template <typename AMD> typename amd::as_external<AMD>::type* as_cl(AMD* amd_obj) {
|
||||
return amd_obj == NULL ? NULL
|
||||
: static_cast<typename amd::as_external<AMD>::type*>(amd_obj->handle());
|
||||
}
|
||||
|
||||
template <typename CL>
|
||||
bool
|
||||
is_valid(CL* handle)
|
||||
{
|
||||
return amd::as_internal<CL>::type::isValidHandle(handle);
|
||||
template <typename CL> bool is_valid(CL* handle) {
|
||||
return amd::as_internal<CL>::type::isValidHandle(handle);
|
||||
}
|
||||
|
||||
#endif /*OBJECT_HPP_*/
|
||||
@@ -22,44 +22,42 @@ namespace amd {
|
||||
*
|
||||
* \brief The container class for the performance counters
|
||||
*/
|
||||
class PerfCounter : public RuntimeObject
|
||||
{
|
||||
public:
|
||||
typedef std::map<cl_perfcounter_property, ulong> Properties;
|
||||
class PerfCounter : public RuntimeObject {
|
||||
public:
|
||||
typedef std::map<cl_perfcounter_property, ulong> Properties;
|
||||
|
||||
//! Constructor of the performance counter object
|
||||
PerfCounter(
|
||||
const Device& device, //!< device object
|
||||
Properties& properties) //!< a list of properties
|
||||
: properties_(properties)
|
||||
, deviceCounter_(NULL)
|
||||
, device_(device)
|
||||
{ }
|
||||
//! Constructor of the performance counter object
|
||||
PerfCounter(const Device& device, //!< device object
|
||||
Properties& properties) //!< a list of properties
|
||||
: properties_(properties),
|
||||
deviceCounter_(NULL),
|
||||
device_(device) {}
|
||||
|
||||
//! Get the performance counter's result
|
||||
const Device& device() const { return device_; }
|
||||
//! Get the performance counter's result
|
||||
const Device& device() const { return device_; }
|
||||
|
||||
//! Get the properties
|
||||
const Properties& properties() const { return properties_; }
|
||||
//! Get the properties
|
||||
const Properties& properties() const { return properties_; }
|
||||
|
||||
//! Get the device performance counter
|
||||
const device::PerfCounter* getDeviceCounter() const { return deviceCounter_; }
|
||||
//! Get the device performance counter
|
||||
const device::PerfCounter* getDeviceCounter() const { return deviceCounter_; }
|
||||
|
||||
//! Set the device performance counter
|
||||
void setDeviceCounter(device::PerfCounter* counter) { deviceCounter_ = counter; }
|
||||
//! Set the device performance counter
|
||||
void setDeviceCounter(device::PerfCounter* counter) { deviceCounter_ = counter; }
|
||||
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const {return ObjectTypePerfCounter;}
|
||||
protected:
|
||||
//! Destructor for PerfCounter class
|
||||
~PerfCounter() { delete deviceCounter_; }
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const { return ObjectTypePerfCounter; }
|
||||
|
||||
Properties properties_; //!< the perf counter properties
|
||||
device::PerfCounter* deviceCounter_; //!< device performance counter
|
||||
const Device& device_; //!< the device object
|
||||
protected:
|
||||
//! Destructor for PerfCounter class
|
||||
~PerfCounter() { delete deviceCounter_; }
|
||||
|
||||
Properties properties_; //!< the perf counter properties
|
||||
device::PerfCounter* deviceCounter_; //!< device performance counter
|
||||
const Device& device_; //!< the device object
|
||||
};
|
||||
|
||||
/*@}*/
|
||||
/*@}*/ } // namespace amd
|
||||
|
||||
#endif // PERFCTR_HPP_
|
||||
#endif // PERFCTR_HPP_
|
||||
File diff suppressed because it is too large.
Load diff
@@ -33,178 +33,154 @@ namespace amd {
|
||||
*/
|
||||
|
||||
//! A kernel function symbol
|
||||
class Symbol : public HeapObject
|
||||
{
|
||||
public:
|
||||
typedef std::map<const Device*, const device::Kernel*> devicekernels_t;
|
||||
class Symbol : public HeapObject {
|
||||
public:
|
||||
typedef std::map<const Device*, const device::Kernel*> devicekernels_t;
|
||||
|
||||
private:
|
||||
devicekernels_t deviceKernels_; //! All device kernels objects.
|
||||
devicekernels_t devKernelsNoOpt_; //! Kernel objects without optimization
|
||||
KernelSignature signature_; //! Kernel signature.
|
||||
private:
|
||||
devicekernels_t deviceKernels_; //! All device kernels objects.
|
||||
devicekernels_t devKernelsNoOpt_; //! Kernel objects without optimization
|
||||
KernelSignature signature_; //! Kernel signature.
|
||||
|
||||
public:
|
||||
//! Default constructor
|
||||
Symbol() {}
|
||||
public:
|
||||
//! Default constructor
|
||||
Symbol() {}
|
||||
|
||||
//! Set the entry point and check or set the signature.
|
||||
bool setDeviceKernel(
|
||||
const Device& device, //!< Device object.
|
||||
const device::Kernel* func, //!< Device kernel object.
|
||||
bool noAlias = true //!< No-alias optimization
|
||||
);
|
||||
//! Set the entry point and check or set the signature.
|
||||
bool setDeviceKernel(const Device& device, //!< Device object.
|
||||
const device::Kernel* func, //!< Device kernel object.
|
||||
bool noAlias = true //!< No-alias optimization
|
||||
);
|
||||
|
||||
//! Return the device kernel.
|
||||
const device::Kernel* getDeviceKernel(
|
||||
const Device& device, //!< Device object.
|
||||
bool noAlias = true //!< No-alias optimization
|
||||
) const;
|
||||
//! Return the device kernel.
|
||||
const device::Kernel* getDeviceKernel(const Device& device, //!< Device object.
|
||||
bool noAlias = true //!< No-alias optimization
|
||||
) const;
|
||||
|
||||
//! Return this Symbol's signature.
|
||||
const KernelSignature& signature() const { return signature_; }
|
||||
//! Return this Symbol's signature.
|
||||
const KernelSignature& signature() const { return signature_; }
|
||||
};
|
||||
|
||||
class Context;
|
||||
|
||||
//! A collection of binaries for devices in the associated context.
|
||||
class Program : public RuntimeObject
|
||||
{
|
||||
public:
|
||||
typedef std::pair<uint8_t*, size_t> binary_t;
|
||||
typedef std::set<Device const*> devicelist_t;
|
||||
typedef std::map<Device const*, binary_t> devicebinary_t;
|
||||
typedef std::map<Device const*, device::Program*> deviceprograms_t;
|
||||
typedef std::map<std::string, Symbol> symbols_t;
|
||||
class Program : public RuntimeObject {
|
||||
public:
|
||||
typedef std::pair<uint8_t*, size_t> binary_t;
|
||||
typedef std::set<Device const*> devicelist_t;
|
||||
typedef std::map<Device const*, binary_t> devicebinary_t;
|
||||
typedef std::map<Device const*, device::Program*> deviceprograms_t;
|
||||
typedef std::map<std::string, Symbol> symbols_t;
|
||||
|
||||
private:
|
||||
//! Replaces the compiled program with the new version from HD
|
||||
void StubProgramSource(const std::string& app_name);
|
||||
private:
|
||||
//! Replaces the compiled program with the new version from HD
|
||||
void StubProgramSource(const std::string& app_name);
|
||||
|
||||
//! The context this program is part of.
|
||||
SharedReference<Context> context_;
|
||||
//! The context this program is part of.
|
||||
SharedReference<Context> context_;
|
||||
|
||||
std::string sourceCode_; //!< Strings that make up the source code
|
||||
bool isSPIRV_; //!< The binary image is SPIRV
|
||||
devicebinary_t binary_; //!< The binary image, provided by the app
|
||||
symbols_t* symbolTable_; //!< The program's kernels symbol table
|
||||
std::string kernelNames_; //!< The program kernel names
|
||||
std::string sourceCode_; //!< Strings that make up the source code
|
||||
bool isSPIRV_; //!< The binary image is SPIRV
|
||||
devicebinary_t binary_; //!< The binary image, provided by the app
|
||||
symbols_t* symbolTable_; //!< The program's kernels symbol table
|
||||
std::string kernelNames_; //!< The program kernel names
|
||||
|
||||
//! The device program objects included in this program
|
||||
deviceprograms_t devicePrograms_;
|
||||
devicelist_t deviceList_;
|
||||
//! The device program objects included in this program
|
||||
deviceprograms_t devicePrograms_;
|
||||
devicelist_t deviceList_;
|
||||
|
||||
std::string programLog_; //!< Log for parsing options, etc.
|
||||
std::string programLog_; //!< Log for parsing options, etc.
|
||||
|
||||
protected:
|
||||
//! Destroy this program.
|
||||
~Program();
|
||||
protected:
|
||||
//! Destroy this program.
|
||||
~Program();
|
||||
|
||||
//! Clears the program object if the app attempts to rebuild the program
|
||||
void clear();
|
||||
//! Clears the program object if the app attempts to rebuild the program
|
||||
void clear();
|
||||
|
||||
//! Global build lock (remove when LLVM is thread-safe).
|
||||
static Monitor buildLock_;
|
||||
//! Global build lock (remove when LLVM is thread-safe).
|
||||
static Monitor buildLock_;
|
||||
|
||||
public:
|
||||
//! Construct a new program to be compiled from the given source code.
|
||||
Program(Context& context, const std::string& sourceCode, bool isSPIRV = false)
|
||||
: context_(context)
|
||||
, sourceCode_(sourceCode)
|
||||
, isSPIRV_(isSPIRV)
|
||||
, symbolTable_(NULL)
|
||||
, programLog_()
|
||||
{ }
|
||||
public:
|
||||
//! Construct a new program to be compiled from the given source code.
|
||||
Program(Context& context, const std::string& sourceCode, bool isSPIRV = false)
|
||||
: context_(context),
|
||||
sourceCode_(sourceCode),
|
||||
isSPIRV_(isSPIRV),
|
||||
symbolTable_(NULL),
|
||||
programLog_() {}
|
||||
|
||||
//! Construct a new program associated with a context.
|
||||
Program(Context& context)
|
||||
: context_(context)
|
||||
, isSPIRV_(false)
|
||||
, symbolTable_(NULL)
|
||||
{ }
|
||||
//! Construct a new program associated with a context.
|
||||
Program(Context& context) : context_(context), isSPIRV_(false), symbolTable_(NULL) {}
|
||||
|
||||
//! Returns context, associated with the current program.
|
||||
const Context& context() const { return context_(); }
|
||||
//! Returns context, associated with the current program.
|
||||
const Context& context() const { return context_(); }
|
||||
|
||||
//! Return the sections for this program.
|
||||
const deviceprograms_t& devicePrograms() const { return devicePrograms_; }
|
||||
//! Return the sections for this program.
|
||||
const deviceprograms_t& devicePrograms() const { return devicePrograms_; }
|
||||
|
||||
//! Return the associated devices.
|
||||
const devicelist_t& deviceList() const { return deviceList_; }
|
||||
//! Return the associated devices.
|
||||
const devicelist_t& deviceList() const { return deviceList_; }
|
||||
|
||||
//! Return the symbols for this program.
|
||||
const symbols_t& symbols() const { return *symbolTable_; }
|
||||
//! Return the symbols for this program.
|
||||
const symbols_t& symbols() const { return *symbolTable_; }
|
||||
|
||||
//! Return the pointer to symbols for this program.
|
||||
const symbols_t* symbolsPtr() const { return symbolTable_; }
|
||||
//! Return the pointer to symbols for this program.
|
||||
const symbols_t* symbolsPtr() const { return symbolTable_; }
|
||||
|
||||
//! Return the program source code.
|
||||
const std::string& sourceCode() const { return sourceCode_; }
|
||||
//! Return the program source code.
|
||||
const std::string& sourceCode() const { return sourceCode_; }
|
||||
|
||||
//! Return the program log.
|
||||
const std::string& programLog() const { return programLog_; }
|
||||
//! Return the program log.
|
||||
const std::string& programLog() const { return programLog_; }
|
||||
|
||||
//! Add a new device program with or without binary image and options.
|
||||
cl_int addDeviceProgram(Device&, const void* image = NULL, size_t len = 0,
|
||||
amd::option::Options* options = NULL);
|
||||
//! Add a new device program with or without binary image and options.
|
||||
cl_int addDeviceProgram(Device&, const void* image = NULL, size_t len = 0,
|
||||
amd::option::Options* options = NULL);
|
||||
|
||||
//! Find the section for the given device. Return NULL if not found.
|
||||
device::Program* getDeviceProgram(const Device& device) const;
|
||||
//! Find the section for the given device. Return NULL if not found.
|
||||
device::Program* getDeviceProgram(const Device& device) const;
|
||||
|
||||
//! Return the symbol for the given kernel name.
|
||||
const Symbol* findSymbol(const char* name) const;
|
||||
//! Return the symbol for the given kernel name.
|
||||
const Symbol* findSymbol(const char* name) const;
|
||||
|
||||
//! Return the binary image.
|
||||
const binary_t& binary(const Device& device) {
|
||||
return binary_[&device.rootDevice()];
|
||||
}
|
||||
//! Return the binary image.
|
||||
const binary_t& binary(const Device& device) { return binary_[&device.rootDevice()]; }
|
||||
|
||||
//! Return the program kernel names
|
||||
const std::string& kernelNames() const { return kernelNames_; }
|
||||
//! Return the program kernel names
|
||||
const std::string& kernelNames() const { return kernelNames_; }
|
||||
|
||||
//! Compile the program for the given devices.
|
||||
cl_int compile(
|
||||
const std::vector<Device*>& devices,
|
||||
size_t numHeaders,
|
||||
const std::vector<const Program*>& headerPrograms,
|
||||
const char** headerIncludeNames,
|
||||
const char* options = NULL,
|
||||
void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
|
||||
void* data = NULL,
|
||||
bool optionChangable = true);
|
||||
//! Compile the program for the given devices.
|
||||
cl_int compile(const std::vector<Device*>& devices, size_t numHeaders,
|
||||
const std::vector<const Program*>& headerPrograms, const char** headerIncludeNames,
|
||||
const char* options = NULL,
|
||||
void(CL_CALLBACK* notifyFptr)(cl_program, void*) = NULL, void* data = NULL,
|
||||
bool optionChangable = true);
|
||||
|
||||
//! Link the programs for the given devices.
|
||||
cl_int link(
|
||||
const std::vector<Device*>& devices,
|
||||
size_t numInputs,
|
||||
const std::vector<Program*>& inputPrograms,
|
||||
const char* options = NULL,
|
||||
void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
|
||||
void* data = NULL,
|
||||
bool optionChangable = true);
|
||||
//! Link the programs for the given devices.
|
||||
cl_int link(const std::vector<Device*>& devices, size_t numInputs,
|
||||
const std::vector<Program*>& inputPrograms, const char* options = NULL,
|
||||
void(CL_CALLBACK* notifyFptr)(cl_program, void*) = NULL, void* data = NULL,
|
||||
bool optionChangable = true);
|
||||
|
||||
//! Build the program for the given devices.
|
||||
cl_int build(
|
||||
const std::vector<Device*>& devices,
|
||||
const char* options = NULL,
|
||||
void (CL_CALLBACK * notifyFptr)(cl_program, void *) = NULL,
|
||||
void* data = NULL,
|
||||
bool optionChangable = true);
|
||||
//! Build the program for the given devices.
|
||||
cl_int build(const std::vector<Device*>& devices, const char* options = NULL,
|
||||
void(CL_CALLBACK* notifyFptr)(cl_program, void*) = NULL, void* data = NULL,
|
||||
bool optionChangable = true);
|
||||
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const {return ObjectTypeProgram;}
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const { return ObjectTypeProgram; }
|
||||
|
||||
static int GetOclCVersion(const char* clVer);
|
||||
static int GetOclCVersion(const char* clVer);
|
||||
|
||||
static bool ParseAllOptions(const std::string& options,
|
||||
option::Options& parsedOptions,
|
||||
bool optionChangable = true,
|
||||
bool linkOptsOnly = false);
|
||||
static bool ParseAllOptions(const std::string& options, option::Options& parsedOptions,
|
||||
bool optionChangable = true, bool linkOptsOnly = false);
|
||||
};
|
||||
|
||||
/*! @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
|
||||
#endif /*PROGRAM_HPP_*/
|
||||
@@ -17,9 +17,9 @@
|
||||
#include <d3d10_1.h>
|
||||
#include <dxgi.h>
|
||||
#include "CL/cl_d3d10.h"
|
||||
#endif //_WIN32
|
||||
#endif //_WIN32
|
||||
|
||||
#if defined(_MSC_VER) //both Win32 and Win64
|
||||
#if defined(_MSC_VER) // both Win32 and Win64
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
@@ -32,133 +32,109 @@ namespace amd {
|
||||
#ifdef __linux__
|
||||
|
||||
static void __runtime_exit() __attribute__((destructor(102)));
|
||||
static void __runtime_exit()
|
||||
{
|
||||
if (ENABLE_CAL_SHUTDOWN) {
|
||||
Runtime::tearDown();
|
||||
}
|
||||
static void __runtime_exit() {
|
||||
if (ENABLE_CAL_SHUTDOWN) {
|
||||
Runtime::tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
volatile bool
|
||||
Runtime::initialized_ = false;
|
||||
volatile bool Runtime::initialized_ = false;
|
||||
|
||||
bool
|
||||
Runtime::init()
|
||||
{
|
||||
if (initialized_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Enter a very basic critical region. We want to prevent 2 threads
|
||||
// from concurrently executing the init() routines. We can't use a
|
||||
// Monitor since the system is not yet initialized.
|
||||
|
||||
static std::atomic_flag lock = ATOMIC_FLAG_INIT;
|
||||
struct CriticalRegion
|
||||
{
|
||||
std::atomic_flag& lock_;
|
||||
CriticalRegion(std::atomic_flag& lock) : lock_(lock)
|
||||
{
|
||||
while (lock.test_and_set(std::memory_order_acquire)) {
|
||||
Os::yield();
|
||||
}
|
||||
}
|
||||
~CriticalRegion()
|
||||
{
|
||||
lock_.clear(std::memory_order_release);
|
||||
}
|
||||
} region(lock);
|
||||
|
||||
if (initialized_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( !Flag::init()
|
||||
|| !option::init()
|
||||
|| !Device::init()
|
||||
// Agent initializes last
|
||||
|| !Agent::init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
initialized_ = true;
|
||||
bool Runtime::init() {
|
||||
if (initialized_) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Runtime::tearDown()
|
||||
{
|
||||
if (!initialized_) {
|
||||
return;
|
||||
// Enter a very basic critical region. We want to prevent 2 threads
|
||||
// from concurrently executing the init() routines. We can't use a
|
||||
// Monitor since the system is not yet initialized.
|
||||
|
||||
static std::atomic_flag lock = ATOMIC_FLAG_INIT;
|
||||
struct CriticalRegion {
|
||||
std::atomic_flag& lock_;
|
||||
CriticalRegion(std::atomic_flag& lock) : lock_(lock) {
|
||||
while (lock.test_and_set(std::memory_order_acquire)) {
|
||||
Os::yield();
|
||||
}
|
||||
}
|
||||
~CriticalRegion() { lock_.clear(std::memory_order_release); }
|
||||
} region(lock);
|
||||
|
||||
Agent::tearDown();
|
||||
Device::tearDown();
|
||||
option::teardown();
|
||||
Flag::tearDown();
|
||||
if (initialized_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Flag::init() || !option::init() || !Device::init()
|
||||
// Agent initializes last
|
||||
|| !Agent::init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
initialized_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint
|
||||
ReferenceCountedObject::retain()
|
||||
{
|
||||
return ++make_atomic(referenceCount_);
|
||||
void Runtime::tearDown() {
|
||||
if (!initialized_) {
|
||||
return;
|
||||
}
|
||||
|
||||
Agent::tearDown();
|
||||
Device::tearDown();
|
||||
option::teardown();
|
||||
Flag::tearDown();
|
||||
}
|
||||
|
||||
uint
|
||||
ReferenceCountedObject::release()
|
||||
{
|
||||
uint newCount = --make_atomic(referenceCount_);
|
||||
if (newCount == 0) {
|
||||
if (terminate()) {
|
||||
delete this;
|
||||
}
|
||||
uint ReferenceCountedObject::retain() { return ++make_atomic(referenceCount_); }
|
||||
|
||||
uint ReferenceCountedObject::release() {
|
||||
uint newCount = --make_atomic(referenceCount_);
|
||||
if (newCount == 0) {
|
||||
if (terminate()) {
|
||||
delete this;
|
||||
}
|
||||
return newCount;
|
||||
}
|
||||
return newCount;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef DEBUG
|
||||
static int
|
||||
reportHook(int reportType, char *message, int *returnValue)
|
||||
{
|
||||
if (returnValue) {
|
||||
*returnValue = 1;
|
||||
}
|
||||
std::cerr << message;
|
||||
::exit(3);
|
||||
return TRUE;
|
||||
static int reportHook(int reportType, char* message, int* returnValue) {
|
||||
if (returnValue) {
|
||||
*returnValue = 1;
|
||||
}
|
||||
std::cerr << message;
|
||||
::exit(3);
|
||||
return TRUE;
|
||||
}
|
||||
#endif // DEBUG
|
||||
#endif // DEBUG
|
||||
|
||||
extern "C" BOOL WINAPI
|
||||
DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
|
||||
{
|
||||
switch (reason) {
|
||||
extern "C" BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
|
||||
switch (reason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
# ifdef DEBUG
|
||||
if (!AMD_OCL_ENABLE_MESSAGE_BOX) {
|
||||
_CrtSetReportHook(reportHook);
|
||||
_set_error_mode(_OUT_TO_STDERR);
|
||||
}
|
||||
# endif // DEBUG
|
||||
break;
|
||||
#ifdef DEBUG
|
||||
if (!AMD_OCL_ENABLE_MESSAGE_BOX) {
|
||||
_CrtSetReportHook(reportHook);
|
||||
_set_error_mode(_OUT_TO_STDERR);
|
||||
}
|
||||
#endif // DEBUG
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (!reserved || ENABLE_CAL_SHUTDOWN) {
|
||||
Runtime::tearDown();
|
||||
}
|
||||
break;
|
||||
if (!reserved || ENABLE_CAL_SHUTDOWN) {
|
||||
Runtime::tearDown();
|
||||
}
|
||||
break;
|
||||
case DLL_THREAD_DETACH: {
|
||||
amd::Thread* thread = amd::Thread::current();
|
||||
delete thread;
|
||||
}
|
||||
break;
|
||||
amd::Thread* thread = amd::Thread::current();
|
||||
delete thread;
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
@@ -14,22 +14,21 @@ namespace amd {
|
||||
* @{
|
||||
*/
|
||||
|
||||
class Runtime : AllStatic
|
||||
{
|
||||
static volatile bool initialized_;
|
||||
class Runtime : AllStatic {
|
||||
static volatile bool initialized_;
|
||||
|
||||
public:
|
||||
//! Return true if the OpencCL runtime is already initialized
|
||||
inline static bool initialized();
|
||||
public:
|
||||
//! Return true if the OpencCL runtime is already initialized
|
||||
inline static bool initialized();
|
||||
|
||||
//! Initialize the OpenCL runtime.
|
||||
static bool init();
|
||||
//! Initialize the OpenCL runtime.
|
||||
static bool init();
|
||||
|
||||
//! Tear down the runtime.
|
||||
static void tearDown();
|
||||
//! Tear down the runtime.
|
||||
static void tearDown();
|
||||
|
||||
//! Return true if the Runtime is still single-threaded.
|
||||
static bool singleThreaded() { return !initialized(); }
|
||||
//! Return true if the Runtime is still single-threaded.
|
||||
static bool singleThreaded() { return !initialized(); }
|
||||
};
|
||||
|
||||
#if 0
|
||||
@@ -65,12 +64,8 @@ public:
|
||||
|
||||
/*@}*/
|
||||
|
||||
inline bool
|
||||
Runtime::initialized()
|
||||
{
|
||||
return initialized_;
|
||||
}
|
||||
inline bool Runtime::initialized() { return initialized_; }
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
|
||||
#endif /*RUNTIME_HPP_*/
|
||||
@@ -9,180 +9,160 @@
|
||||
#include "platform/object.hpp"
|
||||
#include "device/device.hpp"
|
||||
|
||||
namespace amd
|
||||
{
|
||||
namespace amd {
|
||||
|
||||
//! Abstraction layer sampler class
|
||||
class Sampler : public RuntimeObject
|
||||
{
|
||||
public:
|
||||
typedef std::map<Device const*, device::Sampler*> DeviceSamplers;
|
||||
class Sampler : public RuntimeObject {
|
||||
public:
|
||||
typedef std::map<Device const*, device::Sampler*> DeviceSamplers;
|
||||
|
||||
//! \note the sampler states must match the compiler's defines.
|
||||
//! See amd_ocl_sys_predef.c
|
||||
enum State
|
||||
{
|
||||
StateNormalizedCoordsFalse = 0x00,
|
||||
StateNormalizedCoordsTrue = 0x01,
|
||||
StateNormalizedCoordsMask = (StateNormalizedCoordsFalse |
|
||||
StateNormalizedCoordsTrue),
|
||||
StateAddressNone = 0x00,
|
||||
StateAddressRepeat = 0x02,
|
||||
StateAddressClampToEdge = 0x04,
|
||||
StateAddressClamp = 0x06,
|
||||
StateAddressMirroredRepeat = 0x08,
|
||||
StateAddressMask = (StateAddressNone |
|
||||
StateAddressRepeat |
|
||||
StateAddressMirroredRepeat |
|
||||
StateAddressClampToEdge |
|
||||
StateAddressClamp),
|
||||
StateFilterNearest = 0x10,
|
||||
StateFilterLinear = 0x20,
|
||||
StateFilterMask = (StateFilterNearest |
|
||||
StateFilterLinear)
|
||||
};
|
||||
//! \note the sampler states must match the compiler's defines.
|
||||
//! See amd_ocl_sys_predef.c
|
||||
enum State {
|
||||
StateNormalizedCoordsFalse = 0x00,
|
||||
StateNormalizedCoordsTrue = 0x01,
|
||||
StateNormalizedCoordsMask = (StateNormalizedCoordsFalse | StateNormalizedCoordsTrue),
|
||||
StateAddressNone = 0x00,
|
||||
StateAddressRepeat = 0x02,
|
||||
StateAddressClampToEdge = 0x04,
|
||||
StateAddressClamp = 0x06,
|
||||
StateAddressMirroredRepeat = 0x08,
|
||||
StateAddressMask = (StateAddressNone | StateAddressRepeat | StateAddressMirroredRepeat |
|
||||
StateAddressClampToEdge | StateAddressClamp),
|
||||
StateFilterNearest = 0x10,
|
||||
StateFilterLinear = 0x20,
|
||||
StateFilterMask = (StateFilterNearest | StateFilterLinear)
|
||||
};
|
||||
|
||||
private:
|
||||
Context& context_; //!< OpenCL context associated with this sampler
|
||||
uint32_t state_; //!< Sampler state
|
||||
uint mipFilter_; //!< mip filter
|
||||
float minLod_; //!< min level of detail
|
||||
float maxLod_; //!< max level of detail
|
||||
DeviceSamplers deviceSamplers_; //!< Container for the device samplers
|
||||
private:
|
||||
Context& context_; //!< OpenCL context associated with this sampler
|
||||
uint32_t state_; //!< Sampler state
|
||||
uint mipFilter_; //!< mip filter
|
||||
float minLod_; //!< min level of detail
|
||||
float maxLod_; //!< max level of detail
|
||||
DeviceSamplers deviceSamplers_; //!< Container for the device samplers
|
||||
|
||||
public:
|
||||
Sampler(
|
||||
Context& context, //!< OpenCL context
|
||||
bool normCoords, //!< normalized coordinates
|
||||
uint addrMode, //!< adressing mode
|
||||
uint filterMode, //!< filter mode
|
||||
uint mipFilterMode, //!< mip filter mode
|
||||
float minLod, //!< min level of detail
|
||||
float maxLod //!< max level of detail
|
||||
)
|
||||
: context_(context)
|
||||
, mipFilter_(mipFilterMode)
|
||||
, minLod_(minLod)
|
||||
, maxLod_(maxLod)
|
||||
{ // Packs the sampler state into uint32_t for kernel execution
|
||||
state_ = 0;
|
||||
public:
|
||||
Sampler(Context& context, //!< OpenCL context
|
||||
bool normCoords, //!< normalized coordinates
|
||||
uint addrMode, //!< adressing mode
|
||||
uint filterMode, //!< filter mode
|
||||
uint mipFilterMode, //!< mip filter mode
|
||||
float minLod, //!< min level of detail
|
||||
float maxLod //!< max level of detail
|
||||
)
|
||||
: context_(context),
|
||||
mipFilter_(mipFilterMode),
|
||||
minLod_(minLod),
|
||||
maxLod_(maxLod) { // Packs the sampler state into uint32_t for kernel execution
|
||||
state_ = 0;
|
||||
|
||||
// Set normalized state
|
||||
if (normCoords) {
|
||||
state_ |= StateNormalizedCoordsTrue;
|
||||
}
|
||||
else {
|
||||
state_ |= StateNormalizedCoordsFalse;
|
||||
}
|
||||
|
||||
// Program the sampler filter mode
|
||||
if (filterMode == CL_FILTER_LINEAR) {
|
||||
state_ |= StateFilterLinear;
|
||||
}
|
||||
else {
|
||||
state_ |= StateFilterNearest;
|
||||
}
|
||||
|
||||
// Program the sampler address mode
|
||||
switch (addrMode) {
|
||||
case CL_ADDRESS_CLAMP_TO_EDGE:
|
||||
state_ |= StateAddressClampToEdge;
|
||||
break;
|
||||
case CL_ADDRESS_REPEAT:
|
||||
state_ |= StateAddressRepeat;
|
||||
break;
|
||||
case CL_ADDRESS_CLAMP:
|
||||
state_ |= StateAddressClamp;
|
||||
break;
|
||||
case CL_ADDRESS_MIRRORED_REPEAT:
|
||||
state_ |= StateAddressMirroredRepeat;
|
||||
break;
|
||||
case CL_ADDRESS_NONE:
|
||||
state_ |= StateAddressNone;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Set normalized state
|
||||
if (normCoords) {
|
||||
state_ |= StateNormalizedCoordsTrue;
|
||||
} else {
|
||||
state_ |= StateNormalizedCoordsFalse;
|
||||
}
|
||||
|
||||
virtual ~Sampler()
|
||||
{
|
||||
for (const auto& it : deviceSamplers_) {
|
||||
delete it.second;
|
||||
}
|
||||
// Program the sampler filter mode
|
||||
if (filterMode == CL_FILTER_LINEAR) {
|
||||
state_ |= StateFilterLinear;
|
||||
} else {
|
||||
state_ |= StateFilterNearest;
|
||||
}
|
||||
|
||||
bool create()
|
||||
{
|
||||
for (uint i = 0; i < context_.devices().size(); ++i) {
|
||||
device::Sampler* sampler = NULL;
|
||||
Device* dev = context_.devices()[i];
|
||||
if (!dev->createSampler(*this, &sampler)) {
|
||||
return false;
|
||||
}
|
||||
deviceSamplers_[dev] = sampler;
|
||||
}
|
||||
return true;
|
||||
// Program the sampler address mode
|
||||
switch (addrMode) {
|
||||
case CL_ADDRESS_CLAMP_TO_EDGE:
|
||||
state_ |= StateAddressClampToEdge;
|
||||
break;
|
||||
case CL_ADDRESS_REPEAT:
|
||||
state_ |= StateAddressRepeat;
|
||||
break;
|
||||
case CL_ADDRESS_CLAMP:
|
||||
state_ |= StateAddressClamp;
|
||||
break;
|
||||
case CL_ADDRESS_MIRRORED_REPEAT:
|
||||
state_ |= StateAddressMirroredRepeat;
|
||||
break;
|
||||
case CL_ADDRESS_NONE:
|
||||
state_ |= StateAddressNone;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
device::Sampler* getDeviceSampler(const Device& dev) const
|
||||
{
|
||||
auto it = deviceSamplers_.find(&dev);
|
||||
if (it != deviceSamplers_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return NULL;
|
||||
virtual ~Sampler() {
|
||||
for (const auto& it : deviceSamplers_) {
|
||||
delete it.second;
|
||||
}
|
||||
}
|
||||
|
||||
//! Accessor functions
|
||||
Context& context() const { return context_; }
|
||||
uint32_t state() const { return state_; }
|
||||
uint mipFilter() const { return mipFilter_; }
|
||||
float minLod() const { return minLod_; }
|
||||
float maxLod() const { return maxLod_; }
|
||||
|
||||
bool normalizedCoords() const
|
||||
{
|
||||
return (state_ & StateNormalizedCoordsTrue) ? true : false;
|
||||
bool create() {
|
||||
for (uint i = 0; i < context_.devices().size(); ++i) {
|
||||
device::Sampler* sampler = NULL;
|
||||
Device* dev = context_.devices()[i];
|
||||
if (!dev->createSampler(*this, &sampler)) {
|
||||
return false;
|
||||
}
|
||||
deviceSamplers_[dev] = sampler;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint addressingMode() const
|
||||
{
|
||||
uint adressing = 0;
|
||||
|
||||
// Program the sampler address mode
|
||||
switch (state_ & StateAddressMask) {
|
||||
case StateAddressRepeat:
|
||||
adressing = CL_ADDRESS_REPEAT;
|
||||
break;
|
||||
case StateAddressClampToEdge:
|
||||
adressing = CL_ADDRESS_CLAMP_TO_EDGE;
|
||||
break;
|
||||
case StateAddressClamp:
|
||||
adressing = CL_ADDRESS_CLAMP;
|
||||
break;
|
||||
case StateAddressMirroredRepeat:
|
||||
adressing = CL_ADDRESS_MIRRORED_REPEAT;
|
||||
break;
|
||||
case StateAddressNone:
|
||||
adressing = CL_ADDRESS_NONE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return adressing;
|
||||
device::Sampler* getDeviceSampler(const Device& dev) const {
|
||||
auto it = deviceSamplers_.find(&dev);
|
||||
if (it != deviceSamplers_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint filterMode() const
|
||||
{
|
||||
return ((state_ & StateFilterMask) == StateFilterNearest) ?
|
||||
CL_FILTER_NEAREST : CL_FILTER_LINEAR;
|
||||
//! Accessor functions
|
||||
Context& context() const { return context_; }
|
||||
uint32_t state() const { return state_; }
|
||||
uint mipFilter() const { return mipFilter_; }
|
||||
float minLod() const { return minLod_; }
|
||||
float maxLod() const { return maxLod_; }
|
||||
|
||||
bool normalizedCoords() const { return (state_ & StateNormalizedCoordsTrue) ? true : false; }
|
||||
|
||||
uint addressingMode() const {
|
||||
uint adressing = 0;
|
||||
|
||||
// Program the sampler address mode
|
||||
switch (state_ & StateAddressMask) {
|
||||
case StateAddressRepeat:
|
||||
adressing = CL_ADDRESS_REPEAT;
|
||||
break;
|
||||
case StateAddressClampToEdge:
|
||||
adressing = CL_ADDRESS_CLAMP_TO_EDGE;
|
||||
break;
|
||||
case StateAddressClamp:
|
||||
adressing = CL_ADDRESS_CLAMP;
|
||||
break;
|
||||
case StateAddressMirroredRepeat:
|
||||
adressing = CL_ADDRESS_MIRRORED_REPEAT;
|
||||
break;
|
||||
case StateAddressNone:
|
||||
adressing = CL_ADDRESS_NONE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return adressing;
|
||||
}
|
||||
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const { return ObjectTypeSampler; }
|
||||
uint filterMode() const {
|
||||
return ((state_ & StateFilterMask) == StateFilterNearest) ? CL_FILTER_NEAREST
|
||||
: CL_FILTER_LINEAR;
|
||||
}
|
||||
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const { return ObjectTypeSampler; }
|
||||
};
|
||||
|
||||
} // namespace amd
|
||||
} // namespace amd
|
||||
|
||||
#endif /*SAMPLER_HPP_*/
|
||||
@@ -25,105 +25,106 @@ namespace amd {
|
||||
*
|
||||
* \brief The container class for the thread traces
|
||||
*/
|
||||
class ThreadTrace : public RuntimeObject
|
||||
{
|
||||
public:
|
||||
enum State {
|
||||
Undefined,
|
||||
MemoryBound,
|
||||
Begin,
|
||||
End,
|
||||
Pause
|
||||
};
|
||||
typedef struct ThreadTraceConfigRec
|
||||
{
|
||||
size_t configSize_; // structure size
|
||||
size_t cu_; // target compute unit [cu]
|
||||
size_t sh_; // target shader array [sh],that contains target cu
|
||||
size_t simdMask_; // bitmask to enable or disable target tokens for different SIMDs
|
||||
size_t vmIdMask_; // virtual memory [vm] IDs to capture
|
||||
size_t tokenMask_; // bitmask indicating which trace token IDs will be included in the trace
|
||||
size_t regMask_; // bitmask indicating which register types should be included in the trace
|
||||
size_t instMask_; // types of instruction scheduling updates which should be recorded
|
||||
size_t randomSeed_; // linear feedback shift register [LFSR] seed
|
||||
size_t userData_; // user data ,which is written as payload
|
||||
size_t captureMode_; // indicator for the way how THREAD_TRACE_START / STOP events affect token collection
|
||||
bool isUserData_; // indicator if user_data is set
|
||||
bool isWrapped_; // indicator if the memory buffer should be wrapped around instead of stopping at the end
|
||||
//default thread trace configuration/s initializator
|
||||
ThreadTraceConfigRec():configSize_(0),cu_(0),sh_(0),simdMask_(0xF),vmIdMask_(CL_THREAD_TRACE_VM_ID_MASK_SINGLE),
|
||||
tokenMask_(CL_THREAD_TRACE_TOKEN_MASK_ALL_SI),regMask_(CL_THREAD_TRACE_REG_MASK_ALL_SI),
|
||||
instMask_(CL_THREAD_TRACE_INST_MASK_ALL),randomSeed_(0xFFF),userData_(0),
|
||||
captureMode_(CL_THREAD_TRACE_CAPTURE_ALL),isUserData_(false),isWrapped_(false){
|
||||
configSize_ = sizeof(struct ThreadTraceConfigRec);
|
||||
}
|
||||
}ThreadTraceConfig;
|
||||
|
||||
//! Constructor of the thread trace object
|
||||
ThreadTrace(
|
||||
const Device& device) //!< device object
|
||||
: deviceThreadTrace_(NULL)
|
||||
,device_(device)
|
||||
,state_(Undefined)
|
||||
{ }
|
||||
|
||||
//! Get the thread trace's associated device
|
||||
const Device& device() const { return device_; }
|
||||
|
||||
//! Get the shader engines number for thread trace`s associated device
|
||||
const size_t deviceSeNumThreadTrace() const { return device_.info().numberOfShaderEngines; }
|
||||
|
||||
//! Get the device thread trace
|
||||
device::ThreadTrace* getDeviceThreadTrace() { return deviceThreadTrace_; }
|
||||
|
||||
//! Set the device thread trace
|
||||
void setDeviceThreadTrace(device::ThreadTrace* threadTrace) { deviceThreadTrace_ = threadTrace; }
|
||||
|
||||
void setState(State state) {state_ = state;}
|
||||
State getState() {return state_;}
|
||||
|
||||
void setCU(unsigned int cu) { threadTraceConfig_.cu_ = cu; }
|
||||
|
||||
void setSH(unsigned int sh) { threadTraceConfig_.sh_ = sh; }
|
||||
|
||||
void setSIMD(unsigned int simdMask) { threadTraceConfig_.simdMask_ = simdMask; }
|
||||
|
||||
void setUserData(unsigned int userData) {
|
||||
threadTraceConfig_.isUserData_ = true;
|
||||
threadTraceConfig_.userData_ = userData;
|
||||
}
|
||||
|
||||
void setTokenMask(unsigned int tokenMask) { threadTraceConfig_.tokenMask_ = tokenMask; }
|
||||
|
||||
void setRegMask(unsigned int regMask) { threadTraceConfig_.regMask_ = regMask; }
|
||||
|
||||
void setVmIdMask(unsigned int vmIdMask) { threadTraceConfig_.vmIdMask_ = vmIdMask; }
|
||||
|
||||
void setInstMask(unsigned int instMask) { threadTraceConfig_.instMask_ = instMask; }
|
||||
|
||||
void setRandomSeed(unsigned int randomSeed) { threadTraceConfig_.randomSeed_ = randomSeed; }
|
||||
|
||||
void setCaptureMode(unsigned int captureMode) { threadTraceConfig_.captureMode_ = captureMode; }
|
||||
|
||||
void setIsWrapped(bool isWrapped) { threadTraceConfig_.isWrapped_ = isWrapped; }
|
||||
|
||||
const ThreadTraceConfig& threadTraceConfig() const {return threadTraceConfig_;}
|
||||
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const {return ObjectTypeThreadTrace;}
|
||||
protected:
|
||||
//! Destructor for ThreadTrace class
|
||||
~ThreadTrace() {
|
||||
delete deviceThreadTrace_;
|
||||
class ThreadTrace : public RuntimeObject {
|
||||
public:
|
||||
enum State { Undefined, MemoryBound, Begin, End, Pause };
|
||||
typedef struct ThreadTraceConfigRec {
|
||||
size_t configSize_; // structure size
|
||||
size_t cu_; // target compute unit [cu]
|
||||
size_t sh_; // target shader array [sh],that contains target cu
|
||||
size_t simdMask_; // bitmask to enable or disable target tokens for different SIMDs
|
||||
size_t vmIdMask_; // virtual memory [vm] IDs to capture
|
||||
size_t tokenMask_; // bitmask indicating which trace token IDs will be included in the trace
|
||||
size_t regMask_; // bitmask indicating which register types should be included in the trace
|
||||
size_t instMask_; // types of instruction scheduling updates which should be recorded
|
||||
size_t randomSeed_; // linear feedback shift register [LFSR] seed
|
||||
size_t userData_; // user data ,which is written as payload
|
||||
size_t captureMode_; // indicator for the way how THREAD_TRACE_START / STOP events affect token
|
||||
// collection
|
||||
bool isUserData_; // indicator if user_data is set
|
||||
bool isWrapped_; // indicator if the memory buffer should be wrapped around instead of stopping
|
||||
// at the end
|
||||
// default thread trace configuration/s initializator
|
||||
ThreadTraceConfigRec()
|
||||
: configSize_(0),
|
||||
cu_(0),
|
||||
sh_(0),
|
||||
simdMask_(0xF),
|
||||
vmIdMask_(CL_THREAD_TRACE_VM_ID_MASK_SINGLE),
|
||||
tokenMask_(CL_THREAD_TRACE_TOKEN_MASK_ALL_SI),
|
||||
regMask_(CL_THREAD_TRACE_REG_MASK_ALL_SI),
|
||||
instMask_(CL_THREAD_TRACE_INST_MASK_ALL),
|
||||
randomSeed_(0xFFF),
|
||||
userData_(0),
|
||||
captureMode_(CL_THREAD_TRACE_CAPTURE_ALL),
|
||||
isUserData_(false),
|
||||
isWrapped_(false) {
|
||||
configSize_ = sizeof(struct ThreadTraceConfigRec);
|
||||
}
|
||||
} ThreadTraceConfig;
|
||||
|
||||
device::ThreadTrace* deviceThreadTrace_; //!< device thread trace object
|
||||
const Device& device_; //!< the device object
|
||||
State state_;
|
||||
ThreadTraceConfig threadTraceConfig_;
|
||||
//! Constructor of the thread trace object
|
||||
ThreadTrace(const Device& device) //!< device object
|
||||
: deviceThreadTrace_(NULL),
|
||||
device_(device),
|
||||
state_(Undefined) {}
|
||||
|
||||
//! Get the thread trace's associated device
|
||||
const Device& device() const { return device_; }
|
||||
|
||||
//! Get the shader engines number for thread trace`s associated device
|
||||
const size_t deviceSeNumThreadTrace() const { return device_.info().numberOfShaderEngines; }
|
||||
|
||||
//! Get the device thread trace
|
||||
device::ThreadTrace* getDeviceThreadTrace() { return deviceThreadTrace_; }
|
||||
|
||||
//! Set the device thread trace
|
||||
void setDeviceThreadTrace(device::ThreadTrace* threadTrace) { deviceThreadTrace_ = threadTrace; }
|
||||
|
||||
void setState(State state) { state_ = state; }
|
||||
State getState() { return state_; }
|
||||
|
||||
void setCU(unsigned int cu) { threadTraceConfig_.cu_ = cu; }
|
||||
|
||||
void setSH(unsigned int sh) { threadTraceConfig_.sh_ = sh; }
|
||||
|
||||
void setSIMD(unsigned int simdMask) { threadTraceConfig_.simdMask_ = simdMask; }
|
||||
|
||||
void setUserData(unsigned int userData) {
|
||||
threadTraceConfig_.isUserData_ = true;
|
||||
threadTraceConfig_.userData_ = userData;
|
||||
}
|
||||
|
||||
void setTokenMask(unsigned int tokenMask) { threadTraceConfig_.tokenMask_ = tokenMask; }
|
||||
|
||||
void setRegMask(unsigned int regMask) { threadTraceConfig_.regMask_ = regMask; }
|
||||
|
||||
void setVmIdMask(unsigned int vmIdMask) { threadTraceConfig_.vmIdMask_ = vmIdMask; }
|
||||
|
||||
void setInstMask(unsigned int instMask) { threadTraceConfig_.instMask_ = instMask; }
|
||||
|
||||
void setRandomSeed(unsigned int randomSeed) { threadTraceConfig_.randomSeed_ = randomSeed; }
|
||||
|
||||
void setCaptureMode(unsigned int captureMode) { threadTraceConfig_.captureMode_ = captureMode; }
|
||||
|
||||
void setIsWrapped(bool isWrapped) { threadTraceConfig_.isWrapped_ = isWrapped; }
|
||||
|
||||
const ThreadTraceConfig& threadTraceConfig() const { return threadTraceConfig_; }
|
||||
|
||||
//! RTTI internal implementation
|
||||
virtual ObjectType objectType() const { return ObjectTypeThreadTrace; }
|
||||
|
||||
protected:
|
||||
//! Destructor for ThreadTrace class
|
||||
~ThreadTrace() { delete deviceThreadTrace_; }
|
||||
|
||||
device::ThreadTrace* deviceThreadTrace_; //!< device thread trace object
|
||||
const Device& device_; //!< the device object
|
||||
State state_;
|
||||
ThreadTraceConfig threadTraceConfig_;
|
||||
};
|
||||
|
||||
/*@}*/
|
||||
/*@}*/ } // namespace amd
|
||||
|
||||
#endif // THREAD_TRACE_HPP_
|
||||
#endif // THREAD_TRACE_HPP_
|
||||
Reference in new issue
Block a user