Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profiling infrastructure #136

Merged
merged 3 commits into from
Mar 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ include(autocmake_ccache)
include(windows)
include(autocmake_definitions)
include(code_coverage)
include(gperftools)
include(autocmake_int64)
include(autocmake_omp)
include(autocmake_safeguards)
Expand Down
1 change: 1 addition & 0 deletions cmake/autocmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ modules:
- 'custom/windows.cmake'
- '%(url_root)modules/definitions.cmake'
- 'custom/code_coverage.cmake'
- 'custom/gperftools.cmake'
- '%(url_root)modules/int64.cmake'
- '%(url_root)modules/omp.cmake'
- '%(url_root)modules/safeguards.cmake'
Expand Down
146 changes: 146 additions & 0 deletions cmake/custom/FindGperftools.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# This file is part of MADNESS
# https://github.com/m-a-d-n-e-s-s/madness/blob/master/cmake/modules/FindGperftools.cmake
#
# - Try to find Google performance tools (gperftools)
# Input variables:
# GPERFTOOLS_ROOT_DIR - The gperftools install directory
# GPERFTOOLS_INCLUDE_DIR - The gperftools include directory
# GPERFTOOLS_LIBRARY - The gperftools library directory
# Components: profiler, and tcmalloc or tcmalloc_minimal
# Output variables:
# GPERFTOOLS_FOUND - System has gperftools
# GPERFTOOLS_INCLUDE_DIRS - The gperftools include directories
# GPERFTOOLS_LIBRARIES - The libraries needed to use gperftools
# GPERFTOOLS_VERSION - The version string for gperftools

include(FindPackageHandleStandardArgs)

if(NOT DEFINED GPERFTOOLS_FOUND)

# Check to see if libunwind is required
set(GPERFTOOLS_DISABLE_PROFILER FALSE)
if((";${Gperftools_FIND_COMPONENTS};" MATCHES ";profiler;") AND
(CMAKE_SYSTEM_NAME MATCHES "Linux" OR
CMAKE_SYSTEM_NAME MATCHES "BlueGeneQ" OR
CMAKE_SYSTEM_NAME MATCHES "BlueGeneP") AND
(CMAKE_SIZEOF_VOID_P EQUAL 8))

# Libunwind is required by profiler on this platform
if(Gperftools_FIND_REQUIRED_profiler OR Gperftools_FIND_REQUIRED_tcmalloc_and_profiler)
find_package(Libunwind 0.99 REQUIRED)
else()
find_package(Libunwind)
if(NOT LIBUNWIND_FOUND OR LIBUNWIND_VERSION VERSION_LESS 0.99)
set(GPERFTOOLS_DISABLE_PROFILER TRUE)
endif()
endif()
endif()

# Check for invalid components
foreach(_comp ${Gperftools_FIND_COMPONENTS})
if((NOT _comp STREQUAL "tcmalloc_and_profiler") AND
(NOT _comp STREQUAL "tcmalloc") AND
(NOT _comp STREQUAL "tcmalloc_minimal") AND
(NOT _comp STREQUAL "profiler"))
message(FATAL_ERROR "Invalid component specified for Gperftools: ${_comp}")
endif()
endforeach()

# Check for valid component combinations
if(";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc_and_profiler;" AND
(";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc;" OR
";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc_minimal;" OR
";${Gperftools_FIND_COMPONENTS};" MATCHES ";profiler;"))
message("ERROR: Invalid component selection for Gperftools: ${Gperftools_FIND_COMPONENTS}")
message("ERROR: Gperftools cannot link both tcmalloc_and_profiler with the tcmalloc, tcmalloc_minimal, or profiler libraries")
message(FATAL_ERROR "Gperftools component list is invalid")
endif()
if(";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc;" AND ";${Gperftools_FIND_COMPONENTS};" MATCHES ";tcmalloc_minimal;")
message("ERROR: Invalid component selection for Gperftools: ${Gperftools_FIND_COMPONENTS}")
message("ERROR: Gperftools cannot link both tcmalloc and tcmalloc_minimal")
message(FATAL_ERROR "Gperftools component list is invalid")
endif()

# Set default sarch paths for gperftools
if(GPERFTOOLS_ROOT_DIR)
set(GPERFTOOLS_INCLUDE_DIR ${GPERFTOOLS_ROOT_DIR}/include CACHE PATH "The include directory for gperftools")
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(GPERFTOOLS_LIBRARY ${GPERFTOOLS_ROOT_DIR}/lib64;${GPERFTOOLS_ROOT_DIR}/lib CACHE PATH "The library directory for gperftools")
else()
set(GPERFTOOLS_LIBRARY ${GPERFTOOLS_ROOT_DIR}/lib CACHE PATH "The library directory for gperftools")
endif()
endif()

find_path(GPERFTOOLS_INCLUDE_DIRS NAMES gperftools/malloc_extension.h
HINTS ${GPERFTOOLS_INCLUDE_DIR})

# Search for component libraries
foreach(_comp tcmalloc_and_profiler tcmalloc tcmalloc_minimal profiler)
find_library(GPERFTOOLS_${_comp}_LIBRARY ${_comp}
HINTS ${GPERFTOOLS_LIBRARY})
if(GPERFTOOLS_${_comp}_LIBRARY)
set(GPERFTOOLS_${_comp}_FOUND TRUE)
else()
set(GPERFTOOLS_${_comp}_FOUND FALSE)
endif()

# Exclude profiler from the found list if libunwind is required but not found
if(GPERFTOOLS_${_comp}_FOUND AND ${_comp} MATCHES "profiler" AND GPERFTOOLS_DISABLE_PROFILER)
set(GPERFTOOLS_${_comp}_FOUND FALSE)
set(GPERFTOOLS_${_comp}_LIBRARY "GPERFTOOLS_${_comp}_LIBRARY-NOTFOUND")
message("WARNING: Gperftools '${_comp}' requires libunwind 0.99 or later.")
message("WARNING: Gperftools '${_comp}' will be disabled.")
endif()

if(";${Gperftools_FIND_COMPONENTS};" MATCHES ";${_comp};" AND GPERFTOOLS_${_comp}_FOUND)
list(APPEND GPERFTOOLS_LIBRARIES "${GPERFTOOLS_${_comp}_LIBRARY}")
endif()
endforeach()

# Set gperftools libraries if not set based on component list
if(NOT GPERFTOOLS_LIBRARIES)
if(GPERFTOOLS_tcmalloc_and_profiler_FOUND)
set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_and_profiler_LIBRARY}")
elseif(GPERFTOOLS_tcmalloc_FOUND AND GPERFTOOLS_profiler_FOUND)
set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_LIBRARY}" "${GPERFTOOLS_profiler_LIBRARY}")
elseif(GPERFTOOLS_profiler_FOUND)
set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_profiler_LIBRARY}")
elseif(GPERFTOOLS_tcmalloc_FOUND)
set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_LIBRARY}")
elseif(GPERFTOOLS_tcmalloc_minimal_FOUND)
set(GPERFTOOLS_LIBRARIES "${GPERFTOOLS_tcmalloc_minimal_LIBRARY}")
endif()
endif()

# handle the QUIETLY and REQUIRED arguments and set GPERFTOOLS_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(GPERFTOOLS
FOUND_VAR GPERFTOOLS_FOUND
REQUIRED_VARS GPERFTOOLS_LIBRARIES GPERFTOOLS_INCLUDE_DIRS
HANDLE_COMPONENTS)

mark_as_advanced(GPERFTOOLS_INCLUDE_DIR GPERFTOOLS_LIBRARY
GPERFTOOLS_INCLUDE_DIRS GPERFTOOLS_LIBRARIES)

# Add linker flags that instruct the compiler to exclude built in memory
# allocation functions. This works for GNU, Intel, and Clang. Other compilers
# may need to be added in the future.
if(GPERFTOOLS_LIBRARIES MATCHES "tcmalloc")
if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") OR
(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") OR
(CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR
((CMAKE_CXX_COMPILER_ID MATCHES "Intel") AND (NOT CMAKE_CXX_PLATFORM_ID MATCHES "Windows")))
list(APPEND GPERFTOOLS_LIBRARIES "-fno-builtin-malloc"
"-fno-builtin-calloc" "-fno-builtin-realloc" "-fno-builtin-free")
endif()
endif()

# Add libunwind flags to gperftools if the profiler is being used
if(GPERFTOOLS_LIBRARIES MATCHES "profiler" AND LIBUNWIND_FOUND)
list(APPEND GPERFTOOLS_INCLUDE_DIRS "${LIBUNWIND_INCLUDE_DIRS}")
list(APPEND GPERFTOOLS_LIBRARIES "${LIBUNWIND_LIBRARIES}")
endif()

unset(GPERFTOOLS_DISABLE_PROFILER)

endif()
58 changes: 58 additions & 0 deletions cmake/custom/FindLibunwind.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# This file is part of MADNESS
# https://github.com/m-a-d-n-e-s-s/madness/blob/master/cmake/modules/FindLibunwind.cmake
#
# - Try to find Libunwind
# Input variables:
# LIBUNWIND_ROOT_DIR - The libunwind install directory
# LIBUNWIND_INCLUDE_DIR - The libunwind include directory
# LIBUNWIND_LIBRARY - The libunwind library directory
# Output variables:
# LIBUNWIND_FOUND - System has libunwind
# LIBUNWIND_INCLUDE_DIRS - The libunwind include directories
# LIBUNWIND_LIBRARIES - The libraries needed to use libunwind
# LIBUNWIND_VERSION - The version string for libunwind

include(FindPackageHandleStandardArgs)

if(NOT DEFINED LIBUNWIND_FOUND)

# Set default sarch paths for libunwind
if(LIBUNWIND_ROOT_DIR)
set(LIBUNWIND_INCLUDE_DIR ${LIBUNWIND_ROOT_DIR}/include CACHE PATH "The include directory for libunwind")
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(LIBUNWIND_LIBRARY ${LIBUNWIND_ROOT_DIR}/lib64;${LIBUNWIND_ROOT_DIR}/lib CACHE PATH "The library directory for libunwind")
else()
set(LIBUNWIND_LIBRARY ${LIBUNWIND_ROOT_DIR}/lib CACHE PATH "The library directory for libunwind")
endif()
endif()

find_path(LIBUNWIND_INCLUDE_DIRS NAMES libunwind.h
HINTS ${LIBUNWIND_INCLUDE_DIR})

find_library(LIBUNWIND_LIBRARIES unwind
HINTS ${LIBUNWIND_LIBRARY})

# Get libunwind version
if(EXISTS "${LIBUNWIND_INCLUDE_DIRS}/libunwind-common.h")
file(READ "${LIBUNWIND_INCLUDE_DIRS}/libunwind-common.h" _libunwind_version_header)
string(REGEX REPLACE ".*define[ \t]+UNW_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1"
LIBUNWIND_MAJOR_VERSION "${_libunwind_version_header}")
string(REGEX REPLACE ".*define[ \t]+UNW_VERSION_MINOR[ \t]+([0-9]+).*" "\\1"
LIBUNWIND_MINOR_VERSION "${_libunwind_version_header}")
string(REGEX REPLACE ".*define[ \t]+UNW_VERSION_EXTRA[ \t]+([0-9]+).*" "\\1"
LIBUNWIND_MICRO_VERSION "${_libunwind_version_header}")
set(LIBUNWIND_VERSION "${LIBUNWIND_MAJOR_VERSION}.${LIBUNWIND_MINOR_VERSION}.${LIBUNWIND_MICRO_VERSION}")
unset(_libunwind_version_header)
endif()

# handle the QUIETLY and REQUIRED arguments and set LIBUNWIND_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(Libunwind
FOUND_VAR LIBUNWIND_FOUND
VERSION_VAR LIBUNWIND_VERSION
REQUIRED_VARS LIBUNWIND_LIBRARIES LIBUNWIND_INCLUDE_DIRS)

mark_as_advanced(LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARY
LIBUNWIND_INCLUDE_DIRS LIBUNWIND_LIBRARIES)

endif()
19 changes: 19 additions & 0 deletions cmake/custom/gperftools.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#.rst:
#
# Enable profiling with gperftools.
#
# Variables used::
#
# ENABLE_GPERFTOOLS
#
# autocmake.yml configuration::
#
# docopt: "--gperf Enable profiling with gperftools [default: False]."
# define: "'-DENABLE_GPERFTOOLS={0}'.format(arguments['--gperf'])"

option_with_print(ENABLE_GPERFTOOLS "Enable profiling with gperftools" OFF)

if(ENABLE_GPERFTOOLS)
message(STATUS "Linking against gperftools libraries for profiling")
find_package(Gperftools COMPONENTS tcmalloc profiler)
endif()
Loading