diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..3ee4c074 --- /dev/null +++ b/.gitignore @@ -0,0 +1,174 @@ +### Emacs template +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# Flymake-mode +*_flymake.* + +# Eshell files +/eshell/history +/eshell/lastdir + +# ELPA packages +/elpa/ + +# Reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# Cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# Server auth directory +/server/ + +# Projectiles files +.projectile + +# Directory configuration +.dir-locals.el + +# Network security +/network-security.data + + +### Visual Studio Code template +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +### C++ template +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +### Fortran template +# Prerequisites + +# Compiled Object files + +# Precompiled Headers + +# Compiled Dynamic libraries + +# Fortran module files + +# Compiled Static libraries + +# Executables + +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/ + +# CMake +cmake-build-*/ + +# File-based project format +*.iws + +# IntelliJ IDEA +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +### Vim template +# Swap +[._]*.s[a-v][a-z] +!*.svg # Comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +### CMake template +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps + +### Build directory +build/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 0513e9ff..16954847 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,4 +8,4 @@ ### Commits to master ### -DD/MM/YYYY PR #NNN: +30/11/2021 PR #1: Add basic build system, unit-testing, and Doxygen documentation. diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..8ea79443 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,65 @@ +# Set the minimum version of CMake required by the build system. +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) + +# Include file containing in-source build prevention. +include(cmake/PreventInSourceBuilds.cmake) + +# Set project name and the languages required to build the project and a +# project description. +project(profiler LANGUAGES CXX + DESCRIPTION "Met Office profiler") + +# Set project versioning. +# TODO - Issue #12 Move versioning to the project settings above. +set(SOVERSION 0) +set(VERSION 0.1.0) + +# Include general project setting files. +include(cmake/StandardProjectSettings.cmake) +include(cmake/CompilerWarnings.cmake) +include(cmake/Doxygen.cmake) +enable_doxygen() + +# Trick to make it easier to add warnings and options to libs/executables. +add_library(project_options INTERFACE) +add_library(project_warnings INTERFACE) +set_project_warnings(project_warnings) + +# Defines some standard install directories such as $(prefix)/include. +include(GNUInstallDirs) + +# Add src directory to build. +add_subdirectory(src) + +# Include the testing setup. +include(cmake/TestingSetup.cmake) + +# All below is for installation and creation of *.cmake files for use with the +# find_package cmake function. +# TODO - Issue #13 Move installation functionality to file in cmake directory. +install( + EXPORT "${CMAKE_PROJECT_NAME}Targets" + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME} + NAMESPACE ${CMAKE_PROJECT_NAME}:: + FILE "${CMAKE_PROJECT_NAME}Targets.cmake" + ) + +include(CMakePackageConfigHelpers) +configure_package_config_file( + "${CMAKE_PROJECT_NAME}Config.cmake.in" + "${CMAKE_PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME}" + PATH_VARS CMAKE_INSTALL_LIBDIR + ) + +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}ConfigVersion.cmake" + VERSION ${VERSION} + COMPATIBILITY SameMajorVersion +) + +install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}ConfigVersion.cmake" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME}" + ) diff --git a/LICENSE b/LICENCE similarity index 100% rename from LICENSE rename to LICENCE diff --git a/README.md b/README.md index 55caf77b..23a2168b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,31 @@ # profiler + Profiler for scientific code on HPC platforms. + +### Requirements + +- C++17 compatible compiler. +- CMake version 3.13 or newer. +- GoogleTest version 1.11 or newer. + +### Supported Compilers + +The code has been tested with the following compilers: +- GCC versions: 9.2.0, 10.2.0. + +### Testing Framework and Documentation + +The testing framework is GoogleTest (1.11.0). +Source code documentation is generated using Doxygen (minimum 1.8.5). + +### Building profiler + +**To build:** +In project root directory: +~~~~~~~~~~~~~~~~shell +mkdir build +cd build +cmake .. +make +make test +~~~~~~~~~~~~~~~~ diff --git a/cmake/CompilerWarnings.cmake b/cmake/CompilerWarnings.cmake new file mode 100644 index 00000000..650ff1a5 --- /dev/null +++ b/cmake/CompilerWarnings.cmake @@ -0,0 +1,90 @@ +# Contains a function for setting up the appropriate warnings for +# different compilers and build settings. +function(set_project_warnings project_name) + # Create option for forcing errors for all warnings. + option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF) + + # Create option to turn on sanitizers. + option(USE_SANITIZERS "Turn on sanitizers to help reporting of runtime errors" OFF) + + set(CLANG_WARNINGS + # All warnings (actually not all warnings obviously) + -Wall + # More warnings (should be used on non-legacy code) + -Wextra + # Warn the user if a variable declaration shadows one from a parent context + -Wshadow + # Warn the user if a class with virtual functions has a non-virtual destructor. + # This helps catch hard to track down memory errors + -Wnon-virtual-dtor + # Warn for C-style casts + -Wold-style-cast + # Warn for potential performance problem casts + -Wcast-align + # Warn on anything being unused + -Wunused + # Warn if you overload (not override) a virtual function + -Woverloaded-virtual + # Warn if non-standard C++ is used + -Wpedantic + # Warn on type conversions that may lose data + -Wconversion + # Warn on sign conversions + -Wsign-conversion + # Warn if a null dereference is detected + -Wnull-dereference + # Warn if float is implicit promoted to double + -Wdouble-promotion + # Warn on security issues around functions that format output (i.e. 'printf') + -Wformat=2 + ) + + # Set warnings as errors if requested (recommended during development/debug) + if (WARNINGS_AS_ERRORS) + set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror) + endif () + + set(GCC_WARNINGS + # Include all Clang compiler warnings (uses same flags as g++) + ${CLANG_WARNINGS} + # Warn if indentation implies blocks where blocks do not exist + -Wmisleading-indentation + # Warn if 'if / else' chain has duplicated conditions + -Wduplicated-cond + # Warn if 'if / else' branches have duplicated code + -Wduplicated-branches + # Warn about logical operations being used where bitwise were probably wanted + -Wlogical-op + # Warn if you perform a cast to the same type + -Wuseless-cast + ) + + # Set compiler and linker flags depending on compiler + if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + if(USE_SANITIZERS) + # Set Clang sanitizers for memory errors/leaks and undefined behaviour + set(CLANG_WARNINGS -fsanitize=address,undefined ${CLANG_WARNINGS}) + set(CLANG_LINKER_FLAGS -fsanitize=address,undefined) + endif() + set(PROJECT_WARNINGS ${CLANG_WARNINGS}) + set(LINKER_FLAGS ${CLANG_LINKER_FLAGS}) + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(USE_SANITIZERS) + # Get GCC sanitizers for memory errors/leaks, undefined behaviour and pointer operands + set(GCC_WARNINGS + -fsanitize=address,undefined,leak,pointer-compare,pointer-subtract + ${GCC_WARNINGS}) + set(GCC_LINKER_FLAGS + -fsanitize=address,undefined,leak,pointer-compare,pointer-subtract) + endif() + set(PROJECT_WARNINGS ${GCC_WARNINGS}) + set(LINKER_FLAGS ${GCC_LINKER_FLAGS}) + else () + message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.") + endif () + + # Add compiler and linker flags to project_warnings + target_compile_options(project_warnings INTERFACE ${PROJECT_WARNINGS}) + target_link_options(project_warnings INTERFACE ${LINKER_FLAGS}) + +endfunction() diff --git a/cmake/Doxygen.cmake b/cmake/Doxygen.cmake new file mode 100644 index 00000000..1073127a --- /dev/null +++ b/cmake/Doxygen.cmake @@ -0,0 +1,36 @@ +# This file sets up the options for the Doxygen generation of API documentation. +# Available options for CMake Doxygen integration can be found here: +# https://cmake.org/cmake/help/latest/module/FindDoxygen.html +function(enable_doxygen) + option(ENABLE_DOXYGEN "Enable doxygen doc builds of source" ON) + if (ENABLE_DOXYGEN) + set(DOXYGEN_CALLER_GRAPH YES) + set(DOXYGEN_CALL_GRAPH YES) + set(DOXYGEN_EXTRACT_ALL YES) + set(DOXYGEN_PRIVATE YES) + set(DOXYGEN_GENERATE_LATEX YES) + set(DOXYGEN_LATEX_OUTPUT pdf) + set(DOXYGEN_MARKDOWN_SUPPORT YES) + set(DOXYGEN_HIDE_SCOPE_NAMES YES) + set(DOXYGEN_PROJECT_NAME "${CMAKE_PROJECT_NAME}") + set(DOXYGEN_PROJECT_NUMBER "v${VERSION}") + set(DOXYGEN_DISABLE_INDEX NO) + set(DOXYGEN_GENERATE_TREEVIEW YES) + set(DOXYGEN_JAVADOC_BANNER NO) + set(DOXYGEN_JAVADOC_AUTOBRIEF NO) + set(DOXYGEN_JAVADOC_BLOCK NO) + set(DOXYGEN_FULL_PATH_NAMES NO) + set(DOXYGEN_STRIP_CODE_COMMENTS NO) + set(DOXYGEN_HTML_HEADER ${PROJECT_SOURCE_DIR}/documentation/Doxygen/html/header.html) + set(DOXYGEN_HTML_FOOTER ${PROJECT_SOURCE_DIR}/documentation/Doxygen/html/footer.html) + + # Find the Doxygen application install (requires "dot" tool). + find_package(Doxygen REQUIRED dot) + + # Set up Doxygen build with source directory and additional pages. + doxygen_add_docs(doxygen-docs ${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/documentation/Doxygen ALL) + + # Set up installation destination. + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/docs) + endif () +endfunction() diff --git a/cmake/PreventInSourceBuilds.cmake b/cmake/PreventInSourceBuilds.cmake new file mode 100644 index 00000000..9309d992 --- /dev/null +++ b/cmake/PreventInSourceBuilds.cmake @@ -0,0 +1,18 @@ +# This function will prevent in-source builds +function(AssureOutOfSourceBuilds) + # Make sure the user doesn't perform in-source builds by tricking + # the build system through the use of symlinks + get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) + get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) + + # Disallow in-source builds + if ("${srcdir}" STREQUAL "${bindir}") + message("######################################################") + message("Warning: in-source builds are disabled") + message("Please create a separate build directory and run cmake from there") + message("######################################################") + message(FATAL_ERROR "Quitting configuration") + endif () +endfunction() + +AssureOutOfSourceBuilds() diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake new file mode 100644 index 00000000..31e2e003 --- /dev/null +++ b/cmake/StandardProjectSettings.cmake @@ -0,0 +1,50 @@ +# Some basic project settings for defaults such as build type and installation +# prefix. + +# Set C++ standard compliance. +set(CMAKE_CXX_STANDARD 17) + +# Set a default build type if none was specified. +if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.") + set(CMAKE_BUILD_TYPE + RelWithDebInfo + CACHE STRING "Choose the type of build." FORCE) + # Set the possible values of build type for cmake-gui, ccmake. + set_property( + CACHE CMAKE_BUILD_TYPE + PROPERTY STRINGS + # These build type options set the listed compiler options. + # These are CMake default flags for C++. + "Debug" # -g + "Release" # -O3 -DNDEBUG + "MinSizeRel" # -Os -DNDEBUG + "RelWithDebInfo" # -O2 -g -DNDEBUG + ) +endif () + +# Generate compile_commands.json to make it easier to work with Clang-based tools. +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Interprocedural optimisation is useful for improving program performance through +# analysis of the entire program rather than just single program units. +option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" OFF) + +if (ENABLE_IPO) + include(CheckIPOSupported) + check_ipo_supported( + RESULT + result + OUTPUT + output) + if (result) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + else () + message(SEND_ERROR "IPO is not supported: ${output}") + endif () +endif () + +# Set default install location to be in build directory rather than /usr/bin etc. +if (${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT}) + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE PATH "..." FORCE) +endif () diff --git a/cmake/TestingSetup.cmake b/cmake/TestingSetup.cmake new file mode 100644 index 00000000..8ba55173 --- /dev/null +++ b/cmake/TestingSetup.cmake @@ -0,0 +1,10 @@ +# Enable CTest integration with GoogleTest and add a directory for the tests + +# Find required testing packages +find_package(GTest REQUIRED) +include(GoogleTest) + +# Enable CTest +enable_testing() + +add_subdirectory(tests) diff --git a/documentation/Doxygen/Profiler.md b/documentation/Doxygen/Profiler.md new file mode 100644 index 00000000..d1cccf27 --- /dev/null +++ b/documentation/Doxygen/Profiler.md @@ -0,0 +1,38 @@ +Documentation {#mainpage} +============= +[TOC] + +# Introduction {#Introduction} + +This is a profiling tool written in C++ and designed for use with the Unified +Model and LFRic. +The current implementation is a work in progress. + +# Metrics {#metrics} + +The metrics to be included are going to be based on Performance Optimisation +and Productivity (POP) Standard Metrics +for Parallel Performance Analysis. + +## Load Balance {#lb} + +~~~~~~~~~~~~~~~~~~~~~~~cpp +class A { + private: + int a_; + + public: + // Constructor + A(int a):a_(a){}; + + // Destructor + ~A; + + // Getter + int get_a(){return a_;} +}; +~~~~~~~~~~~~~~~~~~~~~~~ + +## Communication Efficiency {#comme} + +TBD \ No newline at end of file diff --git a/documentation/Doxygen/html/footer.html b/documentation/Doxygen/html/footer.html new file mode 100644 index 00000000..dab72aab --- /dev/null +++ b/documentation/Doxygen/html/footer.html @@ -0,0 +1,21 @@ + + + +
+ + +