FindMPI.cmake 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660
  1. #.rst:
  2. # FindMPI
  3. # -------
  4. #
  5. # Find a Message Passing Interface (MPI) implementation
  6. #
  7. # The Message Passing Interface (MPI) is a library used to write
  8. # high-performance distributed-memory parallel applications, and is
  9. # typically deployed on a cluster. MPI is a standard interface (defined
  10. # by the MPI forum) for which many implementations are available. All
  11. # of them have somewhat different include paths, libraries to link
  12. # against, etc., and this module tries to smooth out those differences.
  13. #
  14. # === Variables ===
  15. #
  16. # This module will set the following variables per language in your
  17. # project, where <lang> is one of C, CXX, or Fortran:
  18. #
  19. # ::
  20. #
  21. # MPI_<lang>_FOUND TRUE if FindMPI found MPI flags for <lang>
  22. # MPI_<lang>_COMPILER MPI Compiler wrapper for <lang>
  23. # MPI_<lang>_COMPILE_FLAGS Compilation flags for MPI programs
  24. # MPI_<lang>_INCLUDE_PATH Include path(s) for MPI header
  25. # MPI_<lang>_LINK_FLAGS Linking flags for MPI programs
  26. # MPI_<lang>_LIBRARIES All libraries to link MPI programs against
  27. #
  28. # Additionally, FindMPI sets the following variables for running MPI
  29. # programs from the command line:
  30. #
  31. # ::
  32. #
  33. # MPIEXEC Executable for running MPI programs
  34. # MPIEXEC_NUMPROC_FLAG Flag to pass to MPIEXEC before giving
  35. # it the number of processors to run on
  36. # MPIEXEC_PREFLAGS Flags to pass to MPIEXEC directly
  37. # before the executable to run.
  38. # MPIEXEC_POSTFLAGS Flags to pass to MPIEXEC after other flags
  39. #
  40. # === Usage ===
  41. #
  42. # To use this module, simply call FindMPI from a CMakeLists.txt file, or
  43. # run find_package(MPI), then run CMake. If you are happy with the
  44. # auto- detected configuration for your language, then you're done. If
  45. # not, you have two options:
  46. #
  47. # ::
  48. #
  49. # 1. Set MPI_<lang>_COMPILER to the MPI wrapper (mpicc, etc.) of your
  50. # choice and reconfigure. FindMPI will attempt to determine all the
  51. # necessary variables using THAT compiler's compile and link flags.
  52. # 2. If this fails, or if your MPI implementation does not come with
  53. # a compiler wrapper, then set both MPI_<lang>_LIBRARIES and
  54. # MPI_<lang>_INCLUDE_PATH. You may also set any other variables
  55. # listed above, but these two are required. This will circumvent
  56. # autodetection entirely.
  57. #
  58. # When configuration is successful, MPI_<lang>_COMPILER will be set to
  59. # the compiler wrapper for <lang>, if it was found. MPI_<lang>_FOUND
  60. # and other variables above will be set if any MPI implementation was
  61. # found for <lang>, regardless of whether a compiler was found.
  62. #
  63. # When using MPIEXEC to execute MPI applications, you should typically
  64. # use all of the MPIEXEC flags as follows:
  65. #
  66. # ::
  67. #
  68. # ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} PROCS
  69. # ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS
  70. #
  71. # where PROCS is the number of processors on which to execute the
  72. # program, EXECUTABLE is the MPI program, and ARGS are the arguments to
  73. # pass to the MPI program.
  74. #
  75. # === Backward Compatibility ===
  76. #
  77. # For backward compatibility with older versions of FindMPI, these
  78. # variables are set, but deprecated:
  79. #
  80. # ::
  81. #
  82. # MPI_FOUND MPI_COMPILER MPI_LIBRARY
  83. # MPI_COMPILE_FLAGS MPI_INCLUDE_PATH MPI_EXTRA_LIBRARY
  84. # MPI_LINK_FLAGS MPI_LIBRARIES
  85. #
  86. # In new projects, please use the MPI_<lang>_XXX equivalents.
  87. #=============================================================================
  88. # Copyright 2001-2011 Kitware, Inc.
  89. # Copyright 2010-2011 Todd Gamblin [email protected]
  90. # Copyright 2001-2009 Dave Partyka
  91. #
  92. # Distributed under the OSI-approved BSD License (the "License");
  93. # see accompanying file Copyright.txt for details.
  94. #
  95. # This software is distributed WITHOUT ANY WARRANTY; without even the
  96. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  97. # See the License for more information.
  98. #=============================================================================
  99. # (To distribute this file outside of CMake, substitute the full
  100. # License text for the above reference.)
  101. # include this to handle the QUIETLY and REQUIRED arguments
  102. include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
  103. include(${CMAKE_CURRENT_LIST_DIR}/GetPrerequisites.cmake)
  104. #
  105. # This part detects MPI compilers, attempting to wade through the mess of compiler names in
  106. # a sensible way.
  107. #
  108. # The compilers are detected in this order:
  109. #
  110. # 1. Try to find the most generic available MPI compiler, as this is usually set up by
  111. # cluster admins. e.g., if plain old mpicc is available, we'll use it and assume it's
  112. # the right compiler.
  113. #
  114. # 2. If a generic mpicc is NOT found, then we attempt to find one that matches
  115. # CMAKE_<lang>_COMPILER_ID. e.g. if you are using XL compilers, we'll try to find mpixlc
  116. # and company, but not mpiicc. This hopefully prevents toolchain mismatches.
  117. #
  118. # If you want to force a particular MPI compiler other than what we autodetect (e.g. if you
  119. # want to compile regular stuff with GNU and parallel stuff with Intel), you can always set
  120. # your favorite MPI_<lang>_COMPILER explicitly and this stuff will be ignored.
  121. #
  122. # Start out with the generic MPI compiler names, as these are most commonly used.
  123. set(_MPI_C_COMPILER_NAMES mpicc mpcc mpicc_r mpcc_r)
  124. set(_MPI_CXX_COMPILER_NAMES mpicxx mpiCC mpcxx mpCC mpic++ mpc++
  125. mpicxx_r mpiCC_r mpcxx_r mpCC_r mpic++_r mpc++_r)
  126. set(_MPI_Fortran_COMPILER_NAMES mpif95 mpif95_r mpf95 mpf95_r
  127. mpif90 mpif90_r mpf90 mpf90_r
  128. mpif77 mpif77_r mpf77 mpf77_r)
  129. # GNU compiler names
  130. set(_MPI_GNU_C_COMPILER_NAMES mpigcc mpgcc mpigcc_r mpgcc_r)
  131. set(_MPI_GNU_CXX_COMPILER_NAMES mpig++ mpg++ mpig++_r mpg++_r)
  132. set(_MPI_GNU_Fortran_COMPILER_NAMES mpigfortran mpgfortran mpigfortran_r mpgfortran_r
  133. mpig77 mpig77_r mpg77 mpg77_r)
  134. # Intel MPI compiler names
  135. set(_MPI_Intel_C_COMPILER_NAMES mpiicc)
  136. set(_MPI_Intel_CXX_COMPILER_NAMES mpiicpc mpiicxx mpiic++ mpiiCC)
  137. set(_MPI_Intel_Fortran_COMPILER_NAMES mpiifort mpiif95 mpiif90 mpiif77)
  138. # PGI compiler names
  139. set(_MPI_PGI_C_COMPILER_NAMES mpipgcc mppgcc)
  140. set(_MPI_PGI_CXX_COMPILER_NAMES mpipgCC mppgCC)
  141. set(_MPI_PGI_Fortran_COMPILER_NAMES mpipgf95 mpipgf90 mppgf95 mppgf90 mpipgf77 mppgf77)
  142. # XLC MPI Compiler names
  143. set(_MPI_XL_C_COMPILER_NAMES mpxlc mpxlc_r mpixlc mpixlc_r)
  144. set(_MPI_XL_CXX_COMPILER_NAMES mpixlcxx mpixlC mpixlc++ mpxlcxx mpxlc++ mpixlc++ mpxlCC
  145. mpixlcxx_r mpixlC_r mpixlc++_r mpxlcxx_r mpxlc++_r mpixlc++_r mpxlCC_r)
  146. set(_MPI_XL_Fortran_COMPILER_NAMES mpixlf95 mpixlf95_r mpxlf95 mpxlf95_r
  147. mpixlf90 mpixlf90_r mpxlf90 mpxlf90_r
  148. mpixlf77 mpixlf77_r mpxlf77 mpxlf77_r
  149. mpixlf mpixlf_r mpxlf mpxlf_r)
  150. # append vendor-specific compilers to the list if we either don't know the compiler id,
  151. # or if we know it matches the regular compiler.
  152. foreach (lang C CXX Fortran)
  153. foreach (id GNU Intel PGI XL)
  154. if (NOT CMAKE_${lang}_COMPILER_ID OR "${CMAKE_${lang}_COMPILER_ID}" STREQUAL "${id}")
  155. list(APPEND _MPI_${lang}_COMPILER_NAMES ${_MPI_${id}_${lang}_COMPILER_NAMES})
  156. endif()
  157. unset(_MPI_${id}_${lang}_COMPILER_NAMES) # clean up the namespace here
  158. endforeach()
  159. endforeach()
  160. # Names to try for MPI exec
  161. set(_MPI_EXEC_NAMES mpiexec mpirun lamexec srun)
  162. # Grab the path to MPI from the registry if we're on windows.
  163. set(_MPI_PREFIX_PATH)
  164. if(WIN32)
  165. list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/..")
  166. list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]")
  167. list(APPEND _MPI_PREFIX_PATH "$ENV{ProgramW6432}/MPICH2/")
  168. endif()
  169. # Build a list of prefixes to search for MPI.
  170. foreach(SystemPrefixDir ${CMAKE_SYSTEM_PREFIX_PATH})
  171. foreach(MpiPackageDir ${_MPI_PREFIX_PATH})
  172. if(EXISTS ${SystemPrefixDir}/${MpiPackageDir})
  173. list(APPEND _MPI_PREFIX_PATH "${SystemPrefixDir}/${MpiPackageDir}")
  174. endif()
  175. endforeach()
  176. endforeach()
  177. #
  178. # interrogate_mpi_compiler(lang try_libs)
  179. #
  180. # Attempts to extract compiler and linker args from an MPI compiler. The arguments set
  181. # by this function are:
  182. #
  183. # MPI_<lang>_INCLUDE_PATH MPI_<lang>_LINK_FLAGS MPI_<lang>_FOUND
  184. # MPI_<lang>_COMPILE_FLAGS MPI_<lang>_LIBRARIES
  185. #
  186. # MPI_<lang>_COMPILER must be set beforehand to the absolute path to an MPI compiler for
  187. # <lang>. Additionally, MPI_<lang>_INCLUDE_PATH and MPI_<lang>_LIBRARIES may be set
  188. # to skip autodetection.
  189. #
  190. # If try_libs is TRUE, this will also attempt to find plain MPI libraries in the usual
  191. # way. In general, this is not as effective as interrogating the compilers, as it
  192. # ignores language-specific flags and libraries. However, some MPI implementations
  193. # (Windows implementations) do not have compiler wrappers, so this approach must be used.
  194. #
  195. function (interrogate_mpi_compiler lang try_libs)
  196. # MPI_${lang}_NO_INTERROGATE will be set to a compiler name when the *regular* compiler was
  197. # discovered to be the MPI compiler. This happens on machines like the Cray XE6 that use
  198. # modules to set cc, CC, and ftn to the MPI compilers. If the user force-sets another MPI
  199. # compiler, MPI_${lang}_COMPILER won't be equal to MPI_${lang}_NO_INTERROGATE, and we'll
  200. # inspect that compiler anew. This allows users to set new compilers w/o rm'ing cache.
  201. string(COMPARE NOTEQUAL "${MPI_${lang}_NO_INTERROGATE}" "${MPI_${lang}_COMPILER}" interrogate)
  202. # If MPI is set already in the cache, don't bother with interrogating the compiler.
  203. if (interrogate AND ((NOT MPI_${lang}_INCLUDE_PATH) OR (NOT MPI_${lang}_LIBRARIES)))
  204. if (MPI_${lang}_COMPILER)
  205. # Check whether the -showme:compile option works. This indicates that we have either OpenMPI
  206. # or a newer version of LAM-MPI, and implies that -showme:link will also work.
  207. execute_process(
  208. COMMAND ${MPI_${lang}_COMPILER} -showme:compile
  209. OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
  210. ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
  211. RESULT_VARIABLE MPI_COMPILER_RETURN)
  212. if (MPI_COMPILER_RETURN EQUAL 0)
  213. # If we appear to have -showme:compile, then we should
  214. # also have -showme:link. Try it.
  215. execute_process(
  216. COMMAND ${MPI_${lang}_COMPILER} -showme:link
  217. OUTPUT_VARIABLE MPI_LINK_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
  218. ERROR_VARIABLE MPI_LINK_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
  219. RESULT_VARIABLE MPI_COMPILER_RETURN)
  220. if (MPI_COMPILER_RETURN EQUAL 0)
  221. # We probably have -showme:incdirs and -showme:libdirs as well,
  222. # so grab that while we're at it.
  223. execute_process(
  224. COMMAND ${MPI_${lang}_COMPILER} -showme:incdirs
  225. OUTPUT_VARIABLE MPI_INCDIRS OUTPUT_STRIP_TRAILING_WHITESPACE
  226. ERROR_VARIABLE MPI_INCDIRS ERROR_STRIP_TRAILING_WHITESPACE)
  227. execute_process(
  228. COMMAND ${MPI_${lang}_COMPILER} -showme:libdirs
  229. OUTPUT_VARIABLE MPI_LIBDIRS OUTPUT_STRIP_TRAILING_WHITESPACE
  230. ERROR_VARIABLE MPI_LIBDIRS ERROR_STRIP_TRAILING_WHITESPACE)
  231. else()
  232. # reset things here if something went wrong.
  233. set(MPI_COMPILE_CMDLINE)
  234. set(MPI_LINK_CMDLINE)
  235. endif()
  236. endif ()
  237. # Older versions of LAM-MPI have "-showme". Try to find that.
  238. if (NOT MPI_COMPILER_RETURN EQUAL 0)
  239. execute_process(
  240. COMMAND ${MPI_${lang}_COMPILER} -showme
  241. OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
  242. ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
  243. RESULT_VARIABLE MPI_COMPILER_RETURN)
  244. endif()
  245. # MVAPICH uses -compile-info and -link-info. Try them.
  246. if (NOT MPI_COMPILER_RETURN EQUAL 0)
  247. execute_process(
  248. COMMAND ${MPI_${lang}_COMPILER} -compile-info
  249. OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
  250. ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
  251. RESULT_VARIABLE MPI_COMPILER_RETURN)
  252. # If we have compile-info, also have link-info.
  253. if (MPI_COMPILER_RETURN EQUAL 0)
  254. execute_process(
  255. COMMAND ${MPI_${lang}_COMPILER} -link-info
  256. OUTPUT_VARIABLE MPI_LINK_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
  257. ERROR_VARIABLE MPI_LINK_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
  258. RESULT_VARIABLE MPI_COMPILER_RETURN)
  259. endif()
  260. # make sure we got compile and link. Reset vars if something's wrong.
  261. if (NOT MPI_COMPILER_RETURN EQUAL 0)
  262. set(MPI_COMPILE_CMDLINE)
  263. set(MPI_LINK_CMDLINE)
  264. endif()
  265. endif()
  266. # MPICH just uses "-show". Try it.
  267. if (NOT MPI_COMPILER_RETURN EQUAL 0)
  268. execute_process(
  269. COMMAND ${MPI_${lang}_COMPILER} -show
  270. OUTPUT_VARIABLE MPI_COMPILE_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
  271. ERROR_VARIABLE MPI_COMPILE_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
  272. RESULT_VARIABLE MPI_COMPILER_RETURN)
  273. endif()
  274. if (MPI_COMPILER_RETURN EQUAL 0)
  275. # We have our command lines, but we might need to copy MPI_COMPILE_CMDLINE
  276. # into MPI_LINK_CMDLINE, if we didn't find the link line.
  277. if (NOT MPI_LINK_CMDLINE)
  278. set(MPI_LINK_CMDLINE ${MPI_COMPILE_CMDLINE})
  279. endif()
  280. else()
  281. message(STATUS "Unable to determine MPI from MPI driver ${MPI_${lang}_COMPILER}")
  282. set(MPI_COMPILE_CMDLINE)
  283. set(MPI_LINK_CMDLINE)
  284. endif()
  285. # Here, we're done with the interrogation part, and we'll try to extract args we care
  286. # about from what we learned from the compiler wrapper scripts.
  287. # If interrogation came back with something, extract our variable from the MPI command line
  288. if (MPI_COMPILE_CMDLINE OR MPI_LINK_CMDLINE)
  289. # Extract compile flags from the compile command line.
  290. string(REGEX MATCHALL "(^| )-[Df]([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_FLAGS "${MPI_COMPILE_CMDLINE}")
  291. set(MPI_COMPILE_FLAGS_WORK)
  292. foreach(FLAG ${MPI_ALL_COMPILE_FLAGS})
  293. if (MPI_COMPILE_FLAGS_WORK)
  294. set(MPI_COMPILE_FLAGS_WORK "${MPI_COMPILE_FLAGS_WORK} ${FLAG}")
  295. else()
  296. set(MPI_COMPILE_FLAGS_WORK ${FLAG})
  297. endif()
  298. endforeach()
  299. # Extract include paths from compile command line
  300. string(REGEX MATCHALL "(^| )-I([^\" ]+|\"[^\"]+\")" MPI_ALL_INCLUDE_PATHS "${MPI_COMPILE_CMDLINE}")
  301. foreach(IPATH ${MPI_ALL_INCLUDE_PATHS})
  302. string(REGEX REPLACE "^ ?-I" "" IPATH ${IPATH})
  303. string(REPLACE "//" "/" IPATH ${IPATH})
  304. list(APPEND MPI_INCLUDE_PATH_WORK ${IPATH})
  305. endforeach()
  306. # try using showme:incdirs if extracting didn't work.
  307. if (NOT MPI_INCLUDE_PATH_WORK)
  308. set(MPI_INCLUDE_PATH_WORK ${MPI_INCDIRS})
  309. separate_arguments(MPI_INCLUDE_PATH_WORK)
  310. endif()
  311. # If all else fails, just search for mpi.h in the normal include paths.
  312. if (NOT MPI_INCLUDE_PATH_WORK)
  313. set(MPI_HEADER_PATH "MPI_HEADER_PATH-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
  314. find_path(MPI_HEADER_PATH mpi.h
  315. HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
  316. PATH_SUFFIXES include)
  317. set(MPI_INCLUDE_PATH_WORK ${MPI_HEADER_PATH})
  318. endif()
  319. # Extract linker paths from the link command line
  320. string(REGEX MATCHALL "(^| |-Wl,)-L([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_PATHS "${MPI_LINK_CMDLINE}")
  321. set(MPI_LINK_PATH)
  322. foreach(LPATH ${MPI_ALL_LINK_PATHS})
  323. string(REGEX REPLACE "^(| |-Wl,)-L" "" LPATH ${LPATH})
  324. string(REPLACE "//" "/" LPATH ${LPATH})
  325. list(APPEND MPI_LINK_PATH ${LPATH})
  326. endforeach()
  327. # try using showme:libdirs if extracting didn't work.
  328. if (NOT MPI_LINK_PATH)
  329. set(MPI_LINK_PATH ${MPI_LIBDIRS})
  330. separate_arguments(MPI_LINK_PATH)
  331. endif()
  332. # Extract linker flags from the link command line
  333. string(REGEX MATCHALL "(^| )-Wl,([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}")
  334. set(MPI_LINK_FLAGS_WORK)
  335. foreach(FLAG ${MPI_ALL_LINK_FLAGS})
  336. if (MPI_LINK_FLAGS_WORK)
  337. set(MPI_LINK_FLAGS_WORK "${MPI_LINK_FLAGS_WORK} ${FLAG}")
  338. else()
  339. set(MPI_LINK_FLAGS_WORK ${FLAG})
  340. endif()
  341. endforeach()
  342. # Extract the set of libraries to link against from the link command
  343. # line
  344. string(REGEX MATCHALL "(^| )-l([^\" ]+|\"[^\"]+\")" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
  345. # add the compiler implicit directories because some compilers
  346. # such as the intel compiler have libraries that show up
  347. # in the showme list that can only be found in the implicit
  348. # link directories of the compiler. Do this for C++ and C
  349. # compilers if the implicit link directories are defined.
  350. if (DEFINED CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES)
  351. set(MPI_LINK_PATH
  352. "${MPI_LINK_PATH};${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}")
  353. endif ()
  354. if (DEFINED CMAKE_C_IMPLICIT_LINK_DIRECTORIES)
  355. set(MPI_LINK_PATH
  356. "${MPI_LINK_PATH};${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
  357. endif ()
  358. # Determine full path names for all of the libraries that one needs
  359. # to link against in an MPI program
  360. foreach(LIB ${MPI_LIBNAMES})
  361. string(REGEX REPLACE "^ ?-l" "" LIB ${LIB})
  362. # MPI_LIB is cached by find_library, but we don't want that. Clear it first.
  363. set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
  364. find_library(MPI_LIB NAMES ${LIB} HINTS ${MPI_LINK_PATH})
  365. if (MPI_LIB)
  366. list(APPEND MPI_LIBRARIES_WORK ${MPI_LIB})
  367. elseif (NOT MPI_FIND_QUIETLY)
  368. message(WARNING "Unable to find MPI library ${LIB}")
  369. endif()
  370. endforeach()
  371. # Sanity check MPI_LIBRARIES to make sure there are enough libraries
  372. list(LENGTH MPI_LIBRARIES_WORK MPI_NUMLIBS)
  373. list(LENGTH MPI_LIBNAMES MPI_NUMLIBS_EXPECTED)
  374. if (NOT MPI_NUMLIBS EQUAL MPI_NUMLIBS_EXPECTED)
  375. set(MPI_LIBRARIES_WORK "MPI_${lang}_LIBRARIES-NOTFOUND")
  376. endif()
  377. endif()
  378. elseif(try_libs)
  379. # If we didn't have an MPI compiler script to interrogate, attempt to find everything
  380. # with plain old find functions. This is nasty because MPI implementations have LOTS of
  381. # different library names, so this section isn't going to be very generic. We need to
  382. # make sure it works for MS MPI, though, since there are no compiler wrappers for that.
  383. find_path(MPI_HEADER_PATH mpi.h
  384. HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
  385. PATH_SUFFIXES include Inc)
  386. set(MPI_INCLUDE_PATH_WORK ${MPI_HEADER_PATH})
  387. # Decide between 32-bit and 64-bit libraries for Microsoft's MPI
  388. if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
  389. set(MS_MPI_ARCH_DIR amd64)
  390. else()
  391. set(MS_MPI_ARCH_DIR i386)
  392. endif()
  393. set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
  394. find_library(MPI_LIB
  395. NAMES mpi mpich mpich2 msmpi
  396. HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
  397. PATH_SUFFIXES lib lib/${MS_MPI_ARCH_DIR} Lib Lib/${MS_MPI_ARCH_DIR})
  398. set(MPI_LIBRARIES_WORK ${MPI_LIB})
  399. # Right now, we only know about the extra libs for C++.
  400. # We could add Fortran here (as there is usually libfmpich, etc.), but
  401. # this really only has to work with MS MPI on Windows.
  402. # Assume that other MPI's are covered by the compiler wrappers.
  403. if (${lang} STREQUAL CXX)
  404. set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
  405. find_library(MPI_LIB
  406. NAMES mpi++ mpicxx cxx mpi_cxx
  407. HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
  408. PATH_SUFFIXES lib)
  409. if (MPI_LIBRARIES_WORK AND MPI_LIB)
  410. list(APPEND MPI_LIBRARIES_WORK ${MPI_LIB})
  411. endif()
  412. endif()
  413. if (NOT MPI_LIBRARIES_WORK)
  414. set(MPI_LIBRARIES_WORK "MPI_${lang}_LIBRARIES-NOTFOUND")
  415. endif()
  416. endif()
  417. # If we found MPI, set up all of the appropriate cache entries
  418. set(MPI_${lang}_COMPILE_FLAGS ${MPI_COMPILE_FLAGS_WORK} CACHE STRING "MPI ${lang} compilation flags" FORCE)
  419. set(MPI_${lang}_INCLUDE_PATH ${MPI_INCLUDE_PATH_WORK} CACHE STRING "MPI ${lang} include path" FORCE)
  420. set(MPI_${lang}_LINK_FLAGS ${MPI_LINK_FLAGS_WORK} CACHE STRING "MPI ${lang} linking flags" FORCE)
  421. set(MPI_${lang}_LIBRARIES ${MPI_LIBRARIES_WORK} CACHE STRING "MPI ${lang} libraries to link against" FORCE)
  422. mark_as_advanced(MPI_${lang}_COMPILE_FLAGS MPI_${lang}_INCLUDE_PATH MPI_${lang}_LINK_FLAGS MPI_${lang}_LIBRARIES)
  423. # clear out our temporary lib/header detectionv variable here.
  424. set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE INTERNAL "Scratch variable for MPI lib detection" FORCE)
  425. set(MPI_HEADER_PATH "MPI_HEADER_PATH-NOTFOUND" CACHE INTERNAL "Scratch variable for MPI header detection" FORCE)
  426. endif()
  427. # finally set a found variable for each MPI language
  428. if (MPI_${lang}_INCLUDE_PATH AND MPI_${lang}_LIBRARIES)
  429. set(MPI_${lang}_FOUND TRUE PARENT_SCOPE)
  430. else()
  431. set(MPI_${lang}_FOUND FALSE PARENT_SCOPE)
  432. endif()
  433. endfunction()
  434. # This function attempts to compile with the regular compiler, to see if MPI programs
  435. # work with it. This is a last ditch attempt after we've tried interrogating mpicc and
  436. # friends, and after we've tried to find generic libraries. Works on machines like
  437. # Cray XE6, where the modules environment changes what MPI version cc, CC, and ftn use.
  438. function(try_regular_compiler lang success)
  439. set(scratch_directory ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY})
  440. if (${lang} STREQUAL Fortran)
  441. set(test_file ${scratch_directory}/cmake_mpi_test.f90)
  442. file(WRITE ${test_file}
  443. "program hello\n"
  444. "include 'mpif.h'\n"
  445. "integer ierror\n"
  446. "call MPI_INIT(ierror)\n"
  447. "call MPI_FINALIZE(ierror)\n"
  448. "end\n")
  449. else()
  450. if (${lang} STREQUAL CXX)
  451. set(test_file ${scratch_directory}/cmake_mpi_test.cpp)
  452. else()
  453. set(test_file ${scratch_directory}/cmake_mpi_test.c)
  454. endif()
  455. file(WRITE ${test_file}
  456. "#include <mpi.h>\n"
  457. "int main(int argc, char **argv) {\n"
  458. " MPI_Init(&argc, &argv);\n"
  459. " MPI_Finalize();\n"
  460. "}\n")
  461. endif()
  462. try_compile(compiler_has_mpi ${scratch_directory} ${test_file})
  463. if (compiler_has_mpi)
  464. set(MPI_${lang}_NO_INTERROGATE ${CMAKE_${lang}_COMPILER} CACHE STRING "Whether to interrogate MPI ${lang} compiler" FORCE)
  465. set(MPI_${lang}_COMPILER ${CMAKE_${lang}_COMPILER} CACHE STRING "MPI ${lang} compiler" FORCE)
  466. set(MPI_${lang}_COMPILE_FLAGS "" CACHE STRING "MPI ${lang} compilation flags" FORCE)
  467. set(MPI_${lang}_INCLUDE_PATH "" CACHE STRING "MPI ${lang} include path" FORCE)
  468. set(MPI_${lang}_LINK_FLAGS "" CACHE STRING "MPI ${lang} linking flags" FORCE)
  469. set(MPI_${lang}_LIBRARIES "" CACHE STRING "MPI ${lang} libraries to link against" FORCE)
  470. endif()
  471. set(${success} ${compiler_has_mpi} PARENT_SCOPE)
  472. unset(compiler_has_mpi CACHE)
  473. endfunction()
  474. # End definitions, commence real work here.
  475. # Most mpi distros have some form of mpiexec which gives us something we can reliably look for.
  476. find_program(MPIEXEC
  477. NAMES ${_MPI_EXEC_NAMES}
  478. PATHS ${_MPI_PREFIX_PATH}
  479. PATH_SUFFIXES bin
  480. DOC "Executable for running MPI programs.")
  481. # call get_filename_component twice to remove mpiexec and the directory it exists in (typically bin).
  482. # This gives us a fairly reliable base directory to search for /bin /lib and /include from.
  483. get_filename_component(_MPI_BASE_DIR "${MPIEXEC}" PATH)
  484. get_filename_component(_MPI_BASE_DIR "${_MPI_BASE_DIR}" PATH)
  485. set(MPIEXEC_NUMPROC_FLAG "-np" CACHE STRING "Flag used by MPI to specify the number of processes for MPIEXEC; the next option will be the number of processes.")
  486. set(MPIEXEC_PREFLAGS "" CACHE STRING "These flags will be directly before the executable that is being run by MPIEXEC.")
  487. set(MPIEXEC_POSTFLAGS "" CACHE STRING "These flags will come after all flags given to MPIEXEC.")
  488. set(MPIEXEC_MAX_NUMPROCS "2" CACHE STRING "Maximum number of processors available to run MPI applications.")
  489. mark_as_advanced(MPIEXEC MPIEXEC_NUMPROC_FLAG MPIEXEC_PREFLAGS MPIEXEC_POSTFLAGS MPIEXEC_MAX_NUMPROCS)
  490. #=============================================================================
  491. # Backward compatibility input hacks. Propagate the FindMPI hints to C and
  492. # CXX if the respective new versions are not defined. Translate the old
  493. # MPI_LIBRARY and MPI_EXTRA_LIBRARY to respective MPI_${lang}_LIBRARIES.
  494. #
  495. # Once we find the new variables, we translate them back into their old
  496. # equivalents below.
  497. foreach (lang C CXX)
  498. # Old input variables.
  499. set(_MPI_OLD_INPUT_VARS COMPILER COMPILE_FLAGS INCLUDE_PATH LINK_FLAGS)
  500. # Set new vars based on their old equivalents, if the new versions are not already set.
  501. foreach (var ${_MPI_OLD_INPUT_VARS})
  502. if (NOT MPI_${lang}_${var} AND MPI_${var})
  503. set(MPI_${lang}_${var} "${MPI_${var}}")
  504. endif()
  505. endforeach()
  506. # Special handling for MPI_LIBRARY and MPI_EXTRA_LIBRARY, which we nixed in the
  507. # new FindMPI. These need to be merged into MPI_<lang>_LIBRARIES
  508. if (NOT MPI_${lang}_LIBRARIES AND (MPI_LIBRARY OR MPI_EXTRA_LIBRARY))
  509. set(MPI_${lang}_LIBRARIES ${MPI_LIBRARY} ${MPI_EXTRA_LIBRARY})
  510. endif()
  511. endforeach()
  512. #=============================================================================
  513. # This loop finds the compilers and sends them off for interrogation.
  514. foreach (lang C CXX Fortran)
  515. if (CMAKE_${lang}_COMPILER_WORKS)
  516. # If the user supplies a compiler *name* instead of an absolute path, assume that we need to find THAT compiler.
  517. if (MPI_${lang}_COMPILER)
  518. is_file_executable(MPI_${lang}_COMPILER MPI_COMPILER_IS_EXECUTABLE)
  519. if (NOT MPI_COMPILER_IS_EXECUTABLE)
  520. # Get rid of our default list of names and just search for the name the user wants.
  521. set(_MPI_${lang}_COMPILER_NAMES ${MPI_${lang}_COMPILER})
  522. set(MPI_${lang}_COMPILER "MPI_${lang}_COMPILER-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
  523. # If the user specifies a compiler, we don't want to try to search libraries either.
  524. set(try_libs FALSE)
  525. endif()
  526. else()
  527. set(try_libs TRUE)
  528. endif()
  529. find_program(MPI_${lang}_COMPILER
  530. NAMES ${_MPI_${lang}_COMPILER_NAMES}
  531. PATHS "${MPI_HOME}/bin" "$ENV{MPI_HOME}/bin" ${_MPI_PREFIX_PATH})
  532. interrogate_mpi_compiler(${lang} ${try_libs})
  533. mark_as_advanced(MPI_${lang}_COMPILER)
  534. # last ditch try -- if nothing works so far, just try running the regular compiler and
  535. # see if we can create an MPI executable.
  536. set(regular_compiler_worked 0)
  537. if (NOT MPI_${lang}_LIBRARIES OR NOT MPI_${lang}_INCLUDE_PATH)
  538. try_regular_compiler(${lang} regular_compiler_worked)
  539. endif()
  540. set(MPI_${lang}_FIND_QUIETLY ${MPI_FIND_QUIETLY})
  541. set(MPI_${lang}_FIND_REQUIRED ${MPI_FIND_REQUIRED})
  542. set(MPI_${lang}_FIND_VERSION ${MPI_FIND_VERSION})
  543. set(MPI_${lang}_FIND_VERSION_EXACT ${MPI_FIND_VERSION_EXACT})
  544. if (regular_compiler_worked)
  545. find_package_handle_standard_args(MPI_${lang} DEFAULT_MSG MPI_${lang}_COMPILER)
  546. else()
  547. find_package_handle_standard_args(MPI_${lang} DEFAULT_MSG MPI_${lang}_LIBRARIES MPI_${lang}_INCLUDE_PATH)
  548. endif()
  549. endif()
  550. endforeach()
  551. #=============================================================================
  552. # More backward compatibility stuff
  553. #
  554. # Bare MPI sans ${lang} vars are set to CXX then C, depending on what was found.
  555. # This mimics the behavior of the old language-oblivious FindMPI.
  556. set(_MPI_OLD_VARS FOUND COMPILER INCLUDE_PATH COMPILE_FLAGS LINK_FLAGS LIBRARIES)
  557. if (MPI_CXX_FOUND)
  558. foreach (var ${_MPI_OLD_VARS})
  559. set(MPI_${var} ${MPI_CXX_${var}})
  560. endforeach()
  561. elseif (MPI_C_FOUND)
  562. foreach (var ${_MPI_OLD_VARS})
  563. set(MPI_${var} ${MPI_C_${var}})
  564. endforeach()
  565. else()
  566. # Note that we might still have found Fortran, but you'll need to use MPI_Fortran_FOUND
  567. set(MPI_FOUND FALSE)
  568. endif()
  569. # Chop MPI_LIBRARIES into the old-style MPI_LIBRARY and MPI_EXTRA_LIBRARY, and set them in cache.
  570. if (MPI_LIBRARIES)
  571. list(GET MPI_LIBRARIES 0 MPI_LIBRARY_WORK)
  572. set(MPI_LIBRARY ${MPI_LIBRARY_WORK} CACHE FILEPATH "MPI library to link against" FORCE)
  573. else()
  574. set(MPI_LIBRARY "MPI_LIBRARY-NOTFOUND" CACHE FILEPATH "MPI library to link against" FORCE)
  575. endif()
  576. list(LENGTH MPI_LIBRARIES MPI_NUMLIBS)
  577. if (MPI_NUMLIBS GREATER 1)
  578. set(MPI_EXTRA_LIBRARY_WORK ${MPI_LIBRARIES})
  579. list(REMOVE_AT MPI_EXTRA_LIBRARY_WORK 0)
  580. set(MPI_EXTRA_LIBRARY ${MPI_EXTRA_LIBRARY_WORK} CACHE STRING "Extra MPI libraries to link against" FORCE)
  581. else()
  582. set(MPI_EXTRA_LIBRARY "MPI_EXTRA_LIBRARY-NOTFOUND" CACHE STRING "Extra MPI libraries to link against" FORCE)
  583. endif()
  584. #=============================================================================
  585. # unset these vars to cleanup namespace
  586. unset(_MPI_OLD_VARS)
  587. unset(_MPI_PREFIX_PATH)
  588. unset(_MPI_BASE_DIR)
  589. foreach (lang C CXX Fortran)
  590. unset(_MPI_${lang}_COMPILER_NAMES)
  591. endforeach()