Commit 8db0160a authored by berenger-bramas's avatar berenger-bramas

P2P threaded has changed :

now the cells to compute are taken not from the address in the momery
but from the morton index.

Then to compute P2P between two cells we do something like :
if( cell1.index < cell2.index)
    compute(cell1,cell2)
else
    //it has already been computed or will be next time

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@94 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 76c383e2
......@@ -77,6 +77,20 @@ public:
*/
virtual void P2P(FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>*const FRestrict *const FRestrict directNeighborsParticles, const int size) = 0;
/**
* P2P
* Particles to particles
* @param inCurrentLeafIndex
* @param targets current boxe targets particles
* @param sources current boxe sources particles
* @param directNeighborsParticles the particles from direct neighbors (this is an array of list)
* @param inNeighborsIndex the indexes of neighbors
* @param size the number of direct neighbors (the size of the array directNeighborsParticles)
*/
virtual void P2P(const MortonIndex inCurrentLeafIndex,
FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>* FRestrict const* FRestrict directNeighbors, MortonIndex const* FRestrict inNeighborsIndex, const int size) = 0;
};
......
......@@ -34,6 +34,7 @@ public:
pole->setDataUp(particles->getSize());
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
// During upward
void M2M(CellClass* const FRestrict pole, const CellClass *const FRestrict *const FRestrict child, const int ) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
......@@ -45,6 +46,7 @@ public:
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
// Before Downward
void M2L(CellClass* const FRestrict pole, const CellClass*const FRestrict *const distantNeighbors, const int size, const int ) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
......@@ -54,6 +56,7 @@ public:
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
// During Downward
void L2L(const CellClass*const FRestrict local, CellClass* FRestrict *const FRestrict child, const int) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
......@@ -65,6 +68,7 @@ public:
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
// After Downward
void L2P(const CellClass* const local, FList<ParticleClass*>*const particles){
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
......@@ -76,6 +80,7 @@ public:
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
// After Downward
void P2P(FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>* FRestrict const* FRestrict directNeighbors, const int size) {
......@@ -97,6 +102,29 @@ public:
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
// After Downward
void P2P(const MortonIndex,
FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>* FRestrict const* FRestrict directNeighbors,
MortonIndex const* FRestrict, const int size) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
// Each particles targeted is impacted by the particles sources
long inc = sources->getSize();
if(targets == sources){
inc -= 1;
}
for(int idx = 0 ; idx < size ; ++idx){
inc += directNeighbors[idx]->getSize();
}
typename FList<ParticleClass*>::BasicIterator iter(*targets);
while( iter.isValide() ){
iter.value()->setDataDown(iter.value()->getDataDown() + inc);
iter.progress();
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
};
......
......@@ -331,16 +331,18 @@ public:
Kernel * const myThreadkernels = kernels[omp_get_thread_num()];
// There is a maximum of 26 neighbors
FList<ParticleClass*>* neighbors[26];
MortonIndex neighborsIndex[26];
for(int idxShape = 0 ; idxShape < SizeShape ; ++idxShape){
const int leafAtThisShape = this->shapeLeaf[idxShape];
#pragma omp for
for(int idxLeafs = 0 ; idxLeafs < leafAtThisShape ; ++idxLeafs){
myThreadkernels->L2P(shapeArray[idxShape][idxLeafs].getCurrentCell(), shapeArray[idxShape][idxLeafs].getCurrentListTargets());
OctreeIterator currentIter = shapeArray[idxShape][idxLeafs];
myThreadkernels->L2P(currentIter.getCurrentCell(), currentIter.getCurrentListTargets());
// need the current particles and neighbors particles
const int counter = tree->getLeafsNeighbors(neighbors, shapeArray[idxShape][idxLeafs].getCurrentGlobalIndex(),LeafIndex);
myThreadkernels->P2P( shapeArray[idxShape][idxLeafs].getCurrentListTargets(), shapeArray[idxShape][idxLeafs].getCurrentListSrc() , neighbors, counter);
const int counter = tree->getLeafsNeighborsWithIndex(neighbors, neighborsIndex, currentIter.getCurrentGlobalIndex(), LeafIndex);
myThreadkernels->P2P(currentIter.getCurrentGlobalIndex(), currentIter.getCurrentListTargets(), currentIter.getCurrentListSrc() , neighbors, neighborsIndex, counter);
}
}
}
......
......@@ -864,16 +864,18 @@ public:
Kernel * const myThreadkernels = kernels[omp_get_thread_num()];
// There is a maximum of 26 neighbors
FList<ParticleClass*>* neighbors[26];
MortonIndex neighborsIndex[26];
for(int idxShape = 0 ; idxShape < SizeShape ; ++idxShape){
const int leafAtThisShape = shapeLeaf[idxShape];
#pragma omp for
for(int idxLeafs = startIdx ; idxLeafs < leafAtThisShape ; ++idxLeafs){
myThreadkernels->L2P(shapeArray[idxShape][idxLeafs].getCurrentCell(), shapeArray[idxShape][idxLeafs].getCurrentListTargets());
OctreeIterator currentIter = shapeArray[idxShape][idxLeafs];
myThreadkernels->L2P(currentIter.getCurrentCell(), currentIter.getCurrentListTargets());
// need the current particles and neighbors particles
const int counter = tree->getLeafsNeighbors(neighbors, shapeArray[idxShape][idxLeafs].getCurrentGlobalIndex(),LeafIndex);
myThreadkernels->P2P( shapeArray[idxShape][idxLeafs].getCurrentListTargets(), shapeArray[idxShape][idxLeafs].getCurrentListSrc() , neighbors, counter);
const int counter = tree->getLeafsNeighborsWithIndex(neighbors, neighborsIndex, currentIter.getCurrentGlobalIndex(),LeafIndex);
myThreadkernels->P2P( currentIter.getCurrentGlobalIndex(), currentIter.getCurrentListTargets(), currentIter.getCurrentListSrc() , neighbors, neighborsIndex, counter);
}
}
}
......
......@@ -97,8 +97,6 @@ protected:
int expansion_Redirection_array_for_j[FMB_Info_M2L_P + 1 ];
// To know if we use mutal version
const bool UseMutual;
//////////////////////////////////////////////////////////////////
// Allocation
......@@ -621,13 +619,13 @@ protected:
FFmbKernels& operator=(const FFmbKernels&){ return *this; }
public:
FFmbKernels(const FReal inTreeWidth, const bool inUseMutual = true) :
treeWidthAtRoot(inTreeWidth), UseMutual(inUseMutual) {
FFmbKernels(const FReal inTreeWidth) :
treeWidthAtRoot(inTreeWidth) {
buildPrecompute();
}
FFmbKernels(const FFmbKernels& other)
: treeWidthAtRoot(other.treeWidthAtRoot), UseMutual(other.UseMutual) {
: treeWidthAtRoot(other.treeWidthAtRoot) {
buildPrecompute();
}
......@@ -1321,13 +1319,6 @@ public:
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
void P2P(FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>* FRestrict const* FRestrict directNeighbors, const int size){
if(UseMutual) P2P_Mutual(targets,sources,directNeighbors,size);
else P2P_No_Mutual(targets,sources,directNeighbors,size);
}
///////////////////////////////////////////////////////////////////////////////
// MUTUAL - Need
///////////////////////////////////////////////////////////////////////////////
......@@ -1340,18 +1331,21 @@ public:
* )
*
*/
void P2P_Mutual(FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>* FRestrict const* FRestrict directNeighbors, const int size) {
void P2P(const MortonIndex inCurrentIndex,
FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>* FRestrict const* FRestrict directNeighbors, MortonIndex const* FRestrict inNeighborsIndex, const int size) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
typename FList<ParticleClass*>::BasicIterator iterTarget(*targets);
while( iterTarget.isValide() ){
for(int idxDirectNeighbors = 0 ; idxDirectNeighbors < size ; ++idxDirectNeighbors){
typename FList<ParticleClass*>::BasicIterator iterSource(*directNeighbors[idxDirectNeighbors]);
while( iterSource.isValide() ){
DIRECT_COMPUTATION_MUTUAL_SOFT(&iterTarget.value(),
&iterSource.value());
iterSource.progress();
if(inCurrentIndex < inNeighborsIndex[idxDirectNeighbors] ){
typename FList<ParticleClass*>::BasicIterator iterSource(*directNeighbors[idxDirectNeighbors]);
while( iterSource.isValide() ){
DIRECT_COMPUTATION_MUTUAL_SOFT(&iterTarget.value(),
&iterSource.value());
iterSource.progress();
}
}
}
......@@ -1415,7 +1409,7 @@ public:
* )
*
*/
void P2P_No_Mutual(FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
void P2P(FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>* FRestrict const* FRestrict directNeighbors, const int size) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
typename FList<ParticleClass*>::BasicIterator iterTarget(*targets);
......
......@@ -1370,8 +1370,89 @@ public:
}
///////////////////////////////////////////////////////////////////////////////
// MUTUAL - Need
///////////////////////////////////////////////////////////////////////////////
/** void bodies_Compute_direct_interaction (
* bodies_t *FMB_RESTRICT p_b_target,
* bodies_t *FMB_RESTRICT p_b_src,
* bool mutual
* )
*
*/
void P2P(const MortonIndex inCurrentIndex,
FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>* FRestrict const* FRestrict directNeighbors, MortonIndex const* FRestrict inNeighborsIndex, const int size) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
typename FList<ParticleClass*>::BasicIterator iterTarget(*targets);
while( iterTarget.isValide() ){
for(int idxDirectNeighbors = 0 ; idxDirectNeighbors < size ; ++idxDirectNeighbors){
if(inCurrentIndex < inNeighborsIndex[idxDirectNeighbors] ){
typename FList<ParticleClass*>::BasicIterator iterSource(*directNeighbors[idxDirectNeighbors]);
while( iterSource.isValide() ){
DIRECT_COMPUTATION_MUTUAL_SOFT(&iterTarget.value(),
&iterSource.value());
iterSource.progress();
}
}
}
typename FList<ParticleClass*>::BasicIterator iterSameBox = iterTarget;//(*targets);
iterSameBox.progress();
while( iterSameBox.isValide() ){
if(iterSameBox.value() < iterTarget.value()){
DIRECT_COMPUTATION_MUTUAL_SOFT(&iterTarget.value(),
&iterSameBox.value());
}
iterSameBox.progress();
}
//printf("x = %e \t y = %e \t z = %e \n",iterTarget.value()->getPosition().getX(),iterTarget.value()->getPosition().getY(),iterTarget.value()->getPosition().getZ());
//printf("\t P2P fx = %e \t fy = %e \t fz = %e \n",iterTarget.value()->getForces().getX(),iterTarget.value()->getForces().getY(),iterTarget.value()->getForces().getZ());
//printf("\t potential = %e \n",iterTarget.value()->getPotential());
iterTarget.progress();
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
void DIRECT_COMPUTATION_MUTUAL_SOFT(ParticleClass** const target, ParticleClass** const source){
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
const FReal dx = (*target)->getPosition().getX() - (*source)->getPosition().getX();
const FReal dy = (*target)->getPosition().getY() - (*source)->getPosition().getY();
const FReal dz = (*target)->getPosition().getZ() - (*source)->getPosition().getZ();
FReal inv_square_distance = 1.0/ (dx*dx + dy*dy + dz*dz + FMB_Info_eps_soft_square);
FReal inv_distance = FMath::Sqrt(inv_square_distance);
inv_distance *= (*target)->getPhysicalValue() * (*source)->getPhysicalValue();
inv_square_distance *= inv_distance;
(*target)->setForces(
(*target)->getForces().getX() + dx * inv_square_distance,
(*target)->getForces().getY() + dy * inv_square_distance,
(*target)->getForces().getZ() + dz * inv_square_distance
);
(*target)->setPotential( inv_distance + (*target)->getPotential());
(*source)->setForces(
(*source)->getForces().getX() + (-dx) * inv_square_distance,
(*source)->getForces().getY() + (-dy) * inv_square_distance,
(*source)->getForces().getZ() + (-dz) * inv_square_distance
);
(*source)->setPotential( inv_distance + (*source)->getPotential());
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
///////////////////////////////////////////////////////////////////////////////
// NO MUTUAL
///////////////////////////////////////////////////////////////////////////////
/** void bodies_Compute_direct_interaction (
* bodies_t *FMB_RESTRICT p_b_target,
* bodies_t *FMB_RESTRICT p_b_src,
......
......@@ -1623,8 +1623,89 @@ public:
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
///////////////////////////////////////////////////////////////////////////////
// MUTUAL - Need
///////////////////////////////////////////////////////////////////////////////
/** void bodies_Compute_direct_interaction (
* bodies_t *FMB_RESTRICT p_b_target,
* bodies_t *FMB_RESTRICT p_b_src,
* bool mutual
* )
*
*/
void P2P(const MortonIndex inCurrentIndex,
FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>* FRestrict const* FRestrict directNeighbors, MortonIndex const* FRestrict inNeighborsIndex, const int size) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
typename FList<ParticleClass*>::BasicIterator iterTarget(*targets);
while( iterTarget.isValide() ){
for(int idxDirectNeighbors = 0 ; idxDirectNeighbors < size ; ++idxDirectNeighbors){
if(inCurrentIndex < inNeighborsIndex[idxDirectNeighbors] ){
typename FList<ParticleClass*>::BasicIterator iterSource(*directNeighbors[idxDirectNeighbors]);
while( iterSource.isValide() ){
DIRECT_COMPUTATION_MUTUAL_SOFT(&iterTarget.value(),
&iterSource.value());
iterSource.progress();
}
}
}
typename FList<ParticleClass*>::BasicIterator iterSameBox = iterTarget;//(*targets);
iterSameBox.progress();
while( iterSameBox.isValide() ){
if(iterSameBox.value() < iterTarget.value()){
DIRECT_COMPUTATION_MUTUAL_SOFT(&iterTarget.value(),
&iterSameBox.value());
}
iterSameBox.progress();
}
//printf("x = %e \t y = %e \t z = %e \n",iterTarget.value()->getPosition().getX(),iterTarget.value()->getPosition().getY(),iterTarget.value()->getPosition().getZ());
//printf("\t P2P fx = %e \t fy = %e \t fz = %e \n",iterTarget.value()->getForces().getX(),iterTarget.value()->getForces().getY(),iterTarget.value()->getForces().getZ());
//printf("\t potential = %e \n",iterTarget.value()->getPotential());
iterTarget.progress();
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
void DIRECT_COMPUTATION_MUTUAL_SOFT(ParticleClass** const target, ParticleClass** const source){
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
const FReal dx = (*target)->getPosition().getX() - (*source)->getPosition().getX();
const FReal dy = (*target)->getPosition().getY() - (*source)->getPosition().getY();
const FReal dz = (*target)->getPosition().getZ() - (*source)->getPosition().getZ();
FReal inv_square_distance = 1.0/ (dx*dx + dy*dy + dz*dz + FMB_Info_eps_soft_square);
FReal inv_distance = FMath::Sqrt(inv_square_distance);
inv_distance *= (*target)->getPhysicalValue() * (*source)->getPhysicalValue();
inv_square_distance *= inv_distance;
(*target)->setForces(
(*target)->getForces().getX() + dx * inv_square_distance,
(*target)->getForces().getY() + dy * inv_square_distance,
(*target)->getForces().getZ() + dz * inv_square_distance
);
(*target)->setPotential( inv_distance + (*target)->getPotential());
(*source)->setForces(
(*source)->getForces().getX() + (-dx) * inv_square_distance,
(*source)->getForces().getY() + (-dy) * inv_square_distance,
(*source)->getForces().getZ() + (-dz) * inv_square_distance
);
(*source)->setPotential( inv_distance + (*source)->getPotential());
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
///////////////////////////////////////////////////////////////////////////////
// NO MUTUAL
///////////////////////////////////////////////////////////////////////////////
/** void bodies_Compute_direct_interaction (
* bodies_t *FMB_RESTRICT p_b_target,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment