diff options
Diffstat (limited to 'thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp')
-rw-r--r-- | thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp | 1251 |
1 files changed, 536 insertions, 715 deletions
diff --git a/thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp b/thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp index f0b0abd5e0..e3d235a4fd 100644 --- a/thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp +++ b/thirdparty/bullet/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp @@ -2,7 +2,7 @@ bool gUseLargeBatches = false; bool gCpuBatchContacts = false; bool gCpuSolveConstraint = false; -bool gCpuRadixSort=false; +bool gCpuRadixSort = false; bool gCpuSetSortData = false; bool gCpuSortContactsDeterminism = false; bool gUseCpuCopyConstraints = false; @@ -11,7 +11,6 @@ bool gReorderContactsOnCpu = false; bool optionalSortContactsDeterminism = true; - #include "b3GpuPgsContactSolver.h" #include "Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.h" @@ -23,7 +22,6 @@ bool optionalSortContactsDeterminism = true; #include "Bullet3Collision/NarrowPhaseCollision/b3Config.h" #include "b3Solver.h" - #define B3_SOLVER_SETUP_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solverSetup.cl" #define B3_SOLVER_SETUP2_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solverSetup2.cl" #define B3_SOLVER_CONTACT_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solveContact.cl" @@ -38,11 +36,7 @@ bool optionalSortContactsDeterminism = true; #include "kernels/batchingKernels.h" #include "kernels/batchingKernelsNew.h" - - - - -struct b3GpuBatchingPgsSolverInternalData +struct b3GpuBatchingPgsSolverInternalData { cl_context m_context; cl_device_id m_device; @@ -53,9 +47,9 @@ struct b3GpuBatchingPgsSolverInternalData b3OpenCLArray<b3GpuConstraint4>* m_contactCGPU; b3OpenCLArray<unsigned int>* m_numConstraints; b3OpenCLArray<unsigned int>* m_offsets; - - b3Solver* m_solverGPU; - + + b3Solver* m_solverGPU; + cl_kernel m_batchingKernel; cl_kernel m_batchingKernelNew; cl_kernel m_solveContactKernel; @@ -67,17 +61,14 @@ struct b3GpuBatchingPgsSolverInternalData cl_kernel m_reorderContactKernel; cl_kernel m_copyConstraintKernel; - cl_kernel m_setDeterminismSortDataBodyAKernel; - cl_kernel m_setDeterminismSortDataBodyBKernel; - cl_kernel m_setDeterminismSortDataChildShapeAKernel; - cl_kernel m_setDeterminismSortDataChildShapeBKernel; - + cl_kernel m_setDeterminismSortDataBodyAKernel; + cl_kernel m_setDeterminismSortDataBodyBKernel; + cl_kernel m_setDeterminismSortDataChildShapeAKernel; + cl_kernel m_setDeterminismSortDataChildShapeBKernel; - - - class b3RadixSort32CL* m_sort32; - class b3BoundSearchCL* m_search; - class b3PrefixScanCL* m_scan; + class b3RadixSort32CL* m_sort32; + class b3BoundSearchCL* m_search; + class b3PrefixScanCL* m_scan; b3OpenCLArray<b3SortData>* m_sortDataBuffer; b3OpenCLArray<b3Contact4>* m_contactBuffer; @@ -85,63 +76,56 @@ struct b3GpuBatchingPgsSolverInternalData b3OpenCLArray<b3RigidBodyData>* m_bodyBufferGPU; b3OpenCLArray<b3InertiaData>* m_inertiaBufferGPU; b3OpenCLArray<b3Contact4>* m_pBufContactOutGPU; - - b3OpenCLArray<b3Contact4>* m_pBufContactOutGPUCopy; - b3OpenCLArray<b3SortData>* m_contactKeyValues; + b3OpenCLArray<b3Contact4>* m_pBufContactOutGPUCopy; + b3OpenCLArray<b3SortData>* m_contactKeyValues; b3AlignedObjectArray<unsigned int> m_idxBuffer; b3AlignedObjectArray<b3SortData> m_sortData; b3AlignedObjectArray<b3Contact4> m_old; - b3AlignedObjectArray<int> m_batchSizes; - b3OpenCLArray<int>* m_batchSizesGpu; - + b3AlignedObjectArray<int> m_batchSizes; + b3OpenCLArray<int>* m_batchSizesGpu; }; - - -b3GpuPgsContactSolver::b3GpuPgsContactSolver(cl_context ctx,cl_device_id device, cl_command_queue q,int pairCapacity) +b3GpuPgsContactSolver::b3GpuPgsContactSolver(cl_context ctx, cl_device_id device, cl_command_queue q, int pairCapacity) { - m_debugOutput=0; + m_debugOutput = 0; m_data = new b3GpuBatchingPgsSolverInternalData; m_data->m_context = ctx; m_data->m_device = device; m_data->m_queue = q; m_data->m_pairCapacity = pairCapacity; m_data->m_nIterations = 4; - m_data->m_batchSizesGpu = new b3OpenCLArray<int>(ctx,q); - m_data->m_bodyBufferGPU = new b3OpenCLArray<b3RigidBodyData>(ctx,q); - m_data->m_inertiaBufferGPU = new b3OpenCLArray<b3InertiaData>(ctx,q); - m_data->m_pBufContactOutGPU = new b3OpenCLArray<b3Contact4>(ctx,q); - - m_data->m_pBufContactOutGPUCopy = new b3OpenCLArray<b3Contact4>(ctx,q); - m_data->m_contactKeyValues = new b3OpenCLArray<b3SortData>(ctx,q); + m_data->m_batchSizesGpu = new b3OpenCLArray<int>(ctx, q); + m_data->m_bodyBufferGPU = new b3OpenCLArray<b3RigidBodyData>(ctx, q); + m_data->m_inertiaBufferGPU = new b3OpenCLArray<b3InertiaData>(ctx, q); + m_data->m_pBufContactOutGPU = new b3OpenCLArray<b3Contact4>(ctx, q); + m_data->m_pBufContactOutGPUCopy = new b3OpenCLArray<b3Contact4>(ctx, q); + m_data->m_contactKeyValues = new b3OpenCLArray<b3SortData>(ctx, q); - m_data->m_solverGPU = new b3Solver(ctx,device,q,512*1024); + m_data->m_solverGPU = new b3Solver(ctx, device, q, 512 * 1024); - m_data->m_sort32 = new b3RadixSort32CL(ctx,device,m_data->m_queue); - m_data->m_scan = new b3PrefixScanCL(ctx,device,m_data->m_queue,B3_SOLVER_N_CELLS); - m_data->m_search = new b3BoundSearchCL(ctx,device,m_data->m_queue,B3_SOLVER_N_CELLS); + m_data->m_sort32 = new b3RadixSort32CL(ctx, device, m_data->m_queue); + m_data->m_scan = new b3PrefixScanCL(ctx, device, m_data->m_queue, B3_SOLVER_N_CELLS); + m_data->m_search = new b3BoundSearchCL(ctx, device, m_data->m_queue, B3_SOLVER_N_CELLS); - const int sortSize = B3NEXTMULTIPLEOF( pairCapacity, 512 ); + const int sortSize = B3NEXTMULTIPLEOF(pairCapacity, 512); - m_data->m_sortDataBuffer = new b3OpenCLArray<b3SortData>(ctx,m_data->m_queue,sortSize); - m_data->m_contactBuffer = new b3OpenCLArray<b3Contact4>(ctx,m_data->m_queue); + m_data->m_sortDataBuffer = new b3OpenCLArray<b3SortData>(ctx, m_data->m_queue, sortSize); + m_data->m_contactBuffer = new b3OpenCLArray<b3Contact4>(ctx, m_data->m_queue); - m_data->m_numConstraints = new b3OpenCLArray<unsigned int>(ctx,m_data->m_queue,B3_SOLVER_N_CELLS); + m_data->m_numConstraints = new b3OpenCLArray<unsigned int>(ctx, m_data->m_queue, B3_SOLVER_N_CELLS); m_data->m_numConstraints->resize(B3_SOLVER_N_CELLS); - m_data->m_contactCGPU = new b3OpenCLArray<b3GpuConstraint4>(ctx,q,pairCapacity); + m_data->m_contactCGPU = new b3OpenCLArray<b3GpuConstraint4>(ctx, q, pairCapacity); - m_data->m_offsets = new b3OpenCLArray<unsigned int>( ctx,m_data->m_queue,B3_SOLVER_N_CELLS); + m_data->m_offsets = new b3OpenCLArray<unsigned int>(ctx, m_data->m_queue, B3_SOLVER_N_CELLS); m_data->m_offsets->resize(B3_SOLVER_N_CELLS); const char* additionalMacros = ""; //const char* srcFileNameForCaching=""; - - cl_int pErrNum; const char* batchKernelSource = batchingKernelsCL; const char* batchKernelNewSource = batchingKernelsNewCL; @@ -149,88 +133,73 @@ b3GpuPgsContactSolver::b3GpuPgsContactSolver(cl_context ctx,cl_device_id device, const char* solverSetup2Source = solverSetup2CL; const char* solveContactSource = solveContactCL; const char* solveFrictionSource = solveFrictionCL; - - + { - - cl_program solveContactProg= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solveContactSource, &pErrNum,additionalMacros, B3_SOLVER_CONTACT_KERNEL_PATH); + cl_program solveContactProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solveContactSource, &pErrNum, additionalMacros, B3_SOLVER_CONTACT_KERNEL_PATH); b3Assert(solveContactProg); - - cl_program solveFrictionProg= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solveFrictionSource, &pErrNum,additionalMacros, B3_SOLVER_FRICTION_KERNEL_PATH); + + cl_program solveFrictionProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solveFrictionSource, &pErrNum, additionalMacros, B3_SOLVER_FRICTION_KERNEL_PATH); b3Assert(solveFrictionProg); - cl_program solverSetup2Prog= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solverSetup2Source, &pErrNum,additionalMacros, B3_SOLVER_SETUP2_KERNEL_PATH); - - + cl_program solverSetup2Prog = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solverSetup2Source, &pErrNum, additionalMacros, B3_SOLVER_SETUP2_KERNEL_PATH); + b3Assert(solverSetup2Prog); - - cl_program solverSetupProg= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solverSetupSource, &pErrNum,additionalMacros, B3_SOLVER_SETUP_KERNEL_PATH); + cl_program solverSetupProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solverSetupSource, &pErrNum, additionalMacros, B3_SOLVER_SETUP_KERNEL_PATH); b3Assert(solverSetupProg); - - - m_data->m_solveFrictionKernel= b3OpenCLUtils::compileCLKernelFromString( ctx, device, solveFrictionSource, "BatchSolveKernelFriction", &pErrNum, solveFrictionProg,additionalMacros ); + + m_data->m_solveFrictionKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveFrictionSource, "BatchSolveKernelFriction", &pErrNum, solveFrictionProg, additionalMacros); b3Assert(m_data->m_solveFrictionKernel); - m_data->m_solveContactKernel= b3OpenCLUtils::compileCLKernelFromString( ctx, device, solveContactSource, "BatchSolveKernelContact", &pErrNum, solveContactProg,additionalMacros ); + m_data->m_solveContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveContactSource, "BatchSolveKernelContact", &pErrNum, solveContactProg, additionalMacros); b3Assert(m_data->m_solveContactKernel); - m_data->m_solveSingleContactKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solveContactSource, "solveSingleContactKernel", &pErrNum, solveContactProg,additionalMacros ); + m_data->m_solveSingleContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveContactSource, "solveSingleContactKernel", &pErrNum, solveContactProg, additionalMacros); b3Assert(m_data->m_solveSingleContactKernel); - m_data->m_solveSingleFrictionKernel =b3OpenCLUtils::compileCLKernelFromString( ctx, device, solveFrictionSource, "solveSingleFrictionKernel", &pErrNum, solveFrictionProg,additionalMacros ); + m_data->m_solveSingleFrictionKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveFrictionSource, "solveSingleFrictionKernel", &pErrNum, solveFrictionProg, additionalMacros); b3Assert(m_data->m_solveSingleFrictionKernel); - - m_data->m_contactToConstraintKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetupSource, "ContactToConstraintKernel", &pErrNum, solverSetupProg,additionalMacros ); + + m_data->m_contactToConstraintKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetupSource, "ContactToConstraintKernel", &pErrNum, solverSetupProg, additionalMacros); b3Assert(m_data->m_contactToConstraintKernel); - - m_data->m_setSortDataKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetSortDataKernel", &pErrNum, solverSetup2Prog,additionalMacros ); + + m_data->m_setSortDataKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetSortDataKernel", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_setSortDataKernel); - m_data->m_setDeterminismSortDataBodyAKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetDeterminismSortDataBodyA", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_setDeterminismSortDataBodyAKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataBodyA", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_setDeterminismSortDataBodyAKernel); - m_data->m_setDeterminismSortDataBodyBKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetDeterminismSortDataBodyB", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_setDeterminismSortDataBodyBKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataBodyB", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_setDeterminismSortDataBodyBKernel); - m_data->m_setDeterminismSortDataChildShapeAKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetDeterminismSortDataChildShapeA", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_setDeterminismSortDataChildShapeAKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataChildShapeA", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_setDeterminismSortDataChildShapeAKernel); - m_data->m_setDeterminismSortDataChildShapeBKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetDeterminismSortDataChildShapeB", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_setDeterminismSortDataChildShapeBKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataChildShapeB", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_setDeterminismSortDataChildShapeBKernel); - - m_data->m_reorderContactKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "ReorderContactKernel", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_reorderContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "ReorderContactKernel", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_reorderContactKernel); - - m_data->m_copyConstraintKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "CopyConstraintKernel", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_copyConstraintKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "CopyConstraintKernel", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_copyConstraintKernel); - } { - cl_program batchingProg = b3OpenCLUtils::compileCLProgramFromString( ctx, device, batchKernelSource, &pErrNum,additionalMacros, B3_BATCHING_PATH); + cl_program batchingProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, batchKernelSource, &pErrNum, additionalMacros, B3_BATCHING_PATH); b3Assert(batchingProg); - - m_data->m_batchingKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, batchKernelSource, "CreateBatches", &pErrNum, batchingProg,additionalMacros ); + + m_data->m_batchingKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, batchKernelSource, "CreateBatches", &pErrNum, batchingProg, additionalMacros); b3Assert(m_data->m_batchingKernel); } - + { - cl_program batchingNewProg = b3OpenCLUtils::compileCLProgramFromString( ctx, device, batchKernelNewSource, &pErrNum,additionalMacros, B3_BATCHING_NEW_PATH); + cl_program batchingNewProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, batchKernelNewSource, &pErrNum, additionalMacros, B3_BATCHING_NEW_PATH); b3Assert(batchingNewProg); - - m_data->m_batchingKernelNew = b3OpenCLUtils::compileCLKernelFromString( ctx, device, batchKernelNewSource, "CreateBatchesNew", &pErrNum, batchingNewProg,additionalMacros ); + + m_data->m_batchingKernelNew = b3OpenCLUtils::compileCLKernelFromString(ctx, device, batchKernelNewSource, "CreateBatchesNew", &pErrNum, batchingNewProg, additionalMacros); b3Assert(m_data->m_batchingKernelNew); } - - - - - - - } b3GpuPgsContactSolver::~b3GpuPgsContactSolver() @@ -242,8 +211,6 @@ b3GpuPgsContactSolver::~b3GpuPgsContactSolver() delete m_data->m_pBufContactOutGPUCopy; delete m_data->m_contactKeyValues; - - delete m_data->m_contactCGPU; delete m_data->m_numConstraints; delete m_data->m_offsets; @@ -259,29 +226,25 @@ b3GpuPgsContactSolver::~b3GpuPgsContactSolver() clReleaseKernel(m_data->m_batchingKernelNew); clReleaseKernel(m_data->m_solveSingleContactKernel); clReleaseKernel(m_data->m_solveSingleFrictionKernel); - clReleaseKernel( m_data->m_solveContactKernel); - clReleaseKernel( m_data->m_solveFrictionKernel); + clReleaseKernel(m_data->m_solveContactKernel); + clReleaseKernel(m_data->m_solveFrictionKernel); - clReleaseKernel( m_data->m_contactToConstraintKernel); - clReleaseKernel( m_data->m_setSortDataKernel); - clReleaseKernel( m_data->m_reorderContactKernel); - clReleaseKernel( m_data->m_copyConstraintKernel); + clReleaseKernel(m_data->m_contactToConstraintKernel); + clReleaseKernel(m_data->m_setSortDataKernel); + clReleaseKernel(m_data->m_reorderContactKernel); + clReleaseKernel(m_data->m_copyConstraintKernel); clReleaseKernel(m_data->m_setDeterminismSortDataBodyAKernel); clReleaseKernel(m_data->m_setDeterminismSortDataBodyBKernel); clReleaseKernel(m_data->m_setDeterminismSortDataChildShapeAKernel); clReleaseKernel(m_data->m_setDeterminismSortDataChildShapeBKernel); - - delete m_data; } - - struct b3ConstraintCfg { - b3ConstraintCfg( float dt = 0.f ): m_positionDrift( 0.005f ), m_positionConstraintCoeff( 0.2f ), m_dt(dt), m_staticIdx(0) {} + b3ConstraintCfg(float dt = 0.f) : m_positionDrift(0.005f), m_positionConstraintCoeff(0.2f), m_dt(dt), m_staticIdx(0) {} float m_positionDrift; float m_positionConstraintCoeff; @@ -291,354 +254,306 @@ struct b3ConstraintCfg int m_staticIdx; }; - - -void b3GpuPgsContactSolver::solveContactConstraintBatchSizes( const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* shapeBuf, - b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches,int numIterations, const b3AlignedObjectArray<int>* batchSizes)//const b3OpenCLArray<int>* gpuBatchSizes) +void b3GpuPgsContactSolver::solveContactConstraintBatchSizes(const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* shapeBuf, + b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n, int maxNumBatches, int numIterations, const b3AlignedObjectArray<int>* batchSizes) //const b3OpenCLArray<int>* gpuBatchSizes) { B3_PROFILE("solveContactConstraintBatchSizes"); - int numBatches = batchSizes->size()/B3_MAX_NUM_BATCHES; - for(int iter=0; iter<numIterations; iter++) + int numBatches = batchSizes->size() / B3_MAX_NUM_BATCHES; + for (int iter = 0; iter < numIterations; iter++) { - - for (int cellId=0;cellId<numBatches;cellId++) + for (int cellId = 0; cellId < numBatches; cellId++) { int offset = 0; - for (int ii=0;ii<B3_MAX_NUM_BATCHES;ii++) + for (int ii = 0; ii < B3_MAX_NUM_BATCHES; ii++) { - int numInBatch = batchSizes->at(cellId*B3_MAX_NUM_BATCHES+ii); + int numInBatch = batchSizes->at(cellId * B3_MAX_NUM_BATCHES + ii); if (!numInBatch) break; { - b3LauncherCL launcher( m_data->m_queue, m_data->m_solveSingleContactKernel,"m_solveSingleContactKernel" ); - launcher.setBuffer(bodyBuf->getBufferCL() ); - launcher.setBuffer(shapeBuf->getBufferCL() ); - launcher.setBuffer( constraint->getBufferCL() ); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solveSingleContactKernel, "m_solveSingleContactKernel"); + launcher.setBuffer(bodyBuf->getBufferCL()); + launcher.setBuffer(shapeBuf->getBufferCL()); + launcher.setBuffer(constraint->getBufferCL()); launcher.setConst(cellId); launcher.setConst(offset); launcher.setConst(numInBatch); launcher.launch1D(numInBatch); - offset+=numInBatch; + offset += numInBatch; } } } } - - for(int iter=0; iter<numIterations; iter++) + for (int iter = 0; iter < numIterations; iter++) { - for (int cellId=0;cellId<numBatches;cellId++) + for (int cellId = 0; cellId < numBatches; cellId++) { int offset = 0; - for (int ii=0;ii<B3_MAX_NUM_BATCHES;ii++) + for (int ii = 0; ii < B3_MAX_NUM_BATCHES; ii++) { - int numInBatch = batchSizes->at(cellId*B3_MAX_NUM_BATCHES+ii); + int numInBatch = batchSizes->at(cellId * B3_MAX_NUM_BATCHES + ii); if (!numInBatch) break; { - b3LauncherCL launcher( m_data->m_queue, m_data->m_solveSingleFrictionKernel,"m_solveSingleFrictionKernel" ); - launcher.setBuffer(bodyBuf->getBufferCL() ); - launcher.setBuffer(shapeBuf->getBufferCL() ); - launcher.setBuffer( constraint->getBufferCL() ); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solveSingleFrictionKernel, "m_solveSingleFrictionKernel"); + launcher.setBuffer(bodyBuf->getBufferCL()); + launcher.setBuffer(shapeBuf->getBufferCL()); + launcher.setBuffer(constraint->getBufferCL()); launcher.setConst(cellId); launcher.setConst(offset); launcher.setConst(numInBatch); launcher.launch1D(numInBatch); - offset+=numInBatch; + offset += numInBatch; } } } } } -void b3GpuPgsContactSolver::solveContactConstraint( const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* shapeBuf, - b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n ,int maxNumBatches,int numIterations, const b3AlignedObjectArray<int>* batchSizes)//,const b3OpenCLArray<int>* gpuBatchSizes) +void b3GpuPgsContactSolver::solveContactConstraint(const b3OpenCLArray<b3RigidBodyData>* bodyBuf, const b3OpenCLArray<b3InertiaData>* shapeBuf, + b3OpenCLArray<b3GpuConstraint4>* constraint, void* additionalData, int n, int maxNumBatches, int numIterations, const b3AlignedObjectArray<int>* batchSizes) //,const b3OpenCLArray<int>* gpuBatchSizes) { - //sort the contacts - - b3Int4 cdata = b3MakeInt4( n, 0, 0, 0 ); + b3Int4 cdata = b3MakeInt4(n, 0, 0, 0); { - const int nn = B3_SOLVER_N_CELLS; cdata.x = 0; - cdata.y = maxNumBatches;//250; - + cdata.y = maxNumBatches; //250; - int numWorkItems = 64*nn/B3_SOLVER_N_BATCHES; + int numWorkItems = 64 * nn / B3_SOLVER_N_BATCHES; #ifdef DEBUG_ME - SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems]; - adl::b3OpenCLArray<SolverDebugInfo> gpuDebugInfo(data->m_device,numWorkItems); + SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems]; + adl::b3OpenCLArray<SolverDebugInfo> gpuDebugInfo(data->m_device, numWorkItems); #endif - - { - B3_PROFILE("m_batchSolveKernel iterations"); - for(int iter=0; iter<numIterations; iter++) + for (int iter = 0; iter < numIterations; iter++) { - for(int ib=0; ib<B3_SOLVER_N_BATCHES; ib++) + for (int ib = 0; ib < B3_SOLVER_N_BATCHES; ib++) { #ifdef DEBUG_ME - memset(debugInfo,0,sizeof(SolverDebugInfo)*numWorkItems); - gpuDebugInfo.write(debugInfo,numWorkItems); + memset(debugInfo, 0, sizeof(SolverDebugInfo) * numWorkItems); + gpuDebugInfo.write(debugInfo, numWorkItems); #endif - cdata.z = ib; - - b3LauncherCL launcher( m_data->m_queue, m_data->m_solveContactKernel,"m_solveContactKernel" ); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solveContactKernel, "m_solveContactKernel"); #if 1 - - b3BufferInfoCL bInfo[] = { - - b3BufferInfoCL( bodyBuf->getBufferCL() ), - b3BufferInfoCL( shapeBuf->getBufferCL() ), - b3BufferInfoCL( constraint->getBufferCL() ), - b3BufferInfoCL( m_data->m_solverGPU->m_numConstraints->getBufferCL() ), - b3BufferInfoCL( m_data->m_solverGPU->m_offsets->getBufferCL() ) + + b3BufferInfoCL bInfo[] = { + + b3BufferInfoCL(bodyBuf->getBufferCL()), + b3BufferInfoCL(shapeBuf->getBufferCL()), + b3BufferInfoCL(constraint->getBufferCL()), + b3BufferInfoCL(m_data->m_solverGPU->m_numConstraints->getBufferCL()), + b3BufferInfoCL(m_data->m_solverGPU->m_offsets->getBufferCL()) #ifdef DEBUG_ME - , b3BufferInfoCL(&gpuDebugInfo) + , + b3BufferInfoCL(&gpuDebugInfo) #endif - }; - - + }; - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setBuffer( m_data->m_solverGPU->m_batchSizes.getBufferCL()); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setBuffer(m_data->m_solverGPU->m_batchSizes.getBufferCL()); //launcher.setConst( cdata.x ); - launcher.setConst( cdata.y ); - launcher.setConst( cdata.z ); + launcher.setConst(cdata.y); + launcher.setConst(cdata.z); b3Int4 nSplit; nSplit.x = B3_SOLVER_N_SPLIT_X; nSplit.y = B3_SOLVER_N_SPLIT_Y; nSplit.z = B3_SOLVER_N_SPLIT_Z; - launcher.setConst( nSplit ); - launcher.launch1D( numWorkItems, 64 ); + launcher.setConst(nSplit); + launcher.launch1D(numWorkItems, 64); - #else - const char* fileName = "m_batchSolveKernel.bin"; - FILE* f = fopen(fileName,"rb"); - if (f) - { - int sizeInBytes=0; - if (fseek(f, 0, SEEK_END) || (sizeInBytes = ftell(f)) == EOF || fseek(f, 0, SEEK_SET)) - { - printf("error, cannot get file size\n"); - exit(0); - } - - unsigned char* buf = (unsigned char*) malloc(sizeInBytes); - fread(buf,sizeInBytes,1,f); - int serializedBytes = launcher.deserializeArgs(buf, sizeInBytes,m_context); - int num = *(int*)&buf[serializedBytes]; - - launcher.launch1D( num); - - //this clFinish is for testing on errors - clFinish(m_queue); - } + const char* fileName = "m_batchSolveKernel.bin"; + FILE* f = fopen(fileName, "rb"); + if (f) + { + int sizeInBytes = 0; + if (fseek(f, 0, SEEK_END) || (sizeInBytes = ftell(f)) == EOF || fseek(f, 0, SEEK_SET)) + { + printf("error, cannot get file size\n"); + exit(0); + } + + unsigned char* buf = (unsigned char*)malloc(sizeInBytes); + fread(buf, sizeInBytes, 1, f); + int serializedBytes = launcher.deserializeArgs(buf, sizeInBytes, m_context); + int num = *(int*)&buf[serializedBytes]; + + launcher.launch1D(num); + + //this clFinish is for testing on errors + clFinish(m_queue); + } #endif - #ifdef DEBUG_ME clFinish(m_queue); - gpuDebugInfo.read(debugInfo,numWorkItems); + gpuDebugInfo.read(debugInfo, numWorkItems); clFinish(m_queue); - for (int i=0;i<numWorkItems;i++) + for (int i = 0; i < numWorkItems; i++) { - if (debugInfo[i].m_valInt2>0) + if (debugInfo[i].m_valInt2 > 0) { - printf("debugInfo[i].m_valInt2 = %d\n",i,debugInfo[i].m_valInt2); + printf("debugInfo[i].m_valInt2 = %d\n", i, debugInfo[i].m_valInt2); } - if (debugInfo[i].m_valInt3>0) + if (debugInfo[i].m_valInt3 > 0) { - printf("debugInfo[i].m_valInt3 = %d\n",i,debugInfo[i].m_valInt3); + printf("debugInfo[i].m_valInt3 = %d\n", i, debugInfo[i].m_valInt3); } } -#endif //DEBUG_ME - - +#endif //DEBUG_ME } } - - clFinish(m_data->m_queue); - + clFinish(m_data->m_queue); } cdata.x = 1; - bool applyFriction=true; + bool applyFriction = true; if (applyFriction) - { + { B3_PROFILE("m_batchSolveKernel iterations2"); - for(int iter=0; iter<numIterations; iter++) + for (int iter = 0; iter < numIterations; iter++) { - for(int ib=0; ib<B3_SOLVER_N_BATCHES; ib++) + for (int ib = 0; ib < B3_SOLVER_N_BATCHES; ib++) { cdata.z = ib; - - - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( bodyBuf->getBufferCL() ), - b3BufferInfoCL( shapeBuf->getBufferCL() ), - b3BufferInfoCL( constraint->getBufferCL() ), - b3BufferInfoCL( m_data->m_solverGPU->m_numConstraints->getBufferCL() ), - b3BufferInfoCL( m_data->m_solverGPU->m_offsets->getBufferCL() ) + + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(bodyBuf->getBufferCL()), + b3BufferInfoCL(shapeBuf->getBufferCL()), + b3BufferInfoCL(constraint->getBufferCL()), + b3BufferInfoCL(m_data->m_solverGPU->m_numConstraints->getBufferCL()), + b3BufferInfoCL(m_data->m_solverGPU->m_offsets->getBufferCL()) #ifdef DEBUG_ME - ,b3BufferInfoCL(&gpuDebugInfo) -#endif //DEBUG_ME + , + b3BufferInfoCL(&gpuDebugInfo) +#endif //DEBUG_ME }; - b3LauncherCL launcher( m_data->m_queue, m_data->m_solveFrictionKernel,"m_solveFrictionKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setBuffer( m_data->m_solverGPU->m_batchSizes.getBufferCL()); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solveFrictionKernel, "m_solveFrictionKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setBuffer(m_data->m_solverGPU->m_batchSizes.getBufferCL()); //launcher.setConst( cdata.x ); - launcher.setConst( cdata.y ); - launcher.setConst( cdata.z ); + launcher.setConst(cdata.y); + launcher.setConst(cdata.z); - b3Int4 nSplit; + b3Int4 nSplit; nSplit.x = B3_SOLVER_N_SPLIT_X; nSplit.y = B3_SOLVER_N_SPLIT_Y; nSplit.z = B3_SOLVER_N_SPLIT_Z; - launcher.setConst( nSplit ); - - launcher.launch1D( 64*nn/B3_SOLVER_N_BATCHES, 64 ); + launcher.setConst(nSplit); + + launcher.launch1D(64 * nn / B3_SOLVER_N_BATCHES, 64); } } clFinish(m_data->m_queue); - } #ifdef DEBUG_ME delete[] debugInfo; -#endif //DEBUG_ME +#endif //DEBUG_ME } - - } - - - - - - - - - - -static bool sortfnc(const b3SortData& a,const b3SortData& b) +static bool sortfnc(const b3SortData& a, const b3SortData& b) { - return (a.m_key<b.m_key); + return (a.m_key < b.m_key); } static bool b3ContactCmp(const b3Contact4& p, const b3Contact4& q) { - return ((p.m_bodyAPtrAndSignBit<q.m_bodyAPtrAndSignBit) || - ((p.m_bodyAPtrAndSignBit==q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit<q.m_bodyBPtrAndSignBit)) || - ((p.m_bodyAPtrAndSignBit==q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit==q.m_bodyBPtrAndSignBit) && p.m_childIndexA<q.m_childIndexA ) || - ((p.m_bodyAPtrAndSignBit==q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit==q.m_bodyBPtrAndSignBit) && p.m_childIndexA<q.m_childIndexA ) || - ((p.m_bodyAPtrAndSignBit==q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit==q.m_bodyBPtrAndSignBit) && p.m_childIndexA==q.m_childIndexA && p.m_childIndexB<q.m_childIndexB) - ); + return ((p.m_bodyAPtrAndSignBit < q.m_bodyAPtrAndSignBit) || + ((p.m_bodyAPtrAndSignBit == q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit < q.m_bodyBPtrAndSignBit)) || + ((p.m_bodyAPtrAndSignBit == q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit == q.m_bodyBPtrAndSignBit) && p.m_childIndexA < q.m_childIndexA) || + ((p.m_bodyAPtrAndSignBit == q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit == q.m_bodyBPtrAndSignBit) && p.m_childIndexA < q.m_childIndexA) || + ((p.m_bodyAPtrAndSignBit == q.m_bodyAPtrAndSignBit) && (p.m_bodyBPtrAndSignBit == q.m_bodyBPtrAndSignBit) && p.m_childIndexA == q.m_childIndexA && p.m_childIndexB < q.m_childIndexB)); } - - - - - - - - - - #define USE_SPATIAL_BATCHING 1 #define USE_4x4_GRID 1 #ifndef USE_SPATIAL_BATCHING -static const int gridTable4x4[] = -{ - 0,1,17,16, - 1,2,18,19, - 17,18,32,3, - 16,19,3,34 -}; -static const int gridTable8x8[] = -{ - 0, 2, 3, 16, 17, 18, 19, 1, - 66, 64, 80, 67, 82, 81, 65, 83, - 131,144,128,130,147,129,145,146, - 208,195,194,192,193,211,210,209, - 21, 22, 23, 5, 4, 6, 7, 20, - 86, 85, 69, 87, 70, 68, 84, 71, - 151,133,149,150,135,148,132,134, - 197,27,214,213,212,199,198,196 - -}; +static const int gridTable4x4[] = + { + 0, 1, 17, 16, + 1, 2, 18, 19, + 17, 18, 32, 3, + 16, 19, 3, 34}; +static const int gridTable8x8[] = + { + 0, 2, 3, 16, 17, 18, 19, 1, + 66, 64, 80, 67, 82, 81, 65, 83, + 131, 144, 128, 130, 147, 129, 145, 146, + 208, 195, 194, 192, 193, 211, 210, 209, + 21, 22, 23, 5, 4, 6, 7, 20, + 86, 85, 69, 87, 70, 68, 84, 71, + 151, 133, 149, 150, 135, 148, 132, 134, + 197, 27, 214, 213, 212, 199, 198, 196 +}; #endif - -void SetSortDataCPU(b3Contact4* gContact, b3RigidBodyData* gBodies, b3SortData* gSortDataOut, int nContacts,float scale,const b3Int4& nSplit,int staticIdx) +void SetSortDataCPU(b3Contact4* gContact, b3RigidBodyData* gBodies, b3SortData* gSortDataOut, int nContacts, float scale, const b3Int4& nSplit, int staticIdx) { - for (int gIdx=0;gIdx<nContacts;gIdx++) + for (int gIdx = 0; gIdx < nContacts; gIdx++) { - if( gIdx < nContacts ) + if (gIdx < nContacts) { - int aPtrAndSignBit = gContact[gIdx].m_bodyAPtrAndSignBit; - int bPtrAndSignBit = gContact[gIdx].m_bodyBPtrAndSignBit; + int aPtrAndSignBit = gContact[gIdx].m_bodyAPtrAndSignBit; + int bPtrAndSignBit = gContact[gIdx].m_bodyBPtrAndSignBit; - int aIdx = abs(aPtrAndSignBit ); + int aIdx = abs(aPtrAndSignBit); int bIdx = abs(bPtrAndSignBit); - bool aStatic = (aPtrAndSignBit<0) ||(aPtrAndSignBit==staticIdx); + bool aStatic = (aPtrAndSignBit < 0) || (aPtrAndSignBit == staticIdx); - #if USE_SPATIAL_BATCHING - int idx = (aStatic)? bIdx: aIdx; +#if USE_SPATIAL_BATCHING + int idx = (aStatic) ? bIdx : aIdx; b3Vector3 p = gBodies[idx].m_pos; - int xIdx = (int)((p.x-((p.x<0.f)?1.f:0.f))*scale) & (nSplit.x-1); - int yIdx = (int)((p.y-((p.y<0.f)?1.f:0.f))*scale) & (nSplit.y-1); - int zIdx = (int)((p.z-((p.z<0.f)?1.f:0.f))*scale) & (nSplit.z-1); - - int newIndex = (xIdx+yIdx*nSplit.x+zIdx*nSplit.x*nSplit.y); - - #else//USE_SPATIAL_BATCHING - bool bStatic = (bPtrAndSignBit<0) ||(bPtrAndSignBit==staticIdx); - - #if USE_4x4_GRID - int aa = aIdx&3; - int bb = bIdx&3; + int xIdx = (int)((p.x - ((p.x < 0.f) ? 1.f : 0.f)) * scale) & (nSplit.x - 1); + int yIdx = (int)((p.y - ((p.y < 0.f) ? 1.f : 0.f)) * scale) & (nSplit.y - 1); + int zIdx = (int)((p.z - ((p.z < 0.f) ? 1.f : 0.f)) * scale) & (nSplit.z - 1); + + int newIndex = (xIdx + yIdx * nSplit.x + zIdx * nSplit.x * nSplit.y); + +#else //USE_SPATIAL_BATCHING + bool bStatic = (bPtrAndSignBit < 0) || (bPtrAndSignBit == staticIdx); + +#if USE_4x4_GRID + int aa = aIdx & 3; + int bb = bIdx & 3; if (aStatic) aa = bb; if (bStatic) bb = aa; - int gridIndex = aa + bb*4; + int gridIndex = aa + bb * 4; int newIndex = gridTable4x4[gridIndex]; - #else//USE_4x4_GRID - int aa = aIdx&7; - int bb = bIdx&7; +#else //USE_4x4_GRID + int aa = aIdx & 7; + int bb = bIdx & 7; if (aStatic) aa = bb; if (bStatic) bb = aa; - int gridIndex = aa + bb*8; + int gridIndex = aa + bb * 8; int newIndex = gridTable8x8[gridIndex]; - #endif//USE_4x4_GRID - #endif//USE_SPATIAL_BATCHING - +#endif //USE_4x4_GRID +#endif //USE_SPATIAL_BATCHING gSortDataOut[gIdx].x = newIndex; gSortDataOut[gIdx].y = gIdx; @@ -650,17 +565,12 @@ void SetSortDataCPU(b3Contact4* gContact, b3RigidBodyData* gBodies, b3SortData* } } - - - - - void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem inertiaBuf, int numContacts, cl_mem contactBuf, const b3Config& config, int static0Index) { B3_PROFILE("solveContacts"); - m_data->m_bodyBufferGPU->setFromOpenCLBuffer(bodyBuf,numBodies); - m_data->m_inertiaBufferGPU->setFromOpenCLBuffer(inertiaBuf,numBodies); - m_data->m_pBufContactOutGPU->setFromOpenCLBuffer(contactBuf,numContacts); + m_data->m_bodyBufferGPU->setFromOpenCLBuffer(bodyBuf, numBodies); + m_data->m_inertiaBufferGPU->setFromOpenCLBuffer(inertiaBuf, numBodies); + m_data->m_pBufContactOutGPU->setFromOpenCLBuffer(contactBuf, numContacts); if (optionalSortContactsDeterminism) { @@ -671,61 +581,61 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem m_data->m_pBufContactOutGPUCopy->resize(numContacts); m_data->m_contactKeyValues->resize(numContacts); - m_data->m_pBufContactOutGPU->copyToCL(m_data->m_pBufContactOutGPUCopy->getBufferCL(),numContacts,0,0); + m_data->m_pBufContactOutGPU->copyToCL(m_data->m_pBufContactOutGPUCopy->getBufferCL(), numContacts, 0, 0); { - b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataChildShapeBKernel,"m_setDeterminismSortDataChildShapeBKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataChildShapeBKernel, "m_setDeterminismSortDataChildShapeBKernel"); launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL()); launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL()); launcher.setConst(numContacts); - launcher.launch1D( numContacts, 64 ); + launcher.launch1D(numContacts, 64); } m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues); { - b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataChildShapeAKernel,"m_setDeterminismSortDataChildShapeAKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataChildShapeAKernel, "m_setDeterminismSortDataChildShapeAKernel"); launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL()); launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL()); launcher.setConst(numContacts); - launcher.launch1D( numContacts, 64 ); + launcher.launch1D(numContacts, 64); } m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues); { - b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataBodyBKernel,"m_setDeterminismSortDataBodyBKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataBodyBKernel, "m_setDeterminismSortDataBodyBKernel"); launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL()); launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL()); launcher.setConst(numContacts); - launcher.launch1D( numContacts, 64 ); + launcher.launch1D(numContacts, 64); } - + m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues); - + { - b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataBodyAKernel,"m_setDeterminismSortDataBodyAKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataBodyAKernel, "m_setDeterminismSortDataBodyAKernel"); launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL()); launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL()); launcher.setConst(numContacts); - launcher.launch1D( numContacts, 64 ); + launcher.launch1D(numContacts, 64); } m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues); { B3_PROFILE("gpu reorderContactKernel (determinism)"); - + b3Int4 cdata; cdata.x = numContacts; - + //b3BufferInfoCL bInfo[] = { b3BufferInfoCL( m_data->m_pBufContactOutGPU->getBufferCL() ), b3BufferInfoCL( m_data->m_solverGPU->m_contactBuffer2->getBufferCL()) // , b3BufferInfoCL( m_data->m_solverGPU->m_sortDataBuffer->getBufferCL()) }; - b3LauncherCL launcher(m_data->m_queue,m_data->m_solverGPU->m_reorderContactKernel,"m_reorderContactKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_reorderContactKernel, "m_reorderContactKernel"); launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL()); launcher.setBuffer(m_data->m_pBufContactOutGPU->getBufferCL()); launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL()); - launcher.setConst( cdata ); - launcher.launch1D( numContacts, 64 ); - } - - } else + launcher.setConst(cdata); + launcher.launch1D(numContacts, 64); + } + } + else { B3_PROFILE("CPU Sort contact constraints (determinism)"); b3AlignedObjectArray<b3Contact4> cpuConstraints; @@ -735,96 +645,80 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem { cpuConstraints.quickSort(b3ContactCmp); - for (int i=0;i<cpuConstraints.size();i++) + for (int i = 0; i < cpuConstraints.size(); i++) { cpuConstraints[i].m_batchIdx = i; } } m_data->m_pBufContactOutGPU->copyFromHost(cpuConstraints); - if (m_debugOutput==100) + if (m_debugOutput == 100) { - for (int i=0;i<cpuConstraints.size();i++) + for (int i = 0; i < cpuConstraints.size(); i++) { - printf("c[%d].m_bodyA = %d, m_bodyB = %d, batchId = %d\n",i,cpuConstraints[i].m_bodyAPtrAndSignBit,cpuConstraints[i].m_bodyBPtrAndSignBit, cpuConstraints[i].m_batchIdx); + printf("c[%d].m_bodyA = %d, m_bodyB = %d, batchId = %d\n", i, cpuConstraints[i].m_bodyAPtrAndSignBit, cpuConstraints[i].m_bodyBPtrAndSignBit, cpuConstraints[i].m_batchIdx); } } m_debugOutput++; } } - - - int nContactOut = m_data->m_pBufContactOutGPU->size(); bool useSolver = true; - - - if (useSolver) - { - float dt=1./60.; - b3ConstraintCfg csCfg( dt ); - csCfg.m_enableParallelSolve = true; - csCfg.m_batchCellSize = 6; - csCfg.m_staticIdx = static0Index; - - - b3OpenCLArray<b3RigidBodyData>* bodyBuf = m_data->m_bodyBufferGPU; - - void* additionalData = 0;//m_data->m_frictionCGPU; - const b3OpenCLArray<b3InertiaData>* shapeBuf = m_data->m_inertiaBufferGPU; - b3OpenCLArray<b3GpuConstraint4>* contactConstraintOut = m_data->m_contactCGPU; - int nContacts = nContactOut; - - + + if (useSolver) + { + float dt = 1. / 60.; + b3ConstraintCfg csCfg(dt); + csCfg.m_enableParallelSolve = true; + csCfg.m_batchCellSize = 6; + csCfg.m_staticIdx = static0Index; + + b3OpenCLArray<b3RigidBodyData>* bodyBuf = m_data->m_bodyBufferGPU; + + void* additionalData = 0; //m_data->m_frictionCGPU; + const b3OpenCLArray<b3InertiaData>* shapeBuf = m_data->m_inertiaBufferGPU; + b3OpenCLArray<b3GpuConstraint4>* contactConstraintOut = m_data->m_contactCGPU; + int nContacts = nContactOut; + int maxNumBatches = 0; - + if (!gUseLargeBatches) - { - - if( m_data->m_solverGPU->m_contactBuffer2) - { - m_data->m_solverGPU->m_contactBuffer2->resize(nContacts); - } - - if( m_data->m_solverGPU->m_contactBuffer2 == 0 ) - { - m_data->m_solverGPU->m_contactBuffer2 = new b3OpenCLArray<b3Contact4>(m_data->m_context,m_data->m_queue, nContacts ); - m_data->m_solverGPU->m_contactBuffer2->resize(nContacts); - } - - //clFinish(m_data->m_queue); - - - + { + if (m_data->m_solverGPU->m_contactBuffer2) { - B3_PROFILE("batching"); - //@todo: just reserve it, without copy of original contact (unless we use warmstarting) + m_data->m_solverGPU->m_contactBuffer2->resize(nContacts); + } + if (m_data->m_solverGPU->m_contactBuffer2 == 0) + { + m_data->m_solverGPU->m_contactBuffer2 = new b3OpenCLArray<b3Contact4>(m_data->m_context, m_data->m_queue, nContacts); + m_data->m_solverGPU->m_contactBuffer2->resize(nContacts); + } + //clFinish(m_data->m_queue); - //const b3OpenCLArray<b3RigidBodyData>* bodyNative = bodyBuf; + { + B3_PROFILE("batching"); + //@todo: just reserve it, without copy of original contact (unless we use warmstarting) + //const b3OpenCLArray<b3RigidBodyData>* bodyNative = bodyBuf; { - //b3OpenCLArray<b3RigidBodyData>* bodyNative = b3OpenCLArrayUtils::map<adl::TYPE_CL, true>( data->m_device, bodyBuf ); //b3OpenCLArray<b3Contact4>* contactNative = b3OpenCLArrayUtils::map<adl::TYPE_CL, true>( data->m_device, contactsIn ); - const int sortAlignment = 512; // todo. get this out of sort - if( csCfg.m_enableParallelSolve ) + const int sortAlignment = 512; // todo. get this out of sort + if (csCfg.m_enableParallelSolve) { - - - int sortSize = B3NEXTMULTIPLEOF( nContacts, sortAlignment ); + int sortSize = B3NEXTMULTIPLEOF(nContacts, sortAlignment); b3OpenCLArray<unsigned int>* countsNative = m_data->m_solverGPU->m_numConstraints; b3OpenCLArray<unsigned int>* offsetsNative = m_data->m_solverGPU->m_offsets; - if (!gCpuSetSortData) - { // 2. set cell idx + { // 2. set cell idx B3_PROFILE("GPU set cell idx"); struct CB { @@ -834,29 +728,28 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem b3Int4 m_nSplit; }; - b3Assert( sortSize%64 == 0 ); + b3Assert(sortSize % 64 == 0); CB cdata; cdata.m_nContacts = nContacts; cdata.m_staticIdx = csCfg.m_staticIdx; - cdata.m_scale = 1.f/csCfg.m_batchCellSize; + cdata.m_scale = 1.f / csCfg.m_batchCellSize; cdata.m_nSplit.x = B3_SOLVER_N_SPLIT_X; cdata.m_nSplit.y = B3_SOLVER_N_SPLIT_Y; cdata.m_nSplit.z = B3_SOLVER_N_SPLIT_Z; m_data->m_solverGPU->m_sortDataBuffer->resize(nContacts); - - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( m_data->m_pBufContactOutGPU->getBufferCL() ), b3BufferInfoCL( bodyBuf->getBufferCL()), b3BufferInfoCL( m_data->m_solverGPU->m_sortDataBuffer->getBufferCL()) }; - b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_setSortDataKernel,"m_setSortDataKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata.m_nContacts ); - launcher.setConst( cdata.m_scale ); + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(m_data->m_pBufContactOutGPU->getBufferCL()), b3BufferInfoCL(bodyBuf->getBufferCL()), b3BufferInfoCL(m_data->m_solverGPU->m_sortDataBuffer->getBufferCL())}; + b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_setSortDataKernel, "m_setSortDataKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata.m_nContacts); + launcher.setConst(cdata.m_scale); launcher.setConst(cdata.m_nSplit); launcher.setConst(cdata.m_staticIdx); - - launcher.launch1D( sortSize, 64 ); - } else + launcher.launch1D(sortSize, 64); + } + else { m_data->m_solverGPU->m_sortDataBuffer->resize(nContacts); b3AlignedObjectArray<b3SortData> sortDataCPU; @@ -866,22 +759,19 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem m_data->m_pBufContactOutGPU->copyToHost(contactCPU); b3AlignedObjectArray<b3RigidBodyData> bodiesCPU; bodyBuf->copyToHost(bodiesCPU); - float scale = 1.f/csCfg.m_batchCellSize; + float scale = 1.f / csCfg.m_batchCellSize; b3Int4 nSplit; nSplit.x = B3_SOLVER_N_SPLIT_X; nSplit.y = B3_SOLVER_N_SPLIT_Y; nSplit.z = B3_SOLVER_N_SPLIT_Z; - SetSortDataCPU(&contactCPU[0], &bodiesCPU[0], &sortDataCPU[0], nContacts,scale,nSplit,csCfg.m_staticIdx); - + SetSortDataCPU(&contactCPU[0], &bodiesCPU[0], &sortDataCPU[0], nContacts, scale, nSplit, csCfg.m_staticIdx); m_data->m_solverGPU->m_sortDataBuffer->copyFromHost(sortDataCPU); } - - if (!gCpuRadixSort) - { // 3. sort by cell idx + { // 3. sort by cell idx B3_PROFILE("gpuRadixSort"); //int n = B3_SOLVER_N_SPLIT*B3_SOLVER_N_SPLIT; //int sortBit = 32; @@ -891,10 +781,8 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem //adl::RadixSort32<adl::TYPE_CL>::execute( data->m_sort32, *data->m_sortDataBuffer, sortSize ); b3OpenCLArray<b3SortData>& keyValuesInOut = *(m_data->m_solverGPU->m_sortDataBuffer); this->m_data->m_solverGPU->m_sort32->execute(keyValuesInOut); - - - - } else + } + else { b3OpenCLArray<b3SortData>& keyValuesInOut = *(m_data->m_solverGPU->m_sortDataBuffer); b3AlignedObjectArray<b3SortData> hostValues; @@ -903,7 +791,6 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem keyValuesInOut.copyFromHost(hostValues); } - if (gUseScanHost) { // 4. find entries @@ -914,13 +801,11 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem b3AlignedObjectArray<b3SortData> sortDataHost; m_data->m_solverGPU->m_sortDataBuffer->copyToHost(sortDataHost); - //m_data->m_solverGPU->m_search->executeHost(*m_data->m_solverGPU->m_sortDataBuffer,nContacts,*countsNative,B3_SOLVER_N_CELLS,b3BoundSearchCL::COUNT); - m_data->m_solverGPU->m_search->executeHost(sortDataHost,nContacts,countsHost,B3_SOLVER_N_CELLS,b3BoundSearchCL::COUNT); + m_data->m_solverGPU->m_search->executeHost(sortDataHost, nContacts, countsHost, B3_SOLVER_N_CELLS, b3BoundSearchCL::COUNT); countsNative->copyFromHost(countsHost); - //adl::BoundSearch<adl::TYPE_CL>::execute( data->m_search, *data->m_sortDataBuffer, nContacts, *countsNative, // B3_SOLVER_N_SPLIT*B3_SOLVER_N_SPLIT, adl::BoundSearchBase::COUNT ); @@ -929,24 +814,21 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem b3AlignedObjectArray<unsigned int> offsetsHost; offsetsHost.resize(offsetsNative->size()); - - m_data->m_solverGPU->m_scan->executeHost(countsHost,offsetsHost, B3_SOLVER_N_CELLS);//,&sum ); + m_data->m_solverGPU->m_scan->executeHost(countsHost, offsetsHost, B3_SOLVER_N_CELLS); //,&sum ); offsetsNative->copyFromHost(offsetsHost); //printf("sum = %d\n",sum); - } else + } + else { // 4. find entries B3_PROFILE("gpuBoundSearch"); - m_data->m_solverGPU->m_search->execute(*m_data->m_solverGPU->m_sortDataBuffer,nContacts,*countsNative,B3_SOLVER_N_CELLS,b3BoundSearchCL::COUNT); - m_data->m_solverGPU->m_scan->execute(*countsNative,*offsetsNative, B3_SOLVER_N_CELLS);//,&sum ); - } - - - + m_data->m_solverGPU->m_search->execute(*m_data->m_solverGPU->m_sortDataBuffer, nContacts, *countsNative, B3_SOLVER_N_CELLS, b3BoundSearchCL::COUNT); + m_data->m_solverGPU->m_scan->execute(*countsNative, *offsetsNative, B3_SOLVER_N_CELLS); //,&sum ); + } if (nContacts) - { // 5. sort constraints by cellIdx + { // 5. sort constraints by cellIdx if (gReorderContactsOnCpu) { B3_PROFILE("cpu m_reorderContactKernel"); @@ -956,7 +838,7 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem b3AlignedObjectArray<b3Contact4> outContacts; m_data->m_pBufContactOutGPU->copyToHost(inContacts); outContacts.resize(inContacts.size()); - for (int i=0;i<nContacts;i++) + for (int i = 0; i < nContacts; i++) { int srcIdx = sortDataHost[i].y; outContacts[i] = inContacts[srcIdx]; @@ -974,30 +856,25 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem " }\n" "}\n" */ - } else + } + else { B3_PROFILE("gpu m_reorderContactKernel"); b3Int4 cdata; cdata.x = nContacts; - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( m_data->m_pBufContactOutGPU->getBufferCL() ), - b3BufferInfoCL( m_data->m_solverGPU->m_contactBuffer2->getBufferCL()) - , b3BufferInfoCL( m_data->m_solverGPU->m_sortDataBuffer->getBufferCL()) }; + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(m_data->m_pBufContactOutGPU->getBufferCL()), + b3BufferInfoCL(m_data->m_solverGPU->m_contactBuffer2->getBufferCL()), b3BufferInfoCL(m_data->m_solverGPU->m_sortDataBuffer->getBufferCL())}; - b3LauncherCL launcher(m_data->m_queue,m_data->m_solverGPU->m_reorderContactKernel,"m_reorderContactKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata ); - launcher.launch1D( nContacts, 64 ); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_reorderContactKernel, "m_reorderContactKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata); + launcher.launch1D(nContacts, 64); } } - - - - } - } //clFinish(m_data->m_queue); @@ -1008,48 +885,46 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem // printf(",,,\n"); // } - if (nContacts) { - if (gUseCpuCopyConstraints) { - for (int i=0;i<nContacts;i++) + for (int i = 0; i < nContacts; i++) { m_data->m_pBufContactOutGPU->copyFromOpenCLArray(*m_data->m_solverGPU->m_contactBuffer2); - // m_data->m_solverGPU->m_contactBuffer2->getBufferCL(); - // m_data->m_pBufContactOutGPU->getBufferCL() + // m_data->m_solverGPU->m_contactBuffer2->getBufferCL(); + // m_data->m_pBufContactOutGPU->getBufferCL() } - - } else + } + else { B3_PROFILE("gpu m_copyConstraintKernel"); - b3Int4 cdata; cdata.x = nContacts; - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( m_data->m_solverGPU->m_contactBuffer2->getBufferCL() ), - b3BufferInfoCL( m_data->m_pBufContactOutGPU->getBufferCL() ) - }; - - b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_copyConstraintKernel,"m_copyConstraintKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata ); - launcher.launch1D( nContacts, 64 ); + b3Int4 cdata; + cdata.x = nContacts; + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(m_data->m_solverGPU->m_contactBuffer2->getBufferCL()), + b3BufferInfoCL(m_data->m_pBufContactOutGPU->getBufferCL())}; + + b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_copyConstraintKernel, "m_copyConstraintKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata); + launcher.launch1D(nContacts, 64); //we use the clFinish for proper benchmark/profile clFinish(m_data->m_queue); } } - -// bool compareGPU = false; + // bool compareGPU = false; if (nContacts) { if (!gCpuBatchContacts) { B3_PROFILE("gpu batchContacts"); - maxNumBatches = 250;//250; - m_data->m_solverGPU->batchContacts( m_data->m_pBufContactOutGPU, nContacts, m_data->m_solverGPU->m_numConstraints, m_data->m_solverGPU->m_offsets, csCfg.m_staticIdx ); + maxNumBatches = 250; //250; + m_data->m_solverGPU->batchContacts(m_data->m_pBufContactOutGPU, nContacts, m_data->m_solverGPU->m_numConstraints, m_data->m_solverGPU->m_offsets, csCfg.m_staticIdx); clFinish(m_data->m_queue); - } else + } + else { B3_PROFILE("cpu batchContacts"); static b3AlignedObjectArray<b3Contact4> cpuContacts; @@ -1070,45 +945,43 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem offsetsNative->copyToHost(offsetsNativeHost); } - - int numNonzeroGrid=0; + int numNonzeroGrid = 0; if (gUseLargeBatches) { m_data->m_batchSizes.resize(B3_MAX_NUM_BATCHES); int totalNumConstraints = cpuContacts.size(); //int simdWidth =numBodies+1;//-1;//64;//-1;//32; - int numBatches = sortConstraintByBatch3( &cpuContacts[0], totalNumConstraints, totalNumConstraints+1,csCfg.m_staticIdx ,numBodies,&m_data->m_batchSizes[0]); // on GPU - maxNumBatches = b3Max(numBatches,maxNumBatches); + int numBatches = sortConstraintByBatch3(&cpuContacts[0], totalNumConstraints, totalNumConstraints + 1, csCfg.m_staticIdx, numBodies, &m_data->m_batchSizes[0]); // on GPU + maxNumBatches = b3Max(numBatches, maxNumBatches); static int globalMaxBatch = 0; - if (maxNumBatches>globalMaxBatch ) + if (maxNumBatches > globalMaxBatch) { - globalMaxBatch = maxNumBatches; - b3Printf("maxNumBatches = %d\n",maxNumBatches); + globalMaxBatch = maxNumBatches; + b3Printf("maxNumBatches = %d\n", maxNumBatches); } - - } else + } + else { - m_data->m_batchSizes.resize(B3_SOLVER_N_CELLS*B3_MAX_NUM_BATCHES); + m_data->m_batchSizes.resize(B3_SOLVER_N_CELLS * B3_MAX_NUM_BATCHES); B3_PROFILE("cpu batch grid"); - for(int i=0; i<B3_SOLVER_N_CELLS; i++) + for (int i = 0; i < B3_SOLVER_N_CELLS; i++) { int n = (nNativeHost)[i]; int offset = (offsetsNativeHost)[i]; - if( n ) + if (n) { numNonzeroGrid++; - int simdWidth =numBodies+1;//-1;//64;//-1;//32; - int numBatches = sortConstraintByBatch3( &cpuContacts[0]+offset, n, simdWidth,csCfg.m_staticIdx ,numBodies,&m_data->m_batchSizes[i*B3_MAX_NUM_BATCHES]); // on GPU - maxNumBatches = b3Max(numBatches,maxNumBatches); + int simdWidth = numBodies + 1; //-1;//64;//-1;//32; + int numBatches = sortConstraintByBatch3(&cpuContacts[0] + offset, n, simdWidth, csCfg.m_staticIdx, numBodies, &m_data->m_batchSizes[i * B3_MAX_NUM_BATCHES]); // on GPU + maxNumBatches = b3Max(numBatches, maxNumBatches); static int globalMaxBatch = 0; - if (maxNumBatches>globalMaxBatch ) + if (maxNumBatches > globalMaxBatch) { - globalMaxBatch = maxNumBatches; - b3Printf("maxNumBatches = %d\n",maxNumBatches); + globalMaxBatch = maxNumBatches; + b3Printf("maxNumBatches = %d\n", maxNumBatches); } //we use the clFinish for proper benchmark/profile - } } //clFinish(m_data->m_queue); @@ -1117,22 +990,12 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem B3_PROFILE("m_contactBuffer->copyFromHost"); m_data->m_solverGPU->m_contactBuffer2->copyFromHost((b3AlignedObjectArray<b3Contact4>&)cpuContacts); } - - } - + } } + } + } - - - - - } - - - } - - - //printf("maxNumBatches = %d\n", maxNumBatches); + //printf("maxNumBatches = %d\n", maxNumBatches); if (gUseLargeBatches) { @@ -1140,58 +1003,52 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem { B3_PROFILE("cpu batchContacts"); static b3AlignedObjectArray<b3Contact4> cpuContacts; -// b3OpenCLArray<b3Contact4>* contactsIn = m_data->m_solverGPU->m_contactBuffer2; + // b3OpenCLArray<b3Contact4>* contactsIn = m_data->m_solverGPU->m_contactBuffer2; { B3_PROFILE("copyToHost"); m_data->m_pBufContactOutGPU->copyToHost(cpuContacts); } -// b3OpenCLArray<unsigned int>* countsNative = m_data->m_solverGPU->m_numConstraints; -// b3OpenCLArray<unsigned int>* offsetsNative = m_data->m_solverGPU->m_offsets; - + // b3OpenCLArray<unsigned int>* countsNative = m_data->m_solverGPU->m_numConstraints; + // b3OpenCLArray<unsigned int>* offsetsNative = m_data->m_solverGPU->m_offsets; - -// int numNonzeroGrid=0; + // int numNonzeroGrid=0; { m_data->m_batchSizes.resize(B3_MAX_NUM_BATCHES); int totalNumConstraints = cpuContacts.size(); - // int simdWidth =numBodies+1;//-1;//64;//-1;//32; - int numBatches = sortConstraintByBatch3( &cpuContacts[0], totalNumConstraints, totalNumConstraints+1,csCfg.m_staticIdx ,numBodies,&m_data->m_batchSizes[0]); // on GPU - maxNumBatches = b3Max(numBatches,maxNumBatches); + // int simdWidth =numBodies+1;//-1;//64;//-1;//32; + int numBatches = sortConstraintByBatch3(&cpuContacts[0], totalNumConstraints, totalNumConstraints + 1, csCfg.m_staticIdx, numBodies, &m_data->m_batchSizes[0]); // on GPU + maxNumBatches = b3Max(numBatches, maxNumBatches); static int globalMaxBatch = 0; - if (maxNumBatches>globalMaxBatch ) + if (maxNumBatches > globalMaxBatch) { - globalMaxBatch = maxNumBatches; - b3Printf("maxNumBatches = %d\n",maxNumBatches); + globalMaxBatch = maxNumBatches; + b3Printf("maxNumBatches = %d\n", maxNumBatches); } - } { B3_PROFILE("m_contactBuffer->copyFromHost"); m_data->m_solverGPU->m_contactBuffer2->copyFromHost((b3AlignedObjectArray<b3Contact4>&)cpuContacts); } - - } - + } } if (nContacts) { B3_PROFILE("gpu convertToConstraints"); - m_data->m_solverGPU->convertToConstraints( bodyBuf, - shapeBuf, m_data->m_solverGPU->m_contactBuffer2, - contactConstraintOut, - additionalData, nContacts, - (b3SolverBase::ConstraintCfg&) csCfg ); + m_data->m_solverGPU->convertToConstraints(bodyBuf, + shapeBuf, m_data->m_solverGPU->m_contactBuffer2, + contactConstraintOut, + additionalData, nContacts, + (b3SolverBase::ConstraintCfg&)csCfg); clFinish(m_data->m_queue); } - if (1) { int numIter = 4; - m_data->m_solverGPU->m_nIterations = numIter;//10 + m_data->m_solverGPU->m_nIterations = numIter; //10 if (!gCpuSolveConstraint) { B3_PROFILE("GPU solveContactConstraint"); @@ -1208,32 +1065,30 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem if (gUseLargeBatches) { - solveContactConstraintBatchSizes(m_data->m_bodyBufferGPU, - m_data->m_inertiaBufferGPU, - m_data->m_contactCGPU,0, - nContactOut , - maxNumBatches,numIter,&m_data->m_batchSizes); - } else + solveContactConstraintBatchSizes(m_data->m_bodyBufferGPU, + m_data->m_inertiaBufferGPU, + m_data->m_contactCGPU, 0, + nContactOut, + maxNumBatches, numIter, &m_data->m_batchSizes); + } + else { solveContactConstraint( - m_data->m_bodyBufferGPU, + m_data->m_bodyBufferGPU, m_data->m_inertiaBufferGPU, - m_data->m_contactCGPU,0, - nContactOut , - maxNumBatches,numIter,&m_data->m_batchSizes);//m_data->m_batchSizesGpu); + m_data->m_contactCGPU, 0, + nContactOut, + maxNumBatches, numIter, &m_data->m_batchSizes); //m_data->m_batchSizesGpu); } } else { B3_PROFILE("Host solveContactConstraint"); - m_data->m_solverGPU->solveContactConstraintHost(m_data->m_bodyBufferGPU, m_data->m_inertiaBufferGPU, m_data->m_contactCGPU,0, nContactOut ,maxNumBatches,&m_data->m_batchSizes); + m_data->m_solverGPU->solveContactConstraintHost(m_data->m_bodyBufferGPU, m_data->m_inertiaBufferGPU, m_data->m_contactCGPU, 0, nContactOut, maxNumBatches, &m_data->m_batchSizes); } - - - } - - + } + #if 0 if (0) { @@ -1244,114 +1099,96 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem adl::DeviceUtils::waitForCompletion( m_data->m_deviceCL ); } #endif - - } - + } } - -void b3GpuPgsContactSolver::batchContacts( b3OpenCLArray<b3Contact4>* contacts, int nContacts, b3OpenCLArray<unsigned int>* n, b3OpenCLArray<unsigned int>* offsets, int staticIdx ) +void b3GpuPgsContactSolver::batchContacts(b3OpenCLArray<b3Contact4>* contacts, int nContacts, b3OpenCLArray<unsigned int>* n, b3OpenCLArray<unsigned int>* offsets, int staticIdx) { } - - - - - - - - - - b3AlignedObjectArray<unsigned int> idxBuffer; b3AlignedObjectArray<b3SortData> sortData; b3AlignedObjectArray<b3Contact4> old; - -inline int b3GpuPgsContactSolver::sortConstraintByBatch( b3Contact4* cs, int n, int simdWidth , int staticIdx, int numBodies) +inline int b3GpuPgsContactSolver::sortConstraintByBatch(b3Contact4* cs, int n, int simdWidth, int staticIdx, int numBodies) { - B3_PROFILE("sortConstraintByBatch"); int numIter = 0; - + sortData.resize(n); idxBuffer.resize(n); old.resize(n); - + unsigned int* idxSrc = &idxBuffer[0]; unsigned int* idxDst = &idxBuffer[0]; int nIdxSrc, nIdxDst; - + const int N_FLG = 256; - const int FLG_MASK = N_FLG-1; - unsigned int flg[N_FLG/32]; + const int FLG_MASK = N_FLG - 1; + unsigned int flg[N_FLG / 32]; #if defined(_DEBUG) - for(int i=0; i<n; i++) + for (int i = 0; i < n; i++) cs[i].getBatchIdx() = -1; #endif - for(int i=0; i<n; i++) + for (int i = 0; i < n; i++) idxSrc[i] = i; nIdxSrc = n; - + int batchIdx = 0; - + { B3_PROFILE("cpu batch innerloop"); - while( nIdxSrc ) + while (nIdxSrc) { numIter++; nIdxDst = 0; int nCurrentBatch = 0; - + // clear flag - for(int i=0; i<N_FLG/32; i++) flg[i] = 0; - - for(int i=0; i<nIdxSrc; i++) + for (int i = 0; i < N_FLG / 32; i++) flg[i] = 0; + + for (int i = 0; i < nIdxSrc; i++) { int idx = idxSrc[i]; - - b3Assert( idx < n ); + b3Assert(idx < n); // check if it can go int bodyAS = cs[idx].m_bodyAPtrAndSignBit; int bodyBS = cs[idx].m_bodyBPtrAndSignBit; - - - + int bodyA = abs(bodyAS); int bodyB = abs(bodyBS); - + int aIdx = bodyA & FLG_MASK; int bIdx = bodyB & FLG_MASK; - - unsigned int aUnavailable = flg[ aIdx/32 ] & (1<<(aIdx&31)); - unsigned int bUnavailable = flg[ bIdx/32 ] & (1<<(bIdx&31)); - - bool aIsStatic = (bodyAS<0) || bodyAS==staticIdx; - bool bIsStatic = (bodyBS<0) || bodyBS==staticIdx; - - //use inv_mass! - aUnavailable = !aIsStatic? aUnavailable:0;// - bUnavailable = !bIsStatic? bUnavailable:0; - - if( aUnavailable==0 && bUnavailable==0 ) // ok + + unsigned int aUnavailable = flg[aIdx / 32] & (1 << (aIdx & 31)); + unsigned int bUnavailable = flg[bIdx / 32] & (1 << (bIdx & 31)); + + bool aIsStatic = (bodyAS < 0) || bodyAS == staticIdx; + bool bIsStatic = (bodyBS < 0) || bodyBS == staticIdx; + + //use inv_mass! + aUnavailable = !aIsStatic ? aUnavailable : 0; // + bUnavailable = !bIsStatic ? bUnavailable : 0; + + if (aUnavailable == 0 && bUnavailable == 0) // ok { if (!aIsStatic) - flg[ aIdx/32 ] |= (1<<(aIdx&31)); + flg[aIdx / 32] |= (1 << (aIdx & 31)); if (!bIsStatic) - flg[ bIdx/32 ] |= (1<<(bIdx&31)); + flg[bIdx / 32] |= (1 << (bIdx & 31)); cs[idx].getBatchIdx() = batchIdx; sortData[idx].m_key = batchIdx; sortData[idx].m_value = idx; - + { nCurrentBatch++; - if( nCurrentBatch == simdWidth ) + if (nCurrentBatch == simdWidth) { nCurrentBatch = 0; - for(int i=0; i<N_FLG/32; i++) flg[i] = 0; + for (int i = 0; i < N_FLG / 32; i++) flg[i] = 0; } } } @@ -1360,128 +1197,121 @@ inline int b3GpuPgsContactSolver::sortConstraintByBatch( b3Contact4* cs, int n, idxDst[nIdxDst++] = idx; } } - b3Swap( idxSrc, idxDst ); - b3Swap( nIdxSrc, nIdxDst ); - batchIdx ++; + b3Swap(idxSrc, idxDst); + b3Swap(nIdxSrc, nIdxDst); + batchIdx++; } } { B3_PROFILE("quickSort"); sortData.quickSort(sortfnc); } - - + { - B3_PROFILE("reorder"); + B3_PROFILE("reorder"); // reorder - - memcpy( &old[0], cs, sizeof(b3Contact4)*n); - for(int i=0; i<n; i++) + + memcpy(&old[0], cs, sizeof(b3Contact4) * n); + for (int i = 0; i < n; i++) { int idx = sortData[i].m_value; cs[i] = old[idx]; } } - - + #if defined(_DEBUG) - // debugPrintf( "nBatches: %d\n", batchIdx ); - for(int i=0; i<n; i++) - { - b3Assert( cs[i].getBatchIdx() != -1 ); - } + // debugPrintf( "nBatches: %d\n", batchIdx ); + for (int i = 0; i < n; i++) + { + b3Assert(cs[i].getBatchIdx() != -1); + } #endif return batchIdx; } - b3AlignedObjectArray<int> bodyUsed2; -inline int b3GpuPgsContactSolver::sortConstraintByBatch2( b3Contact4* cs, int numConstraints, int simdWidth , int staticIdx, int numBodies) +inline int b3GpuPgsContactSolver::sortConstraintByBatch2(b3Contact4* cs, int numConstraints, int simdWidth, int staticIdx, int numBodies) { - B3_PROFILE("sortConstraintByBatch2"); - - - bodyUsed2.resize(2*simdWidth); + bodyUsed2.resize(2 * simdWidth); - for (int q=0;q<2*simdWidth;q++) - bodyUsed2[q]=0; + for (int q = 0; q < 2 * simdWidth; q++) + bodyUsed2[q] = 0; int curBodyUsed = 0; int numIter = 0; - + m_data->m_sortData.resize(numConstraints); m_data->m_idxBuffer.resize(numConstraints); m_data->m_old.resize(numConstraints); - + unsigned int* idxSrc = &m_data->m_idxBuffer[0]; - + #if defined(_DEBUG) - for(int i=0; i<numConstraints; i++) + for (int i = 0; i < numConstraints; i++) cs[i].getBatchIdx() = -1; #endif - for(int i=0; i<numConstraints; i++) + for (int i = 0; i < numConstraints; i++) idxSrc[i] = i; - + int numValidConstraints = 0; -// int unprocessedConstraintIndex = 0; + // int unprocessedConstraintIndex = 0; int batchIdx = 0; - { B3_PROFILE("cpu batch innerloop"); - - while( numValidConstraints < numConstraints) + + while (numValidConstraints < numConstraints) { numIter++; int nCurrentBatch = 0; // clear flag - for(int i=0; i<curBodyUsed; i++) + for (int i = 0; i < curBodyUsed; i++) bodyUsed2[i] = 0; - curBodyUsed = 0; + curBodyUsed = 0; - for(int i=numValidConstraints; i<numConstraints; i++) + for (int i = numValidConstraints; i < numConstraints; i++) { int idx = idxSrc[i]; - b3Assert( idx < numConstraints ); + b3Assert(idx < numConstraints); // check if it can go int bodyAS = cs[idx].m_bodyAPtrAndSignBit; int bodyBS = cs[idx].m_bodyBPtrAndSignBit; int bodyA = abs(bodyAS); int bodyB = abs(bodyBS); - bool aIsStatic = (bodyAS<0) || bodyAS==staticIdx; - bool bIsStatic = (bodyBS<0) || bodyBS==staticIdx; + bool aIsStatic = (bodyAS < 0) || bodyAS == staticIdx; + bool bIsStatic = (bodyBS < 0) || bodyBS == staticIdx; int aUnavailable = 0; int bUnavailable = 0; if (!aIsStatic) { - for (int j=0;j<curBodyUsed;j++) + for (int j = 0; j < curBodyUsed; j++) { if (bodyA == bodyUsed2[j]) { - aUnavailable=1; + aUnavailable = 1; break; } } } if (!aUnavailable) - if (!bIsStatic) - { - for (int j=0;j<curBodyUsed;j++) + if (!bIsStatic) { - if (bodyB == bodyUsed2[j]) + for (int j = 0; j < curBodyUsed; j++) { - bUnavailable=1; - break; + if (bodyB == bodyUsed2[j]) + { + bUnavailable = 1; + break; + } } } - } - - if( aUnavailable==0 && bUnavailable==0 ) // ok + + if (aUnavailable == 0 && bUnavailable == 0) // ok { if (!aIsStatic) { @@ -1496,7 +1326,7 @@ inline int b3GpuPgsContactSolver::sortConstraintByBatch2( b3Contact4* cs, int nu m_data->m_sortData[idx].m_key = batchIdx; m_data->m_sortData[idx].m_value = idx; - if (i!=numValidConstraints) + if (i != numValidConstraints) { b3Swap(idxSrc[i], idxSrc[numValidConstraints]); } @@ -1504,20 +1334,19 @@ inline int b3GpuPgsContactSolver::sortConstraintByBatch2( b3Contact4* cs, int nu numValidConstraints++; { nCurrentBatch++; - if( nCurrentBatch == simdWidth ) + if (nCurrentBatch == simdWidth) { nCurrentBatch = 0; - for(int i=0; i<curBodyUsed; i++) + for (int i = 0; i < curBodyUsed; i++) bodyUsed2[i] = 0; - curBodyUsed = 0; } } } } - - batchIdx ++; + + batchIdx++; } } { @@ -1526,155 +1355,148 @@ inline int b3GpuPgsContactSolver::sortConstraintByBatch2( b3Contact4* cs, int nu } { - B3_PROFILE("reorder"); + B3_PROFILE("reorder"); // reorder - - memcpy( &m_data->m_old[0], cs, sizeof(b3Contact4)*numConstraints); - for(int i=0; i<numConstraints; i++) + memcpy(&m_data->m_old[0], cs, sizeof(b3Contact4) * numConstraints); + + for (int i = 0; i < numConstraints; i++) { b3Assert(m_data->m_sortData[idxSrc[i]].m_value == idxSrc[i]); int idx = m_data->m_sortData[idxSrc[i]].m_value; cs[i] = m_data->m_old[idx]; } } - + #if defined(_DEBUG) - // debugPrintf( "nBatches: %d\n", batchIdx ); - for(int i=0; i<numConstraints; i++) - { - b3Assert( cs[i].getBatchIdx() != -1 ); - } + // debugPrintf( "nBatches: %d\n", batchIdx ); + for (int i = 0; i < numConstraints; i++) + { + b3Assert(cs[i].getBatchIdx() != -1); + } #endif - return batchIdx; } - b3AlignedObjectArray<int> bodyUsed; b3AlignedObjectArray<int> curUsed; - -inline int b3GpuPgsContactSolver::sortConstraintByBatch3( b3Contact4* cs, int numConstraints, int simdWidth , int staticIdx, int numBodies, int* batchSizes) +inline int b3GpuPgsContactSolver::sortConstraintByBatch3(b3Contact4* cs, int numConstraints, int simdWidth, int staticIdx, int numBodies, int* batchSizes) { - B3_PROFILE("sortConstraintByBatch3"); - + static int maxSwaps = 0; int numSwaps = 0; - curUsed.resize(2*simdWidth); + curUsed.resize(2 * simdWidth); static int maxNumConstraints = 0; - if (maxNumConstraints<numConstraints) + if (maxNumConstraints < numConstraints) { maxNumConstraints = numConstraints; //printf("maxNumConstraints = %d\n",maxNumConstraints ); } - int numUsedArray = numBodies/32+1; + int numUsedArray = numBodies / 32 + 1; bodyUsed.resize(numUsedArray); - for (int q=0;q<numUsedArray;q++) - bodyUsed[q]=0; + for (int q = 0; q < numUsedArray; q++) + bodyUsed[q] = 0; - int curBodyUsed = 0; int numIter = 0; - + m_data->m_sortData.resize(0); m_data->m_idxBuffer.resize(0); m_data->m_old.resize(0); - - + #if defined(_DEBUG) - for(int i=0; i<numConstraints; i++) + for (int i = 0; i < numConstraints; i++) cs[i].getBatchIdx() = -1; #endif - + int numValidConstraints = 0; -// int unprocessedConstraintIndex = 0; + // int unprocessedConstraintIndex = 0; int batchIdx = 0; - { B3_PROFILE("cpu batch innerloop"); - - while( numValidConstraints < numConstraints) + + while (numValidConstraints < numConstraints) { numIter++; int nCurrentBatch = 0; batchSizes[batchIdx] = 0; // clear flag - for(int i=0; i<curBodyUsed; i++) - bodyUsed[curUsed[i]/32] = 0; + for (int i = 0; i < curBodyUsed; i++) + bodyUsed[curUsed[i] / 32] = 0; - curBodyUsed = 0; + curBodyUsed = 0; - for(int i=numValidConstraints; i<numConstraints; i++) + for (int i = numValidConstraints; i < numConstraints; i++) { int idx = i; - b3Assert( idx < numConstraints ); + b3Assert(idx < numConstraints); // check if it can go int bodyAS = cs[idx].m_bodyAPtrAndSignBit; int bodyBS = cs[idx].m_bodyBPtrAndSignBit; int bodyA = abs(bodyAS); int bodyB = abs(bodyBS); - bool aIsStatic = (bodyAS<0) || bodyAS==staticIdx; - bool bIsStatic = (bodyBS<0) || bodyBS==staticIdx; + bool aIsStatic = (bodyAS < 0) || bodyAS == staticIdx; + bool bIsStatic = (bodyBS < 0) || bodyBS == staticIdx; int aUnavailable = 0; int bUnavailable = 0; if (!aIsStatic) { - aUnavailable = bodyUsed[ bodyA/32 ] & (1<<(bodyA&31)); + aUnavailable = bodyUsed[bodyA / 32] & (1 << (bodyA & 31)); } if (!aUnavailable) - if (!bIsStatic) - { - bUnavailable = bodyUsed[ bodyB/32 ] & (1<<(bodyB&31)); - } - - if( aUnavailable==0 && bUnavailable==0 ) // ok + if (!bIsStatic) + { + bUnavailable = bodyUsed[bodyB / 32] & (1 << (bodyB & 31)); + } + + if (aUnavailable == 0 && bUnavailable == 0) // ok { if (!aIsStatic) { - bodyUsed[ bodyA/32 ] |= (1<<(bodyA&31)); - curUsed[curBodyUsed++]=bodyA; + bodyUsed[bodyA / 32] |= (1 << (bodyA & 31)); + curUsed[curBodyUsed++] = bodyA; } if (!bIsStatic) { - bodyUsed[ bodyB/32 ] |= (1<<(bodyB&31)); - curUsed[curBodyUsed++]=bodyB; + bodyUsed[bodyB / 32] |= (1 << (bodyB & 31)); + curUsed[curBodyUsed++] = bodyB; } cs[idx].getBatchIdx() = batchIdx; - if (i!=numValidConstraints) + if (i != numValidConstraints) { - b3Swap(cs[i],cs[numValidConstraints]); + b3Swap(cs[i], cs[numValidConstraints]); numSwaps++; } numValidConstraints++; { nCurrentBatch++; - if( nCurrentBatch == simdWidth ) + if (nCurrentBatch == simdWidth) { batchSizes[batchIdx] += simdWidth; nCurrentBatch = 0; - for(int i=0; i<curBodyUsed; i++) - bodyUsed[curUsed[i]/32] = 0; + for (int i = 0; i < curBodyUsed; i++) + bodyUsed[curUsed[i] / 32] = 0; curBodyUsed = 0; } } } } - if (batchIdx>=B3_MAX_NUM_BATCHES) + if (batchIdx >= B3_MAX_NUM_BATCHES) { b3Error("batchIdx>=B3_MAX_NUM_BATCHES"); b3Assert(0); @@ -1683,26 +1505,25 @@ inline int b3GpuPgsContactSolver::sortConstraintByBatch3( b3Contact4* cs, int nu batchSizes[batchIdx] += nCurrentBatch; - batchIdx ++; - + batchIdx++; } } - + #if defined(_DEBUG) - // debugPrintf( "nBatches: %d\n", batchIdx ); - for(int i=0; i<numConstraints; i++) - { - b3Assert( cs[i].getBatchIdx() != -1 ); - } + // debugPrintf( "nBatches: %d\n", batchIdx ); + for (int i = 0; i < numConstraints; i++) + { + b3Assert(cs[i].getBatchIdx() != -1); + } #endif - batchSizes[batchIdx] =0; - - if (maxSwaps<numSwaps) + batchSizes[batchIdx] = 0; + + if (maxSwaps < numSwaps) { maxSwaps = numSwaps; //printf("maxSwaps = %d\n", maxSwaps); } - + return batchIdx; } |