1 #include "b3PrefixScanCL.h"
2 #include "b3FillCL.h"
3 #define B3_PREFIXSCAN_PROG_PATH "src/Bullet3OpenCL/ParallelPrimitives/kernels/PrefixScanKernels.cl"
4 
5 #include "b3LauncherCL.h"
6 #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
7 #include "kernels/PrefixScanKernelsCL.h"
8 
b3PrefixScanCL(cl_context ctx,cl_device_id device,cl_command_queue queue,int size)9 b3PrefixScanCL::b3PrefixScanCL(cl_context ctx, cl_device_id device, cl_command_queue queue, int size)
10 	: m_commandQueue(queue)
11 {
12 	const char* scanKernelSource = prefixScanKernelsCL;
13 	cl_int pErrNum;
14 	char* additionalMacros = 0;
15 
16 	m_workBuffer = new b3OpenCLArray<unsigned int>(ctx, queue, size);
17 	cl_program scanProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, scanKernelSource, &pErrNum, additionalMacros, B3_PREFIXSCAN_PROG_PATH);
18 	b3Assert(scanProg);
19 
20 	m_localScanKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, scanKernelSource, "LocalScanKernel", &pErrNum, scanProg, additionalMacros);
21 	b3Assert(m_localScanKernel);
22 	m_blockSumKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, scanKernelSource, "TopLevelScanKernel", &pErrNum, scanProg, additionalMacros);
23 	b3Assert(m_blockSumKernel);
24 	m_propagationKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, scanKernelSource, "AddOffsetKernel", &pErrNum, scanProg, additionalMacros);
25 	b3Assert(m_propagationKernel);
26 }
27 
~b3PrefixScanCL()28 b3PrefixScanCL::~b3PrefixScanCL()
29 {
30 	delete m_workBuffer;
31 	clReleaseKernel(m_localScanKernel);
32 	clReleaseKernel(m_blockSumKernel);
33 	clReleaseKernel(m_propagationKernel);
34 }
35 
36 template <class T>
b3NextPowerOf2(T n)37 T b3NextPowerOf2(T n)
38 {
39 	n -= 1;
40 	for (int i = 0; i < sizeof(T) * 8; i++)
41 		n = n | (n >> i);
42 	return n + 1;
43 }
44 
execute(b3OpenCLArray<unsigned int> & src,b3OpenCLArray<unsigned int> & dst,int n,unsigned int * sum)45 void b3PrefixScanCL::execute(b3OpenCLArray<unsigned int>& src, b3OpenCLArray<unsigned int>& dst, int n, unsigned int* sum)
46 {
47 	//	b3Assert( data->m_option == EXCLUSIVE );
48 	const unsigned int numBlocks = (const unsigned int)((n + BLOCK_SIZE * 2 - 1) / (BLOCK_SIZE * 2));
49 
50 	dst.resize(src.size());
51 	m_workBuffer->resize(src.size());
52 
53 	b3Int4 constBuffer;
54 	constBuffer.x = n;
55 	constBuffer.y = numBlocks;
56 	constBuffer.z = (int)b3NextPowerOf2(numBlocks);
57 
58 	b3OpenCLArray<unsigned int>* srcNative = &src;
59 	b3OpenCLArray<unsigned int>* dstNative = &dst;
60 
61 	{
62 		b3BufferInfoCL bInfo[] = {b3BufferInfoCL(dstNative->getBufferCL()), b3BufferInfoCL(srcNative->getBufferCL()), b3BufferInfoCL(m_workBuffer->getBufferCL())};
63 
64 		b3LauncherCL launcher(m_commandQueue, m_localScanKernel, "m_localScanKernel");
65 		launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
66 		launcher.setConst(constBuffer);
67 		launcher.launch1D(numBlocks * BLOCK_SIZE, BLOCK_SIZE);
68 	}
69 
70 	{
71 		b3BufferInfoCL bInfo[] = {b3BufferInfoCL(m_workBuffer->getBufferCL())};
72 
73 		b3LauncherCL launcher(m_commandQueue, m_blockSumKernel, "m_blockSumKernel");
74 		launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
75 		launcher.setConst(constBuffer);
76 		launcher.launch1D(BLOCK_SIZE, BLOCK_SIZE);
77 	}
78 
79 	if (numBlocks > 1)
80 	{
81 		b3BufferInfoCL bInfo[] = {b3BufferInfoCL(dstNative->getBufferCL()), b3BufferInfoCL(m_workBuffer->getBufferCL())};
82 		b3LauncherCL launcher(m_commandQueue, m_propagationKernel, "m_propagationKernel");
83 		launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL));
84 		launcher.setConst(constBuffer);
85 		launcher.launch1D((numBlocks - 1) * BLOCK_SIZE, BLOCK_SIZE);
86 	}
87 
88 	if (sum)
89 	{
90 		clFinish(m_commandQueue);
91 		dstNative->copyToHostPointer(sum, 1, n - 1, true);
92 	}
93 }
94 
executeHost(b3AlignedObjectArray<unsigned int> & src,b3AlignedObjectArray<unsigned int> & dst,int n,unsigned int * sum)95 void b3PrefixScanCL::executeHost(b3AlignedObjectArray<unsigned int>& src, b3AlignedObjectArray<unsigned int>& dst, int n, unsigned int* sum)
96 {
97 	unsigned int s = 0;
98 	//if( data->m_option == EXCLUSIVE )
99 	{
100 		for (int i = 0; i < n; i++)
101 		{
102 			dst[i] = s;
103 			s += src[i];
104 		}
105 	}
106 	/*else
107 	{
108 		for(int i=0; i<n; i++)
109 		{
110 			s += hSrc[i];
111 			hDst[i] = s;
112 		}
113 	}
114 	*/
115 
116 	if (sum)
117 	{
118 		*sum = dst[n - 1];
119 	}
120 }