FindMPI.cmake 24 KB

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