Commit 66e764be authored by COULAUD Olivier's avatar COULAUD Olivier

Fix bug in Periodic Algorithm - Compilation error with constructeur (=delete)

parent a0807c57
...@@ -35,7 +35,7 @@ GetCpuInfos() ...@@ -35,7 +35,7 @@ GetCpuInfos()
# SCALFMM version number. An even minor number corresponds to releases. # SCALFMM version number. An even minor number corresponds to releases.
set(SCALFMM_MAJOR_VERSION 1) set(SCALFMM_MAJOR_VERSION 1)
set(SCALFMM_MINOR_VERSION 5) set(SCALFMM_MINOR_VERSION 5)
set(SCALFMM_PATCH_VERSION 1) set(SCALFMM_PATCH_VERSION 2)
set(SCALFMM_VERSION "${SCALFMM_MAJOR_VERSION}.${SCALFMM_MINOR_VERSION}.${SCALFMM_PATCH_VERSION}" ) set(SCALFMM_VERSION "${SCALFMM_MAJOR_VERSION}.${SCALFMM_MINOR_VERSION}.${SCALFMM_PATCH_VERSION}" )
set( MORSE_DISTRIB_DIR "" CACHE PATH "Directory of MORSE distribution") set( MORSE_DISTRIB_DIR "" CACHE PATH "Directory of MORSE distribution")
......
...@@ -6,8 +6,12 @@ Copyright (c) 2011-2018 Inria, All rights reserved. ...@@ -6,8 +6,12 @@ Copyright (c) 2011-2018 Inria, All rights reserved.
This file contains the main features as well as overviews of specific This file contains the main features as well as overviews of specific
bug fixes (and other actions) for each version of ScalFMM since bug fixes (and other actions) for each version of ScalFMM since
version 1.1 version 1.1
1.5.2
-----
- Many bug fixes in pseudo preriodic boundary condition un MPI version
1.5.1 1.5.1
-----
- Many bug fixes in MPI version (Loader, GroupTree, ...) - Many bug fixes in MPI version (Loader, GroupTree, ...)
- set cmake_policy CMP0004 to NEW - set cmake_policy CMP0004 to NEW
- fix some errors in Morse module with cmake 3.9.1 - fix some errors in Morse module with cmake 3.9.1
......
// See LICENCE file at project root // See LICENCE file at project root
#ifndef FBASICPARTICLECONTAINER_HPP #ifndef FBASIC_PARTICLE_CONTAINER_HPP_
#define FBASICPARTICLECONTAINER_HPP #define FBASIC_PARTICLE_CONTAINER_HPP_
#include "FAbstractParticleContainer.hpp" #include "FAbstractParticleContainer.hpp"
#include "FAbstractSerializable.hpp" #include "FAbstractSerializable.hpp"
...@@ -135,7 +135,7 @@ public: ...@@ -135,7 +135,7 @@ public:
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
FBasicParticleContainer(const FBasicParticleContainer&) = delete; FBasicParticleContainer(const FBasicParticleContainer&) = delete;
FBasicParticleContainer& operator=(const FBasicParticleContainer&) = delete; FBasicParticleContainer& operator=(const FBasicParticleContainer&) = delete;
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
...@@ -177,6 +177,13 @@ public: ...@@ -177,6 +177,13 @@ public:
} }
/** /**
* @brief getPositions
* @return get the position in write mode
*/
FReal* const* getPositions() {
return positions;
}
/**
* @brief getWPositions * @brief getWPositions
* @return get the position in write mode * @return get the position in write mode
*/ */
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#ifndef FFMMALGORITHMTHREADPROC_HPP #ifndef FFMMALGORITHMTHREADPROC_HPP
#define FFMMALGORITHMTHREADPROC_HPP #define FFMMALGORITHMTHREADPROC_HPP
#define SCALFMM_DISTRIBUTED_ALGORITHM
#include <omp.h> #include <omp.h>
// //
......
...@@ -2,35 +2,40 @@ ...@@ -2,35 +2,40 @@
#ifndef FFMMALGORITHMTHREADPROCPPERIODIC_HPP #ifndef FFMMALGORITHMTHREADPROCPPERIODIC_HPP
#define FFMMALGORITHMTHREADPROCPPERIODIC_HPP #define FFMMALGORITHMTHREADPROCPPERIODIC_HPP
#define SCALFMM_DISTRIBUTED_ALGORITHM
#include "../Utils/FAssert.hpp" #include <array>
#include "../Utils/FLog.hpp" #include <memory>
#include "Utils/FAssert.hpp"
#include "Utils/FLog.hpp"
#include "../Utils/FTic.hpp" #include "Utils/FTic.hpp"
#include "../Utils/FGlobal.hpp" #include "Utils/FGlobal.hpp"
#include "../Utils/FMemUtils.hpp" #include "Utils/FMemUtils.hpp"
#include "../Utils/FEnv.hpp" #include "Utils/FEnv.hpp"
#include "../Containers/FBoolArray.hpp" #include "Containers/FBoolArray.hpp"
#include "../Containers/FOctree.hpp" #include "Containers/FOctree.hpp"
#include "../Containers/FLightOctree.hpp" #include "Containers/FLightOctree.hpp"
#include "../Containers/FBufferWriter.hpp" #include "Containers/FBufferWriter.hpp"
#include "../Containers/FBufferReader.hpp" #include "Containers/FBufferReader.hpp"
#include "../Containers/FMpiBufferWriter.hpp" #include "Containers/FMpiBufferWriter.hpp"
#include "../Containers/FMpiBufferReader.hpp" #include "Containers/FMpiBufferReader.hpp"
#include "../Utils/FEnv.hpp" #include "Utils/FEnv.hpp"
#include "../Utils/FMpi.hpp" #include "Utils/FMpi.hpp"
#ifdef _OPENMP
#include <omp.h> #include <omp.h>
#endif
#include "FCoreCommon.hpp" #include "FCoreCommon.hpp"
#include "FP2PExclusion.hpp" #include "FP2PExclusion.hpp"
#include "Utils/FAlgorithmTimers.hpp" #include "Utils/FAlgorithmTimers.hpp"
#include <memory>
/** /**
* @author Berenger Bramas (berenger.bramas@inria.fr) * @author Berenger Bramas (berenger.bramas@inria.fr)
...@@ -1389,16 +1394,17 @@ protected: ...@@ -1389,16 +1394,17 @@ protected:
FBoolArray leafsNeedOther(this->numberOfLeafs); FBoolArray leafsNeedOther(this->numberOfLeafs);
int countNeedOther = 0; int countNeedOther = 0;
const FReal boxWidth = tree->getBoxWidth();
// To store the result // To store the result
OctreeClass otherP2Ptree( tree->getHeight(), tree->getSubHeight(), tree->getBoxWidth(), tree->getBoxCenter() ); OctreeClass otherP2Ptree( tree->getHeight(), tree->getSubHeight(),
boxWidth, tree->getBoxCenter() );
// init // init
const int LeafIndex = OctreeHeight - 1; const int LeafIndex = OctreeHeight - 1;
const int SizeShape = P2PExclusionClass::SizeShape; const int SizeShape = P2PExclusionClass::SizeShape;
int shapeLeaf[SizeShape]; int shapeLeaf[SizeShape]{};
memset(shapeLeaf,0,SizeShape*sizeof(int));
LeafData* const leafsDataArray = new LeafData[this->numberOfLeafs]; LeafData* const leafsDataArray = new LeafData[this->numberOfLeafs];
...@@ -1627,7 +1633,6 @@ protected: ...@@ -1627,7 +1633,6 @@ protected:
{ {
FLOG(computationCounter.tic()); FLOG(computationCounter.tic());
int previous = 0; int previous = 0;
const FReal boxWidth = tree->getBoxWidth();
for(int idxShape = 0 ; idxShape < SizeShape ; ++idxShape){ for(int idxShape = 0 ; idxShape < SizeShape ; ++idxShape){
const int endAtThisShape = shapeLeaf[idxShape] + previous; const int endAtThisShape = shapeLeaf[idxShape] + previous;
...@@ -1640,10 +1645,11 @@ protected: ...@@ -1640,10 +1645,11 @@ protected:
KernelClass* myThreadkernels = (kernels[omp_get_thread_num()]); KernelClass* myThreadkernels = (kernels[omp_get_thread_num()]);
// There is a maximum of 26 neighbors // There is a maximum of 26 neighbors
ContainerClass* neighbors[26]; ContainerClass* neighbors[26]{};
FTreeCoordinate offsets[26]; FTreeCoordinate offsets[26]{};
int neighborPositions[26]; int neighborPositions[26]{};
bool hasPeriodicLeaves; std::array<FTreeCoordinate,26> periodicOffsets{} ;
bool hasPeriodicLeaves{};
for(int idxTaskLeaf = idxLeafs ; idxTaskLeaf < (idxLeafs + nbLeavesInTask) ; ++idxTaskLeaf){ for(int idxTaskLeaf = idxLeafs ; idxTaskLeaf < (idxLeafs + nbLeavesInTask) ; ++idxTaskLeaf){
LeafData& currentIter = leafsDataArray[idxTaskLeaf]; LeafData& currentIter = leafsDataArray[idxTaskLeaf];
if(l2pEnabled){ if(l2pEnabled){
...@@ -1656,55 +1662,51 @@ protected: ...@@ -1656,55 +1662,51 @@ protected:
int periodicNeighborsCounter = 0; int periodicNeighborsCounter = 0;
if(hasPeriodicLeaves){ if(hasPeriodicLeaves){
ContainerClass* periodicNeighbors[26]; constexpr int maxPeriodicNeighbors = 19;
int periodicNeighborPositions[26]; ContainerClass* periodicNeighbors[maxPeriodicNeighbors]{};
int periodicNeighborPositions[maxPeriodicNeighbors]{};
//
for(int idxNeig = 0 ; idxNeig < counter ; ++idxNeig){ for(int idxNeig = 0 ; idxNeig < counter ; ++idxNeig){
if( !offsets[idxNeig].equals(0,0,0) ){ if( !offsets[idxNeig].equals(0,0,0) ){
// Put periodic neighbors into other array //
FReal*const positionsX = neighbors[idxNeig]->getWPositions()[0]; // Put periodic cell into another cell (copy data)
FReal*const positionsY = neighbors[idxNeig]->getWPositions()[1]; periodicNeighbors[periodicNeighborsCounter] = new ContainerClass(*(neighbors[idxNeig])) ;
FReal*const positionsZ = neighbors[idxNeig]->getWPositions()[2]; // newPos = pos + ofsset
auto * const positionsX = periodicNeighbors[periodicNeighborsCounter]->getPositions()[0];
for(FSize idxPart = 0; idxPart < neighbors[idxNeig]->getNbParticles() ; ++idxPart){ FReal*const positionsY = periodicNeighbors[periodicNeighborsCounter]->getPositions()[1];
positionsX[idxPart] += boxWidth * FReal(offsets[idxNeig].getX()); FReal*const positionsZ = periodicNeighbors[periodicNeighborsCounter]->getPositions()[2];
positionsY[idxPart] += boxWidth * FReal(offsets[idxNeig].getY()); FReal xoffset= boxWidth * FReal(offsets[idxNeig].getX()) ;
positionsZ[idxPart] += boxWidth * FReal(offsets[idxNeig].getZ()); FReal yoffset= boxWidth * FReal(offsets[idxNeig].getY()) ;
} FReal zoffset= boxWidth * FReal(offsets[idxNeig].getZ()) ;
for(FSize idxPart = 0; idxPart < periodicNeighbors[periodicNeighborsCounter]->getNbParticles() ; ++idxPart){
offsets[periodicNeighborsCounter] = offsets[idxNeig]; positionsX[idxPart] += xoffset;
periodicNeighbors[periodicNeighborsCounter] = neighbors[idxNeig]; positionsY[idxPart] += yoffset;
periodicNeighborPositions[periodicNeighborsCounter] = neighborPositions[idxNeig]; positionsZ[idxPart] += zoffset;
++periodicNeighborsCounter; }
periodicNeighborPositions[periodicNeighborsCounter] = neighborPositions[idxNeig];
++periodicNeighborsCounter;
} }
else{ else{
neighbors[idxNeig-periodicNeighborsCounter] = neighbors[idxNeig]; neighbors[idxNeig-periodicNeighborsCounter] = neighbors[idxNeig];
neighborPositions[idxNeig-periodicNeighborsCounter] = neighborPositions[idxNeig]; neighborPositions[idxNeig-periodicNeighborsCounter] = neighborPositions[idxNeig];
} }
} }
myThreadkernels->P2PRemote(currentIter.coord,currentIter.targets, myThreadkernels->P2PRemote(currentIter.coord,currentIter.targets,
currentIter.sources, periodicNeighbors, periodicNeighborPositions, periodicNeighborsCounter); currentIter.sources, periodicNeighbors, periodicNeighborPositions, periodicNeighborsCounter);
for(int idxNeig = 0 ; idxNeig < periodicNeighborsCounter ; ++idxNeig){
for(int idxNeig = 0 ; idxNeig < periodicNeighborsCounter ; ++idxNeig){ delete periodicNeighbors[idxNeig] ;
FAssertLF( periodicNeighbors[idxNeig] ); }
FReal*const positionsX = periodicNeighbors[idxNeig]->getWPositions()[0];
FReal*const positionsY = periodicNeighbors[idxNeig]->getWPositions()[1];
FReal*const positionsZ = periodicNeighbors[idxNeig]->getWPositions()[2];
for(FSize idxPart = 0; idxPart < periodicNeighbors[idxNeig]->getNbParticles() ; ++idxPart){
positionsX[idxPart] -= boxWidth * FReal(offsets[idxNeig].getX());
positionsY[idxPart] -= boxWidth * FReal(offsets[idxNeig].getY());
positionsZ[idxPart] -= boxWidth * FReal(offsets[idxNeig].getZ());
}
}
} }
//
// Now treat P2P interaction with non periodic cells
// Like in non periodic algorithm !!
//
myThreadkernels->P2P( currentIter.coord, currentIter.targets, myThreadkernels->P2P( currentIter.coord, currentIter.targets,
currentIter.sources, neighbors, neighborPositions, counter - periodicNeighborsCounter); currentIter.sources, neighbors, neighborPositions, counter - periodicNeighborsCounter);
} }
} }
} }
} }
previous = endAtThisShape; previous = endAtThisShape;
...@@ -1726,7 +1728,7 @@ protected: ...@@ -1726,7 +1728,7 @@ protected:
#pragma omp master #pragma omp master
{ FLOG( computation2Counter.tic() ); } { FLOG( computation2Counter.tic() ); }
if(p2pEnabled){ if(p2pEnabled && nbProcess > 1){
KernelClass& myThreadkernels = (*kernels[omp_get_thread_num()]); KernelClass& myThreadkernels = (*kernels[omp_get_thread_num()]);
// There is a maximum of 26 neighbors // There is a maximum of 26 neighbors
ContainerClass* neighbors[26]; ContainerClass* neighbors[26];
...@@ -1735,37 +1737,81 @@ protected: ...@@ -1735,37 +1737,81 @@ protected:
int neighborPositions[26]; int neighborPositions[26];
// Box limite // Box limite
const int limite = 1 << (this->OctreeHeight - 1); const int limite = 1 << (this->OctreeHeight - 1);
const int limitem1 = limite -1 ;
FAssertLF(leafsNeedOtherData.getSize() < std::numeric_limits<int>::max()); FAssertLF(leafsNeedOtherData.getSize() < std::numeric_limits<int>::max());
const int nbLeafToProceed = int(leafsNeedOtherData.getSize()); const int nbLeafToProceed = int(leafsNeedOtherData.getSize());
#pragma omp for schedule(dynamic, userChunkSize) #pragma omp for schedule(dynamic, userChunkSize)
for(int idxLeafs = 0 ; idxLeafs < nbLeafToProceed ; ++idxLeafs){ for(int idxLeafs = 0 ; idxLeafs < nbLeafToProceed ; ++idxLeafs){
LeafData currentIter = leafsNeedOtherData[idxLeafs]; LeafData currentIter = leafsNeedOtherData[idxLeafs];
// need the current particles and neighbors particles // need the current particles and neighbors particles
int counter = 0; int counter = 0;
// Take possible data // Take possible data
const int nbNeigh = getNeighborsIndexesPeriodic(currentIter.coord,limite, const int nbNeigh = this->getNeighborsIndexesPeriodic(currentIter.coord,limite,
indexesNeighbors,indexArray,AllDirs); indexesNeighbors,indexArray,AllDirs);
for(int idxNeigh = 0 ; idxNeigh < nbNeigh ; ++idxNeigh){ std::array<ContainerClass*,19> periodicNeighbors{};
if(indexesNeighbors[idxNeigh] < (intervals[idProcess].leftIndex) || (intervals[idProcess].rightIndex) < indexesNeighbors[idxNeigh]){ int nbPeriodicCells = 0 ;
ContainerClass*const hypotheticNeighbor = otherP2Ptree.getLeafSrc(indexesNeighbors[idxNeigh]); //
if(hypotheticNeighbor){ for(int idxNeigh = 0 ; idxNeigh < nbNeigh ; ++idxNeigh){
neighbors[counter] = hypotheticNeighbor; if(indexesNeighbors[idxNeigh] < (intervals[idProcess].leftIndex) || (intervals[idProcess].rightIndex) < indexesNeighbors[idxNeigh]){
neighborPositions[counter] = indexArray[idxNeigh];
++counter; ContainerClass*const hypotheticNeighbor = otherP2Ptree.getLeafSrc(indexesNeighbors[idxNeigh]);
}
} if(hypotheticNeighbor){
} // we should check if the cells is periodic or not
if(counter){ neighbors[counter] = hypotheticNeighbor;
myThreadkernels.P2PRemote( currentIter.coord, currentIter.targets, neighborPositions[counter] = indexArray[idxNeigh];
currentIter.sources, neighbors, neighborPositions, counter); FTreeCoordinate coord3d(indexesNeighbors[idxNeigh] );
} std::array<FReal,3> offSet{};
} bool movePos = false ;
coord3d-=currentIter.coord ;
} if (std::abs(coord3d.getX()) == limitem1 ){ // it's a periodic cell)
offSet[0] = coord3d.getX() < 0 ? boxWidth : -boxWidth;
movePos = true ;
}
if (std::abs(coord3d.getY()) == limitem1 ){ // it's a periodic cell)
offSet[1] = coord3d.getY() < 0 ? boxWidth : -boxWidth;
movePos = true ;
}
if (std::abs(coord3d.getZ()) == limitem1 ){ // it's a periodic cell)
offSet[2] = coord3d.getZ() < 0 ? boxWidth : -boxWidth;
movePos = true ;
}
if(movePos){
// Put periodic cell into another cell (copy data)
periodicNeighbors[nbPeriodicCells] = new ContainerClass(*hypotheticNeighbor) ;
// newPos = pos + ofsset
FReal*const positionsX = periodicNeighbors[nbPeriodicCells]->getPositions()[0];
FReal*const positionsY = periodicNeighbors[nbPeriodicCells]->getPositions()[1];
FReal*const positionsZ = periodicNeighbors[nbPeriodicCells]->getPositions()[2];
for(FSize idxPart = 0; idxPart < periodicNeighbors[nbPeriodicCells]->getNbParticles() ; ++idxPart){
positionsX[idxPart] += offSet[0];
positionsY[idxPart] += offSet[1];
positionsZ[idxPart] += offSet[2];
}
neighbors[counter] = periodicNeighbors[nbPeriodicCells];
++nbPeriodicCells;
}
++counter;
}
}
}
if(counter> 0){ // neighborPositions doesn't use)
myThreadkernels.P2PRemote( currentIter.coord, currentIter.targets,
nullptr /*currentIter.sources*/, neighbors, neighborPositions, counter);
if(nbPeriodicCells >0){
//to Do
for(int i=0 ; i < nbPeriodicCells ; ++i){
delete periodicNeighbors[i] ;
}
}
}
}
}
delete[] leafsDataArray; delete[] leafsDataArray;
...@@ -1992,6 +2038,10 @@ protected: ...@@ -1992,6 +2038,10 @@ protected:
FLOG( FLog::Controller.write("\tStart Periodic Pass\n").write(FLog::Flush); ); FLOG( FLog::Controller.write("\tStart Periodic Pass\n").write(FLog::Flush); );
FLOG(FTic counterTime); FLOG(FTic counterTime);
// the root level of the octree in the virtual array of cells
const int rootLevel = offsetRealTree-1 ;
rootCellFromProc.setLevel(rootLevel+1);
if( nbLevelsAboveRoot != -1 ){ if( nbLevelsAboveRoot != -1 ){
// we will use offsetRealTree-1 cells but for simplicity allocate offsetRealTree // we will use offsetRealTree-1 cells but for simplicity allocate offsetRealTree
// upperCells[offsetRealTree-1] is root cell // upperCells[offsetRealTree-1] is root cell
......
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