EpetraExt Package Browser (Single Doxygen Collection) 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// ----------- Includes ----------
45
46#include <map>
47#include <vector>
48
49#include <cmath>
50
51#include <Teuchos_RCP.hpp>
52
53#include <EpetraExt_Functors.h>
54
55namespace EpetraExt {
56
58
60template <typename KT, typename DT, class DH, class AC, class MG>
62{
63
64public:
65
66 typedef typename std::map< KT, Teuchos::RCP<DT> > DataMap;
67 typedef typename DataMap::iterator DataMapIter;
68 typedef typename DataMap::const_iterator DataMapCIter;
69
70 typedef typename std::multimap< KT, Teuchos::RCP<DT> > DataRecvMap;
71 typedef typename DataRecvMap::iterator DataRecvMapIter;
72 typedef typename DataRecvMap::const_iterator DataRecvMapCIter;
73
74 typedef typename std::vector<KT> KeyList;
75 typedef typename KeyList::iterator KeyListIter;
76 typedef typename KeyList::const_iterator KeyListCIter;
77
78 typedef typename std::vector<int> ProcList;
79 typedef typename ProcList::iterator ProcListIter;
80
81 typedef typename std::pair<int,KT> ProcKeyPair;
82 typedef typename std::vector<ProcKeyPair> ProcKeyList;
83 typedef typename ProcKeyList::iterator ProcKeyListIter;
84
85 typedef typename AC::iterator ContainerIter;
86 typedef typename AC::const_iterator ContainerCIter;
87
88 // Constructors
89 Directory( MG migrate,
90 DH distHash )
91 : migrate_(migrate),
92 distHash_(distHash)
93 {}
94
95 // Destructor
97
98private:
99 // No public copy construction, assignment, or equality operators
101
103
104 bool operator==( const Directory & ) const;
105 bool operator!=( const Directory & ) const;
106
107public:
108
109 // Add objects from directory.
110 void addEntries( DataMap const & entries );
111
112 // Remove objects from directory.
113 void deleteEntries( KeyList & keys );
114
115 // Get the items in the directory.
116 void getEntries( KeyList & keys,
117 DataMap & entries );
118
119 AC & container() { return container_; }
120 ContainerIter & begin() { return container_.begin(); }
121 ContainerIter & end() { return container_.end(); }
122
123protected:
124
125#ifdef EPETRA_MPI
126 void pushKeys_( KeyList &, KeyList &, ProcList & );
127 void pushData_( DataMap const &, DataRecvMap &, ProcList & );
128#endif
129
133
134};
135
137/*** Hash function for processor assignment
138 */
139template <typename T>
140class Hash
141{
142 int operator()( const T & in ) { assert(0); return 0; }
143};
144
145template <>
146class Hash<std::string>
147{
148 float size_;
149
150 public:
151
152 Hash( int size )
153 : size_( static_cast<double>(size) )
154 {}
155
156 int operator()( const std::string & in )
157 {
158 int slen = in.length();
159 int sum = 0;
160 for( int i = 0; i < slen; ++i )
161 sum += static_cast<int>( in[i] );
162
163 return static_cast<int>( fmod( static_cast<float>( sum ), size_ ) );
164 }
165};
166
168
170template < typename T, typename U >
171void SortContainer2( T & firstContainer, U & secondContainer )
172{
173 typedef typename std::multimap< typename T::value_type, typename U::value_type> UTMultiMap;
174
175 UTMultiMap SortMap;
176
177 typename T::iterator iterT = firstContainer.begin();
178 typename T::iterator endT = firstContainer.end();
179 typename U::iterator iterU = secondContainer.begin();
180 typename U::iterator endU = secondContainer.end();
181
182 for( ; (iterT!=endT)||(iterU!=endU) ; ++iterT, ++iterU )
183 SortMap.insert( typename UTMultiMap::value_type( *iterT, *iterU ) );
184
185 firstContainer.clear();
186 secondContainer.clear();
187
188 typename UTMultiMap::iterator iterUTM = SortMap.begin();
189 typename UTMultiMap::iterator endUTM = SortMap.end();
190
191 for( ; iterUTM != endUTM; ++iterUTM )
192 {
193 firstContainer.push_back( iterUTM->first );
194 secondContainer.push_back( iterUTM->second );
195 }
196}
197
199
201template < typename T >
202bool IsSorted( T & container )
203{
204 if( container.size() < 2 ) return true;
205
206 typename T::iterator iterT = container.begin();
207 typename T::iterator endT = container.end();
208 typename T::iterator iterTPlus = iterT;
209 iterTPlus++;
210
211 for( ; iterTPlus != endT; ++iterT, ++iterTPlus )
212 if( !(*iterT<*iterTPlus) ) return false;
213
214 return true;
215}
216
217template <typename KT, typename DT, class DH, class AC, class MG>
218void
220addEntries( DataMap const & entries )
221{
222#ifdef EPETRA_MPI
223
224 DataRecvMap newEntries;
225 ProcList procs;
226 pushData_( entries, newEntries, procs );
227
228 DataRecvMapCIter citDM = newEntries.begin();
229 DataRecvMapCIter cendDM = newEntries.end();
230
231#else
232
233 DataMapCIter citDM = entries.begin();
234 DataMapCIter cendDM = entries.end();
235
236#endif
237
238 for( ; citDM != cendDM; ++citDM )
239 container_.insert( *citDM );
240}
241
242template <typename KT, typename DT, class DH, class AC, class MG>
243void
245deleteEntries( KeyList & keys )
246{
247#ifdef EPETRA_MPI
248
249 KeyList newKeys;
250 ProcList procs;
251 pushKeys_( keys, newKeys, procs );
252
253 KeyListCIter citKL = newKeys.begin();
254 KeyListCIter cendKL = newKeys.end();
255
256#else
257
258 KeyListCIter citKL = keys.begin();
259 KeyListCIter cendKL = keys.end();
260
261#endif
262
263 for( ; citKL != cendKL; ++citKL )
264 container_.erase( *citKL );
265}
266
267template <typename KT, typename DT, class DH, class AC, class MG>
268void
270getEntries( KeyList & keys,
271 DataMap & entries )
272{
273#ifdef EPETRA_MPI
274
275 //Push Keys to owning processors
276 KeyList newKeys;
277 ProcList procs;
278 pushKeys_( keys, newKeys, procs );
279
280 KeyListCIter citKL = newKeys.begin();
281 KeyListCIter cendKL = newKeys.end();
282
283 //Rvs migrate to move data from directory back to requesting procs
284 DataMap newEntries;
285 for( ; citKL != cendKL; ++citKL )
286 {
287 if( !container_.count( *citKL ) )
288 throw "Data not in directory: " + *citKL + "\n";
289
290 newEntries[*citKL] = (container_.lower_bound( *citKL ))->second;
291 }
292
293 migrate_.rvs( procs, newKeys, newEntries, entries );
294
295#else
296
297 KeyListCIter citKL = keys.begin();
298 KeyListCIter cendKL = keys.end();
299 for( ; citKL != cendKL; ++citKL )
300 {
301 if( !container_.count( *citKL ) )
302 throw "Data not in directory: " + *citKL + "\n";
303
304 entries[*citKL] = (container_.lower_bound( *citKL ))->second;
305 }
306
307#endif
308}
309
310#ifdef EPETRA_MPI
311
312template <typename KT, typename DT, class DH, class AC, class MG>
313void
315pushKeys_( KeyList & sKeys,
316 KeyList & rKeys,
317 ProcList & procs )
318{
319 KeyListCIter itKL = sKeys.begin();
320 KeyListCIter endKL = sKeys.end();
321
322 procs.clear();
323 for( ; itKL != endKL; ++itKL )
324 procs.push_back( distHash_(*itKL) );
325
326 if( !IsSorted( procs ) ) SortContainer2( procs, sKeys );
327
328 migrate_( procs, sKeys, rKeys );
329}
330
331template <typename KT, typename DT, class DH, class AC, class MG>
332void
334pushData_( DataMap const & sData,
335 DataRecvMap & rData,
336 ProcList & procs )
337{
338 DataMapCIter itDM = sData.begin();
339 DataMapCIter endDM = sData.end();
340
341 procs.clear();
342 for( ; itDM != endDM; ++itDM )
343 procs.push_back( distHash_(itDM->first) );
344
345 migrate_( procs, sData, rData );
346}
347
348#endif
349
350} //namespace EpetraExt
351
352#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
Directory & operator=(const Directory &)
ProcList::iterator ProcListIter
std::vector< KT > KeyList
bool operator==(const Directory &) const
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
bool operator!=(const Directory &) const
Directory(const Directory &)
int operator()(const std::string &in)
int operator()(const T &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.