FindMPI.cmake 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  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. # MSMPI
  166. list(APPEND _MPI_PREFIX_PATH "$ENV{MSMPI_BIN}")
  167. list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\MPI;InstallRoot]/Bin")
  168. list(APPEND _MPI_PREFIX_PATH "$ENV{MSMPI_INC}/..") # The SDK is installed separately from the runtime
  169. # MPICH
  170. list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH\\SMPD;binary]/..")
  171. list(APPEND _MPI_PREFIX_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MPICH2;Path]")
  172. list(APPEND _MPI_PREFIX_PATH "$ENV{ProgramW6432}/MPICH2/")
  173. endif()
  174. # Build a list of prefixes to search for MPI.
  175. foreach(SystemPrefixDir ${CMAKE_SYSTEM_PREFIX_PATH})
  176. foreach(MpiPackageDir ${_MPI_PREFIX_PATH})
  177. if(EXISTS ${SystemPrefixDir}/${MpiPackageDir})
  178. list(APPEND _MPI_PREFIX_PATH "${SystemPrefixDir}/${MpiPackageDir}")
  179. endif()
  180. endforeach()
  181. endforeach()
  182. function (_mpi_check_compiler compiler options cmdvar resvar)
  183. execute_process(
  184. COMMAND "${compiler}" ${options}
  185. OUTPUT_VARIABLE cmdline OUTPUT_STRIP_TRAILING_WHITESPACE
  186. ERROR_VARIABLE cmdline ERROR_STRIP_TRAILING_WHITESPACE
  187. RESULT_VARIABLE success)
  188. # Intel MPI 5.0.1 will return a zero return code even when the
  189. # argument to the MPI compiler wrapper is unknown. Attempt to
  190. # catch this case.
  191. if("${cmdline}" MATCHES "undefined reference")
  192. set(success 255 )
  193. endif()
  194. set(${cmdvar} "${cmdline}" PARENT_SCOPE)
  195. set(${resvar} "${success}" PARENT_SCOPE)
  196. endfunction()
  197. #
  198. # interrogate_mpi_compiler(lang try_libs)
  199. #
  200. # Attempts to extract compiler and linker args from an MPI compiler. The arguments set
  201. # by this function are:
  202. #
  203. # MPI_<lang>_INCLUDE_PATH MPI_<lang>_LINK_FLAGS MPI_<lang>_FOUND
  204. # MPI_<lang>_COMPILE_FLAGS MPI_<lang>_LIBRARIES
  205. #
  206. # MPI_<lang>_COMPILER must be set beforehand to the absolute path to an MPI compiler for
  207. # <lang>. Additionally, MPI_<lang>_INCLUDE_PATH and MPI_<lang>_LIBRARIES may be set
  208. # to skip autodetection.
  209. #
  210. # If try_libs is TRUE, this will also attempt to find plain MPI libraries in the usual
  211. # way. In general, this is not as effective as interrogating the compilers, as it
  212. # ignores language-specific flags and libraries. However, some MPI implementations
  213. # (Windows implementations) do not have compiler wrappers, so this approach must be used.
  214. #
  215. function (interrogate_mpi_compiler lang try_libs)
  216. # MPI_${lang}_NO_INTERROGATE will be set to a compiler name when the *regular* compiler was
  217. # discovered to be the MPI compiler. This happens on machines like the Cray XE6 that use
  218. # modules to set cc, CC, and ftn to the MPI compilers. If the user force-sets another MPI
  219. # compiler, MPI_${lang}_COMPILER won't be equal to MPI_${lang}_NO_INTERROGATE, and we'll
  220. # inspect that compiler anew. This allows users to set new compilers w/o rm'ing cache.
  221. string(COMPARE NOTEQUAL "${MPI_${lang}_NO_INTERROGATE}" "${MPI_${lang}_COMPILER}" interrogate)
  222. # If MPI is set already in the cache, don't bother with interrogating the compiler.
  223. if (interrogate AND ((NOT MPI_${lang}_INCLUDE_PATH) OR (NOT MPI_${lang}_LIBRARIES)))
  224. if (MPI_${lang}_COMPILER)
  225. # Check whether the -showme:compile option works. This indicates that we have either OpenMPI
  226. # or a newer version of LAM-MPI, and implies that -showme:link will also work.
  227. _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-showme:compile" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
  228. if (MPI_COMPILER_RETURN EQUAL 0)
  229. # If we appear to have -showme:compile, then we should
  230. # also have -showme:link. Try it.
  231. execute_process(
  232. COMMAND ${MPI_${lang}_COMPILER} -showme:link
  233. OUTPUT_VARIABLE MPI_LINK_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
  234. ERROR_VARIABLE MPI_LINK_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
  235. RESULT_VARIABLE MPI_COMPILER_RETURN)
  236. if (MPI_COMPILER_RETURN EQUAL 0)
  237. # We probably have -showme:incdirs and -showme:libdirs as well,
  238. # so grab that while we're at it.
  239. execute_process(
  240. COMMAND ${MPI_${lang}_COMPILER} -showme:incdirs
  241. OUTPUT_VARIABLE MPI_INCDIRS OUTPUT_STRIP_TRAILING_WHITESPACE
  242. ERROR_VARIABLE MPI_INCDIRS ERROR_STRIP_TRAILING_WHITESPACE)
  243. execute_process(
  244. COMMAND ${MPI_${lang}_COMPILER} -showme:libdirs
  245. OUTPUT_VARIABLE MPI_LIBDIRS OUTPUT_STRIP_TRAILING_WHITESPACE
  246. ERROR_VARIABLE MPI_LIBDIRS ERROR_STRIP_TRAILING_WHITESPACE)
  247. else()
  248. # reset things here if something went wrong.
  249. set(MPI_COMPILE_CMDLINE)
  250. set(MPI_LINK_CMDLINE)
  251. endif()
  252. endif ()
  253. # Older versions of LAM-MPI have "-showme". Try to find that.
  254. if (NOT MPI_COMPILER_RETURN EQUAL 0)
  255. _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-showme" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
  256. endif()
  257. # MVAPICH uses -compile-info and -link-info. Try them.
  258. if (NOT MPI_COMPILER_RETURN EQUAL 0)
  259. _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-compile-info" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
  260. # If we have compile-info, also have link-info.
  261. if (MPI_COMPILER_RETURN EQUAL 0)
  262. execute_process(
  263. COMMAND ${MPI_${lang}_COMPILER} -link-info
  264. OUTPUT_VARIABLE MPI_LINK_CMDLINE OUTPUT_STRIP_TRAILING_WHITESPACE
  265. ERROR_VARIABLE MPI_LINK_CMDLINE ERROR_STRIP_TRAILING_WHITESPACE
  266. RESULT_VARIABLE MPI_COMPILER_RETURN)
  267. endif()
  268. # make sure we got compile and link. Reset vars if something's wrong.
  269. if (NOT MPI_COMPILER_RETURN EQUAL 0)
  270. set(MPI_COMPILE_CMDLINE)
  271. set(MPI_LINK_CMDLINE)
  272. endif()
  273. endif()
  274. # MPICH just uses "-show". Try it.
  275. if (NOT MPI_COMPILER_RETURN EQUAL 0)
  276. _mpi_check_compiler("${MPI_${lang}_COMPILER}" "-show" MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
  277. endif()
  278. if (MPI_COMPILER_RETURN EQUAL 0)
  279. # We have our command lines, but we might need to copy MPI_COMPILE_CMDLINE
  280. # into MPI_LINK_CMDLINE, if we didn't find the link line.
  281. if (NOT MPI_LINK_CMDLINE)
  282. set(MPI_LINK_CMDLINE ${MPI_COMPILE_CMDLINE})
  283. endif()
  284. else()
  285. message(STATUS "Unable to determine MPI from MPI driver ${MPI_${lang}_COMPILER}")
  286. set(MPI_COMPILE_CMDLINE)
  287. set(MPI_LINK_CMDLINE)
  288. endif()
  289. # Here, we're done with the interrogation part, and we'll try to extract args we care
  290. # about from what we learned from the compiler wrapper scripts.
  291. # If interrogation came back with something, extract our variable from the MPI command line
  292. if (MPI_COMPILE_CMDLINE OR MPI_LINK_CMDLINE)
  293. # Extract compile flags from the compile command line.
  294. string(REGEX MATCHALL "(^| )-[Df]([^\" ]+|\"[^\"]+\")" MPI_ALL_COMPILE_FLAGS "${MPI_COMPILE_CMDLINE}")
  295. set(MPI_COMPILE_FLAGS_WORK)
  296. foreach(FLAG ${MPI_ALL_COMPILE_FLAGS})
  297. if (MPI_COMPILE_FLAGS_WORK)
  298. set(MPI_COMPILE_FLAGS_WORK "${MPI_COMPILE_FLAGS_WORK} ${FLAG}")
  299. else()
  300. set(MPI_COMPILE_FLAGS_WORK ${FLAG})
  301. endif()
  302. endforeach()
  303. # Extract include paths from compile command line
  304. string(REGEX MATCHALL "(^| )-I([^\" ]+|\"[^\"]+\")" MPI_ALL_INCLUDE_PATHS "${MPI_COMPILE_CMDLINE}")
  305. foreach(IPATH ${MPI_ALL_INCLUDE_PATHS})
  306. string(REGEX REPLACE "^ ?-I" "" IPATH ${IPATH})
  307. string(REPLACE "//" "/" IPATH ${IPATH})
  308. list(APPEND MPI_INCLUDE_PATH_WORK ${IPATH})
  309. endforeach()
  310. # try using showme:incdirs if extracting didn't work.
  311. if (NOT MPI_INCLUDE_PATH_WORK)
  312. set(MPI_INCLUDE_PATH_WORK ${MPI_INCDIRS})
  313. separate_arguments(MPI_INCLUDE_PATH_WORK)
  314. endif()
  315. # If all else fails, just search for mpi.h in the normal include paths.
  316. if (NOT MPI_INCLUDE_PATH_WORK)
  317. set(MPI_HEADER_PATH "MPI_HEADER_PATH-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
  318. find_path(MPI_HEADER_PATH mpi.h
  319. HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
  320. PATH_SUFFIXES include)
  321. set(MPI_INCLUDE_PATH_WORK ${MPI_HEADER_PATH})
  322. endif()
  323. # Extract linker paths from the link command line
  324. string(REGEX MATCHALL "(^| |-Wl,)-L([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_PATHS "${MPI_LINK_CMDLINE}")
  325. set(MPI_LINK_PATH)
  326. foreach(LPATH ${MPI_ALL_LINK_PATHS})
  327. string(REGEX REPLACE "^(| |-Wl,)-L" "" LPATH ${LPATH})
  328. string(REPLACE "//" "/" LPATH ${LPATH})
  329. list(APPEND MPI_LINK_PATH ${LPATH})
  330. endforeach()
  331. # try using showme:libdirs if extracting didn't work.
  332. if (NOT MPI_LINK_PATH)
  333. set(MPI_LINK_PATH ${MPI_LIBDIRS})
  334. separate_arguments(MPI_LINK_PATH)
  335. endif()
  336. # Extract linker flags from the link command line
  337. string(REGEX MATCHALL "(^| )(-Wl,|-Xlinker )([^\" ]+|\"[^\"]+\")" MPI_ALL_LINK_FLAGS "${MPI_LINK_CMDLINE}")
  338. set(MPI_LINK_FLAGS_WORK)
  339. foreach(FLAG ${MPI_ALL_LINK_FLAGS})
  340. if (MPI_LINK_FLAGS_WORK)
  341. set(MPI_LINK_FLAGS_WORK "${MPI_LINK_FLAGS_WORK} ${FLAG}")
  342. else()
  343. set(MPI_LINK_FLAGS_WORK ${FLAG})
  344. endif()
  345. endforeach()
  346. # Extract the set of libraries to link against from the link command
  347. # line
  348. string(REGEX MATCHALL "(^| )-l([^\" ]+|\"[^\"]+\")" MPI_LIBNAMES "${MPI_LINK_CMDLINE}")
  349. # add the compiler implicit directories because some compilers
  350. # such as the intel compiler have libraries that show up
  351. # in the showme list that can only be found in the implicit
  352. # link directories of the compiler.
  353. if (DEFINED CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES)
  354. set(MPI_LINK_PATH
  355. "${MPI_LINK_PATH};${CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES}")
  356. endif ()
  357. # Determine full path names for all of the libraries that one needs
  358. # to link against in an MPI program
  359. foreach(LIB ${MPI_LIBNAMES})
  360. string(REGEX REPLACE "^ ?-l" "" LIB ${LIB})
  361. # MPI_LIB is cached by find_library, but we don't want that. Clear it first.
  362. set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
  363. find_library(MPI_LIB NAMES ${LIB} HINTS ${MPI_LINK_PATH})
  364. if (MPI_LIB)
  365. list(APPEND MPI_LIBRARIES_WORK ${MPI_LIB})
  366. elseif (NOT MPI_FIND_QUIETLY)
  367. message(WARNING "Unable to find MPI library ${LIB}")
  368. endif()
  369. endforeach()
  370. # Sanity check MPI_LIBRARIES to make sure there are enough libraries
  371. list(LENGTH MPI_LIBRARIES_WORK MPI_NUMLIBS)
  372. list(LENGTH MPI_LIBNAMES MPI_NUMLIBS_EXPECTED)
  373. if (NOT MPI_NUMLIBS EQUAL MPI_NUMLIBS_EXPECTED)
  374. set(MPI_LIBRARIES_WORK "MPI_${lang}_LIBRARIES-NOTFOUND")
  375. endif()
  376. endif()
  377. elseif(try_libs)
  378. # If we didn't have an MPI compiler script to interrogate, attempt to find everything
  379. # with plain old find functions. This is nasty because MPI implementations have LOTS of
  380. # different library names, so this section isn't going to be very generic. We need to
  381. # make sure it works for MS MPI, though, since there are no compiler wrappers for that.
  382. find_path(MPI_HEADER_PATH mpi.h
  383. HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
  384. PATH_SUFFIXES include Inc)
  385. set(MPI_INCLUDE_PATH_WORK ${MPI_HEADER_PATH})
  386. # Decide between 32-bit and 64-bit libraries for Microsoft's MPI
  387. if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
  388. set(MS_MPI_ARCH_DIR x64)
  389. set(MS_MPI_ARCH_DIR2 amd64)
  390. else()
  391. set(MS_MPI_ARCH_DIR x86)
  392. set(MS_MPI_ARCH_DIR2 i386)
  393. endif()
  394. set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
  395. find_library(MPI_LIB
  396. NAMES mpi mpich mpich2 msmpi
  397. HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
  398. PATH_SUFFIXES lib lib/${MS_MPI_ARCH_DIR} Lib Lib/${MS_MPI_ARCH_DIR} Lib/${MS_MPI_ARCH_DIR2})
  399. set(MPI_LIBRARIES_WORK ${MPI_LIB})
  400. # Right now, we only know about the extra libs for C++.
  401. # We could add Fortran here (as there is usually libfmpich, etc.), but
  402. # this really only has to work with MS MPI on Windows.
  403. # Assume that other MPI's are covered by the compiler wrappers.
  404. if (${lang} STREQUAL CXX)
  405. set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
  406. find_library(MPI_LIB
  407. NAMES mpi++ mpicxx cxx mpi_cxx
  408. HINTS ${_MPI_BASE_DIR} ${_MPI_PREFIX_PATH}
  409. PATH_SUFFIXES lib)
  410. if (MPI_LIBRARIES_WORK AND MPI_LIB)
  411. list(APPEND MPI_LIBRARIES_WORK ${MPI_LIB})
  412. endif()
  413. endif()
  414. if (NOT MPI_LIBRARIES_WORK)
  415. set(MPI_LIBRARIES_WORK "MPI_${lang}_LIBRARIES-NOTFOUND")
  416. endif()
  417. endif()
  418. # If we found MPI, set up all of the appropriate cache entries
  419. set(MPI_${lang}_COMPILE_FLAGS ${MPI_COMPILE_FLAGS_WORK} CACHE STRING "MPI ${lang} compilation flags" FORCE)
  420. set(MPI_${lang}_INCLUDE_PATH ${MPI_INCLUDE_PATH_WORK} CACHE STRING "MPI ${lang} include path" FORCE)
  421. set(MPI_${lang}_LINK_FLAGS ${MPI_LINK_FLAGS_WORK} CACHE STRING "MPI ${lang} linking flags" FORCE)
  422. set(MPI_${lang}_LIBRARIES ${MPI_LIBRARIES_WORK} CACHE STRING "MPI ${lang} libraries to link against" FORCE)
  423. mark_as_advanced(MPI_${lang}_COMPILE_FLAGS MPI_${lang}_INCLUDE_PATH MPI_${lang}_LINK_FLAGS MPI_${lang}_LIBRARIES)
  424. # clear out our temporary lib/header detectionv variable here.
  425. set(MPI_LIB "MPI_LIB-NOTFOUND" CACHE INTERNAL "Scratch variable for MPI lib detection" FORCE)
  426. set(MPI_HEADER_PATH "MPI_HEADER_PATH-NOTFOUND" CACHE INTERNAL "Scratch variable for MPI header detection" FORCE)
  427. endif()
  428. # finally set a found variable for each MPI language
  429. if (MPI_${lang}_INCLUDE_PATH AND MPI_${lang}_LIBRARIES)
  430. set(MPI_${lang}_FOUND TRUE PARENT_SCOPE)
  431. else()
  432. set(MPI_${lang}_FOUND FALSE PARENT_SCOPE)
  433. endif()
  434. endfunction()
  435. # This function attempts to compile with the regular compiler, to see if MPI programs
  436. # work with it. This is a last ditch attempt after we've tried interrogating mpicc and
  437. # friends, and after we've tried to find generic libraries. Works on machines like
  438. # Cray XE6, where the modules environment changes what MPI version cc, CC, and ftn use.
  439. function(try_regular_compiler lang success)
  440. set(scratch_directory ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY})
  441. if (${lang} STREQUAL Fortran)
  442. set(test_file ${scratch_directory}/cmake_mpi_test.f90)
  443. file(WRITE ${test_file}
  444. "program hello\n"
  445. "include 'mpif.h'\n"
  446. "integer ierror\n"
  447. "call MPI_INIT(ierror)\n"
  448. "call MPI_FINALIZE(ierror)\n"
  449. "end\n")
  450. else()
  451. if (${lang} STREQUAL CXX)
  452. set(test_file ${scratch_directory}/cmake_mpi_test.cpp)
  453. else()
  454. set(test_file ${scratch_directory}/cmake_mpi_test.c)
  455. endif()
  456. file(WRITE ${test_file}
  457. "#include <mpi.h>\n"
  458. "int main(int argc, char **argv) {\n"
  459. " MPI_Init(&argc, &argv);\n"
  460. " MPI_Finalize();\n"
  461. "}\n")
  462. endif()
  463. try_compile(compiler_has_mpi ${scratch_directory} ${test_file})
  464. if (compiler_has_mpi)
  465. set(MPI_${lang}_NO_INTERROGATE ${CMAKE_${lang}_COMPILER} CACHE STRING "Whether to interrogate MPI ${lang} compiler" FORCE)
  466. set(MPI_${lang}_COMPILER ${CMAKE_${lang}_COMPILER} CACHE STRING "MPI ${lang} compiler" FORCE)
  467. set(MPI_${lang}_COMPILE_FLAGS "" CACHE STRING "MPI ${lang} compilation flags" FORCE)
  468. set(MPI_${lang}_INCLUDE_PATH "" CACHE STRING "MPI ${lang} include path" FORCE)
  469. set(MPI_${lang}_LINK_FLAGS "" CACHE STRING "MPI ${lang} linking flags" FORCE)
  470. set(MPI_${lang}_LIBRARIES "" CACHE STRING "MPI ${lang} libraries to link against" FORCE)
  471. endif()
  472. set(${success} ${compiler_has_mpi} PARENT_SCOPE)
  473. unset(compiler_has_mpi CACHE)
  474. endfunction()
  475. # End definitions, commence real work here.
  476. # Most mpi distros have some form of mpiexec which gives us something we can reliably look for.
  477. find_program(MPIEXEC
  478. NAMES ${_MPI_EXEC_NAMES}
  479. HINTS ${MPI_HOME} $ENV{MPI_HOME}
  480. PATHS ${_MPI_PREFIX_PATH}
  481. PATH_SUFFIXES bin
  482. DOC "Executable for running MPI programs.")
  483. # call get_filename_component twice to remove mpiexec and the directory it exists in (typically bin).
  484. # This gives us a fairly reliable base directory to search for /bin /lib and /include from.
  485. get_filename_component(_MPI_BASE_DIR "${MPIEXEC}" PATH)
  486. get_filename_component(_MPI_BASE_DIR "${_MPI_BASE_DIR}" PATH)
  487. 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.")
  488. set(MPIEXEC_PREFLAGS "" CACHE STRING "These flags will be directly before the executable that is being run by MPIEXEC.")
  489. set(MPIEXEC_POSTFLAGS "" CACHE STRING "These flags will come after all flags given to MPIEXEC.")
  490. set(MPIEXEC_MAX_NUMPROCS "2" CACHE STRING "Maximum number of processors available to run MPI applications.")
  491. mark_as_advanced(MPIEXEC MPIEXEC_NUMPROC_FLAG MPIEXEC_PREFLAGS MPIEXEC_POSTFLAGS MPIEXEC_MAX_NUMPROCS)
  492. #=============================================================================
  493. # Backward compatibility input hacks. Propagate the FindMPI hints to C and
  494. # CXX if the respective new versions are not defined. Translate the old
  495. # MPI_LIBRARY and MPI_EXTRA_LIBRARY to respective MPI_${lang}_LIBRARIES.
  496. #
  497. # Once we find the new variables, we translate them back into their old
  498. # equivalents below.
  499. foreach (lang C CXX)
  500. # Old input variables.
  501. set(_MPI_OLD_INPUT_VARS COMPILER COMPILE_FLAGS INCLUDE_PATH LINK_FLAGS)
  502. # Set new vars based on their old equivalents, if the new versions are not already set.
  503. foreach (var ${_MPI_OLD_INPUT_VARS})
  504. if (NOT MPI_${lang}_${var} AND MPI_${var})
  505. set(MPI_${lang}_${var} "${MPI_${var}}")
  506. endif()
  507. endforeach()
  508. # Special handling for MPI_LIBRARY and MPI_EXTRA_LIBRARY, which we nixed in the
  509. # new FindMPI. These need to be merged into MPI_<lang>_LIBRARIES
  510. if (NOT MPI_${lang}_LIBRARIES AND (MPI_LIBRARY OR MPI_EXTRA_LIBRARY))
  511. set(MPI_${lang}_LIBRARIES ${MPI_LIBRARY} ${MPI_EXTRA_LIBRARY})
  512. endif()
  513. endforeach()
  514. #=============================================================================
  515. # This loop finds the compilers and sends them off for interrogation.
  516. foreach (lang C CXX Fortran)
  517. if (CMAKE_${lang}_COMPILER_WORKS)
  518. # If the user supplies a compiler *name* instead of an absolute path, assume that we need to find THAT compiler.
  519. if (MPI_${lang}_COMPILER)
  520. is_file_executable(MPI_${lang}_COMPILER MPI_COMPILER_IS_EXECUTABLE)
  521. if (NOT MPI_COMPILER_IS_EXECUTABLE)
  522. # Get rid of our default list of names and just search for the name the user wants.
  523. set(_MPI_${lang}_COMPILER_NAMES ${MPI_${lang}_COMPILER})
  524. set(MPI_${lang}_COMPILER "MPI_${lang}_COMPILER-NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
  525. # If the user specifies a compiler, we don't want to try to search libraries either.
  526. set(try_libs FALSE)
  527. endif()
  528. else()
  529. set(try_libs TRUE)
  530. endif()
  531. find_program(MPI_${lang}_COMPILER
  532. NAMES ${_MPI_${lang}_COMPILER_NAMES}
  533. HINTS ${_MPI_BASE_DIR}/bin
  534. PATHS ${_MPI_PREFIX_PATH}
  535. )
  536. interrogate_mpi_compiler(${lang} ${try_libs})
  537. mark_as_advanced(MPI_${lang}_COMPILER)
  538. # last ditch try -- if nothing works so far, just try running the regular compiler and
  539. # see if we can create an MPI executable.
  540. set(regular_compiler_worked 0)
  541. if (NOT MPI_${lang}_LIBRARIES OR NOT MPI_${lang}_INCLUDE_PATH)
  542. try_regular_compiler(${lang} regular_compiler_worked)
  543. endif()
  544. set(MPI_${lang}_FIND_QUIETLY ${MPI_FIND_QUIETLY})
  545. set(MPI_${lang}_FIND_REQUIRED ${MPI_FIND_REQUIRED})
  546. set(MPI_${lang}_FIND_VERSION ${MPI_FIND_VERSION})
  547. set(MPI_${lang}_FIND_VERSION_EXACT ${MPI_FIND_VERSION_EXACT})
  548. if (regular_compiler_worked)
  549. find_package_handle_standard_args(MPI_${lang} DEFAULT_MSG MPI_${lang}_COMPILER)
  550. else()
  551. find_package_handle_standard_args(MPI_${lang} DEFAULT_MSG MPI_${lang}_LIBRARIES MPI_${lang}_INCLUDE_PATH)
  552. endif()
  553. endif()
  554. endforeach()
  555. #=============================================================================
  556. # More backward compatibility stuff
  557. #
  558. # Bare MPI sans ${lang} vars are set to CXX then C, depending on what was found.
  559. # This mimics the behavior of the old language-oblivious FindMPI.
  560. set(_MPI_OLD_VARS FOUND COMPILER INCLUDE_PATH COMPILE_FLAGS LINK_FLAGS LIBRARIES)
  561. if (MPI_CXX_FOUND)
  562. foreach (var ${_MPI_OLD_VARS})
  563. set(MPI_${var} ${MPI_CXX_${var}})
  564. endforeach()
  565. elseif (MPI_C_FOUND)
  566. foreach (var ${_MPI_OLD_VARS})
  567. set(MPI_${var} ${MPI_C_${var}})
  568. endforeach()
  569. else()
  570. # Note that we might still have found Fortran, but you'll need to use MPI_Fortran_FOUND
  571. set(MPI_FOUND FALSE)
  572. endif()
  573. # Chop MPI_LIBRARIES into the old-style MPI_LIBRARY and MPI_EXTRA_LIBRARY, and set them in cache.
  574. if (MPI_LIBRARIES)
  575. list(GET MPI_LIBRARIES 0 MPI_LIBRARY_WORK)
  576. set(MPI_LIBRARY ${MPI_LIBRARY_WORK} CACHE FILEPATH "MPI library to link against" FORCE)
  577. else()
  578. set(MPI_LIBRARY "MPI_LIBRARY-NOTFOUND" CACHE FILEPATH "MPI library to link against" FORCE)
  579. endif()
  580. list(LENGTH MPI_LIBRARIES MPI_NUMLIBS)
  581. if (MPI_NUMLIBS GREATER 1)
  582. set(MPI_EXTRA_LIBRARY_WORK ${MPI_LIBRARIES})
  583. list(REMOVE_AT MPI_EXTRA_LIBRARY_WORK 0)
  584. set(MPI_EXTRA_LIBRARY ${MPI_EXTRA_LIBRARY_WORK} CACHE STRING "Extra MPI libraries to link against" FORCE)
  585. else()
  586. set(MPI_EXTRA_LIBRARY "MPI_EXTRA_LIBRARY-NOTFOUND" CACHE STRING "Extra MPI libraries to link against" FORCE)
  587. endif()
  588. #=============================================================================
  589. # unset these vars to cleanup namespace
  590. unset(_MPI_OLD_VARS)
  591. unset(_MPI_PREFIX_PATH)
  592. unset(_MPI_BASE_DIR)
  593. foreach (lang C CXX Fortran)
  594. unset(_MPI_${lang}_COMPILER_NAMES)
  595. endforeach()