diff --git a/runtime/domain/domain_partitioning.hpp b/runtime/domain/domain_partitioning.hpp index 9d22df20e1fef1a6961ed3f5b8894b834878f5b2..5e628f867cd3de109ca70397e44fbbbb6e1c7a69 100644 --- a/runtime/domain/domain_partitioning.hpp +++ b/runtime/domain/domain_partitioning.hpp @@ -6,10 +6,12 @@ typedef double real_t; namespace pairs { -template<int ndims> -class DomainPartitioner { +template<int ndims> class Regular6DStencil; + +template<int ndims> class DomainPartitioner { + friend class Regular6DStencil<ndims>; + protected: - int world_size, rank; real_t grid_min[ndims]; real_t grid_max[ndims]; @@ -28,87 +30,16 @@ public: grid_max[2] = zmax; } - virtual void initialize(); - virtual void fillArrays(int neighbor_ranks[], int pbc[], real_t subdom[]); - virtual void communicateSizes(int dim, const int *nsend, int *nrecv); + virtual void initialize(int *argc, char ***argv) = 0; + virtual void fillArrays(int neighbor_ranks[], int pbc[], real_t subdom[]) = 0; + virtual void communicateSizes(int dim, const int *nsend, int *nrecv) = 0; virtual void communicateData( int dim, int elem_size, const real_t *send_buf, const int *send_offsets, const int *nsend, - real_t *recv_buf, const int *recv_offsets, const int *nrecv); - virtual void finalize(); - inline int getRank() { return rank; } + real_t *recv_buf, const int *recv_offsets, const int *nrecv) = 0; + virtual void finalize() = 0; }; -template<int ndims> -class DimensionRanges : public DomainPartitioner<ndims> { -protected: - int nranks[ndims]; - int prev[ndims]; - int next[ndims]; - int pbc_prev[ndims]; - int pbc_next[ndims]; - real_t subdom_min[ndims]; - real_t subdom_max[ndims]; - -public: - DimensionRanges(real_t xmin, real_t xmax, real_t ymin, real_t ymax, real_t zmin, real_t zmax) : - DomainPartitioner<ndims>(xmin, xmax, ymin, ymax, zmin, zmax) {} - - void fillArrays(int neighbor_ranks[], int pbc[], real_t subdom[]) { - for(int d = 0; d < ndims; d++) { - neighbor_ranks[d * 2 + 0] = this->prev[d]; - neighbor_ranks[d * 2 + 1] = this->next[d]; - pbc[d * 2 + 0] = this->pbc_prev[d]; - pbc[d * 2 + 1] = this->pbc_next[d]; - subdom[d * 2 + 0] = this->subdom_min[d]; - subdom[d * 2 + 1] = this->subdom_max[d]; - } - } - - void communicateSizes(int dim, const int *send_sizes, int *recv_sizes) { - if(prev[dim] != this->getRank()) { - MPI_Send(&send_sizes[dim * 2 + 0], 1, MPI_INT, prev[dim], 0, MPI_COMM_WORLD); - MPI_Recv(&recv_sizes[dim * 2 + 0], 1, MPI_INT, next[dim], 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } else { - recv_sizes[dim * 2 + 0] = send_sizes[dim * 2 + 0]; - } - - if(next[dim] != this->getRank()) { - MPI_Send(&send_sizes[dim * 2 + 1], 1, MPI_INT, next[dim], 0, MPI_COMM_WORLD); - MPI_Recv(&recv_sizes[dim * 2 + 1], 1, MPI_INT, prev[dim], 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } else { - recv_sizes[dim * 2 + 1] = send_sizes[dim * 2 + 1]; - } - } - - void communicateData( - int dim, int elem_size, - const real_t *send_buf, const int *send_offsets, const int *nsend, - real_t *recv_buf, const int *recv_offsets, const int *nrecv) { - - if(prev[dim] != this->getRank()) { - MPI_Send(&send_buf[send_offsets[dim * 2 + 0]], nsend[dim * 2 + 0] * elem_size, MPI_DOUBLE, prev[dim], 0, MPI_COMM_WORLD); - MPI_Recv(&recv_buf[recv_offsets[dim * 2 + 0]], nrecv[dim * 2 + 0] * elem_size, MPI_DOUBLE, next[dim], 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } else { - for(int i = 0; i < nsend[dim * 2 + 0] * elem_size; i++) { - recv_buf[recv_offsets[dim * 2 + 0] + i] = send_buf[send_offsets[dim * 2 + 0] + i]; - } - } - - if(next[dim] != this->getRank()) { - MPI_Send(&send_buf[send_offsets[dim * 2 + 1]], nsend[dim * 2 + 1] * elem_size, MPI_DOUBLE, next[dim], 0, MPI_COMM_WORLD); - MPI_Recv(&recv_buf[recv_offsets[dim * 2 + 1]], nrecv[dim * 2 + 1] * elem_size, MPI_DOUBLE, prev[dim], 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - } else { - for(int i = 0; i < nsend[dim * 2 + 1] * elem_size; i++) { - recv_buf[recv_offsets[dim * 2 + 1] + i] = send_buf[send_offsets[dim * 2 + 1] + i]; - } - } - } -}; - -template<int ndims> -class ListOfBoxes : public DomainPartitioner<ndims> {}; - -class DomainPartitioner<3>; +//class DomainPartitioner<3>; } diff --git a/runtime/domain/no_partition.hpp b/runtime/domain/no_partition.hpp index db9561f3ccf8e672816c3979f5a31aa09a9714d6..51eaa2f3737424a91932216d41c8c213f1db0e0c 100644 --- a/runtime/domain/no_partition.hpp +++ b/runtime/domain/no_partition.hpp @@ -10,9 +10,6 @@ template <int ndims> class NoPartitioning : DimensionRanges<ndims> { public: void initialize(int *argc, const char **argv) { - this->world_size = 1; - this->rank = 0; - for(int d = 0; d < ndims; d++) { this->nranks[d] = 1; this->prev[d] = 0; @@ -25,6 +22,36 @@ public: } void finalize() {} + + void fillArrays(int neighbor_ranks[], int pbc[], real_t subdom[]) { + for(int d = 0; d < ndims; d++) { + neighbor_ranks[d * 2 + 0] = this->prev[d]; + neighbor_ranks[d * 2 + 1] = this->next[d]; + pbc[d * 2 + 0] = this->pbc_prev[d]; + pbc[d * 2 + 1] = this->pbc_next[d]; + subdom[d * 2 + 0] = this->subdom_min[d]; + subdom[d * 2 + 1] = this->subdom_max[d]; + } + } + + void communicateSizes(int dim, const int *send_sizes, int *recv_sizes) { + recv_sizes[dim * 2 + 0] = send_sizes[dim * 2 + 0]; + recv_sizes[dim * 2 + 1] = send_sizes[dim * 2 + 1]; + } + + void communicateData( + int dim, int elem_size, + const real_t *send_buf, const int *send_offsets, const int *nsend, + real_t *recv_buf, const int *recv_offsets, const int *nrecv) { + + for(int i = 0; i < nsend[dim * 2 + 0] * elem_size; i++) { + recv_buf[recv_offsets[dim * 2 + 0] + i] = send_buf[send_offsets[dim * 2 + 0] + i]; + } + + for(int i = 0; i < nsend[dim * 2 + 1] * elem_size; i++) { + recv_buf[recv_offsets[dim * 2 + 1] + i] = send_buf[send_offsets[dim * 2 + 1] + i]; + } + } }; } diff --git a/runtime/domain/regular_6d_stencil.hpp b/runtime/domain/regular_6d_stencil.hpp index 6ec03eec6721168cc230e830ccb457d967b3b5e3..289123221f43b246db756e36997244f4110925d0 100644 --- a/runtime/domain/regular_6d_stencil.hpp +++ b/runtime/domain/regular_6d_stencil.hpp @@ -7,10 +7,20 @@ typedef double real_t; namespace pairs { template <int ndims> -class Regular6DStencil : public DimensionRanges<ndims> { +class Regular6DStencil : public DomainPartitioner<ndims> { +private: + int world_size, rank; + int nranks[ndims]; + int prev[ndims]; + int next[ndims]; + int pbc_prev[ndims]; + int pbc_next[ndims]; + real_t subdom_min[ndims]; + real_t subdom_max[ndims]; + public: Regular6DStencil(real_t xmin, real_t xmax, real_t ymin, real_t ymax, real_t zmin, real_t zmax) : - DimensionRanges<ndims>(xmin, xmax, ymin, ymax, zmin, zmax) {} + DomainPartitioner<ndims>(xmin, xmax, ymin, ymax, zmin, zmax) {} void setConfig() { static_assert(ndims == 3, "setConfig() only implemented for three dimensions!"); @@ -69,8 +79,8 @@ public: void initialize(int *argc, char ***argv) { MPI_Init(argc, argv); - MPI_Comm_size(MPI_COMM_WORLD, &(this->world_size)); - MPI_Comm_rank(MPI_COMM_WORLD, &(this->rank)); + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); this->setConfig(); this->setBoundingBox(); } @@ -78,6 +88,57 @@ public: void finalize() { MPI_Finalize(); } + + void fillArrays(int neighbor_ranks[], int pbc[], real_t subdom[]) { + for(int d = 0; d < ndims; d++) { + neighbor_ranks[d * 2 + 0] = this->prev[d]; + neighbor_ranks[d * 2 + 1] = this->next[d]; + pbc[d * 2 + 0] = this->pbc_prev[d]; + pbc[d * 2 + 1] = this->pbc_next[d]; + subdom[d * 2 + 0] = this->subdom_min[d]; + subdom[d * 2 + 1] = this->subdom_max[d]; + } + } + + void communicateSizes(int dim, const int *send_sizes, int *recv_sizes) { + if(prev[dim] != rank) { + MPI_Send(&send_sizes[dim * 2 + 0], 1, MPI_INT, prev[dim], 0, MPI_COMM_WORLD); + MPI_Recv(&recv_sizes[dim * 2 + 0], 1, MPI_INT, next[dim], 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } else { + recv_sizes[dim * 2 + 0] = send_sizes[dim * 2 + 0]; + } + + if(next[dim] != rank) { + MPI_Send(&send_sizes[dim * 2 + 1], 1, MPI_INT, next[dim], 0, MPI_COMM_WORLD); + MPI_Recv(&recv_sizes[dim * 2 + 1], 1, MPI_INT, prev[dim], 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } else { + recv_sizes[dim * 2 + 1] = send_sizes[dim * 2 + 1]; + } + } + + void communicateData( + int dim, int elem_size, + const real_t *send_buf, const int *send_offsets, const int *nsend, + real_t *recv_buf, const int *recv_offsets, const int *nrecv) { + + if(prev[dim] != rank) { + MPI_Send(&send_buf[send_offsets[dim * 2 + 0]], nsend[dim * 2 + 0] * elem_size, MPI_DOUBLE, prev[dim], 0, MPI_COMM_WORLD); + MPI_Recv(&recv_buf[recv_offsets[dim * 2 + 0]], nrecv[dim * 2 + 0] * elem_size, MPI_DOUBLE, next[dim], 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } else { + for(int i = 0; i < nsend[dim * 2 + 0] * elem_size; i++) { + recv_buf[recv_offsets[dim * 2 + 0] + i] = send_buf[send_offsets[dim * 2 + 0] + i]; + } + } + + if(next[dim] != rank) { + MPI_Send(&send_buf[send_offsets[dim * 2 + 1]], nsend[dim * 2 + 1] * elem_size, MPI_DOUBLE, next[dim], 0, MPI_COMM_WORLD); + MPI_Recv(&recv_buf[recv_offsets[dim * 2 + 1]], nrecv[dim * 2 + 1] * elem_size, MPI_DOUBLE, prev[dim], 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + } else { + for(int i = 0; i < nsend[dim * 2 + 1] * elem_size; i++) { + recv_buf[recv_offsets[dim * 2 + 1] + i] = send_buf[send_offsets[dim * 2 + 1] + i]; + } + } + } }; } diff --git a/runtime/pairs.hpp b/runtime/pairs.hpp index 05aed09a9d69a7d01d471003af3bd49965b0d86d..91ca0ae690ee333d484c06fc180b9c376865f640 100644 --- a/runtime/pairs.hpp +++ b/runtime/pairs.hpp @@ -285,7 +285,7 @@ public: dom_part->initialize(argc, argv); } - DomainPartitioner<ndims> *getDomainPartitioner() { return dom_part; } + Regular6DStencil<ndims> *getDomainPartitioner() { return dom_part; } template<typename T_ptr> void addArray(array_t id, std::string name, T_ptr **h_ptr, std::nullptr_t, size_t size) {