1 /*
2    Copyright (c) 2009-2014, Jack Poulson
3    All rights reserved.
4 
5    This file is part of Elemental and is under the BSD 2-Clause License,
6    which can be found in the LICENSE file in the root directory, or at
7    http://opensource.org/licenses/BSD-2-Clause
8 */
9 #pragma once
10 #ifndef ELEM_ENVIRONMENT_IMPL_HPP
11 #define ELEM_ENVIRONMENT_IMPL_HPP
12 
13 namespace elem {
14 
HandleVersion(std::ostream & os) const15 inline void Args::HandleVersion( std::ostream& os ) const
16 {
17     std::string version = "--version";
18     char** arg = std::find( argv_, argv_+argc_, version );
19     const bool foundVersion = ( arg != argv_+argc_ );
20     if( foundVersion )
21     {
22         if( mpi::WorldRank() == 0 )
23             PrintVersion();
24         throw ArgException();
25     }
26 }
27 
HandleBuild(std::ostream & os) const28 inline void Args::HandleBuild( std::ostream& os ) const
29 {
30     std::string build = "--build";
31     char** arg = std::find( argv_, argv_+argc_, build );
32     const bool foundBuild = ( arg != argv_+argc_ );
33     if( foundBuild )
34     {
35         if( mpi::WorldRank() == 0 )
36         {
37             PrintVersion();
38             PrintConfig();
39             PrintCCompilerInfo();
40             PrintCxxCompilerInfo();
41         }
42         throw ArgException();
43     }
44 }
45 
46 template<typename T>
47 inline T
Input(std::string name,std::string desc)48 Input( std::string name, std::string desc )
49 { return GetArgs().Input<T>( name, desc ); }
50 
51 template<typename T>
52 inline T
Input(std::string name,std::string desc,T defaultVal)53 Input( std::string name, std::string desc, T defaultVal )
54 { return GetArgs().Input( name, desc, defaultVal ); }
55 
56 inline void
ProcessInput()57 ProcessInput()
58 { GetArgs().Process(); }
59 
60 inline void
PrintInputReport()61 PrintInputReport()
62 { GetArgs().PrintReport(); }
63 
ReportException(const std::exception & e,std::ostream & os)64 inline void ReportException( const std::exception& e, std::ostream& os )
65 {
66     if( std::string(e.what()) != "" )
67     {
68         os << "Process " << mpi::WorldRank() << " caught error message:\n"
69            << e.what() << std::endl;
70     }
71     DEBUG_ONLY(DumpCallStack(os))
72 }
73 
ComplainIfDebug()74 inline void ComplainIfDebug()
75 {
76     DEBUG_ONLY(
77         if( mpi::WorldRank() == 0 )
78         {
79             std::cout << "==========================================\n"
80                       << " In debug mode! Performance will be poor! \n"
81                       << "=========================================="
82                       << std::endl;
83         }
84     )
85 }
86 
87 template<typename T>
88 inline void
MemCopy(T * dest,const T * source,std::size_t numEntries)89 MemCopy( T* dest, const T* source, std::size_t numEntries )
90 {
91     // This can be optimized/generalized later
92     std::memcpy( dest, source, numEntries*sizeof(T) );
93 }
94 
95 template<typename T>
96 inline void
MemSwap(T * a,T * b,T * temp,std::size_t numEntries)97 MemSwap( T* a, T* b, T* temp, std::size_t numEntries )
98 {
99     // temp := a
100     std::memcpy( temp, a, numEntries*sizeof(T) );
101     // a := b
102     std::memcpy( a, b, numEntries*sizeof(T) );
103     // b := temp
104     std::memcpy( b, temp, numEntries*sizeof(T) );
105 }
106 
107 template<typename T>
108 inline void
StridedMemCopy(T * dest,std::size_t destStride,const T * source,std::size_t sourceStride,std::size_t numEntries)109 StridedMemCopy
110 (       T* dest,   std::size_t destStride,
111   const T* source, std::size_t sourceStride, std::size_t numEntries )
112 {
113     // For now, use the BLAS wrappers/generalization
114     blas::Copy( numEntries, source, sourceStride, dest, destStride );
115 }
116 
117 template<typename T>
118 inline void
MemZero(T * buffer,std::size_t numEntries)119 MemZero( T* buffer, std::size_t numEntries )
120 {
121     // This can be optimized/generalized later
122     std::memset( buffer, 0, numEntries*sizeof(T) );
123 }
124 
125 template<typename T>
126 inline void
SwapClear(T & x)127 SwapClear( T& x )
128 { T().swap( x ); }
129 
130 template<typename T>
131 inline void
EnsureConsistent(T alpha,mpi::Comm comm,std::string name)132 EnsureConsistent( T alpha, mpi::Comm comm, std::string name )
133 {
134     std::string tag = ( name=="" ? "" : name+" " );
135     const Int commSize = mpi::Size( comm );
136     const Int commRank = mpi::Rank( comm );
137     std::vector<T> a(commSize);
138     mpi::Gather( &alpha, 1, a.data(), 1, 0, comm );
139     if( commRank == 0 )
140     {
141         for( Int j=0; j<commSize; ++j )
142             if( a[j] != alpha )
143                 std::cout << "Process " << j << "'s " << tag << "value, "
144                           << a[j] << ", mismatched the root's, " << alpha
145                           << std::endl;
146     }
147 }
148 
149 } // namespace elem
150 
151 #endif // ifndef ELEM_ENVIRONMENT_IMPL_HPP
152