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