Zoltan2
Loading...
Searching...
No Matches
Zoltan2_AlltoAll.cpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Zoltan2: A package of combinatorial algorithms for scientific computing
4//
5// Copyright 2012 NTESS and the Zoltan2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
15#include <Zoltan2_AlltoAll.hpp>
16#include <Zoltan2_Standards.hpp>
18
19#include <vector>
20#include <climits>
21
22namespace Zoltan2
23{
24
37 const Comm<int> &comm, // Communicator to use for AlltoAll
38 const Environment &env, // Needed only for error handling
39 const ArrayView<const int> &sendCount, // Input: # of data items to
40 // send to each process
41 const ArrayView<int> &recvCount // Output: # of data itmes to
42 // receive from each process
43)
44{
45 int nprocs = comm.getSize();
46 int rank = comm.getRank();
47
48 recvCount[rank] = sendCount[rank];
49
50 if (nprocs > 1) {
51
52 // Post receives
53 RCP<CommRequest<int> > *requests = new RCP<CommRequest<int> > [nprocs];
54 for (int cnt = 0, i = 0; i < nprocs; i++) {
55 if (i != rank) {
56 try {
57 requests[cnt++] = Teuchos::ireceive<int,int>(comm,
58 rcp(&(recvCount[i]),false),
59 i);
60 }
62 }
63 }
64
65 Teuchos::barrier<int>(comm);
66
67 // Send data; can use readySend since receives are posted.
68 for (int i = 0; i < nprocs; i++) {
69 if (i != rank) {
70 try {
71 Teuchos::readySend<int,int>(comm, sendCount[i], i);
72 }
74 }
75 }
76
77 // Wait for messages to return.
78 try {
79 Teuchos::waitAll<int>(comm, arrayView(requests, nprocs-1));
80 }
82
83 delete [] requests;
84 }
85}
86
87/* \brief Specialization for std::string.
88
89 For string of char. Number of chars in a string limited to SCHAR_MAX.
90 Send as chars: 1 char for length of string, then chars in string,
91 1 char for length of next string, and so on.
92 \todo error checking
93 */
94template <>
95void AlltoAllv(const Comm<int> &comm,
96 const Environment &env,
97 const ArrayView<const std::string> &sendBuf,
98 const ArrayView<const int> &sendCount,
99 ArrayRCP<std::string> &recvBuf,
100 const ArrayView<int> &recvCount
101)
102{
103 int nprocs = comm.getSize();
104 int *newCount = new int [nprocs];
105 memset(newCount, 0, sizeof(int) * nprocs);
106 ArrayView<const int> newSendCount(newCount, nprocs);
107
108 size_t numStrings = sendBuf.size();
109 size_t numChars = 0;
110 bool fail=false;
111
112 for (int p=0, i=0; !fail && p < nprocs; p++){
113 for (int c=0; !fail && c < sendCount[p]; c++, i++){
114 size_t nchars = sendBuf[i].size();
115 if (nchars > SCHAR_MAX)
116 fail = true;
117 else
118 newCount[p] += nchars;
119 }
120 newCount[p] += sendCount[p];
121 numChars += newCount[p];
122 }
123
124 if (fail)
125 throw std::runtime_error("id string length exceeds SCHAR_MAX");
126
127 char *sbuf = NULL;
128 if (numChars > 0)
129 sbuf = new char [numChars];
130 char *sbufptr = sbuf;
131
132 ArrayView<const char> newSendBuf(sbuf, numChars);
133
134 for (size_t i=0; i < numStrings; i++){
135 size_t nchars = sendBuf[i].size();
136 *sbufptr++ = static_cast<char>(nchars);
137 for (size_t j=0; j < nchars; j++)
138 *sbufptr++ = sendBuf[i][j];
139 }
140
141 ArrayRCP<char> newRecvBuf;
142 Array<int> newRecvCount(nprocs, 0);
143
144 AlltoAllv<char>(comm, env, newSendBuf, newSendCount,
145 newRecvBuf, newRecvCount());
146
147 delete [] sbuf;
148 delete [] newCount;
149
150 char *inBuf = newRecvBuf.getRawPtr();
151
152 int numNewStrings = 0;
153 char *buf = inBuf;
154 char *endChar = inBuf + newRecvBuf.size();
155 while (buf < endChar){
156 int slen = static_cast<int>(*buf++);
157 buf += slen;
158 numNewStrings++;
159 }
160
161 // Data to return
162 std::string *newStrings = new std::string [numNewStrings];
163
164 buf = inBuf;
165 int next = 0;
166
167 for (int p=0; p < nprocs; p++){
168 int nchars = newRecvCount[p];
169 endChar = buf + nchars;
170 while (buf < endChar){
171 int slen = *buf++;
172 std::string nextString;
173 for (int i=0; i < slen; i++)
174 nextString.push_back(*buf++);
175 newStrings[next++] = nextString;
176 recvCount[p]++;
177 }
178 }
179
180 recvBuf = arcp<std::string>(newStrings, 0, numNewStrings, true);
181}
182
183
184
185/* \brief Specialization for unsigned long long
186 */
187#ifdef HAVE_TPETRA_INT_LONG_LONG
188template <>
189void AlltoAllv(const Comm<int> &comm,
190 const Environment &env,
191 const ArrayView<const unsigned long long> &sendBuf,
192 const ArrayView<const int> &sendCount,
193 ArrayRCP<unsigned long long> &recvBuf, // output, allocated here
194 const ArrayView<int> &recvCount // output
195)
196{
197 const long long *sbuf =
198 reinterpret_cast<const long long *>(sendBuf.getRawPtr());
199 ArrayView<const long long> newSendBuf(sbuf, sendBuf.size());
200 ArrayRCP<long long> newRecvBuf;
201
202 AlltoAllv<long long>(comm, env, newSendBuf, sendCount,
203 newRecvBuf, recvCount);
204
205 recvBuf = arcp_reinterpret_cast<unsigned long long>(newRecvBuf);
206}
207#endif
208
209
210/* \brief Specialization for unsigned short
211 */
212template <>
213void AlltoAllv(const Comm<int> &comm,
214 const Environment &env,
215 const ArrayView<const unsigned short> &sendBuf,
216 const ArrayView<const int> &sendCount,
217 ArrayRCP<unsigned short> &recvBuf, // output, allocated here
218 const ArrayView<int> &recvCount // output
219)
220{
221 const short *sbuf = reinterpret_cast<const short *>(sendBuf.getRawPtr());
222 ArrayView<const short> newSendBuf(sbuf, sendBuf.size());
223 ArrayRCP<short> newRecvBuf;
224
225 AlltoAllv<short>(comm, env, newSendBuf, sendCount,
226 newRecvBuf, recvCount);
227
228 recvBuf = arcp_reinterpret_cast<unsigned short>(newRecvBuf);
229}
230
231
232/* \brief For data type unsigned char (no Teuchos::DirectSerializationTraits)
233 */
234template <>
235void AlltoAllv(const Comm<int> &comm,
236 const Environment &env,
237 const ArrayView<const unsigned char> &sendBuf,
238 const ArrayView<const int> &sendCount,
239 ArrayRCP<unsigned char> &recvBuf, // output, allocated here
240 const ArrayView<int> &recvCount // output
241)
242{
243 const char *sbuf = reinterpret_cast<const char *>(sendBuf.getRawPtr());
244 ArrayView<const char> newSendBuf(sbuf, sendBuf.size());
245 ArrayRCP<char> newRecvBuf;
246
247 AlltoAllv<char>(comm, env, newSendBuf, sendCount,
248 newRecvBuf, recvCount);
249
250 recvBuf = arcp_reinterpret_cast<unsigned char>(newRecvBuf);
251}
252
253} // 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)