From c1d34025c9a4d8ad90d1129aa34b31ecb44d799b Mon Sep 17 00:00:00 2001 From: Paul Bauer Date: Wed, 27 Nov 2019 16:35:16 +0100 Subject: [PATCH] Check for using correct hwloc headers and runtime Also add assertion in the code to prevent errors from linking against the wrong library while running. Fixes #3200 Change-Id: Ib2f2861702e111f67c38b0c9d65ccbe4c81a0ccd --- cmake/FindHwloc.cmake | 45 ++++++++++++++++++++----------- docs/release-notes/2019/2019.5.rst | 9 +++++++ src/config.h.cmakein | 5 +++- src/gromacs/hardware/hardwaretopology.cpp | 28 +++++++++++++------ 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/cmake/FindHwloc.cmake b/cmake/FindHwloc.cmake index 8bfb9cd616..8eda2a4c5e 100644 --- a/cmake/FindHwloc.cmake +++ b/cmake/FindHwloc.cmake @@ -1,7 +1,7 @@ # # This file is part of the GROMACS molecular simulation package. # -# Copyright (c) 2015,2016,2017,2018, by the GROMACS development team, led by +# Copyright (c) 2015,2016,2017,2018,2019, by the GROMACS development team, led by # Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, # and including many others, as listed in the AUTHORS file in the # top-level source directory and at http://www.gromacs.org. @@ -97,7 +97,7 @@ if(HWLOC_INCLUDE_DIRS) message(STATUS "Error executing hwloc-info: ${HWLOC_INFO_ERR}") endif() string(REGEX MATCH "[0-9]+.*[0-9]+" HWLOC_INFO_OUT "${HWLOC_INFO_OUT}") - set(HWLOC_VERSION ${HWLOC_INFO_OUT} CACHE STRING "Hwloc library version") + set(HWLOC_LIBRARY_VERSION ${HWLOC_INFO_OUT} CACHE STRING "Hwloc library version") endif() endif() @@ -106,20 +106,35 @@ if(HWLOC_INCLUDE_DIRS) endif() # Parse header if cross-compiling, or if hwloc-info was not found - if(NOT HWLOC_VERSION) - # Hwloc is never installed as a framework on OS X, so this should always work. - file(READ "${HWLOC_INCLUDE_DIRS}/hwloc.h" - HEADER_CONTENTS LIMIT 16384) - string(REGEX REPLACE ".*#define HWLOC_API_VERSION (0[xX][0-9a-fA-F]+).*" "\\1" - HWLOC_API_VERSION "${HEADER_CONTENTS}") - string(SUBSTRING "${HWLOC_API_VERSION}" 4 2 HEX_MAJOR) - string(SUBSTRING "${HWLOC_API_VERSION}" 6 2 HEX_MINOR) - string(SUBSTRING "${HWLOC_API_VERSION}" 8 2 HEX_PATCH) - hex2dec(${HEX_MAJOR} DEC_MAJOR) - hex2dec(${HEX_MINOR} DEC_MINOR) - hex2dec(${HEX_PATCH} DEC_PATCH) - set(HWLOC_VERSION "${DEC_MAJOR}.${DEC_MINOR}.${DEC_PATCH}" CACHE STRING "Hwloc library version") + # Also used to check that library and header versions match + # HWLOC is never installed as a framework on OS X, so this should always work. + file(READ "${HWLOC_INCLUDE_DIRS}/hwloc.h" + HEADER_CONTENTS LIMIT 16384) + string(REGEX REPLACE ".*#define HWLOC_API_VERSION (0[xX][0-9a-fA-F]+).*" "\\1" + HWLOC_API_VERSION "${HEADER_CONTENTS}") + string(SUBSTRING "${HWLOC_API_VERSION}" 4 2 HEX_MAJOR) + string(SUBSTRING "${HWLOC_API_VERSION}" 6 2 HEX_MINOR) + string(SUBSTRING "${HWLOC_API_VERSION}" 8 2 HEX_PATCH) + hex2dec(${HEX_MAJOR} DEC_MAJOR) + hex2dec(${HEX_MINOR} DEC_MINOR) + hex2dec(${HEX_PATCH} DEC_PATCH) + set(HWLOC_HEADER_VERSION "${DEC_MAJOR}.${DEC_MINOR}.${DEC_PATCH}") + if (HWLOC_LIBRARY_VERSION AND HWLOC_HEADER_VERSION) + string(SUBSTRING "${HWLOC_LIBRARY_VERSION}" 0 1 LIBRARY_MAJOR) + string(SUBSTRING "${HWLOC_HEADER_VERSION}" 0 1 HEADER_MAJOR) + string(COMPARE EQUAL "${LIBRARY_MAJOR}" "${HEADER_MAJOR}" HWLOC_VERSION_CHECK) + if(NOT HWLOC_VERSION_CHECK) + message(FATAL_ERROR "Detected version mismatch between HWLOC headers and library. " + "Library version is ${HWLOC_LIBRARY_VERSION}, but header version is ${HWLOC_HEADER_VERSION}. " + "Make sure that you have the correct include and library directory set for HWLOC") + endif() + endif() + if (HWLOC_LIBRARY_VERSION) + set(HWLOC_VERSION ${HWLOC_LIBRARY_VERSION} CACHE STRING "HWLOC library version") + else() + set(HWLOC_VERSION ${HWLOC_HEADER_VERSION} CACHE STRING "HWLOC library version") endif() + set(GMX_HWLOC_API_VERSION ${HWLOC_API_VERSION} CACHE STRING "HWLOC API version during configuration time") endif() include(FindPackageHandleStandardArgs) diff --git a/docs/release-notes/2019/2019.5.rst b/docs/release-notes/2019/2019.5.rst index 474ceb9053..5f2530099e 100644 --- a/docs/release-notes/2019/2019.5.rst +++ b/docs/release-notes/2019/2019.5.rst @@ -90,6 +90,15 @@ which was not clear for users. Fixes that affect portability ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Check that libhwloc headers and runtime match +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +It could happen that the libhwloc headers and library detection would +lead to a mismatch at compile or runtime that could cause cryptic +crashes while using mdrun. + +:issue:`3200` + Miscellaneous ^^^^^^^^^^^^^ diff --git a/src/config.h.cmakein b/src/config.h.cmakein index c685f264b5..7824bf636b 100644 --- a/src/config.h.cmakein +++ b/src/config.h.cmakein @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -168,6 +168,9 @@ /* Use the Portable Hardware Locality package (hwloc) */ #cmakedefine01 GMX_USE_HWLOC +/* Library version found for hwloc during configuration time */ +#define GMX_HWLOC_API_VERSION @GMX_HWLOC_API_VERSION@ + /* Can and should use nice(3) to set priority */ #cmakedefine01 GMX_USE_NICE diff --git a/src/gromacs/hardware/hardwaretopology.cpp b/src/gromacs/hardware/hardwaretopology.cpp index ae2ce76706..33c2b3ab7c 100644 --- a/src/gromacs/hardware/hardwaretopology.cpp +++ b/src/gromacs/hardware/hardwaretopology.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -161,11 +161,17 @@ parseCpuInfo(HardwareTopology::Machine * machine, #endif // Preprocessor variable for if hwloc api is version 1.x.x or 2.x.x -#if HWLOC_API_VERSION >= 0x00020000 -# define GMX_HWLOC_API_VERSION_IS_2XX 1 -#else -# define GMX_HWLOC_API_VERSION_IS_2XX 0 -#endif +# if HWLOC_API_VERSION >= 0x00020000 +# define GMX_HWLOC_API_VERSION_IS_2XX 1 +# if GMX_HWLOC_API_VERSION < 0x00020000 +# error "HWLOC library major version set during configuration is 1, but currently using version 2 headers" +# endif +# else +# define GMX_HWLOC_API_VERSION_IS_2XX 0 +# if GMX_HWLOC_API_VERSION >= 0x00020000 +# error "HWLOC library major version set during configuration is 2, but currently using version 1 headers" +# endif +# endif /***************************************************************************** * * @@ -607,9 +613,15 @@ parseHwLoc(HardwareTopology::Machine * machine, } // Flags to look for io devices -#if GMX_HWLOC_API_VERSION_IS_2XX +# if GMX_HWLOC_API_VERSION_IS_2XX + GMX_RELEASE_ASSERT( + (hwloc_get_api_version() >= 0x20000), + "Mismatch between hwloc headers and library, using v2 headers with v1 library"); hwloc_topology_set_io_types_filter(topo, HWLOC_TYPE_FILTER_KEEP_IMPORTANT); -#else +# else + GMX_RELEASE_ASSERT( + (hwloc_get_api_version() < 0x20000), + "Mismatch between hwloc headers and library, using v1 headers with v2 library"); hwloc_topology_set_flags(topo, HWLOC_TOPOLOGY_FLAG_IO_DEVICES); #endif -- 2.11.4.GIT