8#include <alien/utils/Precomp.h>
9#include <alien/index_manager/IIndexManager.h>
10#include "BlockSizes.h"
12#include <alien/utils/Precomp.h>
13#include <alien/utils/Trace.h>
15#include <arccore/message_passing/ISerializeMessageList.h>
16#include <arccore/message_passing/Messages.h>
48 Arccore::Ref<Arccore::MessagePassing::ISerializeMessage> m_comm;
62 Arccore::Ref<Arccore::MessagePassing::ISerializeMessage> m_comm;
63 UniqueArray<Integer> m_ids;
67prepare(
const IIndexManager& index_mng, ConstArrayView<Integer> block_sizes)
70 throw FatalErrorException(A_FUNCINFO,
"BlockSizes is already prepared");
76 const Integer size = block_sizes.size();
78 m_local_sizes.resize(size);
79 m_local_offsets.resize(size + 1);
81 Integer sum = 0, max_size = 0;
82 for (Integer i = 0; i < size; ++i) {
83 const Integer block_size = block_sizes[i];
84 max_size = (max_size > block_size) ? max_size : block_size;
85 const Integer index = i + offset;
86 m_sizes[index] = m_local_sizes[i] = block_size;
87 m_offsets[index] = m_local_offsets[i] = sum;
90 m_local_offsets[size] = sum;
91 m_max_size = max_size;
95 const bool is_parallel = (m_parallel_mng !=
nullptr) && (m_parallel_mng->commSize() > 1);
99 const Integer rank = m_parallel_mng->commRank();
101 typedef std::map<String, EntrySendRequest> SendRequestByEntry;
102 typedef std::map<Integer, SendRequestByEntry> SendRequests;
103 SendRequests sendRequests;
105 typedef SharedArray<Integer> Owners;
106 typedef std::map<String, Owners> OwnersByEntry;
107 OwnersByEntry owners_by_entry;
111 ConstArrayView<Integer> all_lids = e->getAllLocalIds();
112 Owners owners = e->getFamily().owners(all_lids);
113 const String name = e->getName();
114 owners_by_entry[name] = owners;
115 for (Integer i = 0; i < owners.size(); ++i) {
116 if (owners[i] != rank)
117 sendRequests[owners[i]][name].m_count++;
122 Alien::Ref<ISerializeMessageList> messageList =
123 Arccore::MessagePassing::mpCreateSerializeMessageListRef(m_parallel_mng);
125 UniqueArray<Integer> sendToDomains(2 * m_parallel_mng->commSize(), 0);
127 for (SendRequests::iterator i = sendRequests.begin(); i != sendRequests.end(); ++i) {
128 const Integer destDomainId = i->first;
129 SendRequestByEntry& requests = i->second;
130 for (SendRequestByEntry::iterator j = requests.begin(); j != requests.end(); ++j) {
131 EntrySendRequest& request = j->second;
132 const String& nameString = j->first;
133 sendToDomains[2 * destDomainId + 0] += 1;
134 sendToDomains[2 * destDomainId + 1] += request.m_count;
135 request.m_comm = messageList->createAndAddMessage(MessageRank(destDomainId),
136 Arccore::MessagePassing::ePointToPointMessageType::MsgSend);
137 auto sbuf = request.m_comm->serializer();
139 sbuf->setMode(Alien::ISerializer::ModeReserve);
140 sbuf->reserve(nameString);
141 sbuf->reserveInteger(1);
142 sbuf->reserve(Alien::ISerializer::DT_Int32, request.m_count);
143 sbuf->allocateBuffer();
144 sbuf->setMode(Alien::ISerializer::ModePut);
145 sbuf->put(nameString);
146 sbuf->put(request.m_count);
151 const String name = e->getName();
152 Owners& owners = owners_by_entry[name];
153 ConstArrayView<Integer> all_indexes = e->getAllIndexes();
154 for (Integer i = 0; i < owners.size(); ++i) {
155 if (owners[i] != rank)
156 sendRequests[owners[i]][name].m_comm->serializer()->put(all_indexes[i]);
160 UniqueArray<Integer> recvFromDomains(2 * m_parallel_mng->commSize());
161 Arccore::MessagePassing::mpAllToAll(m_parallel_mng, sendToDomains, recvFromDomains, 2);
163 typedef std::list<EntryRecvRequest> RecvRequests;
164 RecvRequests recvRequests;
166 for (Integer isd = 0, nsd = m_parallel_mng->commSize(); isd < nsd; ++isd) {
167 Integer recvCount = recvFromDomains[2 * isd + 0];
168 while (recvCount-- > 0) {
169 auto recvMsg = messageList->createAndAddMessage(MessageRank(isd),
170 Arccore::MessagePassing::ePointToPointMessageType::MsgReceive);
172 recvRequests.push_back(EntryRecvRequest());
173 EntryRecvRequest& recvRequest = recvRequests.back();
174 recvRequest.m_comm = recvMsg;
178 messageList->processPendingMessages();
179 messageList->waitMessages(Arccore::MessagePassing::WaitAll);
182 messageList = Arccore::MessagePassing::mpCreateSerializeMessageListRef(m_parallel_mng);
184 for (RecvRequests::iterator i = recvRequests.begin(); i != recvRequests.end(); ++i) {
185 EntryRecvRequest& recvRequest = *i;
192 auto sbuf = recvRequest.m_comm->serializer();
193 sbuf->setMode(Alien::ISerializer::ModeGet);
195 sbuf->get(nameString);
196 uidCount = sbuf->getInteger();
197 recvRequest.m_ids.resize(uidCount);
198 sbuf->get(recvRequest.m_ids);
199 ALIEN_ASSERT((uidCount == recvRequest.m_ids.size()), (
"Inconsistency detected"));
203 auto dest = recvRequest.m_comm->destination();
204 auto orig = recvRequest.m_comm->source();
205 recvRequest.m_comm.reset();
206 recvRequest.m_comm = messageList->createAndAddMessage(dest, Arccore::MessagePassing::ePointToPointMessageType::MsgSend);
209 auto sbuf = recvRequest.m_comm->serializer();
211 sbuf->setMode(Alien::ISerializer::ModeReserve);
212 sbuf->reserve(nameString);
213 sbuf->reserveInteger(1);
214 sbuf->reserveInteger(uidCount);
215 sbuf->allocateBuffer();
216 sbuf->setMode(Alien::ISerializer::ModePut);
217 sbuf->put(nameString);
222 for (RecvRequests::iterator i = recvRequests.begin(); i != recvRequests.end(); ++i) {
223 EntryRecvRequest& recvRequest = *i;
225 auto sbuf = recvRequest.m_comm->serializer();
226 auto& ids = recvRequest.m_ids;
227 for (Integer j = 0; j < ids.size(); ++j) {
228 sbuf->putInteger(block_sizes[ids[j] - offset]);
233 typedef std::list<Alien::Ref<Alien::ISerializeMessage>> ReturnedRequests;
234 ReturnedRequests returnedRequests;
236 typedef std::map<Integer, EntrySendRequest*> SubFastReturnMap;
237 typedef std::map<String, SubFastReturnMap> FastReturnMap;
238 FastReturnMap fastReturnMap;
240 for (SendRequests::iterator i = sendRequests.begin(); i != sendRequests.end(); ++i) {
241 const Integer destDomainId = i->first;
242 SendRequestByEntry& requests = i->second;
243 for (SendRequestByEntry::iterator j = requests.begin(); j != requests.end(); ++j) {
244 EntrySendRequest& request = j->second;
245 const String nameString = j->first;
247 request.m_comm.reset();
249 auto msg = messageList->createAndAddMessage(MessageRank(destDomainId),
250 Arccore::MessagePassing::ePointToPointMessageType::MsgReceive);
252 returnedRequests.push_back(msg);
254 fastReturnMap[nameString][destDomainId] = &request;
258 messageList->processPendingMessages();
259 messageList->waitMessages(Arccore::MessagePassing::WaitAll);
262 for (ReturnedRequests::iterator i = returnedRequests.begin(); i != returnedRequests.end(); ++i) {
267 auto origDomainId = message->destination().value();
268 auto sbuf = message->serializer();
269 sbuf->setMode(Alien::ISerializer::ModeGet);
271 sbuf->get(nameString);
272 ALIEN_ASSERT((fastReturnMap[nameString][origDomainId] != NULL), (
"Inconsistency detected"));
273 EntrySendRequest& request = *fastReturnMap[nameString][origDomainId];
275 const Integer idCount = sbuf->getInteger();
276 ALIEN_ASSERT((request.m_count == idCount), (
"Inconsistency detected"));
280 ConstArrayView<Integer> all_indexes = e->getAllIndexes();
281 Owners owners = owners_by_entry[(*e).getName()];
282 for (Integer i = 0; i < owners.size(); ++i) {
283 const Integer index = all_indexes[i];
284 if (owners[i] != rank) {
285 EntrySendRequest& request = sendRequests[owners[i]][e->getName()];
286 ALIEN_ASSERT((request.m_count > 0), (
"Unexpected empty request"));
288 const Integer block_size = request.m_comm->serializer()->getInteger();
289 m_sizes[index] = block_size;
290 m_max_size = (m_max_size > block_size) ? m_max_size : block_size;
291 m_offsets[index] = sum;
305 m_is_prepared =
true;
312size(Integer index)
const
314 ALIEN_ASSERT((m_is_prepared), (
"BlockSizes is not prepared"));
316 ValuePerBlock::const_iterator it = m_sizes.find(index);
318 if (it == m_sizes.end())
319 throw Alien::FatalErrorException(A_FUNCINFO,
"index is not registered");
328sizeFromLocalIndex(Integer index)
const
332 ALIEN_ASSERT((m_is_prepared), (
"BlockSizes is not prepared"));
334 return m_local_sizes[index];
341offset(Integer index)
const
345 ALIEN_ASSERT((m_is_prepared), (
"BlockSizes is not prepared"));
347 ValuePerBlock::const_iterator it = m_offsets.find(index);
349 if (it == m_offsets.end())
350 throw Alien::FatalErrorException(A_FUNCINFO,
"index is not registered");
359offsetFromLocalIndex(Integer index)
const
361 ALIEN_ASSERT((m_is_prepared), (
"BlockSizes is not prepared"));
363 return m_local_offsets[index];
372 ALIEN_ASSERT((m_is_prepared), (
"BlockSizes is not prepared"));
383 ALIEN_ASSERT((m_is_prepared), (
"BlockSizes is not prepared"));
390ConstArrayView<Integer>
392sizeOfLocalIndex()
const
394 return m_local_sizes;
399ConstArrayView<Integer>
401offsetOfLocalIndex()
const
403 return m_local_offsets;
Classe d'énumération des Entry connues.
bool hasNext() const
Teste l'existence d'un élément suivant.
virtual Arccore::Integer minLocalIndex() const =0
Retourne l'indice minimum local.
virtual Alien::IMessagePassingMng * parallelMng() const =0
Donne le gestionnaire parallèle ayant servi à l'indexation.
virtual EntryEnumerator enumerateEntry() const =0
Construction d'un enumerateur sur les Entry.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --