Skip to content

Commit 1d09697

Browse files
committed
Test the MPI C and Fortran Compilers
- Emit helpful error messages if the C MPI compiler is missing - Try to fall back on a custom mpi module via `include 'mpif.h'` if `use mpi` causes problems. - If `include 'mpif.h'` doesn't work, then skip compiling the `opencoarrays.F90` module, since it's only needed when the compiler is not OCA. - Fixes #246. Kinda? (See discussion there)
1 parent 0298b49 commit 1d09697

File tree

2 files changed

+143
-1
lines changed

2 files changed

+143
-1
lines changed

CMakeLists.txt

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,128 @@ if ( (NOT MPI_C_FOUND) OR (NOT MPI_Fortran_FOUND) )
137137
find_package( MPI REQUIRED )
138138
endif()
139139

140+
#--------------------------------------------------------
141+
# Make sure a simple "hello world" C mpi program compiles
142+
#--------------------------------------------------------
143+
set(OLD_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
144+
set(CMAKE_REQUIRED_FLAGS ${MPI_C_COMPILE_FLAGS} ${MPI_C_LINK_FLAGS})
145+
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
146+
set(CMAKE_REQUIRED_INCLUDES ${MPI_C_INCLUDE_PATH})
147+
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
148+
set(CMAKE_REQUIRED_LIBRARIES ${MPI_C_LIBRARIES})
149+
include (CheckCSourceCompiles)
150+
CHECK_C_SOURCE_COMPILES("
151+
#include <mpi.h>
152+
#include <stdio.h>
153+
int main(int argc, char** argv) {
154+
MPI_Init(NULL, NULL);
155+
int world_size;
156+
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
157+
int world_rank;
158+
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
159+
char processor_name[MPI_MAX_PROCESSOR_NAME];
160+
int name_len;
161+
MPI_Get_processor_name(processor_name, &name_len);
162+
printf('Hello world from processor %s, rank %d out of %d processors',
163+
processor_name, world_rank, world_size);
164+
MPI_Finalize();
165+
}"
166+
MPI_C_COMPILES)
167+
set(CMAKE_REQUIRED_FLAGS ${OLD_REQUIRED_FLAGS})
168+
set(CMAKE_REQUIRED_INCLUDES ${OLD_INCLUDES})
169+
set(CMAKE_REQUIRED_LIBRARIES ${OLD_LIBRARIES})
170+
unset(OLD_REQUIRED_FLAGS)
171+
unset(OLD_INCLUDES)
172+
unset(OLD_LIBRARIES)
173+
174+
if (NOT MPI_C_COMPILES)
175+
message(FATAL_ERROR "MPI_C is missing!"
176+
"Try setting MPI_C_COMPILER to the appropriate C compiler wrapper script and reconfigure."
177+
"i.e., `cmake -DMPI_C_COMPILER=/path/to/mpicc ..` or set it by editing the cache using"
178+
"cmake-gui or ccmake."
179+
)
180+
endif()
181+
182+
#--------------------------------------------------------------
183+
# Make sure a simple "hello world" Fortran mpi program compiles
184+
# Try using mpi.mod first then fall back on includ 'mpif.h'
185+
#--------------------------------------------------------------
186+
set(OLD_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
187+
set(CMAKE_REQUIRED_FLAGS "-ffree-form" ${MPI_Fortran_COMPILE_FLAGS} ${MPI_Fortran_LINK_FLAGS})
188+
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
189+
set(CMAKE_REQUIRED_INCLUDES ${MPI_Fortran_INCLUDE_PATH})
190+
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
191+
set(CMAKE_REQUIRED_LIBRARIES ${MPI_Fortran_LIBRARIES})
192+
include (CheckCSourceCompiles)
193+
CHECK_Fortran_SOURCE_COMPILES("
194+
program mpi_hello
195+
use mpi
196+
implicit none
197+
integer :: ierr, mpi_world_size, mpi_world_rank, res_len
198+
character*(MPI_MAX_PROCESSOR_NAME) :: proc
199+
call mpi_init(ierr)
200+
call mpi_comm_size(MPI_COMM_WORLD,mpi_world_size,ierr)
201+
call mpi_comm_rank(MPI_COMM_WORLD,mpi_world_rank,ierr)
202+
call mpi_get_processor_name(proc,res_len,ierr)
203+
write(*,*) 'Hello from processor ', trim(proc), ' rank ', mpi_world_rank, ' out of ', mpi_world_size, '.'
204+
call mpi_finalize(ierr)
205+
end program
206+
"
207+
MPI_Fortran_MODULE_COMPILES)
208+
set(CMAKE_REQUIRED_FLAGS ${OLD_REQUIRED_FLAGS})
209+
set(CMAKE_REQUIRED_INCLUDES ${OLD_INCLUDES})
210+
set(CMAKE_REQUIRED_LIBRARIES ${OLD_LIBRARIES})
211+
unset(OLD_REQUIRED_FLAGS)
212+
unset(OLD_INCLUDES)
213+
unset(OLD_LIBRARIES)
214+
215+
#--------------------------------
216+
# If that failed try using mpif.h
217+
#--------------------------------
218+
set(OLD_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
219+
set(CMAKE_REQUIRED_FLAGS "-ffree-form" ${MPI_Fortran_COMPILE_FLAGS} ${MPI_Fortran_LINK_FLAGS})
220+
set(OLD_INCLUDES ${CMAKE_REQUIRED_INCLUDES})
221+
set(CMAKE_REQUIRED_INCLUDES ${MPI_Fortran_INCLUDE_PATH})
222+
set(OLD_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
223+
set(CMAKE_REQUIRED_LIBRARIES ${MPI_Fortran_LIBRARIES})
224+
include (CheckCSourceCompiles)
225+
CHECK_Fortran_SOURCE_COMPILES("
226+
program mpi_hello
227+
implicit none
228+
include 'mpif.h'
229+
integer :: ierr, mpi_world_size, mpi_world_rank, res_len
230+
character*(MPI_MAX_PROCESSOR_NAME) :: proc
231+
call mpi_init(ierr)
232+
call mpi_comm_size(MPI_COMM_WORLD,mpi_world_size,ierr)
233+
call mpi_comm_rank(MPI_COMM_WORLD,mpi_world_rank,ierr)
234+
call mpi_get_processor_name(proc,res_len,ierr)
235+
write(*,*) 'Hello from processor ', trim(proc), ' rank ', mpi_world_rank, ' out of ', mpi_world_size, '.'
236+
call mpi_finalize(ierr)
237+
end program
238+
"
239+
MPI_Fortran_INCLUDE_COMPILES)
240+
set(CMAKE_REQUIRED_FLAGS ${OLD_REQUIRED_FLAGS})
241+
set(CMAKE_REQUIRED_INCLUDES ${OLD_INCLUDES})
242+
set(CMAKE_REQUIRED_LIBRARIES ${OLD_LIBRARIES})
243+
unset(OLD_REQUIRED_FLAGS)
244+
unset(OLD_INCLUDES)
245+
unset(OLD_LIBRARIES)
246+
247+
if ( (NOT MPI_Fortran_MODULE_COMPILES) AND (NOT MPI_Fortran_INCLUDE_COMPILES) )
248+
message ( WARNING "It appears that the Fortran MPI compiler is not working."
249+
"For OpenCoarrays Aware compilers, this may be irrelavent:"
250+
" The src/extensions/opencoarrays.F90 module will be disabled, but it is"
251+
" possible that the build will succeed, despite this fishy circumstance."
252+
)
253+
endif()
254+
255+
if ( NOT MPI_Fortran_MODULE_COMPILES )
256+
message ( WARNING "It appears that MPI was built with a different Fortran compiler."
257+
"It is possible that this may cause unpredictable behavior. The build will continue"
258+
"using `mpif.h` BUT please report any suspicious behavior to the OpenCoarrays"
259+
"developers."
260+
)
261+
endif()
140262

141263
#----------------
142264
# Setup MPI flags

src/mpi/CMakeLists.txt

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,27 @@ if(CAF_EXPOSE_INIT_FINALIZE)
2828
add_definitions(-DEXPOSE_INIT_FINALIZE)
2929
endif()
3030

31-
add_library(caf_mpi mpi_caf.c ../common/caf_auxiliary.c ../extensions/opencoarrays.F90)
31+
# Determine whether and how to include OpenCoarrays module based on if the Fortran MPI compiler:
32+
# - workds
33+
# - is compatible with the fortran compiler used to build the MPI implementation
34+
if (MPI_Fortran_MODULE_COMPILES)
35+
# likely the same compiler compiled MPI
36+
set(MPI_CAF_FORTRAN_FILES ../extensions/opencoarrays.F90)
37+
elseif(MPI_Fortran_INCLUDE_COMPILES)
38+
# Likely a different version or completely different Fortran compiler built MPI
39+
# Since the .mod file is incompatible hack together a replacement
40+
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/my_mpi_mod.f90"
41+
"
42+
module mpi
43+
implicit none
44+
public
45+
include 'mpif.h'
46+
end module"
47+
)
48+
set(MPI_CAF_FORTRAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/my_mpi_mod.f90" ../extensions/opencoarrays.F90 )
49+
endif()
50+
51+
add_library(caf_mpi mpi_caf.c ../common/caf_auxiliary.c ${MPI_CAF_FORTRAN_FILES})
3252
target_link_libraries(caf_mpi PRIVATE ${MPI_C_LIBRARIES} ${MPI_Fortran_LIBRARIES})
3353

3454
set_target_properties ( caf_mpi

0 commit comments

Comments
 (0)