Skip to content

Commit e5ef7fd

Browse files
authored
Merge pull request #620 from jgphpc/mpi_init_thread
[test] Add new `MPI_Init_thread()` check
2 parents 0d8b785 + d5e7916 commit e5ef7fd

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed

cscs-checks/prgenv/mpi.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import reframe as rfm
2+
import reframe.utility.sanity as sn
3+
4+
5+
@rfm.required_version('>=2.14')
6+
@rfm.parameterized_test(['single'], ['funneled'], ['serialized'], ['multiple'])
7+
class MpiInitTest(rfm.RegressionTest):
8+
"""This test checks the value returned by calling MPI_Init_thread.
9+
10+
Output should look the same for every prgenv (cray, gnu, intel, pgi)
11+
(mpi_thread_multiple seems to be not supported):
12+
13+
# 'single':
14+
['mpi_thread_supported=MPI_THREAD_SINGLE
15+
mpi_thread_queried=MPI_THREAD_SINGLE 0'],
16+
17+
# 'funneled':
18+
['mpi_thread_supported=MPI_THREAD_FUNNELED
19+
mpi_thread_queried=MPI_THREAD_FUNNELED 1'],
20+
21+
# 'serialized':
22+
['mpi_thread_supported=MPI_THREAD_SERIALIZED
23+
mpi_thread_queried=MPI_THREAD_SERIALIZED 2'],
24+
25+
# 'multiple':
26+
['mpi_thread_supported=MPI_THREAD_SERIALIZED
27+
mpi_thread_queried=MPI_THREAD_SERIALIZED 2']
28+
29+
"""
30+
31+
def __init__(self, required_thread):
32+
super().__init__()
33+
self.valid_systems = ['daint:gpu', 'daint:mc', 'dom:gpu', 'dom:mc']
34+
self.valid_prog_environs = ['PrgEnv-cray', 'PrgEnv-gnu',
35+
'PrgEnv-intel', 'PrgEnv-pgi']
36+
self.build_system = 'SingleSource'
37+
self.sourcepath = 'mpi_init_thread.cpp'
38+
self.cppflags = {
39+
'single': ['-D_MPI_THREAD_SINGLE'],
40+
'funneled': ['-D_MPI_THREAD_FUNNELED'],
41+
'serialized': ['-D_MPI_THREAD_SERIALIZED'],
42+
'multiple': ['-D_MPI_THREAD_MULTIPLE']
43+
}
44+
self.build_system.cppflags = self.cppflags[required_thread]
45+
self.build_system.cppflags += ['-static']
46+
self.time_limit = (0, 1, 0)
47+
found_mpithread = sn.extractsingle(
48+
r'^mpi_thread_required=\w+\s+mpi_thread_supported=\w+'
49+
r'\s+mpi_thread_queried=\w+\s+(?P<result>\d)$',
50+
self.stdout, 1, int)
51+
self.mpithread_version = {
52+
'single': 0,
53+
'funneled': 1,
54+
'serialized': 2,
55+
'multiple': 2
56+
}
57+
self.sanity_patterns = sn.all([
58+
sn.assert_found(r'tid=0 out of 1 from rank 0 out of 1',
59+
self.stdout),
60+
sn.assert_eq(found_mpithread,
61+
self.mpithread_version[required_thread])
62+
])
63+
self.maintainers = ['JG']
64+
self.tags = {'production'}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// testing MPI_Init_thread
2+
#include <iostream>
3+
#include <stdio.h>
4+
#include <mpi.h>
5+
using namespace std;
6+
7+
int main(int argc, char **argv) {
8+
int rank, size, mpiversion, mpisubversion;
9+
int resultlen = -1, mpi_thread_supported=-1;
10+
char mpilibversion[MPI_MAX_LIBRARY_VERSION_STRING];
11+
12+
// --------------------------------------------------------------------------
13+
// int MPI_Init_thread( int *argc, char ***argv, int required, int *provided )
14+
//
15+
// { MPI_THREAD_SINGLE}
16+
// Only one thread will execute.
17+
//
18+
// { MPI_THREAD_FUNNELED}
19+
// The process may be multi-threaded, but only the main thread will make MPI calls
20+
// (all MPI calls are funneled to the main thread).
21+
//
22+
// { MPI_THREAD_SERIALIZED}
23+
// The process may be multi-threaded, and multiple threads may make MPI calls, but
24+
// only one at a time: MPI calls are not made concurrently from two distinct
25+
// threads (all MPI calls are serialized).
26+
//
27+
// { MPI_THREAD_MULTIPLE}
28+
// Multiple threads may call MPI, with no restrictions.
29+
// --------------------------------------------------------------------------
30+
31+
#if defined(_MPI_THREAD_SINGLE)
32+
cout << "mpi_thread_required=MPI_THREAD_SINGLE ";
33+
int ev = MPI_Init_thread( 0,0, MPI_THREAD_SINGLE, &mpi_thread_supported );
34+
#elif defined(_MPI_THREAD_FUNNELED)
35+
cout << "mpi_thread_required=MPI_THREAD_FUNNELED ";
36+
int ev = MPI_Init_thread( 0,0, MPI_THREAD_FUNNELED, &mpi_thread_supported );
37+
#elif defined(_MPI_THREAD_SERIALIZED)
38+
cout << "mpi_thread_required=MPI_THREAD_SERIALIZED ";
39+
int ev = MPI_Init_thread( 0,0, MPI_THREAD_SERIALIZED, &mpi_thread_supported );
40+
#elif defined(_MPI_THREAD_MULTIPLE)
41+
cout << "mpi_thread_required=MPI_THREAD_MULTIPLE ";
42+
int ev = MPI_Init_thread( 0,0, MPI_THREAD_MULTIPLE, &mpi_thread_supported );
43+
#else
44+
cout << "mpi_thread_required=none ";
45+
int ev = MPI_Init(0,0);
46+
#endif
47+
48+
switch ( mpi_thread_supported )
49+
{
50+
case MPI_THREAD_SINGLE: cout << "mpi_thread_supported=MPI_THREAD_SINGLE" ; break;
51+
case MPI_THREAD_FUNNELED: cout << "mpi_thread_supported=MPI_THREAD_FUNNELED" ; break;
52+
case MPI_THREAD_SERIALIZED: cout << "mpi_thread_supported=MPI_THREAD_SERIALIZED" ;break;
53+
case MPI_THREAD_MULTIPLE: cout << "mpi_thread_supported=MPI_THREAD_MULTIPLE" ; break;
54+
default: cout << "mpi_thread_supported=UNKNOWN" ;
55+
}
56+
57+
// Return the level of thread support provided by the MPI library:
58+
int mpi_thread_required=-1;
59+
MPI_Query_thread( &mpi_thread_required );
60+
switch ( mpi_thread_supported )
61+
{
62+
case MPI_THREAD_SINGLE: cout << " mpi_thread_queried=MPI_THREAD_SINGLE " << mpi_thread_required << std::endl; break;
63+
case MPI_THREAD_FUNNELED: cout << " mpi_thread_queried=MPI_THREAD_FUNNELED " << mpi_thread_required << std::endl; break;
64+
case MPI_THREAD_SERIALIZED: cout << " mpi_thread_queried=MPI_THREAD_SERIALIZED "<< mpi_thread_required << std::endl; break;
65+
case MPI_THREAD_MULTIPLE: cout << " mpi_thread_queried=MPI_THREAD_MULTIPLE " << mpi_thread_required << std::endl; break;
66+
default: cout << " mpi_thread_queried=UNKNOWN " << mpi_thread_required << std::endl;
67+
}
68+
69+
MPI_Get_version( &mpiversion, &mpisubversion );
70+
MPI_Get_library_version(mpilibversion, &resultlen);
71+
printf( "# MPI-%d.%d = %s", mpiversion, mpisubversion, mpilibversion);
72+
73+
rank = MPI::COMM_WORLD.Get_rank();
74+
size = MPI::COMM_WORLD.Get_size();
75+
cout << "tid=0 out of 1 from rank " << rank << " out of " << size << "\n";
76+
77+
//std::cout << " mpi_thread_queried=" << mpi_thread_required << std::endl;
78+
79+
MPI::Finalize();
80+
81+
return 0;
82+
} /* end func main */

0 commit comments

Comments
 (0)