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:
foreman
2017-04-13 13:56:38 -04:00
parent a615e4fbb6
commit 465c1c0287
188 changed files with 68133 additions and 78048 deletions
+123 -136
View File
@@ -16,74 +16,69 @@
namespace cpu {
ClBinary::FeatureCheckResult
ClBinary::checkFeatures()
{
/* Validate that all cpu features of loaded binary target (i.e. elf_target) exists in current target.
* If some of elf_target features doesn't exist in current target we fail the build since we assume that elf LLVM-IR and binary are
* target specific and can't be recompiled to current target*/
uint16_t target = (uint16_t)dev().settings().cpuFeatures_;
uint16_t elf_target;
amd::OclElf::oclElfPlatform platform;
if (!elfIn()->getTarget(elf_target, platform)){
LogError("Loading OCL CPU binary: incorrect format");
return ERROR;
ClBinary::FeatureCheckResult ClBinary::checkFeatures() {
/* Validate that all cpu features of loaded binary target (i.e. elf_target) exists in current
* target.
* If some of elf_target features doesn't exist in current target we fail the build since we
* assume that elf LLVM-IR and binary are
* target specific and can't be recompiled to current target*/
uint16_t target = (uint16_t)dev().settings().cpuFeatures_;
uint16_t elf_target;
amd::OclElf::oclElfPlatform platform;
if (!elfIn()->getTarget(elf_target, platform)) {
LogError("Loading OCL CPU binary: incorrect format");
return ERROR;
}
uint64_t chip_options = 0x0;
if (platform == amd::OclElf::COMPLIB_PLATFORM) {
// BIF 3.0
uint32_t flag;
if (!elfIn()->getFlags(flag)) {
LogError("Loading OCL CPU binary: incorrect format");
return ERROR;
}
uint64_t chip_options=0x0;
if (platform == amd::OclElf::COMPLIB_PLATFORM) {
// BIF 3.0
uint32_t flag;
if (!elfIn()->getFlags(flag)) {
LogError("Loading OCL CPU binary: incorrect format");
return ERROR;
}
aclTargetInfo tgtInfo = aclGetTargetInfoFromChipID(LP64_SWITCH("x86", "x86-64"), flag, NULL);
chip_options = aclGetChipOptions(tgtInfo) ;
if (((target & chip_options) != chip_options) ||
((elf_target == EM_386) && (strcmp(LP64_SWITCH("x86", "x86-64"), "x86") != 0)) ||
((elf_target == EM_X86_64) && (strcmp(LP64_SWITCH("x86", "x86-64"), "x86-64") != 0))){
LogError("Loading OCL CPU binary: different target");
return ERROR;
}
aclTargetInfo tgtInfo = aclGetTargetInfoFromChipID(LP64_SWITCH("x86", "x86-64"), flag, NULL);
chip_options = aclGetChipOptions(tgtInfo);
if (((target & chip_options) != chip_options) ||
((elf_target == EM_386) && (strcmp(LP64_SWITCH("x86", "x86-64"), "x86") != 0)) ||
((elf_target == EM_X86_64) && (strcmp(LP64_SWITCH("x86", "x86-64"), "x86-64") != 0))) {
LogError("Loading OCL CPU binary: different target");
return ERROR;
}
else {
// BIF 2.0
if ((platform != amd::OclElf::CPU_PLATFORM) ||
((target & elf_target) != elf_target)) {
LogError("Loading OCL CPU binary: different target");
return ERROR;
}
} else {
// BIF 2.0
if ((platform != amd::OclElf::CPU_PLATFORM) || ((target & elf_target) != elf_target)) {
LogError("Loading OCL CPU binary: different target");
return ERROR;
}
char* section;
size_t sz;
}
char* section;
size_t sz;
/* If current target has more cpu features than the one for which the binary was (notice it must have all features as in elf_target
* due to previous check), we can benefit from recompiling the LLVM-IR if exists in binary (if there are errors, ignore them !).*/
if (((platform == amd::OclElf::CPU_PLATFORM) &&
((target ^ elf_target) != 0)) ||
((platform == amd::OclElf::COMPLIB_PLATFORM) &&
((target ^ chip_options) != 0))) {
if (elfIn_->getSection(amd::OclElf::LLVMIR, &section, &sz)) {
if ((section != NULL) && (sz > 0)) {
// hasDLL being false to force recompiling
RECOMPILE;
}
}
/* If current target has more cpu features than the one for which the binary was (notice it must
* have all features as in elf_target
* due to previous check), we can benefit from recompiling the LLVM-IR if exists in binary (if
* there are errors, ignore them !).*/
if (((platform == amd::OclElf::CPU_PLATFORM) && ((target ^ elf_target) != 0)) ||
((platform == amd::OclElf::COMPLIB_PLATFORM) && ((target ^ chip_options) != 0))) {
if (elfIn_->getSection(amd::OclElf::LLVMIR, &section, &sz)) {
if ((section != NULL) && (sz > 0)) {
// hasDLL being false to force recompiling
RECOMPILE;
}
}
return OK;
}
return OK;
}
bool
ClBinary::loadX86(Program& program, std::string& dllName, bool& hasDLL)
{
hasDLL = false;
bool ClBinary::loadX86(Program& program, std::string& dllName, bool& hasDLL) {
hasDLL = false;
std::string tempName = amd::Os::getTempFileName();
std::string tempName = amd::Os::getTempFileName();
dllName = tempName
+ "." WINDOWS_SWITCH("dll",MACOS_SWITCH("dyld","so"));
dllName = tempName + "." WINDOWS_SWITCH("dll", MACOS_SWITCH("dyld", "so"));
switch (checkFeatures()) {
switch (checkFeatures()) {
case ERROR:
return false;
case RECOMPILE:
@@ -91,67 +86,63 @@ ClBinary::loadX86(Program& program, std::string& dllName, bool& hasDLL)
case OK:
// Fallthrough
break;
}
}
char* section;
size_t sz;
char* section;
size_t sz;
if (!elfIn_->getSection(amd::OclElf::DLL, &section, &sz)) {
LogError("Loading OCL CPU binary: error occured!");
return false;
}
if (!elfIn_->getSection(amd::OclElf::DLL, &section, &sz)) {
LogError("Loading OCL CPU binary: error occured!");
return false;
}
if ((section == NULL) || (sz == 0)) {
// hasDLL being false to force recompiling
return true;
}
if ((section == NULL) || (sz == 0)) {
// hasDLL being false to force recompiling
return true;
}
std::fstream f;
f.open(dllName.c_str(), (std::fstream::out | std::fstream::binary));
std::fstream f;
f.open(dllName.c_str(), (std::fstream::out | std::fstream::binary));
if (!f.is_open()) {
if (!f.is_open()) {
#ifdef _WIN32
amd::Os::unlink(tempName.c_str());
#endif // _WIN32
LogError("Loading OCL CPU binary: cannot open a file!");
return false;
}
f.write(section, sz);
f.close();
amd::Os::unlink(tempName.c_str());
#endif // _WIN32
LogError("Loading OCL CPU binary: cannot open a file!");
return false;
}
f.write(section, sz);
f.close();
hasDLL = true;
return true;
hasDLL = true;
return true;
}
bool
ClBinary::storeX86(Program& program, std::string& dllName)
{
std::fstream f;
f.open(dllName.c_str(), (std::fstream::in | std::fstream::binary));
if (!f.is_open()) {
return false;
}
bool ClBinary::storeX86(Program& program, std::string& dllName) {
std::fstream f;
f.open(dllName.c_str(), (std::fstream::in | std::fstream::binary));
if (!f.is_open()) {
return false;
}
f.seekg(0, std::fstream::end);
size_t x86CodeSize = f.tellg();
f.seekg(0, std::fstream::beg);
f.seekg(0, std::fstream::end);
size_t x86CodeSize = f.tellg();
f.seekg(0, std::fstream::beg);
if (saveISA()) {
char* x86Code = new char[x86CodeSize];
f.read(x86Code, x86CodeSize);
elfOut_->addSection(amd::OclElf::DLL, x86Code, x86CodeSize);
delete [] x86Code;
}
f.close();
return true;
if (saveISA()) {
char* x86Code = new char[x86CodeSize];
f.read(x86Code, x86CodeSize);
elfOut_->addSection(amd::OclElf::DLL, x86Code, x86CodeSize);
delete[] x86Code;
}
f.close();
return true;
}
bool
ClBinary::loadX86JIT(Program& program, bool& hasJITBinary)
{
bool ClBinary::loadX86JIT(Program& program, bool& hasJITBinary) {
hasJITBinary = false;
switch (checkFeatures()) {
switch (checkFeatures()) {
case ERROR:
return false;
case RECOMPILE:
@@ -159,66 +150,62 @@ ClBinary::loadX86JIT(Program& program, bool& hasJITBinary)
case OK:
// Fallthrough
break;
}
}
char* section;
size_t sz;
char* section;
size_t sz;
if (!elfIn_->getSection(amd::OclElf::JITBINARY, &section, &sz)) {
LogError("Loading OCL CPU JIT binary: error occured!");
return false;
}
if (!elfIn_->getSection(amd::OclElf::JITBINARY, &section, &sz)) {
LogError("Loading OCL CPU JIT binary: error occured!");
return false;
}
if ((section == NULL) || (sz == 0)) {
// force recompiling
return true;
}
acl_error err = ACL_SUCCESS;
program.setJITBinary(aclJITObjectImageCopy(program.compiler(), section, sz, &err));
if (err != ACL_SUCCESS) {
LogWarning("aclJITObjectImageCopy failed");
return false;
}
hasJITBinary = true;
if ((section == NULL) || (sz == 0)) {
// force recompiling
return true;
}
acl_error err = ACL_SUCCESS;
program.setJITBinary(aclJITObjectImageCopy(program.compiler(), section, sz, &err));
if (err != ACL_SUCCESS) {
LogWarning("aclJITObjectImageCopy failed");
return false;
}
hasJITBinary = true;
return true;
}
void checkDifference(const char* buf1, const char* buf2, size_t size) {
for(size_t i = 0; i < size; ++i) {
if(buf1[i] != buf2[i]) {
printf("Index %d different",(int)i);
for (size_t i = 0; i < size; ++i) {
if (buf1[i] != buf2[i]) {
printf("Index %d different", (int)i);
return;
}
}
}
bool
ClBinary::storeX86JIT(Program& program)
{
bool ClBinary::storeX86JIT(Program& program) {
if (saveISA()) {
acl_error err = ACL_SUCCESS;
aclJITObjectImage objectImage = program.getJITBinary();
size_t x86CodeSize = aclJITObjectImageSize(program.compiler(), objectImage, &err);
if (err != ACL_SUCCESS) {
LogWarning("aclJITObjectImageSize failed");
return false;
LogWarning("aclJITObjectImageSize failed");
return false;
}
const char* x86CodePtr = aclJITObjectImageData(program.compiler(), objectImage, &err);
if (err != ACL_SUCCESS) {
LogWarning("aclJITObjectImageData failed");
return false;
LogWarning("aclJITObjectImageData failed");
return false;
}
elfOut_->addSection(amd::OclElf::JITBINARY, x86CodePtr, x86CodeSize);
}
return true;
}
bool
ClBinary::storeX86Asm(const char* buffer, size_t size)
{
bool ClBinary::storeX86Asm(const char* buffer, size_t size) {
if (saveAS()) {
elfOut_->addSection(amd::OclElf::ASTEXT, buffer, size);
}
return true;
}
} // namespace cpu
} // namespace cpu
+40 -50
View File
@@ -17,69 +17,59 @@ class Device;
class Program;
//! \class CPU binary
class ClBinary : public device::ClBinary
{
public:
//! Constructor
ClBinary(const Device& dev) : device::ClBinary(dev) {}
class ClBinary : public device::ClBinary {
public:
//! Constructor
ClBinary(const Device& dev) : device::ClBinary(dev) {}
//! Destructor
~ClBinary() {}
//! Destructor
~ClBinary() {}
//! Loads x86 executable code
bool loadX86(
Program& prorgam, //!< CPU Program object
std::string& dllName, //!< Dll name of the CPU binary
bool& hasDLL //!< indicate if the OCL binary has DLL
);
//! Loads x86 executable code
bool loadX86(Program& prorgam, //!< CPU Program object
std::string& dllName, //!< Dll name of the CPU binary
bool& hasDLL //!< indicate if the OCL binary has DLL
);
//! Stores x86 executable code
bool storeX86(
Program& program, //!< CPU Program object
std::string& dllName //!< Dll name for the binary
);
//! Stores x86 executable code
bool storeX86(Program& program, //!< CPU Program object
std::string& dllName //!< Dll name for the binary
);
//! Loads x86 executable in-memory code
bool loadX86JIT(
Program& prorgam, //!< CPU Program object
bool& hasJITBin //!< indicate if the OCL binary has JIT binary
);
//! Loads x86 executable in-memory code
bool loadX86JIT(Program& prorgam, //!< CPU Program object
bool& hasJITBin //!< indicate if the OCL binary has JIT binary
);
//! Stores x86 executable in-memory code
bool storeX86JIT(
Program& program //!< CPU Program object
);
//! Stores x86 executable in-memory code
bool storeX86JIT(Program& program //!< CPU Program object
);
//! Set elf header information for CPU target
bool setElfTarget() {
uint32_t target = dev().settings().cpuFeatures_;
assert (((0xFFFF8000 & target) == 0) && "ASIC target ID >= 2^15");
uint16_t elf_target = (uint16_t)(0x7FFF & target);
return elfOut()->setTarget(elf_target, amd::OclElf::CPU_PLATFORM);
}
//! Set elf header information for CPU target
bool setElfTarget() {
uint32_t target = dev().settings().cpuFeatures_;
assert(((0xFFFF8000 & target) == 0) && "ASIC target ID >= 2^15");
uint16_t elf_target = (uint16_t)(0x7FFF & target);
return elfOut()->setTarget(elf_target, amd::OclElf::CPU_PLATFORM);
}
bool storeX86Asm(const char* buffer, size_t size);
private:
private:
enum FeatureCheckResult { ERROR, RECOMPILE, OK };
enum FeatureCheckResult {
ERROR,
RECOMPILE,
OK
};
FeatureCheckResult checkFeatures();
FeatureCheckResult checkFeatures();
//! Disable default copy constructor
ClBinary(const ClBinary&);
//! Disable default copy constructor
ClBinary(const ClBinary&);
//! Disable default operator=
ClBinary& operator=(const ClBinary&);
//! Disable default operator=
ClBinary& operator=(const ClBinary&);
//! Returns the GPU device for this object
const Device& dev() { return static_cast<const Device&>(dev_); }
//! Returns the GPU device for this object
const Device& dev() { return static_cast<const Device&>(dev_); }
};
} // namespace cpu
} // namespace cpu
#endif // CPUBINARY_HPP_
#endif // CPUBINARY_HPP_
+31 -36
View File
@@ -6,52 +6,47 @@
#include "device/cpu/cpucommand.hpp"
#include <amdocl/cl_kernel.h>
#include <cstdio> // for printf
#include <cstdio> // for printf
#include <stdarg.h>
#define BUF_SIZE_PRINTF 4095
//In the current implementation of printf in gcc 4.5.2 runtime libraries,inf/infinity and nan are not supported
//The [-]infinity value is printed as [-]1.#INF00
//The [-]nan value is printed as [-]1.#INF00
//bufOutUpdate converts the all printed instanced of [-]1.#INF00 to inf,and
// In the current implementation of printf in gcc 4.5.2 runtime libraries,inf/infinity and nan are
// not supported
// The [-]infinity value is printed as [-]1.#INF00
// The [-]nan value is printed as [-]1.#INF00
// bufOutUpdate converts the all printed instanced of [-]1.#INF00 to inf,and
// all printed instanced of [-]1.#IND00 to nan
void bufOutUpdate(std::string& sBufOut,const char* strToReplace,const char* strReplace)
{
size_t foundIdx = 0;
while ((foundIdx = sBufOut.find(strToReplace,foundIdx)) != std::string::npos) {
sBufOut.replace(foundIdx,strlen(strToReplace),strReplace,strlen(strReplace));
foundIdx += 3;
}
void bufOutUpdate(std::string& sBufOut, const char* strToReplace, const char* strReplace) {
size_t foundIdx = 0;
while ((foundIdx = sBufOut.find(strToReplace, foundIdx)) != std::string::npos) {
sBufOut.replace(foundIdx, strlen(strToReplace), strReplace, strlen(strReplace));
foundIdx += 3;
}
}
int cpuprintf(const char* format,...)
{
char cBufOut[BUF_SIZE_PRINTF];
std::string sBufOut;
va_list args;
va_start(args, format);
//write to the buffer
vsprintf(cBufOut,format,args);
sBufOut = cBufOut;
int cpuprintf(const char* format, ...) {
char cBufOut[BUF_SIZE_PRINTF];
std::string sBufOut;
va_list args;
va_start(args, format);
// write to the buffer
vsprintf(cBufOut, format, args);
sBufOut = cBufOut;
//convert to correct infinity/nan representation
bufOutUpdate(sBufOut,"1.#INF00","inf");
bufOutUpdate(sBufOut,"1.#IND00","nan");
bufOutUpdate(sBufOut,"1.#QNAN0","nan");
int ret = amd::Os::printf("%s",sBufOut.c_str());
fflush(stdout);
va_end (args);
return ret;
// convert to correct infinity/nan representation
bufOutUpdate(sBufOut, "1.#INF00", "inf");
bufOutUpdate(sBufOut, "1.#IND00", "nan");
bufOutUpdate(sBufOut, "1.#QNAN0", "nan");
int ret = amd::Os::printf("%s", sBufOut.c_str());
fflush(stdout);
va_end(args);
return ret;
}
namespace cpu {
const clk_builtins_t
Builtins::dispatchTable_ =
{
const clk_builtins_t Builtins::dispatchTable_ = {
/* Synchronization functions */
&WorkItem::barrier,
/* AMD Only builtins: FIXME_lmoriche: remove or add an extension */
NULL,
cpuprintf
};
NULL, cpuprintf};
} // namespace cpu
} // namespace cpu
+3 -4
View File
@@ -10,11 +10,10 @@
namespace cpu {
struct Builtins : public amd::AllStatic
{
static const clk_builtins_t dispatchTable_;
struct Builtins : public amd::AllStatic {
static const clk_builtins_t dispatchTable_;
};
} // namespace cpu
} // namespace cpu
#endif /*BUILTINS_HPP_*/
File diff suppressed because it is too large Load Diff
+235 -287
View File
@@ -15,7 +15,7 @@
#if defined(ATI_ARCH_ARM)
#include <setjmp.h>
#endif // ATI_ARCH_ARM
#endif // ATI_ARCH_ARM
namespace cpu {
@@ -27,94 +27,91 @@ namespace cpu {
*/
//! A saved stack context
class StackContext : public amd::StackObject
{
private:
class StackContext : public amd::StackObject {
private:
#if defined(ATI_ARCH_ARM)
jmp_buf env_;
jmp_buf env_;
#elif defined(_WIN64)
intptr_t __declspec(align(16)) regs_[32];
#else // !_WIN64
intptr_t regs_[LP64_SWITCH(6,8)];
#endif // !_WIN64
intptr_t __declspec(align(16)) regs_[32];
#else // !_WIN64
intptr_t regs_[LP64_SWITCH(6, 8)];
#endif // !_WIN64
public:
//! Save the stack context. Return 0 if returning directly.
inline intptr_t setjmp();
public:
//! Save the stack context. Return 0 if returning directly.
inline intptr_t setjmp();
//! Restore the stack context
inline void longjmp(intptr_t val) const;
//! Restore the stack context
inline void longjmp(intptr_t val) const;
};
//! A thread fiber
class Fiber : public amd::StackObject
{
private:
//! Next fiber in the thread.
Fiber* next_;
class Fiber : public amd::StackObject {
private:
//! Next fiber in the thread.
Fiber* next_;
//! This fiber's saved state.
StackContext context_;
//! This fiber's saved state.
StackContext context_;
public:
//! Construct a new Fiber
Fiber() : next_(NULL) { }
public:
//! Construct a new Fiber
Fiber() : next_(NULL) {}
//! Return the next fiber in the current thread.
const Fiber* next() const { return next_; }
//! Set the next fiber in the current thread.
void setNext(Fiber* next) { next_ = next; }
//! Return the next fiber in the current thread.
const Fiber* next() const { return next_; }
//! Set the next fiber in the current thread.
void setNext(Fiber* next) { next_ = next; }
//! Save the state of this fiber. Return true if directly returning.
ALWAYSINLINE bool save() { return context_.setjmp() == 0; }
//! Restore this fiber from the saved context.
void restore() const { context_.longjmp(1); }
//! Save the state of this fiber. Return true if directly returning.
ALWAYSINLINE bool save() { return context_.setjmp() == 0; }
//! Restore this fiber from the saved context.
void restore() const { context_.longjmp(1); }
//! Switch to the given fiber.
void swap(const Fiber* fiber) { if (save()) { fiber->restore(); } }
//! Switch to the given fiber.
void swap(const Fiber* fiber) {
if (save()) {
fiber->restore();
}
}
};
//! A CPU core operation (enqueued in the worker thread queue)
class Operation : public amd::HeapObject
{
public:
//! An atomic counter
class Counter
{
// FIXME_lmoriche: recycle the counters, implement a thread local pool.
private:
amd::Event& event_;
//! The atomic counter value.
amd::Atomic<size_t> counter_;
class Operation : public amd::HeapObject {
public:
//! An atomic counter
class Counter {
// FIXME_lmoriche: recycle the counters, implement a thread local pool.
private:
amd::Event& event_;
//! The atomic counter value.
amd::Atomic<size_t> counter_;
public:
//! Initialize the counter with the given initial value.
Counter(amd::Event& event, size_t initialValue) :
event_(event), counter_(initialValue) { }
//! Return the event associated with this counter.
amd::Event& event() { return event_; }
//! Decrement the counter and return the new value.
size_t decrement() { return --counter_; }
};
public:
//! Initialize the counter with the given initial value.
Counter(amd::Event& event, size_t initialValue) : event_(event), counter_(initialValue) {}
//! Return the event associated with this counter.
amd::Event& event() { return event_; }
//! Decrement the counter and return the new value.
size_t decrement() { return --counter_; }
};
protected:
amd::Command& command_;
protected:
amd::Command& command_;
public:
Operation(amd::Command& command) : command_(command)
{ }
public:
Operation(amd::Command& command) : command_(command) {}
virtual ~Operation() {};
virtual ~Operation(){};
virtual void clone(Operation* buf) = 0;
virtual void clone(Operation* buf) = 0;
void cleanup();
void cleanup();
amd::Command& command() { return command_;}
amd::Command& command() { return command_; }
virtual void execute() = 0;
virtual void execute() = 0;
};
/*! @}
@@ -123,243 +120,210 @@ public:
*/
//! A work item instance
class WorkItem : public Fiber
{
private:
//! Thread info block (must be the last field).
clk_thread_info_block_t tib_;
class WorkItem : public Fiber {
private:
//! Thread info block (must be the last field).
clk_thread_info_block_t tib_;
private:
//! Cannot be deleted (allocated with placement new).
void operator delete(void*) { ShouldNotCallThis(); }
private:
//! Cannot be deleted (allocated with placement new).
void operator delete(void*) { ShouldNotCallThis(); }
public:
//! Initialize this workgroup.
WorkItem(
const amd::NDRangeContainer& size,
void* scratchMemPtr,
void* localMemPtr);
public:
//! Initialize this workgroup.
WorkItem(const amd::NDRangeContainer& size, void* scratchMemPtr, void* localMemPtr);
//! Return the current WorkItem (based of the current stack pointer).
static WorkItem* current() {
return (WorkItem*)amd::alignUp((intptr_t) amd::Os::currentStackPtr(),
CLK_PRIVATE_MEMORY_SIZE) - 1;
}
//! Return the current WorkItem (based of the current stack pointer).
static WorkItem* current() {
return (WorkItem*)amd::alignUp((intptr_t)amd::Os::currentStackPtr(), CLK_PRIVATE_MEMORY_SIZE) -
1;
}
clk_thread_info_block_t& infoBlock() { return tib_; }
clk_thread_info_block_t& infoBlock() { return tib_; }
//! Return the native stack pointer base for this workitem.
address nativeStackPtr() const {
address newSp = amd::alignDown((address) this - CPUKERNEL_STACK_ALIGN,
CPUKERNEL_STACK_ALIGN);
WINDOWS_ONLY(NOT_WIN64(newSp += sizeof(void*)));
return newSp;
}
//! Return the native stack pointer base for this workitem.
address nativeStackPtr() const {
address newSp = amd::alignDown((address) this - CPUKERNEL_STACK_ALIGN, CPUKERNEL_STACK_ALIGN);
WINDOWS_ONLY(NOT_WIN64(newSp += sizeof(void*)));
return newSp;
}
//! These functions are mapping "n" from 1d index to the required dimension
inline void setGroupId(
const amd::NDRange& rangeLimits,
const amd::NDRange& offset,
size_t n);
inline void incrementGroupId(
const amd::NDRange& rangeLimits,
const amd::NDRange& offset,
size_t n);
//! These functions are mapping "n" from 1d index to the required dimension
inline void setGroupId(const amd::NDRange& rangeLimits, const amd::NDRange& offset, size_t n);
inline void incrementGroupId(const amd::NDRange& rangeLimits, const amd::NDRange& offset,
size_t n);
//! Execute a thread synchronization barrier.
static void barrier(cl_mem_fence_flags flags);
//! Execute a thread synchronization barrier.
static void barrier(cl_mem_fence_flags flags);
};
typedef void (*kernelentrypoint_t)(const void*);
//! Execute a workgroup (work-items).
class WorkGroup
{
private:
amd::NDRangeKernelCommand& command_;
const cpu::Kernel& kernel_;
WorkerThread& thread_;
address params_;
WorkItem* const workItem0_;
const Fiber* workingFiber_;
size_t numWorkItems_;
class WorkGroup {
private:
amd::NDRangeKernelCommand& command_;
const cpu::Kernel& kernel_;
WorkerThread& thread_;
address params_;
WorkItem* const workItem0_;
const Fiber* workingFiber_;
size_t numWorkItems_;
public:
WorkGroup(
amd::NDRangeKernelCommand& parent,
const cpu::Kernel& kernel,
WorkerThread& thread,
address params,
WorkItem* workItem0,
const size_t numWorkItems) :
command_(parent),
kernel_(kernel),
thread_(thread),
params_(params),
workItem0_(workItem0),
numWorkItems_(numWorkItems)
{ }
public:
WorkGroup(amd::NDRangeKernelCommand& parent, const cpu::Kernel& kernel, WorkerThread& thread,
address params, WorkItem* workItem0, const size_t numWorkItems)
: command_(parent),
kernel_(kernel),
thread_(thread),
params_(params),
workItem0_(workItem0),
numWorkItems_(numWorkItems) {}
WorkItem* getBaseWorkItem() { return workItem0_; }
WorkerThread& getWorkerThread() { return thread_; }
WorkItem* getBaseWorkItem() { return workItem0_; }
WorkerThread& getWorkerThread() { return thread_; }
void executeWorkItem(); // In case of 1 WorkItem
void executeWithBarrier();
void executeWithoutBarrier();
void executeWorkItem(); // In case of 1 WorkItem
void executeWithBarrier();
void executeWithoutBarrier();
void setNumWorkItems(size_t workItems) { numWorkItems_ = workItems; }
size_t getNumWorkItems() { return numWorkItems_; }
private:
void callKernelRange(
kernelentrypoint_t entryPoint,
address stackPtr,
clk_thread_info_block_t& tib);
inline void callKernel(
kernelentrypoint_t entryPoint,
address stackPtr);
inline void callKernelProtectedReturn(
kernelentrypoint_t entryPoint,
address stackPtr);
void setNumWorkItems(size_t workItems) { numWorkItems_ = workItems; }
size_t getNumWorkItems() { return numWorkItems_; }
private:
void callKernelRange(kernelentrypoint_t entryPoint, address stackPtr,
clk_thread_info_block_t& tib);
inline void callKernel(kernelentrypoint_t entryPoint, address stackPtr);
inline void callKernelProtectedReturn(kernelentrypoint_t entryPoint, address stackPtr);
};
class NDRangeKernelBatch : public Operation
{
protected:
size_t coreId_;
const size_t numWorkGroups_;
const size_t numCores_;
volatile size_t currentOpId_;
const amd::NDRange groupIds_; //!< Number of groups in each dimensions
VirtualCPU& virtualDevice_;
class NDRangeKernelBatch : public Operation {
protected:
size_t coreId_;
const size_t numWorkGroups_;
const size_t numCores_;
volatile size_t currentOpId_;
const amd::NDRange groupIds_; //!< Number of groups in each dimensions
VirtualCPU& virtualDevice_;
public:
enum ExecutionOrder {
ORDER_DEFAULT,
ORDER_ROUND_ROBIN = ORDER_DEFAULT,
//ORDER_LINEAR
};
public:
enum ExecutionOrder {
ORDER_DEFAULT,
ORDER_ROUND_ROBIN = ORDER_DEFAULT,
// ORDER_LINEAR
};
enum ExecutionNature {
NATURE_WITH_BARRIER,
NATURE_WITHOUT_BARRIER,
NATURE_1_WORK_ITEM,
NATURE_WG_LEVEL_EXEC
};
enum ExecutionNature {
NATURE_WITH_BARRIER,
NATURE_WITHOUT_BARRIER,
NATURE_1_WORK_ITEM,
NATURE_WG_LEVEL_EXEC
};
NDRangeKernelBatch(
amd::NDRangeKernelCommand& parent,
VirtualCPU& virtualDevice,
const amd::NDRange& groupIds, size_t numCores) :
Operation(parent),
coreId_(0),
numWorkGroups_(groupIds.product()),
numCores_(numCores),
currentOpId_(0),
groupIds_(groupIds),
virtualDevice_(virtualDevice)
{ }
NDRangeKernelBatch(amd::NDRangeKernelCommand& parent, VirtualCPU& virtualDevice,
const amd::NDRange& groupIds, size_t numCores)
: Operation(parent),
coreId_(0),
numWorkGroups_(groupIds.product()),
numCores_(numCores),
currentOpId_(0),
groupIds_(groupIds),
virtualDevice_(virtualDevice) {}
virtual void clone(Operation* buf)
{
::new(buf) NDRangeKernelBatch(static_cast<amd::NDRangeKernelCommand&>(command_),
virtualDevice_, groupIds_, numCores_);
static_cast<NDRangeKernelBatch*>(buf)->setCoreId(coreId_);
}
virtual void clone(Operation* buf) {
::new (buf) NDRangeKernelBatch(static_cast<amd::NDRangeKernelCommand&>(command_),
virtualDevice_, groupIds_, numCores_);
static_cast<NDRangeKernelBatch*>(buf)->setCoreId(coreId_);
}
virtual void execute();
virtual void execute();
void setCoreId(size_t coreId) { coreId_ = coreId; currentOpId_ = coreId; }
void setCoreId(size_t coreId) {
coreId_ = coreId;
currentOpId_ = coreId;
}
inline bool getNextOperationId(size_t& opId);
inline size_t getNextOperationIds(size_t& opId, size_t count);
inline bool getNextOperationId(size_t& opId);
inline size_t getNextOperationIds(size_t& opId, size_t count);
private:
bool patchParameters(
const cpu::Kernel& kernel,
address params,
address& localMemPtr,
const address localMemLimit,
size_t localMemSize) const;
private:
bool patchParameters(const cpu::Kernel& kernel, address params, address& localMemPtr,
const address localMemLimit, size_t localMemSize) const;
};
class NativeFn : public Operation
{
public:
NativeFn(amd::NativeFnCommand& parent) : Operation(parent)
{ }
class NativeFn : public Operation {
public:
NativeFn(amd::NativeFnCommand& parent) : Operation(parent) {}
virtual void clone(Operation* buf)
{
::new(buf) NativeFn(static_cast<amd::NativeFnCommand&>(command_));
}
virtual void clone(Operation* buf) {
::new (buf) NativeFn(static_cast<amd::NativeFnCommand&>(command_));
}
virtual void execute();
virtual void execute();
};
#ifndef MAX
#define MAX(x,y) ((x)>=(y) ?(x) : (y))
#endif //MAX
#define MAX(x, y) ((x) >= (y) ? (x) : (y))
#endif // MAX
#define MAX_OPERATION_ALLOC_SIZE (MAX(sizeof(NDRangeKernelBatch), sizeof(NativeFn)))
//! A thread bound to a cpu core.
class WorkerThread : public amd::Thread
{
private:
Fiber mainFiber_; //!< main fiber for this worker thread.
class WorkerThread : public amd::Thread {
private:
Fiber mainFiber_; //!< main fiber for this worker thread.
amd::Monitor queueLock_; //!< lock protecting the queue.
volatile int waitingOp_;
bool terminated_; //!< true if the thread is shutting down.
//! Local memory storage
address localDataStorage_;
//! Size of the local memory.
size_t localDataSize_;
amd::Monitor queueLock_; //!< lock protecting the queue.
volatile int waitingOp_;
bool terminated_; //!< true if the thread is shutting down.
char operation_[MAX_OPERATION_ALLOC_SIZE];
//! Local memory storage
address localDataStorage_;
//! Size of the local memory.
size_t localDataSize_;
address baseWorkItemsStack_;
private:
//! Awaits operations and execute them as they become ready.
void loop();
char operation_[MAX_OPERATION_ALLOC_SIZE];
public:
//! Construct a new WorkerThread.
WorkerThread(const cpu::Device& device);
//! Destroy the worker thread.
virtual ~WorkerThread();
//! Cleanup the thread before termination.
bool terminate();
address baseWorkItemsStack_;
//! Return the main fiber for this thread.
Fiber& mainFiber() { return mainFiber_; }
//! Return the LDS for this thread
address localDataStorage() const { return localDataStorage_; }
//! Return the size of the local memory for this thread.
size_t localDataSize() const { return localDataSize_; }
private:
//! Awaits operations and execute them as they become ready.
void loop();
address baseWorkItemsStack() { return baseWorkItemsStack_; }
public:
//! Construct a new WorkerThread.
WorkerThread(const cpu::Device& device);
//! Destroy the worker thread.
virtual ~WorkerThread();
//! Cleanup the thread before termination.
bool terminate();
Operation* operation() { return reinterpret_cast<Operation*>(operation_); }
bool isOperationValid() { return waitingOp_ > 0; }
//! Return the main fiber for this thread.
Fiber& mainFiber() { return mainFiber_; }
//! Return the LDS for this thread
address localDataStorage() const { return localDataStorage_; }
//! Return the size of the local memory for this thread.
size_t localDataSize() const { return localDataSize_; }
//! Enqueue a new operation to execute in this thread.
void enqueue(Operation& op);
//! Signal to start processing the commands in the queue.
void flush() { amd::ScopedLock sl(queueLock_); queueLock_.notify(); }
address baseWorkItemsStack() { return baseWorkItemsStack_; }
//! This thread's execution engine.
void run(void* data) {
loop();
}
Operation* operation() { return reinterpret_cast<Operation*>(operation_); }
bool isOperationValid() { return waitingOp_ > 0; }
bool isWorkerThread() const { return true; }
//! Enqueue a new operation to execute in this thread.
void enqueue(Operation& op);
//! Signal to start processing the commands in the queue.
void flush() {
amd::ScopedLock sl(queueLock_);
queueLock_.notify();
}
//! Return the currently executing WorkerThread's instance.
static WorkerThread* current()
{
return static_cast<WorkerThread*>(Thread::current());
}
//! This thread's execution engine.
void run(void* data) { loop(); }
bool isWorkerThread() const { return true; }
//! Return the currently executing WorkerThread's instance.
static WorkerThread* current() { return static_cast<WorkerThread*>(Thread::current()); }
};
/*! @}
@@ -371,59 +335,43 @@ extern "C" intptr_t _StackContext_setjmp(intptr_t* regs);
#if !defined(ATI_ARCH_ARM)
ALWAYSINLINE
#endif
intptr_t
StackContext::setjmp()
{
intptr_t StackContext::setjmp() {
#if defined(ATI_ARCH_ARM)
return ::setjmp(env_);
return ::setjmp(env_);
#else
return _StackContext_setjmp(regs_);
return _StackContext_setjmp(regs_);
#endif
}
extern "C" void _StackContext_longjmp(const intptr_t* env, intptr_t val);
ALWAYSINLINE void
StackContext::longjmp(intptr_t val) const
{
ALWAYSINLINE void StackContext::longjmp(intptr_t val) const {
#if defined(ATI_ARCH_ARM)
return ::longjmp(*const_cast<jmp_buf*>(&env_), val);
return ::longjmp(*const_cast<jmp_buf*>(&env_), val);
#else
return _StackContext_longjmp(regs_, val);
return _StackContext_longjmp(regs_, val);
#endif
}
extern "C" void _WorkGroup_callKernel(address params, kernelentrypoint_t entryPoint,
address stackPtr);
extern "C" void _WorkGroup_callKernel(
address params,
kernelentrypoint_t entryPoint,
address stackPtr);
extern "C" void _WorkGroup_callKernelProtectedReturn(
address params,
kernelentrypoint_t entryPoint,
address stackPtr);
extern "C" void _WorkGroup_callKernelProtectedReturn(address params, kernelentrypoint_t entryPoint,
address stackPtr);
ALWAYSINLINE void
WorkGroup::callKernel(
kernelentrypoint_t entryPoint,
address stackPtr)
{
_WorkGroup_callKernel(params_, entryPoint, stackPtr);
ALWAYSINLINE void WorkGroup::callKernel(kernelentrypoint_t entryPoint, address stackPtr) {
_WorkGroup_callKernel(params_, entryPoint, stackPtr);
}
// This version support the case of changing the stack for fibers.
ALWAYSINLINE void
WorkGroup::callKernelProtectedReturn(
kernelentrypoint_t entryPoint,
address stackPtr)
{
_WorkGroup_callKernelProtectedReturn(params_, entryPoint, stackPtr);
ALWAYSINLINE void WorkGroup::callKernelProtectedReturn(kernelentrypoint_t entryPoint,
address stackPtr) {
_WorkGroup_callKernelProtectedReturn(params_, entryPoint, stackPtr);
}
} // namespace cpu
} // namespace cpu
#endif /*OPERATION_HPP_*/
File diff suppressed because it is too large Load Diff
+125 -159
View File
@@ -21,9 +21,9 @@
namespace cpu {
//! Maximum number of the supported samplers
const static uint32_t MaxSamplers = 16;
const static uint32_t MaxSamplers = 16;
//! Maximum number of supported read images
const static uint32_t MaxReadImage = 128;
const static uint32_t MaxReadImage = 128;
//! Maximum number of supported write images
const static uint32_t MaxWriteImage = 64;
//! Maximum number of supported read/write images
@@ -40,203 +40,169 @@ const static uint32_t MaxReadWriteImage = 64;
*/
//! A CPU device ordinal
class Device : public amd::Device
{
protected:
static aclCompiler* compiler_;
public:
aclCompiler* compiler() const { return compiler_; }
class Device : public amd::Device {
protected:
static aclCompiler* compiler_;
public:
static bool init(void);
public:
aclCompiler* compiler() const { return compiler_; }
//! Shutdown CPU device
static void tearDown();
public:
static bool init(void);
//! Construct a new identifier
Device(Device* parent = NULL) :
amd::Device(parent),
workerThreadsAffinity_(NULL)
{}
//! Shutdown CPU device
static void tearDown();
virtual ~Device();
//! Construct a new identifier
Device(Device* parent = NULL) : amd::Device(parent), workerThreadsAffinity_(NULL) {}
bool create();
virtual ~Device();
virtual cl_int createSubDevices(
device::CreateSubDevicesInfo& create_info,
cl_uint num_entries,
cl_device_id* devices,
cl_uint* num_devices);
bool create();
//! Instantiate a new virtual device
virtual device::VirtualDevice* createVirtualDevice(
amd::CommandQueue* queue = NULL
)
{
VirtualCPU* virtualCpu = new VirtualCPU(*this);
if (virtualCpu != NULL && !virtualCpu->acceptingCommands()) {
virtualCpu->terminate();
delete virtualCpu;
virtualCpu = NULL;
}
return virtualCpu;
virtual cl_int createSubDevices(device::CreateSubDevicesInfo& create_info, cl_uint num_entries,
cl_device_id* devices, cl_uint* num_devices);
//! Instantiate a new virtual device
virtual device::VirtualDevice* createVirtualDevice(amd::CommandQueue* queue = NULL) {
VirtualCPU* virtualCpu = new VirtualCPU(*this);
if (virtualCpu != NULL && !virtualCpu->acceptingCommands()) {
virtualCpu->terminate();
delete virtualCpu;
virtualCpu = NULL;
}
return virtualCpu;
}
//! Compile the given source code.
virtual device::Program* createProgram(amd::option::Options* options = NULL);
//! Compile the given source code.
virtual device::Program* createProgram(amd::option::Options* options = NULL);
//! Just returns NULL as CPU devices use the host memory
virtual device::Memory* createMemory(amd::Memory& owner) const
{
return NULL;
}
//! Just returns NULL as CPU devices use the host memory
virtual device::Memory* createMemory(amd::Memory& owner) const { return NULL; }
//! Sampler object allocation
virtual bool createSampler(
const amd::Sampler& owner, //!< abstraction layer sampler object
device::Sampler** sampler //!< device sampler object
) const
{
// Just return NULL on CPU device
*sampler = NULL;
return true;
}
//! Sampler object allocation
virtual bool createSampler(const amd::Sampler& owner, //!< abstraction layer sampler object
device::Sampler** sampler //!< device sampler object
) const {
// Just return NULL on CPU device
*sampler = NULL;
return true;
}
//! Reallocates device memory obje
virtual bool reallocMemory(amd::Memory& owner) const
{
return true;
}
//! Reallocates device memory obje
virtual bool reallocMemory(amd::Memory& owner) const { return true; }
//! Just returns NULL as CPU devices use the host memory
virtual device::Memory* createView(
amd::Memory& owner, //!< Owner memory object
const device::Memory& parent //!< Parent device memory object for the view
) const
{
return NULL;
}
//! Just returns NULL as CPU devices use the host memory
virtual device::Memory* createView(
amd::Memory& owner, //!< Owner memory object
const device::Memory& parent //!< Parent device memory object for the view
) const {
return NULL;
}
//! Acquire external graphics API object in the host thread
//! Needed for OpenGL objects on CPU device
//! Acquire external graphics API object in the host thread
//! Needed for OpenGL objects on CPU device
//! Return true if initialized interoperability, otherwise false
virtual bool bindExternalDevice(uint flags, void* const pDevice[], void* pContext, bool validateOnly)
{
return true; // On CPU always avail if pD3DDevice is not NULL
}
//! Return true if initialized interoperability, otherwise false
virtual bool bindExternalDevice(uint flags, void* const pDevice[], void* pContext,
bool validateOnly) {
return true; // On CPU always avail if pD3DDevice is not NULL
}
virtual bool unbindExternalDevice(uint flags, void* const pDevice[], void* pContext, bool validateOnly)
{
return true;
}
virtual bool unbindExternalDevice(uint flags, void* const pDevice[], void* pContext,
bool validateOnly) {
return true;
}
//! Gets a pointer to a region of host-visible memory for use as the target
//! of a non-blocking map for a given memory object
virtual void* allocMapTarget(
amd::Memory& mem, //!< Abstraction layer memory object
const amd::Coord3D& origin, //!< The map location in memory
const amd::Coord3D& region, //!< The map region in memory
uint mapFlags, //!< Map flags
size_t* rowPitch = NULL, //!< Row pitch for the mapped memory
size_t* slicePitch = NULL //!< Slice for the mapped memory
);
//! Gets a pointer to a region of host-visible memory for use as the target
//! of a non-blocking map for a given memory object
virtual void* allocMapTarget(amd::Memory& mem, //!< Abstraction layer memory object
const amd::Coord3D& origin, //!< The map location in memory
const amd::Coord3D& region, //!< The map region in memory
uint mapFlags, //!< Map flags
size_t* rowPitch = NULL, //!< Row pitch for the mapped memory
size_t* slicePitch = NULL //!< Slice for the mapped memory
);
//! Releases non-blocking map target memory
virtual void freeMapTarget(amd::Memory& mem, void* target);
//! Releases non-blocking map target memory
virtual void freeMapTarget(amd::Memory& mem, void* target);
//! Empty implementation on a CPU device
virtual bool globalFreeMemory(size_t* freeMemory) const { return false; }
//! Empty implementation on a CPU device
virtual bool globalFreeMemory(size_t* freeMemory) const { return false; }
//! Get CPU device settings
const cpu::Settings& settings() const
{ return reinterpret_cast<cpu::Settings&>(*settings_); }
//! Get CPU device settings
const cpu::Settings& settings() const { return reinterpret_cast<cpu::Settings&>(*settings_); }
bool hasAVXInstructions() const
{ return (settings().cpuFeatures_ & Settings::AVXInstructions) ? true : false; }
bool hasAVXInstructions() const {
return (settings().cpuFeatures_ & Settings::AVXInstructions) ? true : false;
}
bool hasFMA4Instructions() const
{ return (settings().cpuFeatures_ & Settings::FMA4Instructions) ? true : false; }
bool hasFMA4Instructions() const {
return (settings().cpuFeatures_ & Settings::FMA4Instructions) ? true : false;
}
static size_t getMaxWorkerThreadsNumber() { return maxWorkerThreads_; }
static size_t getMaxWorkerThreadsNumber() { return maxWorkerThreads_; }
void setWorkerThreadsAffinity(
cl_uint numWorkerThreads,
const amd::Os::ThreadAffinityMask* threadsAffinityMask,
uint& baseCoreId);
void setWorkerThreadsAffinity(cl_uint numWorkerThreads,
const amd::Os::ThreadAffinityMask* threadsAffinityMask,
uint& baseCoreId);
const amd::Os::ThreadAffinityMask* getWorkerThreadsAffinity() const
{
return workerThreadsAffinity_;
}
//! host memory alloc
virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags, void* svmPtr) const
{
return NULL;
}
const amd::Os::ThreadAffinityMask* getWorkerThreadsAffinity() const {
return workerThreadsAffinity_;
}
//! host memory alloc
virtual void* svmAlloc(amd::Context& context, size_t size, size_t alignment,
cl_svm_mem_flags flags, void* svmPtr) const {
return NULL;
}
//! host memory deallocation
virtual void svmFree(void* ptr) const
{
return;
}
private:
bool initSubDevice(
device::Info& info,
cl_uint maxComputeUnits,
const device::CreateSubDevicesInfo& create_info);
//! host memory deallocation
virtual void svmFree(void* ptr) const { return; }
cl_int partitionEqually(
const device::CreateSubDevicesInfo& create_info,
cl_uint num_entries,
cl_device_id* devices,
cl_uint* num_devices);
private:
bool initSubDevice(device::Info& info, cl_uint maxComputeUnits,
const device::CreateSubDevicesInfo& create_info);
cl_int partitionByCounts(
const device::CreateSubDevicesInfo& create_info,
cl_uint num_entries,
cl_device_id* devices,
cl_uint* num_devices);
cl_int partitionEqually(const device::CreateSubDevicesInfo& create_info, cl_uint num_entries,
cl_device_id* devices, cl_uint* num_devices);
cl_int partitionByAffinityDomainNUMA(
const device::CreateSubDevicesInfo& create_info,
cl_uint num_entries,
cl_device_id* devices,
cl_uint* num_devices);
cl_int partitionByCounts(const device::CreateSubDevicesInfo& create_info, cl_uint num_entries,
cl_device_id* devices, cl_uint* num_devices);
cl_int partitionByAffinityDomainCacheLevel(
const device::CreateSubDevicesInfo& create_info,
cl_uint num_entries,
cl_device_id* devices,
cl_uint* num_devices);
cl_int partitionByAffinityDomainNUMA(const device::CreateSubDevicesInfo& create_info,
cl_uint num_entries, cl_device_id* devices,
cl_uint* num_devices);
private:
cl_int partitionByAffinityDomainCacheLevel(const device::CreateSubDevicesInfo& create_info,
cl_uint num_entries, cl_device_id* devices,
cl_uint* num_devices);
private:
#if defined(__linux__) && defined(NUMA_SUPPORT)
public:
const nodemask_t* getNumaMask() const
{
return (info_.partitionCreateInfo_.type_ == device::PartitionType::BY_AFFINITY_DOMAIN &&
info_.partitionCreateInfo_.byAffinityDomain_.numa_) ?
numaMask_ : NULL;
}
public:
const nodemask_t* getNumaMask() const {
return (info_.partitionCreateInfo_.type_ == device::PartitionType::BY_AFFINITY_DOMAIN &&
info_.partitionCreateInfo_.byAffinityDomain_.numa_)
? numaMask_
: NULL;
}
private:
union {
nodemask_t* numaMask_;
amd::Os::ThreadAffinityMask* workerThreadsAffinity_; //!< As the number of compute units.
};
private:
union {
nodemask_t* numaMask_;
amd::Os::ThreadAffinityMask* workerThreadsAffinity_; //!< As the number of compute units.
};
#else
amd::Os::ThreadAffinityMask* workerThreadsAffinity_; //!< As the number of compute units.
amd::Os::ThreadAffinityMask* workerThreadsAffinity_; //!< As the number of compute units.
#endif
static size_t maxWorkerThreads_; //!< Maximum number of Worker Threads
static size_t maxWorkerThreads_; //!< Maximum number of Worker Threads
};
/*! @}
* @}
*/
} // namespace cpu
} // namespace cpu
#endif // CPUDEVICE_HPP_
#endif // CPUDEVICE_HPP_
+1 -1
View File
@@ -24,4 +24,4 @@
#define CPUFEAT_DX_SSE (1 < 25)
#define CPUFEAT_DX_SSE2 (1 << 26)
#endif // CPUFEAT_HPP
#endif // CPUFEAT_HPP
+57 -69
View File
@@ -15,91 +15,79 @@
namespace cpu {
//! \class CPU kernel
class Kernel : public device::Kernel
{
private:
const void* entryPoint_; //!< entry for the kernel
class Kernel : public device::Kernel {
private:
const void* entryPoint_; //!< entry for the kernel
std::vector< std::pair<size_t, size_t> > args_;
std::vector< std::pair < HCtoDCmap, size_t> > HCtoDCmaps_;
std::vector< HCtoDCmap > internal_maps_;
public:
uint nature_; //!< kernel's nature
uint privateSize_; //!< WorkItem's private memory size (in bytes)
std::vector<std::pair<size_t, size_t> > args_;
std::vector<std::pair<HCtoDCmap, size_t> > HCtoDCmaps_;
std::vector<HCtoDCmap> internal_maps_;
private:
//! Disable default copy constructor
Kernel(const Kernel&);
//! Disable operator=
Kernel& operator=(const Kernel&);
public:
uint nature_; //!< kernel's nature
uint privateSize_; //!< WorkItem's private memory size (in bytes)
public:
void addArg(size_t size, size_t alignment) {
args_.push_back(std::pair<size_t, size_t>(size, alignment));
}
private:
//! Disable default copy constructor
Kernel(const Kernel&);
//! Disable operator=
Kernel& operator=(const Kernel&);
size_t getArgSize(int argIndex) const {
return args_[argIndex].first;
}
public:
void addArg(size_t size, size_t alignment) {
args_.push_back(std::pair<size_t, size_t>(size, alignment));
}
size_t getArgAlignment(int argIndex) const {
return args_[argIndex].second;
}
size_t getArgSize(int argIndex) const { return args_[argIndex].first; }
void addInternalMap(HCtoDCmap *new_map) {
if (new_map != NULL) {
internal_maps_.push_back(*new_map);
this->addInternalMap(new_map->internal_field_map);
this->addInternalMap(new_map->next_field_map);
}
else
return;
}
size_t getArgAlignment(int argIndex) const { return args_[argIndex].second; }
void addHCtoDCmap(HCtoDCmap *new_map) {
if (new_map != NULL) {
if (HCtoDCmaps_.size() > 0)
HCtoDCmaps_.push_back(std::pair< HCtoDCmap, size_t >(*new_map, HCtoDCmaps_.back().second));
else
HCtoDCmaps_.push_back(std::pair< HCtoDCmap, size_t >(*new_map, 0));
}
else
return;
}
void addInternalMap(HCtoDCmap* new_map) {
if (new_map != NULL) {
internal_maps_.push_back(*new_map);
this->addInternalMap(new_map->internal_field_map);
this->addInternalMap(new_map->next_field_map);
} else
return;
}
HCtoDCmap getHCtoDCmap(int mapIndex) const {
return HCtoDCmaps_[mapIndex].first;
}
void addHCtoDCmap(HCtoDCmap* new_map) {
if (new_map != NULL) {
if (HCtoDCmaps_.size() > 0)
HCtoDCmaps_.push_back(std::pair<HCtoDCmap, size_t>(*new_map, HCtoDCmaps_.back().second));
else
HCtoDCmaps_.push_back(std::pair<HCtoDCmap, size_t>(*new_map, 0));
} else
return;
}
HCtoDCmap getHCtoDCmap(int mapIndex) const { return HCtoDCmaps_[mapIndex].first; }
uint getArgNumber() {
return HCtoDCmaps_.size();
}
uint getArgNumber() { return HCtoDCmaps_.size(); }
//! Default constructor
Kernel(const std::string& name)
: device::Kernel(name), entryPoint_(NULL), nature_(0),
privateSize_(CLK_PRIVATE_MEMORY_SIZE)
{
workGroupInfo_.size_ = CPU_MAX_WORKGROUP_SIZE;
}
//! Default constructor
Kernel(const std::string& name)
: device::Kernel(name), entryPoint_(NULL), nature_(0), privateSize_(CLK_PRIVATE_MEMORY_SIZE) {
workGroupInfo_.size_ = CPU_MAX_WORKGROUP_SIZE;
}
//! Default destructor
~Kernel() {}
//! Default destructor
~Kernel() {}
//! Returns the CPU kernel entry point
const void* getEntryPoint() const { return entryPoint_; }
//! Returns the CPU kernel entry point
const void* getEntryPoint() const { return entryPoint_; }
//! Sets the CPU kernel entry point
void setEntryPoint(const void* entryPoint) { entryPoint_ = entryPoint; }
//! Sets the CPU kernel entry point
void setEntryPoint(const void* entryPoint) { entryPoint_ = entryPoint; }
//! Returns true if the kernel has a call to barrier
bool hasBarrier() const { return 0 != (nature_ & KN_HAS_BARRIER); }
//! Returns true if the kernel has a call to barrier
bool hasBarrier() const { return 0 != (nature_ & KN_HAS_BARRIER); }
//! Returns the private memory size of a single WorkItem
uint getWorkItemPrivateMemSize() const { return privateSize_; }
//! Returns the private memory size of a single WorkItem
uint getWorkItemPrivateMemSize() const { return privateSize_; }
};
} // namespace cpu
} // namespace cpu
#endif // CPUKERNEL_HPP_
#endif // CPUKERNEL_HPP_
+389 -340
View File
@@ -25,354 +25,403 @@ using std::min;
using std::max;
namespace cpu {
HCtoDCmap::HCtoDCmap(const clk_parameter_descriptor_t* desc, unsigned int level_alignment, unsigned int index, unsigned int init_offset)
{
level_alignment = std::max(level_alignment, 1u); // Minimal possible alignment is 1 and alignment is used as a divisor below.
//Initialize fields
hc_offset = 0;
hc_size = 0;
dc_offset = 0;
dc_size = 0;
hc_alignment = level_alignment;
dc_alignment = level_alignment;
internal_field_map = NULL;
next_field_map = NULL;
return;
}
HCtoDCmap::HCtoDCmap(const clk_parameter_descriptor_t* desc, unsigned int level_alignment,
unsigned int index, unsigned int init_offset) {
level_alignment =
std::max(level_alignment,
1u); // Minimal possible alignment is 1 and alignment is used as a divisor below.
// Initialize fields
hc_offset = 0;
hc_size = 0;
dc_offset = 0;
dc_size = 0;
hc_alignment = level_alignment;
dc_alignment = level_alignment;
internal_field_map = NULL;
next_field_map = NULL;
return;
}
HCtoDCmap::~HCtoDCmap()
{
return;
}
HCtoDCmap::~HCtoDCmap() { return; }
//Helper to find sizes of each scalar type
size_t HCtoDCmap::getHostScalarParamSize(const clk_value_type_t type) const
{
size_t size = 0;
switch (type) {
case T_CHAR:
size = 1;
break;
case T_SHORT: case T_CHAR2:
size = 2;
break;
case T_FLOAT: case T_INT: case T_CHAR4:
case T_SHORT2: case T_CHAR3:
size = 4;
break;
case T_SAMPLER:
size = 4;
break;
case T_LONG: case T_DOUBLE: case T_CHAR8:
case T_SHORT4: case T_INT2: case T_FLOAT2:
case T_SHORT3:
size = 8;
break;
case T_INT3: case T_FLOAT3:
case T_CHAR16: case T_SHORT8: case T_INT4:
case T_FLOAT4: case T_LONG2: case T_DOUBLE2:
size = 16;
break;
case T_LONG3: case T_DOUBLE3:
case T_SHORT16: case T_INT8: case T_FLOAT8:
case T_LONG4: case T_DOUBLE4:
size = 32;
break;
case T_INT16: case T_FLOAT16: case T_LONG8:
case T_DOUBLE8:
size = 64;
break;
case T_LONG16: case T_DOUBLE16:
size = 128;
break;
case T_POINTER: case T_VOID:
size = sizeof(void*);
break;
default:
assert(0 && "unknown scalar parameter size");
break;
}
return size;
}
// Helper to find sizes of each scalar type
size_t HCtoDCmap::getHostScalarParamSize(const clk_value_type_t type) const {
size_t size = 0;
switch (type) {
case T_CHAR:
size = 1;
break;
case T_SHORT:
case T_CHAR2:
size = 2;
break;
case T_FLOAT:
case T_INT:
case T_CHAR4:
case T_SHORT2:
case T_CHAR3:
size = 4;
break;
case T_SAMPLER:
size = 4;
break;
case T_LONG:
case T_DOUBLE:
case T_CHAR8:
case T_SHORT4:
case T_INT2:
case T_FLOAT2:
case T_SHORT3:
size = 8;
break;
case T_INT3:
case T_FLOAT3:
case T_CHAR16:
case T_SHORT8:
case T_INT4:
case T_FLOAT4:
case T_LONG2:
case T_DOUBLE2:
size = 16;
break;
case T_LONG3:
case T_DOUBLE3:
case T_SHORT16:
case T_INT8:
case T_FLOAT8:
case T_LONG4:
case T_DOUBLE4:
size = 32;
break;
case T_INT16:
case T_FLOAT16:
case T_LONG8:
case T_DOUBLE8:
size = 64;
break;
case T_LONG16:
case T_DOUBLE16:
size = 128;
break;
case T_POINTER:
case T_VOID:
size = sizeof(void*);
break;
default:
assert(0 && "unknown scalar parameter size");
break;
}
return size;
}
size_t HCtoDCmap::getScalarAlignment(const clk_value_type_t type, bool isHost) const
{
size_t align = 0;
switch (type) {
case T_CHAR:
align = 1;
break;
case T_SHORT: case T_CHAR2:
align = 2;
break;
case T_FLOAT: case T_INT: case T_CHAR4:
case T_SHORT2: case T_CHAR3:
align = 4;
break;
case T_SAMPLER:
align = sizeof(uint32_t);
break;
case T_LONG:
#if defined(_WIN32)
align = 8;
#else
align = isHost? 8 : LP64_SWITCH(4, 8);
#endif
break;
case T_DOUBLE:
#if defined(_WIN32)
align = 8;
#else
align = LP64_SWITCH(4, 8);
#endif
break;
case T_CHAR8:
case T_SHORT4: case T_INT2: case T_FLOAT2:
case T_SHORT3:
align = 4;
break;
case T_INT3: case T_FLOAT3:
case T_CHAR16: case T_SHORT8: case T_INT4:
case T_FLOAT4: case T_LONG2: case T_DOUBLE2:
case T_LONG3: case T_DOUBLE3:
case T_SHORT16: case T_INT8: case T_FLOAT8:
case T_LONG4: case T_DOUBLE4:
case T_INT16: case T_FLOAT16: case T_LONG8:
case T_DOUBLE8:
case T_LONG16: case T_DOUBLE16:
align = LP64_SWITCH(4, 8);
break;
case T_POINTER: case T_VOID:
align = sizeof(void*);
break;
default:
assert(0 && "unknown scalar parameter alignment");
break;
}
return align;
}
size_t HCtoDCmap::getScalarAlignment(const clk_value_type_t type, bool isHost) const {
size_t align = 0;
switch (type) {
case T_CHAR:
align = 1;
break;
case T_SHORT:
case T_CHAR2:
align = 2;
break;
case T_FLOAT:
case T_INT:
case T_CHAR4:
case T_SHORT2:
case T_CHAR3:
align = 4;
break;
case T_SAMPLER:
align = sizeof(uint32_t);
break;
case T_LONG:
#if defined(_WIN32)
align = 8;
#else
align = isHost ? 8 : LP64_SWITCH(4, 8);
#endif
break;
case T_DOUBLE:
#if defined(_WIN32)
align = 8;
#else
align = LP64_SWITCH(4, 8);
#endif
break;
case T_CHAR8:
case T_SHORT4:
case T_INT2:
case T_FLOAT2:
case T_SHORT3:
align = 4;
break;
case T_INT3:
case T_FLOAT3:
case T_CHAR16:
case T_SHORT8:
case T_INT4:
case T_FLOAT4:
case T_LONG2:
case T_DOUBLE2:
case T_LONG3:
case T_DOUBLE3:
case T_SHORT16:
case T_INT8:
case T_FLOAT8:
case T_LONG4:
case T_DOUBLE4:
case T_INT16:
case T_FLOAT16:
case T_LONG8:
case T_DOUBLE8:
case T_LONG16:
case T_DOUBLE16:
align = LP64_SWITCH(4, 8);
break;
case T_POINTER:
case T_VOID:
align = sizeof(void*);
break;
default:
assert(0 && "unknown scalar parameter alignment");
break;
}
return align;
}
// Align up arguments within each map, return the size of current map parameter
// Input current alignment of the parameter, size of outer struct if it exists
void HCtoDCmap::align_map(unsigned outer_hc_alignment, unsigned outer_dc_alignment, unsigned &outer_hc_size, unsigned &outer_dc_size, int &inStruct)
{
unsigned map_param_size = 0;
if (internal_field_map != NULL) {
hc_size = 0; //Recalculate size to account for internal offsets
inStruct++;
internal_field_map->align_map(hc_alignment, dc_alignment, hc_size, dc_size, inStruct); // align internal struct, might alter size of this struct
if (hc_alignment != 1 && hc_size%hc_alignment)
hc_size = max(hc_size, hc_size - (hc_size%hc_alignment) + hc_alignment);
if (dc_alignment != 1 && dc_size%dc_alignment)
dc_size = max(dc_size, dc_size - (dc_size%dc_alignment) + dc_alignment);
}
// Use map_param_size to store current parameter size after adjusting alignment
if (hc_alignment != 1 && hc_size % hc_alignment != 0) {
map_param_size = max(hc_alignment, hc_size - (hc_size%hc_alignment) + hc_alignment);
}
else {
map_param_size = max(hc_alignment, hc_size);
}
if (next_field_map != NULL) {
next_field_map->hc_offset = this->next_offset(hc_offset, map_param_size, inStruct);
next_field_map->align_map(outer_hc_alignment, outer_dc_alignment, outer_hc_size, outer_dc_size, inStruct);
// Reset parameter size for char padding
if (next_field_map->type == T_CHAR)
map_param_size = 1;
}
else
{
// Moving out of struct
if (inStruct > 0)
inStruct--;
if (type == T_CHAR)
map_param_size = 1;
}
outer_hc_size = max(outer_hc_size, hc_offset+map_param_size);
outer_dc_size = max(outer_dc_size, dc_offset+dc_size);
return;
}
// Align up arguments within each map, return the size of current map parameter
// Input current alignment of the parameter, size of outer struct if it exists
void HCtoDCmap::align_map(unsigned outer_hc_alignment, unsigned outer_dc_alignment,
unsigned& outer_hc_size, unsigned& outer_dc_size, int& inStruct) {
unsigned map_param_size = 0;
if (internal_field_map != NULL) {
hc_size = 0; // Recalculate size to account for internal offsets
inStruct++;
internal_field_map->align_map(
hc_alignment, dc_alignment, hc_size, dc_size,
inStruct); // align internal struct, might alter size of this struct
if (hc_alignment != 1 && hc_size % hc_alignment)
hc_size = max(hc_size, hc_size - (hc_size % hc_alignment) + hc_alignment);
if (dc_alignment != 1 && dc_size % dc_alignment)
dc_size = max(dc_size, dc_size - (dc_size % dc_alignment) + dc_alignment);
}
// Use map_param_size to store current parameter size after adjusting alignment
if (hc_alignment != 1 && hc_size % hc_alignment != 0) {
map_param_size = max(hc_alignment, hc_size - (hc_size % hc_alignment) + hc_alignment);
} else {
map_param_size = max(hc_alignment, hc_size);
}
if (next_field_map != NULL) {
next_field_map->hc_offset = this->next_offset(hc_offset, map_param_size, inStruct);
next_field_map->align_map(outer_hc_alignment, outer_dc_alignment, outer_hc_size, outer_dc_size,
inStruct);
// Reset parameter size for char padding
if (next_field_map->type == T_CHAR) map_param_size = 1;
} else {
// Moving out of struct
if (inStruct > 0) inStruct--;
if (type == T_CHAR) map_param_size = 1;
}
outer_hc_size = max(outer_hc_size, hc_offset + map_param_size);
outer_dc_size = max(outer_dc_size, dc_offset + dc_size);
return;
}
// Return current size of map, calculate internal maps and process next args if in struct.
// Alignment: alignment flag for members in case of structs, alignment of scalar otherwise.
int HCtoDCmap::compute_map(const clk_parameter_descriptor_t* desc, unsigned int &outer_hc_alignment, unsigned int &outer_dc_alignment, unsigned int init_offset, int& inStruct, int& index_out)
{
unsigned internal_index;
// Return current size of map, calculate internal maps and process next args if in struct.
// Alignment: alignment flag for members in case of structs, alignment of scalar otherwise.
int HCtoDCmap::compute_map(const clk_parameter_descriptor_t* desc, unsigned int& outer_hc_alignment,
unsigned int& outer_dc_alignment, unsigned int init_offset,
int& inStruct, int& index_out) {
unsigned internal_index;
internal_index = index_out;
unsigned int next_offset = init_offset;
unsigned struct_size = 0;
type = desc[internal_index].type;
if (desc[internal_index].type == T_STRUCT) {
// Moving into struct, go to next index
inStruct++;
hc_offset = init_offset;
if (desc[index_out + 1].type != T_VOID) {
index_out++;
internal_index = index_out;
internal_field_map = new HCtoDCmap(desc, 0, internal_index, init_offset);
hc_size = internal_field_map->compute_map(desc, hc_alignment, dc_alignment, next_offset,
inStruct, index_out);
hc_alignment =
max(hc_alignment,
internal_field_map->hc_alignment); // Adjust alignment to biggest member alignment
struct_size = hc_size;
internal_index = index_out;
outer_hc_alignment = max(outer_hc_alignment, hc_alignment);
if (inStruct > 0) {
if (desc[index_out + 1].type != T_VOID) {
// Still inside struct and not done
index_out++;
internal_index = index_out;
next_field_map = new HCtoDCmap(desc, 0, internal_index, next_offset);
struct_size = hc_size;
struct_size += next_field_map->compute_map(desc, outer_hc_alignment, outer_dc_alignment,
next_offset, inStruct, index_out);
next_offset = max(next_field_map->hc_offset + next_field_map->hc_size,
next_field_map->hc_offset + hc_alignment);
// running count of strucdc_size = hc_size + size of next member
return struct_size;
} else {
// Moving out of struct, go to next index
index_out++;
internal_index = index_out;
inStruct--;
return hc_size; // return last struct member size
}
}
}
} else if (desc[internal_index].type == T_PAD) {
// Struct has padding
hc_offset = init_offset;
if (desc[index_out + 1].type != T_VOID) {
index_out++;
internal_index = index_out;
internal_field_map = new HCtoDCmap(desc, 0, internal_index, init_offset);
hc_size = internal_field_map->compute_map(desc, hc_alignment, dc_alignment, next_offset,
inStruct, index_out);
// Adjust alignment to biggest member alignment
hc_alignment = 1;
dc_alignment = 1;
unsigned pad_size = hc_size;
internal_index = index_out;
if (desc[index_out + 1].type != T_VOID) {
// Still inside padding and not done
index_out++;
internal_index = index_out;
unsigned int next_offset = init_offset;
unsigned struct_size = 0;
type = desc[internal_index].type;
if (desc[internal_index].type == T_STRUCT) {
//Moving into struct, go to next index
inStruct++;
hc_offset = init_offset;
if (desc[index_out+1].type != T_VOID) {
index_out++;
internal_index = index_out;
internal_field_map = new HCtoDCmap(desc, 0, internal_index, init_offset);
hc_size = internal_field_map->compute_map(desc, hc_alignment, dc_alignment, next_offset, inStruct, index_out);
hc_alignment = max(hc_alignment, internal_field_map->hc_alignment); // Adjust alignment to biggest member alignment
struct_size = hc_size;
internal_index = index_out;
outer_hc_alignment = max(outer_hc_alignment, hc_alignment);
if (inStruct > 0) {
if (desc[index_out+1].type != T_VOID) {
//Still inside struct and not done
index_out++;
internal_index = index_out;
next_field_map = new HCtoDCmap(desc, 0, internal_index, next_offset);
struct_size = hc_size;
struct_size += next_field_map->compute_map(desc, outer_hc_alignment, outer_dc_alignment, next_offset, inStruct, index_out);
next_offset = max(next_field_map->hc_offset+next_field_map->hc_size, next_field_map->hc_offset+hc_alignment);
// running count of strucdc_size = hc_size + size of next member
return struct_size;
}
else {
//Moving out of struct, go to next index
index_out++;
internal_index = index_out;
inStruct--;
return hc_size; //return last struct member size
}
}
}
}
else if (desc[internal_index].type == T_PAD) {
//Struct has padding
hc_offset = init_offset;
if (desc[index_out+1].type != T_VOID) {
index_out++;
internal_index = index_out;
internal_field_map = new HCtoDCmap(desc, 0, internal_index, init_offset);
hc_size = internal_field_map->compute_map(desc, hc_alignment, dc_alignment, next_offset, inStruct, index_out);
// Adjust alignment to biggest member alignment
hc_alignment = 1;
dc_alignment = 1;
unsigned pad_size = hc_size;
internal_index = index_out;
if (desc[index_out+1].type != T_VOID) {
//Still inside padding and not done
index_out++;
internal_index = index_out;
next_field_map = new HCtoDCmap(desc, 0, internal_index, next_offset);
pad_size = hc_size;
pad_size += next_field_map->compute_map(desc, outer_hc_alignment, outer_dc_alignment, next_offset, inStruct, index_out);
next_offset = max(next_field_map->hc_offset+next_field_map->hc_size, next_field_map->hc_offset+hc_alignment);
// running count of padding dc_size = hc_size + size of next member
return pad_size;
}
else {
//Moving out of struct, go to next index
index_out++;
internal_index = index_out;
return hc_size; //return last padding member size
}
}
}
else {
//Scalar parameter
hc_offset = init_offset;
hc_size = getHostScalarParamSize(desc[internal_index].type);
dc_size = hc_size;
hc_alignment = getScalarAlignment(desc[internal_index].type, true);
dc_alignment = getScalarAlignment(desc[internal_index].type, false);
outer_hc_alignment = max(outer_hc_alignment, hc_alignment); //Adjust alignment of upper level struct if necessary, upper level alignment = max alignment of members
outer_dc_alignment = max(outer_dc_alignment, dc_alignment); //Adjust alignment of upper level struct if necessary, upper level alignment = max alignment of members
if (inStruct > 0) {
if (desc[index_out+1].type != T_VOID) {
//Still inside struct and not done
index_out++;
next_field_map = new HCtoDCmap(desc, outer_hc_alignment, internal_index, next_offset);
struct_size = hc_size;
struct_size += next_field_map->compute_map(desc, outer_hc_alignment, outer_dc_alignment, next_offset, inStruct, index_out);
next_offset = hc_offset+hc_alignment;
outer_hc_alignment = max(outer_hc_alignment, next_field_map->hc_alignment);
outer_dc_alignment = max(outer_dc_alignment, next_field_map->dc_alignment);
// running count of strucdc_size = hc_size + size of next member
return struct_size;
}
else {
//Moving out of struct, go to next index
index_out++;
inStruct--;
return hc_size; //return last struct member size
}
}
}
return hc_size;
next_field_map = new HCtoDCmap(desc, 0, internal_index, next_offset);
pad_size = hc_size;
pad_size += next_field_map->compute_map(desc, outer_hc_alignment, outer_dc_alignment,
next_offset, inStruct, index_out);
next_offset = max(next_field_map->hc_offset + next_field_map->hc_size,
next_field_map->hc_offset + hc_alignment);
// running count of padding dc_size = hc_size + size of next member
return pad_size;
} else {
// Moving out of struct, go to next index
index_out++;
internal_index = index_out;
return hc_size; // return last padding member size
}
}
// Adjust offset for source and target, return next source offset
unsigned HCtoDCmap::next_offset(unsigned current_offset, unsigned &map_param_size, int& inStruct_flag)
{
unsigned next_offset = current_offset;
if (next_field_map == NULL) {
assert(0 && "invalid next struct field map");
return next_offset;
}
else {
// Ignore alignment when a char occurs to account for padding
if (type == T_PAD) {
next_field_map->dc_offset = dc_offset + dc_size;
next_offset = current_offset + hc_size;
}
else {
if ((dc_offset + dc_size) % next_field_map->dc_alignment != 0) {
this->next_field_map->dc_offset = dc_offset + dc_size - (dc_size % next_field_map->dc_alignment) + next_field_map->dc_alignment;
}
else {
this->next_field_map->dc_offset = dc_offset + max(dc_size, next_field_map->dc_alignment);
}
if ((hc_offset + hc_size) % next_field_map->hc_alignment != 0) {
next_offset = hc_offset + hc_size - (hc_size % next_field_map->hc_alignment) + next_field_map->hc_alignment;
}
else {
next_offset = hc_offset + max(next_field_map->hc_alignment, map_param_size);
}
}
return next_offset;
}
} else {
// Scalar parameter
hc_offset = init_offset;
hc_size = getHostScalarParamSize(desc[internal_index].type);
dc_size = hc_size;
hc_alignment = getScalarAlignment(desc[internal_index].type, true);
dc_alignment = getScalarAlignment(desc[internal_index].type, false);
outer_hc_alignment = max(outer_hc_alignment, hc_alignment); // Adjust alignment of upper level
// struct if necessary, upper level
// alignment = max alignment of
// members
outer_dc_alignment = max(outer_dc_alignment, dc_alignment); // Adjust alignment of upper level
// struct if necessary, upper level
// alignment = max alignment of
// members
if (inStruct > 0) {
if (desc[index_out + 1].type != T_VOID) {
// Still inside struct and not done
index_out++;
next_field_map = new HCtoDCmap(desc, outer_hc_alignment, internal_index, next_offset);
struct_size = hc_size;
struct_size += next_field_map->compute_map(desc, outer_hc_alignment, outer_dc_alignment,
next_offset, inStruct, index_out);
next_offset = hc_offset + hc_alignment;
outer_hc_alignment = max(outer_hc_alignment, next_field_map->hc_alignment);
outer_dc_alignment = max(outer_dc_alignment, next_field_map->dc_alignment);
// running count of strucdc_size = hc_size + size of next member
return struct_size;
} else {
// Moving out of struct, go to next index
index_out++;
inStruct--;
return hc_size; // return last struct member size
}
}
}
return hc_size;
}
// Copy memory according to mapping
unsigned int HCtoDCmap::copy_params(void *dst, const void *src, unsigned int arg_offset, int& error_code, int &inStruct) const
{
unsigned int padding = 0;
// Pad offset to be aligned by 8 if parameter is double, not as struct field
if ((arg_offset) % 8 != 0 && (type == T_DOUBLE) && inStruct == 0)
padding = hc_alignment-((arg_offset+dc_offset)%hc_alignment);
#if defined(_WIN32)
// In windows, double is aligned by 8, add padding to struct if it contains double
if ((arg_offset+dc_offset) % 8 != 0 && hc_alignment == 8)
padding = hc_alignment-((arg_offset+dc_offset)%hc_alignment);
#endif
::memcpy(reinterpret_cast<void *>(reinterpret_cast<unsigned char*>(dst)+padding), src, hc_size);
#if defined(_WIN32)
if (internal_field_map != NULL) {
inStruct++;
void *internal_dst = reinterpret_cast<void *>(reinterpret_cast<unsigned char*>(dst)+padding);
internal_field_map->copy_params(internal_dst, src, arg_offset+padding, error_code, inStruct);
inStruct--;
}
if (next_field_map != NULL) {
void *next_dst = reinterpret_cast<void *>(reinterpret_cast<unsigned char*>(dst)+next_field_map->dc_offset); // Next field starts with padding
const void *next_src = reinterpret_cast<const void *>(reinterpret_cast<const unsigned char*>(src)+next_field_map->hc_offset);
next_field_map->copy_params(next_dst, next_src, arg_offset+next_field_map->dc_offset, error_code, inStruct);
}
#else
if (internal_field_map != NULL) {
inStruct++;
internal_field_map->copy_params(dst, src, arg_offset, error_code, inStruct);
inStruct--;
}
if (next_field_map != NULL) {
void *next_dst = reinterpret_cast<void *>(reinterpret_cast<unsigned char*>(dst)+next_field_map->dc_offset);
const void *next_src = reinterpret_cast<const void *>(reinterpret_cast<const unsigned char*>(src)+next_field_map->hc_offset);
next_field_map->copy_params(next_dst, next_src, arg_offset, error_code, inStruct);
}
#endif
return padding;
// Adjust offset for source and target, return next source offset
unsigned HCtoDCmap::next_offset(unsigned current_offset, unsigned& map_param_size,
int& inStruct_flag) {
unsigned next_offset = current_offset;
if (next_field_map == NULL) {
assert(0 && "invalid next struct field map");
return next_offset;
} else {
// Ignore alignment when a char occurs to account for padding
if (type == T_PAD) {
next_field_map->dc_offset = dc_offset + dc_size;
next_offset = current_offset + hc_size;
} else {
if ((dc_offset + dc_size) % next_field_map->dc_alignment != 0) {
this->next_field_map->dc_offset = dc_offset + dc_size -
(dc_size % next_field_map->dc_alignment) + next_field_map->dc_alignment;
} else {
this->next_field_map->dc_offset = dc_offset + max(dc_size, next_field_map->dc_alignment);
}
if ((hc_offset + hc_size) % next_field_map->hc_alignment != 0) {
next_offset = hc_offset + hc_size - (hc_size % next_field_map->hc_alignment) +
next_field_map->hc_alignment;
} else {
next_offset = hc_offset + max(next_field_map->hc_alignment, map_param_size);
}
}
return next_offset;
}
}
} //namespace cpu
// Copy memory according to mapping
unsigned int HCtoDCmap::copy_params(void* dst, const void* src, unsigned int arg_offset,
int& error_code, int& inStruct) const {
unsigned int padding = 0;
// Pad offset to be aligned by 8 if parameter is double, not as struct field
if ((arg_offset) % 8 != 0 && (type == T_DOUBLE) && inStruct == 0)
padding = hc_alignment - ((arg_offset + dc_offset) % hc_alignment);
#if defined(_WIN32)
// In windows, double is aligned by 8, add padding to struct if it contains double
if ((arg_offset + dc_offset) % 8 != 0 && hc_alignment == 8)
padding = hc_alignment - ((arg_offset + dc_offset) % hc_alignment);
#endif
::memcpy(reinterpret_cast<void*>(reinterpret_cast<unsigned char*>(dst) + padding), src, hc_size);
#if defined(_WIN32)
if (internal_field_map != NULL) {
inStruct++;
void* internal_dst = reinterpret_cast<void*>(reinterpret_cast<unsigned char*>(dst) + padding);
internal_field_map->copy_params(internal_dst, src, arg_offset + padding, error_code, inStruct);
inStruct--;
}
if (next_field_map != NULL) {
void* next_dst =
reinterpret_cast<void*>(reinterpret_cast<unsigned char*>(dst) +
next_field_map->dc_offset); // Next field starts with padding
const void* next_src = reinterpret_cast<const void*>(
reinterpret_cast<const unsigned char*>(src) + next_field_map->hc_offset);
next_field_map->copy_params(next_dst, next_src, arg_offset + next_field_map->dc_offset,
error_code, inStruct);
}
#else
if (internal_field_map != NULL) {
inStruct++;
internal_field_map->copy_params(dst, src, arg_offset, error_code, inStruct);
inStruct--;
}
if (next_field_map != NULL) {
void* next_dst =
reinterpret_cast<void*>(reinterpret_cast<unsigned char*>(dst) + next_field_map->dc_offset);
const void* next_src = reinterpret_cast<const void*>(
reinterpret_cast<const unsigned char*>(src) + next_field_map->hc_offset);
next_field_map->copy_params(next_dst, next_src, arg_offset, error_code, inStruct);
}
#endif
return padding;
}
} // namespace cpu
+28 -27
View File
@@ -9,36 +9,37 @@
namespace cpu {
class HCtoDCmap
{
class HCtoDCmap {
public:
unsigned int hc_offset, hc_size; // Offset and size of this parameter in host compiler
unsigned int dc_offset, dc_size; // Offset and size of this parameter in device compiler
unsigned int hc_alignment; // Alignment of parameter in host compiler
unsigned int dc_alignment; // Alignment of parameter in device compiler
clk_value_type_t type; // Type of parameter
HCtoDCmap*
internal_field_map; // Pointer to internal mapping when current parameter is of type T_STRUCT
HCtoDCmap*
next_field_map; // Pointer to next struct field when current parameter is a struct member
public:
unsigned int hc_offset, hc_size; // Offset and size of this parameter in host compiler
unsigned int dc_offset, dc_size; // Offset and size of this parameter in device compiler
unsigned int hc_alignment; // Alignment of parameter in host compiler
unsigned int dc_alignment; // Alignment of parameter in device compiler
clk_value_type_t type; // Type of parameter
HCtoDCmap *internal_field_map; // Pointer to internal mapping when current parameter is of type T_STRUCT
HCtoDCmap *next_field_map; // Pointer to next struct field when current parameter is a struct member
HCtoDCmap(const clk_parameter_descriptor_t*, unsigned int, unsigned int, unsigned int);
virtual ~HCtoDCmap();
int compute_map(const clk_parameter_descriptor_t*, unsigned int&, unsigned int&, unsigned int,
int&, int&);
unsigned next_offset(unsigned, unsigned&, int&);
size_t getHostScalarParamSize(const clk_value_type_t) const;
size_t getScalarAlignment(const clk_value_type_t, bool) const;
void align_map(unsigned, unsigned, unsigned&, unsigned&, int&);
unsigned int copy_params(void*, const void*, unsigned int, int&, int&) const;
HCtoDCmap(const clk_parameter_descriptor_t*, unsigned int, unsigned int, unsigned int);
virtual ~HCtoDCmap();
int compute_map(const clk_parameter_descriptor_t*, unsigned int &, unsigned int &, unsigned int, int&, int&);
unsigned next_offset(unsigned, unsigned &, int &);
size_t getHostScalarParamSize(const clk_value_type_t) const;
size_t getScalarAlignment(const clk_value_type_t, bool) const;
void align_map(unsigned, unsigned, unsigned&, unsigned&, int&);
unsigned int copy_params(void *, const void *, unsigned int, int&, int&) const;
private:
private:
};
} // namespace cpu
} // namespace cpu
#endif // CPUMAPPING_HPP_
// Mapping rule
// Long types are treated with 8 byte alignment in runtime when passed in as arguments
// but they are treated with 4 byte alignment in compiler
// Double members have 8 byte alignment when passed as scalar argument
// but have 4 byte alignment as a field inside a struct
#endif // CPUMAPPING_HPP_
// Mapping rule
// Long types are treated with 8 byte alignment in runtime when passed in as arguments
// but they are treated with 4 byte alignment in compiler
// Double members have 8 byte alignment when passed as scalar argument
// but have 4 byte alignment as a field inside a struct
File diff suppressed because it is too large Load Diff
+63 -75
View File
@@ -14,106 +14,94 @@
namespace amd {
namespace option {
class Options;
} // option
} // amd
} // option
} // amd
//! \namespace cpu CPU Device Implementation
namespace cpu {
//! \class CPU program
class Program : public device::Program
{
private:
aclJITObjectImage JITBinary;
std::string sourceFileName_; //!< The source image.
void* handle_; // @todo: remove me
class Program : public device::Program {
private:
aclJITObjectImage JITBinary;
std::string sourceFileName_; //!< The source image.
void* handle_; // @todo: remove me
public:
//! Default constructor
Program(Device& cpuDev)
: device::Program(cpuDev), JITBinary(NULL), handle_(NULL) {}
public:
//! Default constructor
Program(Device& cpuDev) : device::Program(cpuDev), JITBinary(NULL), handle_(NULL) {}
//! Default destructor
~Program();
//! Default destructor
~Program();
//! pre-compile setup for CPU
virtual bool initBuild(amd::option::Options* options);
//! pre-compile setup for CPU
virtual bool initBuild(amd::option::Options* options);
//! post-compile setup for CPU
virtual bool finiBuild(bool isBuildGood);
//! post-compile setup for CPU
virtual bool finiBuild(bool isBuildGood);
//! Compiles CPU program
virtual bool compileImpl(
const std::string& sourceCode,
const std::vector<const std::string*>& headers,
const char** headerIncludeNames,
amd::option::Options* options );
//! Compiles CPU program
virtual bool compileImpl(const std::string& sourceCode,
const std::vector<const std::string*>& headers,
const char** headerIncludeNames, amd::option::Options* options);
//! Links CPU program
virtual bool linkImpl(amd::option::Options* options = NULL);
//! Links CPU program
virtual bool linkImpl(amd::option::Options* options = NULL);
//! Links CPU programs
virtual bool linkImpl(
const std::vector<device::Program*>& inputPrograms,
amd::option::Options* options = NULL,
bool createLibrary = false);
//! Links CPU programs
virtual bool linkImpl(const std::vector<device::Program*>& inputPrograms,
amd::option::Options* options = NULL, bool createLibrary = false);
virtual bool createBinary(amd::option::Options* options);
virtual bool createBinary(amd::option::Options* options);
//! Returns the device object, associated with this program.
const Device& device() {
return static_cast<const Device&>(device::Program::device());
}
//! Returns the device object, associated with this program.
const Device& device() { return static_cast<const Device&>(device::Program::device()); }
/*! \brief Invokes the LLC compiler for the LLVM binary compilation
* to x86 ASM text source code and ISA binary
*
* \return True if we successefully compiled a CPU program
*/
bool compileBinaryToISA(
amd::option::Options* options //!< options for compilation
);
/*! \brief Invokes the LLC compiler for the LLVM binary compilation
* to x86 ASM text source code and ISA binary
*
* \return True if we successefully compiled a CPU program
*/
bool compileBinaryToISA(amd::option::Options* options //!< options for compilation
);
//! Load the library into memory
bool loadDllCode(amd::option::Options* options, bool addElfSymbols=false);
//! Load the library into memory
bool loadDllCode(amd::option::Options* options, bool addElfSymbols = false);
//! Initialize binary for CPU
virtual bool initClBinary();
//! Initialize binary for CPU
virtual bool initClBinary();
//! Release binary for CPU
virtual void releaseClBinary();
//! Release binary for CPU
virtual void releaseClBinary();
ClBinary* clBinary() {
return static_cast<ClBinary*>(device::Program::clBinary());
}
const ClBinary* clBinary() const {
return static_cast<const ClBinary*>(device::Program::clBinary());
}
ClBinary* clBinary() { return static_cast<ClBinary*>(device::Program::clBinary()); }
const ClBinary* clBinary() const {
return static_cast<const ClBinary*>(device::Program::clBinary());
}
aclJITObjectImage getJITBinary() { return this->JITBinary; }
void setJITBinary(aclJITObjectImage JITBinary) { this->JITBinary = JITBinary; }
aclJITObjectImage getJITBinary() { return this->JITBinary; }
void setJITBinary(aclJITObjectImage JITBinary) { this->JITBinary = JITBinary; }
//! Returns the pointer to the Compiler struct
//! Became public (prev. private) due to use in cpubinary for aclJIT functionality
aclCompiler* compiler() { return static_cast<const Device&>(device()).compiler(); }
//! Returns the pointer to the Compiler struct
//! Became public (prev. private) due to use in cpubinary for aclJIT functionality
aclCompiler* compiler() { return static_cast<const Device&>(device()).compiler(); }
private:
private:
//! Disable default copy constructor
Program(const Program&);
//! Disable default copy constructor
Program(const Program&);
//! Disable operator=
Program& operator=(const Program&);
//! Disable operator=
Program& operator=(const Program&);
std::string dllFileName_; //!< File name of the dll with kernels
protected:
virtual bool isElf(const char* bin) const {
return amd::isElfHeader(bin, LP64_SWITCH(ELFCLASS32, ELFCLASS64));
}
std::string dllFileName_; //!< File name of the dll with kernels
protected:
virtual bool isElf(const char* bin) const {
return amd::isElfHeader(bin, LP64_SWITCH(ELFCLASS32, ELFCLASS64));
}
virtual const aclTargetInfo & info(const char * str = "");
virtual const aclTargetInfo& info(const char* str = "");
};
} // namespace cpu
} // namespace cpu
#endif // CPUPROGRAM_HPP_
#endif // CPUPROGRAM_HPP_
+68 -75
View File
@@ -7,99 +7,92 @@
namespace cpu {
bool
Settings::create()
{
// This code is temporary until cl_khr_fp64 is unconditional
if (flagIsDefault(CL_KHR_FP64) || CL_KHR_FP64) {
enableExtension(ClKhrFp64);
}
bool Settings::create() {
// This code is temporary until cl_khr_fp64 is unconditional
if (flagIsDefault(CL_KHR_FP64) || CL_KHR_FP64) {
enableExtension(ClKhrFp64);
}
enableExtension(ClAmdFp64);
enableExtension(ClKhrGlobalInt32BaseAtomics);
enableExtension(ClKhrGlobalInt32ExtendedAtomics);
enableExtension(ClKhrLocalInt32BaseAtomics);
enableExtension(ClKhrLocalInt32ExtendedAtomics);
enableExtension(ClAmdFp64);
enableExtension(ClKhrGlobalInt32BaseAtomics);
enableExtension(ClKhrGlobalInt32ExtendedAtomics);
enableExtension(ClKhrLocalInt32BaseAtomics);
enableExtension(ClKhrLocalInt32ExtendedAtomics);
#ifdef _LP64
enableExtension(ClKhrInt64BaseAtomics);
enableExtension(ClKhrInt64ExtendedAtomics);
#endif // _LP64
enableExtension(ClKhrByteAddressableStore);
enableExtension(ClKhrGlSharing);
enableExtension(ClKhrGlEvent);
enableExtension(ClExtDeviceFission);
enableExtension(ClAmdDeviceAttributeQuery);
enableExtension(ClAmdVec3);
enableExtension(ClAmdMediaOps);
enableExtension(ClAmdMediaOps2);
enableExtension(ClAmdPopcnt);
enableExtension(ClAmdPrintf);
enableExtension(ClKhrInt64BaseAtomics);
enableExtension(ClKhrInt64ExtendedAtomics);
#endif // _LP64
enableExtension(ClKhrByteAddressableStore);
enableExtension(ClKhrGlSharing);
enableExtension(ClKhrGlEvent);
enableExtension(ClExtDeviceFission);
enableExtension(ClAmdDeviceAttributeQuery);
enableExtension(ClAmdVec3);
enableExtension(ClAmdMediaOps);
enableExtension(ClAmdMediaOps2);
enableExtension(ClAmdPopcnt);
enableExtension(ClAmdPrintf);
// enableExtension(ClKhrSelectFpRoundingMode);
enableExtension(ClKhr3DImageWrites);
// enableExtension(ClKhrSelectFpRoundingMode);
enableExtension(ClKhr3DImageWrites);
// enableExtension(ClKhrFp16);
// enableExtension(ClKhrFp16);
#if defined(_WIN32)
enableExtension(ClKhrD3d10Sharing);
#endif // _WIN32
enableExtension(ClKhrSpir);
// ToDo: enable this after conformance test is updated to accept it
// enableExtension(ClKhrIlProgram);
enableExtension(ClKhrD3d10Sharing);
#endif // _WIN32
enableExtension(ClKhrSpir);
// ToDo: enable this after conformance test is updated to accept it
// enableExtension(ClKhrIlProgram);
// Enable some OpenCL 2.0 extensions
if ((OPENCL_MAJOR >= 2) && (CPU_OPENCL_VERSION >= 200)) {
partialDispatch_ = true;
enableExtension(ClKhrSubGroups);
supportDepthsRGB_ = true;
enableExtension(ClKhrDepthImages);
}
// Enable some OpenCL 2.0 extensions
if ((OPENCL_MAJOR >= 2) && (CPU_OPENCL_VERSION >= 200)) {
partialDispatch_ = true;
enableExtension(ClKhrSubGroups);
supportDepthsRGB_ = true;
enableExtension(ClKhrDepthImages);
}
// Map CPUID feature bits to our own feature bits
const int sse2_features = CPUFEAT_DX_SSE | CPUFEAT_DX_SSE2;
const int avx_features = CPUFEAT_CX_SSE3 | CPUFEAT_CX_SSSE3 |
CPUFEAT_CX_SSE4_1 | CPUFEAT_CX_SSE4_2 |
CPUFEAT_CX_POPCNT | CPUFEAT_CX_AVX |
CPUFEAT_CX_OSXSAVE;
const int fma3_features = INTEL_CPUFEAT_CX_FMA3;
const int fma4_features = AMD_CPUFEAT_CX_FMA4 | AMD_CPUFEAT_CX_XOP;
int regs[4];
// Map CPUID feature bits to our own feature bits
const int sse2_features = CPUFEAT_DX_SSE | CPUFEAT_DX_SSE2;
const int avx_features = CPUFEAT_CX_SSE3 | CPUFEAT_CX_SSSE3 | CPUFEAT_CX_SSE4_1 |
CPUFEAT_CX_SSE4_2 | CPUFEAT_CX_POPCNT | CPUFEAT_CX_AVX | CPUFEAT_CX_OSXSAVE;
const int fma3_features = INTEL_CPUFEAT_CX_FMA3;
const int fma4_features = AMD_CPUFEAT_CX_FMA4 | AMD_CPUFEAT_CX_XOP;
int regs[4];
#if defined(ATI_ARCH_X86)
amd::Os::cpuid(regs, 0x0);
bool isAmd = regs[1] == ('A' | ('u' << 8) | ('t' << 16) | ('h' << 24));
bool isIntel = regs[1] == ('G' | ('e' << 8) | ('n' << 16) | ('u' << 24));
amd::Os::cpuid(regs, 0x0);
bool isAmd = regs[1] == ('A' | ('u' << 8) | ('t' << 16) | ('h' << 24));
bool isIntel = regs[1] == ('G' | ('e' << 8) | ('n' << 16) | ('u' << 24));
amd::Os::cpuid(regs, 0x1);
amd::Os::cpuid(regs, 0x1);
cpuFeatures_ = (regs[3] & sse2_features) == sse2_features ?
SSE2Instructions : 0;
cpuFeatures_ = (regs[3] & sse2_features) == sse2_features ? SSE2Instructions : 0;
if ((regs[2] & avx_features) == avx_features) {
// Check for state support
uint64_t xcr0 = amd::Os::xgetbv(0);
if ((regs[2] & avx_features) == avx_features) {
// Check for state support
uint64_t xcr0 = amd::Os::xgetbv(0);
// Check for SSE and YMM bits (1 and 2)
if (((uint32_t)xcr0 & 0x6U) == 0x6U) {
cpuFeatures_ |= AVXInstructions;
// Check for SSE and YMM bits (1 and 2)
if (((uint32_t)xcr0 & 0x6U) == 0x6U) {
cpuFeatures_ |= AVXInstructions;
// Now check for FMA and XOP
if (isIntel) {
cpuFeatures_ |= (regs[2] & fma3_features) == fma3_features ?
FMA3Instructions : 0;
}
// Now check for FMA and XOP
if (isIntel) {
cpuFeatures_ |= (regs[2] & fma3_features) == fma3_features ? FMA3Instructions : 0;
}
if (isAmd) {
amd::Os::cpuid(regs, 0x80000001);
cpuFeatures_ |= (regs[2] & fma4_features) == fma4_features ?
FMA4Instructions : 0;
}
}
if (isAmd) {
amd::Os::cpuid(regs, 0x80000001);
cpuFeatures_ |= (regs[2] & fma4_features) == fma4_features ? FMA4Instructions : 0;
}
}
#endif // ATI_ARCH_X86
}
#endif // ATI_ARCH_X86
return true;
return true;
}
} // namespace cpu
} // namespace cpu
+21 -22
View File
@@ -13,32 +13,31 @@
namespace cpu {
//! Device settings
class Settings : public device::Settings
{
public:
enum CpuFeatures {
SSE2Instructions = 0x01,
AVXInstructions = 0x02, // Processor reports SSSE3, SSE4_1, SSE4_2
// POPCNT and AVX
FMA3Instructions = 0x04, // Intel processor reports FMA3
FMA4Instructions = 0x08 // AMD processor reports FMA4 and XOP
};
uint32_t cpuFeatures_; //!< CPU features
class Settings : public device::Settings {
public:
enum CpuFeatures {
SSE2Instructions = 0x01,
AVXInstructions = 0x02, // Processor reports SSSE3, SSE4_1, SSE4_2
// POPCNT and AVX
FMA3Instructions = 0x04, // Intel processor reports FMA3
FMA4Instructions = 0x08 // AMD processor reports FMA4 and XOP
};
uint32_t cpuFeatures_; //!< CPU features
//! Default constructor
Settings() { cpuFeatures_ = 0; }
//! Default constructor
Settings() { cpuFeatures_ = 0; }
//! Creates settings
bool create();
//! Creates settings
bool create();
private:
//! Disable copy constructor
Settings(const Settings&);
private:
//! Disable copy constructor
Settings(const Settings&);
//! Disable assignment
Settings& operator=(const Settings&);
//! Disable assignment
Settings& operator=(const Settings&);
};
} // namespace cpu
} // namespace cpu
#endif // CPUSETTINGS_HPP_
#endif // CPUSETTINGS_HPP_
File diff suppressed because it is too large Load Diff
+382 -462
View File
@@ -17,367 +17,328 @@ namespace cpu {
amd::Atomic<size_t> VirtualCPU::numWorkerThreads_(0);
VirtualCPU::VirtualCPU(Device& device)
: device::VirtualDevice(device), acceptingCommands_(false)
{
const size_t numCores = device.info().maxComputeUnits_;
VirtualCPU::VirtualCPU(Device& device) : device::VirtualDevice(device), acceptingCommands_(false) {
const size_t numCores = device.info().maxComputeUnits_;
if ((numWorkerThreads_ += numCores) >= Device::getMaxWorkerThreadsNumber()) {
numWorkerThreads_ -= numCores;
cores_ = NULL;
return;
}
cores_ = new(std::nothrow) WorkerThread*[numCores];
if (cores_ == NULL) {
return;
}
// Clear memory for the worker threads
memset(cores_, 0, numCores * sizeof(WorkerThread*));
#if defined(__linux__)
const bool isNuma =
#if defined(NUMA_SUPPORT)
device.getNumaMask() == NULL;
#else
false;
#endif // NUMA_SUPPORT
const amd::Os::ThreadAffinityMask* affinityMask = isNuma ? NULL :
#else
const amd::Os::ThreadAffinityMask* affinityMask =
#endif
device.getWorkerThreadsAffinity();
uint coreId = affinityMask != NULL ? affinityMask->getFirstSet() : (uint)-1;
for (size_t i = 0; i < numCores; ++i) {
WorkerThread* thread = cores_[i] = new WorkerThread(device);
if (thread == NULL) {
for (size_t j = 0; j < i; ++j) {
cores_[j]->resume();
}
return;
}
if (thread->state() != amd::Thread::INITIALIZED) {
return;
}
#if defined(__linux__)
if (!isNuma) {
if (coreId == (uint)-1) {
thread->setAffinity((uint) i);
}
else {
thread->setAffinity(coreId);
coreId = affinityMask->getNextSet(coreId);
}
}
#else // On Windows we set an affinity mask and not a specific ID.
if (coreId != (uint)-1) {
thread->setAffinity(*affinityMask);
}
#endif
thread->start();
}
blitMgr_ = new device::HostBlitManager(*this);
if ((NULL == blitMgr_) || !blitMgr_->create(device)) {
LogError("Could not create BlitManager!");
return;
}
acceptingCommands_ = true;
}
VirtualCPU::~VirtualCPU()
{
if (cores_ == NULL) {
return;
}
delete blitMgr_;
const size_t numCores = device().info().maxComputeUnits_;
for (size_t i = 0; i < numCores; ++i) {
delete cores_[i];
}
if ((numWorkerThreads_ += numCores) >= Device::getMaxWorkerThreadsNumber()) {
numWorkerThreads_ -= numCores;
delete[] cores_;
cores_ = NULL;
return;
}
cores_ = new (std::nothrow) WorkerThread*[numCores];
if (cores_ == NULL) {
return;
}
// Clear memory for the worker threads
memset(cores_, 0, numCores * sizeof(WorkerThread*));
#if defined(__linux__)
const bool isNuma =
#if defined(NUMA_SUPPORT)
device.getNumaMask() == NULL;
#else
false;
#endif // NUMA_SUPPORT
const amd::Os::ThreadAffinityMask* affinityMask = isNuma ? NULL :
#else
const amd::Os::ThreadAffinityMask* affinityMask =
#endif
device.getWorkerThreadsAffinity();
uint coreId = affinityMask != NULL ? affinityMask->getFirstSet() : (uint)-1;
for (size_t i = 0; i < numCores; ++i) {
WorkerThread* thread = cores_[i] = new WorkerThread(device);
if (thread == NULL) {
for (size_t j = 0; j < i; ++j) {
cores_[j]->resume();
}
return;
}
if (thread->state() != amd::Thread::INITIALIZED) {
return;
}
#if defined(__linux__)
if (!isNuma) {
if (coreId == (uint)-1) {
thread->setAffinity((uint)i);
} else {
thread->setAffinity(coreId);
coreId = affinityMask->getNextSet(coreId);
}
}
#else // On Windows we set an affinity mask and not a specific ID.
if (coreId != (uint)-1) {
thread->setAffinity(*affinityMask);
}
#endif
thread->start();
}
blitMgr_ = new device::HostBlitManager(*this);
if ((NULL == blitMgr_) || !blitMgr_->create(device)) {
LogError("Could not create BlitManager!");
return;
}
acceptingCommands_ = true;
}
bool
VirtualCPU::terminate()
{
if (cores_ == NULL) {
return true;
}
VirtualCPU::~VirtualCPU() {
if (cores_ == NULL) {
return;
}
const size_t numCores = device().info().maxComputeUnits_;
for (size_t i = 0; i < numCores; ++i) {
if (cores_[i]) {
cores_[i]->terminate();
}
}
delete blitMgr_;
const size_t numCores = device().info().maxComputeUnits_;
for (size_t i = 0; i < numCores; ++i) {
delete cores_[i];
}
numWorkerThreads_ -= numCores;
delete[] cores_;
}
bool VirtualCPU::terminate() {
if (cores_ == NULL) {
return true;
}
const size_t numCores = device().info().maxComputeUnits_;
for (size_t i = 0; i < numCores; ++i) {
if (cores_[i]) {
cores_[i]->terminate();
}
}
return true;
}
void
VirtualCPU::submitReadMemory(amd::ReadMemoryCommand& vcmd)
{
vcmd.setStatus(CL_RUNNING);
void VirtualCPU::submitReadMemory(amd::ReadMemoryCommand& vcmd) {
vcmd.setStatus(CL_RUNNING);
bool result = false;
device::Memory memory(vcmd.source());
bool result = false;
device::Memory memory(vcmd.source());
// Ensure memory up-to-date
vcmd.source().cacheWriteBack();
// Ensure memory up-to-date
vcmd.source().cacheWriteBack();
switch (vcmd.type()) {
switch (vcmd.type()) {
case CL_COMMAND_READ_BUFFER:
result = blitMgr().readBuffer(memory, vcmd.destination(),
vcmd.origin(), vcmd.size(), vcmd.isEntireMemory());
break;
result = blitMgr().readBuffer(memory, vcmd.destination(), vcmd.origin(), vcmd.size(),
vcmd.isEntireMemory());
break;
case CL_COMMAND_READ_BUFFER_RECT:
result = blitMgr().readBufferRect(memory,
vcmd.destination(), vcmd.bufRect(), vcmd.hostRect(), vcmd.size(),
vcmd.isEntireMemory());
break;
result = blitMgr().readBufferRect(memory, vcmd.destination(), vcmd.bufRect(), vcmd.hostRect(),
vcmd.size(), vcmd.isEntireMemory());
break;
case CL_COMMAND_READ_IMAGE:
result = blitMgr().readImage(memory, vcmd.destination(),
vcmd.origin(), vcmd.size(), vcmd.rowPitch(), vcmd.slicePitch(),
vcmd.isEntireMemory());
break;
result = blitMgr().readImage(memory, vcmd.destination(), vcmd.origin(), vcmd.size(),
vcmd.rowPitch(), vcmd.slicePitch(), vcmd.isEntireMemory());
break;
default:
LogError("Unsupported type for the read command");
break;
}
LogError("Unsupported type for the read command");
break;
}
if (!result) {
LogError("submitReadMemory failed!");
vcmd.setStatus(CL_INVALID_OPERATION);
}
else {
vcmd.setStatus(CL_COMPLETE);
}
if (!result) {
LogError("submitReadMemory failed!");
vcmd.setStatus(CL_INVALID_OPERATION);
} else {
vcmd.setStatus(CL_COMPLETE);
}
}
void
VirtualCPU::submitWriteMemory(amd::WriteMemoryCommand& vcmd)
{
vcmd.setStatus(CL_RUNNING);
void VirtualCPU::submitWriteMemory(amd::WriteMemoryCommand& vcmd) {
vcmd.setStatus(CL_RUNNING);
bool result = false;
device::Memory memory(vcmd.destination());
bool result = false;
device::Memory memory(vcmd.destination());
// Ensure memory up-to-date
vcmd.destination().cacheWriteBack();
// Ensure memory up-to-date
vcmd.destination().cacheWriteBack();
// Process different write commands
switch (vcmd.type()) {
// Process different write commands
switch (vcmd.type()) {
case CL_COMMAND_WRITE_BUFFER:
result = blitMgr().writeBuffer(vcmd.source(), memory,
vcmd.origin(), vcmd.size(), vcmd.isEntireMemory());
break;
result = blitMgr().writeBuffer(vcmd.source(), memory, vcmd.origin(), vcmd.size(),
vcmd.isEntireMemory());
break;
case CL_COMMAND_WRITE_BUFFER_RECT:
result = blitMgr().writeBufferRect(vcmd.source(), memory,
vcmd.hostRect(), vcmd.bufRect(), vcmd.size(),
vcmd.isEntireMemory());
break;
result = blitMgr().writeBufferRect(vcmd.source(), memory, vcmd.hostRect(), vcmd.bufRect(),
vcmd.size(), vcmd.isEntireMemory());
break;
case CL_COMMAND_WRITE_IMAGE:
result = blitMgr().writeImage(vcmd.source(), memory,
vcmd.origin(), vcmd.size(), vcmd.rowPitch(), vcmd.slicePitch(),
vcmd.isEntireMemory());
break;
result = blitMgr().writeImage(vcmd.source(), memory, vcmd.origin(), vcmd.size(),
vcmd.rowPitch(), vcmd.slicePitch(), vcmd.isEntireMemory());
break;
default:
LogError("Unsupported type for the write command");
break;
}
LogError("Unsupported type for the write command");
break;
}
// Mark cache as clean (CPU works directly on backing store)
vcmd.destination().signalWrite(NULL);
// Mark cache as clean (CPU works directly on backing store)
vcmd.destination().signalWrite(NULL);
if (!result) {
LogError("submitWriteMemory failed!");
vcmd.setStatus(CL_INVALID_OPERATION);
}
else {
vcmd.setStatus(CL_COMPLETE);
}
if (!result) {
LogError("submitWriteMemory failed!");
vcmd.setStatus(CL_INVALID_OPERATION);
} else {
vcmd.setStatus(CL_COMPLETE);
}
}
void
VirtualCPU::submitCopyMemory(amd::CopyMemoryCommand& vcmd)
{
vcmd.setStatus(CL_RUNNING);
void VirtualCPU::submitCopyMemory(amd::CopyMemoryCommand& vcmd) {
vcmd.setStatus(CL_RUNNING);
// Ensure memory up-to-date
vcmd.source().cacheWriteBack();
vcmd.destination().cacheWriteBack();
// Ensure memory up-to-date
vcmd.source().cacheWriteBack();
vcmd.destination().cacheWriteBack();
// Translate memory references and ensure cache up-to-date
device::Memory dstMemory(vcmd.destination());
device::Memory srcMemory(vcmd.source());
// Translate memory references and ensure cache up-to-date
device::Memory dstMemory(vcmd.destination());
device::Memory srcMemory(vcmd.source());
bool result = false;
bool result = false;
// Check if HW can be used for memory copy
switch (vcmd.type()) {
// Check if HW can be used for memory copy
switch (vcmd.type()) {
case CL_COMMAND_COPY_BUFFER:
result = blitMgr().copyBuffer(srcMemory, dstMemory,
vcmd.srcOrigin(), vcmd.dstOrigin(), vcmd.size(),
vcmd.isEntireMemory());
break;
result = blitMgr().copyBuffer(srcMemory, dstMemory, vcmd.srcOrigin(), vcmd.dstOrigin(),
vcmd.size(), vcmd.isEntireMemory());
break;
case CL_COMMAND_COPY_BUFFER_RECT:
result = blitMgr().copyBufferRect(srcMemory, dstMemory,
vcmd.srcRect(), vcmd.dstRect(), vcmd.size(),
vcmd.isEntireMemory());
break;
result = blitMgr().copyBufferRect(srcMemory, dstMemory, vcmd.srcRect(), vcmd.dstRect(),
vcmd.size(), vcmd.isEntireMemory());
break;
case CL_COMMAND_COPY_IMAGE_TO_BUFFER:
result = blitMgr().copyImageToBuffer(srcMemory, dstMemory,
vcmd.srcOrigin(), vcmd.dstOrigin(), vcmd.size(),
vcmd.isEntireMemory());
break;
result = blitMgr().copyImageToBuffer(srcMemory, dstMemory, vcmd.srcOrigin(), vcmd.dstOrigin(),
vcmd.size(), vcmd.isEntireMemory());
break;
case CL_COMMAND_COPY_BUFFER_TO_IMAGE:
result = blitMgr().copyBufferToImage(srcMemory, dstMemory,
vcmd.srcOrigin(), vcmd.dstOrigin(), vcmd.size(),
vcmd.isEntireMemory());
break;
result = blitMgr().copyBufferToImage(srcMemory, dstMemory, vcmd.srcOrigin(), vcmd.dstOrigin(),
vcmd.size(), vcmd.isEntireMemory());
break;
case CL_COMMAND_COPY_IMAGE:
result = blitMgr().copyImage(srcMemory, dstMemory,
vcmd.srcOrigin(), vcmd.dstOrigin(), vcmd.size(),
vcmd.isEntireMemory());
break;
result = blitMgr().copyImage(srcMemory, dstMemory, vcmd.srcOrigin(), vcmd.dstOrigin(),
vcmd.size(), vcmd.isEntireMemory());
break;
default:
LogError("Unsupported command type for memory copy!");
break;
}
LogError("Unsupported command type for memory copy!");
break;
}
// Mark cache as clean (CPU works directly on backing store)
vcmd.destination().signalWrite(NULL);
// Mark cache as clean (CPU works directly on backing store)
vcmd.destination().signalWrite(NULL);
if (!result) {
LogError("submitCopyMemory failed!");
vcmd.setStatus(CL_INVALID_OPERATION);
}
else {
vcmd.setStatus(CL_COMPLETE);
}
if (!result) {
LogError("submitCopyMemory failed!");
vcmd.setStatus(CL_INVALID_OPERATION);
} else {
vcmd.setStatus(CL_COMPLETE);
}
}
void
VirtualCPU::submitMapMemory(amd::MapMemoryCommand& cmd)
{
cmd.setStatus(CL_RUNNING);
void VirtualCPU::submitMapMemory(amd::MapMemoryCommand& cmd) {
cmd.setStatus(CL_RUNNING);
if (cmd.mapFlags() & CL_MAP_READ
|| cmd.mapFlags() & CL_MAP_WRITE) {
LogInfo("cpu::VirtualCPU::submitMapMemory() CL_MAP_READ and CL_MAP_WRITE ignored");
}
if (cmd.mapFlags() & CL_MAP_READ || cmd.mapFlags() & CL_MAP_WRITE) {
LogInfo("cpu::VirtualCPU::submitMapMemory() CL_MAP_READ and CL_MAP_WRITE ignored");
}
// Ensure memory up-to-date
cmd.memory().cacheWriteBack();
// Ensure memory up-to-date
cmd.memory().cacheWriteBack();
cmd.setStatus(CL_COMPLETE);
cmd.setStatus(CL_COMPLETE);
}
void
VirtualCPU::submitUnmapMemory(amd::UnmapMemoryCommand& cmd)
{
cmd.setStatus(CL_RUNNING);
void VirtualCPU::submitUnmapMemory(amd::UnmapMemoryCommand& cmd) {
cmd.setStatus(CL_RUNNING);
// Mark cache as clean (CPU works directly on backing store)
cmd.memory().signalWrite(NULL);
// Mark cache as clean (CPU works directly on backing store)
cmd.memory().signalWrite(NULL);
//! @todo:dgladdin: strictly speaking we should check that the mem object was mapped
cmd.setStatus(CL_COMPLETE);
//! @todo:dgladdin: strictly speaking we should check that the mem object was mapped
cmd.setStatus(CL_COMPLETE);
}
void
VirtualCPU::submitFillMemory(amd::FillMemoryCommand& vcmd)
{
vcmd.setStatus(CL_RUNNING);
void VirtualCPU::submitFillMemory(amd::FillMemoryCommand& vcmd) {
vcmd.setStatus(CL_RUNNING);
device::Memory memory(vcmd.memory());
device::Memory memory(vcmd.memory());
vcmd.memory().cacheWriteBack();
vcmd.memory().cacheWriteBack();
bool result = false;
bool result = false;
// Find the the right fill operation
switch (vcmd.type()) {
// Find the the right fill operation
switch (vcmd.type()) {
case CL_COMMAND_FILL_BUFFER:
result = blitMgr().fillBuffer(memory, vcmd.pattern(),
vcmd.patternSize(), vcmd.origin(), vcmd.size(),
vcmd.isEntireMemory());
break;
result = blitMgr().fillBuffer(memory, vcmd.pattern(), vcmd.patternSize(), vcmd.origin(),
vcmd.size(), vcmd.isEntireMemory());
break;
case CL_COMMAND_FILL_IMAGE:
result = blitMgr().fillImage(memory, vcmd.pattern(),
vcmd.origin(), vcmd.size(), vcmd.isEntireMemory());
break;
result = blitMgr().fillImage(memory, vcmd.pattern(), vcmd.origin(), vcmd.size(),
vcmd.isEntireMemory());
break;
default:
LogError("Unsupported command type for FillMemory!");
break;
}
LogError("Unsupported command type for FillMemory!");
break;
}
vcmd.memory().signalWrite(NULL);
vcmd.memory().signalWrite(NULL);
if (!result) {
LogError("submitFillMemory failed!");
vcmd.setStatus(CL_INVALID_OPERATION);
}
else {
vcmd.setStatus(CL_COMPLETE);
}
if (!result) {
LogError("submitFillMemory failed!");
vcmd.setStatus(CL_INVALID_OPERATION);
} else {
vcmd.setStatus(CL_COMPLETE);
}
}
//! Helper function for forcing a cache sync for all kernel parameters
static void syncAllParams(amd::NDRangeKernelCommand& cmd)
{
const amd::Kernel& kernel = cmd.kernel();
const amd::KernelParameters& kernelParam = kernel.parameters();
const amd::KernelSignature& signature = kernel.signature();
const amd::Device& device = cmd.queue()->device();
static void syncAllParams(amd::NDRangeKernelCommand& cmd) {
const amd::Kernel& kernel = cmd.kernel();
const amd::KernelParameters& kernelParam = kernel.parameters();
const amd::KernelSignature& signature = kernel.signature();
const amd::Device& device = cmd.queue()->device();
for (size_t i = 0; i < signature.numParameters(); ++i) {
const amd::KernelParameterDescriptor& desc = signature.at(i);
if (desc.type_ == T_POINTER && desc.size_ > 0 &&
!kernelParam.boundToSvmPointer(device, cmd.parameters(), i)) {
address ptr = (address) (cmd.parameters() + desc.offset_);
amd::Memory* memArg = *(amd::Memory**)ptr;
for (size_t i = 0; i < signature.numParameters(); ++i) {
const amd::KernelParameterDescriptor& desc = signature.at(i);
if (desc.type_ == T_POINTER && desc.size_ > 0 &&
!kernelParam.boundToSvmPointer(device, cmd.parameters(), i)) {
address ptr = (address)(cmd.parameters() + desc.offset_);
amd::Memory* memArg = *(amd::Memory**)ptr;
if (memArg != NULL) {
memArg->cacheWriteBack();
memArg->signalWrite(NULL);
}
}
if (memArg != NULL) {
memArg->cacheWriteBack();
memArg->signalWrite(NULL);
}
}
}
}
void
VirtualCPU::computeLocalSizes(amd::NDRangeKernelCommand& command,
amd::NDRange& local) {
bool uniformSize = (OPENCL_MAJOR < 2) ||
command.kernel().getDeviceKernel(device())->getUniformWorkGroupSize();
void VirtualCPU::computeLocalSizes(amd::NDRangeKernelCommand& command, amd::NDRange& local) {
bool uniformSize =
(OPENCL_MAJOR < 2) || command.kernel().getDeviceKernel(device())->getUniformWorkGroupSize();
const amd::NDRangeContainer& sizes = command.sizes();
const size_t numCores = device().info().maxComputeUnits_;
const size_t globalSize1D = sizes.global().product();
const size_t targetNumOperations =
std::min(globalSize1D, numCores * 4);
size_t localSize1D =
std::min(globalSize1D / targetNumOperations,
device().info().maxWorkGroupSize_);
const size_t targetNumOperations = std::min(globalSize1D, numCores * 4);
size_t localSize1D =
std::min(globalSize1D / targetNumOperations, device().info().maxWorkGroupSize_);
for (size_t i = 0; i < local.dimensions(); ++i) {
const size_t globalSize = sizes.global()[i];
size_t localSize =
std::min(std::min(localSize1D, globalSize),
device().info().maxWorkItemSizes_[i]);
std::min(std::min(localSize1D, globalSize), device().info().maxWorkItemSizes_[i]);
// local must exactly divide global if uniform size is required
// For non uniform size, we could use the work group size hint
if (uniformSize && globalSize % localSize != 0) {
@@ -395,222 +356,181 @@ VirtualCPU::computeLocalSizes(amd::NDRangeKernelCommand& command,
}
static
amd::NDRange computeRemainders(const amd::NDRange& global,
const amd::NDRange& local)
{
static amd::NDRange computeRemainders(const amd::NDRange& global, const amd::NDRange& local) {
amd::NDRange remainders(local.dimensions());
for (size_t i = 0; i < local.dimensions(); ++i) {
remainders[i] = (global[i] % local[i] != 0) ? 1 : 0;
remainders[i] = (global[i] % local[i] != 0) ? 1 : 0;
}
return remainders;
}
void
VirtualCPU::submitKernel(amd::NDRangeKernelCommand& command)
{
const amd::NDRangeContainer& sizes = command.sizes();
const size_t numCores = device().info().maxComputeUnits_;
void VirtualCPU::submitKernel(amd::NDRangeKernelCommand& command) {
const amd::NDRangeContainer& sizes = command.sizes();
const size_t numCores = device().info().maxComputeUnits_;
amd::NDRange local = sizes.local();
amd::NDRange local = sizes.local();
if (local == 0) {
computeLocalSizes(command, local);
}
amd::NDRange remainders = computeRemainders(sizes.global(), local);
if (local == 0) {
computeLocalSizes(command, local);
}
amd::NDRange remainders = computeRemainders(sizes.global(), local);
// number of groups in each dimensions
const amd::NDRange numGroups = (sizes.global() / local) + remainders;
// number of groups in each dimensions
const amd::NDRange numGroups = (sizes.global() / local) + remainders;
size_t numOperations = numGroups.product();
if (numOperations == 0) {
command.setStatus(CL_COMPLETE);
return;
}
syncAllParams(command);
// retain the command here instead of retaining in NDRangeKernelBatch' ctor
command.retain();
size_t batchCount = std::min(numOperations, numCores);
NDRangeKernelBatch batch(command, *this, numGroups, batchCount);
Operation::Counter counter(command, batchCount);
command.setData(&counter);
for (size_t coreId = 0; coreId < batchCount; ++coreId) {
batch.setCoreId(coreId);
cores_[coreId]->enqueue(batch);
cores_[coreId]->flush();
}
command.awaitCompletion();
command.release();
}
void
VirtualCPU::submitNativeFn(amd::NativeFnCommand& command)
{
NativeFn fn(command);
cores_[0]->enqueue(fn);
cores_[0]->flush();
command.awaitCompletion();
}
void
VirtualCPU::submitMarker(amd::Marker& command)
{
size_t numOperations = numGroups.product();
if (numOperations == 0) {
command.setStatus(CL_COMPLETE);
return;
}
syncAllParams(command);
// retain the command here instead of retaining in NDRangeKernelBatch' ctor
command.retain();
size_t batchCount = std::min(numOperations, numCores);
NDRangeKernelBatch batch(command, *this, numGroups, batchCount);
Operation::Counter counter(command, batchCount);
command.setData(&counter);
for (size_t coreId = 0; coreId < batchCount; ++coreId) {
batch.setCoreId(coreId);
cores_[coreId]->enqueue(batch);
cores_[coreId]->flush();
}
command.awaitCompletion();
command.release();
}
void
VirtualCPU::submitAcquireExtObjects(amd::AcquireExtObjectsCommand& cmd)
{
//! @todo [odintsov]: create an AcquireExtObjectsOperation and enqueue it
//! to a core when a core scheduler is around.
//
// cores_[0]->enqueue(new AcquireExtObjectsOperation(cmd));
// the code below will be moved to AcquireExtObjectsOperation::execute()
cmd.setStatus(CL_RUNNING);
//
// AcquireExtObjects execution starts here
//
bool bError = false;
//! Go through ext objects by one and call member function to execute
//! a sequence of external graphics API commands for each external object
for(std::vector<amd::Memory*>::const_iterator itr = cmd.getMemList().begin();
itr != cmd.getMemList().end(); itr++) {
if(*itr) {
bError |= !((*itr)->mapExtObjectInCQThread());
}
}
if(bError) {
cmd.setStatus(CL_INVALID_OPERATION);
}
else {
cmd.setStatus(CL_COMPLETE);
}
void VirtualCPU::submitNativeFn(amd::NativeFnCommand& command) {
NativeFn fn(command);
cores_[0]->enqueue(fn);
cores_[0]->flush();
command.awaitCompletion();
}
void
VirtualCPU::submitReleaseExtObjects(amd::ReleaseExtObjectsCommand& cmd)
{
//! @todo [odintsov]: create a ReleaseExtObjectsOperation and enqueue it
//! to a core when a core scheduler is around.
//
// cores_[i]->enqueue(new ReleaseExtObjectsOperation(cmd));
// the code below will be moved to ReleaseExtObjectsOperation::execute()
cmd.setStatus(CL_RUNNING);
void VirtualCPU::submitMarker(amd::Marker& command) { command.setStatus(CL_COMPLETE); }
bool bError = false;
void VirtualCPU::submitAcquireExtObjects(amd::AcquireExtObjectsCommand& cmd) {
//! @todo [odintsov]: create an AcquireExtObjectsOperation and enqueue it
//! to a core when a core scheduler is around.
//
// cores_[0]->enqueue(new AcquireExtObjectsOperation(cmd));
// the code below will be moved to AcquireExtObjectsOperation::execute()
cmd.setStatus(CL_RUNNING);
for(std::vector<amd::Memory*>::const_iterator itr = cmd.getMemList().begin();
itr != cmd.getMemList().end(); itr++) {
if(*itr) {
bError |= !((*itr)->unmapExtObjectInCQThread());
}
}
if(bError) {
cmd.setStatus(CL_INVALID_OPERATION);
}
else {
cmd.setStatus(CL_COMPLETE);
}
}
//
// AcquireExtObjects execution starts here
//
bool bError = false;
void VirtualCPU::submitPerfCounter(amd::PerfCounterCommand& cmd)
{
cmd.setStatus(CL_RUNNING);
LogError("We don't support HW perf counters on CPU");
//! Go through ext objects by one and call member function to execute
//! a sequence of external graphics API commands for each external object
for (std::vector<amd::Memory*>::const_iterator itr = cmd.getMemList().begin();
itr != cmd.getMemList().end(); itr++) {
if (*itr) {
bError |= !((*itr)->mapExtObjectInCQThread());
}
}
if (bError) {
cmd.setStatus(CL_INVALID_OPERATION);
} else {
cmd.setStatus(CL_COMPLETE);
}
}
void VirtualCPU::submitThreadTraceMemObjects(amd::ThreadTraceMemObjectsCommand& cmd)
{
cmd.setStatus(CL_RUNNING);
LogError("We don't support thread trace on CPU");
cmd.setStatus(CL_INVALID_OPERATION);
}
void VirtualCPU::submitReleaseExtObjects(amd::ReleaseExtObjectsCommand& cmd) {
//! @todo [odintsov]: create a ReleaseExtObjectsOperation and enqueue it
//! to a core when a core scheduler is around.
//
// cores_[i]->enqueue(new ReleaseExtObjectsOperation(cmd));
// the code below will be moved to ReleaseExtObjectsOperation::execute()
cmd.setStatus(CL_RUNNING);
void VirtualCPU::submitThreadTrace(amd::ThreadTraceCommand& cmd)
{
cmd.setStatus(CL_RUNNING);
LogError("We don't support thread trace on CPU");
cmd.setStatus(CL_INVALID_OPERATION);
}
bool bError = false;
void
VirtualCPU::flush(amd::Command* list, bool wait)
{
amd::Command* head = list;
// Release all commands from the link list
while (head != NULL) {
amd::Command * it = head->getNext();
head->release();
head = it;
for (std::vector<amd::Memory*>::const_iterator itr = cmd.getMemList().begin();
itr != cmd.getMemList().end(); itr++) {
if (*itr) {
bError |= !((*itr)->unmapExtObjectInCQThread());
}
}
void
VirtualCPU::submitSignal(amd::SignalCommand & cmd)
{
}
if (bError) {
cmd.setStatus(CL_INVALID_OPERATION);
} else {
cmd.setStatus(CL_COMPLETE);
}
}
void
VirtualCPU::submitMakeBuffersResident(amd::MakeBuffersResidentCommand & cmd)
{
cmd.setStatus(CL_INVALID_OPERATION);
void VirtualCPU::submitPerfCounter(amd::PerfCounterCommand& cmd) {
cmd.setStatus(CL_RUNNING);
LogError("We don't support HW perf counters on CPU");
cmd.setStatus(CL_INVALID_OPERATION);
}
void
VirtualCPU::submitSvmFreeMemory(amd::SvmFreeMemoryCommand& cmd)
{
cmd.setStatus(CL_RUNNING);
if (cmd.pfnFreeFunc() == NULL) {
// pointers allocated using clSVMAlloc
for (cl_uint i = 0; i < cmd.svmPointers().size(); i++) {
amd::SvmBuffer::free(cmd.context(), cmd.svmPointers()[i]);
}
void VirtualCPU::submitThreadTraceMemObjects(amd::ThreadTraceMemObjectsCommand& cmd) {
cmd.setStatus(CL_RUNNING);
LogError("We don't support thread trace on CPU");
cmd.setStatus(CL_INVALID_OPERATION);
}
void VirtualCPU::submitThreadTrace(amd::ThreadTraceCommand& cmd) {
cmd.setStatus(CL_RUNNING);
LogError("We don't support thread trace on CPU");
cmd.setStatus(CL_INVALID_OPERATION);
}
void VirtualCPU::flush(amd::Command* list, bool wait) {
amd::Command* head = list;
// Release all commands from the link list
while (head != NULL) {
amd::Command* it = head->getNext();
head->release();
head = it;
}
}
void VirtualCPU::submitSignal(amd::SignalCommand& cmd) { cmd.setStatus(CL_INVALID_OPERATION); }
void VirtualCPU::submitMakeBuffersResident(amd::MakeBuffersResidentCommand& cmd) {
cmd.setStatus(CL_INVALID_OPERATION);
}
void VirtualCPU::submitSvmFreeMemory(amd::SvmFreeMemoryCommand& cmd) {
cmd.setStatus(CL_RUNNING);
if (cmd.pfnFreeFunc() == NULL) {
// pointers allocated using clSVMAlloc
for (cl_uint i = 0; i < cmd.svmPointers().size(); i++) {
amd::SvmBuffer::free(cmd.context(), cmd.svmPointers()[i]);
}
else {
cmd.pfnFreeFunc()(as_cl(cmd.queue()->asCommandQueue()), cmd.svmPointers().size(),
(void**) (&(cmd.svmPointers()[0])), cmd.userData());
}
cmd.setStatus(CL_COMPLETE);
} else {
cmd.pfnFreeFunc()(as_cl(cmd.queue()->asCommandQueue()), cmd.svmPointers().size(),
(void**)(&(cmd.svmPointers()[0])), cmd.userData());
}
cmd.setStatus(CL_COMPLETE);
}
void
VirtualCPU::submitSvmCopyMemory(amd::SvmCopyMemoryCommand& cmd)
{
cmd.setStatus(CL_RUNNING);
amd::SvmBuffer::memFill(cmd.dst(), cmd.src(), cmd.srcSize(), 1);
cmd.setStatus(CL_COMPLETE);
void VirtualCPU::submitSvmCopyMemory(amd::SvmCopyMemoryCommand& cmd) {
cmd.setStatus(CL_RUNNING);
amd::SvmBuffer::memFill(cmd.dst(), cmd.src(), cmd.srcSize(), 1);
cmd.setStatus(CL_COMPLETE);
}
void
VirtualCPU::submitSvmFillMemory(amd::SvmFillMemoryCommand& cmd)
{
cmd.setStatus(CL_RUNNING);
amd::SvmBuffer::memFill(cmd.dst(), cmd.pattern(), cmd.patternSize(), cmd.times());
cmd.setStatus(CL_COMPLETE);
void VirtualCPU::submitSvmFillMemory(amd::SvmFillMemoryCommand& cmd) {
cmd.setStatus(CL_RUNNING);
amd::SvmBuffer::memFill(cmd.dst(), cmd.pattern(), cmd.patternSize(), cmd.times());
cmd.setStatus(CL_COMPLETE);
}
void
VirtualCPU::submitSvmMapMemory(amd::SvmMapMemoryCommand& cmd)
{
cmd.setStatus(CL_COMPLETE);
void VirtualCPU::submitSvmMapMemory(amd::SvmMapMemoryCommand& cmd) { cmd.setStatus(CL_COMPLETE); }
void VirtualCPU::submitSvmUnmapMemory(amd::SvmUnmapMemoryCommand& cmd) {
cmd.setStatus(CL_COMPLETE);
}
void
VirtualCPU::submitSvmUnmapMemory(amd::SvmUnmapMemoryCommand& cmd)
{
cmd.setStatus(CL_COMPLETE);
}
} // namespace cpu
} // namespace cpu
+40 -48
View File
@@ -17,60 +17,52 @@ namespace cpu {
class WorkerThread;
class Device;
class VirtualCPU : public device::VirtualDevice
{
private:
WorkerThread** cores_; //!< Pointer to array of Worker threads
static amd::Atomic<size_t> numWorkerThreads_; //!< Current Worker Threads number
bool acceptingCommands_;
class VirtualCPU : public device::VirtualDevice {
private:
WorkerThread** cores_; //!< Pointer to array of Worker threads
static amd::Atomic<size_t> numWorkerThreads_; //!< Current Worker Threads number
bool acceptingCommands_;
public:
VirtualCPU(cpu::Device& device);
~VirtualCPU();
bool terminate();
public:
VirtualCPU(cpu::Device& device);
~VirtualCPU();
bool terminate();
WorkerThread* getWorkerThread(size_t id) { return cores_[id]; }
WorkerThread* getWorkerThread(size_t id) { return cores_[id]; }
bool acceptingCommands() const { return acceptingCommands_; }
bool acceptingCommands() const { return acceptingCommands_; }
virtual void submitReadMemory(amd::ReadMemoryCommand& command);
virtual void submitWriteMemory(amd::WriteMemoryCommand& command);
virtual void submitCopyMemory(amd::CopyMemoryCommand& command);
virtual void submitMapMemory(amd::MapMemoryCommand& command);
virtual void submitUnmapMemory(amd::UnmapMemoryCommand& command);
virtual void submitKernel(amd::NDRangeKernelCommand& command);
virtual void submitNativeFn(amd::NativeFnCommand& command);
virtual void submitMarker(amd::Marker& command);
virtual void submitFillMemory(amd::FillMemoryCommand& command);
virtual void submitMigrateMemObjects(amd::MigrateMemObjectsCommand& cmd) {}
virtual void submitAcquireExtObjects(amd::AcquireExtObjectsCommand& cmd);
virtual void submitReleaseExtObjects(amd::ReleaseExtObjectsCommand& cmd);
virtual void submitPerfCounter(amd::PerfCounterCommand& cmd);
virtual void submitThreadTraceMemObjects(amd::ThreadTraceMemObjectsCommand& cmd);
virtual void submitThreadTrace(amd::ThreadTraceCommand& cmd);
virtual void flush(amd::Command* list = NULL, bool wait = false);
virtual void submitSignal(amd::SignalCommand & cmd);
virtual void submitMakeBuffersResident(amd::MakeBuffersResidentCommand & cmd);
virtual void submitSvmFreeMemory(amd::SvmFreeMemoryCommand& cmd);
virtual void submitSvmCopyMemory(amd::SvmCopyMemoryCommand& cmd);
virtual void submitSvmFillMemory(amd::SvmFillMemoryCommand& cmd);
virtual void submitSvmMapMemory(amd::SvmMapMemoryCommand& cmd);
virtual void submitSvmUnmapMemory(amd::SvmUnmapMemoryCommand& cmd);
virtual void submitReadMemory(amd::ReadMemoryCommand& command);
virtual void submitWriteMemory(amd::WriteMemoryCommand& command);
virtual void submitCopyMemory(amd::CopyMemoryCommand& command);
virtual void submitMapMemory(amd::MapMemoryCommand& command);
virtual void submitUnmapMemory(amd::UnmapMemoryCommand& command);
virtual void submitKernel(amd::NDRangeKernelCommand& command);
virtual void submitNativeFn(amd::NativeFnCommand& command);
virtual void submitMarker(amd::Marker& command);
virtual void submitFillMemory(amd::FillMemoryCommand& command);
virtual void submitMigrateMemObjects(amd::MigrateMemObjectsCommand& cmd) {}
virtual void submitAcquireExtObjects(amd::AcquireExtObjectsCommand& cmd);
virtual void submitReleaseExtObjects(amd::ReleaseExtObjectsCommand& cmd);
virtual void submitPerfCounter(amd::PerfCounterCommand& cmd);
virtual void submitThreadTraceMemObjects(amd::ThreadTraceMemObjectsCommand& cmd);
virtual void submitThreadTrace(amd::ThreadTraceCommand& cmd);
virtual void flush(amd::Command* list = NULL, bool wait = false);
virtual void submitSignal(amd::SignalCommand& cmd);
virtual void submitMakeBuffersResident(amd::MakeBuffersResidentCommand& cmd);
virtual void submitSvmFreeMemory(amd::SvmFreeMemoryCommand& cmd);
virtual void submitSvmCopyMemory(amd::SvmCopyMemoryCommand& cmd);
virtual void submitSvmFillMemory(amd::SvmFillMemoryCommand& cmd);
virtual void submitSvmMapMemory(amd::SvmMapMemoryCommand& cmd);
virtual void submitSvmUnmapMemory(amd::SvmUnmapMemoryCommand& cmd);
virtual void computeLocalSizes(amd::NDRangeKernelCommand& command,
amd::NDRange& local);
virtual void computeLocalSizes(amd::NDRangeKernelCommand& command, amd::NDRange& local);
static bool fillImage(
amd::Image& image,
address fillMem,
const void* pattern,
const amd::Coord3D& origin,
const amd::Coord3D& region,
size_t rowPitch,
size_t slicePitch,
size_t elementSize);
static bool fillImage(amd::Image& image, address fillMem, const void* pattern,
const amd::Coord3D& origin, const amd::Coord3D& region, size_t rowPitch,
size_t slicePitch, size_t elementSize);
};
} // namespace cpu
} // namespace cpu
#endif // CPUVIRTUAL_HPP_
#endif // CPUVIRTUAL_HPP_