FindMPI.cmake 30 KB

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