Loading src/TNL/Meshes/DistributedMeshes/BufferEntitiesHelper.h +15 −14 Original line number Diff line number Diff line Loading @@ -21,8 +21,9 @@ namespace DistributedMeshes { template < typename MeshFunctionType, int dim, typename RealType, typename Device > typename RealType=typename MeshFunctionType::MeshType::RealType, typename Device=typename MeshFunctionType::MeshType::DeviceType, typename Index=typename MeshFunctionType::MeshType::GlobalIndexType > class BufferEntitiesHelper { }; Loading @@ -30,15 +31,15 @@ class BufferEntitiesHelper //======================================== 1D ==================================================== //host template < typename MeshFunctionType, typename RealType, typename Device > class BufferEntitiesHelper<MeshFunctionType,1,RealType,Device> template < typename MeshFunctionType, typename RealType, typename Device, typename Index > class BufferEntitiesHelper<MeshFunctionType,1,RealType,Device,Index> { public: static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, int beginx, int sizex,bool tobuffer) static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, Index beginx, Index sizex, bool tobuffer) { auto mesh = meshFunction.getMesh(); RealType* meshFunctionData = meshFunction.getData().getData(); auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx] __cuda_callable__ ( int j ) auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx] __cuda_callable__ ( Index j ) { typename MeshFunctionType::MeshType::Cell entity(mesh); entity.getCoordinates().x()=beginx+j; Loading @@ -54,15 +55,15 @@ class BufferEntitiesHelper<MeshFunctionType,1,RealType,Device> //======================================== 2D ==================================================== template <typename MeshFunctionType, typename RealType, typename Device > class BufferEntitiesHelper<MeshFunctionType,2,RealType,Device> template <typename MeshFunctionType, typename RealType, typename Device, typename Index > class BufferEntitiesHelper<MeshFunctionType,2,RealType,Device,Index> { public: static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, int beginx, int beginy, int sizex, int sizey,bool tobuffer) static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, Index beginx, Index beginy, Index sizex, Index sizey,bool tobuffer) { auto mesh=meshFunction.getMesh(); RealType *meshFunctionData=meshFunction.getData().getData(); auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx, sizex, beginy] __cuda_callable__ ( int i, int j ) auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx, sizex, beginy] __cuda_callable__ ( Index i, Index j ) { typename MeshFunctionType::MeshType::Cell entity(mesh); entity.getCoordinates().x()=beginx+j; Loading @@ -81,16 +82,16 @@ class BufferEntitiesHelper<MeshFunctionType,2,RealType,Device> //======================================== 3D ==================================================== template <typename MeshFunctionType, typename RealType, typename Device> class BufferEntitiesHelper<MeshFunctionType,3,RealType,Device> template <typename MeshFunctionType, typename RealType, typename Device, typename Index > class BufferEntitiesHelper<MeshFunctionType,3,RealType,Device,Index> { public: static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, int beginx, int beginy, int beginz, int sizex, int sizey, int sizez, bool tobuffer) static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, Index beginx, Index beginy, Index beginz, Index sizex, Index sizey, Index sizez, bool tobuffer) { auto mesh=meshFunction.getMesh(); RealType * meshFunctionData=meshFunction.getData().getData(); auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx, sizex, beginy, sizey, beginz] __cuda_callable__ ( int k, int i, int j ) auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx, sizex, beginy, sizey, beginz] __cuda_callable__ ( Index k, Index i, Index j ) { typename MeshFunctionType::MeshType::Cell entity(mesh); entity.getCoordinates().x()=beginx+j; Loading src/TNL/Meshes/DistributedMeshes/CopyEntitiesHelper.h +9 −6 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ class CopyEntitiesHelper<MeshFunctionType, 1> public: typedef typename MeshFunctionType::MeshType::CoordinatesType CoordinatesType; typedef typename MeshFunctionType::MeshType::Cell Cell; typedef typename MeshFunctionType::MeshType::GlobalIndexType Index; static void Copy(MeshFunctionType &from, MeshFunctionType &to, CoordinatesType &fromBegin, CoordinatesType &toBegin, CoordinatesType &size) { Loading @@ -44,7 +45,7 @@ class CopyEntitiesHelper<MeshFunctionType, 1> auto fromData=from.getData().getData(); auto fromMesh=from.getMesh(); auto toMesh=to.getMesh(); auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( int i ) auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( Index i ) { Cell fromEntity(fromMesh); Cell toEntity(toMesh); Loading @@ -54,7 +55,7 @@ class CopyEntitiesHelper<MeshFunctionType, 1> fromEntity.refresh(); toData[toEntity.getIndex()]=fromData[fromEntity.getIndex()]; }; ParallelFor< typename MeshFunctionType::MeshType::DeviceType >::exec( 0, size.x(), kernel ); ParallelFor< typename MeshFunctionType::MeshType::DeviceType >::exec( (Index)0, (Index)size.x(), kernel ); } Loading @@ -68,6 +69,7 @@ class CopyEntitiesHelper<MeshFunctionType,2> public: typedef typename MeshFunctionType::MeshType::CoordinatesType CoordinatesType; typedef typename MeshFunctionType::MeshType::Cell Cell; typedef typename MeshFunctionType::MeshType::GlobalIndexType Index; static void Copy(MeshFunctionType &from, MeshFunctionType &to, CoordinatesType &fromBegin, CoordinatesType &toBegin, CoordinatesType &size) { Loading @@ -75,7 +77,7 @@ class CopyEntitiesHelper<MeshFunctionType,2> auto fromData=from.getData().getData(); auto fromMesh=from.getMesh(); auto toMesh=to.getMesh(); auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( int j, int i ) auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( Index j, Index i ) { Cell fromEntity(fromMesh); Cell toEntity(toMesh); Loading @@ -87,7 +89,7 @@ class CopyEntitiesHelper<MeshFunctionType,2> fromEntity.refresh(); toData[toEntity.getIndex()]=fromData[fromEntity.getIndex()]; }; ParallelFor2D< typename MeshFunctionType::MeshType::DeviceType >::exec( 0,0,size.y(), size.x(), kernel ); ParallelFor2D< typename MeshFunctionType::MeshType::DeviceType >::exec( (Index)0,(Index)0,(Index)size.y(), (Index)size.x(), kernel ); } Loading @@ -100,6 +102,7 @@ class CopyEntitiesHelper<MeshFunctionType,3> public: typedef typename MeshFunctionType::MeshType::CoordinatesType CoordinatesType; typedef typename MeshFunctionType::MeshType::Cell Cell; typedef typename MeshFunctionType::MeshType::GlobalIndexType Index; static void Copy(MeshFunctionType &from, MeshFunctionType &to, CoordinatesType &fromBegin, CoordinatesType &toBegin, CoordinatesType &size) { Loading @@ -107,7 +110,7 @@ class CopyEntitiesHelper<MeshFunctionType,3> auto fromData=from.getData().getData(); auto fromMesh=from.getMesh(); auto toMesh=to.getMesh(); auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( int k,int j, int i ) auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( Index k, Index j, Index i ) { Cell fromEntity(fromMesh); Cell toEntity(toMesh); Loading @@ -121,7 +124,7 @@ class CopyEntitiesHelper<MeshFunctionType,3> fromEntity.refresh(); toData[toEntity.getIndex()]=fromData[fromEntity.getIndex()]; }; ParallelFor3D< typename MeshFunctionType::MeshType::DeviceType >::exec( 0,0,0,size.z() ,size.y(), size.x(), kernel ); ParallelFor3D< typename MeshFunctionType::MeshType::DeviceType >::exec( (Index)0,(Index)0,(Index)0,(Index)size.z() ,(Index)size.y(), (Index)size.x(), kernel ); } }; Loading src/TNL/Meshes/DistributedMeshes/DistributedGridIO.h +272 −8 Original line number Diff line number Diff line Loading @@ -18,11 +18,15 @@ #include <iostream> #ifdef MPIIO #include <TNL/Communicators/MpiCommunicator.h> #endif namespace TNL { namespace Meshes { namespace DistributedMeshes { enum DistrGridIOTypes { Dummy = 0 , LocalCopy = 1 }; enum DistrGridIOTypes { Dummy = 0 , LocalCopy = 1, MpiIO=2 }; template<typename MeshFunctionType, DistrGridIOTypes type = LocalCopy> Loading @@ -33,12 +37,12 @@ class DistributedGridIO template<typename MeshFunctionType> class DistributedGridIO<MeshFunctionType,Dummy> { bool save(File &file,MeshFunctionType meshFunction) bool save(const String& fileName, MeshFunctionType &meshFunction) { return true; }; bool load(File &file,MeshFunctionType &meshFunction) bool load(const String& fileName, MeshFunctionType &meshFunction) { return true; }; Loading @@ -61,13 +65,13 @@ class DistributedGridIO<MeshFunctionType,LocalCopy> typedef typename MeshFunctionType::VectorType VectorType; //typedef DistributedGrid< MeshType,MeshFunctionType::getMeshDimension()> DistributedGridType; static bool save(File &file,MeshFunctionType &meshFunction) static bool save(const String& fileName, MeshFunctionType &meshFunction) { auto *distrGrid=meshFunction.getMesh().GetDistMesh(); if(distrGrid==NULL) //not distributed { return meshFunction.save(file); return meshFunction.save(fileName); } MeshType mesh=meshFunction.getMesh(); Loading @@ -83,6 +87,11 @@ class DistributedGridIO<MeshFunctionType,LocalCopy> newMesh->setSpaceSteps(spaceSteps); newMesh->setOrigin(origin+TNL::Containers::tnlDotProduct(spaceSteps,localBegin)); File meshFile; meshFile.open( fileName+String("-mesh-")+distrGrid->printProcessCoords(),IOMode::write); newMesh->save( meshFile ); meshFile.close(); VectorType newDof(newMesh-> template getEntitiesCount< typename MeshType::Cell >()); MeshFunctionType newMeshFunction; Loading @@ -92,16 +101,22 @@ class DistributedGridIO<MeshFunctionType,LocalCopy> zeroCoord.setValue(0); CopyEntitiesHelper<MeshFunctionType>::Copy(meshFunction,newMeshFunction,localBegin,zeroCoord,localSize); return newMeshFunction.save(file); File file; file.open( fileName+String("-")+distrGrid->printProcessCoords(), IOMode::write ); bool ret=newMeshFunction.save(file); file.close(); return ret; }; static bool load(File &file,MeshFunctionType &meshFunction) static bool load(const String& fileName,MeshFunctionType &meshFunction) { auto *distrGrid=meshFunction.getMesh().GetDistMesh(); if(distrGrid==NULL) //not distributed { return meshFunction.boundLoad(file); return meshFunction.boundLoad(fileName); } MeshType mesh=meshFunction.getMesh(); Loading @@ -124,7 +139,10 @@ class DistributedGridIO<MeshFunctionType,LocalCopy> CoordinatesType zeroCoord; zeroCoord.setValue(0); File file; file.open( fileName+String("-")+distrGrid->printProcessCoords(), IOMode::read ); bool result=newMeshFunction.boundLoad(file); file.close(); CopyEntitiesHelper<MeshFunctionType>::Copy(newMeshFunction,meshFunction,zeroCoord,localBegin,localSize); return result; Loading @@ -132,6 +150,252 @@ class DistributedGridIO<MeshFunctionType,LocalCopy> }; /* * Save distributed data into single file without overlaps using MPIIO and MPI datatypes, * EXPLOSIVE: works with only Grids and MPI * BAD IMPLEMENTTION creating MPI-Types at every save! -- I dont want contamine more places by MPI.. */ #ifdef MPIIO template<typename MeshFunctionType> class DistributedGridIO<MeshFunctionType,MpiIO> { public: typedef typename MeshFunctionType::MeshType MeshType; typedef typename MeshFunctionType::MeshType::CoordinatesType CoordinatesType; typedef typename MeshFunctionType::MeshType::PointType PointType; typedef typename MeshFunctionType::VectorType VectorType; //typedef DistributedGrid< MeshType,MeshFunctionType::getMeshDimension()> DistributedGridType; static bool save(const String& fileName, MeshFunctionType &meshFunction) { auto *distrGrid=meshFunction.getMesh().GetDistMesh(); if(distrGrid==NULL) //not distributed { return meshFunction.save(fileName); } MPI_Datatype ftype; MPI_Datatype atype; int dataCount=CreateDataTypes(distrGrid,&ftype,&atype); double * data=meshFunction.getData().getData();//TYP //write MPI_File file; MPI_File_open(MPI_COMM_WORLD,fileName.getString(), MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &file); int headerSize=0; if(Communicators::MpiCommunicator::GetRank()==0) { headerSize=writeMeshFunctionHeader(file,meshFunction,dataCount); } MPI_Bcast(&headerSize, 1, MPI_INT,0, MPI_COMM_WORLD); MPI_File_set_view(file,headerSize,MPI_DOUBLE,ftype,"native",MPI_INFO_NULL);//TYP MPI_Status wstatus; MPI_File_write(file,data,1,atype,&wstatus); MPI_File_close(&file); MPI_Type_free(&atype); MPI_Type_free(&ftype); return true; }; template<typename DitsributedGridType> static int CreateDataTypes(DitsributedGridType *distrGrid,MPI_Datatype *ftype,MPI_Datatype *atype) { int dim=distrGrid->getMeshDimension(); int fstarts[dim]; int flsize[dim]; int fgsize[dim]; hackArray(dim,fstarts,distrGrid->getGlobalBegin().getData()); hackArray(dim,flsize,distrGrid->getLocalSize().getData()); hackArray(dim,fgsize,distrGrid->getGlobalSize().getData()); MPI_Type_create_subarray(dim, fgsize,flsize,fstarts, MPI_ORDER_C,MPI_DOUBLE,ftype); //TYP MPI_Type_commit(ftype); int agsize[dim]; int alsize[dim]; int astarts[dim]; hackArray(dim,astarts,distrGrid->getLocalBegin().getData()); hackArray(dim,alsize,distrGrid->getLocalSize().getData()); hackArray(dim,agsize,distrGrid->getLocalGridSize().getData()); MPI_Type_create_subarray(dim, agsize,alsize,astarts, MPI_ORDER_C,MPI_DOUBLE,atype); //TYP MPI_Type_commit(atype); int dataCount=1; for(int i=0;i<dim;i++) dataCount*=fgsize[i]; return dataCount; } template<typename Index> static void hackArray(int dim, int* out, Index* in) { if(dim==1) { out[0]=in[0]; } if(dim==2) { out[1]=in[0]; out[0]=in[1]; } if(dim==3) { out[0]=in[2]; out[1]=in[1]; out[2]=in[0]; } } static unsigned int writeMeshFunctionHeader(MPI_File file,MeshFunctionType &meshFunction, int length ) { unsigned int size=0; int count; MPI_Status wstatus; //Magic MPI_File_write(file,"TNLMN",5,MPI_CHAR,&wstatus); MPI_Get_count(&wstatus,MPI_CHAR,&count); size+=count*sizeof(char); //Meshfunction type String meshFunctionSerializationType=meshFunction.getSerializationTypeVirtual(); int meshFunctionSerializationTypeLength=meshFunctionSerializationType.getLength(); MPI_File_write(file,&meshFunctionSerializationTypeLength,1,MPI_INT,&wstatus); MPI_Get_count(&wstatus,MPI_INT,&count); size+=count*sizeof(int); MPI_File_write(file,meshFunctionSerializationType.getString(),meshFunctionSerializationType.getLength(),MPI_CHAR,&wstatus); MPI_Get_count(&wstatus,MPI_CHAR,&count); size+=count*sizeof(char); //Magic MPI_File_write(file,"TNLMN",5,MPI_CHAR,&wstatus); MPI_Get_count(&wstatus,MPI_CHAR,&count); size+=count*sizeof(char); //Vector Type String dataSerializationType=meshFunction.getData().getSerializationTypeVirtual(); int dataSerializationTypeLength=dataSerializationType.getLength(); MPI_File_write(file,&dataSerializationTypeLength,1,MPI_INT,&wstatus); MPI_Get_count(&wstatus,MPI_INT,&count); size+=count*sizeof(int); MPI_File_write(file,dataSerializationType.getString(),dataSerializationType.getLength(),MPI_CHAR,&wstatus); MPI_Get_count(&wstatus,MPI_CHAR,&count); size+=count*sizeof(char); //Data count MPI_File_write(file,&(length),1,MPI_INT,&wstatus); MPI_Get_count(&wstatus,MPI_INT,&count); size+=count*sizeof(int); return size; }; /* Funky bomb - no checks - only dirty load */ static bool load(const String& fileName,MeshFunctionType &meshFunction) { auto *distrGrid=meshFunction.getMesh().GetDistMesh(); if(distrGrid==NULL) //not distributed { return meshFunction.boundLoad(fileName); } MPI_Datatype ftype; MPI_Datatype atype; int dataCount=CreateDataTypes(distrGrid,&ftype,&atype); double * data=meshFunction.getData().getData();//TYP //write MPI_File file; MPI_File_open(MPI_COMM_WORLD,fileName.getString(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file); int headerSize=0; if(Communicators::MpiCommunicator::GetRank()==0) { headerSize=readMeshFunctionHeader(file,meshFunction,dataCount); } MPI_Bcast(&headerSize, 1, MPI_INT,0, MPI_COMM_WORLD); if(headerSize<0) return false; MPI_File_set_view(file,headerSize,MPI_DOUBLE,ftype,"native",MPI_INFO_NULL);//TYP MPI_Status wstatus; MPI_File_read(file,(void*)data,1,atype,&wstatus); MPI_File_close(&file); MPI_Type_free(&atype); MPI_Type_free(&ftype); return true; }; //tak mohlo by to něco kontrolovat...ale nic to nekontroluje static int readMeshFunctionHeader(MPI_File file,MeshFunctionType &meshFunction, int length) { MPI_Status rstatus; char buffer[255]; int size=0; int count=0; MPI_File_read(file, (void *)buffer,5, MPI_CHAR, &rstatus);//MAGIC size+=5*sizeof(char); MPI_File_read(file, (void *)&count,1, MPI_INT, &rstatus);//SIZE OF DATATYPE size+=1*sizeof(int); MPI_File_read(file, (void *)&buffer,count, MPI_CHAR, &rstatus);//DATATYPE size+=count*sizeof(char); MPI_File_read(file, (void *)buffer,5, MPI_CHAR, &rstatus);//MAGIC size+=5*sizeof(char); MPI_File_read(file, (void *)&count,1, MPI_INT, &rstatus);//SIZE OF DATATYPE size+=1*sizeof(int); MPI_File_read(file, (void *)&buffer,count, MPI_CHAR, &rstatus);//DATATYPE size+=count*sizeof(char); MPI_File_read(file, (void *)&count,1, MPI_INT, &rstatus);//DATACOUNT size+=1*sizeof(int); if(count!=length) { std::cerr<<"Chyba načítání MeshFunction, délka dat v souboru neodpovídá očekávané délce" << std::endl; size=-1; } return size; }; }; #endif } } } src/TNL/Meshes/DistributedMeshes/DistributedGrid_1D.h +36 −11 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> CoordinatesType localsize; CoordinatesType localgridsize; CoordinatesType overlap; CoordinatesType globalsize; CoordinatesType globalbegin; PointType spaceSteps; Loading Loading @@ -95,6 +97,8 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> localorigin=globalGrid.getOrigin(); localsize=globalGrid.getDimensions(); localgridsize=globalGrid.getDimensions(); globalsize=globalGrid.getDimensions(); globalbegin=CoordinatesType(0); localbegin=CoordinatesType(0); return; Loading @@ -107,6 +111,8 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> if(rank!=nproc-1) right=rank+1; globalsize=globalGrid.getDimensions(); //compute local mesh size numberoflarger=globalGrid.getDimensions().x()%nproc; Loading @@ -115,12 +121,17 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> localsize.x()+=1; if(numberoflarger>rank) { globalbegin.x()=rank*localsize.x(); localorigin.x()=globalGrid.getOrigin().x() +(rank*localsize.x()-overlap.x())*globalGrid.getSpaceSteps().x(); +(globalbegin.x()-overlap.x())*globalGrid.getSpaceSteps().x(); } else localorigin.x()=globalGrid.getOrigin().x() +(numberoflarger*(localsize.x()+1)+(rank-numberoflarger)*localsize.x()-overlap.x()) *globalGrid.getSpaceSteps().x(); { globalbegin.x()=numberoflarger*(localsize.x()+1)+(rank-numberoflarger)*localsize.x(); localorigin.x()=(globalGrid.getOrigin().x()-overlap.x()) +globalbegin.x()*globalGrid.getSpaceSteps().x(); } localbegin=overlap; Loading Loading @@ -151,14 +162,14 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> grid.SetDistMesh(this); }; void printcoords(std::ostream& out) String printProcessCoords() { out<<rank<<":"; return convertToString(rank); }; void printdistr(std::ostream& out) String printProcessDistr() { out<<"("<<nproc<<"):"; return convertToString(nproc); }; bool IsDistributed(void) Loading @@ -183,17 +194,31 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> return this->overlap; }; //number of elemnts of local sub domain WITHOUT overlap CoordinatesType getLocalSize() { return this->localsize; } //number of elements of global grid CoordinatesType getGlobalSize() { return this->globalsize; } //coordinates of begin of local subdomain without overlaps in global grid CoordinatesType getGlobalBegin() { return this->globalbegin; } //number of elemnts of local sub domain WITH overlap CoordinatesType getLocalGridSize() { return this->localgridsize; } //coordinates of begin of local subdomain without overlaps in local grid CoordinatesType getLocalBegin() { return this->localbegin; Loading src/TNL/Meshes/DistributedMeshes/DistributedGrid_2D.h +32 −17 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/TNL/Meshes/DistributedMeshes/BufferEntitiesHelper.h +15 −14 Original line number Diff line number Diff line Loading @@ -21,8 +21,9 @@ namespace DistributedMeshes { template < typename MeshFunctionType, int dim, typename RealType, typename Device > typename RealType=typename MeshFunctionType::MeshType::RealType, typename Device=typename MeshFunctionType::MeshType::DeviceType, typename Index=typename MeshFunctionType::MeshType::GlobalIndexType > class BufferEntitiesHelper { }; Loading @@ -30,15 +31,15 @@ class BufferEntitiesHelper //======================================== 1D ==================================================== //host template < typename MeshFunctionType, typename RealType, typename Device > class BufferEntitiesHelper<MeshFunctionType,1,RealType,Device> template < typename MeshFunctionType, typename RealType, typename Device, typename Index > class BufferEntitiesHelper<MeshFunctionType,1,RealType,Device,Index> { public: static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, int beginx, int sizex,bool tobuffer) static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, Index beginx, Index sizex, bool tobuffer) { auto mesh = meshFunction.getMesh(); RealType* meshFunctionData = meshFunction.getData().getData(); auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx] __cuda_callable__ ( int j ) auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx] __cuda_callable__ ( Index j ) { typename MeshFunctionType::MeshType::Cell entity(mesh); entity.getCoordinates().x()=beginx+j; Loading @@ -54,15 +55,15 @@ class BufferEntitiesHelper<MeshFunctionType,1,RealType,Device> //======================================== 2D ==================================================== template <typename MeshFunctionType, typename RealType, typename Device > class BufferEntitiesHelper<MeshFunctionType,2,RealType,Device> template <typename MeshFunctionType, typename RealType, typename Device, typename Index > class BufferEntitiesHelper<MeshFunctionType,2,RealType,Device,Index> { public: static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, int beginx, int beginy, int sizex, int sizey,bool tobuffer) static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, Index beginx, Index beginy, Index sizex, Index sizey,bool tobuffer) { auto mesh=meshFunction.getMesh(); RealType *meshFunctionData=meshFunction.getData().getData(); auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx, sizex, beginy] __cuda_callable__ ( int i, int j ) auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx, sizex, beginy] __cuda_callable__ ( Index i, Index j ) { typename MeshFunctionType::MeshType::Cell entity(mesh); entity.getCoordinates().x()=beginx+j; Loading @@ -81,16 +82,16 @@ class BufferEntitiesHelper<MeshFunctionType,2,RealType,Device> //======================================== 3D ==================================================== template <typename MeshFunctionType, typename RealType, typename Device> class BufferEntitiesHelper<MeshFunctionType,3,RealType,Device> template <typename MeshFunctionType, typename RealType, typename Device, typename Index > class BufferEntitiesHelper<MeshFunctionType,3,RealType,Device,Index> { public: static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, int beginx, int beginy, int beginz, int sizex, int sizey, int sizez, bool tobuffer) static void BufferEntities(MeshFunctionType meshFunction, RealType * buffer, Index beginx, Index beginy, Index beginz, Index sizex, Index sizey, Index sizez, bool tobuffer) { auto mesh=meshFunction.getMesh(); RealType * meshFunctionData=meshFunction.getData().getData(); auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx, sizex, beginy, sizey, beginz] __cuda_callable__ ( int k, int i, int j ) auto kernel = [tobuffer, mesh, buffer, meshFunctionData, beginx, sizex, beginy, sizey, beginz] __cuda_callable__ ( Index k, Index i, Index j ) { typename MeshFunctionType::MeshType::Cell entity(mesh); entity.getCoordinates().x()=beginx+j; Loading
src/TNL/Meshes/DistributedMeshes/CopyEntitiesHelper.h +9 −6 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ class CopyEntitiesHelper<MeshFunctionType, 1> public: typedef typename MeshFunctionType::MeshType::CoordinatesType CoordinatesType; typedef typename MeshFunctionType::MeshType::Cell Cell; typedef typename MeshFunctionType::MeshType::GlobalIndexType Index; static void Copy(MeshFunctionType &from, MeshFunctionType &to, CoordinatesType &fromBegin, CoordinatesType &toBegin, CoordinatesType &size) { Loading @@ -44,7 +45,7 @@ class CopyEntitiesHelper<MeshFunctionType, 1> auto fromData=from.getData().getData(); auto fromMesh=from.getMesh(); auto toMesh=to.getMesh(); auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( int i ) auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( Index i ) { Cell fromEntity(fromMesh); Cell toEntity(toMesh); Loading @@ -54,7 +55,7 @@ class CopyEntitiesHelper<MeshFunctionType, 1> fromEntity.refresh(); toData[toEntity.getIndex()]=fromData[fromEntity.getIndex()]; }; ParallelFor< typename MeshFunctionType::MeshType::DeviceType >::exec( 0, size.x(), kernel ); ParallelFor< typename MeshFunctionType::MeshType::DeviceType >::exec( (Index)0, (Index)size.x(), kernel ); } Loading @@ -68,6 +69,7 @@ class CopyEntitiesHelper<MeshFunctionType,2> public: typedef typename MeshFunctionType::MeshType::CoordinatesType CoordinatesType; typedef typename MeshFunctionType::MeshType::Cell Cell; typedef typename MeshFunctionType::MeshType::GlobalIndexType Index; static void Copy(MeshFunctionType &from, MeshFunctionType &to, CoordinatesType &fromBegin, CoordinatesType &toBegin, CoordinatesType &size) { Loading @@ -75,7 +77,7 @@ class CopyEntitiesHelper<MeshFunctionType,2> auto fromData=from.getData().getData(); auto fromMesh=from.getMesh(); auto toMesh=to.getMesh(); auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( int j, int i ) auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( Index j, Index i ) { Cell fromEntity(fromMesh); Cell toEntity(toMesh); Loading @@ -87,7 +89,7 @@ class CopyEntitiesHelper<MeshFunctionType,2> fromEntity.refresh(); toData[toEntity.getIndex()]=fromData[fromEntity.getIndex()]; }; ParallelFor2D< typename MeshFunctionType::MeshType::DeviceType >::exec( 0,0,size.y(), size.x(), kernel ); ParallelFor2D< typename MeshFunctionType::MeshType::DeviceType >::exec( (Index)0,(Index)0,(Index)size.y(), (Index)size.x(), kernel ); } Loading @@ -100,6 +102,7 @@ class CopyEntitiesHelper<MeshFunctionType,3> public: typedef typename MeshFunctionType::MeshType::CoordinatesType CoordinatesType; typedef typename MeshFunctionType::MeshType::Cell Cell; typedef typename MeshFunctionType::MeshType::GlobalIndexType Index; static void Copy(MeshFunctionType &from, MeshFunctionType &to, CoordinatesType &fromBegin, CoordinatesType &toBegin, CoordinatesType &size) { Loading @@ -107,7 +110,7 @@ class CopyEntitiesHelper<MeshFunctionType,3> auto fromData=from.getData().getData(); auto fromMesh=from.getMesh(); auto toMesh=to.getMesh(); auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( int k,int j, int i ) auto kernel = [fromData,toData, fromMesh, toMesh, fromBegin, toBegin] __cuda_callable__ ( Index k, Index j, Index i ) { Cell fromEntity(fromMesh); Cell toEntity(toMesh); Loading @@ -121,7 +124,7 @@ class CopyEntitiesHelper<MeshFunctionType,3> fromEntity.refresh(); toData[toEntity.getIndex()]=fromData[fromEntity.getIndex()]; }; ParallelFor3D< typename MeshFunctionType::MeshType::DeviceType >::exec( 0,0,0,size.z() ,size.y(), size.x(), kernel ); ParallelFor3D< typename MeshFunctionType::MeshType::DeviceType >::exec( (Index)0,(Index)0,(Index)0,(Index)size.z() ,(Index)size.y(), (Index)size.x(), kernel ); } }; Loading
src/TNL/Meshes/DistributedMeshes/DistributedGridIO.h +272 −8 Original line number Diff line number Diff line Loading @@ -18,11 +18,15 @@ #include <iostream> #ifdef MPIIO #include <TNL/Communicators/MpiCommunicator.h> #endif namespace TNL { namespace Meshes { namespace DistributedMeshes { enum DistrGridIOTypes { Dummy = 0 , LocalCopy = 1 }; enum DistrGridIOTypes { Dummy = 0 , LocalCopy = 1, MpiIO=2 }; template<typename MeshFunctionType, DistrGridIOTypes type = LocalCopy> Loading @@ -33,12 +37,12 @@ class DistributedGridIO template<typename MeshFunctionType> class DistributedGridIO<MeshFunctionType,Dummy> { bool save(File &file,MeshFunctionType meshFunction) bool save(const String& fileName, MeshFunctionType &meshFunction) { return true; }; bool load(File &file,MeshFunctionType &meshFunction) bool load(const String& fileName, MeshFunctionType &meshFunction) { return true; }; Loading @@ -61,13 +65,13 @@ class DistributedGridIO<MeshFunctionType,LocalCopy> typedef typename MeshFunctionType::VectorType VectorType; //typedef DistributedGrid< MeshType,MeshFunctionType::getMeshDimension()> DistributedGridType; static bool save(File &file,MeshFunctionType &meshFunction) static bool save(const String& fileName, MeshFunctionType &meshFunction) { auto *distrGrid=meshFunction.getMesh().GetDistMesh(); if(distrGrid==NULL) //not distributed { return meshFunction.save(file); return meshFunction.save(fileName); } MeshType mesh=meshFunction.getMesh(); Loading @@ -83,6 +87,11 @@ class DistributedGridIO<MeshFunctionType,LocalCopy> newMesh->setSpaceSteps(spaceSteps); newMesh->setOrigin(origin+TNL::Containers::tnlDotProduct(spaceSteps,localBegin)); File meshFile; meshFile.open( fileName+String("-mesh-")+distrGrid->printProcessCoords(),IOMode::write); newMesh->save( meshFile ); meshFile.close(); VectorType newDof(newMesh-> template getEntitiesCount< typename MeshType::Cell >()); MeshFunctionType newMeshFunction; Loading @@ -92,16 +101,22 @@ class DistributedGridIO<MeshFunctionType,LocalCopy> zeroCoord.setValue(0); CopyEntitiesHelper<MeshFunctionType>::Copy(meshFunction,newMeshFunction,localBegin,zeroCoord,localSize); return newMeshFunction.save(file); File file; file.open( fileName+String("-")+distrGrid->printProcessCoords(), IOMode::write ); bool ret=newMeshFunction.save(file); file.close(); return ret; }; static bool load(File &file,MeshFunctionType &meshFunction) static bool load(const String& fileName,MeshFunctionType &meshFunction) { auto *distrGrid=meshFunction.getMesh().GetDistMesh(); if(distrGrid==NULL) //not distributed { return meshFunction.boundLoad(file); return meshFunction.boundLoad(fileName); } MeshType mesh=meshFunction.getMesh(); Loading @@ -124,7 +139,10 @@ class DistributedGridIO<MeshFunctionType,LocalCopy> CoordinatesType zeroCoord; zeroCoord.setValue(0); File file; file.open( fileName+String("-")+distrGrid->printProcessCoords(), IOMode::read ); bool result=newMeshFunction.boundLoad(file); file.close(); CopyEntitiesHelper<MeshFunctionType>::Copy(newMeshFunction,meshFunction,zeroCoord,localBegin,localSize); return result; Loading @@ -132,6 +150,252 @@ class DistributedGridIO<MeshFunctionType,LocalCopy> }; /* * Save distributed data into single file without overlaps using MPIIO and MPI datatypes, * EXPLOSIVE: works with only Grids and MPI * BAD IMPLEMENTTION creating MPI-Types at every save! -- I dont want contamine more places by MPI.. */ #ifdef MPIIO template<typename MeshFunctionType> class DistributedGridIO<MeshFunctionType,MpiIO> { public: typedef typename MeshFunctionType::MeshType MeshType; typedef typename MeshFunctionType::MeshType::CoordinatesType CoordinatesType; typedef typename MeshFunctionType::MeshType::PointType PointType; typedef typename MeshFunctionType::VectorType VectorType; //typedef DistributedGrid< MeshType,MeshFunctionType::getMeshDimension()> DistributedGridType; static bool save(const String& fileName, MeshFunctionType &meshFunction) { auto *distrGrid=meshFunction.getMesh().GetDistMesh(); if(distrGrid==NULL) //not distributed { return meshFunction.save(fileName); } MPI_Datatype ftype; MPI_Datatype atype; int dataCount=CreateDataTypes(distrGrid,&ftype,&atype); double * data=meshFunction.getData().getData();//TYP //write MPI_File file; MPI_File_open(MPI_COMM_WORLD,fileName.getString(), MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &file); int headerSize=0; if(Communicators::MpiCommunicator::GetRank()==0) { headerSize=writeMeshFunctionHeader(file,meshFunction,dataCount); } MPI_Bcast(&headerSize, 1, MPI_INT,0, MPI_COMM_WORLD); MPI_File_set_view(file,headerSize,MPI_DOUBLE,ftype,"native",MPI_INFO_NULL);//TYP MPI_Status wstatus; MPI_File_write(file,data,1,atype,&wstatus); MPI_File_close(&file); MPI_Type_free(&atype); MPI_Type_free(&ftype); return true; }; template<typename DitsributedGridType> static int CreateDataTypes(DitsributedGridType *distrGrid,MPI_Datatype *ftype,MPI_Datatype *atype) { int dim=distrGrid->getMeshDimension(); int fstarts[dim]; int flsize[dim]; int fgsize[dim]; hackArray(dim,fstarts,distrGrid->getGlobalBegin().getData()); hackArray(dim,flsize,distrGrid->getLocalSize().getData()); hackArray(dim,fgsize,distrGrid->getGlobalSize().getData()); MPI_Type_create_subarray(dim, fgsize,flsize,fstarts, MPI_ORDER_C,MPI_DOUBLE,ftype); //TYP MPI_Type_commit(ftype); int agsize[dim]; int alsize[dim]; int astarts[dim]; hackArray(dim,astarts,distrGrid->getLocalBegin().getData()); hackArray(dim,alsize,distrGrid->getLocalSize().getData()); hackArray(dim,agsize,distrGrid->getLocalGridSize().getData()); MPI_Type_create_subarray(dim, agsize,alsize,astarts, MPI_ORDER_C,MPI_DOUBLE,atype); //TYP MPI_Type_commit(atype); int dataCount=1; for(int i=0;i<dim;i++) dataCount*=fgsize[i]; return dataCount; } template<typename Index> static void hackArray(int dim, int* out, Index* in) { if(dim==1) { out[0]=in[0]; } if(dim==2) { out[1]=in[0]; out[0]=in[1]; } if(dim==3) { out[0]=in[2]; out[1]=in[1]; out[2]=in[0]; } } static unsigned int writeMeshFunctionHeader(MPI_File file,MeshFunctionType &meshFunction, int length ) { unsigned int size=0; int count; MPI_Status wstatus; //Magic MPI_File_write(file,"TNLMN",5,MPI_CHAR,&wstatus); MPI_Get_count(&wstatus,MPI_CHAR,&count); size+=count*sizeof(char); //Meshfunction type String meshFunctionSerializationType=meshFunction.getSerializationTypeVirtual(); int meshFunctionSerializationTypeLength=meshFunctionSerializationType.getLength(); MPI_File_write(file,&meshFunctionSerializationTypeLength,1,MPI_INT,&wstatus); MPI_Get_count(&wstatus,MPI_INT,&count); size+=count*sizeof(int); MPI_File_write(file,meshFunctionSerializationType.getString(),meshFunctionSerializationType.getLength(),MPI_CHAR,&wstatus); MPI_Get_count(&wstatus,MPI_CHAR,&count); size+=count*sizeof(char); //Magic MPI_File_write(file,"TNLMN",5,MPI_CHAR,&wstatus); MPI_Get_count(&wstatus,MPI_CHAR,&count); size+=count*sizeof(char); //Vector Type String dataSerializationType=meshFunction.getData().getSerializationTypeVirtual(); int dataSerializationTypeLength=dataSerializationType.getLength(); MPI_File_write(file,&dataSerializationTypeLength,1,MPI_INT,&wstatus); MPI_Get_count(&wstatus,MPI_INT,&count); size+=count*sizeof(int); MPI_File_write(file,dataSerializationType.getString(),dataSerializationType.getLength(),MPI_CHAR,&wstatus); MPI_Get_count(&wstatus,MPI_CHAR,&count); size+=count*sizeof(char); //Data count MPI_File_write(file,&(length),1,MPI_INT,&wstatus); MPI_Get_count(&wstatus,MPI_INT,&count); size+=count*sizeof(int); return size; }; /* Funky bomb - no checks - only dirty load */ static bool load(const String& fileName,MeshFunctionType &meshFunction) { auto *distrGrid=meshFunction.getMesh().GetDistMesh(); if(distrGrid==NULL) //not distributed { return meshFunction.boundLoad(fileName); } MPI_Datatype ftype; MPI_Datatype atype; int dataCount=CreateDataTypes(distrGrid,&ftype,&atype); double * data=meshFunction.getData().getData();//TYP //write MPI_File file; MPI_File_open(MPI_COMM_WORLD,fileName.getString(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file); int headerSize=0; if(Communicators::MpiCommunicator::GetRank()==0) { headerSize=readMeshFunctionHeader(file,meshFunction,dataCount); } MPI_Bcast(&headerSize, 1, MPI_INT,0, MPI_COMM_WORLD); if(headerSize<0) return false; MPI_File_set_view(file,headerSize,MPI_DOUBLE,ftype,"native",MPI_INFO_NULL);//TYP MPI_Status wstatus; MPI_File_read(file,(void*)data,1,atype,&wstatus); MPI_File_close(&file); MPI_Type_free(&atype); MPI_Type_free(&ftype); return true; }; //tak mohlo by to něco kontrolovat...ale nic to nekontroluje static int readMeshFunctionHeader(MPI_File file,MeshFunctionType &meshFunction, int length) { MPI_Status rstatus; char buffer[255]; int size=0; int count=0; MPI_File_read(file, (void *)buffer,5, MPI_CHAR, &rstatus);//MAGIC size+=5*sizeof(char); MPI_File_read(file, (void *)&count,1, MPI_INT, &rstatus);//SIZE OF DATATYPE size+=1*sizeof(int); MPI_File_read(file, (void *)&buffer,count, MPI_CHAR, &rstatus);//DATATYPE size+=count*sizeof(char); MPI_File_read(file, (void *)buffer,5, MPI_CHAR, &rstatus);//MAGIC size+=5*sizeof(char); MPI_File_read(file, (void *)&count,1, MPI_INT, &rstatus);//SIZE OF DATATYPE size+=1*sizeof(int); MPI_File_read(file, (void *)&buffer,count, MPI_CHAR, &rstatus);//DATATYPE size+=count*sizeof(char); MPI_File_read(file, (void *)&count,1, MPI_INT, &rstatus);//DATACOUNT size+=1*sizeof(int); if(count!=length) { std::cerr<<"Chyba načítání MeshFunction, délka dat v souboru neodpovídá očekávané délce" << std::endl; size=-1; } return size; }; }; #endif } } }
src/TNL/Meshes/DistributedMeshes/DistributedGrid_1D.h +36 −11 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> CoordinatesType localsize; CoordinatesType localgridsize; CoordinatesType overlap; CoordinatesType globalsize; CoordinatesType globalbegin; PointType spaceSteps; Loading Loading @@ -95,6 +97,8 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> localorigin=globalGrid.getOrigin(); localsize=globalGrid.getDimensions(); localgridsize=globalGrid.getDimensions(); globalsize=globalGrid.getDimensions(); globalbegin=CoordinatesType(0); localbegin=CoordinatesType(0); return; Loading @@ -107,6 +111,8 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> if(rank!=nproc-1) right=rank+1; globalsize=globalGrid.getDimensions(); //compute local mesh size numberoflarger=globalGrid.getDimensions().x()%nproc; Loading @@ -115,12 +121,17 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> localsize.x()+=1; if(numberoflarger>rank) { globalbegin.x()=rank*localsize.x(); localorigin.x()=globalGrid.getOrigin().x() +(rank*localsize.x()-overlap.x())*globalGrid.getSpaceSteps().x(); +(globalbegin.x()-overlap.x())*globalGrid.getSpaceSteps().x(); } else localorigin.x()=globalGrid.getOrigin().x() +(numberoflarger*(localsize.x()+1)+(rank-numberoflarger)*localsize.x()-overlap.x()) *globalGrid.getSpaceSteps().x(); { globalbegin.x()=numberoflarger*(localsize.x()+1)+(rank-numberoflarger)*localsize.x(); localorigin.x()=(globalGrid.getOrigin().x()-overlap.x()) +globalbegin.x()*globalGrid.getSpaceSteps().x(); } localbegin=overlap; Loading Loading @@ -151,14 +162,14 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> grid.SetDistMesh(this); }; void printcoords(std::ostream& out) String printProcessCoords() { out<<rank<<":"; return convertToString(rank); }; void printdistr(std::ostream& out) String printProcessDistr() { out<<"("<<nproc<<"):"; return convertToString(nproc); }; bool IsDistributed(void) Loading @@ -183,17 +194,31 @@ class DistributedMesh<Grid< 1, RealType, Device, Index >> return this->overlap; }; //number of elemnts of local sub domain WITHOUT overlap CoordinatesType getLocalSize() { return this->localsize; } //number of elements of global grid CoordinatesType getGlobalSize() { return this->globalsize; } //coordinates of begin of local subdomain without overlaps in global grid CoordinatesType getGlobalBegin() { return this->globalbegin; } //number of elemnts of local sub domain WITH overlap CoordinatesType getLocalGridSize() { return this->localgridsize; } //coordinates of begin of local subdomain without overlaps in local grid CoordinatesType getLocalBegin() { return this->localbegin; Loading
src/TNL/Meshes/DistributedMeshes/DistributedGrid_2D.h +32 −17 File changed.Preview size limit exceeded, changes collapsed. Show changes