annotate src/fftw-3.3.8/mpi/wisdom-api.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents d0c2a83c1364
children
rev   line source
Chris@82 1 /*
Chris@82 2 * Copyright (c) 2003, 2007-14 Matteo Frigo
Chris@82 3 * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
Chris@82 4 *
Chris@82 5 * This program is free software; you can redistribute it and/or modify
Chris@82 6 * it under the terms of the GNU General Public License as published by
Chris@82 7 * the Free Software Foundation; either version 2 of the License, or
Chris@82 8 * (at your option) any later version.
Chris@82 9 *
Chris@82 10 * This program is distributed in the hope that it will be useful,
Chris@82 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@82 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@82 13 * GNU General Public License for more details.
Chris@82 14 *
Chris@82 15 * You should have received a copy of the GNU General Public License
Chris@82 16 * along with this program; if not, write to the Free Software
Chris@82 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Chris@82 18 *
Chris@82 19 */
Chris@82 20
Chris@82 21 #include "fftw3-mpi.h"
Chris@82 22 #include "ifftw-mpi.h"
Chris@82 23 #include <string.h>
Chris@82 24
Chris@82 25 #if SIZEOF_SIZE_T == SIZEOF_UNSIGNED_INT
Chris@82 26 # define FFTW_MPI_SIZE_T MPI_UNSIGNED
Chris@82 27 #elif SIZEOF_SIZE_T == SIZEOF_UNSIGNED_LONG
Chris@82 28 # define FFTW_MPI_SIZE_T MPI_UNSIGNED_LONG
Chris@82 29 #elif SIZEOF_SIZE_T == SIZEOF_UNSIGNED_LONG_LONG
Chris@82 30 # define FFTW_MPI_SIZE_T MPI_UNSIGNED_LONG_LONG
Chris@82 31 #else
Chris@82 32 # error MPI type for size_t is unknown
Chris@82 33 # define FFTW_MPI_SIZE_T MPI_UNSIGNED_LONG
Chris@82 34 #endif
Chris@82 35
Chris@82 36 /* Import wisdom from all processes to process 0, as prelude to
Chris@82 37 exporting a single wisdom file (this is convenient when we are
Chris@82 38 running on identical processors, to avoid the annoyance of having
Chris@82 39 per-process wisdom files). In order to make the time for this
Chris@82 40 operation logarithmic in the number of processors (rather than
Chris@82 41 linear), we employ a tree reduction algorithm. This means that the
Chris@82 42 wisdom is modified on processes other than root, which shouldn't
Chris@82 43 matter in practice. */
Chris@82 44 void XM(gather_wisdom)(MPI_Comm comm_)
Chris@82 45 {
Chris@82 46 MPI_Comm comm, comm2;
Chris@82 47 int my_pe, n_pes;
Chris@82 48 char *wis;
Chris@82 49 size_t wislen;
Chris@82 50 MPI_Status status;
Chris@82 51
Chris@82 52 MPI_Comm_dup(comm_, &comm);
Chris@82 53 MPI_Comm_rank(comm, &my_pe);
Chris@82 54 MPI_Comm_size(comm, &n_pes);
Chris@82 55
Chris@82 56 if (n_pes > 2) { /* recursively split into even/odd processes */
Chris@82 57 MPI_Comm_split(comm, my_pe % 2, my_pe, &comm2);
Chris@82 58 XM(gather_wisdom)(comm2);
Chris@82 59 MPI_Comm_free(&comm2);
Chris@82 60 }
Chris@82 61 if (n_pes > 1 && my_pe < 2) { /* import process 1 -> 0 */
Chris@82 62 if (my_pe == 1) {
Chris@82 63 wis = X(export_wisdom_to_string)();
Chris@82 64 wislen = strlen(wis) + 1;
Chris@82 65 MPI_Send(&wislen, 1, FFTW_MPI_SIZE_T, 0, 111, comm);
Chris@82 66 MPI_Send(wis, wislen, MPI_CHAR, 0, 222, comm);
Chris@82 67 free(wis);
Chris@82 68 }
Chris@82 69 else /* my_pe == 0 */ {
Chris@82 70 MPI_Recv(&wislen, 1, FFTW_MPI_SIZE_T, 1, 111, comm, &status);
Chris@82 71 wis = (char *) MALLOC(wislen * sizeof(char), OTHER);
Chris@82 72 MPI_Recv(wis, wislen, MPI_CHAR, 1, 222, comm, &status);
Chris@82 73 if (!X(import_wisdom_from_string)(wis))
Chris@82 74 MPI_Abort(comm, 1);
Chris@82 75 X(ifree)(wis);
Chris@82 76 }
Chris@82 77 }
Chris@82 78 MPI_Comm_free(&comm);
Chris@82 79 }
Chris@82 80
Chris@82 81 /* broadcast wisdom from process 0 to all other processes; this
Chris@82 82 is useful so that we can import wisdom once and not worry
Chris@82 83 about parallel I/O or process-specific wisdom, although of
Chris@82 84 course it assumes that all the processes have identical
Chris@82 85 performance characteristics (i.e. identical hardware). */
Chris@82 86 void XM(broadcast_wisdom)(MPI_Comm comm_)
Chris@82 87 {
Chris@82 88 MPI_Comm comm;
Chris@82 89 int my_pe;
Chris@82 90 char *wis;
Chris@82 91 size_t wislen;
Chris@82 92
Chris@82 93 MPI_Comm_dup(comm_, &comm);
Chris@82 94 MPI_Comm_rank(comm, &my_pe);
Chris@82 95
Chris@82 96 if (my_pe != 0) {
Chris@82 97 MPI_Bcast(&wislen, 1, FFTW_MPI_SIZE_T, 0, comm);
Chris@82 98 wis = (char *) MALLOC(wislen * sizeof(char), OTHER);
Chris@82 99 MPI_Bcast(wis, wislen, MPI_CHAR, 0, comm);
Chris@82 100 if (!X(import_wisdom_from_string)(wis))
Chris@82 101 MPI_Abort(comm, 1);
Chris@82 102 X(ifree)(wis);
Chris@82 103 }
Chris@82 104 else /* my_pe == 0 */ {
Chris@82 105 wis = X(export_wisdom_to_string)();
Chris@82 106 wislen = strlen(wis) + 1;
Chris@82 107 MPI_Bcast(&wislen, 1, FFTW_MPI_SIZE_T, 0, comm);
Chris@82 108 MPI_Bcast(wis, wislen, MPI_CHAR, 0, comm);
Chris@82 109 X(free)(wis);
Chris@82 110 }
Chris@82 111 MPI_Comm_free(&comm);
Chris@82 112 }