Line data Source code
1 :
2 : /* Copyright (c) 2014, Carlos Duelo <cduelo@cesvima.upm.es>
3 : * Stefan.Eilemann@epfl.ch
4 : *
5 : * This library is free software; you can redistribute it and/or modify it under
6 : * the terms of the GNU Lesser General Public License version 2.1 as published
7 : * by the Free Software Foundation.
8 : *
9 : * This library is distributed in the hope that it will be useful, but WITHOUT
10 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 : * details.
13 : *
14 : * You should have received a copy of the GNU Lesser General Public License
15 : * along with this library; if not, write to the Free Software Foundation, Inc.,
16 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 : */
18 :
19 : #include "mpi.h"
20 :
21 : #include <lunchbox/log.h>
22 : #include <lunchbox/debug.h>
23 :
24 : #ifdef LUNCHBOX_USE_MPI
25 : # include <mpi.h>
26 : #endif
27 :
28 : namespace lunchbox
29 : {
30 : namespace
31 : {
32 : bool _supportsThreads = false;
33 : }
34 :
35 : namespace detail
36 : {
37 : class MPI
38 : {
39 : public:
40 2 : MPI( int* argc LB_UNUSED, char*** argv LB_UNUSED )
41 : : rank( -1 )
42 : , size( -1 )
43 2 : , initCalled( false )
44 : {
45 : #ifdef LUNCHBOX_USE_MPI
46 2 : int initialized = false;
47 2 : MPI_Initialized( &initialized );
48 2 : if( !initialized )
49 : {
50 1 : int threadLevel = -1;
51 1 : if( MPI_SUCCESS != MPI_Init_thread( argc, argv,
52 : MPI_THREAD_MULTIPLE,
53 1 : &threadLevel ))
54 : {
55 0 : LBERROR << "MPI_Init_thread failed" << std::endl;
56 2 : return;
57 : }
58 :
59 1 : initCalled = true;
60 :
61 1 : switch( threadLevel )
62 : {
63 : case MPI_THREAD_SINGLE:
64 0 : LBVERB << "MPI_THREAD_SINGLE thread support" << std::endl;
65 0 : break;
66 : case MPI_THREAD_FUNNELED:
67 0 : LBVERB << "MPI_THREAD_FUNNELED thread support" << std::endl;
68 0 : break;
69 : case MPI_THREAD_SERIALIZED:
70 1 : LBVERB << "MPI_THREAD_SERIALIZED thread support" << std::endl;
71 1 : _supportsThreads = true;
72 1 : break;
73 : case MPI_THREAD_MULTIPLE:
74 0 : LBVERB << "MPI_THREAD_MULTIPLE thread support" << std::endl;
75 0 : _supportsThreads = true;
76 0 : break;
77 : default:
78 0 : LBERROR << "Unknown MPI thread support" << std::endl;
79 : }
80 : }
81 :
82 2 : if( MPI_SUCCESS != MPI_Comm_rank( MPI_COMM_WORLD, &rank ) )
83 0 : LBERROR << "MPI_Comm_rank failed" << std::endl;
84 :
85 2 : if( MPI_SUCCESS != MPI_Comm_size( MPI_COMM_WORLD, &size ) )
86 0 : LBERROR << "MPI_Comm_size failed" << std::endl;
87 : #endif
88 : }
89 :
90 2 : ~MPI()
91 : {
92 : #ifdef LUNCHBOX_USE_MPI
93 2 : if( !initCalled )
94 1 : return;
95 :
96 1 : if( MPI_SUCCESS != MPI_Finalize() )
97 0 : LBERROR << "MPI_Finalize failed" << std::endl;
98 1 : _supportsThreads = false;
99 : #endif
100 2 : }
101 :
102 : int rank;
103 : int size;
104 : bool initCalled;
105 :
106 : };
107 : }
108 :
109 1 : MPI::MPI()
110 1 : : _impl( new detail::MPI( 0, 0 ))
111 1 : {}
112 :
113 1 : MPI::MPI( int& argc, char**& argv )
114 1 : : _impl( new detail::MPI( &argc, &argv ))
115 1 : {}
116 :
117 3 : MPI::~MPI()
118 : {
119 3 : }
120 :
121 :
122 2 : bool MPI::supportsThreads() const
123 : {
124 2 : return _supportsThreads;
125 : }
126 :
127 5 : int MPI::getRank() const
128 : {
129 5 : return _impl->rank;
130 : }
131 :
132 4 : int MPI::getSize() const
133 : {
134 4 : return _impl->size;
135 : }
136 :
137 90 : }
|