diff --git a/src/Makefile.am b/src/Makefile.am index 0fdc51571424e2a9ad91d1d7c714d91446702161..c71cbbbbd1b1463a61e8b138fb85525d74ebbe03 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,7 +41,7 @@ include_HEADERS = space.h runner.h queue.h task.h lock.h cell.h part.h const.h \ AM_SOURCES = space.c runner.c queue.c task.c cell.c engine.c \ serial_io.c timers.c debug.c scheduler.c proxy.c parallel_io.c \ units.c common_io.c single_io.c multipole.c version.c map.c \ - kernel.c tools.c + kernel.c tools.c part.c # Include files for distribution, not installation. noinst_HEADERS = atomic.h cycle.h error.h inline.h kernel.h vector.h \ diff --git a/src/engine.c b/src/engine.c index 2f242f2ec3a27e143e7e4f08a3abdf3af8619dfe..c9a1de94cf8ddc2accc7049fd0ca232e5c650ebf 100644 --- a/src/engine.c +++ b/src/engine.c @@ -47,6 +47,7 @@ #include "cycle.h" #include "debug.h" #include "error.h" +#include "part.h" #include "timers.h" #ifdef LEGACY_GADGET2_SPH @@ -215,28 +216,24 @@ void engine_redistribute(struct engine *e) { offset_send += counts[ind_send]; offset_recv += counts[ind_recv]; } else { - if (MPI_Isend(&s->parts[offset_send], - sizeof(struct part) * counts[ind_send], MPI_BYTE, k, - 2 * ind_send + 0, MPI_COMM_WORLD, + if (MPI_Isend(&s->parts[offset_send], counts[ind_send], + *(e->part_mpi_type), k, 2 * ind_send + 0, MPI_COMM_WORLD, &reqs[4 * k]) != MPI_SUCCESS) error("Failed to isend parts to node %i.", k); - if (MPI_Isend(&s->xparts[offset_send], - sizeof(struct xpart) * counts[ind_send], MPI_BYTE, k, - 2 * ind_send + 1, MPI_COMM_WORLD, + if (MPI_Isend(&s->xparts[offset_send], counts[ind_send], + *(e->xpart_mpi_type), k, 2 * ind_send + 1, MPI_COMM_WORLD, &reqs[4 * k + 1]) != MPI_SUCCESS) error("Failed to isend xparts to node %i.", k); offset_send += counts[ind_send]; } } if (k != nodeID && counts[ind_recv] > 0) { - if (MPI_Irecv(&parts_new[offset_recv], - sizeof(struct part) * counts[ind_recv], MPI_BYTE, k, - 2 * ind_recv + 0, MPI_COMM_WORLD, + if (MPI_Irecv(&parts_new[offset_recv], counts[ind_recv], + *(e->part_mpi_type), k, 2 * ind_recv + 0, MPI_COMM_WORLD, &reqs[4 * k + 2]) != MPI_SUCCESS) error("Failed to emit irecv of parts from node %i.", k); - if (MPI_Irecv(&xparts_new[offset_recv], - sizeof(struct xpart) * counts[ind_recv], MPI_BYTE, k, - 2 * ind_recv + 1, MPI_COMM_WORLD, + if (MPI_Irecv(&xparts_new[offset_recv], counts[ind_recv], + *(e->xpart_mpi_type), k, 2 * ind_recv + 1, MPI_COMM_WORLD, &reqs[4 * k + 3]) != MPI_SUCCESS) error("Failed to emit irecv of parts from node %i.", k); offset_recv += counts[ind_recv]; @@ -2202,6 +2199,12 @@ void engine_init(struct engine *e, struct space *s, float dt, int nr_threads, #endif } +/* Construct types for MPI communications */ +#ifdef WITH_MPI + part_create_mpi_type(e->part_mpi_type); + xpart_create_mpi_type(e->xpart_mpi_type); +#endif + /* First of all, init the barrier and lock it. */ if (pthread_mutex_init(&e->barrier_mutex, NULL) != 0) error("Failed to initialize barrier mutex."); diff --git a/src/engine.h b/src/engine.h index 4da743f3151704b2d32a6086352957e4d947bfc6..4ab86288a04fc18b6236a6c44a048a01314a088d 100644 --- a/src/engine.h +++ b/src/engine.h @@ -19,6 +19,14 @@ #ifndef SWIFT_ENGINE_H #define SWIFT_ENGINE_H +/* Config parameters. */ +#include "../config.h" + +/* MPI headers. */ +#ifdef WITH_MPI +#include <mpi.h> +#endif + /* Some standard headers. */ #include <pthread.h> @@ -125,6 +133,10 @@ struct engine { /* Linked list for cell-task association. */ struct link *links; int nr_links, size_links; + + /* MPI data type for the particle transfers */ + MPI_Datatype *part_mpi_type; + MPI_Datatype *xpart_mpi_type; }; /* Function prototypes. */ diff --git a/src/part.c b/src/part.c new file mode 100644 index 0000000000000000000000000000000000000000..1923e3f0443153fff97227f6005762d51cb33f78 --- /dev/null +++ b/src/part.c @@ -0,0 +1,62 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +/* Config parameters. */ +#include "../config.h" + +/* MPI headers. */ +#ifdef WITH_MPI +#include <mpi.h> +#endif + +/* This object's header. */ +#include "part.h" + +#ifdef WITH_MPI +/** + * @brief Registers and returns an MPI type for the particles + * + */ +void part_create_mpi_type(MPI_Datatype* part_type) { + + /* This is not the recommended way of doing this. */ + /* One should define the structure field by field */ + /* But as long as we don't do serialization via MPI-IO */ + /* we don't really care. */ + MPI_Type_contiguous(sizeof(struct part) / sizeof(unsigned char), MPI_BYTE, + part_type); + MPI_Type_commit(part_type); +} + +/** + * @brief Registers and returns an MPI type for the xparticles + * + */ +void xpart_create_mpi_type(MPI_Datatype* xpart_type) { + + /* This is not the recommended way of doing this. */ + /* One should define the structure field by field */ + /* But as long as we don't do serialization via MPI-IO */ + /* we don't really care. */ + MPI_Type_contiguous(sizeof(struct xpart) / sizeof(unsigned char), MPI_BYTE, + xpart_type); + MPI_Type_commit(xpart_type); +} + +#endif diff --git a/src/part.h b/src/part.h index 1ad62888b3accd38c6c3f5e13f49988d2c6d69d1..e2940e29c1b008b55efbb7dfa178bae80c134add 100644 --- a/src/part.h +++ b/src/part.h @@ -19,6 +19,18 @@ #ifndef SWIFT_PART_H #define SWIFT_PART_H +/* Config parameters. */ +#include "../config.h" + +/* Some standard headers. */ +#include <stdlib.h> + +/* MPI headers. */ +#ifdef WITH_MPI +#include <mpi.h> +#endif + +/* Local headers. */ #include "const.h" /* Some constants. */ @@ -72,7 +84,7 @@ struct gpart { size_t id; /* Pointer to corresponding SPH part. */ - struct part *part; + struct part* part; }; } __attribute__((aligned(part_align))); @@ -162,8 +174,13 @@ struct part { unsigned long long id; /* Associated gravitas. */ - struct gpart *gpart; + struct gpart* gpart; } __attribute__((aligned(part_align))); +#ifdef WITH_MPI +void part_create_mpi_type(MPI_Datatype* part_type); +void xpart_create_mpi_type(MPI_Datatype* xpart_type); +#endif + #endif /* SWIFT_PART_H */