From 422600a8496aa92673b74a31fb943fb5acb9307e Mon Sep 17 00:00:00 2001 From: andrewcoughtrie <24609575+andrewcoughtrie@users.noreply.github.com> Date: Wed, 27 Oct 2021 11:51:57 +0100 Subject: [PATCH 01/30] Basic build system, unit-testing, and Doxygen documentation. --- .gitignore | 216 +++++++++++++++++++++++++ CMakeLists.txt | 55 +++++++ README.md | 15 ++ cmake/CompilerWarnings.cmake | 55 +++++++ cmake/Doxygen.cmake | 27 ++++ cmake/PreventInSourceBuilds.cmake | 18 +++ cmake/StandardProjectSettings.cmake | 42 +++++ cmake/TestingSetup.cmake | 2 + documentation/Doxygen/Profiler.md | 35 ++++ documentation/Doxygen/html/footer.html | 21 +++ documentation/Doxygen/html/header.html | 55 +++++++ profilerConfig.cmake.in | 2 + src/CMakeLists.txt | 22 +++ src/profiler.h | 6 + tests/CMakeLists.txt | 14 ++ tests/hello_test.cpp | 18 +++ 16 files changed, 603 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 cmake/CompilerWarnings.cmake create mode 100644 cmake/Doxygen.cmake create mode 100644 cmake/PreventInSourceBuilds.cmake create mode 100644 cmake/StandardProjectSettings.cmake create mode 100644 cmake/TestingSetup.cmake create mode 100644 documentation/Doxygen/Profiler.md create mode 100644 documentation/Doxygen/html/footer.html create mode 100644 documentation/Doxygen/html/header.html create mode 100644 profilerConfig.cmake.in create mode 100644 src/CMakeLists.txt create mode 100644 src/profiler.h create mode 100644 tests/CMakeLists.txt create mode 100644 tests/hello_test.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..00e3fe11 --- /dev/null +++ b/.gitignore @@ -0,0 +1,216 @@ +### 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 + + +### VisualStudioCode 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/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### 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 \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..db01eb68 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,55 @@ +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) +include(cmake/PreventInSourceBuilds.cmake) + +project(profiler LANGUAGES CXX + DESCRIPTION "Met Office Profiler") + +set(SOVERSION 0) +set(VERSION 0.1.0) + +include(cmake/StandardProjectSettings.cmake) +include(cmake/CompilerWarnings.cmake) +include(cmake/Doxygen.cmake) +enable_doxygen() + +add_library(project_options INTERFACE) +add_library(project_warnings INTERFACE) +set_project_warnings(project_warnings) + +# Find required packages +find_package(GTest REQUIRED) +include(GoogleTest) + +include(GNUInstallDirs) + +add_subdirectory(src) + +include(cmake/TestingSetup.cmake) + +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/README.md b/README.md index 55caf77b..1d4d97f2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ # profiler Profiler for scientific code on HPC platforms. + +## Building +Requires a c++17 compatible compiler, currently only tested with GCC-9.2.0. + +The testing framework is GoogleTest (1.11.0) and source code documentation is created using Doxygen (1.8.5). + +**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..6354e028 --- /dev/null +++ b/cmake/CompilerWarnings.cmake @@ -0,0 +1,55 @@ +function(set_project_warnings project_name) + option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF) + + set(CLANG_WARNINGS + -Wall + -Wextra # reasonable and standard + -Wshadow # warn the user if a variable declaration shadows one from a parent context + -Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps + # catch hard to track down memory errors + -Wold-style-cast # warn for c-style casts + -Wcast-align # warn for potential performance problem casts + -Wunused # warn on anything being unused + -Woverloaded-virtual # warn if you overload (not override) a virtual function + -Wpedantic # warn if non-standard C++ is used + -Wconversion # warn on type conversions that may lose data + -Wsign-conversion # warn on sign conversions + -Wnull-dereference # warn if a null dereference is detected + -Wdouble-promotion # warn if float is implicit promoted to double + -Wformat=2 # warn on security issues around functions that format output (ie printf) + ) + + if (WARNINGS_AS_ERRORS) + set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror) + endif () + + set(GCC_WARNINGS + -fsanitize=address,undefined,leak,pointer-compare,pointer-subtract + ${CLANG_WARNINGS} + -Wmisleading-indentation # warn if indentation implies blocks where blocks do not exist + -Wduplicated-cond # warn if if / else chain has duplicated conditions + -Wduplicated-branches # warn if if / else branches have duplicated code + -Wlogical-op # warn about logical operations being used where bitwise were probably wanted + -Wuseless-cast # warn if you perform a cast to the same type + ) + + set(CLANG_LINKER_FLAGS + -fsanitize=address,undefined) + + set(GCC_LINKER_FLAGS + -fsanitize=address,undefined,leak,pointer-compare,pointer-subtract) + + if (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") + set(PROJECT_WARNINGS ${CLANG_WARNINGS}) + set(LINKER_FLAGS ${CLANG_LINKER_FLAGS}) + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + 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 () + + target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS}) + target_link_options(${project_name} INTERFACE ${LINKER_FLAGS}) + +endfunction() \ No newline at end of file diff --git a/cmake/Doxygen.cmake b/cmake/Doxygen.cmake new file mode 100644 index 00000000..167e3bd7 --- /dev/null +++ b/cmake/Doxygen.cmake @@ -0,0 +1,27 @@ +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_HIDE_SCOPE_NAMES YES) + set(DOXYGEN_PROJECT_NAME "Profiler") + 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) +# set(DOXYGEN_HTML_STYLESHEET ${PROJECT_SOURCE_DIR}/documentation/Doxygen/customdoxygen.css) + find_package(Doxygen REQUIRED dot) + doxygen_add_docs(doxygen-docs ${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/documentation/Doxygen ALL) + install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/docs) + endif () +endfunction() \ No newline at end of file diff --git a/cmake/PreventInSourceBuilds.cmake b/cmake/PreventInSourceBuilds.cmake new file mode 100644 index 00000000..d3cee97a --- /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 play dirty with 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() \ No newline at end of file diff --git a/cmake/StandardProjectSettings.cmake b/cmake/StandardProjectSettings.cmake new file mode 100644 index 00000000..bc980ad8 --- /dev/null +++ b/cmake/StandardProjectSettings.cmake @@ -0,0 +1,42 @@ +# 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 + "Debug" + "Debug-Coverage" + "Release" + "MinSizeRel" + "RelWithDebInfo") +endif () + +# Generate compile_commands.json to make it easier to work with clang based tools +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +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 () + +if(${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT}) + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}" CACHE PATH "..." FORCE) +endif() \ No newline at end of file diff --git a/cmake/TestingSetup.cmake b/cmake/TestingSetup.cmake new file mode 100644 index 00000000..5cba7816 --- /dev/null +++ b/cmake/TestingSetup.cmake @@ -0,0 +1,2 @@ +enable_testing() +add_subdirectory(tests) diff --git a/documentation/Doxygen/Profiler.md b/documentation/Doxygen/Profiler.md new file mode 100644 index 00000000..44960adf --- /dev/null +++ b/documentation/Doxygen/Profiler.md @@ -0,0 +1,35 @@ +Documentation {#mainpage} +============= +[TOC] + +# Introduction {#Introduction} +This is a profiling tool written in C++ 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 + void get_a(){return a_;} +}; +~~~~~~~~~~~~~~~~~~~~~~~ + +## Communication Efficiency {#comme} + \ 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..1ea92c85 --- /dev/null +++ b/documentation/Doxygen/html/footer.html @@ -0,0 +1,21 @@ + + + +
+ + +