EpetraExt Development
Loading...
Searching...
No Matches
EpetraExt_Directory.h
Go to the documentation of this file.
1//@HEADER
2// ***********************************************************************
3//
4// EpetraExt: Epetra Extended - Linear Algebra Services Package
5// Copyright (2011) Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8// the U.S. Government retains certain rights in this software.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38//
39// ***********************************************************************
40//@HEADER
41#ifndef EPETRAEXT_DIRECTORY_H
42#define EPETRAEXT_DIRECTORY_H
43
44#if defined(EpetraExt_SHOW_DEPRECATED_WARNINGS)
45#ifdef __GNUC__
46#warning "The EpetraExt package is deprecated"
47#endif
48#endif
49
50// ----------- Includes ----------
51
52#include <map>
53#include <vector>
54
55#include <cmath>
56
57#include <Teuchos_RCP.hpp>
58
59#include <EpetraExt_Functors.h>
60
61namespace EpetraExt {
62
64
66template <typename KT, typename DT, class DH, class AC, class MG>
68{
69
70public:
71
72 typedef typename std::map< KT, Teuchos::RCP<DT> > DataMap;
73 typedef typename DataMap::iterator DataMapIter;
74 typedef typename DataMap::const_iterator DataMapCIter;
75
76 typedef typename std::multimap< KT, Teuchos::RCP<DT> > DataRecvMap;
77 typedef typename DataRecvMap::iterator DataRecvMapIter;
78 typedef typename DataRecvMap::const_iterator DataRecvMapCIter;
79
80 typedef typename std::vector<KT> KeyList;
81 typedef typename KeyList::iterator KeyListIter;
82 typedef typename KeyList::const_iterator KeyListCIter;
83
84 typedef typename std::vector<int> ProcList;
85 typedef typename ProcList::iterator ProcListIter;
86
87 typedef typename std::pair<int,KT> ProcKeyPair;
88 typedef typename std::vector<ProcKeyPair> ProcKeyList;
89 typedef typename ProcKeyList::iterator ProcKeyListIter;
90
91 typedef typename AC::iterator ContainerIter;
92 typedef typename AC::const_iterator ContainerCIter;
93
94 // Constructors
95 Directory( MG migrate,
96 DH distHash )
97 : migrate_(migrate),
98 distHash_(distHash)
99 {}
100
101 // Destructor
103
104private:
105 // No public copy construction, assignment, or equality operators
106 Directory( const Directory & );
107
108 Directory & operator=( const Directory & );
109
110 bool operator==( const Directory & ) const;
111 bool operator!=( const Directory & ) const;
112
113public:
114
115 // Add objects from directory.
116 void addEntries( DataMap const & entries );
117
118 // Remove objects from directory.
119 void deleteEntries( KeyList & keys );
120
121 // Get the items in the directory.
122 void getEntries( KeyList & keys,
123 DataMap & entries );
124
125 AC & container() { return container_; }
126 ContainerIter & begin() { return container_.begin(); }
127 ContainerIter & end() { return container_.end(); }
128
129protected:
130
131#ifdef EPETRA_MPI
132 void pushKeys_( KeyList &, KeyList &, ProcList & );
133 void pushData_( DataMap const &, DataRecvMap &, ProcList & );
134#endif
135
139
140};
141
143/*** Hash function for processor assignment
144 */
145template <typename T>
146class Hash
147{
148 int operator()( const T & in ) { assert(0); return 0; }
149};
150
151template <>
152class Hash<std::string>
153{
154 float size_;
155
156 public:
157
158 Hash( int size )
159 : size_( static_cast<double>(size) )
160 {}
161
162 int operator()( const std::string & in )
163 {
164 int slen = in.length();
165 int sum = 0;
166 for( int i = 0; i < slen; ++i )
167 sum += static_cast<int>( in[i] );
168
169 return static_cast<int>( fmod( static_cast<float>( sum ), size_ ) );
170 }
171};
172
174
176template < typename T, typename U >
177void SortContainer2( T & firstContainer, U & secondContainer )
178{
179 typedef typename std::multimap< typename T::value_type, typename U::value_type> UTMultiMap;
180
181 UTMultiMap SortMap;
182
183 typename T::iterator iterT = firstContainer.begin();
184 typename T::iterator endT = firstContainer.end();
185 typename U::iterator iterU = secondContainer.begin();
186 typename U::iterator endU = secondContainer.end();
187
188 for( ; (iterT!=endT)||(iterU!=endU) ; ++iterT, ++iterU )
189 SortMap.insert( typename UTMultiMap::value_type( *iterT, *iterU ) );
190
191 firstContainer.clear();
192 secondContainer.clear();
193
194 typename UTMultiMap::iterator iterUTM = SortMap.begin();
195 typename UTMultiMap::iterator endUTM = SortMap.end();
196
197 for( ; iterUTM != endUTM; ++iterUTM )
198 {
199 firstContainer.push_back( iterUTM->first );
200 secondContainer.push_back( iterUTM->second );
201 }
202}
203
205
207template < typename T >
208bool IsSorted( T & container )
209{
210 if( container.size() < 2 ) return true;
211
212 typename T::iterator iterT = container.begin();
213 typename T::iterator endT = container.end();
214 typename T::iterator iterTPlus = iterT;
215 iterTPlus++;
216
217 for( ; iterTPlus != endT; ++iterT, ++iterTPlus )
218 if( !(*iterT<*iterTPlus) ) return false;
219
220 return true;
221}
222
223template <typename KT, typename DT, class DH, class AC, class MG>
224void
226addEntries( DataMap const & entries )
227{
228#ifdef EPETRA_MPI
229
230 DataRecvMap newEntries;
231 ProcList procs;
232 pushData_( entries, newEntries, procs );
233
234 DataRecvMapCIter citDM = newEntries.begin();
235 DataRecvMapCIter cendDM = newEntries.end();
236
237#else
238
239 DataMapCIter citDM = entries.begin();
240 DataMapCIter cendDM = entries.end();
241
242#endif
243
244 for( ; citDM != cendDM; ++citDM )
245 container_.insert( *citDM );
246}
247
248template <typename KT, typename DT, class DH, class AC, class MG>
249void
251deleteEntries( KeyList & keys )
252{
253#ifdef EPETRA_MPI
254
255 KeyList newKeys;
256 ProcList procs;
257 pushKeys_( keys, newKeys, procs );
258
259 KeyListCIter citKL = newKeys.begin();
260 KeyListCIter cendKL = newKeys.end();
261
262#else
263
264 KeyListCIter citKL = keys.begin();
265 KeyListCIter cendKL = keys.end();
266
267#endif
268
269 for( ; citKL != cendKL; ++citKL )
270 container_.erase( *citKL );
271}
272
273template <typename KT, typename DT, class DH, class AC, class MG>
274void
276getEntries( KeyList & keys,
277 DataMap & entries )
278{
279#ifdef EPETRA_MPI
280
281 //Push Keys to owning processors
282 KeyList newKeys;
283 ProcList procs;
284 pushKeys_( keys, newKeys, procs );
285
286 KeyListCIter citKL = newKeys.begin();
287 KeyListCIter cendKL = newKeys.end();
288
289 //Rvs migrate to move data from directory back to requesting procs
290 DataMap newEntries;
291 for( ; citKL != cendKL; ++citKL )
292 {
293 if( !container_.count( *citKL ) )
294 throw "Data not in directory: " + *citKL + "\n";
295
296 newEntries[*citKL] = (container_.lower_bound( *citKL ))->second;
297 }
298
299 migrate_.rvs( procs, newKeys, newEntries, entries );
300
301#else
302
303 KeyListCIter citKL = keys.begin();
304 KeyListCIter cendKL = keys.end();
305 for( ; citKL != cendKL; ++citKL )
306 {
307 if( !container_.count( *citKL ) )
308 throw "Data not in directory: " + *citKL + "\n";
309
310 entries[*citKL] = (container_.lower_bound( *citKL ))->second;
311 }
312
313#endif
314}
315
316#ifdef EPETRA_MPI
317
318template <typename KT, typename DT, class DH, class AC, class MG>
319void
321pushKeys_( KeyList & sKeys,
322 KeyList & rKeys,
323 ProcList & procs )
324{
325 KeyListCIter itKL = sKeys.begin();
326 KeyListCIter endKL = sKeys.end();
327
328 procs.clear();
329 for( ; itKL != endKL; ++itKL )
330 procs.push_back( distHash_(*itKL) );
331
332 if( !IsSorted( procs ) ) SortContainer2( procs, sKeys );
333
334 migrate_( procs, sKeys, rKeys );
335}
336
337template <typename KT, typename DT, class DH, class AC, class MG>
338void
340pushData_( DataMap const & sData,
341 DataRecvMap & rData,
342 ProcList & procs )
343{
344 DataMapCIter itDM = sData.begin();
345 DataMapCIter endDM = sData.end();
346
347 procs.clear();
348 for( ; itDM != endDM; ++itDM )
349 procs.push_back( distHash_(itDM->first) );
350
351 migrate_( procs, sData, rData );
352}
353
354#endif
355
356} //namespace EpetraExt
357
358#endif
Distributed Directory Tool.
void addEntries(DataMap const &entries)
KeyList::const_iterator KeyListCIter
std::pair< int, KT > ProcKeyPair
void pushKeys_(KeyList &, KeyList &, ProcList &)
std::multimap< KT, Teuchos::RCP< DT > > DataRecvMap
AC::const_iterator ContainerCIter
DataMap::const_iterator DataMapCIter
void pushData_(DataMap const &, DataRecvMap &, ProcList &)
ProcKeyList::iterator ProcKeyListIter
ProcList::iterator ProcListIter
std::vector< KT > KeyList
DataRecvMap::const_iterator DataRecvMapCIter
void deleteEntries(KeyList &keys)
std::vector< ProcKeyPair > ProcKeyList
Directory(MG migrate, DH distHash)
std::map< KT, Teuchos::RCP< DT > > DataMap
DataRecvMap::iterator DataRecvMapIter
std::vector< int > ProcList
KeyList::iterator KeyListIter
void getEntries(KeyList &keys, DataMap &entries)
DataMap::iterator DataMapIter
int operator()(const std::string &in)
EpetraExt::BlockCrsMatrix: A class for constructing a distributed block matrix.
bool IsSorted(T &container)
Checks if data in a container is sorted.
void SortContainer2(T &firstContainer, U &secondContainer)
Sorts a given container: deal with a problem with some STL impl.