Zoltan2
Loading...
Searching...
No Matches
Zoltan2_AlltoAll.cpp
Go to the documentation of this file.
1// @HEADER
2//
3// ***********************************************************************
4//
5// Zoltan2: A package of combinatorial algorithms for scientific computing
6// Copyright 2012 Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact Karen Devine (kddevin@sandia.gov)
39// Erik Boman (egboman@sandia.gov)
40// Siva Rajamanickam (srajama@sandia.gov)
41//
42// ***********************************************************************
43//
44// @HEADER
45
51#include <Zoltan2_AlltoAll.hpp>
52#include <Zoltan2_Standards.hpp>
54
55#include <vector>
56#include <climits>
57
58namespace Zoltan2
59{
60
73 const Comm<int> &comm, // Communicator to use for AlltoAll
74 const Environment &env, // Needed only for error handling
75 const ArrayView<const int> &sendCount, // Input: # of data items to
76 // send to each process
77 const ArrayView<int> &recvCount // Output: # of data itmes to
78 // receive from each process
79)
80{
81 int nprocs = comm.getSize();
82 int rank = comm.getRank();
83
84 recvCount[rank] = sendCount[rank];
85
86 if (nprocs > 1) {
87
88 // Post receives
89 RCP<CommRequest<int> > *requests = new RCP<CommRequest<int> > [nprocs];
90 for (int cnt = 0, i = 0; i < nprocs; i++) {
91 if (i != rank) {
92 try {
93 requests[cnt++] = Teuchos::ireceive<int,int>(comm,
94 rcp(&(recvCount[i]),false),
95 i);
96 }
98 }
99 }
100
101 Teuchos::barrier<int>(comm);
102
103 // Send data; can use readySend since receives are posted.
104 for (int i = 0; i < nprocs; i++) {
105 if (i != rank) {
106 try {
107 Teuchos::readySend<int,int>(comm, sendCount[i], i);
108 }
110 }
111 }
112
113 // Wait for messages to return.
114 try {
115 Teuchos::waitAll<int>(comm, arrayView(requests, nprocs-1));
116 }
118
119 delete [] requests;
120 }
121}
122
123/* \brief Specialization for std::string.
124
125 For string of char. Number of chars in a string limited to SCHAR_MAX.
126 Send as chars: 1 char for length of string, then chars in string,
127 1 char for length of next string, and so on.
128 \todo error checking
129 */
130template <>
131void AlltoAllv(const Comm<int> &comm,
132 const Environment &env,
133 const ArrayView<const std::string> &sendBuf,
134 const ArrayView<const int> &sendCount,
135 ArrayRCP<std::string> &recvBuf,
136 const ArrayView<int> &recvCount
137)
138{
139 int nprocs = comm.getSize();
140 int *newCount = new int [nprocs];
141 memset(newCount, 0, sizeof(int) * nprocs);
142 ArrayView<const int> newSendCount(newCount, nprocs);
143
144 size_t numStrings = sendBuf.size();
145 size_t numChars = 0;
146 bool fail=false;
147
148 for (int p=0, i=0; !fail && p < nprocs; p++){
149 for (int c=0; !fail && c < sendCount[p]; c++, i++){
150 size_t nchars = sendBuf[i].size();
151 if (nchars > SCHAR_MAX)
152 fail = true;
153 else
154 newCount[p] += nchars;
155 }
156 newCount[p] += sendCount[p];
157 numChars += newCount[p];
158 }
159
160 if (fail)
161 throw std::runtime_error("id string length exceeds SCHAR_MAX");
162
163 char *sbuf = NULL;
164 if (numChars > 0)
165 sbuf = new char [numChars];
166 char *sbufptr = sbuf;
167
168 ArrayView<const char> newSendBuf(sbuf, numChars);
169
170 for (size_t i=0; i < numStrings; i++){
171 size_t nchars = sendBuf[i].size();
172 *sbufptr++ = static_cast<char>(nchars);
173 for (size_t j=0; j < nchars; j++)
174 *sbufptr++ = sendBuf[i][j];
175 }
176
177 ArrayRCP<char> newRecvBuf;
178 Array<int> newRecvCount(nprocs, 0);
179
180 AlltoAllv<char>(comm, env, newSendBuf, newSendCount,
181 newRecvBuf, newRecvCount());
182
183 delete [] sbuf;
184 delete [] newCount;
185
186 char *inBuf = newRecvBuf.getRawPtr();
187
188 int numNewStrings = 0;
189 char *buf = inBuf;
190 char *endChar = inBuf + newRecvBuf.size();
191 while (buf < endChar){
192 int slen = static_cast<int>(*buf++);
193 buf += slen;
194 numNewStrings++;
195 }
196
197 // Data to return
198 std::string *newStrings = new std::string [numNewStrings];
199
200 buf = inBuf;
201 int next = 0;
202
203 for (int p=0; p < nprocs; p++){
204 int nchars = newRecvCount[p];
205 endChar = buf + nchars;
206 while (buf < endChar){
207 int slen = *buf++;
208 std::string nextString;
209 for (int i=0; i < slen; i++)
210 nextString.push_back(*buf++);
211 newStrings[next++] = nextString;
212 recvCount[p]++;
213 }
214 }
215
216 recvBuf = arcp<std::string>(newStrings, 0, numNewStrings, true);
217}
218
219
220
221/* \brief Specialization for unsigned long long
222 */
223#ifdef HAVE_TPETRA_INT_LONG_LONG
224template <>
225void AlltoAllv(const Comm<int> &comm,
226 const Environment &env,
227 const ArrayView<const unsigned long long> &sendBuf,
228 const ArrayView<const int> &sendCount,
229 ArrayRCP<unsigned long long> &recvBuf, // output, allocated here
230 const ArrayView<int> &recvCount // output
231)
232{
233 const long long *sbuf =
234 reinterpret_cast<const long long *>(sendBuf.getRawPtr());
235 ArrayView<const long long> newSendBuf(sbuf, sendBuf.size());
236 ArrayRCP<long long> newRecvBuf;
237
238 AlltoAllv<long long>(comm, env, newSendBuf, sendCount,
239 newRecvBuf, recvCount);
240
241 recvBuf = arcp_reinterpret_cast<unsigned long long>(newRecvBuf);
242}
243#endif
244
245
246/* \brief Specialization for unsigned short
247 */
248template <>
249void AlltoAllv(const Comm<int> &comm,
250 const Environment &env,
251 const ArrayView<const unsigned short> &sendBuf,
252 const ArrayView<const int> &sendCount,
253 ArrayRCP<unsigned short> &recvBuf, // output, allocated here
254 const ArrayView<int> &recvCount // output
255)
256{
257 const short *sbuf = reinterpret_cast<const short *>(sendBuf.getRawPtr());
258 ArrayView<const short> newSendBuf(sbuf, sendBuf.size());
259 ArrayRCP<short> newRecvBuf;
260
261 AlltoAllv<short>(comm, env, newSendBuf, sendCount,
262 newRecvBuf, recvCount);
263
264 recvBuf = arcp_reinterpret_cast<unsigned short>(newRecvBuf);
265}
266
267
268/* \brief For data type unsigned char (no Teuchos::DirectSerializationTraits)
269 */
270template <>
271void AlltoAllv(const Comm<int> &comm,
272 const Environment &env,
273 const ArrayView<const unsigned char> &sendBuf,
274 const ArrayView<const int> &sendCount,
275 ArrayRCP<unsigned char> &recvBuf, // output, allocated here
276 const ArrayView<int> &recvCount // output
277)
278{
279 const char *sbuf = reinterpret_cast<const char *>(sendBuf.getRawPtr());
280 ArrayView<const char> newSendBuf(sbuf, sendBuf.size());
281 ArrayRCP<char> newRecvBuf;
282
283 AlltoAllv<char>(comm, env, newSendBuf, sendCount,
284 newRecvBuf, recvCount);
285
286 recvBuf = arcp_reinterpret_cast<unsigned char>(newRecvBuf);
287}
288
289} // namespace Z2
AlltoAll communication methods.
Defines the Environment class.
#define Z2_THROW_OUTSIDE_ERROR(env)
Throw an error returned from outside the Zoltan2 library.
Gathering definitions used in software development.
The user parameters, debug, timing and memory profiling output objects, and error checking methods.
Created by mbenlioglu on Aug 31, 2020.
static const std::string fail
void AlltoAllCount(const Comm< int > &comm, const Environment &env, const ArrayView< const int > &sendCount, const ArrayView< int > &recvCount)
Each process sends a value to every process, an all-to-all.
void AlltoAllv(const Comm< int > &comm, const Environment &env, const ArrayView< const std::string > &sendBuf, const ArrayView< const int > &sendCount, ArrayRCP< std::string > &recvBuf, const ArrayView< int > &recvCount)