From 08272c7de5240f204532d282a92cfb76926d68ad Mon Sep 17 00:00:00 2001 From: erwin coumans Date: Mon, 11 Mar 2013 22:03:27 +0100 Subject: [PATCH] import opencl_course source for a start --- build/findDirectX11.lua | 36 + build/findOpenCL.lua | 151 +++ build/findOpenGLGlewGlut.lua | 51 + build/premake4.exe | Bin 0 -> 281088 bytes build/premake4.lua | 96 ++ build/premake4_linux | Bin 0 -> 283516 bytes build/premake4_linux64 | Bin 0 -> 392616 bytes build/premake4_osx | Bin 0 -> 481412 bytes build/stringify.bat | 13 + build/stringify.sh | 8 + build/stringifyKernel.lua | 78 ++ build/vs2010.bat | 6 + build/xcode.command | 4 + opencl/basic_initialize/btOpenCLInclude.h | 44 + opencl/basic_initialize/btOpenCLUtils.cpp | 903 ++++++++++++++ opencl/basic_initialize/btOpenCLUtils.h | 179 +++ opencl/basic_initialize/main.cpp | 98 ++ opencl/basic_initialize/premake4.lua | 28 + opencl/lds_bank_conflict/lds_kernels.cl | 171 +++ opencl/lds_bank_conflict/main.cpp | 361 ++++++ opencl/lds_bank_conflict/premake4.lua | 37 + .../benchmark/premake4.lua | 35 + .../benchmark/test_large_problem_sorting.cpp | 709 +++++++++++ .../host/CommandLineArgs.h | 92 ++ .../host/btAlignedAllocator.cpp | 181 +++ .../host/btAlignedAllocator.h | 107 ++ .../host/btAlignedObjectArray.h | 511 ++++++++ .../host/btBoundSearchCL.cpp | 213 ++++ .../host/btBoundSearchCL.h | 67 + .../parallel_primitives/host/btBufferInfoCL.h | 19 + opencl/parallel_primitives/host/btFillCL.cpp | 126 ++ opencl/parallel_primitives/host/btFillCL.h | 137 +++ opencl/parallel_primitives/host/btHashMap.h | 450 +++++++ .../parallel_primitives/host/btLauncherCL.h | 363 ++++++ opencl/parallel_primitives/host/btMinMax.h | 71 ++ .../parallel_primitives/host/btOpenCLArray.h | 274 +++++ .../host/btPrefixScanCL.cpp | 126 ++ .../parallel_primitives/host/btPrefixScanCL.h | 37 + .../parallel_primitives/host/btQuickprof.cpp | 566 +++++++++ opencl/parallel_primitives/host/btQuickprof.h | 203 ++++ .../host/btRadixSort32CL.cpp | 712 +++++++++++ .../host/btRadixSort32CL.h | 85 ++ opencl/parallel_primitives/host/btScalar.h | 660 ++++++++++ opencl/parallel_primitives/host/premake4.lua | 26 + .../kernels/BoundSearchKernels.cl | 106 ++ .../kernels/BoundSearchKernelsCL.h | 110 ++ .../kernels/CopyKernels.cl | 128 ++ .../kernels/CopyKernelsCL.h | 132 ++ .../kernels/FillKernels.cl | 107 ++ .../kernels/FillKernelsCL.h | 111 ++ .../kernels/PrefixScanKernels.cl | 154 +++ .../kernels/PrefixScanKernelsCL.h | 158 +++ .../kernels/RadixSort32Kernels.cl | 1071 ++++++++++++++++ .../kernels/RadixSort32KernelsCL.h | 1074 +++++++++++++++++ opencl/parallel_primitives/test/main.cpp | 379 ++++++ opencl/parallel_primitives/test/premake4.lua | 41 + opencl/reduce/main.cpp | 116 ++ opencl/reduce/premake4.lua | 37 + opencl/vector_add/VectorAddKernels.cl | 16 + opencl/vector_add/VectorAddKernels.h | 20 + opencl/vector_add/main.cpp | 408 +++++++ opencl/vector_add/premake4.lua | 28 + opencl/vector_add_simplified/main.cpp | 69 ++ opencl/vector_add_simplified/premake4.lua | 37 + 64 files changed, 12336 insertions(+) create mode 100644 build/findDirectX11.lua create mode 100644 build/findOpenCL.lua create mode 100644 build/findOpenGLGlewGlut.lua create mode 100644 build/premake4.exe create mode 100644 build/premake4.lua create mode 100644 build/premake4_linux create mode 100644 build/premake4_linux64 create mode 100644 build/premake4_osx create mode 100644 build/stringify.bat create mode 100644 build/stringify.sh create mode 100644 build/stringifyKernel.lua create mode 100644 build/vs2010.bat create mode 100644 build/xcode.command create mode 100644 opencl/basic_initialize/btOpenCLInclude.h create mode 100644 opencl/basic_initialize/btOpenCLUtils.cpp create mode 100644 opencl/basic_initialize/btOpenCLUtils.h create mode 100644 opencl/basic_initialize/main.cpp create mode 100644 opencl/basic_initialize/premake4.lua create mode 100644 opencl/lds_bank_conflict/lds_kernels.cl create mode 100644 opencl/lds_bank_conflict/main.cpp create mode 100644 opencl/lds_bank_conflict/premake4.lua create mode 100644 opencl/parallel_primitives/benchmark/premake4.lua create mode 100644 opencl/parallel_primitives/benchmark/test_large_problem_sorting.cpp create mode 100644 opencl/parallel_primitives/host/CommandLineArgs.h create mode 100644 opencl/parallel_primitives/host/btAlignedAllocator.cpp create mode 100644 opencl/parallel_primitives/host/btAlignedAllocator.h create mode 100644 opencl/parallel_primitives/host/btAlignedObjectArray.h create mode 100644 opencl/parallel_primitives/host/btBoundSearchCL.cpp create mode 100644 opencl/parallel_primitives/host/btBoundSearchCL.h create mode 100644 opencl/parallel_primitives/host/btBufferInfoCL.h create mode 100644 opencl/parallel_primitives/host/btFillCL.cpp create mode 100644 opencl/parallel_primitives/host/btFillCL.h create mode 100644 opencl/parallel_primitives/host/btHashMap.h create mode 100644 opencl/parallel_primitives/host/btLauncherCL.h create mode 100644 opencl/parallel_primitives/host/btMinMax.h create mode 100644 opencl/parallel_primitives/host/btOpenCLArray.h create mode 100644 opencl/parallel_primitives/host/btPrefixScanCL.cpp create mode 100644 opencl/parallel_primitives/host/btPrefixScanCL.h create mode 100644 opencl/parallel_primitives/host/btQuickprof.cpp create mode 100644 opencl/parallel_primitives/host/btQuickprof.h create mode 100644 opencl/parallel_primitives/host/btRadixSort32CL.cpp create mode 100644 opencl/parallel_primitives/host/btRadixSort32CL.h create mode 100644 opencl/parallel_primitives/host/btScalar.h create mode 100644 opencl/parallel_primitives/host/premake4.lua create mode 100644 opencl/parallel_primitives/kernels/BoundSearchKernels.cl create mode 100644 opencl/parallel_primitives/kernels/BoundSearchKernelsCL.h create mode 100644 opencl/parallel_primitives/kernels/CopyKernels.cl create mode 100644 opencl/parallel_primitives/kernels/CopyKernelsCL.h create mode 100644 opencl/parallel_primitives/kernels/FillKernels.cl create mode 100644 opencl/parallel_primitives/kernels/FillKernelsCL.h create mode 100644 opencl/parallel_primitives/kernels/PrefixScanKernels.cl create mode 100644 opencl/parallel_primitives/kernels/PrefixScanKernelsCL.h create mode 100644 opencl/parallel_primitives/kernels/RadixSort32Kernels.cl create mode 100644 opencl/parallel_primitives/kernels/RadixSort32KernelsCL.h create mode 100644 opencl/parallel_primitives/test/main.cpp create mode 100644 opencl/parallel_primitives/test/premake4.lua create mode 100644 opencl/reduce/main.cpp create mode 100644 opencl/reduce/premake4.lua create mode 100644 opencl/vector_add/VectorAddKernels.cl create mode 100644 opencl/vector_add/VectorAddKernels.h create mode 100644 opencl/vector_add/main.cpp create mode 100644 opencl/vector_add/premake4.lua create mode 100644 opencl/vector_add_simplified/main.cpp create mode 100644 opencl/vector_add_simplified/premake4.lua diff --git a/build/findDirectX11.lua b/build/findDirectX11.lua new file mode 100644 index 000000000..68771c4a0 --- /dev/null +++ b/build/findDirectX11.lua @@ -0,0 +1,36 @@ +function findDirectX11() + local dx11path = os.getenv("DXSDK_DIR") + if (dx11path) then + local filepath = string.format("%s%s",dx11path,"Include/D3D11.h") + headerdx11 = io.open(filepath, "r") + if (headerdx11) then + printf("Found DX11: '%s'", filepath) + return true + end + end + return false + end + +function initDirectX11() + configuration {} + + local dx11path = os.getenv("DXSDK_DIR") + defines { "ADL_ENABLE_DX11"} + includedirs {"$(DXSDK_DIR)/include"} + + configuration "x32" + libdirs {"$(DXSDK_DIR)/Lib/x86"} + configuration "x64" + libdirs {"$(DXSDK_DIR)/Lib/x64"} + configuration {} + links {"d3dcompiler", + "dxerr", + "dxguid", + "d3dx9", + "d3d9", + "winmm", + "comctl32", + "d3dx11" + } + return true +end \ No newline at end of file diff --git a/build/findOpenCL.lua b/build/findOpenCL.lua new file mode 100644 index 000000000..e2eda667a --- /dev/null +++ b/build/findOpenCL.lua @@ -0,0 +1,151 @@ + + + function findOpenCL_Apple() + if os.is("macosx") then + return true + else + return false + end + end + + + function findOpenCL_AMD() + local amdopenclpath = os.getenv("AMDAPPSDKROOT") + if (amdopenclpath) then + return true + end + return false + end + + function findOpenCL_NVIDIA() + local nvidiaopenclpath = os.getenv("CUDA_PATH") + if (nvidiaopenclpath) then + return true + end + return false + end + + function findOpenCL_Intel() + if os.is("Windows") then + local intelopenclpath = os.getenv("INTELOCLSDKROOT") + if (intelopenclpath) then + return true + end + end + if os.is("Linux") then + local intelsdk = io.open("/usr/include/CL/opencl.h","r") + if (intelsdk) then + return true; + end + end + return false + end + + function initOpenCL_Apple() + configuration{} + includedirs { + "/System/Library/Frameworks/OpenCL.framework" + } + libdirs "/System/Library/Frameworks/OpenCL.framework" + links + { + "OpenCL.framework" + } + end + + function initOpenCL_AMD() + configuration {} + local amdopenclpath = os.getenv("AMDAPPSDKROOT") + if (amdopenclpath) then + defines { "ADL_ENABLE_CL" , "CL_PLATFORM_AMD"} + includedirs { + "$(AMDAPPSDKROOT)/include" + } + configuration "x32" + libdirs {"$(AMDAPPSDKROOT)/lib/x86"} + configuration "x64" + libdirs {"$(AMDAPPSDKROOT)/lib/x86_64"} + configuration {} + links {"OpenCL"} + return true + end + return false + end + + + function initOpenCL_NVIDIA() + configuration {} + local nvidiaopenclpath = os.getenv("CUDA_PATH") + if (nvidiaopenclpath) then + defines { "ADL_ENABLE_CL" , "CL_PLATFORM_NVIDIA"} + includedirs { + "$(CUDA_PATH)/include" + } + configuration "x32" + libdirs {"$(CUDA_PATH)/lib/Win32"} + configuration "x64" + libdirs {"$(CUDA_PATH)/lib/x64"} + configuration {} + links {"OpenCL"} + return true + end + return false + end + + function initOpenCL_Intel() + configuration {} + if os.is("Windows") then + local intelopenclpath = os.getenv("INTELOCLSDKROOT") + if (intelopenclpath) then + defines { "ADL_ENABLE_CL" , "CL_PLATFORM_INTEL"} + includedirs { + "$(INTELOCLSDKROOT)/include" + } + configuration "x32" + libdirs {"$(INTELOCLSDKROOT)/lib/x86"} + configuration "x64" + libdirs {"$(INTELOCLSDKROOT)/lib/x64"} + configuration {} + links {"OpenCL"} + return true + end + end + if os.is("Linux") then + defines { "ADL_ENABLE_CL" , "CL_PLATFORM_INTEL"} + configuration {} + links {"OpenCL"} + end + return false + end + + function findOpenCL (vendor ) + if vendor=="AMD" then + return findOpenCL_AMD() + end + if vendor=="NVIDIA" then + return findOpenCL_NVIDIA() + end + if vendor=="Intel" then + return findOpenCL_Intel() + end + if vendor=="Apple" then + return findOpenCL_Apple() + end + return false + end + + function initOpenCL ( vendor ) + if vendor=="AMD" then + initOpenCL_AMD() + end + if vendor=="NVIDIA" then + return initOpenCL_NVIDIA() + end + if vendor=="Intel" then + initOpenCL_Intel() + end + if vendor=="Apple" then + return initOpenCL_Apple() + end + end + diff --git a/build/findOpenGLGlewGlut.lua b/build/findOpenGLGlewGlut.lua new file mode 100644 index 000000000..f808972da --- /dev/null +++ b/build/findOpenGLGlewGlut.lua @@ -0,0 +1,51 @@ + + function initOpenGL() + configuration {} + configuration {"Windows"} + links {"opengl32","glu32"} + configuration {"MacOSX"} + links { "OpenGL.framework"} + configuration {"not Windows", "not MacOSX"} + links {"GL"} + configuration{} + end + + function initGlut() + configuration {} + configuration {"Windows"} + + includedirs { + projectRootDir .. "rendering/GlutGlewWindows" + } + libdirs { projectRootDir .. "rendering/GlutGlewWindows"} + configuration {"Windows", "x32"} + links {"glut32"} + configuration {"Windows", "x64"} + links {"glut64"} + + configuration {"MacOSX"} + links { "Glut.framework" } + configuration {"Linux"} + links {"glut","GLU"} + configuration{} + end + + function initGlew() + configuration {} + if os.is("Windows") then + configuration {"Windows"} + defines { "GLEW_STATIC"} + includedirs { + projectRootDir .. "rendering/GlutGlewWindows" + } + libdirs { projectRootDir .. "rendering/GlutGlewWindows"} + files { projectRootDir .. "rendering/GlutGlewWindows/glew.c"} + end + if os.is("Linux") then + links{"GLEW"} + end + configuration{} + end + + + diff --git a/build/premake4.exe b/build/premake4.exe new file mode 100644 index 0000000000000000000000000000000000000000..072560edb578d278f98ca3cb216ce9b9cfce3604 GIT binary patch literal 281088 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¨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�u8p(9~&C5FlR*e4cr2W zkeheTCh8zMuHFLIxx-XLJVuG}(b≥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 literal 0 HcmV?d00001 diff --git a/build/premake4.lua b/build/premake4.lua new file mode 100644 index 000000000..16a50c9c0 --- /dev/null +++ b/build/premake4.lua @@ -0,0 +1,96 @@ + + solution "0MySolution" + + -- Multithreaded compiling + if _ACTION == "vs2010" or _ACTION=="vs2008" then + buildoptions { "/MP" } + end + + act = "" + + if _ACTION then + act = _ACTION + end + + + newoption + { + trigger = "ios", + description = "Enable iOS target (requires xcode4)" + } + + + configurations {"Release", "Debug"} + configuration "Release" + flags { "Optimize", "EnableSSE","StaticRuntime", "NoMinimalRebuild", "FloatFast"} + configuration "Debug" + defines {"_DEBUG=1"} + flags { "Symbols", "StaticRuntime" , "NoMinimalRebuild", "NoEditAndContinue" ,"FloatFast"} + + platforms {"x32", "x64"} + + configuration {"x32"} + targetsuffix ("_" .. act) + configuration "x64" + targetsuffix ("_" .. act .. "_64" ) + configuration {"x64", "debug"} + targetsuffix ("_" .. act .. "_x64_debug") + configuration {"x64", "release"} + targetsuffix ("_" .. act .. "_x64_release" ) + configuration {"x32", "debug"} + targetsuffix ("_" .. act .. "_debug" ) + + configuration{} + + postfix="" + + if _ACTION == "xcode4" then + if _OPTIONS["ios"] then + postfix = "ios"; + xcodebuildsettings + { + 'CODE_SIGN_IDENTITY = "iPhone Developer"', + "SDKROOT = iphoneos", + 'ARCHS = "armv7"', + 'TARGETED_DEVICE_FAMILY = "1,2"', + 'VALID_ARCHS = "armv7"', + } + else + xcodebuildsettings + { + 'ARCHS = "$(ARCHS_STANDARD_32_BIT) $(ARCHS_STANDARD_64_BIT)"', + 'VALID_ARCHS = "x86_64 i386"', + } + end + end + + + flags { "NoRTTI", "NoExceptions"} + defines { "_HAS_EXCEPTIONS=0" } + targetdir "../bin" + location("./" .. act .. postfix) + + + projectRootDir = os.getcwd() .. "/../" + print("Project root directroy: " .. projectRootDir); + + dofile ("findOpenCL.lua") + dofile ("findDirectX11.lua") + dofile ("findOpenGLGlewGlut.lua") + + language "C++" + + + + if not _OPTIONS["ios"] then + include "../opencl/vector_add_simplified" + include "../opencl/vector_add" + include "../opencl/basic_initialize" + include "../opencl/parallel_primitives/host" + include "../opencl/parallel_primitives/test" + include "../opencl/parallel_primitives/benchmark" + include "../opencl/lds_bank_conflict" + include "../opencl/reduce" + + + end \ No newline at end of file diff --git a/build/premake4_linux b/build/premake4_linux new file mode 100644 index 0000000000000000000000000000000000000000..53442a8017657482640e2bb3c639ac0ed6018d18 GIT binary patch literal 283516 zcma&P3w%`7wLg9)nIr=Y%m7iMMvXOS5EP=Q#1IV`CJA74k};EjhJZjE!Yh&)KzW4@ zX*nF{mbP+hZ);0i+tO-#xxJNQd^CW+45+mc)CM6M5$#S-YNtpsMe6*&-@VV|VcYxp zkDlza_It0r*4k^Yz4l?N_wG`g&88)PDO##VsQ5c}$8?0V@3qUM=~|AKq2*~;XqRj0 zh+*3F7UaRxgLgh@c$hmCPbMnK+-7(184s8b(^xkj`9oO^Pg99q=Ec?MS4m^wTG~ro;=Q=$3c$VSe?@kqHS0kKf zy%Ps46T}n1lY@u9t5l$^L|A6MUxRRj_0FKgdap<5wce*#;X?>#;$dGG;PKVWAZ+N9e{vA8y{r~SPNL8Ege`LP$-=t0YLi{Cwzl0~(il00r{d&CLhR2C#6`pZ;lD|>O z7lh=~o>_SA$MXQ5 zOYzLXb1$CJc;@3Fzwmb%o+JZ4C}T8874WO|PW+MnZFo30Et6BeM402`Z_<^IWj{0T zgZ3F`jqHc27n9V7{gQP?5KFv_w;H}16%u~f%Ke{K`m1aRKh6u&|3m;k;*RiID?Mt# z7ZLKe2oKZ$$4X~Nc$Ni|?+K6Pfbctlhwv>HoJ{}N%1_>B`X)U5HQ^y#Y~}xz1rMFy z9K;cK$zKj$%B=dDF>aP8Px04+hwxqtADmCZx|N^wK=^qp{UO8?zT1LNS?NIw-fY2? zwfuG9VSWz*{9;!5?d#v+^hD<$4RQKpxhYVwJzyg8c~jyABW2 z*ID^jAS8Si4}T*w6#O@ zV(sYXGIXoHeo5$&re*aHvL~#XEj2&FVQLM{OBS!j$kr}PVqrBaYErFmpzARs>(?$1 zEn}v|OVP&a#XyrBwnWX+;&-JV9o2Q6*4*5dT33!scG3-*@wY6IR&a;%R=iO z3^!=?AS8)kR;T7c(OP{ysm)@CRf{p94Jv^d*MKC@zhxNg1`tF@E4zD6iKqVNoAL+V zrVYH^eA6uh@6!j~2IFo9i*oPGClx!*RA{bz4RY^bQ4uiI(9e7_LBV=i5Qj2zv@k;sTORq1oiP0?JF1u74B(x z#x7qD5$Dj#F+9e(C7iBRS@O|_-56yo)0*%!U%nhF(n#$AD}ScUKSB#y@OTMlXlpHa zoP^V~O%|-$vwxwz)FJKJjs99xtkcG?G}a*&f6JcL$ZTmx~4tG5IV~)hS)ql&JZJfg5gN$e+;3l?_ucFw5J#X zV|y8nfsAK}{_JCjjpnZzVgWh8a6D`t46)&AXLyOGz0B}Z>?0Uraea+pmZo(w#HQ*^ zhL>wv7ego?rx<3#Hp1{qO*_L7n+(Aa#)v+KIhqz{c#Wo=WB4Ua>t}eard?#nMfy#I z6M-*=SR@?`ugBh#AvSGphLfNNFuXz2vKV4<%VszQ_+@w_^fiVzVV}ovs-{h0I1RMK zFdyqWLom_|hERTIGQ?tE%n-`MY=%%;%NgE|eF;M-w?2jinsy&UC^@wZv0;6HA(Yxh z42z&2GQ=h$$Ph+^l?;nPn+#`R{u!2F{uz2O{|ski{uz2P{|rkp{|w78{|w79{|x6~ z{u$22{4<<~`Db`H=AU5&=AYp`n16=%V*VNWF#ilIG5-v!F#impG{3+QN=7@wYRo^w z0Op?|l*-o_)?)q{&c`${T!8s!h>iFuhEQ^Q7}jC_87{>9GlcP|kKrQBKf}eCe})fY z{uwU8{4-pN`F{)HGR!~22FyRhhcN#Pp$xhiF30>cY{dLCTmhSt{-Hn8XBVhJyMNnZ z?Jm1!eDh)=k!U>@N)w+WR$K}85nUBFt@i$-hZDE11jQvLHsLSJBqoONh6XgPw+F=% z6E_fMT5qR>HxVYg_qI!zoEij2XubO+OpXoa5Z)tUa&9n>@Gc2IMi>;R^|nZO7hzD8 z*4rfE#|ak`UL@fs2$vJ~N%*^jF@sufv4qL#LClEOJ59pm_~0VKIT9x42RWc#w}hV| z+(cND@IJyD2**E1#Kd0{ZXw(w;RA$s5bl)l3xszOZkI46Meqs2`y@<>5!^#~kAx{X zf_n+?lJIMU_YrQ9a3|pdgqtM%CgFC%izM7d_y}R2gijIfBwQ?EN}6C7;b{`4#0mBg z&XF)BPf!qcOSq44oUkV0IN^T6@qcjq=Ll1#_x4D*pD?%ky`2)iNSJDWZ@YvwP;4-Z z@IDFK3Fi>rBVh;OJi@yq>?F+XRBwxf-GpZlZjx{&;bOvzB%DRKoUl*A*@S(BizS>x zxR&rV3Fi`CL^wynd4z+6-4dQcxQVbP;c0}qed&#pPbN+$+(NiV!ZQf(Alxb8nS^%{ zZkKQ|;U@_1lkjZ9dkF85a5>?Nrw@BDW_yFN13ExM!o$w+F*AhNL*eBr! z2zL@Lmhd9NU4*Aecq!o?!Z{KS5*CEr5?)C-PFRz06XAZs@y|H^5MgK?7{7!!5Oxsm zl<+3PZo=&nZXujSc%Ou~6V4&LN5VS@=Mml|;l~J1Bith4U4&;4Zj$ihgo_C;lJFCR z%L)4={9VF6!o?EaL%5dkGzmXNcoE?o3GXFL^I5N3!p{(HBCJVxAK?vz;}<0V6K)~g zBjE#tcM$HB@C$@@5pI`oJK-k?@00M$g!d5MBjF>2_Y&SE;nxW7Bith4PQnKWH%a(S z!tI0?Nw|yf5yCzRpCa5zxLCqHgu4h&lkgeBJ%n>4EC>t2ZVC4hjuX}-94FjQIR1CZ z|Ae7^V*C>BC+r~HDdCHR-GtjE%#|vbMR=ctxnc!#2=9?FSFT_l;aw8u3KpD3xJANT z$$~QoH%XW)TCkY#A_;S43sT+f^#O*Q((?bjP=7yiChohhD!A|cG++yVDg(jBAKD$l z#GuaY8ur7Q80mAg6y-t()k01)JJN3dQ7)=Y9Qy$S!`*r;Y<8qE-FEcwE|vcWEjZ?C zZ4Zs3Y}W8HB4*EJT%t3X$K9wU!VdA+e?fl$18FKgV1yn1sz$BR77%q%4Rw32epvhn z%ocgsje4$*^f?1!6beONcKU<+V08$H*d_I=EJy|IVMVIy8zp(DG>{nCN zyVu87-}c&2fjj?LYkSyfR3B(LUwrUSV6>KyEcU%UlX75xy;VTKpX z_xVNFw>8bEyO``Y$6OOY5hwDa1RFSsG7?Gwq+yEi{&qQt zN_0c^0V6R}^4p`!&fUMTzD~};umNPsw%t43Ef=PSGFvV@5OTF#$PJC$ek^o(%LdyW z;Y^~w`UlWi7X*(3`F`QV@{GCQVEtmp6F51kZTyE{WT`wo zGLQJ_kUUEV@|@cv>-n?H^YYL<#RGXdRi5)Q&mQENUmHyMfDL~WKTai?e_=B3=wdZ|X%)Fi@jl1b-oRtmy)ZT|rA0rG@QSUf={ppX8> z!WwbxJZHc0jv92n1Me(zQtt?jX>Hfv4LJ+C^p15Y`n#>?Lt}kzn#Ba(h>;MSgQWUeMYv;;glwsdKLdJDQ!7jT2ty`j{%3$2FRiL- z{G2(n9v>XMIRn)655}e-mOVWm8lit$=4zEXrZ)~oVe0R`DN_r)ao2yC(540n81yFP zfL~2sHMWoo<_G^_h`z6Sz8dyTe6chuYC6Q4tZMqbYJ>m4Fh(MEndhPKw{bM5#3 zC0f_U@MHe@GynAQkI6rO;-6mr5&ZK<{`rW1KIES>{PO|-oaUeR`KQMhtVeJB;!mHj z&2oQ@_%UT1FhGPF)$wJwT*97WTT;`XNDQYp|F*vDVsga5aQcDU*8bln5sQgR1A?5 zHToX{Xg?REuDA9;W(~n;V^NhDan71N5btFD@TAYSeU?DQThg9q;4AglL|ZB9e8PpC z9ow%YpqZJ0z)OyU4#z<1Vlct{`=d`XIgogkEr~DxNRq1`#HS)|{jMbQrz9%>Ta6h4 ze^kqzS}0w=H4jTxe)}+Fj>Kq^$c)~dYsW&Fc=)1{@0F3hEW>8ZvFqMbdPSFbH4V-6 zIZ2XV!zLJv64X8f9d)%kFmr3%D$32Msn0O#0W0bWM*U3YnuDnN+Tb&?hle0}Sj%l^ zkp6L3BH@aTIsU})5jxy zKzM&^D6mrk?wFU_u-5w|{utFgMn#ul|GHdA!f8>T%^cHm;l}VdEFw3Col#$k-X%W8 zRG6!gw?wZ#69|BM{`3PiF7IHw-+^Q@D$W?*F8%fB%pK;nm8F%5^%wo(CFF%r|J*NL z#pI!D#XbVtq$F}jV)nxDsqitwd&;OjGuhh{ot=`HJ`xtq7PY#4P@ z=!U9D`>00EmuPm1Uk@}Z6^VfO4T>d&m3bNE{VgI9mz=MA?1sk1ZaAD?uf>tB%*W-ZZ|V;uAK!?lf{2gLWHB$%jo59U#uIjGg; z8s2?=|3odWX+>HK{6v)A6cAUSZ%J8(4(Oehc1Zn=Dj)Qq>(GM*^NnIVhKOo!_&$Yc zQr%O^kW;Oe7ym<2j)fm5@gvgD%7Jp!%?>dG!>%Qgrs9S3dObqamfwDqil$tHpbD$% zR=9B3ZqIdtbg;^-LPc1Lzz$ObqUA41!RhS_RqKaQ{iILyPoo~2Ps~O}h%s=BUgGcv zeB$`WD&lD3qEX`LuxDxc?NYCtJti^P+ecz_t1@~C)Ze~^^(9s29jH?Ov@u2e?XR*l z>Y9Il@aFG396oUtoz8EMpgvZkJ99;6GLy4@0a|>6qw>b@$Bc<*(N%OuPpO?>#fAPA zAPGWM5`|B>@XrNERxfp5!;3LFV#VNU;L+!Z`kcBOJAnLl{X?U|X;j)_&l_WS-MZVb z#b(KDa)Uq;Xw-uH_hKtl^(#vzKwEeFe8I;M=@)5+n(r>TSj-q#WJMKRX}nO9GIei1 z`{}(H_4fOMcc2eMXvsIYU6SL$l+?gviE1xa>3`tl%&C+}-w#n?Y=-_`oqr7KlwUs_ zZE_mgqGIet8HZBs_NgmZ98GqyL^|ND|d?;WuSB6Vt@c_(pBNhI-J~A@KC+ zxy9Iy#DiCVkBeM4w5`a?Sv7u9x>HSiI%Xj`?I8DUeR(Y(t9xd137A>CqkD-`bUO2 z?N-qvDyj9PYj^8=s4LQcMYy5mMZRjGI-klV6->Wa`Gp=`X7#8LJ<{W%6-uyvxcB*C zO$P^?PGj944&n#92-$t;bIDoZ2IeC4VW@7zqA&Qu({>lH3q6QNwcABq&J35XdxFl7pTiJ!~Pc43*<51V5uE0cKw$O9w}>Qj0b)YAhP zb5f%MzhG@~`!Vy8LM=4D?ZOM`ju@;Hkb3FFxH+BuXts;BsuOa5o`ZJJG2S7lG54`kUYAw>e> z127b*x(2Tkuq4(ls0oNJiyXa_#+qK|)WZ&IAiZaS&mn`7LL7^S6OI0JYaf1Ppf#@j z0dZ0_50U2bMSh=vf)fybKqj-AGA$sg(VO}8%=r{HPTW@Uf#)Ri9;v z2hktX30pxxJdRyebc4+r%^W1?{g{;@y@iysL-aybdmlDDA69TX#lfdaw8cDj&O}na z)#x#a(Z~k7ZOcNV*zr75vF*dw2v&{j)E-Xn@cHzvPdh0G#5lwmHFomnLA`TQSES#u z)n4%Wx)Gj&^fLR9K1z({pqEi^+-P=4wB@qiQHsL! znBFz%NSZST4!eieU+Jr=sT8mG$|cB_dVf9f)e5~0nawX@p#89GLF|r(QiGI_R0?HY zm&i&Cqt8L)ysXM(AkR54X4K9l~@1^GS*THs1f^6 zFZ-IY^U~5C?qWS-UgWbxxO-rXT#S_Pc2IZ^lilC4%1ZHV=?IxXMk4I=ize0kK%nua zMA$73e3X=O9pOySeR7q?vH?3%$dS-LoxIsy344HB-yHXg#~_uJf_)=s1G|1GqjOc2 zAjrFkA!xtbCGN0ZwcL4AI883CRdT^?hWG_-Nh^ihFYZKbAXOAOfg-3ED*RP4i`%@W zriPXOS=ANkPYb!wX_#xwh&3~+v8z-Dwltzt54(G>!SG{>?J$Y~j7j0)gz%ubGA_4A z&!8zZidMd=Dv<(XhN^eFYz9je6@}-aD5#v%WKL(Yim^!eKh!~q@^Zy`a=Tm#hJgqZ zm(WfE4b(3_9H=@)bpm)C15U?CZRkS&F=>@V##;d;n*x97Foi0K=%7UWXTkBzmnEJk zrevD|u~ZR;?8sH%qJVhN8l;Vy^J8GBWCKHmA~`rjW(w~LU_i-L_gsFvUtGOUHUjRL z8#uoC%2;yG}d_bHHXYx|aQzNq)tzMxm7V65gCP(qNqam>FZ^S$Sm-I8V*Bs%^` zj!J6wXgV8BH`=1qWBRcO$}xa~`Xz4Hphj4>QXtnM7Ujl=YYi=rKu%45LJ4%QTZvcj z8K@G9fwwQ5-iwWuRtBz%%DiU*i+NFDiIn(FCM2diTMkN>4^=;~dDD1=5Hz1B;!br`3I^70VH{NQ*mqzttj-uc2hpgy;rpsVKIgF3h5$Gja}A zUo6-ZBXMxQoZxU4crNC3He;|lXhhCjZwW=-z$8-Sz1+gpt@<&{LlxvqqZUZg5shVC zzerX$0?7O->N0PRdLOIw1lRYJI}Ia3+M)uHaJ=*{?vY zK!SN~Wb-a9oDuWxT80e>B`WgxgNJ0MAInTRgPI2P4Bv;tCS{!!! zf<34Kd~>~;)Zs(yg8=0o5Lkl#Ivu5?xqmKRz#D&IN%0Rk8#(%BCy=ENh^OASfiMy* z$yHVpc0h?ZrCNrjayWDs46)G8)YOB*rjn^GV*LPe6m#GBIcY2vEFqB-!jeuxYuf^@ z8|}|Oi2|tN9`s%BLXM%LQGXliy3beX7vI?`>+%KsBKO~nQfex|!tBSamh@Oy$&9(!BTyq=lv9C`=!by=J8^JU?-x%#$ji*Z9OgHd{?^ zy`uGGXsWakkG_bdUjI~X!Dl7(R1@2~xL$`989TuNt#Xxxs`#)boN_x0lHxHEH-puE zAf7Qay@ca6Vl4`pPN=aGx&aV&ZP-YjH^)|0`F-NR2NtJ=ZYjl1-?0A*%hQJtZmHm_ z8gY}-a&^}3W~T;4iXF0$vp&2#nbdlq`_#FCtFdaV1zn+W%z1*CV&{8df@N7X5RRRU zv8``P4n%u3+HqV21?aoG-h;~aBL6Nkq&*v(O>9?NPchz`skgp~7n&{%88x`|QCqrb zYaHo%>lysT##fgc6!Ut$e^OT^7sq>HB(7bMc$T#Ugbv8q&HW5nCwl@G@@Ls}^jVho zi|_SVm;y7rAa&^)l)&~@#H4+TnnWV;Ec+&&;2Jg53jYQQCkL#~K%K$tA7C+>05nq+ z*F&9@dXy5zl3k%j!+P`DMoBPGlf&o}b~tJ;BwpDhf;sOB`I|s2?cR%Mge!-)%CDT#xnKYB} zgvKv!M66N01IQ}q43A8%`R3I)7bvlz-iKAcd3M!cgM`HL%l({ROlo0u&PI3eN(|mF zE(09%wjhtzI}(3OBcD6BR7WBD_n0^M8qQ%Q z(PG+4p@}@^Q<;MUnR`(+YSwyxg+G;zDZ%No)Kf|dqW-Gj?TD!nlm16`E9%|n3l_>e z`OxbO?;a&6+*Q8dT{8M|rS2Kt$6=8QjRK$T3VM)Y-e!28*s0B26&?YDP&H$6XL>^R znISAJXn3hCJsAy~;}YS$(dvCw!G~nr5h&PHZQj{Hq)+zl0Q$bFM3fv8Sm|3ou}1G| zJq1xCXW(gMpTAILuT|LxiB1v|&wt(>q&z8_C23(1YE1Eo5uiFwMLNhzkBQsC($Ipj ziT>InNo3!JGc2dChLHzAaVDmM@1H8_1Jztr31$)#xo^3M-t~QP+DfBL<5=13ZLkAnS zvj)1>*dHg+GM=fyZ=ii<>4zjRt1PBUMZ~w!q507Fz+(in&?Vy8hDG-)>!c>QV}W9{ zuc+F&_TTeMOQYxl^U3+cXa{E$lezQMu*r<{DFuN7WCNNQ6d=kr7knHd#wV6zGI1=f z_Cx__xN4`pCp!Wn4HU%vqp?)rcnc27>3B5zmOQe3u9NOUSnjZUkBd*CG(9w zF^u^FgDUlFa;lsGR@d`Il&gGIRh2%Wp;6GS%y(dTzJgBJFZ9>Jx8Y04j6U&GbQNfY znIIc)=13g4;k=`K?O+w*;Z<0>i+`4CK5}Dt&c8WDcZX zWmN2Hd*Vm3ZwHZXR6O2xm&*PtmHqC3`0!YAC}W;0XW|8nR@*PFR083H#~R$@v8rkBzZu5nNbm07H;N!E~m?9&d+7aT4+yylW$ z**@(^QPAv5%(W$vkL*am>&g=T)uLWg%DdlSZ9+%HI&@?HLXhrUv;h730QaOx*^AXt z9h?3QiNgfYwmv7?guP;@cD(yMCRE=Ym(!}w=YkJmK%%;n_;x04<*`z{a(ZU0Y3_=3$S5S2Ami8`QF;b@cbBCA!l*We?_bM}|2BA&-VugE)NWety~Jrc$f z@kb>)F@sZl#+5uR#=it>GyK?A`cQ9M~bh#DXRd*q43_-61ly%K!^H* z3riXD4eUgczI!zI8=mP6g`V5iQSLt@7n*rk%`ku!)lR43adddnZIe264-~kIks}GY zPr=^PvZR37?IHKpj7WdVCa-xTl#1}3lv!hg@1ZW!QPnsh_*c9I#8uD9T4Nr09~7J2 zON~-TL^ut%QEtZxf<9iKXV*OrSk(1W%ic6#RKQl63M7=vqM!f#=Oc}cdF#im=*aS| z@J!3Xv4^YjCo*dni4Qx+}%U6dv z8YlD$C~+9$;7t1$!=GnfW0b_L*tk(5tXE-_^jWWcdS~QNR-q?z-CKsosUkf|b0E=) zBXAyemrN-*xHZGpj*Y!JB5Jp(ljpkLYnApbWdY4G@X+}E6ghEJ#2kjtZIsL|EGb^g zMU(pHxzX|EJY@Bztm+Bhv5OIvNCT zs}hsdgrH}UV#nYxm1zM!XL<)F$&FdPXk_7NWg!?)9)$RyVz?_PUP=)!=Gtvbm$e2 z>8+d4YnW_|wXm-236F?*`;ZG>%9H(h2QQ>9KSa`lCEM_1Pxd&9;z*O@&Gd^x)hQ4P zs!L-E+%Y;l1&~2pDgBA+7Df1ovrT@M4W%~cOn#9sdXpn{V~)NN{sveCl4kj-kaAxf znzZDEo#)GDq=d?h`WzhVVTl$g>~7|HS-lp;gW%Yrvhhcj}}X_TIuX9W87S?7$> zi+UwqF1DTw<3P?FSGeA>_8s$Yu~`lxs~nlJq4+DtqTg$o%8I24WLw|MNT;WV_abu| zB|*LQ0dzeo|LP^dXe&3JJ`ws|Qu^|^n$~egqT0#f$(*PHnGLUX?Dh?M>2$*j=QWX9nrFE6(oCb+sRtknvvzv_vZJ&B2G`9l@KQo;1=;JjH|RL z!MrEY8Ib1#)y|!s^qIEMczA$f#mFr5ihO!q|lyih`>DrpBVWn$UTl~4Uaprp;m)ay<7tfh+e1E zBn~*`1i%9et=@oE8w}5FWE%DuI?QQy#N&>6RuYRbPmlp@H3?rWItPi>XcOCCSC$I; z!(auQRwUODCpwbm7u6s!Gq=jtPEW#HQ5%YF+o+ZqE-3lH6?P4f6mqbck#;OhIL#eG zZBvvvJhIV|9(uH$4n@UT49H^qO-{E9Y)M7QV{0f7YDnM(2ulXVjiiQ0j1f1ve)(topsUe}O%&V-l=GZyxMVQLAvd z?(K5zzkiNiC(Q9kO?bPo9&kb;?bHw zx2N!T#N}up9SaEd?g5c|v!<=s+;h$n!{8V*FM)%!&r%mUA~7fIe0_=VnSi)&8mb&` zKuN*6?a<5Z@F6oQdQekAMc=01p*rhOYx+J;0}G8Wx~PI`N~xr$LyHMTfbc)Oey zqw1ecI&9_|_dufeC!j>kl0)*G|6n$eV&G0A^%up zb(X#NTS%F7XxjyfBDHn}k~b%Y^z63~5kq?B?MyAr(M#Z7>C{v7Qc_uRiQ@rBiJJ|F z#^At}t%an8$c^eSsd7OIBz$hnMjLk$t?e5w^ZQqHvJyz0fXD$U%1sb*P;|n-Qyp4C za!NJ0!r8JBB<;@(UyAWWXPpDzu0;otA3`SItbihn#U#1#T_F$EUQwMu1_&%jYzO$o zOfyobE_*U3L+C)kuDdv(P(sZ*+FKI?4Gd*;if!w-$TPi|!jw{IU0y@c5e?2jz90pw zU;HmN8>YLVs7G5z^#?*GF73E(?2!GULoE)llt|qOi5-&i48NQ5(^A`9@+?=L!1NZt zrDtI2&p#^ducp0t)*B+y?^^$9q(4JHv<~ju{Zaex$ZjJJ)v0SxTp2qtrby4#p;3|3 z8IePdXnErJX_<_>ORA=HL?0B6q6CVr|HQSwC5Tbf*>I6cd0a~O2BXqZ=y!x~i(IgU zuHWitJ+{vlnq*!XxsVddid;wykMFj1r^@3$9zlHP&^4WAhG8pACA7bNnCDIM*l}m- z%%X6%uZBLb0rB2pIfWgw?@SB~c4l$d8~KX^ytNsJ)KnJVJNrwZna&FVxW_z_5Lq3v zSmEaQx=SW+jw5jzOb)is0%BoIrr`Y0yw4Z;3#`$_a(1peBI65UxN(DXmY@f*&?5hz zjBS|-$F_0OLF+$IGp?<$Ix|%&15Q;V4%;hGW{5x8C&*eoRF}O-WwsW#69&}SBTvgo z9@tg=lX$moR#2u7%(Z1Pnn{HLo8cj6Y;8mVj&61D0Z5J(tYID;(enSKY@DdTysrEI$ag52&p}L@ zaM-v#>g|%v1bzQaYkQy_DrR*T&^AZuHs)1rHRzk^?(iPRF-f%gc!&2bZHMRlS`e0OCXG5FBF5E7q?@SrH&QVFF3I&$J$qX zF47K}4~_mxig6qk)V(}RqlaZ4J~o&hZnEGqEdGJ@U~mVU%WZWy4)Fs;Xf4K|cBc8q z3c9+l4&8@ytqnNJs-;kLBgZbxfBvy5-+NPX;m+HAHF8U-$|JGs#p#0(=p9&UJlIgi z(JLc;=P1|yH_p%Y*>b|Y`Ny^&bv=G)Q2fFULAg`IBX+pE`FUVoKf`nvHaRwroEy$C zu)@2|akC0eY#s%@BDE~5pvk`F{XsiB&Dzz@mPfG@!CF?5ffX#$o@t`Zl8mUml^DT^ zxb%EhE;^Re3&@_%RgKu2O*z<;!s`m))osiTbymf=1L7sb;C5!Cw!)K#^&Bdyc-qP| zO=Zdqh;I*On!!w2xRzjL%2k=Nv05cFHQo(HtwBOqhv8OYQ(I3lN0clgqb@wz)2 zSgEJ72Z2qx4{I;DJqzzf?Nh2o^m8)tJgUI=i-@%C{87U87jz9!Auntt00HLAWl^uKGvT_M%bC4+@hzl>cMi-_JJkY8J!L@BQlm|!nnpgl0*E$swN#~QNov^A}9zQ zWl#;g?j7|R*wIF3-|jXuta}FYBEn7&PwZZXY}ZzJoyvd)VwH8n`FOBqAn~QY5*6t- z>OCIkPOo!^CnLGD8fp}C7+c(Cm658KF4~Emc|7$?o-|B6PKQ8cPl3_Ro3Z}G5@gK7 zb_zNPs0z0maMytv$}DL3s6SJoLit3YVGPJvxCmY<(5#&W9!K-{lQS>vhETVH_dNw4 z23}ty625a{m=6OKsu|#~U=a4~Xx*Fsq_Gu#h2r2#5D+-={`QM<8KCDp?*aKlKN1$q zN2lLhVHs^rs4>9}r~}UZ>e$YxhC5;Me&hPzQpzRyhxZGyd(~gX0!b%i@v~*p^bEu4 zpC6JVf{Hd4OAsO&R0JF-E@?ga$XH)Z@JZQ916o1kNH|x~|8G9YSSgE1Rgt^w8IYGe z2)}WGRqa+62GFR9uV4hd$3QR8%$VWyDV(w`jJyuhiC?%-TmI3umz0Tr9@bSrhX{FJ z!*25qL_9~PXzP%1ort>*aajA?K9DhQA|}&{c~!=AA%+$i=6M4#*d?7p)L*cAfY5_) zBMQffH?GXUIJ`aLiKPl5xIBoyD5aLy;&I|=Q$yj=H*NJxYC-epR#;vLs(&FlQ{hn< zs9*d9xy`YazLWM`XwKc)xqk68Re`j%56+3S9FTD&Hr|2t{MV$KN3mDM*&_}U;JAja zW(9D<*@+YpLQ~SSu5-EMV_DyTV+*JEIC`L0#Kk)Y;JAI#m=PL_d(hA-7NP?(w>cF# z;64VJ=LF-PgPjM=7n~#=1Z#lIjHmp^&yUKX{6SY#ZiP zx|>7h{fCr*_;J9Z=B?b^gAYG%gVZYkDI@VIu=I%+$Gu1MPAdaBfL1r&PW*y@Pd@3C z?@TjV`L4HS;x8t+<*sX@@?9Qkm-)oA&!b`!s)3&RO`ALn zdJjFW5dk&h@Plgo4LG~9aRhg*b1_3GbQuu@ofjm>Edx2nbme0ebA9g=cIDmKKuA@fqxCX`6FXY3K%j}IvE7Nb<|QPq^i~HV z&CN3>hDYu!vqjh2U?;rA*v;4iS$^#}pefqQs(j*U7|zfGLxMXe@E(MGH4FW?y11K_ z?r6OnS);N|pZru)m3Rs>i%zNz`BdXLNoY~EmF>*f4qQKi!b6(6R@rz5&pjpKLrcCL zyp>$mlmaHUV^))Lt?O0+kpx2K0(Z1}@E|cVBTfG>JT9^U>a;Vm!JSY$QGRGcYI4{c z8zotKNj4y;uk>+*A=j|)Iw;26n80mzu6g$8-ELc*euP<~&fUPXrhk}P?rc4_1%|te z(aMXFp1WEOto$`TuJTBV{)Ws-M*+$}bE5RVg{qxE13h=)`d27JNxyM2Wjj(pozObo zrlxF}arIZle;^_MD2&S;I3&=eE;Y`&JFP_8wq*U4U4@HE0 z;Lu+=_^0%i3%1LSZF`?Xj+`zY@rt|@Doq$XnuJTP)2PbSXYahI5NT~4jP%rnx#<18 zg2P*`-uBtw(ID_pDQw$q8bS`s5Vb(>ie=^qoWG6HrZ zLycNyoM4RH_C5zc;)tGtS^{( zQm39igzYR{TRK?-(a0OR(a0j{rt8yiN9!=Cr(gW{<`NR_n$JUlN7jJggIWS#jn2o?F&3!V<(Ff0dp3#n;Z zWsn)<$&lg6!u-cP)BzI3g{4!rTnh@i0VoXq1M}8skCsmHftYZbDt1fXnjD%%Jy{0M zg=T&kFDNu^%e6H%!wXGAp-dK9lq{5K_+ie4@i(qJccC1<(V+XYhD?N?f>TTXq&pTJ~CuLD?BoBLeK{SidEa+gghmi=|R5 znQLT=xH}1?*v*;hB@IRbw8gnjrDVd#4$M-XA;iVm3#c2%EO8<5hQcs1s6y!hsQ{qA zgN26QTIfcJLF`J`Pq#AjRD$vi*g@NoX^I>Hhi6i-&3l49pFqazX5WU#cMrZCaCRoczYIr)A4<(BWy0%`Yzj3g4 zLUfj`;PBSVVbh7uz9ms`WJ}(`o(Yfw6iA(VhItw2O=2rLdwjy@Z%oB?SCBmhJcKT5 z)DeD;QS7ctth4JCXK>!?6H~`w3Al6X�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 KnI9=A<9`5vxO=hy literal 0 HcmV?d00001 diff --git a/build/premake4_linux64 b/build/premake4_linux64 new file mode 100644 index 0000000000000000000000000000000000000000..4724db58819c33c60ed3442e5d1f3940e9faa5d0 GIT binary patch literal 392616 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 z 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 literal 0 HcmV?d00001 diff --git a/build/premake4_osx b/build/premake4_osx new file mode 100644 index 0000000000000000000000000000000000000000..67e25d5b94b80be747a92c571bd37121c4a5faa2 GIT binary patch literal 481412 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 literal 0 HcmV?d00001 diff --git a/build/stringify.bat b/build/stringify.bat new file mode 100644 index 000000000..890f27d9d --- /dev/null +++ b/build/stringify.bat @@ -0,0 +1,13 @@ + +@echo off + + +premake4 --file=stringifyKernel.lua --kernelfile="../opencl/vector_add/VectorAddKernels.cl" --headerfile="../opencl/vector_add/VectorAddKernels.h" --stringname="vectorAddCL" stringify + +premake4 --file=stringifyKernel.lua --kernelfile="../opencl/parallel_primitives/kernels/RadixSort32Kernels.cl" --headerfile="../opencl/parallel_primitives/kernels/RadixSort32KernelsCL.h" --stringname="radixSort32KernelsCL" stringify +premake4 --file=stringifyKernel.lua --kernelfile="../opencl/parallel_primitives/kernels/BoundSearchKernels.cl" --headerfile="../opencl/parallel_primitives/kernels/BoundSearchKernelsCL.h" --stringname="boundSearchKernelsCL" stringify +premake4 --file=stringifyKernel.lua --kernelfile="../opencl/parallel_primitives/kernels/PrefixScanKernels.cl" --headerfile="../opencl/parallel_primitives/kernels/PrefixScanKernelsCL.h" --stringname="prefixScanKernelsCL" stringify +premake4 --file=stringifyKernel.lua --kernelfile="../opencl/parallel_primitives/kernels/FillKernels.cl" --headerfile="../opencl/parallel_primitives/kernels/FillKernelsCL.h" --stringname="fillKernelsCL" stringify + + +pause \ No newline at end of file diff --git a/build/stringify.sh b/build/stringify.sh new file mode 100644 index 000000000..bb93fa405 --- /dev/null +++ b/build/stringify.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +./premake4_osx --file=stringifyKernel.lua --kernelfile="../opencl/vector_add/VectorAddKernels.cl" --headerfile="../opencl/vector_add/VectorAddKernels.h" --stringname="vectorAddCL" stringify +./premake4_osx --file=stringifyKernel.lua --kernelfile="../opencl/parallel_primitives/kernels/RadixSort32Kernels.cl" --headerfile="../opencl/parallel_primitives/kernels/RadixSort32KernelsCL.h" --stringname="radixSort32KernelsCL" stringify +./premake4_osx --file=stringifyKernel.lua --kernelfile="../opencl/parallel_primitives/kernels/BoundSearchKernels.cl" --headerfile="../opencl/parallel_primitives/kernels/BoundSearchKernelsCL.h" --stringname="boundSearchKernelsCL" stringify +./premake4_osx --file=stringifyKernel.lua --kernelfile="../opencl/parallel_primitives/kernels/PrefixScanKernels.cl" --headerfile="../opencl/parallel_primitives/kernels/PrefixScanKernelsCL.h" --stringname="prefixScanKernelsCL" stringify +./premake4_osx --file=stringifyKernel.lua --kernelfile="../opencl/parallel_primitives/kernels/FillKernels.cl" --headerfile="../opencl/parallel_primitives/kernels/FillKernelsCL.h" --stringname="fillKernelsCL" stringify + diff --git a/build/stringifyKernel.lua b/build/stringifyKernel.lua new file mode 100644 index 000000000..dea0a73fe --- /dev/null +++ b/build/stringifyKernel.lua @@ -0,0 +1,78 @@ + + +function stringifyKernel(filenameIn, filenameOut, kernelMethod) + local BUFSIZE = 1024*1024 -- 1MB + local f = io.open(filenameIn,"r"); + local fw = io.open(filenameOut,"w"); + fw:write("//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project\n") + fw:write("static const char* " .. kernelMethod .. "= \\\n") + local cc, lc, wc = 0, 0, 0 -- char, line, and word counts + while true do + local lines, rest = f:read(BUFSIZE, "*line") + if not lines then break end + + local i = 0 + local startpos = 0 + local slen = string.len(lines) + local endpos = 0 + while true do + i = string.find(lines, "\n", i+1) -- find 'next' newline + if i == nil then + endpos = slen + else + endpos = i + end + oneline = string.sub(lines,startpos,endpos) + oneline = string.gsub(oneline,"\n","") + oneline = '\"' .. oneline .. '\\n\"' + oneline = string.gsub(oneline,"\\\\n","") + oneline = oneline .. "\n" + --print(oneline) + fw:write(oneline) + if i == nil then break end + startpos = i+1 + end + + if rest then lines = lines .. rest .. '\n' end + cc = cc + string.len(lines) + -- count words in the chunk + local _,t = string.gsub(lines, "%S+", "") + wc = wc + t + -- count newlines in the chunk + _,t = string.gsub(lines, "\n", "\n") + lc = lc + t + end + --print("stringified " .. filenameIn .. " into " .. filenameOut .. " processed " .. lc .. " lines") + print(filenameIn .. " (" .. lc .. " lines)") + + f:close() + fw:write(";\n") + fw:close() + end + + newoption { + trigger = "kernelfile", + value = "kernelpath", + description = "full path to the kernel source input file" + } + + newoption { + trigger = "headerfile", + value = "path", + description = "full path to the header output file" + } + + newoption { + trigger = "stringname", + value = "var", + description = "name of the kernel string variable" + } + + newaction { + trigger = "stringify", + description = "stringify kernels source code into strings", + execute = function () + stringifyKernel( _OPTIONS["kernelfile"] , _OPTIONS["headerfile"], _OPTIONS["stringname"]) + + end +} \ No newline at end of file diff --git a/build/vs2010.bat b/build/vs2010.bat new file mode 100644 index 000000000..584d0baa8 --- /dev/null +++ b/build/vs2010.bat @@ -0,0 +1,6 @@ + +rem premake4 --with-pe vs2010 +premake4 vs2010 + +mkdir vs2010\cache +pause \ No newline at end of file diff --git a/build/xcode.command b/build/xcode.command new file mode 100644 index 000000000..52a4a4a7c --- /dev/null +++ b/build/xcode.command @@ -0,0 +1,4 @@ + +cd `dirname $0` +./premake4_osx xcode4 + diff --git a/opencl/basic_initialize/btOpenCLInclude.h b/opencl/basic_initialize/btOpenCLInclude.h new file mode 100644 index 000000000..5f0e78da6 --- /dev/null +++ b/opencl/basic_initialize/btOpenCLInclude.h @@ -0,0 +1,44 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_OPENCL_INCLUDE_H +#define BT_OPENCL_INCLUDE_H + + +#ifdef __APPLE__ +#ifdef USE_MINICL +#include +#else +#include +#include //clLogMessagesToStderrAPPLE +#endif +#else +#ifdef USE_MINICL +#include +#else +#include +#ifdef _WIN32 +#include "CL/cl_gl.h" +#endif //_WIN32 +#endif +#endif //__APPLE__ + +#include +#include +#define oclCHECKERROR(a, b) if((a)!=(b)) { printf("OCL Error : %d\n", (a)); assert((a) == (b)); } + + +#endif //BT_OPENCL_INCLUDE_H + diff --git a/opencl/basic_initialize/btOpenCLUtils.cpp b/opencl/basic_initialize/btOpenCLUtils.cpp new file mode 100644 index 000000000..af29461e7 --- /dev/null +++ b/opencl/basic_initialize/btOpenCLUtils.cpp @@ -0,0 +1,903 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2011 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//original author: Roman Ponomarev +//cleanup by Erwin Coumans + +#include + +#ifdef _WIN32 +#pragma warning (disable:4996) +#endif +#include "btOpenCLUtils.h" +//#include "btOpenCLInclude.h" + +#include +#include + +#define BT_MAX_CL_DEVICES 16 //who needs 16 devices? + +#ifdef _WIN32 +#include +#endif + +#include +#define btAssert assert + + +//Set the preferred platform vendor using the OpenCL SDK +static const char* spPlatformVendor = +#if defined(CL_PLATFORM_MINI_CL) +"MiniCL, SCEA"; +#elif defined(CL_PLATFORM_AMD) +"Advanced Micro Devices, Inc."; +#elif defined(CL_PLATFORM_NVIDIA) +"NVIDIA Corporation"; +#elif defined(CL_PLATFORM_INTEL) +"Intel(R) Corporation"; +#else +"Unknown Vendor"; +#endif + +#ifndef CL_PLATFORM_MINI_CL +#ifdef _WIN32 +#include "CL/cl_gl.h" +#endif //_WIN32 +#endif + +bool gDebugForceLoadingFromSource = false; +bool gDebugSkipLoadingBinary = false; + +void MyFatalBreakAPPLE( const char * errstr , + const void * private_info , + size_t cb , + void * user_data ) +{ + printf("Error: %s\n", errstr); + + const char* patloc = strstr(errstr, "Warning"); + //find out if it is a warning or error, exit if error + + if (patloc) + { + printf("warning\n"); + } else + { + printf("error\n"); + btAssert(0); + } + + +} + + +int btOpenCLUtils_getNumPlatforms(cl_int* pErrNum) +{ + + cl_platform_id pPlatforms[10] = { 0 }; + + cl_uint numPlatforms = 0; + cl_int ciErrNum = clGetPlatformIDs(10, pPlatforms, &numPlatforms); + //cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms); + + if(ciErrNum != CL_SUCCESS) + { + if(pErrNum != NULL) + *pErrNum = ciErrNum; + } + return numPlatforms; + +} + +const char* btOpenCLUtils_getSdkVendorName() +{ + return spPlatformVendor; +} + +cl_platform_id btOpenCLUtils_getPlatform(int platformIndex0, cl_int* pErrNum) +{ + cl_platform_id platform = 0; + unsigned int platformIndex = (unsigned int )platformIndex0; + cl_uint numPlatforms; + cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms); + + if (platformIndex>=0 && platformIndexm_platformVendor,NULL); + oclCHECKERROR(ciErrNum,CL_SUCCESS); + ciErrNum = clGetPlatformInfo( platform,CL_PLATFORM_NAME,BT_MAX_STRING_LENGTH,platformInfo->m_platformName,NULL); + oclCHECKERROR(ciErrNum,CL_SUCCESS); + ciErrNum = clGetPlatformInfo( platform,CL_PLATFORM_VERSION,BT_MAX_STRING_LENGTH,platformInfo->m_platformVersion,NULL); + oclCHECKERROR(ciErrNum,CL_SUCCESS); +} + +void btOpenCLUtils_printPlatformInfo(cl_platform_id platform) +{ + btOpenCLPlatformInfo platformInfo; + btOpenCLUtils::getPlatformInfo (platform, &platformInfo); + printf("Platform info:\n"); + printf(" CL_PLATFORM_VENDOR: \t\t\t%s\n",platformInfo.m_platformVendor); + printf(" CL_PLATFORM_NAME: \t\t\t%s\n",platformInfo.m_platformName); + printf(" CL_PLATFORM_VERSION: \t\t\t%s\n",platformInfo.m_platformVersion); +} + + + +cl_context btOpenCLUtils_createContextFromPlatform(cl_platform_id platform, cl_device_type deviceType, cl_int* pErrNum, void* pGLContext, void* pGLDC, int preferredDeviceIndex, int preferredPlatformIndex) +{ + cl_context retContext = 0; + cl_int ciErrNum=0; + cl_uint num_entries; + cl_device_id devices[BT_MAX_CL_DEVICES]; + cl_uint num_devices; + cl_context_properties* cprops; + + /* + * If we could find our platform, use it. Otherwise pass a NULL and get whatever the + * implementation thinks we should be using. + */ + cl_context_properties cps[7] = {0,0,0,0,0,0,0}; + cps[0] = CL_CONTEXT_PLATFORM; + cps[1] = (cl_context_properties)platform; +#ifdef _WIN32 + if (pGLContext && pGLDC) + { + cps[2] = CL_GL_CONTEXT_KHR; + cps[3] = (cl_context_properties)pGLContext; + cps[4] = CL_WGL_HDC_KHR; + cps[5] = (cl_context_properties)pGLDC; + } +#endif //_WIN32 + num_entries = BT_MAX_CL_DEVICES; + + + num_devices=-1; + + ciErrNum = clGetDeviceIDs( + platform, + deviceType, + num_entries, + devices, + &num_devices); + + if (ciErrNum<0) + { + printf("clGetDeviceIDs returned %d\n",ciErrNum); + return 0; + } + cprops = (NULL == platform) ? NULL : cps; + + if (!num_devices) + return 0; + + if (pGLContext) + { + //search for the GPU that relates to the OpenCL context + unsigned int i; + for (i=0;i=0 && (unsigned int)preferredDeviceIndex 0) + { + cl_platform_id* platforms = (cl_platform_id*) malloc (sizeof(cl_platform_id)*numPlatforms); + ciErrNum = clGetPlatformIDs(numPlatforms, platforms, NULL); + if(ciErrNum != CL_SUCCESS) + { + if(pErrNum != NULL) + *pErrNum = ciErrNum; + free(platforms); + return NULL; + } + + + + for ( i = 0; i < numPlatforms; ++i) + { + char pbuf[128]; + ciErrNum = clGetPlatformInfo( platforms[i], + CL_PLATFORM_VENDOR, + sizeof(pbuf), + pbuf, + NULL); + if(ciErrNum != CL_SUCCESS) + { + if(pErrNum != NULL) *pErrNum = ciErrNum; + return NULL; + } + + if (preferredPlatformIndex>=0 && i==preferredPlatformIndex) + { + cl_platform_id tmpPlatform = platforms[0]; + platforms[0] = platforms[i]; + platforms[i] = tmpPlatform; + break; + } else + { + if(!strcmp(pbuf, spPlatformVendor)) + { + cl_platform_id tmpPlatform = platforms[0]; + platforms[0] = platforms[i]; + platforms[i] = tmpPlatform; + } + } + } + + for (i = 0; i < numPlatforms; ++i) + { + cl_platform_id platform = platforms[i]; + assert(platform); + + retContext = btOpenCLUtils_createContextFromPlatform(platform,deviceType,pErrNum,pGLContext,pGLDC,preferredDeviceIndex,preferredPlatformIndex); + + if (retContext) + { +// printf("OpenCL platform details:\n"); + btOpenCLPlatformInfo platformInfo; + + btOpenCLUtils::getPlatformInfo(platform, &platformInfo); + + if (retPlatformId) + *retPlatformId = platform; + + break; + } + } + + free (platforms); + } + return retContext; +} + + +////////////////////////////////////////////////////////////////////////////// +//! Gets the id of the nth device from the context +//! +//! @return the id or -1 when out of range +//! @param cxMainContext OpenCL context +//! @param device_idx index of the device of interest +////////////////////////////////////////////////////////////////////////////// +cl_device_id btOpenCLUtils_getDevice(cl_context cxMainContext, int deviceIndex) +{ + assert(cxMainContext); + + size_t szParmDataBytes; + cl_device_id* cdDevices; + cl_device_id device ; + + // get the list of devices associated with context + clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParmDataBytes); + + if( szParmDataBytes / sizeof(cl_device_id) < (unsigned int)deviceIndex ) { + return (cl_device_id)-1; + } + + cdDevices = (cl_device_id*) malloc(szParmDataBytes); + + clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, szParmDataBytes, cdDevices, NULL); + + device = cdDevices[deviceIndex]; + free(cdDevices); + + return device; +} + +int btOpenCLUtils_getNumDevices(cl_context cxMainContext) +{ + size_t szParamDataBytes; + int device_count; + clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParamDataBytes); + device_count = (int) szParamDataBytes/ sizeof(cl_device_id); + return device_count; +} + + + +void btOpenCLUtils::getDeviceInfo(cl_device_id device, btOpenCLDeviceInfo* info) +{ + // CL_DEVICE_NAME + clGetDeviceInfo(device, CL_DEVICE_NAME, BT_MAX_STRING_LENGTH, &info->m_deviceName, NULL); + + // CL_DEVICE_VENDOR + clGetDeviceInfo(device, CL_DEVICE_VENDOR, BT_MAX_STRING_LENGTH, &info->m_deviceVendor, NULL); + + // CL_DRIVER_VERSION + clGetDeviceInfo(device, CL_DRIVER_VERSION, BT_MAX_STRING_LENGTH, &info->m_driverVersion, NULL); + + // CL_DEVICE_INFO + clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(cl_device_type), &info->m_deviceType, NULL); + + // CL_DEVICE_MAX_COMPUTE_UNITS + clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(info->m_computeUnits), &info->m_computeUnits, NULL); + + // CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS + clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(info->m_workitemDims), &info->m_workitemDims, NULL); + + // CL_DEVICE_MAX_WORK_ITEM_SIZES + clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(info->m_workItemSize), &info->m_workItemSize, NULL); + + // CL_DEVICE_MAX_WORK_GROUP_SIZE + clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(info->m_workgroupSize), &info->m_workgroupSize, NULL); + + // CL_DEVICE_MAX_CLOCK_FREQUENCY + clGetDeviceInfo(device, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(info->m_clockFrequency), &info->m_clockFrequency, NULL); + + // CL_DEVICE_ADDRESS_BITS + clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(info->m_addressBits), &info->m_addressBits, NULL); + + // CL_DEVICE_MAX_MEM_ALLOC_SIZE + clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(info->m_maxMemAllocSize), &info->m_maxMemAllocSize, NULL); + + // CL_DEVICE_GLOBAL_MEM_SIZE + clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(info->m_globalMemSize), &info->m_globalMemSize, NULL); + + // CL_DEVICE_ERROR_CORRECTION_SUPPORT + clGetDeviceInfo(device, CL_DEVICE_ERROR_CORRECTION_SUPPORT, sizeof(info->m_errorCorrectionSupport), &info->m_errorCorrectionSupport, NULL); + + // CL_DEVICE_LOCAL_MEM_TYPE + clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_TYPE, sizeof(info->m_localMemType), &info->m_localMemType, NULL); + + // CL_DEVICE_LOCAL_MEM_SIZE + clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(info->m_localMemSize), &info->m_localMemSize, NULL); + + // CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE + clGetDeviceInfo(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof(info->m_constantBufferSize), &info->m_constantBufferSize, NULL); + + // CL_DEVICE_QUEUE_PROPERTIES + clGetDeviceInfo(device, CL_DEVICE_QUEUE_PROPERTIES, sizeof(info->m_queueProperties), &info->m_queueProperties, NULL); + + // CL_DEVICE_IMAGE_SUPPORT + clGetDeviceInfo(device, CL_DEVICE_IMAGE_SUPPORT, sizeof(info->m_imageSupport), &info->m_imageSupport, NULL); + + // CL_DEVICE_MAX_READ_IMAGE_ARGS + clGetDeviceInfo(device, CL_DEVICE_MAX_READ_IMAGE_ARGS, sizeof(info->m_maxReadImageArgs), &info->m_maxReadImageArgs, NULL); + + // CL_DEVICE_MAX_WRITE_IMAGE_ARGS + clGetDeviceInfo(device, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, sizeof(info->m_maxWriteImageArgs), &info->m_maxWriteImageArgs, NULL); + + // CL_DEVICE_IMAGE2D_MAX_WIDTH, CL_DEVICE_IMAGE2D_MAX_HEIGHT, CL_DEVICE_IMAGE3D_MAX_WIDTH, CL_DEVICE_IMAGE3D_MAX_HEIGHT, CL_DEVICE_IMAGE3D_MAX_DEPTH + clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &info->m_image2dMaxWidth, NULL); + clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof(size_t), &info->m_image2dMaxHeight, NULL); + clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof(size_t), &info->m_image3dMaxWidth, NULL); + clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof(size_t), &info->m_image3dMaxHeight, NULL); + clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof(size_t), &info->m_image3dMaxDepth, NULL); + + // CL_DEVICE_EXTENSIONS: get device extensions, and if any then parse & log the string onto separate lines + clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, BT_MAX_STRING_LENGTH, &info->m_deviceExtensions, NULL); + + // CL_DEVICE_PREFERRED_VECTOR_WIDTH_ + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), &info->m_vecWidthChar, NULL); + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, sizeof(cl_uint), &info->m_vecWidthShort, NULL); + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof(cl_uint), &info->m_vecWidthInt, NULL); + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, sizeof(cl_uint), &info->m_vecWidthLong, NULL); + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, sizeof(cl_uint), &info->m_vecWidthFloat, NULL); + clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, sizeof(cl_uint), &info->m_vecWidthDouble, NULL); +} + + +void btOpenCLUtils_printDeviceInfo(cl_device_id device) +{ + btOpenCLDeviceInfo info; + btOpenCLUtils::getDeviceInfo(device,&info); + printf("Device Info:\n"); + printf(" CL_DEVICE_NAME: \t\t\t%s\n", info.m_deviceName); + printf(" CL_DEVICE_VENDOR: \t\t\t%s\n", info.m_deviceVendor); + printf(" CL_DRIVER_VERSION: \t\t\t%s\n", info.m_driverVersion); + + if( info.m_deviceType & CL_DEVICE_TYPE_CPU ) + printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_CPU"); + if( info.m_deviceType & CL_DEVICE_TYPE_GPU ) + printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_GPU"); + if( info.m_deviceType & CL_DEVICE_TYPE_ACCELERATOR ) + printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_ACCELERATOR"); + if( info.m_deviceType & CL_DEVICE_TYPE_DEFAULT ) + printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_DEFAULT"); + + printf(" CL_DEVICE_MAX_COMPUTE_UNITS:\t\t%u\n", info.m_computeUnits); + printf(" CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:\t%u\n", info.m_workitemDims); + printf(" CL_DEVICE_MAX_WORK_ITEM_SIZES:\t%u / %u / %u \n", info.m_workItemSize[0], info.m_workItemSize[1], info.m_workItemSize[2]); + printf(" CL_DEVICE_MAX_WORK_GROUP_SIZE:\t%u\n", info.m_workgroupSize); + printf(" CL_DEVICE_MAX_CLOCK_FREQUENCY:\t%u MHz\n", info.m_clockFrequency); + printf(" CL_DEVICE_ADDRESS_BITS:\t\t%u\n", info.m_addressBits); + printf(" CL_DEVICE_MAX_MEM_ALLOC_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_maxMemAllocSize/ (1024 * 1024))); + printf(" CL_DEVICE_GLOBAL_MEM_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_globalMemSize/ (1024 * 1024))); + printf(" CL_DEVICE_ERROR_CORRECTION_SUPPORT:\t%s\n", info.m_errorCorrectionSupport== CL_TRUE ? "yes" : "no"); + printf(" CL_DEVICE_LOCAL_MEM_TYPE:\t\t%s\n", info.m_localMemType == 1 ? "local" : "global"); + printf(" CL_DEVICE_LOCAL_MEM_SIZE:\t\t%u KByte\n", (unsigned int)(info.m_localMemSize / 1024)); + printf(" CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:\t%u KByte\n", (unsigned int)(info.m_constantBufferSize / 1024)); + if( info.m_queueProperties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE ) + printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE"); + if( info.m_queueProperties & CL_QUEUE_PROFILING_ENABLE ) + printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_PROFILING_ENABLE"); + + printf(" CL_DEVICE_IMAGE_SUPPORT:\t\t%u\n", info.m_imageSupport); + + printf(" CL_DEVICE_MAX_READ_IMAGE_ARGS:\t%u\n", info.m_maxReadImageArgs); + printf(" CL_DEVICE_MAX_WRITE_IMAGE_ARGS:\t%u\n", info.m_maxWriteImageArgs); + printf("\n CL_DEVICE_IMAGE "); + printf("\t\t\t2D_MAX_WIDTH\t %u\n", info.m_image2dMaxWidth); + printf("\t\t\t\t\t2D_MAX_HEIGHT\t %u\n", info.m_image2dMaxHeight); + printf("\t\t\t\t\t3D_MAX_WIDTH\t %u\n", info.m_image3dMaxWidth); + printf("\t\t\t\t\t3D_MAX_HEIGHT\t %u\n", info.m_image3dMaxHeight); + printf("\t\t\t\t\t3D_MAX_DEPTH\t %u\n", info.m_image3dMaxDepth); + if (info.m_deviceExtensions != 0) + printf("\n CL_DEVICE_EXTENSIONS:%s\n",info.m_deviceExtensions); + else + printf(" CL_DEVICE_EXTENSIONS: None\n"); + printf(" CL_DEVICE_PREFERRED_VECTOR_WIDTH_\t"); + printf("CHAR %u, SHORT %u, INT %u,LONG %u, FLOAT %u, DOUBLE %u\n\n\n", + info.m_vecWidthChar, info.m_vecWidthShort, info.m_vecWidthInt, info.m_vecWidthLong,info.m_vecWidthFloat, info.m_vecWidthDouble); + + +} + + +static const char* strip2(const char* name, const char* pattern) +{ + size_t const patlen = strlen(pattern); + size_t patcnt = 0; + const char * oriptr; + const char * patloc; + // find how many times the pattern occurs in the original string + for (oriptr = name; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen) + { + patcnt++; + } + return oriptr; +} + +cl_program btOpenCLUtils_compileCLProgramFromString(cl_context clContext, cl_device_id device, const char* kernelSourceOrg, cl_int* pErrNum, const char* additionalMacrosArg , const char* clFileNameForCaching) +{ + const char* additionalMacros = additionalMacrosArg?additionalMacrosArg:""; + + cl_program m_cpProgram=0; + cl_int status; + +#ifdef _WIN32 + char binaryFileName[BT_MAX_STRING_LENGTH]; + char* bla=0; + + if (clFileNameForCaching && !(gDebugSkipLoadingBinary||gDebugForceLoadingFromSource) ) + { + + char deviceName[256]; + char driverVersion[256]; + const char* strippedName; + int fileUpToDate = 0; + int binaryFileValid=0; + FILETIME modtimeBinary; + + clGetDeviceInfo(device, CL_DEVICE_NAME, 256, &deviceName, NULL); + clGetDeviceInfo(device, CL_DRIVER_VERSION, 256, &driverVersion, NULL); + + + strippedName = strip2(clFileNameForCaching,"\\"); + strippedName = strip2(strippedName,"/"); + +#ifdef _WIN32 + sprintf_s(binaryFileName,BT_MAX_STRING_LENGTH,"cache/%s.%s.%s.bin",strippedName, deviceName,driverVersion ); +#else + sprintf(binaryFileName,"cache/%s.%s.%s.bin",strippedName, deviceName,driverVersion ); +#endif + + + //printf("searching for %s\n", binaryFileName); + + + + + CreateDirectory("cache",0); + { + + HANDLE binaryFileHandle = CreateFile(binaryFileName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); + if (binaryFileHandle ==INVALID_HANDLE_VALUE) + { + DWORD errorCode; + errorCode = GetLastError(); + switch (errorCode) + { + case ERROR_FILE_NOT_FOUND: + { + printf("\nCached file not found %s\n", binaryFileName); + break; + } + case ERROR_PATH_NOT_FOUND: + { + printf("\nCached file path not found %s\n", binaryFileName); + break; + } + default: + { + printf("\nFailed reading cached file with errorCode = %d\n", errorCode); + } + } + } else + { + if (GetFileTime(binaryFileHandle, NULL, NULL, &modtimeBinary)==0) + { + DWORD errorCode; + errorCode = GetLastError(); + printf("\nGetFileTime errorCode = %d\n", errorCode); + } else + { + binaryFileValid = 1; + } + CloseHandle(binaryFileHandle); + } + + if (binaryFileValid) + { + HANDLE srcFileHandle = CreateFile(clFileNameForCaching,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); + + if (srcFileHandle==INVALID_HANDLE_VALUE) + { + const char* prefix[]={"../","../../","../../../","../../../../"}; + for (int i=0;(srcFileHandle==INVALID_HANDLE_VALUE) && i<3;i++) + { + char relativeFileName[1024]; + sprintf(relativeFileName,"%s%s",prefix[i],clFileNameForCaching); + srcFileHandle = CreateFile(relativeFileName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); + } + + } + + + if (srcFileHandle!=INVALID_HANDLE_VALUE) + { + FILETIME modtimeSrc; + if (GetFileTime(srcFileHandle, NULL, NULL, &modtimeSrc)==0) + { + DWORD errorCode; + errorCode = GetLastError(); + printf("\nGetFileTime errorCode = %d\n", errorCode); + } + if ( ( modtimeSrc.dwHighDateTime < modtimeBinary.dwHighDateTime) + ||(( modtimeSrc.dwHighDateTime == modtimeBinary.dwHighDateTime)&&(modtimeSrc.dwLowDateTime <= modtimeBinary.dwLowDateTime))) + { + fileUpToDate=1; + } else + { + printf("\nCached binary file out-of-date (%s)\n",binaryFileName); + } + CloseHandle(srcFileHandle); + } + else + { +#ifdef _DEBUG + DWORD errorCode; + errorCode = GetLastError(); + switch (errorCode) + { + case ERROR_FILE_NOT_FOUND: + { + printf("\nSrc file not found %s\n", clFileNameForCaching); + break; + } + case ERROR_PATH_NOT_FOUND: + { + printf("\nSrc path not found %s\n", clFileNameForCaching); + break; + } + default: + { + printf("\nnSrc file reading errorCode = %d\n", errorCode); + } + } + + //we should make sure the src file exists so we can verify the timestamp with binary + assert(0); + fileUpToDate = false; +#else + //if we cannot find the source, assume it is OK in release builds + fileUpToDate = true; +#endif + } + } + + + } + + if( fileUpToDate) + { +#ifdef _WIN32 + FILE* file; + if (fopen_s(&file,binaryFileName, "rb")!=0) + file=0; +#else + FILE* file = fopen(binaryFileName, "rb"); +#endif + + if (file) + { + size_t binarySize=0; + char* binary =0; + + fseek( file, 0L, SEEK_END ); + binarySize = ftell( file ); + rewind( file ); + binary = (char*)malloc(sizeof(char)*binarySize); + fread( binary, sizeof(char), binarySize, file ); + fclose( file ); + + m_cpProgram = clCreateProgramWithBinary( clContext, 1,&device, &binarySize, (const unsigned char**)&binary, 0, &status ); + btAssert( status == CL_SUCCESS ); + status = clBuildProgram( m_cpProgram, 1, &device, additionalMacros, 0, 0 ); + btAssert( status == CL_SUCCESS ); + + if( status != CL_SUCCESS ) + { + char *build_log; + size_t ret_val_size; + clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size); + build_log = (char*)malloc(sizeof(char)*(ret_val_size+1)); + clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL); + build_log[ret_val_size] = '\0'; + printf("%s\n", build_log); + free (build_log); + btAssert(0); + m_cpProgram = 0; + } + free (binary); + } + } + + } +#endif //_WIN32 + + if (!m_cpProgram) + { + + cl_int localErrNum; + char* compileFlags; + int flagsize; + + + + const char* kernelSource = kernelSourceOrg; + + if (!kernelSourceOrg || gDebugForceLoadingFromSource) + { + if (clFileNameForCaching) + { + + FILE* file = fopen(clFileNameForCaching, "rb"); + //in many cases the relative path is a few levels up the directory hierarchy, so try it + if (!file) + { + const char* prefix[]={"../","../../","../../../","../../../../"}; + for (int i=0;!file && i<3;i++) + { + char relativeFileName[1024]; + sprintf(relativeFileName,"%s%s",prefix[i],clFileNameForCaching); + file = fopen(relativeFileName, "rb"); + } + } + + if (file) + { + char* kernelSrc=0; + fseek( file, 0L, SEEK_END ); + int kernelSize = ftell( file ); + rewind( file ); + kernelSrc = (char*)malloc(kernelSize+1); + int readBytes = fread((void*)kernelSrc,1,kernelSize, file); + kernelSrc[kernelSize] = 0; + fclose(file); + kernelSource = kernelSrc; + } + } + } + + size_t program_length = kernelSource ? strlen(kernelSource) : 0; +#ifdef MAC //or __APPLE__? + char* flags = "-cl-mad-enable -DMAC -DGUID_ARG"; +#else + //const char* flags = "-DGUID_ARG= -fno-alias"; + const char* flags = "-DGUID_ARG= "; +#endif + + + m_cpProgram = clCreateProgramWithSource(clContext, 1, (const char**)&kernelSource, &program_length, &localErrNum); + if (localErrNum!= CL_SUCCESS) + { + if (pErrNum) + *pErrNum = localErrNum; + return 0; + } + + // Build the program with 'mad' Optimization option + + + + flagsize = sizeof(char)*(strlen(additionalMacros) + strlen(flags) + 5); + compileFlags = (char*) malloc(flagsize); +#ifdef _WIN32 + sprintf_s(compileFlags,flagsize, "%s %s", flags, additionalMacros); +#else + sprintf(compileFlags, "%s %s", flags, additionalMacros); +#endif + localErrNum = clBuildProgram(m_cpProgram, 1, &device, compileFlags, NULL, NULL); + if (localErrNum!= CL_SUCCESS) + { + char *build_log; + size_t ret_val_size; + clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size); + build_log = (char*) malloc(sizeof(char)*(ret_val_size+1)); + clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL); + + // to be carefully, terminate with \0 + // there's no information in the reference whether the string is 0 terminated or not + build_log[ret_val_size] = '\0'; + + + printf("Error in clBuildProgram, Line %u in file %s, Log: \n%s\n !!!\n\n", __LINE__, __FILE__, build_log); + free (build_log); + if (pErrNum) + *pErrNum = localErrNum; + return 0; + } + +#ifdef _WIN32 + + if( clFileNameForCaching ) + { // write to binary + + cl_uint numAssociatedDevices; + status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_NUM_DEVICES, sizeof(cl_uint), &numAssociatedDevices, 0 ); + btAssert( status == CL_SUCCESS ); + if (numAssociatedDevices==1) + { + + size_t binarySize; + char* binary ; + + status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binarySize, 0 ); + btAssert( status == CL_SUCCESS ); + + binary = (char*)malloc(sizeof(char)*binarySize); + + status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARIES, sizeof(char*), &binary, 0 ); + btAssert( status == CL_SUCCESS ); + + { + FILE* file=0; +#ifdef _WIN32 + if (fopen_s(&file,binaryFileName, "wb")!=0) + file=0; +#else + file = fopen(binaryFileName, "wb"); +#endif + if (file) + { + fwrite( binary, sizeof(char), binarySize, file ); + fclose( file ); + } else + { + printf("cannot write file %s\n", binaryFileName); + } + } + + free (binary); + } + } +#endif //_WIN32 + + free(compileFlags); + + } + return m_cpProgram; +} + + +cl_kernel btOpenCLUtils_compileCLKernelFromString(cl_context clContext, cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum, cl_program prog, const char* additionalMacros ) +{ + + cl_kernel kernel; + cl_int localErrNum; + + cl_program m_cpProgram = prog; + + printf("compiling kernel %s ",kernelName); + + if (!m_cpProgram) + { + m_cpProgram = btOpenCLUtils_compileCLProgramFromString(clContext,device,kernelSource,pErrNum, additionalMacros,0); + } + + + // Create the kernel + kernel = clCreateKernel(m_cpProgram, kernelName, &localErrNum); + if (localErrNum != CL_SUCCESS) + { + printf("Error in clCreateKernel, Line %u in file %s, cannot find kernel function %s !!!\n\n", __LINE__, __FILE__, kernelName); + assert(0); + if (pErrNum) + *pErrNum = localErrNum; + return 0; + } + + if (!prog && m_cpProgram) + { + clReleaseProgram(m_cpProgram); + } + printf("ready. \n"); + + + if (pErrNum) + *pErrNum = CL_SUCCESS; + return kernel; + +} diff --git a/opencl/basic_initialize/btOpenCLUtils.h b/opencl/basic_initialize/btOpenCLUtils.h new file mode 100644 index 000000000..a1c7fbd7c --- /dev/null +++ b/opencl/basic_initialize/btOpenCLUtils.h @@ -0,0 +1,179 @@ +/* +Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org +Copyright (C) 2006 - 2011 Sony Computer Entertainment Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//original author: Roman Ponomarev +//cleanup by Erwin Coumans + +#ifndef BT_OPENCL_UTILS_H +#define BT_OPENCL_UTILS_H + +#include "btOpenCLInclude.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +///C API for OpenCL utilities: convenience functions, see below for C++ API + +/// CL Context optionally takes a GL context. This is a generic type because we don't really want this code +/// to have to understand GL types. It is a HGLRC in _WIN32 or a GLXContext otherwise. +cl_context btOpenCLUtils_createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx , void* pGLDC , int preferredDeviceIndex , int preferredPlatformIndex, cl_platform_id* platformId); + +int btOpenCLUtils_getNumDevices(cl_context cxMainContext); + +cl_device_id btOpenCLUtils_getDevice(cl_context cxMainContext, int nr); + +void btOpenCLUtils_printDeviceInfo(cl_device_id device); + +cl_kernel btOpenCLUtils_compileCLKernelFromString( cl_context clContext,cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum, cl_program prog,const char* additionalMacros); + +//optional +cl_program btOpenCLUtils_compileCLProgramFromString( cl_context clContext,cl_device_id device, const char* kernelSource, cl_int* pErrNum,const char* additionalMacros , const char* srcFileNameForCaching); + +//the following optional APIs provide access using specific platform information +int btOpenCLUtils_getNumPlatforms(cl_int* pErrNum); + +///get the nr'th platform, where nr is in the range [0..getNumPlatforms) +cl_platform_id btOpenCLUtils_getPlatform(int nr, cl_int* pErrNum); + +void btOpenCLUtils_printPlatformInfo(cl_platform_id platform); + +const char* btOpenCLUtils_getSdkVendorName(); + +cl_context btOpenCLUtils_createContextFromPlatform(cl_platform_id platform, cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx , void* pGLDC ,int preferredDeviceIndex , int preferredPlatformIndex); + +#ifdef __cplusplus +} + +#define BT_MAX_STRING_LENGTH 1024 + +typedef struct +{ + char m_deviceName[BT_MAX_STRING_LENGTH]; + char m_deviceVendor[BT_MAX_STRING_LENGTH]; + char m_driverVersion[BT_MAX_STRING_LENGTH]; + char m_deviceExtensions[BT_MAX_STRING_LENGTH]; + + cl_device_type m_deviceType; + cl_uint m_computeUnits; + size_t m_workitemDims; + size_t m_workItemSize[3]; + size_t m_image2dMaxWidth; + size_t m_image2dMaxHeight; + size_t m_image3dMaxWidth; + size_t m_image3dMaxHeight; + size_t m_image3dMaxDepth; + size_t m_workgroupSize; + cl_uint m_clockFrequency; + cl_ulong m_constantBufferSize; + cl_ulong m_localMemSize; + cl_ulong m_globalMemSize; + cl_bool m_errorCorrectionSupport; + cl_device_local_mem_type m_localMemType; + cl_uint m_maxReadImageArgs; + cl_uint m_maxWriteImageArgs; + + + + cl_uint m_addressBits; + cl_ulong m_maxMemAllocSize; + cl_command_queue_properties m_queueProperties; + cl_bool m_imageSupport; + cl_uint m_vecWidthChar; + cl_uint m_vecWidthShort; + cl_uint m_vecWidthInt; + cl_uint m_vecWidthLong; + cl_uint m_vecWidthFloat; + cl_uint m_vecWidthDouble; + +} btOpenCLDeviceInfo; + +typedef struct +{ + char m_platformVendor[BT_MAX_STRING_LENGTH]; + char m_platformName[BT_MAX_STRING_LENGTH]; + char m_platformVersion[BT_MAX_STRING_LENGTH]; +} btOpenCLPlatformInfo; + + +///C++ API for OpenCL utilities: convenience functions +struct btOpenCLUtils +{ + /// CL Context optionally takes a GL context. This is a generic type because we don't really want this code + /// to have to understand GL types. It is a HGLRC in _WIN32 or a GLXContext otherwise. + static inline cl_context createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx = 0, void* pGLDC = 0, int preferredDeviceIndex = -1, int preferredPlatformIndex= - 1, cl_platform_id* platformId=0) + { + return btOpenCLUtils_createContextFromType(deviceType, pErrNum, pGLCtx , pGLDC , preferredDeviceIndex, preferredPlatformIndex, platformId); + } + + static inline int getNumDevices(cl_context cxMainContext) + { + return btOpenCLUtils_getNumDevices(cxMainContext); + } + static inline cl_device_id getDevice(cl_context cxMainContext, int nr) + { + return btOpenCLUtils_getDevice(cxMainContext,nr); + } + + static void getDeviceInfo(cl_device_id device, btOpenCLDeviceInfo* info); + + static inline void printDeviceInfo(cl_device_id device) + { + btOpenCLUtils_printDeviceInfo(device); + } + + static inline cl_kernel compileCLKernelFromString( cl_context clContext,cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum=0, cl_program prog=0,const char* additionalMacros = "" ) + { + return btOpenCLUtils_compileCLKernelFromString(clContext,device, kernelSource, kernelName, pErrNum, prog,additionalMacros); + } + + //optional + static inline cl_program compileCLProgramFromString( cl_context clContext,cl_device_id device, const char* kernelSource, cl_int* pErrNum=0,const char* additionalMacros = "" , const char* srcFileNameForCaching=0) + { + return btOpenCLUtils_compileCLProgramFromString(clContext,device, kernelSource, pErrNum,additionalMacros, srcFileNameForCaching); + } + + //the following optional APIs provide access using specific platform information + static inline int getNumPlatforms(cl_int* pErrNum=0) + { + return btOpenCLUtils_getNumPlatforms(pErrNum); + } + ///get the nr'th platform, where nr is in the range [0..getNumPlatforms) + static inline cl_platform_id getPlatform(int nr, cl_int* pErrNum=0) + { + return btOpenCLUtils_getPlatform(nr,pErrNum); + } + + static void getPlatformInfo(cl_platform_id platform, btOpenCLPlatformInfo* platformInfo); + + static inline void printPlatformInfo(cl_platform_id platform) + { + btOpenCLUtils_printPlatformInfo(platform); + } + + static inline const char* getSdkVendorName() + { + return btOpenCLUtils_getSdkVendorName(); + } + static inline cl_context createContextFromPlatform(cl_platform_id platform, cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx = 0, void* pGLDC = 0,int preferredDeviceIndex = -1, int preferredPlatformIndex= -1) + { + return btOpenCLUtils_createContextFromPlatform(platform, deviceType, pErrNum, pGLCtx,pGLDC,preferredDeviceIndex, preferredPlatformIndex); + } +}; + +#endif //__cplusplus + +#endif // BT_OPENCL_UTILS_H diff --git a/opencl/basic_initialize/main.cpp b/opencl/basic_initialize/main.cpp new file mode 100644 index 000000000..263ba1b30 --- /dev/null +++ b/opencl/basic_initialize/main.cpp @@ -0,0 +1,98 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +///original author: Erwin Coumans + +#include "btOpenCLUtils.h" +#include + +cl_context g_cxMainContext; +cl_command_queue g_cqCommandQue; + + + +int main(int argc, char* argv[]) +{ + int ciErrNum = 0; + + cl_device_type deviceType = CL_DEVICE_TYPE_ALL; + const char* vendorSDK = btOpenCLUtils::getSdkVendorName(); + + printf("This program was compiled using the %s OpenCL SDK\n",vendorSDK); + int numPlatforms = btOpenCLUtils::getNumPlatforms(); + printf("Num Platforms = %d\n", numPlatforms); + + for (int i=0;i +#include +#include + +//make sure to update the same #define in the opencl/lds_bank_conflict/lds_kernels.cl +const int TILE_DIM = 32; +const int BLOCK_ROWS = 8; +const int NUM_REPS = 100; + +// Check errors and print GB/s +void postprocess(const float *ref, const float *res, int n, float ms) +{ + bool passed = true; + for (int i = 0; i < n; i++) + if (res[i] != ref[i]) { + printf("\nError: at res[%d] got %f but expected %f\n", i, res[i], ref[i]); + printf("%25s\n", "*** FAILED ***"); + passed = false; + break; + } + if (passed) + printf("%20.2f\n", 2 * n * sizeof(float) * 1e-6 * NUM_REPS / ms ); +} + +char* loadProgSource(const char* cFilename, const char* cPreamble, size_t* szFinalLength) +{ + // locals + FILE* pFileStream = NULL; + size_t szSourceLength; + + // open the OpenCL source code file + pFileStream = fopen(cFilename, "rb"); + if(pFileStream == 0) + { + return NULL; + } + + size_t szPreambleLength = strlen(cPreamble); + + // get the length of the source code + fseek(pFileStream, 0, SEEK_END); + szSourceLength = ftell(pFileStream); + fseek(pFileStream, 0, SEEK_SET); + + // allocate a buffer for the source code string and read it in + char* cSourceString = (char *)malloc(szSourceLength + szPreambleLength + 1); + memcpy(cSourceString, cPreamble, szPreambleLength); + fread((cSourceString) + szPreambleLength, szSourceLength, 1, pFileStream); + + // close the file and return the total length of the combined (preamble + source) string + fclose(pFileStream); + if(szFinalLength != 0) + { + *szFinalLength = szSourceLength + szPreambleLength; + } + cSourceString[szSourceLength + szPreambleLength] = '\0'; + + return cSourceString; +} + +int main(int argc, char **argv) +{ + printf("Use --deviceId= or --platformId= to override OpenCL device\n"); + CommandLineArgs args(argc,argv); + + const int nx = 1024; + const int ny = 1024; + + const int mem_size = nx*ny*sizeof(float); + const int num_elements = nx*ny; + btClock clock; + double startEvent=0.f; + double stopEvent=0.f; + + int localSizeX = TILE_DIM; + int localSizeY = BLOCK_ROWS; + + int numThreadsX = (nx/TILE_DIM)*TILE_DIM; + int numThreadsY = (ny/TILE_DIM)*BLOCK_ROWS; + + int gridX = numThreadsX / localSizeX; + int gridY = numThreadsY / localSizeY; + + int ciErrNum = 0; + int preferred_device = -1; + int preferred_platform = -1; + args.GetCmdLineArgument("deviceId",preferred_device); + args.GetCmdLineArgument("platformId",preferred_platform); + + + cl_platform_id platformId=0; + cl_context ctx=0; + cl_command_queue queue=0; + cl_device_id device=0; + cl_kernel copyKernel=0; + cl_kernel copySharedMemKernel=0; + cl_kernel transposeNaiveKernel = 0; + cl_kernel transposeCoalescedKernel = 0; + cl_kernel transposeNoBankConflictsKernel= 0; + + + ctx = btOpenCLUtils::createContextFromType(CL_DEVICE_TYPE_ALL, &ciErrNum,0,0,preferred_device,preferred_platform,&platformId); + btOpenCLUtils::printPlatformInfo(platformId); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + device = btOpenCLUtils::getDevice(ctx,0); + btOpenCLUtils::printDeviceInfo(device); + queue = clCreateCommandQueue(ctx, device, 0, &ciErrNum); + + const char* cSourceFile = "opencl/lds_bank_conflict/lds_kernels.cl"; + + size_t szKernelLength; + + const char* cSourceCL =0; + char relativeFileName[1024]; + + { + const char* prefix[]={"./","../","../../","../../../","../../../../"}; + int numPrefixes = sizeof(prefix)/sizeof(char*); + + for (int i=0;!cSourceCL && i d_idataCL(ctx,queue);d_idataCL.resize(num_elements); + btOpenCLArray d_cdataCL(ctx,queue);d_cdataCL.resize(num_elements); + btOpenCLArray d_tdataCL(ctx,queue);d_tdataCL.resize(num_elements); + + + // check parameters and calculate execution configuration + if (nx % TILE_DIM || ny % TILE_DIM) + { + printf("nx and ny must be a multiple of TILE_DIM\n"); + goto error_exit; + } + + if (TILE_DIM % BLOCK_ROWS) + { + printf("TILE_DIM must be a multiple of BLOCK_ROWS\n"); + goto error_exit; + } + + // host + for (int j = 0; j < ny; j++) + for (int i = 0; i < nx; i++) + h_idata[j*nx + i] = j*nx + i; + + // correct result for error checking + for (int j = 0; j < ny; j++) + for (int i = 0; i < nx; i++) + { + gold[j*nx + i] = h_idata[i*nx + j]; + } + + d_idataCL.copyFromHostPointer(h_idata,num_elements); + + // events for timing + clock.reset(); + + float ms; + + // ------------ + // time kernels + // ------------ + printf("%25s%25s\n", "Routine", "Bandwidth (GB/s)"); + + // ---- + // copy + // ---- + printf("%25s", "copy"); + + clMemSet.execute(d_cdataCL,0.f,num_elements); + + { + // warm up + btLauncherCL launcher( queue, copyKernel); + launcher.setBuffer( d_cdataCL.getBufferCL()); + launcher.setBuffer( d_idataCL.getBufferCL()); + launcher.launch2D(numThreadsX,numThreadsY,localSizeX,localSizeY ); + + startEvent = clock.getTimeMicroseconds()/1e3; + for (int i = 0; i < NUM_REPS; i++) + launcher.launch2D(numThreadsX,numThreadsY,localSizeX,localSizeY ); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + clFinish(queue); + stopEvent = clock.getTimeMicroseconds()/1e3; + } + + ms = float(stopEvent-startEvent); + + d_cdataCL.copyToHostPointer(h_cdata,num_elements,0); + postprocess(h_idata, h_cdata, nx*ny, ms); + + // ------------- + // copySharedMem + // ------------- + printf("%25s", "shared memory copy"); + clMemSet.execute(d_cdataCL,0.f,num_elements); + + { + btLauncherCL launcher( queue, copySharedMemKernel); + launcher.setBuffer( d_cdataCL.getBufferCL()); + launcher.setBuffer( d_idataCL.getBufferCL()); + launcher.launch2D(numThreadsX,numThreadsY,localSizeX,localSizeY ); + + startEvent = clock.getTimeMicroseconds()/1e3; + for (int i = 0; i < NUM_REPS; i++) + launcher.launch2D(numThreadsX,numThreadsY,localSizeX,localSizeY ); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + clFinish(queue); + stopEvent = clock.getTimeMicroseconds()/1e3; + } + + ms = float(stopEvent-startEvent); + d_cdataCL.copyToHostPointer(h_cdata,num_elements,0); + postprocess(h_idata, h_cdata, nx * ny, ms); + + // -------------- + // transposeNaive + // -------------- + printf("%25s", "naive transpose"); + clMemSet.execute(d_tdataCL,0.f,num_elements); + { + // warmup + btLauncherCL launcher( queue, transposeNaiveKernel); + launcher.setBuffer( d_tdataCL.getBufferCL()); + launcher.setBuffer( d_idataCL.getBufferCL()); + launcher.launch2D(numThreadsX,numThreadsY,localSizeX,localSizeY ); + + startEvent = clock.getTimeMicroseconds()/1e3; + for (int i = 0; i < NUM_REPS; i++) + launcher.launch2D(numThreadsX,numThreadsY,localSizeX,localSizeY ); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + clFinish(queue); + stopEvent = clock.getTimeMicroseconds()/1e3; + } + ms = float(stopEvent-startEvent); + d_tdataCL.copyToHostPointer(h_tdata,num_elements,0); + postprocess(gold, h_tdata, nx * ny, ms); + + // ------------------ + // transposeCoalesced + // ------------------ + printf("%25s", "coalesced transpose"); + clMemSet.execute(d_tdataCL,0.f,num_elements); + { + btLauncherCL launcher( queue, transposeCoalescedKernel); + launcher.setBuffer( d_tdataCL.getBufferCL()); + launcher.setBuffer( d_idataCL.getBufferCL()); + launcher.launch2D(numThreadsX,numThreadsY,localSizeX,localSizeY ); + + startEvent = clock.getTimeMicroseconds()/1e3; + for (int i = 0; i < NUM_REPS; i++) + launcher.launch2D(numThreadsX,numThreadsY,localSizeX,localSizeY ); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + clFinish(queue); + stopEvent = clock.getTimeMicroseconds()/1e3; + } + + ms = float(stopEvent-startEvent); + d_tdataCL.copyToHostPointer(h_tdata,num_elements,0); + postprocess(gold, h_tdata, nx * ny, ms); + + // ------------------------ + // transposeNoBankConflicts + // ------------------------ + printf("%25s", "conflict-free transpose"); + clMemSet.execute(d_tdataCL,0.f,num_elements); + { + btLauncherCL launcher( queue, transposeNoBankConflictsKernel); + launcher.setBuffer( d_tdataCL.getBufferCL()); + launcher.setBuffer( d_idataCL.getBufferCL()); + launcher.launch2D(numThreadsX,numThreadsY,localSizeX,localSizeY ); + + startEvent = clock.getTimeMicroseconds()/1e3; + for (int i = 0; i < NUM_REPS; i++) + launcher.launch2D(numThreadsX,numThreadsY,localSizeX,localSizeY ); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + clFinish(queue); + stopEvent = clock.getTimeMicroseconds()/1e3; + } + + ms = float(stopEvent-startEvent); + d_tdataCL.copyToHostPointer(h_tdata,num_elements,0); + postprocess(gold, h_tdata, nx * ny, ms); + +error_exit: + // cleanup + clReleaseKernel(copyKernel); + clReleaseCommandQueue(queue); + clReleaseContext(ctx); + + free(h_idata); + free(h_tdata); + free(h_cdata); + free(gold); + printf("Press \n"); + getchar(); +} diff --git a/opencl/lds_bank_conflict/premake4.lua b/opencl/lds_bank_conflict/premake4.lua new file mode 100644 index 000000000..7a26da2cc --- /dev/null +++ b/opencl/lds_bank_conflict/premake4.lua @@ -0,0 +1,37 @@ + +function createProject (vendor) + + local hasCL = findOpenCL(vendor) + + if (hasCL) then + + project ( "OpenCL_lds_bank_conflict_" .. vendor) + + initOpenCL(vendor) + + language "C++" + + kind "ConsoleApp" + targetdir "../../bin" + + links { + "OpenCL_lib_parallel_primitives_host_" .. vendor + } + + includedirs { + "../basic_initialize" + } + + files { + "main.cpp", + "../basic_initialize/btOpenCLUtils.cpp", + "../basic_initialize/btOpenCLUtils.h" + } + end + +end + +createProject("AMD") +createProject("NVIDIA") +createProject("Intel") +createProject("Apple") diff --git a/opencl/parallel_primitives/benchmark/premake4.lua b/opencl/parallel_primitives/benchmark/premake4.lua new file mode 100644 index 000000000..515540c8b --- /dev/null +++ b/opencl/parallel_primitives/benchmark/premake4.lua @@ -0,0 +1,35 @@ +function createProject(vendor) + hasCL = findOpenCL(vendor) + + if (hasCL) then + + project ("OpenCL_radixsort_benchmark_" .. vendor) + + initOpenCL(vendor) + + language "C++" + + kind "ConsoleApp" + targetdir "../../../bin" + includedirs {".."} + + links { + ("OpenCL_lib_parallel_primitives_host_" .. vendor) + } + + files { + "test_large_problem_sorting.cpp", + "../../basic_initialize/btOpenCLUtils.cpp", + "../../basic_initialize/btOpenCLUtils.h", + "../host/btFillCL.cpp", + "../host/btPrefixScanCL.cpp", + "../host/btRadixSort32CL.cpp", + } + + end +end + +createProject("AMD") +createProject("Intel") +createProject("NVIDIA") +createProject("Apple") \ No newline at end of file diff --git a/opencl/parallel_primitives/benchmark/test_large_problem_sorting.cpp b/opencl/parallel_primitives/benchmark/test_large_problem_sorting.cpp new file mode 100644 index 000000000..b3629c3f8 --- /dev/null +++ b/opencl/parallel_primitives/benchmark/test_large_problem_sorting.cpp @@ -0,0 +1,709 @@ +/****************************************************************************** + * Copyright 2010 Duane Merrill + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * + * + * + * AUTHORS' REQUEST: + * + * If you use|reference|benchmark this code, please cite our Technical + * Report (http://www.cs.virginia.edu/~dgm4d/papers/RadixSortTR.pdf): + * + * @TechReport{ Merrill:Sorting:2010, + * author = "Duane Merrill and Andrew Grimshaw", + * title = "Revisiting Sorting for GPGPU Stream Architectures", + * year = "2010", + * institution = "University of Virginia, Department of Computer Science", + * address = "Charlottesville, VA, USA", + * number = "CS2010-03" + * } + * + * For more information, see our Google Code project site: + * http://code.google.com/p/back40computing/ + * + * Thanks! + ******************************************************************************/ + +/****************************************************************************** + * Simple test driver program for *large-problem* radix sorting. + * + * Useful for demonstrating how to integrate radix sorting into + * your application + ******************************************************************************/ + +/****************************************************************************** + * Converted from CUDA to OpenCL/DirectCompute by Erwin Coumans + ******************************************************************************/ +#ifdef _WIN32 +#pragma warning (disable:4996) +#endif +#include +#include +#include +#include +#include +#include +#include + + +//#include +#include +/********************** +* +*/ + +#include "../host/btRadixSort32CL.h" +#include "../../basic_initialize/btOpenCLUtils.h" +#include "../host/btQuickprof.h" + +cl_context g_cxMainContext; +cl_device_id g_device; +cl_command_queue g_cqCommandQueue; + +/*********************** +* +*/ + +bool g_verbose; +///Preferred OpenCL device/platform. When < 0 then no preference is used. +///Note that btOpenCLUtils might still use the preference of using a platform vendor that matches the SDK vendor used to build the application. +///Preferred device/platform take priority over this platform-vendor match +int gPreferredDeviceId = -1; +int gPreferredPlatformId = -1; + + + +/****************************************************************************** + * Routines + ******************************************************************************/ + + +/** + * Keys-only sorting. Uses the GPU to sort the specified vector of elements for the given + * number of iterations, displaying runtime information. + * + * @param[in] num_elements + * Size in elements of the vector to sort + * @param[in] h_keys + * Vector of keys to sort + * @param[in] iterations + * Number of times to invoke the GPU sorting primitive + * @param[in] cfg + * Config + */ +template +void TimedSort( + unsigned int num_elements, + K *h_keys, + unsigned int iterations) +{ + printf("Keys only, %d iterations, %d elements\n", iterations, num_elements); + + int max_elements = num_elements; + btAlignedObjectArray hostData; + hostData.resize(num_elements); + for (int i=0;i gpuData(g_cxMainContext,g_cqCommandQueue); + gpuData.copyFromHost(hostData); + //sorter.executeHost(gpuData); + sorter.execute(gpuData); + + btAlignedObjectArray hostDataSorted; + gpuData.copyToHost(hostDataSorted); + + clFinish(g_cqCommandQueue); + + { + //printf("Key-values, %d iterations, %d elements", iterations, num_elements); + + // Create sorting enactor + + // Perform the timed number of sorting iterations + double elapsed = 0; + float duration = 0; + btClock watch; + + //warm-start + gpuData.copyFromHost(hostData); + clFinish(g_cqCommandQueue); + sorter.execute(gpuData); + + watch.reset(); + + + for (int i = 0; i < iterations; i++) + { + + + + // Move a fresh copy of the problem into device storage + gpuData.copyFromHost(hostData); + clFinish(g_cqCommandQueue); + + // Start GPU timing record + double startMs = watch.getTimeMicroseconds()/1e3; + + // Call the sorting API routine + sorter.execute(gpuData); + + + + clFinish(g_cqCommandQueue); + + double stopMs = watch.getTimeMicroseconds()/1e3; + + duration = stopMs - startMs; + + // End GPU timing record + elapsed += (double) duration; + printf("duration = %f\n", duration); + } + + // Display timing information + double avg_runtime = elapsed / iterations; + // double throughput = ((double) num_elements) / avg_runtime / 1000.0 / 1000.0; + // printf(", %f GPU ms, %f x10^9 elts/sec\n", avg_runtime, throughput); + double throughput = ((double) num_elements) / avg_runtime / 1000.0 ; + printf(", %f GPU ms, %f x10^6 elts/sec\n", avg_runtime, throughput); + + gpuData.copyToHost(hostData); + for (int i=0;i +void TimedSort( + unsigned int num_elements, + K *h_keys, + V *h_values, + unsigned int iterations) +{ + + printf("Key-values, %d iterations, %d elements\n", iterations, num_elements); + + int max_elements = num_elements; + btAlignedObjectArray hostData; + hostData.resize(num_elements); + for (int i=0;i gpuData(g_cxMainContext,g_cqCommandQueue); + gpuData.copyFromHost(hostData); + //sorter.executeHost(gpuData); + sorter.execute(gpuData); + + btAlignedObjectArray hostDataSorted; + gpuData.copyToHost(hostDataSorted); +#if 0 + for (int i=0;i +void RandomBits(K &key, int entropy_reduction = 0, int lower_key_bits = sizeof(K) * 8) +{ + const unsigned int NUM_UCHARS = (sizeof(K) + sizeof(unsigned char) - 1) / sizeof(unsigned char); + unsigned char key_bits[NUM_UCHARS]; + + do { + + for (int j = 0; j < NUM_UCHARS; j++) { + unsigned char quarterword = 0xff; + for (int i = 0; i <= entropy_reduction; i++) { + quarterword &= (rand() >> 7); + } + key_bits[j] = quarterword; + } + + if (lower_key_bits < sizeof(K) * 8) { + unsigned long long base = 0; + memcpy(&base, key_bits, sizeof(K)); + base &= (1 << lower_key_bits) - 1; + memcpy(key_bits, &base, sizeof(K)); + } + + memcpy(&key, key_bits, sizeof(K)); + + } while (key != key); // avoids NaNs when generating random floating point numbers +} + + +/****************************************************************************** + * Templated routines for printing keys/values to the console + ******************************************************************************/ + +template +void PrintValue(T val) { + printf("%d", val); +} + +template<> +void PrintValue(float val) { + printf("%f", val); +} + +template<> +void PrintValue(double val) { + printf("%f", val); +} + +template<> +void PrintValue(unsigned char val) { + printf("%u", val); +} + +template<> +void PrintValue(unsigned short val) { + printf("%u", val); +} + +template<> +void PrintValue(unsigned int val) { + printf("%u", val); +} + +template<> +void PrintValue(long val) { + printf("%ld", val); +} + +template<> +void PrintValue(unsigned long val) { + printf("%lu", val); +} + +template<> +void PrintValue(long long val) { + printf("%lld", val); +} + +template<> +void PrintValue(unsigned long long val) { + printf("%llu", val); +} + + + +/** + * Compares the equivalence of two arrays + */ +template +int CompareResults(T* computed, T* reference, SizeT len, bool verbose = true) +{ + printf("\n"); + for (SizeT i = 0; i < len; i++) { + + if (computed[i] != reference[i]) { + printf("INCORRECT: [%lu]: ", (unsigned long) i); + PrintValue(computed[i]); + printf(" != "); + PrintValue(reference[i]); + + if (verbose) { + printf("\nresult[..."); + for (size_t j = (i >= 5) ? i - 5 : 0; (j < i + 5) && (j < len); j++) { + PrintValue(computed[j]); + printf(", "); + } + printf("...]"); + printf("\nreference[..."); + for (size_t j = (i >= 5) ? i - 5 : 0; (j < i + 5) && (j < len); j++) { + PrintValue(reference[j]); + printf(", "); + } + printf("...]"); + } + + return 1; + } + } + + printf("CORRECT\n"); + return 0; +} + +/** + * Creates an example sorting problem whose keys is a vector of the specified + * number of K elements, values of V elements, and then dispatches the problem + * to the GPU for the given number of iterations, displaying runtime information. + * + * @param[in] iterations + * Number of times to invoke the GPU sorting primitive + * @param[in] num_elements + * Size in elements of the vector to sort + * @param[in] cfg + * Config + */ +template +void TestSort( + unsigned int iterations, + int num_elements, + bool keys_only) +{ + // Allocate the sorting problem on the host and fill the keys with random bytes + + K *h_keys = NULL; + K *h_reference_keys = NULL; + V *h_values = NULL; + h_keys = (K*) malloc(num_elements * sizeof(K)); + h_reference_keys = (K*) malloc(num_elements * sizeof(K)); + if (!keys_only) h_values = (V*) malloc(num_elements * sizeof(V)); + + + // Use random bits + for (unsigned int i = 0; i < num_elements; ++i) { + RandomBits(h_keys[i], 0); + //h_keys[i] = num_elements-i; + //h_keys[i] = 0xffffffffu-i; + if (!keys_only) + h_values[i] = h_keys[i];//0xffffffffu-i; + + h_reference_keys[i] = h_keys[i]; + } + + // Run the timing test + if (keys_only) { + TimedSort(num_elements, h_keys, iterations); + } else { + TimedSort(num_elements, h_keys, h_values, iterations); + } + +// cudaThreadSynchronize(); + + // Display sorted key data + if (g_verbose) { + printf("\n\nKeys:\n"); + for (int i = 0; i < num_elements; i++) { + PrintValue(h_keys[i]); + printf(", "); + } + printf("\n\n"); + } + + // Verify solution + std::sort(h_reference_keys, h_reference_keys + num_elements); + CompareResults(h_keys, h_reference_keys, num_elements, true); + printf("\n"); + fflush(stdout); + + // Free our allocated host memory + if (h_keys != NULL) free(h_keys); + if (h_values != NULL) free(h_values); +} + + + +/** + * Displays the commandline usage for this tool + */ +void Usage() +{ + printf("\ntest_large_problem_sorting [--device=] [--v] [--i=] [--n=] [--key-values] [--deviceId=] [--platformId=]\n"); + printf("\n"); + printf("\t--v\tDisplays sorted results to the console.\n"); + printf("\n"); + printf("\t--i\tPerforms the sorting operation times\n"); + printf("\t\t\ton the device. Re-copies original input each time. Default = 1\n"); + printf("\n"); + printf("\t--n\tThe number of elements to comprise the sample problem\n"); + printf("\t\t\tDefault = 512\n"); + printf("\n"); + printf("\t--key-values\tSpecifies that keys are accommodated by value pairings\n"); + printf("\n"); +} + + +/****************************************************************************** + * Command-line parsing + ******************************************************************************/ +#include +#include +#include + +class CommandLineArgs +{ +protected: + + std::map pairs; + +public: + + // Constructor + CommandLineArgs(int argc, char **argv) + { + using namespace std; + + for (int i = 1; i < argc; i++) + { + string arg = argv[i]; + + if ((arg[0] != '-') || (arg[1] != '-')) { + continue; + } + + string::size_type pos; + string key, val; + if ((pos = arg.find( '=')) == string::npos) { + key = string(arg, 2, arg.length() - 2); + val = ""; + } else { + key = string(arg, 2, pos - 2); + val = string(arg, pos + 1, arg.length() - 1); + } + pairs[key] = val; + } + } + + bool CheckCmdLineFlag(const char* arg_name) + { + using namespace std; + map::iterator itr; + if ((itr = pairs.find(arg_name)) != pairs.end()) { + return true; + } + return false; + } + + template + void GetCmdLineArgument(const char *arg_name, T &val); + + int ParsedArgc() + { + return pairs.size(); + } +}; + +template +void CommandLineArgs::GetCmdLineArgument(const char *arg_name, T &val) +{ + using namespace std; + map::iterator itr; + if ((itr = pairs.find(arg_name)) != pairs.end()) { + istringstream strstream(itr->second); + strstream >> val; + } +} + +template <> +void CommandLineArgs::GetCmdLineArgument(const char* arg_name, char* &val) +{ + using namespace std; + map::iterator itr; + if ((itr = pairs.find(arg_name)) != pairs.end()) { + + string s = itr->second; + val = (char*) malloc(sizeof(char) * (s.length() + 1)); + strcpy(val, s.c_str()); + + } else { + val = NULL; + } +} + + + + + +/****************************************************************************** + * Main + ******************************************************************************/ + +extern bool gDebugSkipLoadingBinary; + +int main( int argc, char** argv) +{ + gDebugSkipLoadingBinary = true; + + cl_int ciErrNum; + CommandLineArgs args(argc,argv); + + args.GetCmdLineArgument("deviceId", gPreferredDeviceId); + args.GetCmdLineArgument("platformId", gPreferredPlatformId); + + printf("Initialize OpenCL using btOpenCLUtils_createContextFromType\n"); + cl_platform_id platformId; + g_cxMainContext = btOpenCLUtils_createContextFromType(CL_DEVICE_TYPE_ALL, &ciErrNum, 0, 0,gPreferredDeviceId,gPreferredPlatformId,&platformId); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + int numDev = btOpenCLUtils_getNumDevices(g_cxMainContext); + + if (!numDev) + { + printf("error: no OpenCL devices\n"); + exit(0); + } + int result; + int devId = 0; + g_device = btOpenCLUtils_getDevice(g_cxMainContext,devId); + btOpenCLUtils_printDeviceInfo(g_device); + // create a command-queue + g_cqCommandQueue = clCreateCommandQueue(g_cxMainContext, g_device, 0, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + + + + //srand(time(NULL)); + srand(0); // presently deterministic + + unsigned int num_elements = 32*1024*1024;//4*1024*1024;//4*1024*1024;//257;//8*524288;//2048;//512;//524288; + unsigned int iterations = 10; + bool keys_only = true; + + // + // Check command line arguments + // + + + + if (args.CheckCmdLineFlag("help")) + { + Usage(); + return 0; + } + + args.GetCmdLineArgument("i", iterations); + args.GetCmdLineArgument("n", num_elements); + + + + keys_only = !args.CheckCmdLineFlag("key-values"); + g_verbose = args.CheckCmdLineFlag("v"); + + + + TestSort( + iterations, + num_elements, + keys_only); + + +} diff --git a/opencl/parallel_primitives/host/CommandLineArgs.h b/opencl/parallel_primitives/host/CommandLineArgs.h new file mode 100644 index 000000000..b2a43016f --- /dev/null +++ b/opencl/parallel_primitives/host/CommandLineArgs.h @@ -0,0 +1,92 @@ +#ifndef COMMAND_LINE_ARGS_H +#define COMMAND_LINE_ARGS_H + +/****************************************************************************** + * Command-line parsing + ******************************************************************************/ +#include +#include +#include +#include +#include +class CommandLineArgs +{ +protected: + + std::map pairs; + +public: + + // Constructor + CommandLineArgs(int argc, char **argv) + { + using namespace std; + + for (int i = 1; i < argc; i++) + { + string arg = argv[i]; + + if ((arg[0] != '-') || (arg[1] != '-')) { + continue; + } + + string::size_type pos; + string key, val; + if ((pos = arg.find( '=')) == string::npos) { + key = string(arg, 2, arg.length() - 2); + val = ""; + } else { + key = string(arg, 2, pos - 2); + val = string(arg, pos + 1, arg.length() - 1); + } + pairs[key] = val; + } + } + + bool CheckCmdLineFlag(const char* arg_name) + { + using namespace std; + map::iterator itr; + if ((itr = pairs.find(arg_name)) != pairs.end()) { + return true; + } + return false; + } + + template + void GetCmdLineArgument(const char *arg_name, T &val); + + int ParsedArgc() + { + return pairs.size(); + } +}; + +template +void CommandLineArgs::GetCmdLineArgument(const char *arg_name, T &val) +{ + using namespace std; + map::iterator itr; + if ((itr = pairs.find(arg_name)) != pairs.end()) { + istringstream strstream(itr->second); + strstream >> val; + } +} + +template <> +void CommandLineArgs::GetCmdLineArgument(const char* arg_name, char* &val) +{ + using namespace std; + map::iterator itr; + if ((itr = pairs.find(arg_name)) != pairs.end()) { + + string s = itr->second; + val = (char*) malloc(sizeof(char) * (s.length() + 1)); + std::strcpy(val, s.c_str()); + + } else { + val = NULL; + } +} + +#endif //COMMAND_LINE_ARGS_H diff --git a/opencl/parallel_primitives/host/btAlignedAllocator.cpp b/opencl/parallel_primitives/host/btAlignedAllocator.cpp new file mode 100644 index 000000000..a65296c6a --- /dev/null +++ b/opencl/parallel_primitives/host/btAlignedAllocator.cpp @@ -0,0 +1,181 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btAlignedAllocator.h" + +int gNumAlignedAllocs = 0; +int gNumAlignedFree = 0; +int gTotalBytesAlignedAllocs = 0;//detect memory leaks + +static void *btAllocDefault(size_t size) +{ + return malloc(size); +} + +static void btFreeDefault(void *ptr) +{ + free(ptr); +} + +static btAllocFunc *sAllocFunc = btAllocDefault; +static btFreeFunc *sFreeFunc = btFreeDefault; + + + +#if defined (BT_HAS_ALIGNED_ALLOCATOR) +#include +static void *btAlignedAllocDefault(size_t size, int alignment) +{ + return _aligned_malloc(size, (size_t)alignment); +} + +static void btAlignedFreeDefault(void *ptr) +{ + _aligned_free(ptr); +} +#elif defined(__CELLOS_LV2__) +#include + +static inline void *btAlignedAllocDefault(size_t size, int alignment) +{ + return memalign(alignment, size); +} + +static inline void btAlignedFreeDefault(void *ptr) +{ + free(ptr); +} +#else + + + + + +static inline void *btAlignedAllocDefault(size_t size, int alignment) +{ + void *ret; + char *real; + real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1)); + if (real) { + ret = btAlignPointer(real + sizeof(void *),alignment); + *((void **)(ret)-1) = (void *)(real); + } else { + ret = (void *)(real); + } + return (ret); +} + +static inline void btAlignedFreeDefault(void *ptr) +{ + void* real; + + if (ptr) { + real = *((void **)(ptr)-1); + sFreeFunc(real); + } +} +#endif + + +static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault; +static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault; + +void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc) +{ + sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault; + sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault; +} + +void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc) +{ + sAllocFunc = allocFunc ? allocFunc : btAllocDefault; + sFreeFunc = freeFunc ? freeFunc : btFreeDefault; +} + +#ifdef BT_DEBUG_MEMORY_ALLOCATIONS +//this generic allocator provides the total allocated number of bytes +#include + +void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename) +{ + void *ret; + char *real; + + gTotalBytesAlignedAllocs += size; + gNumAlignedAllocs++; + + + real = (char *)sAllocFunc(size + 2*sizeof(void *) + (alignment-1)); + if (real) { + ret = (void*) btAlignPointer(real + 2*sizeof(void *), alignment); + *((void **)(ret)-1) = (void *)(real); + *((int*)(ret)-2) = size; + + } else { + ret = (void *)(real);//?? + } + + printf("allocation#%d at address %x, from %s,line %d, size %d\n",gNumAlignedAllocs,real, filename,line,size); + + int* ptr = (int*)ret; + *ptr = 12; + return (ret); +} + +void btAlignedFreeInternal (void* ptr,int line,char* filename) +{ + + void* real; + gNumAlignedFree++; + + if (ptr) { + real = *((void **)(ptr)-1); + int size = *((int*)(ptr)-2); + gTotalBytesAlignedAllocs -= size; + + printf("free #%d at address %x, from %s,line %d, size %d\n",gNumAlignedFree,real, filename,line,size); + + sFreeFunc(real); + } else + { + printf("NULL ptr\n"); + } +} + +#else //BT_DEBUG_MEMORY_ALLOCATIONS + +void* btAlignedAllocInternal (size_t size, int alignment) +{ + gNumAlignedAllocs++; + void* ptr; + ptr = sAlignedAllocFunc(size, alignment); +// printf("btAlignedAllocInternal %d, %x\n",size,ptr); + return ptr; +} + +void btAlignedFreeInternal (void* ptr) +{ + if (!ptr) + { + return; + } + + gNumAlignedFree++; +// printf("btAlignedFreeInternal %x\n",ptr); + sAlignedFreeFunc(ptr); +} + +#endif //BT_DEBUG_MEMORY_ALLOCATIONS + diff --git a/opencl/parallel_primitives/host/btAlignedAllocator.h b/opencl/parallel_primitives/host/btAlignedAllocator.h new file mode 100644 index 000000000..f168f3c66 --- /dev/null +++ b/opencl/parallel_primitives/host/btAlignedAllocator.h @@ -0,0 +1,107 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BT_ALIGNED_ALLOCATOR +#define BT_ALIGNED_ALLOCATOR + +///we probably replace this with our own aligned memory allocator +///so we replace _aligned_malloc and _aligned_free with our own +///that is better portable and more predictable + +#include "btScalar.h" +//#define BT_DEBUG_MEMORY_ALLOCATIONS 1 +#ifdef BT_DEBUG_MEMORY_ALLOCATIONS + +#define btAlignedAlloc(a,b) \ + btAlignedAllocInternal(a,b,__LINE__,__FILE__) + +#define btAlignedFree(ptr) \ + btAlignedFreeInternal(ptr,__LINE__,__FILE__) + +void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filename); + +void btAlignedFreeInternal (void* ptr,int line,char* filename); + +#else + void* btAlignedAllocInternal (size_t size, int alignment); + void btAlignedFreeInternal (void* ptr); + + #define btAlignedAlloc(size,alignment) btAlignedAllocInternal(size,alignment) + #define btAlignedFree(ptr) btAlignedFreeInternal(ptr) + +#endif +typedef int size_type; + +typedef void *(btAlignedAllocFunc)(size_t size, int alignment); +typedef void (btAlignedFreeFunc)(void *memblock); +typedef void *(btAllocFunc)(size_t size); +typedef void (btFreeFunc)(void *memblock); + +///The developer can let all Bullet memory allocations go through a custom memory allocator, using btAlignedAllocSetCustom +void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc); +///If the developer has already an custom aligned allocator, then btAlignedAllocSetCustomAligned can be used. The default aligned allocator pre-allocates extra memory using the non-aligned allocator, and instruments it. +void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc); + + +///The btAlignedAllocator is a portable class for aligned memory allocations. +///Default implementations for unaligned and aligned allocations can be overridden by a custom allocator using btAlignedAllocSetCustom and btAlignedAllocSetCustomAligned. +template < typename T , unsigned Alignment > +class btAlignedAllocator { + + typedef btAlignedAllocator< T , Alignment > self_type; + +public: + + //just going down a list: + btAlignedAllocator() {} + /* + btAlignedAllocator( const self_type & ) {} + */ + + template < typename Other > + btAlignedAllocator( const btAlignedAllocator< Other , Alignment > & ) {} + + typedef const T* const_pointer; + typedef const T& const_reference; + typedef T* pointer; + typedef T& reference; + typedef T value_type; + + pointer address ( reference ref ) const { return &ref; } + const_pointer address ( const_reference ref ) const { return &ref; } + pointer allocate ( size_type n , const_pointer * hint = 0 ) { + (void)hint; + return reinterpret_cast< pointer >(btAlignedAlloc( sizeof(value_type) * n , Alignment )); + } + void construct ( pointer ptr , const value_type & value ) { new (ptr) value_type( value ); } + void deallocate( pointer ptr ) { + btAlignedFree( reinterpret_cast< void * >( ptr ) ); + } + void destroy ( pointer ptr ) { ptr->~value_type(); } + + + template < typename O > struct rebind { + typedef btAlignedAllocator< O , Alignment > other; + }; + template < typename O > + self_type & operator=( const btAlignedAllocator< O , Alignment > & ) { return *this; } + + friend bool operator==( const self_type & , const self_type & ) { return true; } +}; + + + +#endif //BT_ALIGNED_ALLOCATOR + diff --git a/opencl/parallel_primitives/host/btAlignedObjectArray.h b/opencl/parallel_primitives/host/btAlignedObjectArray.h new file mode 100644 index 000000000..24e59ab65 --- /dev/null +++ b/opencl/parallel_primitives/host/btAlignedObjectArray.h @@ -0,0 +1,511 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_OBJECT_ARRAY__ +#define BT_OBJECT_ARRAY__ + +#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE +#include "btAlignedAllocator.h" + +///If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW +///then the btAlignedObjectArray doesn't support objects with virtual methods, and non-trivial constructors/destructors +///You can enable BT_USE_MEMCPY, then swapping elements in the array will use memcpy instead of operator= +///see discussion here: http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1231 and +///http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1240 + +#define BT_USE_PLACEMENT_NEW 1 +//#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in or or otherwise... +#define BT_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful + +#ifdef BT_USE_MEMCPY +#include +#include +#endif //BT_USE_MEMCPY + +#ifdef BT_USE_PLACEMENT_NEW +#include //for placement new +#endif //BT_USE_PLACEMENT_NEW + + +///The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods +///It is developed to replace stl::vector to avoid portability issues, including STL alignment issues to add SIMD/SSE data +template +//template +class btAlignedObjectArray +{ + btAlignedAllocator m_allocator; + + int m_size; + int m_capacity; + T* m_data; + //PCK: added this line + bool m_ownsMemory; + +#ifdef BT_ALLOW_ARRAY_COPY_OPERATOR +public: + SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray &other) + { + copyFromArray(other); + return *this; + } +#else//BT_ALLOW_ARRAY_COPY_OPERATOR +private: + SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray &other); +#endif//BT_ALLOW_ARRAY_COPY_OPERATOR + +protected: + SIMD_FORCE_INLINE int allocSize(int size) + { + return (size ? size*2 : 1); + } + SIMD_FORCE_INLINE void copy(int start,int end, T* dest) const + { + int i; + for (i=start;i=0); + btAssert(n=0); + btAssert(n=0); + btAssert(n=0); + btAssert(n0); + m_size--; + m_data[m_size].~T(); + } + + + ///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument. + ///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations. + SIMD_FORCE_INLINE void resizeNoInitialize(int newsize) + { + int curSize = size(); + + if (newsize < curSize) + { + } else + { + if (newsize > size()) + { + reserve(newsize); + } + //leave this uninitialized + } + m_size = newsize; + } + + SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T()) + { + int curSize = size(); + + if (newsize < curSize) + { + for(int i = newsize; i < curSize; i++) + { + m_data[i].~T(); + } + } else + { + if (newsize > size()) + { + reserve(newsize); + } +#ifdef BT_USE_PLACEMENT_NEW + for (int i=curSize;i + void quickSortInternal(const L& CompareFunc,int lo, int hi) + { + // lo is the lower index, hi is the upper index + // of the region of array a that is to be sorted + int i=lo, j=hi; + T x=m_data[(lo+hi)/2]; + + // partition + do + { + while (CompareFunc(m_data[i],x)) + i++; + while (CompareFunc(x,m_data[j])) + j--; + if (i<=j) + { + swap(i,j); + i++; j--; + } + } while (i<=j); + + // recursion + if (lo + void quickSort(const L& CompareFunc) + { + //don't sort 0 or 1 elements + if (size()>1) + { + quickSortInternal(CompareFunc,0,size()-1); + } + } + + + ///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/ + template + void downHeap(T *pArr, int k, int n, const L& CompareFunc) + { + /* PRE: a[k+1..N] is a heap */ + /* POST: a[k..N] is a heap */ + + T temp = pArr[k - 1]; + /* k has child(s) */ + while (k <= n/2) + { + int child = 2*k; + + if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child])) + { + child++; + } + /* pick larger child */ + if (CompareFunc(temp , pArr[child - 1])) + { + /* move child up */ + pArr[k - 1] = pArr[child - 1]; + k = child; + } + else + { + break; + } + } + pArr[k - 1] = temp; + } /*downHeap*/ + + void swap(int index0,int index1) + { +#ifdef BT_USE_MEMCPY + char temp[sizeof(T)]; + memcpy(temp,&m_data[index0],sizeof(T)); + memcpy(&m_data[index0],&m_data[index1],sizeof(T)); + memcpy(&m_data[index1],temp,sizeof(T)); +#else + T temp = m_data[index0]; + m_data[index0] = m_data[index1]; + m_data[index1] = temp; +#endif //BT_USE_PLACEMENT_NEW + + } + + template + void heapSort(const L& CompareFunc) + { + /* sort a[0..N-1], N.B. 0 to N-1 */ + int k; + int n = m_size; + for (k = n/2; k > 0; k--) + { + downHeap(m_data, k, n, CompareFunc); + } + + /* a[1..N] is now a heap */ + while ( n>=1 ) + { + swap(0,n-1); /* largest of a[0..n-1] */ + + + n = n - 1; + /* restore a[1..i-1] heap */ + downHeap(m_data, 1, n, CompareFunc); + } + } + + ///non-recursive binary search, assumes sorted array + int findBinarySearch(const T& key) const + { + int first = 0; + int last = size()-1; + + //assume sorted array + while (first <= last) { + int mid = (first + last) / 2; // compute mid point. + if (key > m_data[mid]) + first = mid + 1; // repeat search in top half. + else if (key < m_data[mid]) + last = mid - 1; // repeat search in bottom half. + else + return mid; // found it. return position ///// + } + return size(); // failed to find key + } + + + int findLinearSearch(const T& key) const + { + int index=size(); + int i; + + for (i=0;i( device, 1, BufferBase::BUFFER_CONST ); + + m_lower = (maxSize == 0)? 0: new btOpenCLArray(ctx,queue,maxSize ); + m_upper = (maxSize == 0)? 0: new btOpenCLArray(ctx,queue, maxSize ); + + m_filler = new btFillCL(ctx,device,queue); +} + +btBoundSearchCL::~btBoundSearchCL() +{ + + delete m_lower; + delete m_upper; + delete m_filler; + + clReleaseKernel(m_lowerSortDataKernel); + clReleaseKernel(m_upperSortDataKernel); + clReleaseKernel(m_subtractKernel); + + +} + + +void btBoundSearchCL::execute(btOpenCLArray& src, int nSrc, btOpenCLArray& dst, int nDst, Option option ) +{ + btInt4 constBuffer; + constBuffer.x = nSrc; + constBuffer.y = nDst; + + if( option == BOUND_LOWER ) + { + btBufferInfoCL bInfo[] = { btBufferInfoCL( src.getBufferCL(), true ), btBufferInfoCL( dst.getBufferCL()) }; + + btLauncherCL launcher( m_queue, m_lowerSortDataKernel ); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( nSrc ); + launcher.setConst( nDst ); + + launcher.launch1D( nSrc, 64 ); + } + else if( option == BOUND_UPPER ) + { + btBufferInfoCL bInfo[] = { btBufferInfoCL( src.getBufferCL(), true ), btBufferInfoCL( dst.getBufferCL() ) }; + + btLauncherCL launcher(m_queue, m_upperSortDataKernel ); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( nSrc ); + launcher.setConst( nDst ); + + launcher.launch1D( nSrc, 64 ); + } + else if( option == COUNT ) + { + btAssert( m_lower ); + btAssert( m_upper ); + btAssert( m_lower->capacity() <= (int)nDst ); + btAssert( m_upper->capacity() <= (int)nDst ); + + int zero = 0; + m_filler->execute( *m_lower, zero, nDst ); + m_filler->execute( *m_upper, zero, nDst ); + + execute( src, nSrc, *m_lower, nDst, BOUND_LOWER ); + execute( src, nSrc, *m_upper, nDst, BOUND_UPPER ); + + { + btBufferInfoCL bInfo[] = { btBufferInfoCL( m_upper->getBufferCL(), true ), btBufferInfoCL( m_lower->getBufferCL(), true ), btBufferInfoCL( dst.getBufferCL() ) }; + + btLauncherCL launcher( m_queue, m_subtractKernel ); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( nSrc ); + launcher.setConst( nDst ); + + launcher.launch1D( nDst, 64 ); + } + } + else + { + btAssert( 0 ); + } + +} + + +void btBoundSearchCL::executeHost( btAlignedObjectArray& src, int nSrc, + btAlignedObjectArray& dst, int nDst, Option option ) +{ + + + for(int i=0; i lower; + lower.resize(nDst ); + btAlignedObjectArray upper; + upper.resize(nDst ); + + for(int i=0; i +#include +#include +#include +*/ + +#include "btOpenCLArray.h" +#include "btFillCL.h" +#include "btRadixSort32CL.h" //for btSortData (perhaps move it?) +class btBoundSearchCL +{ + public: + + enum Option + { + BOUND_LOWER, + BOUND_UPPER, + COUNT, + }; + + cl_context m_context; + cl_device_id m_device; + cl_command_queue m_queue; + + + cl_kernel m_lowerSortDataKernel; + cl_kernel m_upperSortDataKernel; + cl_kernel m_subtractKernel; + + btOpenCLArray* m_constbtOpenCLArray; + btOpenCLArray* m_lower; + btOpenCLArray* m_upper; + + btFillCL* m_filler; + + btBoundSearchCL(cl_context context, cl_device_id device, cl_command_queue queue, int size); + + virtual ~btBoundSearchCL(); + + // src has to be src[i].m_key <= src[i+1].m_key + void execute( btOpenCLArray& src, int nSrc, btOpenCLArray& dst, int nDst, Option option = BOUND_LOWER ); + + void executeHost( btAlignedObjectArray& src, int nSrc, btAlignedObjectArray& dst, int nDst, Option option = BOUND_LOWER); +}; + + +#endif //BT_BOUNDSEARCH_H diff --git a/opencl/parallel_primitives/host/btBufferInfoCL.h b/opencl/parallel_primitives/host/btBufferInfoCL.h new file mode 100644 index 000000000..48798e232 --- /dev/null +++ b/opencl/parallel_primitives/host/btBufferInfoCL.h @@ -0,0 +1,19 @@ + +#ifndef BT_BUFFER_INFO_CL_H +#define BT_BUFFER_INFO_CL_H + +#include "btOpenCLArray.h" + + +struct btBufferInfoCL +{ + //btBufferInfoCL(){} + +// template + btBufferInfoCL(cl_mem buff, bool isReadOnly = false): m_clBuffer(buff), m_isReadOnly(isReadOnly){} + + cl_mem m_clBuffer; + bool m_isReadOnly; +}; + +#endif //BT_BUFFER_INFO_CL_H diff --git a/opencl/parallel_primitives/host/btFillCL.cpp b/opencl/parallel_primitives/host/btFillCL.cpp new file mode 100644 index 000000000..18a7e2093 --- /dev/null +++ b/opencl/parallel_primitives/host/btFillCL.cpp @@ -0,0 +1,126 @@ +#include "btFillCL.h" +#include "../../basic_initialize/btOpenCLUtils.h" +#include "btBufferInfoCL.h" +#include "btLauncherCL.h" + +#define FILL_CL_PROGRAM_PATH "opencl/parallel_primitives/kernels/FillKernels.cl" + +#include "../kernels/FillKernelsCL.h" + +btFillCL::btFillCL(cl_context ctx, cl_device_id device, cl_command_queue queue) +:m_commandQueue(queue) +{ + const char* kernelSource = fillKernelsCL; + cl_int pErrNum; + const char* additionalMacros = ""; + + cl_program fillProg = btOpenCLUtils::compileCLProgramFromString( ctx, device, kernelSource, &pErrNum,additionalMacros, FILL_CL_PROGRAM_PATH); + btAssert(fillProg); + + m_fillIntKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "FillIntKernel", &pErrNum, fillProg,additionalMacros ); + btAssert(m_fillIntKernel); + + m_fillUnsignedIntKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "FillUnsignedIntKernel", &pErrNum, fillProg,additionalMacros ); + btAssert(m_fillIntKernel); + + m_fillFloatKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "FillFloatKernel", &pErrNum, fillProg,additionalMacros ); + btAssert(m_fillFloatKernel); + + + + m_fillKernelInt2 = btOpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "FillInt2Kernel", &pErrNum, fillProg,additionalMacros ); + btAssert(m_fillKernelInt2); + +} + +btFillCL::~btFillCL() +{ + clReleaseKernel(m_fillKernelInt2); + clReleaseKernel(m_fillIntKernel); + clReleaseKernel(m_fillUnsignedIntKernel); + clReleaseKernel(m_fillFloatKernel); + +} + +void btFillCL::execute(btOpenCLArray& src, const float value, int n, int offset) +{ + btAssert( n>0 ); + + { + btLauncherCL launcher( m_commandQueue, m_fillFloatKernel ); + launcher.setBuffer( src.getBufferCL()); + launcher.setConst( n ); + launcher.setConst( value ); + launcher.setConst( offset); + + launcher.launch1D( n ); + } +} + +void btFillCL::execute(btOpenCLArray& src, const int value, int n, int offset) +{ + btAssert( n>0 ); + + + { + btLauncherCL launcher( m_commandQueue, m_fillIntKernel ); + launcher.setBuffer(src.getBufferCL()); + launcher.setConst( n); + launcher.setConst( value); + launcher.setConst( offset); + launcher.launch1D( n ); + } +} + + +void btFillCL::execute(btOpenCLArray& src, const unsigned int value, int n, int offset) +{ + btAssert( n>0 ); + + { + btBufferInfoCL bInfo[] = { btBufferInfoCL( src.getBufferCL() ) }; + + btLauncherCL launcher( m_commandQueue, m_fillUnsignedIntKernel ); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( n ); + launcher.setConst(value); + launcher.setConst(offset); + + launcher.launch1D( n ); + } +} + +void btFillCL::executeHost(btAlignedObjectArray &src, const btInt2 &value, int n, int offset) +{ + for (int i=0;i &src, const int value, int n, int offset) +{ + for (int i=0;i &src, const btInt2 &value, int n, int offset) +{ + btAssert( n>0 ); + + + { + btBufferInfoCL bInfo[] = { btBufferInfoCL( src.getBufferCL() ) }; + + btLauncherCL launcher(m_commandQueue, m_fillKernelInt2); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst(n); + launcher.setConst(value); + launcher.setConst(offset); + + //( constBuffer ); + launcher.launch1D( n ); + } +} diff --git a/opencl/parallel_primitives/host/btFillCL.h b/opencl/parallel_primitives/host/btFillCL.h new file mode 100644 index 000000000..a9303a73d --- /dev/null +++ b/opencl/parallel_primitives/host/btFillCL.h @@ -0,0 +1,137 @@ +#ifndef BT_FILL_CL_H +#define BT_FILL_CL_H + +#include "btOpenCLArray.h" +#include "btScalar.h" + +ATTRIBUTE_ALIGNED16(struct) btUnsignedInt4 +{ + BT_DECLARE_ALIGNED_ALLOCATOR(); + + union + { + struct + { + unsigned int x,y,z,w; + }; + struct + { + unsigned int s[4]; + }; + }; +}; + +ATTRIBUTE_ALIGNED16(struct) btInt4 +{ + BT_DECLARE_ALIGNED_ALLOCATOR(); + + union + { + struct + { + int x,y,z,w; + }; + struct + { + int s[4]; + }; + }; +}; + +struct btUnsignedInt2 +{ + union + { + struct + { + unsigned int x,y; + }; + struct + { + unsigned int s[2]; + }; + }; +}; + +struct btInt2 +{ + union + { + struct + { + int x,y; + }; + struct + { + int s[2]; + }; + }; +}; + +SIMD_FORCE_INLINE btInt4 btMakeInt4(int x, int y, int z, int w = 0) +{ + btInt4 v; + v.s[0] = x; v.s[1] = y; v.s[2] = z; v.s[3] = w; + return v; +} + +SIMD_FORCE_INLINE btUnsignedInt4 btMakeUnsignedInt4(unsigned int x, unsigned int y, unsigned int z, unsigned int w = 0) +{ + btUnsignedInt4 v; + v.s[0] = x; v.s[1] = y; v.s[2] = z; v.s[3] = w; + return v; +} + +class btFillCL +{ + + cl_command_queue m_commandQueue; + + cl_kernel m_fillKernelInt2; + cl_kernel m_fillIntKernel; + cl_kernel m_fillUnsignedIntKernel; + cl_kernel m_fillFloatKernel; + + public: + + struct btConstData + { + union + { + btInt4 m_data; + btUnsignedInt4 m_UnsignedData; + }; + int m_offset; + int m_n; + int m_padding[2]; + }; + +protected: + +public: + + btFillCL(cl_context ctx, cl_device_id device, cl_command_queue queue); + + virtual ~btFillCL(); + + void execute(btOpenCLArray& src, const unsigned int value, int n, int offset = 0); + + void execute(btOpenCLArray& src, const int value, int n, int offset = 0); + + void execute(btOpenCLArray& src, const float value, int n, int offset = 0); + + void execute(btOpenCLArray& src, const btInt2& value, int n, int offset = 0); + + void executeHost(btAlignedObjectArray &src, const btInt2 &value, int n, int offset); + + void executeHost(btAlignedObjectArray &src, const int value, int n, int offset); + + // void execute(btOpenCLArray& src, const btInt4& value, int n, int offset = 0); + +}; + + + + + +#endif //BT_FILL_CL_H diff --git a/opencl/parallel_primitives/host/btHashMap.h b/opencl/parallel_primitives/host/btHashMap.h new file mode 100644 index 000000000..ce07db3ac --- /dev/null +++ b/opencl/parallel_primitives/host/btHashMap.h @@ -0,0 +1,450 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#ifndef BT_HASH_MAP_H +#define BT_HASH_MAP_H + +#include "btAlignedObjectArray.h" + +///very basic hashable string implementation, compatible with btHashMap +struct btHashString +{ + const char* m_string; + unsigned int m_hash; + + SIMD_FORCE_INLINE unsigned int getHash()const + { + return m_hash; + } + + btHashString(const char* name) + :m_string(name) + { + /* magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ */ + static const unsigned int InitialFNV = 2166136261u; + static const unsigned int FNVMultiple = 16777619u; + + /* Fowler / Noll / Vo (FNV) Hash */ + unsigned int hash = InitialFNV; + + for(int i = 0; m_string[i]; i++) + { + hash = hash ^ (m_string[i]); /* xor the low 8 bits */ + hash = hash * FNVMultiple; /* multiply by the magic number */ + } + m_hash = hash; + } + + int portableStringCompare(const char* src, const char* dst) const + { + int ret = 0 ; + + while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst) + ++src, ++dst; + + if ( ret < 0 ) + ret = -1 ; + else if ( ret > 0 ) + ret = 1 ; + + return( ret ); + } + + bool equals(const btHashString& other) const + { + return (m_string == other.m_string) || + (0==portableStringCompare(m_string,other.m_string)); + + } + +}; + +const int BT_HASH_NULL=0xffffffff; + + +class btHashInt +{ + int m_uid; +public: + btHashInt(int uid) :m_uid(uid) + { + } + + int getUid1() const + { + return m_uid; + } + + void setUid1(int uid) + { + m_uid = uid; + } + + bool equals(const btHashInt& other) const + { + return getUid1() == other.getUid1(); + } + //to our success + SIMD_FORCE_INLINE unsigned int getHash()const + { + int key = m_uid; + // Thomas Wang's hash + key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + return key; + } +}; + + + +class btHashPtr +{ + + union + { + const void* m_pointer; + int m_hashValues[2]; + }; + +public: + + btHashPtr(const void* ptr) + :m_pointer(ptr) + { + } + + const void* getPointer() const + { + return m_pointer; + } + + bool equals(const btHashPtr& other) const + { + return getPointer() == other.getPointer(); + } + + //to our success + SIMD_FORCE_INLINE unsigned int getHash()const + { + const bool VOID_IS_8 = ((sizeof(void*)==8)); + + int key = VOID_IS_8? m_hashValues[0]+m_hashValues[1] : m_hashValues[0]; + + // Thomas Wang's hash + key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + return key; + } + + +}; + + +template +class btHashKeyPtr +{ + int m_uid; +public: + + btHashKeyPtr(int uid) :m_uid(uid) + { + } + + int getUid1() const + { + return m_uid; + } + + bool equals(const btHashKeyPtr& other) const + { + return getUid1() == other.getUid1(); + } + + //to our success + SIMD_FORCE_INLINE unsigned int getHash()const + { + int key = m_uid; + // Thomas Wang's hash + key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + return key; + } + + +}; + + +template +class btHashKey +{ + int m_uid; +public: + + btHashKey(int uid) :m_uid(uid) + { + } + + int getUid1() const + { + return m_uid; + } + + bool equals(const btHashKey& other) const + { + return getUid1() == other.getUid1(); + } + //to our success + SIMD_FORCE_INLINE unsigned int getHash()const + { + int key = m_uid; + // Thomas Wang's hash + key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + return key; + } +}; + + +///The btHashMap template class implements a generic and lightweight hashmap. +///A basic sample of how to use btHashMap is located in Demos\BasicDemo\main.cpp +template +class btHashMap +{ + +protected: + btAlignedObjectArray m_hashTable; + btAlignedObjectArray m_next; + + btAlignedObjectArray m_valueArray; + btAlignedObjectArray m_keyArray; + + void growTables(const Key& /*key*/) + { + int newCapacity = m_valueArray.capacity(); + + if (m_hashTable.size() < newCapacity) + { + //grow hashtable and next table + int curHashtableSize = m_hashTable.size(); + + m_hashTable.resize(newCapacity); + m_next.resize(newCapacity); + + int i; + + for (i= 0; i < newCapacity; ++i) + { + m_hashTable[i] = BT_HASH_NULL; + } + for (i = 0; i < newCapacity; ++i) + { + m_next[i] = BT_HASH_NULL; + } + + for(i=0;i= (unsigned int)m_hashTable.size()) + { + return BT_HASH_NULL; + } + + int index = m_hashTable[hash]; + while ((index != BT_HASH_NULL) && key.equals(m_keyArray[index]) == false) + { + index = m_next[index]; + } + return index; + } + + void clear() + { + m_hashTable.clear(); + m_next.clear(); + m_valueArray.clear(); + m_keyArray.clear(); + } + +}; + +#endif //BT_HASH_MAP_H diff --git a/opencl/parallel_primitives/host/btLauncherCL.h b/opencl/parallel_primitives/host/btLauncherCL.h new file mode 100644 index 000000000..6b5657426 --- /dev/null +++ b/opencl/parallel_primitives/host/btLauncherCL.h @@ -0,0 +1,363 @@ + +#ifndef BT_LAUNCHER_CL_H +#define BT_LAUNCHER_CL_H + +#include "btBufferInfoCL.h" +#include "btMinMax.h" +#include "btOpenCLArray.h" +#include + +#ifdef _WIN32 +#pragma warning(disable :4996) +#endif +#define BT_CL_MAX_ARG_SIZE 16 +struct btKernelArgData +{ + int m_isBuffer; + int m_argIndex; + int m_argSizeInBytes; + union + { + cl_mem m_clBuffer; + unsigned char m_argData[BT_CL_MAX_ARG_SIZE]; + }; + +}; + +class btLauncherCL +{ + + cl_command_queue m_commandQueue; + cl_kernel m_kernel; + int m_idx; + + btAlignedObjectArray m_kernelArguments; + + + int m_serializationSizeInBytes; + + public: + + btAlignedObjectArray* > m_arrays; + + btLauncherCL(cl_command_queue queue, cl_kernel kernel) + :m_commandQueue(queue), + m_kernel(kernel), + m_idx(0) + { + m_serializationSizeInBytes = sizeof(int); + } + + virtual ~btLauncherCL() + { + for (int i=0;igetBufferCL()); + } + } + + inline void setBuffer( cl_mem clBuffer) + { + + btKernelArgData kernelArg; + kernelArg.m_argIndex = m_idx; + kernelArg.m_isBuffer = 1; + kernelArg.m_clBuffer = clBuffer; + + cl_mem_info param_name = CL_MEM_SIZE; + size_t param_value; + size_t sizeInBytes = sizeof(size_t); + size_t actualSizeInBytes; + cl_int err; + err = clGetMemObjectInfo ( kernelArg.m_clBuffer, + param_name, + sizeInBytes, + ¶m_value, + &actualSizeInBytes); + + btAssert( err == CL_SUCCESS ); + kernelArg.m_argSizeInBytes = param_value; + + m_kernelArguments.push_back(kernelArg); + m_serializationSizeInBytes+= sizeof(btKernelArgData); + m_serializationSizeInBytes+=param_value; + + cl_int status = clSetKernelArg( m_kernel, m_idx++, sizeof(cl_mem), &clBuffer); + btAssert( status == CL_SUCCESS ); + } + + + inline void setBuffers( btBufferInfoCL* buffInfo, int n ) + { + for(int i=0; im_isBuffer) + { + btOpenCLArray* clData = new btOpenCLArray(ctx,m_commandQueue, arg->m_argSizeInBytes); + clData->resize(arg->m_argSizeInBytes); + + clData->copyFromHostPointer(&buf[index], arg->m_argSizeInBytes); + + arg->m_clBuffer = clData->getBufferCL(); + + m_arrays.push_back(clData); + + cl_int status = clSetKernelArg( m_kernel, m_idx++, sizeof(cl_mem), &arg->m_clBuffer); + btAssert( status == CL_SUCCESS ); + index+=arg->m_argSizeInBytes; + } else + { + cl_int status = clSetKernelArg( m_kernel, m_idx++, arg->m_argSizeInBytes, &arg->m_argData); + btAssert( status == CL_SUCCESS ); + } + m_kernelArguments.push_back(*arg); + } + m_serializationSizeInBytes = index; + return index; + } + + inline int validateResults(unsigned char* goldBuffer, int goldBufferCapacity, cl_context ctx) + { + int index=0; + + int numArguments = *(int*) &goldBuffer[index]; + index+=sizeof(int); + + if (numArguments != m_kernelArguments.size()) + { + printf("failed validation: expected %d arguments, found %d\n",numArguments, m_kernelArguments.size()); + return -1; + } + + for (int ii=0;iim_argSizeInBytes) + { + printf("failed validation: argument %d sizeInBytes expected: %d, found %d\n",ii, argGold->m_argSizeInBytes, m_kernelArguments[ii].m_argSizeInBytes); + return -2; + } + + { + int expected = argGold->m_isBuffer; + int found = m_kernelArguments[ii].m_isBuffer; + + if (expected != found) + { + printf("failed validation: argument %d isBuffer expected: %d, found %d\n",ii,expected, found); + return -3; + } + } + index+=sizeof(btKernelArgData); + + if (argGold->m_isBuffer) + { + + unsigned char* memBuf= (unsigned char*) malloc(m_kernelArguments[ii].m_argSizeInBytes); + unsigned char* goldBuf = &goldBuffer[index]; + for (int j=0;jm_argSizeInBytes; + } else + { + + //compare content + for (int b=0;bm_argData[b]; + int found =m_kernelArguments[ii].m_argData[b]; + if (expected != found) + { + printf("failed validation: argument %d const data at byte position %d expected: %d, found %d\n", + ii, b, expected, found); + return -5; + } + } + + } + } + return index; + + } + + inline int serializeArguments(unsigned char* destBuffer, int destBufferCapacity) + { + //initialize to known values + for (int i=0;i=m_serializationSizeInBytes); + + //todo: use the btSerializer for this to allow for 32/64bit, endianness etc + int numArguments = m_kernelArguments.size(); + int curBufferSize = 0; + int* dest = (int*)&destBuffer[curBufferSize]; + *dest = numArguments; + curBufferSize += sizeof(int); + + + + for (int i=0;im_kernelArguments.size();i++) + { + btKernelArgData* arg = (btKernelArgData*) &destBuffer[curBufferSize]; + *arg = m_kernelArguments[i]; + curBufferSize+=sizeof(btKernelArgData); + if (arg->m_isBuffer==1) + { + //copy the OpenCL buffer content + cl_int status = 0; + status = clEnqueueReadBuffer( m_commandQueue, arg->m_clBuffer, 0, 0, arg->m_argSizeInBytes, + &destBuffer[curBufferSize], 0,0,0 ); + btAssert( status==CL_SUCCESS ); + clFinish(m_commandQueue); + curBufferSize+=arg->m_argSizeInBytes; + } + + } + return curBufferSize; + } + + void serializeToFile(const char* fileName, int numWorkItems) + { + int num = numWorkItems; + int buffSize = getSerializationBufferSize(); + unsigned char* buf = new unsigned char[buffSize+sizeof(int)]; + for (int i=0;i + inline void setConst( const T& consts ) + { + int sz=sizeof(T); + btAssert(sz<=BT_CL_MAX_ARG_SIZE); + btKernelArgData kernelArg; + kernelArg.m_argIndex = m_idx; + kernelArg.m_isBuffer = 0; + T* destArg = (T*)kernelArg.m_argData; + *destArg = consts; + kernelArg.m_argSizeInBytes = sizeof(T); + m_kernelArguments.push_back(kernelArg); + m_serializationSizeInBytes+=sizeof(btKernelArgData); + + cl_int status = clSetKernelArg( m_kernel, m_idx++, sz, &consts ); + btAssert( status == CL_SUCCESS ); + } + + inline void launch1D( int numThreads, int localSize = 64) + { + launch2D( numThreads, 1, localSize, 1 ); + } + + inline void launch2D( int numThreadsX, int numThreadsY, int localSizeX, int localSizeY ) + { + size_t gRange[3] = {1,1,1}; + size_t lRange[3] = {1,1,1}; + lRange[0] = localSizeX; + lRange[1] = localSizeY; + gRange[0] = btMax((size_t)1, (numThreadsX/lRange[0])+(!(numThreadsX%lRange[0])?0:1)); + gRange[0] *= lRange[0]; + gRange[1] = btMax((size_t)1, (numThreadsY/lRange[1])+(!(numThreadsY%lRange[1])?0:1)); + gRange[1] *= lRange[1]; + + cl_int status = clEnqueueNDRangeKernel( m_commandQueue, + m_kernel, 2, NULL, gRange, lRange, 0,0,0 ); + if (status != CL_SUCCESS) + { + printf("Error: OpenCL status = %d\n",status); + } + btAssert( status == CL_SUCCESS ); + + } +}; + + + +#endif //BT_LAUNCHER_CL_H diff --git a/opencl/parallel_primitives/host/btMinMax.h b/opencl/parallel_primitives/host/btMinMax.h new file mode 100644 index 000000000..5b436e9ba --- /dev/null +++ b/opencl/parallel_primitives/host/btMinMax.h @@ -0,0 +1,71 @@ +/* +Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_GEN_MINMAX_H +#define BT_GEN_MINMAX_H + +#include "btScalar.h" + +template +SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) +{ + return a < b ? a : b ; +} + +template +SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b) +{ + return a > b ? a : b; +} + +template +SIMD_FORCE_INLINE const T& btClamped(const T& a, const T& lb, const T& ub) +{ + return a < lb ? lb : (ub < a ? ub : a); +} + +template +SIMD_FORCE_INLINE void btSetMin(T& a, const T& b) +{ + if (b < a) + { + a = b; + } +} + +template +SIMD_FORCE_INLINE void btSetMax(T& a, const T& b) +{ + if (a < b) + { + a = b; + } +} + +template +SIMD_FORCE_INLINE void btClamp(T& a, const T& lb, const T& ub) +{ + if (a < lb) + { + a = lb; + } + else if (ub < a) + { + a = ub; + } +} + +#endif //BT_GEN_MINMAX_H diff --git a/opencl/parallel_primitives/host/btOpenCLArray.h b/opencl/parallel_primitives/host/btOpenCLArray.h new file mode 100644 index 000000000..91e88e9ed --- /dev/null +++ b/opencl/parallel_primitives/host/btOpenCLArray.h @@ -0,0 +1,274 @@ +#ifndef BT_OPENCL_ARRAY_H +#define BT_OPENCL_ARRAY_H + +#include "btAlignedObjectArray.h" +#include "../../basic_initialize/btOpenCLInclude.h" + +template +class btOpenCLArray +{ + int m_size; + int m_capacity; + cl_mem m_clBuffer; + + cl_context m_clContext; + cl_command_queue m_commandQueue; + + bool m_ownsMemory; + + bool m_allowGrowingCapacity; + + void deallocate() + { + if (m_clBuffer && m_ownsMemory) + { + clReleaseMemObject(m_clBuffer); + } + m_clBuffer = 0; + m_capacity=0; + } + + btOpenCLArray& operator=(const btOpenCLArray& src); + + SIMD_FORCE_INLINE int allocSize(int size) + { + return (size ? size*2 : 1); + } + +public: + + btOpenCLArray(cl_context ctx, cl_command_queue queue, int initialCapacity=0, bool allowGrowingCapacity=true) + :m_size(0), m_capacity(0),m_clBuffer(0), + m_clContext(ctx),m_commandQueue(queue), + m_ownsMemory(true),m_allowGrowingCapacity(true) + { + if (initialCapacity) + { + reserve(initialCapacity); + } + m_allowGrowingCapacity = allowGrowingCapacity; + } + + ///this is an error-prone method with no error checking, be careful! + void setFromOpenCLBuffer(cl_mem buffer, int sizeInElements) + { + deallocate(); + m_ownsMemory = false; + m_allowGrowingCapacity = false; + m_clBuffer = buffer; + m_size = sizeInElements; + m_capacity = sizeInElements; + } + +// we could enable this assignment, but need to make sure to avoid accidental deep copies +// btOpenCLArray& operator=(const btAlignedObjectArray& src) +// { +// copyFromArray(src); +// return *this; +// } + + + cl_mem getBufferCL() const + { + return m_clBuffer; + } + + + virtual ~btOpenCLArray() + { + deallocate(); + m_size=0; + m_capacity=0; + } + + SIMD_FORCE_INLINE void push_back(const T& _Val,bool waitForCompletion=true) + { + int sz = size(); + if( sz == capacity() ) + { + reserve( allocSize(size()) ); + } + copyFromHostPointer(&_Val, 1, sz, waitForCompletion); + m_size++; + } + + SIMD_FORCE_INLINE T forcedAt(int n) const + { + btAssert(n>=0); + btAssert(n=0); + btAssert(n size()) + { + reserve(newsize,copyOldContents); + } + + //leave new data uninitialized (init in debug mode?) + //for (int i=curSize;i0); + btAssert(numElements<=m_size); + + int srcOffsetBytes = sizeof(T)*firstElem; + int dstOffsetInBytes = sizeof(T)*dstOffsetInElems; + + status = clEnqueueCopyBuffer( m_commandQueue, m_clBuffer, destination, + srcOffsetBytes, dstOffsetInBytes, sizeof(T)*numElements, 0, 0, 0 ); + + btAssert( status == CL_SUCCESS ); + } + + void copyFromHost(const btAlignedObjectArray& srcArray, bool waitForCompletion=true) + { + int newSize = srcArray.size(); + + bool copyOldContents = false; + resize (newSize,copyOldContents); + if (newSize) + copyFromHostPointer(&srcArray[0],newSize,0,waitForCompletion); + + } + + void copyFromHostPointer(const T* src, int numElems, int destFirstElem= 0, bool waitForCompletion=true) + { + btAssert(numElems+destFirstElem <= capacity()); + + cl_int status = 0; + int sizeInBytes=sizeof(T)*numElems; + status = clEnqueueWriteBuffer( m_commandQueue, m_clBuffer, 0, sizeof(T)*destFirstElem, sizeInBytes, + src, 0,0,0 ); + btAssert(status == CL_SUCCESS ); + if (waitForCompletion) + clFinish(m_commandQueue); + + } + + + void copyToHost(btAlignedObjectArray& destArray, bool waitForCompletion=true) const + { + destArray.resize(this->size()); + if (size()) + copyToHostPointer(&destArray[0], size(),0,waitForCompletion); + } + + void copyToHostPointer(T* destPtr, int numElem, int srcFirstElem=0, bool waitForCompletion=true) const + { + btAssert(numElem+srcFirstElem <= capacity()); + + cl_int status = 0; + status = clEnqueueReadBuffer( m_commandQueue, m_clBuffer, 0, sizeof(T)*srcFirstElem, sizeof(T)*numElem, + destPtr, 0,0,0 ); + btAssert( status==CL_SUCCESS ); + + if (waitForCompletion) + clFinish(m_commandQueue); + } + + void copyFromOpenCLArray(const btOpenCLArray& src) + { + int newSize = src.size(); + resize(newSize); + if (size()) + { + src.copyToCL(m_clBuffer,size()); + } + } + +}; + + +#endif //BT_OPENCL_ARRAY_H diff --git a/opencl/parallel_primitives/host/btPrefixScanCL.cpp b/opencl/parallel_primitives/host/btPrefixScanCL.cpp new file mode 100644 index 000000000..c584097c5 --- /dev/null +++ b/opencl/parallel_primitives/host/btPrefixScanCL.cpp @@ -0,0 +1,126 @@ +#include "btPrefixScanCL.h" +#include "btFillCL.h" +#define BT_PREFIXSCAN_PROG_PATH "opencl/parallel_primitives/kernels/PrefixScanKernels.cl" + +#include "btLauncherCL.h" +#include "../../basic_initialize/btOpenCLUtils.h" +#include "../kernels/PrefixScanKernelsCL.h" + +btPrefixScanCL::btPrefixScanCL(cl_context ctx, cl_device_id device, cl_command_queue queue, int size) +:m_commandQueue(queue) +{ + const char* scanKernelSource = prefixScanKernelsCL; + cl_int pErrNum; + char* additionalMacros=0; + + m_workBuffer = new btOpenCLArray(ctx,queue,size); + cl_program scanProg = btOpenCLUtils::compileCLProgramFromString( ctx, device, scanKernelSource, &pErrNum,additionalMacros, BT_PREFIXSCAN_PROG_PATH); + btAssert(scanProg); + + m_localScanKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, scanKernelSource, "LocalScanKernel", &pErrNum, scanProg,additionalMacros ); + btAssert(m_localScanKernel ); + m_blockSumKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, scanKernelSource, "TopLevelScanKernel", &pErrNum, scanProg,additionalMacros ); + btAssert(m_blockSumKernel ); + m_propagationKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, scanKernelSource, "AddOffsetKernel", &pErrNum, scanProg,additionalMacros ); + btAssert(m_propagationKernel ); +} + + +btPrefixScanCL::~btPrefixScanCL() +{ + delete m_workBuffer; + clReleaseKernel(m_localScanKernel); + clReleaseKernel(m_blockSumKernel); + clReleaseKernel(m_propagationKernel); +} + +template +T btNextPowerOf2(T n) +{ + n -= 1; + for(int i=0; i>i); + return n+1; +} + +void btPrefixScanCL::execute(btOpenCLArray& src, btOpenCLArray& dst, int n, unsigned int* sum) +{ + +// btAssert( data->m_option == EXCLUSIVE ); + const unsigned int numBlocks = (const unsigned int)( (n+BLOCK_SIZE*2-1)/(BLOCK_SIZE*2) ); + + dst.resize(src.size()); + m_workBuffer->resize(src.size()); + + btInt4 constBuffer; + constBuffer.x = n; + constBuffer.y = numBlocks; + constBuffer.z = (int)btNextPowerOf2( numBlocks ); + + btOpenCLArray* srcNative = &src; + btOpenCLArray* dstNative = &dst; + + { + btBufferInfoCL bInfo[] = { btBufferInfoCL( dstNative->getBufferCL() ), btBufferInfoCL( srcNative->getBufferCL() ), btBufferInfoCL( m_workBuffer->getBufferCL() ) }; + + btLauncherCL launcher( m_commandQueue, m_localScanKernel ); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( constBuffer ); + launcher.launch1D( numBlocks*BLOCK_SIZE, BLOCK_SIZE ); + } + + { + btBufferInfoCL bInfo[] = { btBufferInfoCL( m_workBuffer->getBufferCL() ) }; + + btLauncherCL launcher( m_commandQueue, m_blockSumKernel ); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( constBuffer ); + launcher.launch1D( BLOCK_SIZE, BLOCK_SIZE ); + } + + + if( numBlocks > 1 ) + { + btBufferInfoCL bInfo[] = { btBufferInfoCL( dstNative->getBufferCL() ), btBufferInfoCL( m_workBuffer->getBufferCL() ) }; + btLauncherCL launcher( m_commandQueue, m_propagationKernel ); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( constBuffer ); + launcher.launch1D( (numBlocks-1)*BLOCK_SIZE, BLOCK_SIZE ); + } + + + if( sum ) + { + clFinish(m_commandQueue); + dstNative->copyToHostPointer(sum,1,n-1,true); + } + +} + + +void btPrefixScanCL::executeHost(btAlignedObjectArray& src, btAlignedObjectArray& dst, int n, unsigned int* sum) +{ + unsigned int s = 0; + //if( data->m_option == EXCLUSIVE ) + { + for(int i=0; i* m_workBuffer; + + + public: + + btPrefixScanCL(cl_context ctx, cl_device_id device, cl_command_queue queue,int size=0); + + virtual ~btPrefixScanCL(); + + void execute(btOpenCLArray& src, btOpenCLArray& dst, int n, unsigned int* sum = 0); + void executeHost(btAlignedObjectArray& src, btAlignedObjectArray& dst, int n, unsigned int* sum); +}; + +#endif //BT_PREFIX_SCAN_CL_H diff --git a/opencl/parallel_primitives/host/btQuickprof.cpp b/opencl/parallel_primitives/host/btQuickprof.cpp new file mode 100644 index 000000000..544aee89d --- /dev/null +++ b/opencl/parallel_primitives/host/btQuickprof.cpp @@ -0,0 +1,566 @@ +/* + +*************************************************************************************************** +** +** profile.cpp +** +** Real-Time Hierarchical Profiling for Game Programming Gems 3 +** +** by Greg Hjelstrom & Byon Garrabrant +** +***************************************************************************************************/ + +// Credits: The Clock class was inspired by the Timer classes in +// Ogre (www.ogre3d.org). + +#include "btQuickprof.h" + +#ifndef BT_NO_PROFILE + + +static btClock gProfileClock; + + +#ifdef __CELLOS_LV2__ +#include +#include +#include +#endif + +#if defined (SUNOS) || defined (__SUNOS__) +#include +#endif + +#if defined(WIN32) || defined(_WIN32) + +#define BT_USE_WINDOWS_TIMERS +#define WIN32_LEAN_AND_MEAN +#define NOWINRES +#define NOMCX +#define NOIME + +#ifdef _XBOX + #include +#else //_XBOX + #include +#endif //_XBOX + +#include + + +#else //_WIN32 +#include +#endif //_WIN32 + +#define mymin(a,b) (a > b ? a : b) + +struct btClockData +{ + +#ifdef BT_USE_WINDOWS_TIMERS + LARGE_INTEGER mClockFrequency; + DWORD mStartTick; + LONGLONG mPrevElapsedTime; + LARGE_INTEGER mStartTime; +#else +#ifdef __CELLOS_LV2__ + uint64_t mStartTime; +#else + struct timeval mStartTime; +#endif +#endif //__CELLOS_LV2__ + +}; + +///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling. +btClock::btClock() +{ + m_data = new btClockData; +#ifdef BT_USE_WINDOWS_TIMERS + QueryPerformanceFrequency(&m_data->mClockFrequency); +#endif + reset(); +} + +btClock::~btClock() +{ + delete m_data; +} + +btClock::btClock(const btClock& other) +{ + m_data = new btClockData; + *m_data = *other.m_data; +} + +btClock& btClock::operator=(const btClock& other) +{ + *m_data = *other.m_data; + return *this; +} + + + /// Resets the initial reference time. +void btClock::reset() +{ +#ifdef BT_USE_WINDOWS_TIMERS + QueryPerformanceCounter(&m_data->mStartTime); + m_data->mStartTick = GetTickCount(); + m_data->mPrevElapsedTime = 0; +#else +#ifdef __CELLOS_LV2__ + + typedef uint64_t ClockSize; + ClockSize newTime; + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + SYS_TIMEBASE_GET( newTime ); + m_data->mStartTime = newTime; +#else + gettimeofday(&m_data->mStartTime, 0); +#endif +#endif +} + +/// Returns the time in ms since the last call to reset or since +/// the btClock was created. +unsigned long int btClock::getTimeMilliseconds() +{ +#ifdef BT_USE_WINDOWS_TIMERS + LARGE_INTEGER currentTime; + QueryPerformanceCounter(¤tTime); + LONGLONG elapsedTime = currentTime.QuadPart - + m_data->mStartTime.QuadPart; + // Compute the number of millisecond ticks elapsed. + unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / + m_data->mClockFrequency.QuadPart); + // Check for unexpected leaps in the Win32 performance counter. + // (This is caused by unexpected data across the PCI to ISA + // bridge, aka south bridge. See Microsoft KB274323.) + unsigned long elapsedTicks = GetTickCount() - m_data->mStartTick; + signed long msecOff = (signed long)(msecTicks - elapsedTicks); + if (msecOff < -100 || msecOff > 100) + { + // Adjust the starting time forwards. + LONGLONG msecAdjustment = mymin(msecOff * + m_data->mClockFrequency.QuadPart / 1000, elapsedTime - + m_data->mPrevElapsedTime); + m_data->mStartTime.QuadPart += msecAdjustment; + elapsedTime -= msecAdjustment; + + // Recompute the number of millisecond ticks elapsed. + msecTicks = (unsigned long)(1000 * elapsedTime / + m_data->mClockFrequency.QuadPart); + } + + // Store the current elapsed time for adjustments next time. + m_data->mPrevElapsedTime = elapsedTime; + + return msecTicks; +#else + +#ifdef __CELLOS_LV2__ + uint64_t freq=sys_time_get_timebase_frequency(); + double dFreq=((double) freq) / 1000.0; + typedef uint64_t ClockSize; + ClockSize newTime; + SYS_TIMEBASE_GET( newTime ); + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + + return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq); +#else + + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000; +#endif //__CELLOS_LV2__ +#endif +} + + /// Returns the time in us since the last call to reset or since + /// the Clock was created. +unsigned long int btClock::getTimeMicroseconds() +{ +#ifdef BT_USE_WINDOWS_TIMERS + LARGE_INTEGER currentTime; + QueryPerformanceCounter(¤tTime); + LONGLONG elapsedTime = currentTime.QuadPart - + m_data->mStartTime.QuadPart; + + // Compute the number of millisecond ticks elapsed. + unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / + m_data->mClockFrequency.QuadPart); + + // Check for unexpected leaps in the Win32 performance counter. + // (This is caused by unexpected data across the PCI to ISA + // bridge, aka south bridge. See Microsoft KB274323.) + unsigned long elapsedTicks = GetTickCount() - m_data->mStartTick; + signed long msecOff = (signed long)(msecTicks - elapsedTicks); + if (msecOff < -100 || msecOff > 100) + { + // Adjust the starting time forwards. + LONGLONG msecAdjustment = mymin(msecOff * + m_data->mClockFrequency.QuadPart / 1000, elapsedTime - + m_data->mPrevElapsedTime); + m_data->mStartTime.QuadPart += msecAdjustment; + elapsedTime -= msecAdjustment; + } + + // Store the current elapsed time for adjustments next time. + m_data->mPrevElapsedTime = elapsedTime; + + // Convert to microseconds. + unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime / + m_data->mClockFrequency.QuadPart); + + return usecTicks; +#else + +#ifdef __CELLOS_LV2__ + uint64_t freq=sys_time_get_timebase_frequency(); + double dFreq=((double) freq)/ 1000000.0; + typedef uint64_t ClockSize; + ClockSize newTime; + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + SYS_TIMEBASE_GET( newTime ); + + return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq); +#else + + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec); +#endif//__CELLOS_LV2__ +#endif +} + + + + + +inline void Profile_Get_Ticks(unsigned long int * ticks) +{ + *ticks = gProfileClock.getTimeMicroseconds(); +} + +inline float Profile_Get_Tick_Rate(void) +{ +// return 1000000.f; + return 1000.f; + +} + + + +/*************************************************************************************************** +** +** CProfileNode +** +***************************************************************************************************/ + +/*********************************************************************************************** + * INPUT: * + * name - pointer to a static string which is the name of this profile node * + * parent - parent pointer * + * * + * WARNINGS: * + * The name is assumed to be a static pointer, only the pointer is stored and compared for * + * efficiency reasons. * + *=============================================================================================*/ +CProfileNode::CProfileNode( const char * name, CProfileNode * parent ) : + Name( name ), + TotalCalls( 0 ), + TotalTime( 0 ), + StartTime( 0 ), + RecursionCounter( 0 ), + Parent( parent ), + Child( NULL ), + Sibling( NULL ), + m_userPtr(0) +{ + Reset(); +} + + +void CProfileNode::CleanupMemory() +{ + delete ( Child); + Child = NULL; + delete ( Sibling); + Sibling = NULL; +} + +CProfileNode::~CProfileNode( void ) +{ + delete ( Child); + delete ( Sibling); +} + + +/*********************************************************************************************** + * INPUT: * + * name - static string pointer to the name of the node we are searching for * + * * + * WARNINGS: * + * All profile names are assumed to be static strings so this function uses pointer compares * + * to find the named node. * + *=============================================================================================*/ +CProfileNode * CProfileNode::Get_Sub_Node( const char * name ) +{ + // Try to find this sub node + CProfileNode * child = Child; + while ( child ) { + if ( child->Name == name ) { + return child; + } + child = child->Sibling; + } + + // We didn't find it, so add it + + CProfileNode * node = new CProfileNode( name, this ); + node->Sibling = Child; + Child = node; + return node; +} + + +void CProfileNode::Reset( void ) +{ + TotalCalls = 0; + TotalTime = 0.0f; + + + if ( Child ) { + Child->Reset(); + } + if ( Sibling ) { + Sibling->Reset(); + } +} + + +void CProfileNode::Call( void ) +{ + TotalCalls++; + if (RecursionCounter++ == 0) { + Profile_Get_Ticks(&StartTime); + } +} + + +bool CProfileNode::Return( void ) +{ + if ( --RecursionCounter == 0 && TotalCalls != 0 ) { + unsigned long int time; + Profile_Get_Ticks(&time); + time-=StartTime; + TotalTime += (float)time / Profile_Get_Tick_Rate(); + } + return ( RecursionCounter == 0 ); +} + + +/*************************************************************************************************** +** +** CProfileIterator +** +***************************************************************************************************/ +CProfileIterator::CProfileIterator( CProfileNode * start ) +{ + CurrentParent = start; + CurrentChild = CurrentParent->Get_Child(); +} + + +void CProfileIterator::First(void) +{ + CurrentChild = CurrentParent->Get_Child(); +} + + +void CProfileIterator::Next(void) +{ + CurrentChild = CurrentChild->Get_Sibling(); +} + + +bool CProfileIterator::Is_Done(void) +{ + return CurrentChild == NULL; +} + + +void CProfileIterator::Enter_Child( int index ) +{ + CurrentChild = CurrentParent->Get_Child(); + while ( (CurrentChild != NULL) && (index != 0) ) { + index--; + CurrentChild = CurrentChild->Get_Sibling(); + } + + if ( CurrentChild != NULL ) { + CurrentParent = CurrentChild; + CurrentChild = CurrentParent->Get_Child(); + } +} + + +void CProfileIterator::Enter_Parent( void ) +{ + if ( CurrentParent->Get_Parent() != NULL ) { + CurrentParent = CurrentParent->Get_Parent(); + } + CurrentChild = CurrentParent->Get_Child(); +} + + +/*************************************************************************************************** +** +** CProfileManager +** +***************************************************************************************************/ + +CProfileNode CProfileManager::Root( "Root", NULL ); +CProfileNode * CProfileManager::CurrentNode = &CProfileManager::Root; +int CProfileManager::FrameCounter = 0; +unsigned long int CProfileManager::ResetTime = 0; + + +/*********************************************************************************************** + * CProfileManager::Start_Profile -- Begin a named profile * + * * + * Steps one level deeper into the tree, if a child already exists with the specified name * + * then it accumulates the profiling; otherwise a new child node is added to the profile tree. * + * * + * INPUT: * + * name - name of this profiling record * + * * + * WARNINGS: * + * The string used is assumed to be a static string; pointer compares are used throughout * + * the profiling code for efficiency. * + *=============================================================================================*/ +void CProfileManager::Start_Profile( const char * name ) +{ + if (name != CurrentNode->Get_Name()) { + CurrentNode = CurrentNode->Get_Sub_Node( name ); + } + + CurrentNode->Call(); +} + + +/*********************************************************************************************** + * CProfileManager::Stop_Profile -- Stop timing and record the results. * + *=============================================================================================*/ +void CProfileManager::Stop_Profile( void ) +{ + // Return will indicate whether we should back up to our parent (we may + // be profiling a recursive function) + if (CurrentNode->Return()) { + CurrentNode = CurrentNode->Get_Parent(); + } +} + + +/*********************************************************************************************** + * CProfileManager::Reset -- Reset the contents of the profiling system * + * * + * This resets everything except for the tree structure. All of the timing data is reset. * + *=============================================================================================*/ +void CProfileManager::Reset( void ) +{ + gProfileClock.reset(); + Root.Reset(); + Root.Call(); + FrameCounter = 0; + Profile_Get_Ticks(&ResetTime); +} + + +/*********************************************************************************************** + * CProfileManager::Increment_Frame_Counter -- Increment the frame counter * + *=============================================================================================*/ +void CProfileManager::Increment_Frame_Counter( void ) +{ + FrameCounter++; +} + + +/*********************************************************************************************** + * CProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset * + *=============================================================================================*/ +float CProfileManager::Get_Time_Since_Reset( void ) +{ + unsigned long int time; + Profile_Get_Ticks(&time); + time -= ResetTime; + return (float)time / Profile_Get_Tick_Rate(); +} + +#include + +void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing) +{ + profileIterator->First(); + if (profileIterator->Is_Done()) + return; + + float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); + int i; + int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset(); + for (i=0;iGet_Current_Parent_Name(), parent_time ); + float totalTime = 0.f; + + + int numChildren = 0; + + for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next()) + { + numChildren++; + float current_total_time = profileIterator->Get_Current_Total_Time(); + accumulated_time += current_total_time; + float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; + { + int i; for (i=0;iGet_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls()); + totalTime += current_total_time; + //recurse into children + } + + if (parent_time < accumulated_time) + { + printf("what's wrong\n"); + } + for (i=0;i SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); + + for (i=0;iEnter_Child(i); + dumpRecursive(profileIterator,spacing+3); + profileIterator->Enter_Parent(); + } +} + + + +void CProfileManager::dumpAll() +{ + CProfileIterator* profileIterator = 0; + profileIterator = CProfileManager::Get_Iterator(); + + dumpRecursive(profileIterator,0); + + CProfileManager::Release_Iterator(profileIterator); +} + + + + +#endif //BT_NO_PROFILE diff --git a/opencl/parallel_primitives/host/btQuickprof.h b/opencl/parallel_primitives/host/btQuickprof.h new file mode 100644 index 000000000..93f3f4a60 --- /dev/null +++ b/opencl/parallel_primitives/host/btQuickprof.h @@ -0,0 +1,203 @@ + +/*************************************************************************************************** +** +** Real-Time Hierarchical Profiling for Game Programming Gems 3 +** +** by Greg Hjelstrom & Byon Garrabrant +** +***************************************************************************************************/ + +// Credits: The Clock class was inspired by the Timer classes in +// Ogre (www.ogre3d.org). + + + +#ifndef BT_QUICK_PROF_H +#define BT_QUICK_PROF_H + +//To disable built-in profiling, please comment out next line +//#define BT_NO_PROFILE 1 +#ifndef BT_NO_PROFILE +#include //@todo remove this, backwards compatibility +#include "btScalar.h" +#include "btAlignedAllocator.h" +#include + + + + + +#define USE_BT_CLOCK 1 + +#ifdef USE_BT_CLOCK + +///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling. +class btClock +{ +public: + btClock(); + + btClock(const btClock& other); + btClock& operator=(const btClock& other); + + ~btClock(); + + /// Resets the initial reference time. + void reset(); + + /// Returns the time in ms since the last call to reset or since + /// the btClock was created. + unsigned long int getTimeMilliseconds(); + + /// Returns the time in us since the last call to reset or since + /// the Clock was created. + unsigned long int getTimeMicroseconds(); +private: + struct btClockData* m_data; +}; + +#endif //USE_BT_CLOCK + + + + +///A node in the Profile Hierarchy Tree +class CProfileNode { + +public: + CProfileNode( const char * name, CProfileNode * parent ); + ~CProfileNode( void ); + + CProfileNode * Get_Sub_Node( const char * name ); + + CProfileNode * Get_Parent( void ) { return Parent; } + CProfileNode * Get_Sibling( void ) { return Sibling; } + CProfileNode * Get_Child( void ) { return Child; } + + void CleanupMemory(); + void Reset( void ); + void Call( void ); + bool Return( void ); + + const char * Get_Name( void ) { return Name; } + int Get_Total_Calls( void ) { return TotalCalls; } + float Get_Total_Time( void ) { return TotalTime; } + void* GetUserPointer() const {return m_userPtr;} + void SetUserPointer(void* ptr) { m_userPtr = ptr;} +protected: + + const char * Name; + int TotalCalls; + float TotalTime; + unsigned long int StartTime; + int RecursionCounter; + + CProfileNode * Parent; + CProfileNode * Child; + CProfileNode * Sibling; + void* m_userPtr; +}; + +///An iterator to navigate through the tree +class CProfileIterator +{ +public: + // Access all the children of the current parent + void First(void); + void Next(void); + bool Is_Done(void); + bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); } + + void Enter_Child( int index ); // Make the given child the new parent + void Enter_Largest_Child( void ); // Make the largest child the new parent + void Enter_Parent( void ); // Make the current parent's parent the new parent + + // Access the current child + const char * Get_Current_Name( void ) { return CurrentChild->Get_Name(); } + int Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); } + float Get_Current_Total_Time( void ) { return CurrentChild->Get_Total_Time(); } + + void* Get_Current_UserPointer( void ) { return CurrentChild->GetUserPointer(); } + void Set_Current_UserPointer(void* ptr) {CurrentChild->SetUserPointer(ptr);} + // Access the current parent + const char * Get_Current_Parent_Name( void ) { return CurrentParent->Get_Name(); } + int Get_Current_Parent_Total_Calls( void ) { return CurrentParent->Get_Total_Calls(); } + float Get_Current_Parent_Total_Time( void ) { return CurrentParent->Get_Total_Time(); } + + + +protected: + + CProfileNode * CurrentParent; + CProfileNode * CurrentChild; + + + CProfileIterator( CProfileNode * start ); + friend class CProfileManager; +}; + + +///The Manager for the Profile system +class CProfileManager { +public: + static void Start_Profile( const char * name ); + static void Stop_Profile( void ); + + static void CleanupMemory(void) + { + Root.CleanupMemory(); + } + + static void Reset( void ); + static void Increment_Frame_Counter( void ); + static int Get_Frame_Count_Since_Reset( void ) { return FrameCounter; } + static float Get_Time_Since_Reset( void ); + + static CProfileIterator * Get_Iterator( void ) + { + + return new CProfileIterator( &Root ); + } + static void Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); } + + static void dumpRecursive(CProfileIterator* profileIterator, int spacing); + + static void dumpAll(); + +private: + static CProfileNode Root; + static CProfileNode * CurrentNode; + static int FrameCounter; + static unsigned long int ResetTime; +}; + + +///ProfileSampleClass is a simple way to profile a function's scope +///Use the BT_PROFILE macro at the start of scope to time +class CProfileSample { +public: + CProfileSample( const char * name ) + { + CProfileManager::Start_Profile( name ); + } + + ~CProfileSample( void ) + { + CProfileManager::Stop_Profile(); + } +}; + + +#define BT_PROFILE( name ) CProfileSample __profile( name ) + +#else + +#define BT_PROFILE( name ) + +#endif //#ifndef BT_NO_PROFILE + + + +#endif //BT_QUICK_PROF_H + + diff --git a/opencl/parallel_primitives/host/btRadixSort32CL.cpp b/opencl/parallel_primitives/host/btRadixSort32CL.cpp new file mode 100644 index 000000000..6d007fef2 --- /dev/null +++ b/opencl/parallel_primitives/host/btRadixSort32CL.cpp @@ -0,0 +1,712 @@ + +#include "btRadixSort32CL.h" +#include "btLauncherCL.h" +#include "../../basic_initialize/btOpenCLUtils.h" +#include "btPrefixScanCL.h" +#include "btFillCL.h" + +#define RADIXSORT32_PATH "opencl/parallel_primitives/kernels/RadixSort32Kernels.cl" + +#include "../kernels/RadixSort32KernelsCL.h" + +btRadixSort32CL::btRadixSort32CL(cl_context ctx, cl_device_id device, cl_command_queue queue, int initialCapacity) +:m_commandQueue(queue) +{ + btOpenCLDeviceInfo info; + btOpenCLUtils::getDeviceInfo(device,&info); + m_deviceCPU = (info.m_deviceType & CL_DEVICE_TYPE_CPU)!=0; + + m_workBuffer1 = new btOpenCLArray(ctx,queue); + m_workBuffer2 = new btOpenCLArray(ctx,queue); + m_workBuffer3 = new btOpenCLArray(ctx,queue); + m_workBuffer3a = new btOpenCLArray(ctx,queue); + m_workBuffer4 = new btOpenCLArray(ctx,queue); + m_workBuffer4a = new btOpenCLArray(ctx,queue); + + + if (initialCapacity>0) + { + m_workBuffer1->resize(initialCapacity); + m_workBuffer3->resize(initialCapacity); + m_workBuffer3a->resize(initialCapacity); + m_workBuffer4->resize(initialCapacity); + m_workBuffer4a->resize(initialCapacity); + } + + m_scan = new btPrefixScanCL(ctx,device,queue); + m_fill = new btFillCL(ctx,device,queue); + + const char* additionalMacros = ""; + const char* srcFileNameForCaching=""; + + cl_int pErrNum; + const char* kernelSource = radixSort32KernelsCL; + + cl_program sortProg = btOpenCLUtils::compileCLProgramFromString( ctx, device, kernelSource, &pErrNum,additionalMacros, RADIXSORT32_PATH); + btAssert(sortProg); + + m_streamCountSortDataKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "StreamCountSortDataKernel", &pErrNum, sortProg,additionalMacros ); + btAssert(m_streamCountSortDataKernel ); + + + + m_streamCountKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "StreamCountKernel", &pErrNum, sortProg,additionalMacros ); + btAssert(m_streamCountKernel); + + + + if (m_deviceCPU) + { + + m_sortAndScatterSortDataKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "SortAndScatterSortDataKernelSerial", &pErrNum, sortProg,additionalMacros ); + btAssert(m_sortAndScatterSortDataKernel); + m_sortAndScatterKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "SortAndScatterKernelSerial", &pErrNum, sortProg,additionalMacros ); + btAssert(m_sortAndScatterKernel); + } else + { + m_sortAndScatterSortDataKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "SortAndScatterSortDataKernel", &pErrNum, sortProg,additionalMacros ); + btAssert(m_sortAndScatterSortDataKernel); + m_sortAndScatterKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "SortAndScatterKernel", &pErrNum, sortProg,additionalMacros ); + btAssert(m_sortAndScatterKernel); + } + + m_prefixScanKernel = btOpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "PrefixScanKernel", &pErrNum, sortProg,additionalMacros ); + btAssert(m_prefixScanKernel); + +} + +btRadixSort32CL::~btRadixSort32CL() +{ + delete m_scan; + delete m_fill; + delete m_workBuffer1; + delete m_workBuffer2; + delete m_workBuffer3; + delete m_workBuffer3a; + delete m_workBuffer4; + delete m_workBuffer4a; + + clReleaseKernel(m_streamCountSortDataKernel); + clReleaseKernel(m_streamCountKernel); + clReleaseKernel(m_sortAndScatterSortDataKernel); + clReleaseKernel(m_sortAndScatterKernel); + clReleaseKernel(m_prefixScanKernel); +} + +void btRadixSort32CL::executeHost(btAlignedObjectArray& inout, int sortBits /* = 32 */) +{ + int n = inout.size(); + const int BITS_PER_PASS = 8; + const int NUM_TABLES = (1< workbuffer; + workbuffer.resize(inout.size()); + btSortData* dst = &workbuffer[0]; + + int count=0; + for(int startBit=0; startBit> startBit) & (NUM_TABLES-1); + tables[tableIdx]++; + } +//#define TEST +#ifdef TEST + printf("histogram size=%d\n",NUM_TABLES); + for (int i=0;i> startBit) & (NUM_TABLES-1); + + dst[tables[tableIdx] + counter[tableIdx]] = src[i]; + counter[tableIdx] ++; + } + + btSwap( src, dst ); + count++; + } + + if (count&1) + { + btAssert(0);//need to copy + + } +} + +void btRadixSort32CL::executeHost(btOpenCLArray& keyValuesInOut, int sortBits /* = 32 */) +{ + + btAlignedObjectArray inout; + keyValuesInOut.copyToHost(inout); + + executeHost(inout,sortBits); + + keyValuesInOut.copyFromHost(inout); +} + +void btRadixSort32CL::execute(btOpenCLArray& keysIn, btOpenCLArray& keysOut, btOpenCLArray& valuesIn, + btOpenCLArray& valuesOut, int n, int sortBits) +{ + +} + +//#define DEBUG_RADIXSORT +//#define DEBUG_RADIXSORT2 + + +void btRadixSort32CL::execute(btOpenCLArray& keyValuesInOut, int sortBits /* = 32 */) +{ + + int originalSize = keyValuesInOut.size(); + int workingSize = originalSize; + + + int dataAlignment = DATA_ALIGNMENT; + +#ifdef DEBUG_RADIXSORT2 + btAlignedObjectArray test2; + keyValuesInOut.copyToHost(test2); + printf("numElem = %d\n",test2.size()); + for (int i=0;i* src = 0; + + if (workingSize%dataAlignment) + { + workingSize += dataAlignment-(workingSize%dataAlignment); + m_workBuffer4->copyFromOpenCLArray(keyValuesInOut); + m_workBuffer4->resize(workingSize); + btSortData fillValue; + fillValue.m_key = 0xffffffff; + fillValue.m_value = 0xffffffff; + +#define USE_BTFILL +#ifdef USE_BTFILL + m_fill->execute((btOpenCLArray&)*m_workBuffer4,(btInt2&)fillValue,workingSize-originalSize,originalSize); +#else + //fill the remaining bits (very slow way, todo: fill on GPU/OpenCL side) + + for (int i=originalSize; icopyFromHostPointer(&fillValue,1,i); + } +#endif//USE_BTFILL + + src = m_workBuffer4; + } else + { + src = &keyValuesInOut; + m_workBuffer4->resize(0); + } + + btAssert( workingSize%DATA_ALIGNMENT == 0 ); + int minCap = NUM_BUCKET*NUM_WGS; + + + int n = workingSize; + + m_workBuffer1->resize(minCap); + m_workBuffer3->resize(workingSize); + + +// ADLASSERT( ELEMENTS_PER_WORK_ITEM == 4 ); + btAssert( BITS_PER_PASS == 4 ); + btAssert( WG_SIZE == 64 ); + btAssert( (sortBits&0x3) == 0 ); + + + + btOpenCLArray* dst = m_workBuffer3; + + btOpenCLArray* srcHisto = m_workBuffer1; + btOpenCLArray* destHisto = m_workBuffer2; + + + int nWGs = NUM_WGS; + btConstData cdata; + + { + int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE;//set at 256 + int nBlocks = (n+blockSize-1)/(blockSize); + cdata.m_n = n; + cdata.m_nWGs = NUM_WGS; + cdata.m_startBit = 0; + cdata.m_nBlocksPerWG = (nBlocks + cdata.m_nWGs - 1)/cdata.m_nWGs; + if( nBlocks < NUM_WGS ) + { + cdata.m_nBlocksPerWG = 1; + nWGs = nBlocks; + } + } + + int count=0; + for(int ib=0; ibsize()) + { + btBufferInfoCL bInfo[] = { btBufferInfoCL( src->getBufferCL(), true ), btBufferInfoCL( srcHisto->getBufferCL() ) }; + btLauncherCL launcher(m_commandQueue, m_streamCountSortDataKernel); + + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( cdata ); + + int num = NUM_WGS*WG_SIZE; + launcher.launch1D( num, WG_SIZE ); + } + + + +#ifdef DEBUG_RADIXSORT + btAlignedObjectArray testHist; + srcHisto->copyToHost(testHist); + printf("ib = %d, testHist size = %d, non zero elements:\n",ib, testHist.size()); + for (int i=0;igetBufferCL() ) }; + btLauncherCL launcher( m_commandQueue, m_prefixScanKernel ); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( cdata ); + launcher.launch1D( 128, 128 ); + destHisto = srcHisto; + }else + { + //unsigned int sum; //for debugging + m_scan->execute(*srcHisto,*destHisto,1920,0);//,&sum); + } + + +#ifdef DEBUG_RADIXSORT + destHisto->copyToHost(testHist); + printf("ib = %d, testHist size = %d, non zero elements:\n",ib, testHist.size()); + for (int i=0;isize()) + {// local sort and distribute + btBufferInfoCL bInfo[] = { btBufferInfoCL( src->getBufferCL(), true ), btBufferInfoCL( destHisto->getBufferCL(), true ), btBufferInfoCL( dst->getBufferCL() )}; + btLauncherCL launcher( m_commandQueue, m_sortAndScatterSortDataKernel ); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( cdata ); + launcher.launch1D( nWGs*WG_SIZE, WG_SIZE ); + + } +#else + { +#define NUM_TABLES 16 +//#define SEQUENTIAL +#ifdef SEQUENTIAL + int counter2[NUM_TABLES]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + int tables[NUM_TABLES]; + int startBit = ib; + + destHisto->copyToHost(testHist); + btAlignedObjectArray srcHost; + btAlignedObjectArray dstHost; + dstHost.resize(src->size()); + + src->copyToHost(srcHost); + + for (int i=0;i> startBit) & (NUM_TABLES-1); + + dstHost[tables[tableIdx] + counter2[tableIdx]] = srcHost[i]; + counter2[tableIdx] ++; + } + + +#else + + int counter2[NUM_TABLES]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + int tables[NUM_TABLES]; + btAlignedObjectArray dstHostOK; + dstHostOK.resize(src->size()); + + destHisto->copyToHost(testHist); + btAlignedObjectArray srcHost; + src->copyToHost(srcHost); + + int blockSize = 256; + int nBlocksPerWG = cdata.m_nBlocksPerWG; + int startBit = ib; + + { + for (int i=0;i> startBit) & (NUM_TABLES-1); + + dstHostOK[tables[tableIdx] + counter2[tableIdx]] = srcHost[i]; + counter2[tableIdx] ++; + } + + + } + + + btAlignedObjectArray dstHost; + dstHost.resize(src->size()); + + + int counter[NUM_TABLES]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + + + for (int wgIdx=0;wgIdx> startBit) & (NUM_TABLES-1); + + int destIndex = testHist[tableIdx*NUM_WGS+wgIdx] + counter[tableIdx]; + + btSortData ok = dstHostOK[destIndex]; + + if (ok.m_key != srcHost[i].m_key) + { + printf("ok.m_key = %d, srcHost[i].m_key = %d\n", ok.m_key,srcHost[i].m_key ); + printf("(ok.m_value = %d, srcHost[i].m_value = %d)\n", ok.m_value,srcHost[i].m_value ); + } + if (ok.m_value != srcHost[i].m_value) + { + + printf("ok.m_value = %d, srcHost[i].m_value = %d\n", ok.m_value,srcHost[i].m_value ); + printf("(ok.m_key = %d, srcHost[i].m_key = %d)\n", ok.m_key,srcHost[i].m_key ); + + } + + dstHost[destIndex] = srcHost[i]; + counter[tableIdx] ++; + + } + } + } + } + } + + +#endif //SEQUENTIAL + + dst->copyFromHost(dstHost); + } +#endif//USE_GPU + + + +#ifdef DEBUG_RADIXSORT + destHisto->copyToHost(testHist); + printf("ib = %d, testHist size = %d, non zero elements:\n",ib, testHist.size()); + for (int i=0;isize()) + { + m_workBuffer4->resize(originalSize); + keyValuesInOut.copyFromOpenCLArray(*m_workBuffer4); + } + + +#ifdef DEBUG_RADIXSORT + keyValuesInOut.copyToHost(test2); + + printf("numElem = %d\n",test2.size()); + for (int i=0;i& keysInOut, int sortBits /* = 32 */) +{ + int originalSize = keysInOut.size(); + int workingSize = originalSize; + + + int dataAlignment = DATA_ALIGNMENT; + + btOpenCLArray* src = 0; + + if (workingSize%dataAlignment) + { + workingSize += dataAlignment-(workingSize%dataAlignment); + m_workBuffer4a->copyFromOpenCLArray(keysInOut); + m_workBuffer4a->resize(workingSize); + unsigned int fillValue = 0xffffffff; + + m_fill->execute(*m_workBuffer4a,fillValue,workingSize-originalSize,originalSize); + + src = m_workBuffer4a; + } else + { + src = &keysInOut; + m_workBuffer4a->resize(0); + } + + + + btAssert( workingSize%DATA_ALIGNMENT == 0 ); + int minCap = NUM_BUCKET*NUM_WGS; + + + int n = workingSize; + + + m_workBuffer1->resize(minCap); + m_workBuffer3->resize(workingSize); + m_workBuffer3a->resize(workingSize); + +// ADLASSERT( ELEMENTS_PER_WORK_ITEM == 4 ); + btAssert( BITS_PER_PASS == 4 ); + btAssert( WG_SIZE == 64 ); + btAssert( (sortBits&0x3) == 0 ); + + + + btOpenCLArray* dst = m_workBuffer3a; + + btOpenCLArray* srcHisto = m_workBuffer1; + btOpenCLArray* destHisto = m_workBuffer2; + + + int nWGs = NUM_WGS; + btConstData cdata; + + { + int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE;//set at 256 + int nBlocks = (n+blockSize-1)/(blockSize); + cdata.m_n = n; + cdata.m_nWGs = NUM_WGS; + cdata.m_startBit = 0; + cdata.m_nBlocksPerWG = (nBlocks + cdata.m_nWGs - 1)/cdata.m_nWGs; + if( nBlocks < NUM_WGS ) + { + cdata.m_nBlocksPerWG = 1; + nWGs = nBlocks; + } + } + + int count=0; + for(int ib=0; ibsize()) + { + btBufferInfoCL bInfo[] = { btBufferInfoCL( src->getBufferCL(), true ), btBufferInfoCL( srcHisto->getBufferCL() ) }; + btLauncherCL launcher(m_commandQueue, m_streamCountKernel); + + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( cdata ); + + int num = NUM_WGS*WG_SIZE; + launcher.launch1D( num, WG_SIZE ); + } + + + +//fast prefix scan is not working properly on Mac OSX yet +#ifdef _WIN32 + bool fastScan=!m_deviceCPU; + +#else + bool fastScan=false; +#endif + + if (fastScan) + {// prefix scan group histogram + btBufferInfoCL bInfo[] = { btBufferInfoCL( srcHisto->getBufferCL() ) }; + btLauncherCL launcher( m_commandQueue, m_prefixScanKernel ); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( cdata ); + launcher.launch1D( 128, 128 ); + destHisto = srcHisto; + }else + { + //unsigned int sum; //for debugging + m_scan->execute(*srcHisto,*destHisto,1920,0);//,&sum); + } + + if (src->size()) + {// local sort and distribute + btBufferInfoCL bInfo[] = { btBufferInfoCL( src->getBufferCL(), true ), btBufferInfoCL( destHisto->getBufferCL(), true ), btBufferInfoCL( dst->getBufferCL() )}; + btLauncherCL launcher( m_commandQueue, m_sortAndScatterKernel ); + launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(btBufferInfoCL) ); + launcher.setConst( cdata ); + launcher.launch1D( nWGs*WG_SIZE, WG_SIZE ); + + } + + btSwap(src, dst ); + btSwap(srcHisto,destHisto); + + count++; + } + + if (count&1) + { + btAssert(0);//need to copy from workbuffer to keyValuesInOut + } + + if (m_workBuffer4a->size()) + { + m_workBuffer4a->resize(originalSize); + keysInOut.copyFromOpenCLArray(*m_workBuffer4a); + } + +} + + + + + + + diff --git a/opencl/parallel_primitives/host/btRadixSort32CL.h b/opencl/parallel_primitives/host/btRadixSort32CL.h new file mode 100644 index 000000000..4570303c6 --- /dev/null +++ b/opencl/parallel_primitives/host/btRadixSort32CL.h @@ -0,0 +1,85 @@ + +#ifndef BT_RADIXSORT32_H +#define BT_RADIXSORT32_H + +#include "btOpenCLArray.h" + +struct btSortData +{ + int m_key; + int m_value; +}; +#include "btBufferInfoCL.h" + +class btRadixSort32CL +{ + + btOpenCLArray* m_workBuffer1; + btOpenCLArray* m_workBuffer2; + + btOpenCLArray* m_workBuffer3; + btOpenCLArray* m_workBuffer4; + + btOpenCLArray* m_workBuffer3a; + btOpenCLArray* m_workBuffer4a; + + cl_command_queue m_commandQueue; + + cl_kernel m_streamCountSortDataKernel; + cl_kernel m_streamCountKernel; + + cl_kernel m_prefixScanKernel; + cl_kernel m_sortAndScatterSortDataKernel; + cl_kernel m_sortAndScatterKernel; + + + bool m_deviceCPU; + + class btPrefixScanCL* m_scan; + class btFillCL* m_fill; + +public: + struct btConstData + { + int m_n; + int m_nWGs; + int m_startBit; + int m_nBlocksPerWG; + }; + enum + { + DATA_ALIGNMENT = 256, + WG_SIZE = 64, + BLOCK_SIZE = 256, + ELEMENTS_PER_WORK_ITEM = (BLOCK_SIZE/WG_SIZE), + BITS_PER_PASS = 4, + NUM_BUCKET=(1<& keysIn, btOpenCLArray& keysOut, btOpenCLArray& valuesIn, + btOpenCLArray& valuesOut, int n, int sortBits = 32); + + ///keys only + void execute(btOpenCLArray& keysInOut, int sortBits = 32 ); + + void execute(btOpenCLArray& keyValuesInOut, int sortBits = 32 ); + void executeHost(btOpenCLArray& keyValuesInOut, int sortBits = 32); + void executeHost(btAlignedObjectArray& keyValuesInOut, int sortBits = 32); + +}; +#endif //BT_RADIXSORT32_H + diff --git a/opencl/parallel_primitives/host/btScalar.h b/opencl/parallel_primitives/host/btScalar.h new file mode 100644 index 000000000..3a94054e9 --- /dev/null +++ b/opencl/parallel_primitives/host/btScalar.h @@ -0,0 +1,660 @@ +/* +Copyright (c) 2003-2009 Erwin Coumans http://bullet.googlecode.com + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + + +#ifndef BT_SCALAR_H +#define BT_SCALAR_H + +#ifdef BT_MANAGED_CODE +//Aligned data types not supported in managed code +#pragma unmanaged +#endif + + +#include +#include //size_t for MSVC 6.0 +#include + +/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/ +#define BT_BULLET_VERSION 281 + +inline int btGetVersion() +{ + return BT_BULLET_VERSION; +} + +#if defined(DEBUG) || defined (_DEBUG) +#define BT_DEBUG +#endif + + +#ifdef _WIN32 + + #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300) + + #define SIMD_FORCE_INLINE inline + #define ATTRIBUTE_ALIGNED16(a) a + #define ATTRIBUTE_ALIGNED64(a) a + #define ATTRIBUTE_ALIGNED128(a) a + #else + //#define BT_HAS_ALIGNED_ALLOCATOR + #pragma warning(disable : 4324) // disable padding warning +// #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning. +// #pragma warning(disable:4996) //Turn off warnings about deprecated C routines +// #pragma warning(disable:4786) // Disable the "debug name too long" warning + + #define SIMD_FORCE_INLINE __forceinline + #define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a + #define ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a + #define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a + #ifdef _XBOX + #define BT_USE_VMX128 + + #include + #define BT_HAVE_NATIVE_FSEL + #define btFsel(a,b,c) __fsel((a),(b),(c)) + #else + +#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION)) + #define BT_USE_SSE + #ifdef BT_USE_SSE + //BT_USE_SSE_IN_API is disabled under Windows by default, because + //it makes it harder to integrate Bullet into your application under Windows + //(structured embedding Bullet structs/classes need to be 16-byte aligned) + //with relatively little performance gain + //If you are not embedded Bullet data in your classes, or make sure that you align those classes on 16-byte boundaries + //you can manually enable this line or set it in the build system for a bit of performance gain (a few percent, dependent on usage) + //#define BT_USE_SSE_IN_API + #endif //BT_USE_SSE + #include +#endif + + #endif//_XBOX + + #endif //__MINGW32__ + +#ifdef BT_DEBUG + #ifdef _MSC_VER + #include + #define btAssert(x) { if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);__debugbreak(); }} + #else//_MSC_VER + #include + #define btAssert assert + #endif//_MSC_VER +#else + #define btAssert(x) +#endif + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) + + #define btLikely(_c) _c + #define btUnlikely(_c) _c + +#else + +#if defined (__CELLOS_LV2__) + #define SIMD_FORCE_INLINE inline __attribute__((always_inline)) + #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) + #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) + #ifndef assert + #include + #endif +#ifdef BT_DEBUG +#ifdef __SPU__ +#include +#define printf spu_printf + #define btAssert(x) {if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}} +#else + #define btAssert assert +#endif + +#else + #define btAssert(x) +#endif + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) + + #define btLikely(_c) _c + #define btUnlikely(_c) _c + +#else + +#ifdef USE_LIBSPE2 + + #define SIMD_FORCE_INLINE __inline + #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) + #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) + #ifndef assert + #include + #endif +#ifdef BT_DEBUG + #define btAssert assert +#else + #define btAssert(x) +#endif + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) + + + #define btLikely(_c) __builtin_expect((_c), 1) + #define btUnlikely(_c) __builtin_expect((_c), 0) + + +#else + //non-windows systems + +#if (defined (__APPLE__) && (!defined (BT_USE_DOUBLE_PRECISION))) + #if defined (__i386__) || defined (__x86_64__) + #define BT_USE_SSE + //BT_USE_SSE_IN_API is enabled on Mac OSX by default, because memory is automatically aligned on 16-byte boundaries + //if apps run into issues, we will disable the next line + #define BT_USE_SSE_IN_API + #ifdef BT_USE_SSE + // include appropriate SSE level + #if defined (__SSE4_1__) + #include + #elif defined (__SSSE3__) + #include + #elif defined (__SSE3__) + #include + #else + #include + #endif + #endif //BT_USE_SSE + #elif defined( __armv7__ ) + #ifdef __clang__ + #define BT_USE_NEON 1 + + #if defined BT_USE_NEON && defined (__clang__) + #include + #endif//BT_USE_NEON + #endif //__clang__ + #endif//__arm__ + + #define SIMD_FORCE_INLINE inline __attribute__ ((always_inline)) +///@todo: check out alignment methods for other platforms/compilers + #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + #define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) + #define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) + #ifndef assert + #include + #endif + + #if defined(DEBUG) || defined (_DEBUG) + #if defined (__i386__) || defined (__x86_64__) + #include + #define btAssert(x)\ + {\ + if(!(x))\ + {\ + printf("Assert %s in line %d, file %s\n",#x, __LINE__, __FILE__);\ + asm volatile ("int3");\ + }\ + } + #else//defined (__i386__) || defined (__x86_64__) + #define btAssert assert + #endif//defined (__i386__) || defined (__x86_64__) + #else//defined(DEBUG) || defined (_DEBUG) + #define btAssert(x) + #endif//defined(DEBUG) || defined (_DEBUG) + + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) + #define btLikely(_c) _c + #define btUnlikely(_c) _c + +#else + + #define SIMD_FORCE_INLINE inline + ///@todo: check out alignment methods for other platforms/compilers + ///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + ///#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) + ///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) + #define ATTRIBUTE_ALIGNED16(a) a + #define ATTRIBUTE_ALIGNED64(a) a + #define ATTRIBUTE_ALIGNED128(a) a + #ifndef assert + #include + #endif + +#if defined(DEBUG) || defined (_DEBUG) + #define btAssert assert +#else + #define btAssert(x) +#endif + + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) + #define btLikely(_c) _c + #define btUnlikely(_c) _c +#endif //__APPLE__ + +#endif // LIBSPE2 + +#endif //__CELLOS_LV2__ +#endif + + +///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision. +#if defined(BT_USE_DOUBLE_PRECISION) +typedef double btScalar; +//this number could be bigger in double precision +#define BT_LARGE_FLOAT 1e30 +#else +typedef float btScalar; +//keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX +#define BT_LARGE_FLOAT 1e18f +#endif + +#ifdef BT_USE_SSE +typedef __m128 btSimdFloat4; +#endif//BT_USE_SSE + +#if defined BT_USE_SSE_IN_API && defined (BT_USE_SSE) +#ifdef _WIN32 + +#ifndef BT_NAN +static int btNanMask = 0x7F800001; +#define BT_NAN (*(float*)&btNanMask) +#endif + +#ifndef BT_INFINITY +static int btInfinityMask = 0x7F800000; +#define BT_INFINITY (*(float*)&btInfinityMask) +#endif + +inline __m128 operator + (const __m128 A, const __m128 B) +{ + return _mm_add_ps(A, B); +} + +inline __m128 operator - (const __m128 A, const __m128 B) +{ + return _mm_sub_ps(A, B); +} + +inline __m128 operator * (const __m128 A, const __m128 B) +{ + return _mm_mul_ps(A, B); +} + +#define btCastfTo128i(a) (_mm_castps_si128(a)) +#define btCastfTo128d(a) (_mm_castps_pd(a)) +#define btCastiTo128f(a) (_mm_castsi128_ps(a)) +#define btCastdTo128f(a) (_mm_castpd_ps(a)) +#define btCastdTo128i(a) (_mm_castpd_si128(a)) +#define btAssign128(r0,r1,r2,r3) _mm_setr_ps(r0,r1,r2,r3) + +#else//_WIN32 + +#define btCastfTo128i(a) ((__m128i)(a)) +#define btCastfTo128d(a) ((__m128d)(a)) +#define btCastiTo128f(a) ((__m128) (a)) +#define btCastdTo128f(a) ((__m128) (a)) +#define btCastdTo128i(a) ((__m128i)(a)) +#define btAssign128(r0,r1,r2,r3) (__m128){r0,r1,r2,r3} +#define BT_INFINITY INFINITY +#define BT_NAN NAN +#endif//_WIN32 +#endif //BT_USE_SSE_IN_API + +#ifdef BT_USE_NEON +#include + +typedef float32x4_t btSimdFloat4; +#define BT_INFINITY INFINITY +#define BT_NAN NAN +#define btAssign128(r0,r1,r2,r3) (float32x4_t){r0,r1,r2,r3} +#endif + + + + + +#define BT_DECLARE_ALIGNED_ALLOCATOR() \ + SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes,16); } \ + SIMD_FORCE_INLINE void operator delete(void* ptr) { btAlignedFree(ptr); } \ + SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \ + SIMD_FORCE_INLINE void operator delete(void*, void*) { } \ + SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes,16); } \ + SIMD_FORCE_INLINE void operator delete[](void* ptr) { btAlignedFree(ptr); } \ + SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr) { return ptr; } \ + SIMD_FORCE_INLINE void operator delete[](void*, void*) { } \ + + + +#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS) + +SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); } +SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); } +SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); } +SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); } +SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); } +SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { if (xbtScalar(1)) x=btScalar(1); return acos(x); } +SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { if (xbtScalar(1)) x=btScalar(1); return asin(x); } +SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); } +SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); } +SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); } +SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); } +SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); } +SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmod(x,y); } + +#else + +SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) +{ +#ifdef USE_APPROXIMATION + double x, z, tempf; + unsigned long *tfptr = ((unsigned long *)&tempf) + 1; + + tempf = y; + *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */ + x = tempf; + z = y*btScalar(0.5); + x = (btScalar(1.5)*x)-(x*x)*(x*z); /* iteration formula */ + x = (btScalar(1.5)*x)-(x*x)*(x*z); + x = (btScalar(1.5)*x)-(x*x)*(x*z); + x = (btScalar(1.5)*x)-(x*x)*(x*z); + x = (btScalar(1.5)*x)-(x*x)*(x*z); + return x*y; +#else + return sqrtf(y); +#endif +} +SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); } +SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); } +SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); } +SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); } +SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { + if (xbtScalar(1)) + x=btScalar(1); + return acosf(x); +} +SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { + if (xbtScalar(1)) + x=btScalar(1); + return asinf(x); +} +SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); } +SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); } +SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); } +SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); } +SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); } +SIMD_FORCE_INLINE btScalar btFmod(btScalar x,btScalar y) { return fmodf(x,y); } + +#endif + +#define SIMD_2_PI btScalar(6.283185307179586232) +#define SIMD_PI (SIMD_2_PI * btScalar(0.5)) +#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25)) +#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0)) +#define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI) +#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490) + +#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x)))) /* reciprocal square root */ + + +#ifdef BT_USE_DOUBLE_PRECISION +#define SIMD_EPSILON DBL_EPSILON +#define SIMD_INFINITY DBL_MAX +#else +#define SIMD_EPSILON FLT_EPSILON +#define SIMD_INFINITY FLT_MAX +#endif + +SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) +{ + btScalar coeff_1 = SIMD_PI / 4.0f; + btScalar coeff_2 = 3.0f * coeff_1; + btScalar abs_y = btFabs(y); + btScalar angle; + if (x >= 0.0f) { + btScalar r = (x - abs_y) / (x + abs_y); + angle = coeff_1 - coeff_1 * r; + } else { + btScalar r = (x + abs_y) / (abs_y - x); + angle = coeff_2 - coeff_1 * r; + } + return (y < 0.0f) ? -angle : angle; +} + +SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; } + +SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps) { + return (((a) <= eps) && !((a) < -eps)); +} +SIMD_FORCE_INLINE bool btGreaterEqual (btScalar a, btScalar eps) { + return (!((a) <= eps)); +} + + +SIMD_FORCE_INLINE int btIsNegative(btScalar x) { + return x < btScalar(0.0) ? 1 : 0; +} + +SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; } +SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; } + +#define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name + +#ifndef btFsel +SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c) +{ + return a >= 0 ? b : c; +} +#endif +#define btFsels(a,b,c) (btScalar)btFsel(a,b,c) + + +SIMD_FORCE_INLINE bool btMachineIsLittleEndian() +{ + long int i = 1; + const char *p = (const char *) &i; + if (p[0] == 1) // Lowest address contains the least significant byte + return true; + else + return false; +} + + + +///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360 +///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html +SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) +{ + // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero + // Rely on positive value or'ed with its negative having sign bit on + // and zero value or'ed with its negative (which is still zero) having sign bit off + // Use arithmetic shift right, shifting the sign bit through all 32 bits + unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); + unsigned testEqz = ~testNz; + return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); +} +SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero) +{ + unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); + unsigned testEqz = ~testNz; + return static_cast((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); +} +SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero) +{ +#ifdef BT_HAVE_NATIVE_FSEL + return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero); +#else + return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; +#endif +} + +template SIMD_FORCE_INLINE void btSwap(T& a, T& b) +{ + T tmp = a; + a = b; + b = tmp; +} + + +//PCK: endian swapping functions +SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val) +{ + return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); +} + +SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val) +{ + return static_cast(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)); +} + +SIMD_FORCE_INLINE unsigned btSwapEndian(int val) +{ + return btSwapEndian((unsigned)val); +} + +SIMD_FORCE_INLINE unsigned short btSwapEndian(short val) +{ + return btSwapEndian((unsigned short) val); +} + +///btSwapFloat uses using char pointers to swap the endianness +////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values +///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754. +///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception. +///In most systems, running user mode code, you wouldn't get an exception, but instead the hardware/os/runtime will 'fix' the number for you. +///so instead of returning a float/double, we return integer/long long integer +SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d) +{ + unsigned int a = 0; + unsigned char *dst = (unsigned char *)&a; + unsigned char *src = (unsigned char *)&d; + + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; + return a; +} + +// unswap using char pointers +SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) +{ + float d = 0.0f; + unsigned char *src = (unsigned char *)&a; + unsigned char *dst = (unsigned char *)&d; + + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; + + return d; +} + + +// swap using char pointers +SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char* dst) +{ + unsigned char *src = (unsigned char *)&d; + + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; + +} + +// unswap using char pointers +SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) +{ + double d = 0.0; + unsigned char *dst = (unsigned char *)&d; + + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; + + return d; +} + +// returns normalized value in range [-SIMD_PI, SIMD_PI] +SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians) +{ + angleInRadians = btFmod(angleInRadians, SIMD_2_PI); + if(angleInRadians < -SIMD_PI) + { + return angleInRadians + SIMD_2_PI; + } + else if(angleInRadians > SIMD_PI) + { + return angleInRadians - SIMD_2_PI; + } + else + { + return angleInRadians; + } +} + +///rudimentary class to provide type info +struct btTypedObject +{ + btTypedObject(int objectType) + :m_objectType(objectType) + { + } + int m_objectType; + inline int getObjectType() const + { + return m_objectType; + } +}; + + + +///align a pointer to the provided alignment, upwards +template T* btAlignPointer(T* unalignedPtr, size_t alignment) +{ + + struct btConvertPointerSizeT + { + union + { + T* ptr; + size_t integer; + }; + }; + btConvertPointerSizeT converter; + + + const size_t bit_mask = ~(alignment - 1); + converter.ptr = unalignedPtr; + converter.integer += alignment-1; + converter.integer &= bit_mask; + return converter.ptr; +} + +#endif //BT_SCALAR_H diff --git a/opencl/parallel_primitives/host/premake4.lua b/opencl/parallel_primitives/host/premake4.lua new file mode 100644 index 000000000..9aaa4692e --- /dev/null +++ b/opencl/parallel_primitives/host/premake4.lua @@ -0,0 +1,26 @@ +function createProject(vendor) + hasCL = findOpenCL(vendor) + + if (hasCL) then + + project ("OpenCL_lib_parallel_primitives_host_" .. vendor) + + initOpenCL(vendor) + + kind "StaticLib" + targetdir "../../../lib" + includedirs { + ".", + } + files { + "**.cpp", + "**.h" + } + + end +end + +createProject("AMD") +createProject("Intel") +createProject("NVIDIA") +createProject("Apple") \ No newline at end of file diff --git a/opencl/parallel_primitives/kernels/BoundSearchKernels.cl b/opencl/parallel_primitives/kernels/BoundSearchKernels.cl new file mode 100644 index 000000000..f3b4a1e8a --- /dev/null +++ b/opencl/parallel_primitives/kernels/BoundSearchKernels.cl @@ -0,0 +1,106 @@ +/* +Copyright (c) 2012 Advanced Micro Devices, Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +//Originally written by Takahiro Harada + + +typedef unsigned int u32; +#define GET_GROUP_IDX get_group_id(0) +#define GET_LOCAL_IDX get_local_id(0) +#define GET_GLOBAL_IDX get_global_id(0) +#define GET_GROUP_SIZE get_local_size(0) +#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE) + +typedef struct +{ + u32 m_key; + u32 m_value; +}SortData; + + + +typedef struct +{ + u32 m_nSrc; + u32 m_nDst; + u32 m_padding[2]; +} ConstBuffer; + + + +__attribute__((reqd_work_group_size(64,1,1))) +__kernel +void SearchSortDataLowerKernel(__global SortData* src, __global u32 *dst, + unsigned int nSrc, unsigned int nDst) +{ + int gIdx = GET_GLOBAL_IDX; + + if( gIdx < nSrc ) + { + SortData first; first.m_key = (u32)(-1); first.m_value = (u32)(-1); + SortData end; end.m_key = nDst; end.m_value = nDst; + + SortData iData = (gIdx==0)? first: src[gIdx-1]; + SortData jData = (gIdx==nSrc)? end: src[gIdx]; + + if( iData.m_key != jData.m_key ) + { +// for(u32 k=iData.m_key+1; k<=min(jData.m_key, nDst-1); k++) + u32 k = jData.m_key; + { + dst[k] = gIdx; + } + } + } +} + + +__attribute__((reqd_work_group_size(64,1,1))) +__kernel +void SearchSortDataUpperKernel(__global SortData* src, __global u32 *dst, + unsigned int nSrc, unsigned int nDst) +{ + int gIdx = GET_GLOBAL_IDX+1; + + if( gIdx < nSrc+1 ) + { + SortData first; first.m_key = 0; first.m_value = 0; + SortData end; end.m_key = nDst; end.m_value = nDst; + + SortData iData = src[gIdx-1]; + SortData jData = (gIdx==nSrc)? end: src[gIdx]; + + if( iData.m_key != jData.m_key ) + { + u32 k = iData.m_key; + { + dst[k] = gIdx; + } + } + } +} + +__attribute__((reqd_work_group_size(64,1,1))) +__kernel +void SubtractKernel(__global u32* A, __global u32 *B, __global u32 *C, + unsigned int nSrc, unsigned int nDst) +{ + int gIdx = GET_GLOBAL_IDX; + + + if( gIdx < nDst ) + { + C[gIdx] = A[gIdx] - B[gIdx]; + } +} + diff --git a/opencl/parallel_primitives/kernels/BoundSearchKernelsCL.h b/opencl/parallel_primitives/kernels/BoundSearchKernelsCL.h new file mode 100644 index 000000000..bf802e9fe --- /dev/null +++ b/opencl/parallel_primitives/kernels/BoundSearchKernelsCL.h @@ -0,0 +1,110 @@ +//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project +static const char* boundSearchKernelsCL= \ +"/*\n" +"Copyright (c) 2012 Advanced Micro Devices, Inc. \n" +"\n" +"This software is provided 'as-is', without any express or implied warranty.\n" +"In no event will the authors be held liable for any damages arising from the use of this software.\n" +"Permission is granted to anyone to use this software for any purpose, \n" +"including commercial applications, and to alter it and redistribute it freely, \n" +"subject to the following restrictions:\n" +"\n" +"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" +"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" +"3. This notice may not be removed or altered from any source distribution.\n" +"*/\n" +"//Originally written by Takahiro Harada\n" +"\n" +"\n" +"typedef unsigned int u32;\n" +"#define GET_GROUP_IDX get_group_id(0)\n" +"#define GET_LOCAL_IDX get_local_id(0)\n" +"#define GET_GLOBAL_IDX get_global_id(0)\n" +"#define GET_GROUP_SIZE get_local_size(0)\n" +"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" +"\n" +"typedef struct\n" +"{\n" +" u32 m_key; \n" +" u32 m_value;\n" +"}SortData;\n" +"\n" +"\n" +"\n" +"typedef struct\n" +"{\n" +" u32 m_nSrc;\n" +" u32 m_nDst;\n" +" u32 m_padding[2];\n" +"} ConstBuffer;\n" +"\n" +"\n" +"\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"__kernel\n" +"void SearchSortDataLowerKernel(__global SortData* src, __global u32 *dst, \n" +" unsigned int nSrc, unsigned int nDst)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +"\n" +" if( gIdx < nSrc )\n" +" {\n" +" SortData first; first.m_key = (u32)(-1); first.m_value = (u32)(-1);\n" +" SortData end; end.m_key = nDst; end.m_value = nDst;\n" +"\n" +" SortData iData = (gIdx==0)? first: src[gIdx-1];\n" +" SortData jData = (gIdx==nSrc)? end: src[gIdx];\n" +"\n" +" if( iData.m_key != jData.m_key )\n" +" {\n" +"// for(u32 k=iData.m_key+1; k<=min(jData.m_key, nDst-1); k++)\n" +" u32 k = jData.m_key;\n" +" {\n" +" dst[k] = gIdx;\n" +" }\n" +" }\n" +" }\n" +"}\n" +"\n" +"\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"__kernel\n" +"void SearchSortDataUpperKernel(__global SortData* src, __global u32 *dst, \n" +" unsigned int nSrc, unsigned int nDst)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX+1;\n" +"\n" +" if( gIdx < nSrc+1 )\n" +" {\n" +" SortData first; first.m_key = 0; first.m_value = 0;\n" +" SortData end; end.m_key = nDst; end.m_value = nDst;\n" +"\n" +" SortData iData = src[gIdx-1];\n" +" SortData jData = (gIdx==nSrc)? end: src[gIdx];\n" +"\n" +" if( iData.m_key != jData.m_key )\n" +" {\n" +" u32 k = iData.m_key;\n" +" {\n" +" dst[k] = gIdx;\n" +" }\n" +" }\n" +" }\n" +"}\n" +"\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"__kernel\n" +"void SubtractKernel(__global u32* A, __global u32 *B, __global u32 *C, \n" +" unsigned int nSrc, unsigned int nDst)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +" \n" +"\n" +" if( gIdx < nDst )\n" +" {\n" +" C[gIdx] = A[gIdx] - B[gIdx];\n" +" }\n" +"}\n" +"\n" +"\n" +; diff --git a/opencl/parallel_primitives/kernels/CopyKernels.cl b/opencl/parallel_primitives/kernels/CopyKernels.cl new file mode 100644 index 000000000..2eee5752e --- /dev/null +++ b/opencl/parallel_primitives/kernels/CopyKernels.cl @@ -0,0 +1,128 @@ +/* +Copyright (c) 2012 Advanced Micro Devices, Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +//Originally written by Takahiro Harada + +#pragma OPENCL EXTENSION cl_amd_printf : enable +#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable + +typedef unsigned int u32; +#define GET_GROUP_IDX get_group_id(0) +#define GET_LOCAL_IDX get_local_id(0) +#define GET_GLOBAL_IDX get_global_id(0) +#define GET_GROUP_SIZE get_local_size(0) +#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE) +#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE) +#define AtomInc(x) atom_inc(&(x)) +#define AtomInc1(x, out) out = atom_inc(&(x)) + +#define make_uint4 (uint4) +#define make_uint2 (uint2) +#define make_int2 (int2) + +typedef struct +{ + int m_n; + int m_padding[3]; +} ConstBuffer; + + + +__kernel +__attribute__((reqd_work_group_size(64,1,1))) +void Copy1F4Kernel(__global float4* dst, __global float4* src, + ConstBuffer cb) +{ + int gIdx = GET_GLOBAL_IDX; + + if( gIdx < cb.m_n ) + { + float4 a0 = src[gIdx]; + + dst[ gIdx ] = a0; + } +} + +__kernel +__attribute__((reqd_work_group_size(64,1,1))) +void Copy2F4Kernel(__global float4* dst, __global float4* src, + ConstBuffer cb) +{ + int gIdx = GET_GLOBAL_IDX; + + if( 2*gIdx <= cb.m_n ) + { + float4 a0 = src[gIdx*2+0]; + float4 a1 = src[gIdx*2+1]; + + dst[ gIdx*2+0 ] = a0; + dst[ gIdx*2+1 ] = a1; + } +} + +__kernel +__attribute__((reqd_work_group_size(64,1,1))) +void Copy4F4Kernel(__global float4* dst, __global float4* src, + ConstBuffer cb) +{ + int gIdx = GET_GLOBAL_IDX; + + if( 4*gIdx <= cb.m_n ) + { + int idx0 = gIdx*4+0; + int idx1 = gIdx*4+1; + int idx2 = gIdx*4+2; + int idx3 = gIdx*4+3; + + float4 a0 = src[idx0]; + float4 a1 = src[idx1]; + float4 a2 = src[idx2]; + float4 a3 = src[idx3]; + + dst[ idx0 ] = a0; + dst[ idx1 ] = a1; + dst[ idx2 ] = a2; + dst[ idx3 ] = a3; + } +} + +__kernel +__attribute__((reqd_work_group_size(64,1,1))) +void CopyF1Kernel(__global float* dstF1, __global float* srcF1, + ConstBuffer cb) +{ + int gIdx = GET_GLOBAL_IDX; + + if( gIdx < cb.m_n ) + { + float a0 = srcF1[gIdx]; + + dstF1[ gIdx ] = a0; + } +} + +__kernel +__attribute__((reqd_work_group_size(64,1,1))) +void CopyF2Kernel(__global float2* dstF2, __global float2* srcF2, + ConstBuffer cb) +{ + int gIdx = GET_GLOBAL_IDX; + + if( gIdx < cb.m_n ) + { + float2 a0 = srcF2[gIdx]; + + dstF2[ gIdx ] = a0; + } +} + diff --git a/opencl/parallel_primitives/kernels/CopyKernelsCL.h b/opencl/parallel_primitives/kernels/CopyKernelsCL.h new file mode 100644 index 000000000..e5670e3cd --- /dev/null +++ b/opencl/parallel_primitives/kernels/CopyKernelsCL.h @@ -0,0 +1,132 @@ +//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project +static const char* copyKernelsCL= \ +"/*\n" +"Copyright (c) 2012 Advanced Micro Devices, Inc. \n" +"\n" +"This software is provided 'as-is', without any express or implied warranty.\n" +"In no event will the authors be held liable for any damages arising from the use of this software.\n" +"Permission is granted to anyone to use this software for any purpose, \n" +"including commercial applications, and to alter it and redistribute it freely, \n" +"subject to the following restrictions:\n" +"\n" +"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" +"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" +"3. This notice may not be removed or altered from any source distribution.\n" +"*/\n" +"//Originally written by Takahiro Harada\n" +"\n" +"#pragma OPENCL EXTENSION cl_amd_printf : enable\n" +"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" +"\n" +"typedef unsigned int u32;\n" +"#define GET_GROUP_IDX get_group_id(0)\n" +"#define GET_LOCAL_IDX get_local_id(0)\n" +"#define GET_GLOBAL_IDX get_global_id(0)\n" +"#define GET_GROUP_SIZE get_local_size(0)\n" +"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" +"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" +"#define AtomInc(x) atom_inc(&(x))\n" +"#define AtomInc1(x, out) out = atom_inc(&(x))\n" +"\n" +"#define make_uint4 (uint4)\n" +"#define make_uint2 (uint2)\n" +"#define make_int2 (int2)\n" +"\n" +"typedef struct\n" +"{\n" +" int m_n;\n" +" int m_padding[3];\n" +"} ConstBuffer;\n" +"\n" +"\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"void Copy1F4Kernel(__global float4* dst, __global float4* src, \n" +" ConstBuffer cb)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +"\n" +" if( gIdx < cb.m_n )\n" +" {\n" +" float4 a0 = src[gIdx];\n" +"\n" +" dst[ gIdx ] = a0;\n" +" }\n" +"}\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"void Copy2F4Kernel(__global float4* dst, __global float4* src, \n" +" ConstBuffer cb)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +"\n" +" if( 2*gIdx <= cb.m_n )\n" +" {\n" +" float4 a0 = src[gIdx*2+0];\n" +" float4 a1 = src[gIdx*2+1];\n" +"\n" +" dst[ gIdx*2+0 ] = a0;\n" +" dst[ gIdx*2+1 ] = a1;\n" +" }\n" +"}\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"void Copy4F4Kernel(__global float4* dst, __global float4* src, \n" +" ConstBuffer cb)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +"\n" +" if( 4*gIdx <= cb.m_n )\n" +" {\n" +" int idx0 = gIdx*4+0;\n" +" int idx1 = gIdx*4+1;\n" +" int idx2 = gIdx*4+2;\n" +" int idx3 = gIdx*4+3;\n" +"\n" +" float4 a0 = src[idx0];\n" +" float4 a1 = src[idx1];\n" +" float4 a2 = src[idx2];\n" +" float4 a3 = src[idx3];\n" +"\n" +" dst[ idx0 ] = a0;\n" +" dst[ idx1 ] = a1;\n" +" dst[ idx2 ] = a2;\n" +" dst[ idx3 ] = a3;\n" +" }\n" +"}\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"void CopyF1Kernel(__global float* dstF1, __global float* srcF1, \n" +" ConstBuffer cb)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +"\n" +" if( gIdx < cb.m_n )\n" +" {\n" +" float a0 = srcF1[gIdx];\n" +"\n" +" dstF1[ gIdx ] = a0;\n" +" }\n" +"}\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"void CopyF2Kernel(__global float2* dstF2, __global float2* srcF2, \n" +" ConstBuffer cb)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +"\n" +" if( gIdx < cb.m_n )\n" +" {\n" +" float2 a0 = srcF2[gIdx];\n" +"\n" +" dstF2[ gIdx ] = a0;\n" +" }\n" +"}\n" +"\n" +"\n" +; diff --git a/opencl/parallel_primitives/kernels/FillKernels.cl b/opencl/parallel_primitives/kernels/FillKernels.cl new file mode 100644 index 000000000..71c31075d --- /dev/null +++ b/opencl/parallel_primitives/kernels/FillKernels.cl @@ -0,0 +1,107 @@ +/* +Copyright (c) 2012 Advanced Micro Devices, Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +//Originally written by Takahiro Harada + + +#pragma OPENCL EXTENSION cl_amd_printf : enable +#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable + +typedef unsigned int u32; +#define GET_GROUP_IDX get_group_id(0) +#define GET_LOCAL_IDX get_local_id(0) +#define GET_GLOBAL_IDX get_global_id(0) +#define GET_GROUP_SIZE get_local_size(0) +#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE) +#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE) +#define AtomInc(x) atom_inc(&(x)) +#define AtomInc1(x, out) out = atom_inc(&(x)) + +#define make_uint4 (uint4) +#define make_uint2 (uint2) +#define make_int2 (int2) + +typedef struct +{ + union + { + int4 m_data; + uint4 m_unsignedData; + float m_floatData; + }; + int m_offset; + int m_n; + int m_padding[2]; +} ConstBuffer; + + +__kernel +__attribute__((reqd_work_group_size(64,1,1))) +void FillIntKernel(__global int* dstInt, int num_elements, int value, const int offset) +{ + int gIdx = GET_GLOBAL_IDX; + + if( gIdx < num_elements ) + { + dstInt[ offset+gIdx ] = value; + } +} + +__kernel +__attribute__((reqd_work_group_size(64,1,1))) +void FillFloatKernel(__global float* dstFloat, int num_elements, float value, const int offset) +{ + int gIdx = GET_GLOBAL_IDX; + + if( gIdx < num_elements ) + { + dstFloat[ offset+gIdx ] = value; + } +} + +__kernel +__attribute__((reqd_work_group_size(64,1,1))) +void FillUnsignedIntKernel(__global unsigned int* dstInt, const int num, const unsigned int value, const int offset) +{ + int gIdx = GET_GLOBAL_IDX; + + if( gIdx < num ) + { + dstInt[ offset+gIdx ] = value; + } +} + +__kernel +__attribute__((reqd_work_group_size(64,1,1))) +void FillInt2Kernel(__global int2* dstInt2, const int num, const int2 value, const int offset) +{ + int gIdx = GET_GLOBAL_IDX; + + if( gIdx < num ) + { + dstInt2[ gIdx + offset] = make_int2( value.x, value.y ); + } +} + +__kernel +__attribute__((reqd_work_group_size(64,1,1))) +void FillInt4Kernel(__global int4* dstInt4, const int num, const int4 value, const int offset) +{ + int gIdx = GET_GLOBAL_IDX; + + if( gIdx < num ) + { + dstInt4[ offset+gIdx ] = value; + } +} + diff --git a/opencl/parallel_primitives/kernels/FillKernelsCL.h b/opencl/parallel_primitives/kernels/FillKernelsCL.h new file mode 100644 index 000000000..24eac7b11 --- /dev/null +++ b/opencl/parallel_primitives/kernels/FillKernelsCL.h @@ -0,0 +1,111 @@ +//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project +static const char* fillKernelsCL= \ +"/*\n" +"Copyright (c) 2012 Advanced Micro Devices, Inc. \n" +"\n" +"This software is provided 'as-is', without any express or implied warranty.\n" +"In no event will the authors be held liable for any damages arising from the use of this software.\n" +"Permission is granted to anyone to use this software for any purpose, \n" +"including commercial applications, and to alter it and redistribute it freely, \n" +"subject to the following restrictions:\n" +"\n" +"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" +"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" +"3. This notice may not be removed or altered from any source distribution.\n" +"*/\n" +"//Originally written by Takahiro Harada\n" +"\n" +"\n" +"#pragma OPENCL EXTENSION cl_amd_printf : enable\n" +"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" +"\n" +"typedef unsigned int u32;\n" +"#define GET_GROUP_IDX get_group_id(0)\n" +"#define GET_LOCAL_IDX get_local_id(0)\n" +"#define GET_GLOBAL_IDX get_global_id(0)\n" +"#define GET_GROUP_SIZE get_local_size(0)\n" +"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" +"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" +"#define AtomInc(x) atom_inc(&(x))\n" +"#define AtomInc1(x, out) out = atom_inc(&(x))\n" +"\n" +"#define make_uint4 (uint4)\n" +"#define make_uint2 (uint2)\n" +"#define make_int2 (int2)\n" +"\n" +"typedef struct\n" +"{\n" +" union\n" +" {\n" +" int4 m_data;\n" +" uint4 m_unsignedData;\n" +" float m_floatData;\n" +" };\n" +" int m_offset;\n" +" int m_n;\n" +" int m_padding[2];\n" +"} ConstBuffer;\n" +"\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"void FillIntKernel(__global int* dstInt, int num_elements, int value, const int offset)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +"\n" +" if( gIdx < num_elements )\n" +" {\n" +" dstInt[ offset+gIdx ] = value;\n" +" }\n" +"}\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"void FillFloatKernel(__global float* dstFloat, int num_elements, float value, const int offset)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +"\n" +" if( gIdx < num_elements )\n" +" {\n" +" dstFloat[ offset+gIdx ] = value;\n" +" }\n" +"}\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"void FillUnsignedIntKernel(__global unsigned int* dstInt, const int num, const unsigned int value, const int offset)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +"\n" +" if( gIdx < num )\n" +" {\n" +" dstInt[ offset+gIdx ] = value;\n" +" }\n" +"}\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"void FillInt2Kernel(__global int2* dstInt2, const int num, const int2 value, const int offset)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +"\n" +" if( gIdx < num )\n" +" {\n" +" dstInt2[ gIdx + offset] = make_int2( value.x, value.y );\n" +" }\n" +"}\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(64,1,1)))\n" +"void FillInt4Kernel(__global int4* dstInt4, const int num, const int4 value, const int offset)\n" +"{\n" +" int gIdx = GET_GLOBAL_IDX;\n" +"\n" +" if( gIdx < num )\n" +" {\n" +" dstInt4[ offset+gIdx ] = value;\n" +" }\n" +"}\n" +"\n" +"\n" +; diff --git a/opencl/parallel_primitives/kernels/PrefixScanKernels.cl b/opencl/parallel_primitives/kernels/PrefixScanKernels.cl new file mode 100644 index 000000000..963cc1e48 --- /dev/null +++ b/opencl/parallel_primitives/kernels/PrefixScanKernels.cl @@ -0,0 +1,154 @@ +/* +Copyright (c) 2012 Advanced Micro Devices, Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +//Originally written by Takahiro Harada + + +typedef unsigned int u32; +#define GET_GROUP_IDX get_group_id(0) +#define GET_LOCAL_IDX get_local_id(0) +#define GET_GLOBAL_IDX get_global_id(0) +#define GET_GROUP_SIZE get_local_size(0) +#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE) + +// takahiro end +#define WG_SIZE 128 +#define m_numElems x +#define m_numBlocks y +#define m_numScanBlocks z + +/*typedef struct +{ + uint m_numElems; + uint m_numBlocks; + uint m_numScanBlocks; + uint m_padding[1]; +} ConstBuffer; +*/ + +u32 ScanExclusive(__local u32* data, u32 n, int lIdx, int lSize) +{ + u32 blocksum; + int offset = 1; + for(int nActive=n>>1; nActive>0; nActive>>=1, offset<<=1) + { + GROUP_LDS_BARRIER; + for(int iIdx=lIdx; iIdx>= 1; + for(int nActive=1; nActive>=1 ) + { + GROUP_LDS_BARRIER; + for( int iIdx = lIdx; iIdx>1; nActive>0; nActive>>=1, offset<<=1)\n" +" {\n" +" GROUP_LDS_BARRIER;\n" +" for(int iIdx=lIdx; iIdx>= 1;\n" +" for(int nActive=1; nActive>=1 )\n" +" {\n" +" GROUP_LDS_BARRIER;\n" +" for( int iIdx = lIdx; iIdx 64 ) + { + sorterSharedMemory[idx] += sorterSharedMemory[idx-64]; + GROUP_MEM_FENCE; + } + + sorterSharedMemory[idx-1] += sorterSharedMemory[idx-2]; + GROUP_MEM_FENCE; + } +#else + if( lIdx < 64 ) + { + sorterSharedMemory[idx] += sorterSharedMemory[idx-1]; + GROUP_MEM_FENCE; + sorterSharedMemory[idx] += sorterSharedMemory[idx-2]; + GROUP_MEM_FENCE; + sorterSharedMemory[idx] += sorterSharedMemory[idx-4]; + GROUP_MEM_FENCE; + sorterSharedMemory[idx] += sorterSharedMemory[idx-8]; + GROUP_MEM_FENCE; + sorterSharedMemory[idx] += sorterSharedMemory[idx-16]; + GROUP_MEM_FENCE; + sorterSharedMemory[idx] += sorterSharedMemory[idx-32]; + GROUP_MEM_FENCE; + if( wgSize > 64 ) + { + sorterSharedMemory[idx] += sorterSharedMemory[idx-64]; + GROUP_MEM_FENCE; + } + + sorterSharedMemory[idx-1] += sorterSharedMemory[idx-2]; + GROUP_MEM_FENCE; + } +#endif + } + + GROUP_LDS_BARRIER; + + *totalSum = sorterSharedMemory[wgSize*2-1]; + u32 addValue = sorterSharedMemory[lIdx+wgSize-1]; + return addValue; +} + +//__attribute__((reqd_work_group_size(128,1,1))) +uint4 localPrefixSum128V( uint4 pData, uint lIdx, uint* totalSum, __local u32* sorterSharedMemory ) +{ + u32 s4 = prefixScanVectorEx( &pData ); + u32 rank = localPrefixSum( s4, lIdx, totalSum, sorterSharedMemory, 128 ); + return pData + make_uint4( rank, rank, rank, rank ); +} + + +//__attribute__((reqd_work_group_size(64,1,1))) +uint4 localPrefixSum64V( uint4 pData, uint lIdx, uint* totalSum, __local u32* sorterSharedMemory ) +{ + u32 s4 = prefixScanVectorEx( &pData ); + u32 rank = localPrefixSum( s4, lIdx, totalSum, sorterSharedMemory, 64 ); + return pData + make_uint4( rank, rank, rank, rank ); +} + +u32 unpack4Key( u32 key, int keyIdx ){ return (key>>(keyIdx*8)) & 0xff;} + +u32 bit8Scan(u32 v) +{ + return (v<<8) + (v<<16) + (v<<24); +} + +//=== + + + + +#define MY_HISTOGRAM(idx) localHistogramMat[(idx)*WG_SIZE+lIdx] + + +__kernel +__attribute__((reqd_work_group_size(WG_SIZE,1,1))) +void StreamCountKernel( __global u32* gSrc, __global u32* histogramOut, int4 cb ) +{ + __local u32 localHistogramMat[NUM_BUCKET*WG_SIZE]; + + u32 gIdx = GET_GLOBAL_IDX; + u32 lIdx = GET_LOCAL_IDX; + u32 wgIdx = GET_GROUP_IDX; + u32 wgSize = GET_GROUP_SIZE; + const int startBit = cb.m_startBit; + const int n = cb.m_n; + const int nWGs = cb.m_nWGs; + const int nBlocksPerWG = cb.m_nBlocksPerWG; + + for(int i=0; i>startBit) & 0xf; +#if defined(NV_GPU) + MY_HISTOGRAM( localKey )++; +#else + AtomInc( MY_HISTOGRAM( localKey ) ); +#endif + } + } + } + + GROUP_LDS_BARRIER; + + if( lIdx < NUM_BUCKET ) + { + u32 sum = 0; + for(int i=0; i>startBit) & 0xf; +#if defined(NV_GPU) + MY_HISTOGRAM( localKey )++; +#else + AtomInc( MY_HISTOGRAM( localKey ) ); +#endif + } + } + } + + GROUP_LDS_BARRIER; + + if( lIdx < NUM_BUCKET ) + { + u32 sum = 0; + for(int i=0; i>startBit) & mask, (sortData[1]>>startBit) & mask, (sortData[2]>>startBit) & mask, (sortData[3]>>startBit) & mask ); + uint4 prefixSum = SELECT_UINT4( make_uint4(1,1,1,1), make_uint4(0,0,0,0), cmpResult != make_uint4(0,0,0,0) ); + u32 total; + prefixSum = localPrefixSum64V( prefixSum, lIdx, &total, ldsSortData ); + { + uint4 localAddr = make_uint4(lIdx*4+0,lIdx*4+1,lIdx*4+2,lIdx*4+3); + uint4 dstAddr = localAddr - prefixSum + make_uint4( total, total, total, total ); + dstAddr = SELECT_UINT4( prefixSum, dstAddr, cmpResult != make_uint4(0, 0, 0, 0) ); + + GROUP_LDS_BARRIER; + + ldsSortData[dstAddr.x] = sortData[0]; + ldsSortData[dstAddr.y] = sortData[1]; + ldsSortData[dstAddr.z] = sortData[2]; + ldsSortData[dstAddr.w] = sortData[3]; + + GROUP_LDS_BARRIER; + + sortData[0] = ldsSortData[localAddr.x]; + sortData[1] = ldsSortData[localAddr.y]; + sortData[2] = ldsSortData[localAddr.z]; + sortData[3] = ldsSortData[localAddr.w]; + + GROUP_LDS_BARRIER; + } + } +} + +// 2 scan, 2 exchange +void sort4Bits1(u32 sortData[4], int startBit, int lIdx, __local u32* ldsSortData) +{ + for(uint ibit=0; ibit>(startBit+ibit)) & 0x3, + (sortData[1]>>(startBit+ibit)) & 0x3, + (sortData[2]>>(startBit+ibit)) & 0x3, + (sortData[3]>>(startBit+ibit)) & 0x3); + + u32 key4; + u32 sKeyPacked[4] = { 0, 0, 0, 0 }; + { + sKeyPacked[0] |= 1<<(8*b.x); + sKeyPacked[1] |= 1<<(8*b.y); + sKeyPacked[2] |= 1<<(8*b.z); + sKeyPacked[3] |= 1<<(8*b.w); + + key4 = sKeyPacked[0] + sKeyPacked[1] + sKeyPacked[2] + sKeyPacked[3]; + } + + u32 rankPacked; + u32 sumPacked; + { + rankPacked = localPrefixSum( key4, lIdx, &sumPacked, ldsSortData, WG_SIZE ); + } + + GROUP_LDS_BARRIER; + + u32 newOffset[4] = { 0,0,0,0 }; + { + u32 sumScanned = bit8Scan( sumPacked ); + + u32 scannedKeys[4]; + scannedKeys[0] = 1<<(8*b.x); + scannedKeys[1] = 1<<(8*b.y); + scannedKeys[2] = 1<<(8*b.z); + scannedKeys[3] = 1<<(8*b.w); + { // 4 scans at once + u32 sum4 = 0; + for(int ie=0; ie<4; ie++) + { + u32 tmp = scannedKeys[ie]; + scannedKeys[ie] = sum4; + sum4 += tmp; + } + } + + { + u32 sumPlusRank = sumScanned + rankPacked; + { u32 ie = b.x; + scannedKeys[0] += sumPlusRank; + newOffset[0] = unpack4Key( scannedKeys[0], ie ); + } + { u32 ie = b.y; + scannedKeys[1] += sumPlusRank; + newOffset[1] = unpack4Key( scannedKeys[1], ie ); + } + { u32 ie = b.z; + scannedKeys[2] += sumPlusRank; + newOffset[2] = unpack4Key( scannedKeys[2], ie ); + } + { u32 ie = b.w; + scannedKeys[3] += sumPlusRank; + newOffset[3] = unpack4Key( scannedKeys[3], ie ); + } + } + } + + + GROUP_LDS_BARRIER; + + { + ldsSortData[newOffset[0]] = sortData[0]; + ldsSortData[newOffset[1]] = sortData[1]; + ldsSortData[newOffset[2]] = sortData[2]; + ldsSortData[newOffset[3]] = sortData[3]; + + GROUP_LDS_BARRIER; + + u32 dstAddr = 4*lIdx; + sortData[0] = ldsSortData[dstAddr+0]; + sortData[1] = ldsSortData[dstAddr+1]; + sortData[2] = ldsSortData[dstAddr+2]; + sortData[3] = ldsSortData[dstAddr+3]; + + GROUP_LDS_BARRIER; + } + } +} + +#define SET_HISTOGRAM(setIdx, key) ldsSortData[(setIdx)*NUM_BUCKET+key] + +__kernel +__attribute__((reqd_work_group_size(WG_SIZE,1,1))) +void SortAndScatterKernel( __global const u32* restrict gSrc, __global const u32* rHistogram, __global u32* restrict gDst, int4 cb ) +{ + __local u32 ldsSortData[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16]; + __local u32 localHistogramToCarry[NUM_BUCKET]; + __local u32 localHistogram[NUM_BUCKET*2]; + + u32 gIdx = GET_GLOBAL_IDX; + u32 lIdx = GET_LOCAL_IDX; + u32 wgIdx = GET_GROUP_IDX; + u32 wgSize = GET_GROUP_SIZE; + + const int n = cb.m_n; + const int nWGs = cb.m_nWGs; + const int startBit = cb.m_startBit; + const int nBlocksPerWG = cb.m_nBlocksPerWG; + + if( lIdx < (NUM_BUCKET) ) + { + localHistogramToCarry[lIdx] = rHistogram[lIdx*nWGs + wgIdx]; + } + + GROUP_LDS_BARRIER; + + const int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE; + + int nBlocks = n/blockSize - nBlocksPerWG*wgIdx; + + int addr = blockSize*nBlocksPerWG*wgIdx + ELEMENTS_PER_WORK_ITEM*lIdx; + + for(int iblock=0; iblock>startBit) & 0xf; + + { // create histogram + u32 setIdx = lIdx/16; + if( lIdx < NUM_BUCKET ) + { + localHistogram[lIdx] = 0; + } + ldsSortData[lIdx] = 0; + GROUP_LDS_BARRIER; + + for(int i=0; i>(startBit+ibit)) & 0x3, + (sortData[1]>>(startBit+ibit)) & 0x3, + (sortData[2]>>(startBit+ibit)) & 0x3, + (sortData[3]>>(startBit+ibit)) & 0x3); + + u32 key4; + u32 sKeyPacked[4] = { 0, 0, 0, 0 }; + { + sKeyPacked[0] |= 1<<(8*b.x); + sKeyPacked[1] |= 1<<(8*b.y); + sKeyPacked[2] |= 1<<(8*b.z); + sKeyPacked[3] |= 1<<(8*b.w); + + key4 = sKeyPacked[0] + sKeyPacked[1] + sKeyPacked[2] + sKeyPacked[3]; + } + + u32 rankPacked; + u32 sumPacked; + { + rankPacked = localPrefixSum( key4, lIdx, &sumPacked, ldsSortData, WG_SIZE ); + } + + GROUP_LDS_BARRIER; + + u32 newOffset[4] = { 0,0,0,0 }; + { + u32 sumScanned = bit8Scan( sumPacked ); + + u32 scannedKeys[4]; + scannedKeys[0] = 1<<(8*b.x); + scannedKeys[1] = 1<<(8*b.y); + scannedKeys[2] = 1<<(8*b.z); + scannedKeys[3] = 1<<(8*b.w); + { // 4 scans at once + u32 sum4 = 0; + for(int ie=0; ie<4; ie++) + { + u32 tmp = scannedKeys[ie]; + scannedKeys[ie] = sum4; + sum4 += tmp; + } + } + + { + u32 sumPlusRank = sumScanned + rankPacked; + { u32 ie = b.x; + scannedKeys[0] += sumPlusRank; + newOffset[0] = unpack4Key( scannedKeys[0], ie ); + } + { u32 ie = b.y; + scannedKeys[1] += sumPlusRank; + newOffset[1] = unpack4Key( scannedKeys[1], ie ); + } + { u32 ie = b.z; + scannedKeys[2] += sumPlusRank; + newOffset[2] = unpack4Key( scannedKeys[2], ie ); + } + { u32 ie = b.w; + scannedKeys[3] += sumPlusRank; + newOffset[3] = unpack4Key( scannedKeys[3], ie ); + } + } + } + + + GROUP_LDS_BARRIER; + + { + ldsSortData[newOffset[0]] = sortData[0]; + ldsSortData[newOffset[1]] = sortData[1]; + ldsSortData[newOffset[2]] = sortData[2]; + ldsSortData[newOffset[3]] = sortData[3]; + + ldsSortVal[newOffset[0]] = sortVal[0]; + ldsSortVal[newOffset[1]] = sortVal[1]; + ldsSortVal[newOffset[2]] = sortVal[2]; + ldsSortVal[newOffset[3]] = sortVal[3]; + + GROUP_LDS_BARRIER; + + u32 dstAddr = 4*lIdx; + sortData[0] = ldsSortData[dstAddr+0]; + sortData[1] = ldsSortData[dstAddr+1]; + sortData[2] = ldsSortData[dstAddr+2]; + sortData[3] = ldsSortData[dstAddr+3]; + + sortVal[0] = ldsSortVal[dstAddr+0]; + sortVal[1] = ldsSortVal[dstAddr+1]; + sortVal[2] = ldsSortVal[dstAddr+2]; + sortVal[3] = ldsSortVal[dstAddr+3]; + + GROUP_LDS_BARRIER; + } + } +} + + + + +__kernel +__attribute__((reqd_work_group_size(WG_SIZE,1,1))) +void SortAndScatterSortDataKernel( __global const SortDataCL* restrict gSrc, __global const u32* rHistogram, __global SortDataCL* restrict gDst, int4 cb) +{ + __local int ldsSortData[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16]; + __local int ldsSortVal[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16]; + __local u32 localHistogramToCarry[NUM_BUCKET]; + __local u32 localHistogram[NUM_BUCKET*2]; + + u32 gIdx = GET_GLOBAL_IDX; + u32 lIdx = GET_LOCAL_IDX; + u32 wgIdx = GET_GROUP_IDX; + u32 wgSize = GET_GROUP_SIZE; + + const int n = cb.m_n; + const int nWGs = cb.m_nWGs; + const int startBit = cb.m_startBit; + const int nBlocksPerWG = cb.m_nBlocksPerWG; + + if( lIdx < (NUM_BUCKET) ) + { + localHistogramToCarry[lIdx] = rHistogram[lIdx*nWGs + wgIdx]; + } + + GROUP_LDS_BARRIER; + + + const int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE; + + int nBlocks = n/blockSize - nBlocksPerWG*wgIdx; + + int addr = blockSize*nBlocksPerWG*wgIdx + ELEMENTS_PER_WORK_ITEM*lIdx; + + for(int iblock=0; iblock>startBit) & 0xf; + + { // create histogram + u32 setIdx = lIdx/16; + if( lIdx < NUM_BUCKET ) + { + localHistogram[lIdx] = 0; + } + ldsSortData[lIdx] = 0; + GROUP_LDS_BARRIER; + + for(int i=0; i0) + return; + + for (int c=0;c>startBit) & 0xf;//0xf = NUM_TABLES-1 + gDst[rHistogram[tableIdx*nWGs+wgIdx] + counter[tableIdx]] = gSrc[i]; + counter[tableIdx] ++; + } + } + } + } + +} + + +__kernel +__attribute__((reqd_work_group_size(WG_SIZE,1,1))) +void SortAndScatterKernelSerial( __global const u32* restrict gSrc, __global const u32* rHistogram, __global u32* restrict gDst, int4 cb ) +{ + + u32 gIdx = GET_GLOBAL_IDX; + u32 realLocalIdx = GET_LOCAL_IDX; + u32 wgIdx = GET_GROUP_IDX; + u32 wgSize = GET_GROUP_SIZE; + const int startBit = cb.m_startBit; + const int n = cb.m_n; + const int nWGs = cb.m_nWGs; + const int nBlocksPerWG = cb.m_nBlocksPerWG; + + int counter[NUM_BUCKET]; + + if (realLocalIdx>0) + return; + + for (int c=0;c>startBit) & 0xf;//0xf = NUM_TABLES-1 + gDst[rHistogram[tableIdx*nWGs+wgIdx] + counter[tableIdx]] = gSrc[i]; + counter[tableIdx] ++; + } + } + } + } + +} \ No newline at end of file diff --git a/opencl/parallel_primitives/kernels/RadixSort32KernelsCL.h b/opencl/parallel_primitives/kernels/RadixSort32KernelsCL.h new file mode 100644 index 000000000..464829c3b --- /dev/null +++ b/opencl/parallel_primitives/kernels/RadixSort32KernelsCL.h @@ -0,0 +1,1074 @@ +//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project +static const char* radixSort32KernelsCL= \ +"/*\n" +"Bullet Continuous Collision Detection and Physics Library\n" +"Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org\n" +"\n" +"This software is provided 'as-is', without any express or implied warranty.\n" +"In no event will the authors be held liable for any damages arising from the use of this software.\n" +"Permission is granted to anyone to use this software for any purpose, \n" +"including commercial applications, and to alter it and redistribute it freely, \n" +"subject to the following restrictions:\n" +"\n" +"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" +"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" +"3. This notice may not be removed or altered from any source distribution.\n" +"*/\n" +"//Author Takahiro Harada\n" +"\n" +"\n" +"//#pragma OPENCL EXTENSION cl_amd_printf : enable\n" +"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" +"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" +"\n" +"typedef unsigned int u32;\n" +"#define GET_GROUP_IDX get_group_id(0)\n" +"#define GET_LOCAL_IDX get_local_id(0)\n" +"#define GET_GLOBAL_IDX get_global_id(0)\n" +"#define GET_GROUP_SIZE get_local_size(0)\n" +"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" +"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" +"#define AtomInc(x) atom_inc(&(x))\n" +"#define AtomInc1(x, out) out = atom_inc(&(x))\n" +"#define AtomAdd(x, value) atom_add(&(x), value)\n" +"\n" +"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" +"\n" +"\n" +"#define make_uint4 (uint4)\n" +"#define make_uint2 (uint2)\n" +"#define make_int2 (int2)\n" +"\n" +"#define WG_SIZE 64\n" +"#define ELEMENTS_PER_WORK_ITEM (256/WG_SIZE)\n" +"#define BITS_PER_PASS 4\n" +"#define NUM_BUCKET (1< 64 )\n" +" {\n" +" sorterSharedMemory[idx] += sorterSharedMemory[idx-64];\n" +" GROUP_MEM_FENCE;\n" +" }\n" +"\n" +" sorterSharedMemory[idx-1] += sorterSharedMemory[idx-2];\n" +" GROUP_MEM_FENCE;\n" +" }\n" +"#else\n" +" if( lIdx < 64 )\n" +" {\n" +" sorterSharedMemory[idx] += sorterSharedMemory[idx-1];\n" +" GROUP_MEM_FENCE;\n" +" sorterSharedMemory[idx] += sorterSharedMemory[idx-2]; \n" +" GROUP_MEM_FENCE;\n" +" sorterSharedMemory[idx] += sorterSharedMemory[idx-4];\n" +" GROUP_MEM_FENCE;\n" +" sorterSharedMemory[idx] += sorterSharedMemory[idx-8];\n" +" GROUP_MEM_FENCE;\n" +" sorterSharedMemory[idx] += sorterSharedMemory[idx-16];\n" +" GROUP_MEM_FENCE;\n" +" sorterSharedMemory[idx] += sorterSharedMemory[idx-32];\n" +" GROUP_MEM_FENCE;\n" +" if( wgSize > 64 )\n" +" {\n" +" sorterSharedMemory[idx] += sorterSharedMemory[idx-64];\n" +" GROUP_MEM_FENCE;\n" +" }\n" +"\n" +" sorterSharedMemory[idx-1] += sorterSharedMemory[idx-2];\n" +" GROUP_MEM_FENCE;\n" +" }\n" +"#endif\n" +" }\n" +"\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" *totalSum = sorterSharedMemory[wgSize*2-1];\n" +" u32 addValue = sorterSharedMemory[lIdx+wgSize-1];\n" +" return addValue;\n" +"}\n" +"\n" +"//__attribute__((reqd_work_group_size(128,1,1)))\n" +"uint4 localPrefixSum128V( uint4 pData, uint lIdx, uint* totalSum, __local u32* sorterSharedMemory )\n" +"{\n" +" u32 s4 = prefixScanVectorEx( &pData );\n" +" u32 rank = localPrefixSum( s4, lIdx, totalSum, sorterSharedMemory, 128 );\n" +" return pData + make_uint4( rank, rank, rank, rank );\n" +"}\n" +"\n" +"\n" +"//__attribute__((reqd_work_group_size(64,1,1)))\n" +"uint4 localPrefixSum64V( uint4 pData, uint lIdx, uint* totalSum, __local u32* sorterSharedMemory )\n" +"{\n" +" u32 s4 = prefixScanVectorEx( &pData );\n" +" u32 rank = localPrefixSum( s4, lIdx, totalSum, sorterSharedMemory, 64 );\n" +" return pData + make_uint4( rank, rank, rank, rank );\n" +"}\n" +"\n" +"u32 unpack4Key( u32 key, int keyIdx ){ return (key>>(keyIdx*8)) & 0xff;}\n" +"\n" +"u32 bit8Scan(u32 v)\n" +"{\n" +" return (v<<8) + (v<<16) + (v<<24);\n" +"}\n" +"\n" +"//===\n" +"\n" +"\n" +"\n" +"\n" +"#define MY_HISTOGRAM(idx) localHistogramMat[(idx)*WG_SIZE+lIdx]\n" +"\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" +"void StreamCountKernel( __global u32* gSrc, __global u32* histogramOut, int4 cb )\n" +"{\n" +" __local u32 localHistogramMat[NUM_BUCKET*WG_SIZE];\n" +"\n" +" u32 gIdx = GET_GLOBAL_IDX;\n" +" u32 lIdx = GET_LOCAL_IDX;\n" +" u32 wgIdx = GET_GROUP_IDX;\n" +" u32 wgSize = GET_GROUP_SIZE;\n" +" const int startBit = cb.m_startBit;\n" +" const int n = cb.m_n;\n" +" const int nWGs = cb.m_nWGs;\n" +" const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" +"\n" +" for(int i=0; i>startBit) & 0xf;\n" +"#if defined(NV_GPU)\n" +" MY_HISTOGRAM( localKey )++;\n" +"#else\n" +" AtomInc( MY_HISTOGRAM( localKey ) );\n" +"#endif\n" +" }\n" +" }\n" +" }\n" +"\n" +" GROUP_LDS_BARRIER;\n" +" \n" +" if( lIdx < NUM_BUCKET )\n" +" {\n" +" u32 sum = 0;\n" +" for(int i=0; i>startBit) & 0xf;\n" +"#if defined(NV_GPU)\n" +" MY_HISTOGRAM( localKey )++;\n" +"#else\n" +" AtomInc( MY_HISTOGRAM( localKey ) );\n" +"#endif\n" +" }\n" +" }\n" +" }\n" +"\n" +" GROUP_LDS_BARRIER;\n" +" \n" +" if( lIdx < NUM_BUCKET )\n" +" {\n" +" u32 sum = 0;\n" +" for(int i=0; i>startBit) & mask, (sortData[1]>>startBit) & mask, (sortData[2]>>startBit) & mask, (sortData[3]>>startBit) & mask );\n" +" uint4 prefixSum = SELECT_UINT4( make_uint4(1,1,1,1), make_uint4(0,0,0,0), cmpResult != make_uint4(0,0,0,0) );\n" +" u32 total;\n" +" prefixSum = localPrefixSum64V( prefixSum, lIdx, &total, ldsSortData );\n" +" {\n" +" uint4 localAddr = make_uint4(lIdx*4+0,lIdx*4+1,lIdx*4+2,lIdx*4+3);\n" +" uint4 dstAddr = localAddr - prefixSum + make_uint4( total, total, total, total );\n" +" dstAddr = SELECT_UINT4( prefixSum, dstAddr, cmpResult != make_uint4(0, 0, 0, 0) );\n" +"\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" ldsSortData[dstAddr.x] = sortData[0];\n" +" ldsSortData[dstAddr.y] = sortData[1];\n" +" ldsSortData[dstAddr.z] = sortData[2];\n" +" ldsSortData[dstAddr.w] = sortData[3];\n" +"\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" sortData[0] = ldsSortData[localAddr.x];\n" +" sortData[1] = ldsSortData[localAddr.y];\n" +" sortData[2] = ldsSortData[localAddr.z];\n" +" sortData[3] = ldsSortData[localAddr.w];\n" +"\n" +" GROUP_LDS_BARRIER;\n" +" }\n" +" }\n" +"}\n" +"\n" +"// 2 scan, 2 exchange\n" +"void sort4Bits1(u32 sortData[4], int startBit, int lIdx, __local u32* ldsSortData)\n" +"{\n" +" for(uint ibit=0; ibit>(startBit+ibit)) & 0x3, \n" +" (sortData[1]>>(startBit+ibit)) & 0x3, \n" +" (sortData[2]>>(startBit+ibit)) & 0x3, \n" +" (sortData[3]>>(startBit+ibit)) & 0x3);\n" +"\n" +" u32 key4;\n" +" u32 sKeyPacked[4] = { 0, 0, 0, 0 };\n" +" {\n" +" sKeyPacked[0] |= 1<<(8*b.x);\n" +" sKeyPacked[1] |= 1<<(8*b.y);\n" +" sKeyPacked[2] |= 1<<(8*b.z);\n" +" sKeyPacked[3] |= 1<<(8*b.w);\n" +"\n" +" key4 = sKeyPacked[0] + sKeyPacked[1] + sKeyPacked[2] + sKeyPacked[3];\n" +" }\n" +"\n" +" u32 rankPacked;\n" +" u32 sumPacked;\n" +" {\n" +" rankPacked = localPrefixSum( key4, lIdx, &sumPacked, ldsSortData, WG_SIZE );\n" +" }\n" +"\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" u32 newOffset[4] = { 0,0,0,0 };\n" +" {\n" +" u32 sumScanned = bit8Scan( sumPacked );\n" +"\n" +" u32 scannedKeys[4];\n" +" scannedKeys[0] = 1<<(8*b.x);\n" +" scannedKeys[1] = 1<<(8*b.y);\n" +" scannedKeys[2] = 1<<(8*b.z);\n" +" scannedKeys[3] = 1<<(8*b.w);\n" +" { // 4 scans at once\n" +" u32 sum4 = 0;\n" +" for(int ie=0; ie<4; ie++)\n" +" {\n" +" u32 tmp = scannedKeys[ie];\n" +" scannedKeys[ie] = sum4;\n" +" sum4 += tmp;\n" +" }\n" +" }\n" +"\n" +" {\n" +" u32 sumPlusRank = sumScanned + rankPacked;\n" +" { u32 ie = b.x;\n" +" scannedKeys[0] += sumPlusRank;\n" +" newOffset[0] = unpack4Key( scannedKeys[0], ie );\n" +" }\n" +" { u32 ie = b.y;\n" +" scannedKeys[1] += sumPlusRank;\n" +" newOffset[1] = unpack4Key( scannedKeys[1], ie );\n" +" }\n" +" { u32 ie = b.z;\n" +" scannedKeys[2] += sumPlusRank;\n" +" newOffset[2] = unpack4Key( scannedKeys[2], ie );\n" +" }\n" +" { u32 ie = b.w;\n" +" scannedKeys[3] += sumPlusRank;\n" +" newOffset[3] = unpack4Key( scannedKeys[3], ie );\n" +" }\n" +" }\n" +" }\n" +"\n" +"\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" {\n" +" ldsSortData[newOffset[0]] = sortData[0];\n" +" ldsSortData[newOffset[1]] = sortData[1];\n" +" ldsSortData[newOffset[2]] = sortData[2];\n" +" ldsSortData[newOffset[3]] = sortData[3];\n" +"\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" u32 dstAddr = 4*lIdx;\n" +" sortData[0] = ldsSortData[dstAddr+0];\n" +" sortData[1] = ldsSortData[dstAddr+1];\n" +" sortData[2] = ldsSortData[dstAddr+2];\n" +" sortData[3] = ldsSortData[dstAddr+3];\n" +"\n" +" GROUP_LDS_BARRIER;\n" +" }\n" +" }\n" +"}\n" +"\n" +"#define SET_HISTOGRAM(setIdx, key) ldsSortData[(setIdx)*NUM_BUCKET+key]\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" +"void SortAndScatterKernel( __global const u32* restrict gSrc, __global const u32* rHistogram, __global u32* restrict gDst, int4 cb )\n" +"{\n" +" __local u32 ldsSortData[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16];\n" +" __local u32 localHistogramToCarry[NUM_BUCKET];\n" +" __local u32 localHistogram[NUM_BUCKET*2];\n" +"\n" +" u32 gIdx = GET_GLOBAL_IDX;\n" +" u32 lIdx = GET_LOCAL_IDX;\n" +" u32 wgIdx = GET_GROUP_IDX;\n" +" u32 wgSize = GET_GROUP_SIZE;\n" +"\n" +" const int n = cb.m_n;\n" +" const int nWGs = cb.m_nWGs;\n" +" const int startBit = cb.m_startBit;\n" +" const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" +"\n" +" if( lIdx < (NUM_BUCKET) )\n" +" {\n" +" localHistogramToCarry[lIdx] = rHistogram[lIdx*nWGs + wgIdx];\n" +" }\n" +"\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" const int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE;\n" +"\n" +" int nBlocks = n/blockSize - nBlocksPerWG*wgIdx;\n" +"\n" +" int addr = blockSize*nBlocksPerWG*wgIdx + ELEMENTS_PER_WORK_ITEM*lIdx;\n" +"\n" +" for(int iblock=0; iblock>startBit) & 0xf;\n" +"\n" +" { // create histogram\n" +" u32 setIdx = lIdx/16;\n" +" if( lIdx < NUM_BUCKET )\n" +" {\n" +" localHistogram[lIdx] = 0;\n" +" }\n" +" ldsSortData[lIdx] = 0;\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" for(int i=0; i>(startBit+ibit)) & 0x3, \n" +" (sortData[1]>>(startBit+ibit)) & 0x3, \n" +" (sortData[2]>>(startBit+ibit)) & 0x3, \n" +" (sortData[3]>>(startBit+ibit)) & 0x3);\n" +"\n" +" u32 key4;\n" +" u32 sKeyPacked[4] = { 0, 0, 0, 0 };\n" +" {\n" +" sKeyPacked[0] |= 1<<(8*b.x);\n" +" sKeyPacked[1] |= 1<<(8*b.y);\n" +" sKeyPacked[2] |= 1<<(8*b.z);\n" +" sKeyPacked[3] |= 1<<(8*b.w);\n" +"\n" +" key4 = sKeyPacked[0] + sKeyPacked[1] + sKeyPacked[2] + sKeyPacked[3];\n" +" }\n" +"\n" +" u32 rankPacked;\n" +" u32 sumPacked;\n" +" {\n" +" rankPacked = localPrefixSum( key4, lIdx, &sumPacked, ldsSortData, WG_SIZE );\n" +" }\n" +"\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" u32 newOffset[4] = { 0,0,0,0 };\n" +" {\n" +" u32 sumScanned = bit8Scan( sumPacked );\n" +"\n" +" u32 scannedKeys[4];\n" +" scannedKeys[0] = 1<<(8*b.x);\n" +" scannedKeys[1] = 1<<(8*b.y);\n" +" scannedKeys[2] = 1<<(8*b.z);\n" +" scannedKeys[3] = 1<<(8*b.w);\n" +" { // 4 scans at once\n" +" u32 sum4 = 0;\n" +" for(int ie=0; ie<4; ie++)\n" +" {\n" +" u32 tmp = scannedKeys[ie];\n" +" scannedKeys[ie] = sum4;\n" +" sum4 += tmp;\n" +" }\n" +" }\n" +"\n" +" {\n" +" u32 sumPlusRank = sumScanned + rankPacked;\n" +" { u32 ie = b.x;\n" +" scannedKeys[0] += sumPlusRank;\n" +" newOffset[0] = unpack4Key( scannedKeys[0], ie );\n" +" }\n" +" { u32 ie = b.y;\n" +" scannedKeys[1] += sumPlusRank;\n" +" newOffset[1] = unpack4Key( scannedKeys[1], ie );\n" +" }\n" +" { u32 ie = b.z;\n" +" scannedKeys[2] += sumPlusRank;\n" +" newOffset[2] = unpack4Key( scannedKeys[2], ie );\n" +" }\n" +" { u32 ie = b.w;\n" +" scannedKeys[3] += sumPlusRank;\n" +" newOffset[3] = unpack4Key( scannedKeys[3], ie );\n" +" }\n" +" }\n" +" }\n" +"\n" +"\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" {\n" +" ldsSortData[newOffset[0]] = sortData[0];\n" +" ldsSortData[newOffset[1]] = sortData[1];\n" +" ldsSortData[newOffset[2]] = sortData[2];\n" +" ldsSortData[newOffset[3]] = sortData[3];\n" +"\n" +" ldsSortVal[newOffset[0]] = sortVal[0];\n" +" ldsSortVal[newOffset[1]] = sortVal[1];\n" +" ldsSortVal[newOffset[2]] = sortVal[2];\n" +" ldsSortVal[newOffset[3]] = sortVal[3];\n" +"\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" u32 dstAddr = 4*lIdx;\n" +" sortData[0] = ldsSortData[dstAddr+0];\n" +" sortData[1] = ldsSortData[dstAddr+1];\n" +" sortData[2] = ldsSortData[dstAddr+2];\n" +" sortData[3] = ldsSortData[dstAddr+3];\n" +"\n" +" sortVal[0] = ldsSortVal[dstAddr+0];\n" +" sortVal[1] = ldsSortVal[dstAddr+1];\n" +" sortVal[2] = ldsSortVal[dstAddr+2];\n" +" sortVal[3] = ldsSortVal[dstAddr+3];\n" +"\n" +" GROUP_LDS_BARRIER;\n" +" }\n" +" }\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" +"void SortAndScatterSortDataKernel( __global const SortDataCL* restrict gSrc, __global const u32* rHistogram, __global SortDataCL* restrict gDst, int4 cb)\n" +"{\n" +" __local int ldsSortData[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16];\n" +" __local int ldsSortVal[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16];\n" +" __local u32 localHistogramToCarry[NUM_BUCKET];\n" +" __local u32 localHistogram[NUM_BUCKET*2];\n" +"\n" +" u32 gIdx = GET_GLOBAL_IDX;\n" +" u32 lIdx = GET_LOCAL_IDX;\n" +" u32 wgIdx = GET_GROUP_IDX;\n" +" u32 wgSize = GET_GROUP_SIZE;\n" +"\n" +" const int n = cb.m_n;\n" +" const int nWGs = cb.m_nWGs;\n" +" const int startBit = cb.m_startBit;\n" +" const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" +"\n" +" if( lIdx < (NUM_BUCKET) )\n" +" {\n" +" localHistogramToCarry[lIdx] = rHistogram[lIdx*nWGs + wgIdx];\n" +" }\n" +"\n" +" GROUP_LDS_BARRIER;\n" +" \n" +"\n" +" const int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE;\n" +"\n" +" int nBlocks = n/blockSize - nBlocksPerWG*wgIdx;\n" +"\n" +" int addr = blockSize*nBlocksPerWG*wgIdx + ELEMENTS_PER_WORK_ITEM*lIdx;\n" +"\n" +" for(int iblock=0; iblock>startBit) & 0xf;\n" +"\n" +" { // create histogram\n" +" u32 setIdx = lIdx/16;\n" +" if( lIdx < NUM_BUCKET )\n" +" {\n" +" localHistogram[lIdx] = 0;\n" +" }\n" +" ldsSortData[lIdx] = 0;\n" +" GROUP_LDS_BARRIER;\n" +"\n" +" for(int i=0; i0)\n" +" return;\n" +" \n" +" for (int c=0;c>startBit) & 0xf;//0xf = NUM_TABLES-1\n" +" gDst[rHistogram[tableIdx*nWGs+wgIdx] + counter[tableIdx]] = gSrc[i];\n" +" counter[tableIdx] ++;\n" +" }\n" +" }\n" +" }\n" +" }\n" +" \n" +"}\n" +"\n" +"\n" +"__kernel\n" +"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" +"void SortAndScatterKernelSerial( __global const u32* restrict gSrc, __global const u32* rHistogram, __global u32* restrict gDst, int4 cb )\n" +"{\n" +" \n" +" u32 gIdx = GET_GLOBAL_IDX;\n" +" u32 realLocalIdx = GET_LOCAL_IDX;\n" +" u32 wgIdx = GET_GROUP_IDX;\n" +" u32 wgSize = GET_GROUP_SIZE;\n" +" const int startBit = cb.m_startBit;\n" +" const int n = cb.m_n;\n" +" const int nWGs = cb.m_nWGs;\n" +" const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" +"\n" +" int counter[NUM_BUCKET];\n" +" \n" +" if (realLocalIdx>0)\n" +" return;\n" +" \n" +" for (int c=0;c>startBit) & 0xf;//0xf = NUM_TABLES-1\n" +" gDst[rHistogram[tableIdx*nWGs+wgIdx] + counter[tableIdx]] = gSrc[i];\n" +" counter[tableIdx] ++;\n" +" }\n" +" }\n" +" }\n" +" }\n" +" \n" +"}\n" +; diff --git a/opencl/parallel_primitives/test/main.cpp b/opencl/parallel_primitives/test/main.cpp new file mode 100644 index 000000000..d659410f1 --- /dev/null +++ b/opencl/parallel_primitives/test/main.cpp @@ -0,0 +1,379 @@ +/* +Copyright (c) 2012 Advanced Micro Devices, Inc. + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + + +#include +#include "../basic_initialize/btOpenCLUtils.h" +#include "../host/btFillCL.h" +#include "../host/btBoundSearchCL.h" +#include "../host/btRadixSort32CL.h" +#include "../host/btPrefixScanCL.h" +#include "../host/CommandLineArgs.h" + +#include "../host/btMinMax.h" +int g_nPassed = 0; +int g_nFailed = 0; +bool g_testFailed = 0; + +#define TEST_INIT g_testFailed = 0; +#define TEST_ASSERT(x) if( !(x) ){g_testFailed = 1;} +#define TEST_REPORT(testName) printf("[%s] %s\n",(g_testFailed)?"X":"O", testName); if(g_testFailed) g_nFailed++; else g_nPassed++; +#define NEXTMULTIPLEOF(num, alignment) (((num)/(alignment) + (((num)%(alignment)==0)?0:1))*(alignment)) + +cl_context g_context=0; +cl_device_id g_device=0; +cl_command_queue g_queue =0; +const char* g_deviceName = 0; + +void initCL(int preferredDeviceIndex, int preferredPlatformIndex) +{ + void* glCtx=0; + void* glDC = 0; + int ciErrNum = 0; + //bound search and radix sort only work on GPU right now (assume 32 or 64 width workgroup without barriers) + + cl_device_type deviceType = CL_DEVICE_TYPE_ALL; + + g_context = btOpenCLUtils::createContextFromType(deviceType, &ciErrNum, 0,0,preferredDeviceIndex, preferredPlatformIndex); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + int numDev = btOpenCLUtils::getNumDevices(g_context); + if (numDev>0) + { + btOpenCLDeviceInfo info; + g_device= btOpenCLUtils::getDevice(g_context,0); + g_queue = clCreateCommandQueue(g_context, g_device, 0, &ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + btOpenCLUtils::printDeviceInfo(g_device); + btOpenCLUtils::getDeviceInfo(g_device,&info); + g_deviceName = info.m_deviceName; + } +} + +void exitCL() +{ + clReleaseCommandQueue(g_queue); + clReleaseContext(g_context); +} + + +inline void fillIntTest() +{ + TEST_INIT; + + btFillCL* fillCL = new btFillCL(g_context,g_device,g_queue); + int maxSize=1024*256; + btOpenCLArray intBuffer(g_context,g_queue,maxSize); + intBuffer.resize(maxSize); + +#define NUM_TESTS 7 + + int dx = maxSize/NUM_TESTS; + for (int iter=0;iterexecute(intBuffer,value,size,offset); + + btAlignedObjectArray hostBuf2; + hostBuf2.resize(size); + fillCL->executeHost(hostBuf2,value,size,offset); + + btAlignedObjectArray hostBuf; + intBuffer.copyToHost(hostBuf); + + for(int i=0; i +__inline +T getRandom(const T& minV, const T& maxV) +{ + float r = (rand()%10000)/10000.f; + T range = maxV - minV; + return (T)(minV + r*range); +} + +struct btSortDataCompare +{ + inline bool operator()(const btSortData& first, const btSortData& second) const + { + return (first.m_key < second.m_key) || (first.m_key==second.m_key && first.m_value < second.m_value); + } +}; + + +void boundSearchTest( ) +{ + TEST_INIT; + + int maxSize = 1024*256; + int bucketSize = 256; + + btOpenCLArray srcCL(g_context,g_queue,maxSize); + btOpenCLArray upperCL(g_context,g_queue,maxSize); + btOpenCLArray lowerCL(g_context,g_queue,maxSize); + + btAlignedObjectArray srcHost; + btAlignedObjectArray upperHost; + btAlignedObjectArray lowerHost; + btAlignedObjectArray upperHostCompare; + btAlignedObjectArray lowerHostCompare; + + btBoundSearchCL* search = new btBoundSearchCL(g_context,g_device,g_queue, maxSize); + + + int dx = maxSize/NUM_TESTS; + for(int iter=0; iterexecute(srcCL,size,upperCL,bucketSize,btBoundSearchCL::BOUND_UPPER); + search->execute(srcCL,size,lowerCL,bucketSize,btBoundSearchCL::BOUND_LOWER); + + search->executeHost(srcHost,size,upperHostCompare,bucketSize,btBoundSearchCL::BOUND_UPPER); + search->executeHost(srcHost,size,lowerHostCompare,bucketSize,btBoundSearchCL::BOUND_LOWER); + + lowerCL.copyToHost(lowerHost); + upperCL.copyToHost(upperHost); + for(int i=0; i buf0Host; + btAlignedObjectArray buf1Host; + + btOpenCLArray buf2CL(g_context,g_queue,maxSize); + btOpenCLArray buf3CL(g_context,g_queue,maxSize); + + + btPrefixScanCL* scan = new btPrefixScanCL(g_context,g_device,g_queue,maxSize); + + int dx = maxSize/NUM_TESTS; + for(int iter=0; iterexecuteHost(buf0Host, buf1Host, size, &sumHost ); + scan->execute( buf2CL, buf3CL, size, &sumGPU ); + + buf3CL.copyToHost(buf0Host); + + TEST_ASSERT( sumHost == sumGPU ); + for(int i=0; i buf0Host; + buf0Host.resize(maxSize); + btAlignedObjectArray buf1Host; + buf1Host.resize(maxSize ); + btOpenCLArray buf2CL(g_context,g_queue,maxSize); + + btRadixSort32CL* sort = new btRadixSort32CL(g_context,g_device,g_queue,maxSize); + + int dx = maxSize/NUM_TESTS; + for(int iter=0; iterexecuteHost( buf0Host); + sort->execute(buf2CL); + + buf2CL.copyToHost(buf1Host); + + for(int i=0; i\n"); + getchar(); +} + diff --git a/opencl/parallel_primitives/test/premake4.lua b/opencl/parallel_primitives/test/premake4.lua new file mode 100644 index 000000000..119087926 --- /dev/null +++ b/opencl/parallel_primitives/test/premake4.lua @@ -0,0 +1,41 @@ +function createProject(vendor) + hasCL = findOpenCL(vendor) + + if (hasCL) then + + project ("OpenCL_primitives_test_" .. vendor) + + initOpenCL(vendor) + + language "C++" + + kind "ConsoleApp" + targetdir "../../../bin" + includedirs {".",".."} + + + files { + "main.cpp", + "../../basic_initialize/btOpenCLInclude.h", + "../../basic_initialize/btOpenCLUtils.cpp", + "../../basic_initialize/btOpenCLUtils.h", + "../host/btFillCL.cpp", + "../host/btFillCL.h", + "../host/btBoundSearchCL.cpp", + "../host/btBoundSearchCL.h", + "../host/btPrefixScanCL.cpp", + "../host/btPrefixScanCL.h", + "../host/btRadixSort32CL.cpp", + "../host/btRadixSort32CL.h", + "../host/btAlignedAllocator.cpp", + "../host/btAlignedAllocator.h", + "../host/btAlignedObjectArray.h", + } + + end +end + +createProject("AMD") +createProject("Intel") +createProject("NVIDIA") +createProject("Apple") \ No newline at end of file diff --git a/opencl/reduce/main.cpp b/opencl/reduce/main.cpp new file mode 100644 index 000000000..f925f6855 --- /dev/null +++ b/opencl/reduce/main.cpp @@ -0,0 +1,116 @@ +///original author: Erwin Coumans +#include "btOpenCLUtils.h" +#include "../parallel_primitives/host/btOpenCLArray.h" +#include "../parallel_primitives/host/btLauncherCL.h" +#include + + +#define MSTRINGIFY(A) #A +const char* kernelString= MSTRINGIFY( +__kernel void ReduceGlobal(__global int* d_in, __global int* d_out, int numElements) +{ + int myId = get_global_id(0); + int tid = get_local_id(0); + + + int ls = get_local_size(0); + for (unsigned int s=ls/2;s>0;s>>=1) + { + if (myId a(ctx,queue); + btOpenCLArray b(ctx,queue); + btAlignedObjectArray hostA; + btAlignedObjectArray hostB; + + for (int i=0;i=numElements) + return; + + float8 aGID = a[iGID]; + float8 bGID = b[iGID]; + + float8 result = aGID + bGID; + // write back out to GMEM + c[iGID] = result; +} diff --git a/opencl/vector_add/VectorAddKernels.h b/opencl/vector_add/VectorAddKernels.h new file mode 100644 index 000000000..55c238aae --- /dev/null +++ b/opencl/vector_add/VectorAddKernels.h @@ -0,0 +1,20 @@ +//this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project +static const char* vectorAddCL= \ +"\n" +"\n" +"__kernel void VectorAdd(__global const float8* a, __global const float8* b, __global float8* c, int numElements)\n" +"{\n" +" // get oct-float index into global data array\n" +" int iGID = get_global_id(0);\n" +" if (iGID>=numElements)\n" +" return;\n" +"\n" +" float8 aGID = a[iGID];\n" +" float8 bGID = b[iGID];\n" +"\n" +" float8 result = aGID + bGID;\n" +" // write back out to GMEM\n" +" c[iGID] = result;\n" +"}\n" +"\n" +; diff --git a/opencl/vector_add/main.cpp b/opencl/vector_add/main.cpp new file mode 100644 index 000000000..aa4132d98 --- /dev/null +++ b/opencl/vector_add/main.cpp @@ -0,0 +1,408 @@ + +///VectorAdd sample, from the NVidia JumpStart Guide +///http://developer.download.nvidia.com/OpenCL/NVIDIA_OpenCL_JumpStart_Guide.pdf + +///Instead of #include we include +///Apart from this include file, all other code should compile and work on OpenCL compliant implementation + + +#define LOAD_FROM_FILE + +#ifdef __APPLE__ + #include +#else + #include +#endif //__APPLE__ +#ifdef _WIN32 +#pragma warning (disable:4996) +#endif +#include +#include +#include +#include + +#define GRID3DOCL_CHECKERROR(a, b) if((a)!=(b)) { printf("3D GRID OCL Error : %d\n", (a)); btAssert((a) == (b)); } +size_t wgSize; + +#include "VectorAddKernels.h" + +#ifdef CL_PLATFORM_INTEL + const char* preferredPlatform = "Intel(R) Corporation"; +#elif defined CL_PLATFORM_AMD + const char* preferredPlatform = "Advanced Micro Devices, Inc."; +#elif defined CL_PLATFORM_NVIDIA + const char* preferredPlatform = "NVIDIA Corporation"; +#else + const char* preferredPlatform = "Unknown"; +#endif + + + +char* loadProgSource(const char* cFilename, const char* cPreamble, size_t* szFinalLength) +{ + // locals + FILE* pFileStream = NULL; + size_t szSourceLength; + + // open the OpenCL source code file + pFileStream = fopen(cFilename, "rb"); + if(pFileStream == 0) + { + return NULL; + } + + size_t szPreambleLength = strlen(cPreamble); + + // get the length of the source code + fseek(pFileStream, 0, SEEK_END); + szSourceLength = ftell(pFileStream); + fseek(pFileStream, 0, SEEK_SET); + + // allocate a buffer for the source code string and read it in + char* cSourceString = (char *)malloc(szSourceLength + szPreambleLength + 1); + memcpy(cSourceString, cPreamble, szPreambleLength); + fread((cSourceString) + szPreambleLength, szSourceLength, 1, pFileStream); + + // close the file and return the total length of the combined (preamble + source) string + fclose(pFileStream); + if(szFinalLength != 0) + { + *szFinalLength = szSourceLength + szPreambleLength; + } + cSourceString[szSourceLength + szPreambleLength] = '\0'; + + return cSourceString; +} + +size_t workitem_size[3]; + +void printDevInfo(cl_device_id device) +{ + char device_string[1024]; + + clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(device_string), &device_string, NULL); + printf( " Device %s:\n", device_string); + + // CL_DEVICE_INFO + cl_device_type type; + clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(type), &type, NULL); + if( type & CL_DEVICE_TYPE_CPU ) + printf(" CL_DEVICE_TYPE:\t\t%s\n", "CL_DEVICE_TYPE_CPU"); + if( type & CL_DEVICE_TYPE_GPU ) + printf( " CL_DEVICE_TYPE:\t\t%s\n", "CL_DEVICE_TYPE_GPU"); + if( type & CL_DEVICE_TYPE_ACCELERATOR ) + printf( " CL_DEVICE_TYPE:\t\t%s\n", "CL_DEVICE_TYPE_ACCELERATOR"); + if( type & CL_DEVICE_TYPE_DEFAULT ) + printf( " CL_DEVICE_TYPE:\t\t%s\n", "CL_DEVICE_TYPE_DEFAULT"); + + // CL_DEVICE_MAX_COMPUTE_UNITS + cl_uint compute_units; + clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(compute_units), &compute_units, NULL); + printf( " CL_DEVICE_MAX_COMPUTE_UNITS:\t%d\n", compute_units); + + // CL_DEVICE_MAX_WORK_GROUP_SIZE + + clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(workitem_size), &workitem_size, NULL); + printf( " CL_DEVICE_MAX_WORK_ITEM_SIZES:\t%u / %u / %u \n", workitem_size[0], workitem_size[1], workitem_size[2]); + +} + + + + +// Main function +// ********************************************************************* +int main(int argc, char **argv) +{ + void *srcA, *srcB, *dst; // Host buffers for OpenCL test + cl_context cxGPUContext; // OpenCL context + cl_command_queue cqCommandQue; // OpenCL command que + cl_device_id* cdDevices; // OpenCL device list + cl_program cpProgram; // OpenCL program + cl_kernel ckKernel; // OpenCL kernel + cl_mem cmMemObjs[3]; // OpenCL memory buffer objects: 3 for device + size_t szGlobalWorkSize[1]; // 1D var for Total # of work items + size_t szLocalWorkSize[1]; // 1D var for # of work items in the work group + size_t szParmDataBytes; // Byte size of context information + cl_int ciErr1, ciErr2; // Error code var + + + int iTestN = 100000 * 8; // Size of Vectors to process + + int actualGlobalSize = iTestN / 8; + + + // set Global and Local work size dimensions + szGlobalWorkSize[0] = iTestN >> 3; // do 8 computations per work item + szLocalWorkSize[0]= iTestN>>3; + + + // Allocate and initialize host arrays + srcA = (void *)malloc (sizeof(cl_float) * iTestN); + srcB = (void *)malloc (sizeof(cl_float) * iTestN); + dst = (void *)malloc (sizeof(cl_float) * iTestN); + + int i; + + // Initialize arrays with some values + for (i=0;i processing outside of the buffer + //make sure to check kernel + } + + size_t globalThreads[] = {num_t * workgroupSize}; + size_t localThreads[] = {workgroupSize}; + + + localWorkSize[0] = workgroupSize; + globalWorkSize[0] = num_t * workgroupSize; + localWorkSize[1] = 1; + globalWorkSize[1] = 1; + + // Copy input data from host to GPU and launch kernel + ciErr1 |= clEnqueueNDRangeKernel(cqCommandQue, ckKernel, 1, NULL, globalThreads, localThreads, 0, NULL, NULL); + + } + + if (ciErrNum != CL_SUCCESS) + { + printf("cannot clEnqueueNDRangeKernel\n"); + exit(0); + } + + clFinish(cqCommandQue); + // Read back results and check accumulated errors + ciErr1 |= clEnqueueReadBuffer(cqCommandQue, cmMemObjs[2], CL_TRUE, 0, sizeof(cl_float8) * szGlobalWorkSize[0], dst, 0, NULL, NULL); + + // Release kernel, program, and memory objects + // NOTE: Most properly this should be done at any of the exit points above, but it is omitted elsewhere for clarity. + free(cdDevices); + clReleaseKernel(ckKernel); + clReleaseProgram(cpProgram); + clReleaseCommandQueue(cqCommandQue); + clReleaseContext(cxGPUContext); + + + // print the results + int iErrorCount = 0; + for (i = 0; i < iTestN; i++) + { + if (((float*)dst)[i] != ((float*)srcA)[i]+((float*)srcB)[i]) + iErrorCount++; + } + + if (iErrorCount) + { + printf("Validation FAILED\n"); + } else + { + printf("Validation SUCCESSFULL\n"); + } + // Free host memory, close log and return success + for (i = 0; i < 3; i++) + { + clReleaseMemObject(cmMemObjs[i]); + } + + free(srcA); + free(srcB); + free (dst); + printf("Press ENTER to quit\n"); + getchar(); +} + + diff --git a/opencl/vector_add/premake4.lua b/opencl/vector_add/premake4.lua new file mode 100644 index 000000000..ccaabd73b --- /dev/null +++ b/opencl/vector_add/premake4.lua @@ -0,0 +1,28 @@ +function createProject(vendor) + + hasCL = findOpenCL(vendor) + + if (hasCL) then + + project ("OpenCL_VectorAdd_" .. vendor) + + initOpenCL(vendor) + + language "C++" + + kind "ConsoleApp" + targetdir "../../bin" + + files { + "main.cpp", + "../basic_initialize/btOpenCLUtils.cpp", + "../basic_initialize/btOpenCLUtils.h" + } + + end +end + +createProject("AMD") +createProject("Intel") +createProject("NVIDIA") +createProject("Apple") diff --git a/opencl/vector_add_simplified/main.cpp b/opencl/vector_add_simplified/main.cpp new file mode 100644 index 000000000..d911ec2c2 --- /dev/null +++ b/opencl/vector_add_simplified/main.cpp @@ -0,0 +1,69 @@ +///original author: Erwin Coumans +#include "btOpenCLUtils.h" +#include "../parallel_primitives/host/btOpenCLArray.h" +#include "../parallel_primitives/host/btLauncherCL.h" +#include + + +#define MSTRINGIFY(A) #A +const char* kernelString= MSTRINGIFY( +__kernel void VectorAdd(__global const float* a, __global const float* b, __global float* c, int numElements) +{ + int iGID = get_global_id(0); + if (iGID>=numElements) + return; + float aGID = a[iGID]; + float bGID = b[iGID]; + float result = aGID + bGID; + c[iGID] = result; +} +); + +int main(int argc, char* argv[]) +{ + int ciErrNum = 0; + int preferred_device = -1; + int preferred_platform = -1; + cl_platform_id platformId; + cl_context ctx; + cl_command_queue queue; + cl_device_id device; + cl_kernel addKernel; + ctx = btOpenCLUtils::createContextFromType(CL_DEVICE_TYPE_GPU, &ciErrNum,0,0,preferred_device,preferred_platform,&platformId); + btOpenCLUtils::printPlatformInfo(platformId); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + if (!ctx) { + printf("No OpenCL capable GPU found!"); + return 0; + } + + device = btOpenCLUtils::getDevice(ctx,0); + queue = clCreateCommandQueue(ctx, device, 0, &ciErrNum); + addKernel = btOpenCLUtils::compileCLKernelFromString(ctx,device,kernelString,"VectorAdd",&ciErrNum); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + int numElements = 32; + btOpenCLArray a(ctx,queue); + btOpenCLArray b(ctx,queue); + btOpenCLArray c(ctx,queue); + for (int i=0;i