Skip to content

Follow standard CMake layout#214

Open
EmilyBourne wants to merge 24 commits intomainfrom
ebourne_cleanup_cmake
Open

Follow standard CMake layout#214
EmilyBourne wants to merge 24 commits intomainfrom
ebourne_cleanup_cmake

Conversation

@EmilyBourne
Copy link
Copy Markdown
Collaborator

@EmilyBourne EmilyBourne commented Apr 20, 2026

Clean up CMake files to follow standard practice. In particular:

  • All find_package calls are moved to the root CMakeLists.txt so dependencies are easy to locate
  • Definitions of installed dependencies are moved to dedicated cmake/FindX.cmake files so they can be located via a standard find_package call
    • LIKWID
    • MUMPS
    • Metis (via MUMPS)
  • Definition of the C++ standard is moved to the root of the project
  • The target InputFunctions (which is only required for testing and for the CLI) is removed from the GMGPolarLib target
  • The target GMGPolarInterface is added to group example input functions and other tools required for the command line interface.
  • The condition if(OpenMP_CXX_FOUND) is removed as OpenMP is a required dependency so this should always be True
  • Relative paths are avoided. Instead CMake ensures that the include/ folder is included via the compile command
  • Add an install target to allow GMGPolar to be installed on a system and included via find_package(GMGPolar)

Merge Request - GuideLine Checklist

Guideline to check code before resolve WIP and approval, respectively.
As many checkboxes as possible should be ticked.

Checks by code author:

Always to be checked:

  • There is at least one issue associated with the pull request.
  • New code adheres with the coding guidelines
  • No large data files have been added to the repository. Maximum size for files should be of the order of KB not MB. In particular avoid adding of pdf, word, or other files that cannot be change-tracked correctly by git.

If functions were changed or functionality was added:

  • Tests for new functionality has been added
  • A local test was succesful

If new functionality was added:

  • There is appropriate documentation of your work. (use doxygen style comments)

If new third party software is used:

  • Did you pay attention to its license? Please remember to add it to the wiki after successful merging.

If new mathematical methods or epidemiological terms are used:

  • Are new methods referenced? Did you provide further documentation?

Checks by code reviewer(s):

  • Is the code clean of development artifacts e.g., unnecessary comments, prints, ...
  • The ticket goals for each associated issue are reached or problems are clearly addressed (i.e., a new issue was introduced).
  • There are appropriate unit tests and they pass.
  • The git history is clean and linearized for the merge request. All reviewers should squash commits and write a simple and meaningful commit message.
  • Coverage report for new code is acceptable.
  • No large data files have been added to the repository. Maximum size for files should be of the order of KB not MB. In particular avoid adding of pdf, word, or other files that cannot be change-tracked correctly by git.

@EmilyBourne
Copy link
Copy Markdown
Collaborator Author

@tpadioleau can you have a look at this please to see if it aligns with what you had in mind for linking to Gyselalib++?

@EmilyBourne EmilyBourne force-pushed the ebourne_cleanup_cmake branch from 6a681a8 to 6e94e02 Compare April 21, 2026 10:29
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.70%. Comparing base (b34ba98) to head (b101c71).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #214   +/-   ##
=======================================
  Coverage   90.70%   90.70%           
=======================================
  Files          86       86           
  Lines        9458     9458           
=======================================
  Hits         8579     8579           
  Misses        879      879           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown

@tpadioleau tpadioleau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is an improvement, my main concern is whether we should install files related to InputFunctions ?

Comment on lines +7 to +8
find_dependency(OpenMP REQUIRED)
find_dependency(Kokkos REQUIRED)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
find_dependency(OpenMP REQUIRED)
find_dependency(Kokkos REQUIRED)
find_dependency(OpenMP COMPONENTS CXX)
find_dependency(Kokkos)

This must not be REQUIRED because find_package(GMGPolar) is allowed to fail.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So REQUIRED in a XConfig.cmake file makes the sub-dependency required for the calling project?

These are required for GMGPolar. If I remove the REQUIRED won't this successfully import GMGPolar if the only thing that is missing is Kokkos?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So REQUIRED in a XConfig.cmake file makes the sub-dependency required for the calling project?

That is the way I understand, it cannot be optional at this point. The configure and build stages can manage an optional dependency, but once it is determined, installation should whether it is required or not.

These are required for GMGPolar. If I remove the REQUIRED won't this successfully import GMGPolar if the only thing that is missing is Kokkos?

It should not, find_package(GMGPolar) should make GMGPolar_FOUND false.

Comment on lines 20 to 22
target_include_directories(InputFunctions_BoundaryConditions PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/include/InputFunctions/BoundaryConditions
${GMGPOLAR_INCLUDE_DIRS}
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to replace by target_link_libraries(InputFunctions_BoundaryConditions PUBLIC GMGPolarLib) ? I think the target GMGPolarLib should be responsible to bring these headers.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible. This seemed more logical to me as the files in InputFunctions include files that are never used in GMGPolarLib (e.g. the associated .hpp files for these .cpp files) so GMGPolarLib is not needed to compile the InputFunctions for testing.

E.g. in theory we could use InputFunctions in https://github.com/gyselax/gysela-mini-app_poisson even when testing a different solver

find_dependency(Kokkos REQUIRED)

if(@GMGPOLAR_USE_MUMPS@)
find_dependency(MUMPS REQUIRED)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
find_dependency(MUMPS REQUIRED)
find_dependency(MUMPS COMPONENTS OpenMP METIS)
find_dependency(Metis)

endif()

if(@GMGPOLAR_USE_LIKWID@)
find_dependency(LIKWID REQUIRED)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
find_dependency(LIKWID REQUIRED)
find_dependency(LIKWID)

Comment thread cmake/FindMetis.cmake
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this METIS from https://github.com/KarypisLab/METIS ? I see it is based on CMake, it does not generate its own Config files ?

Does not need to be handled in the PR.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't check, I just reorganised what was already in the existing CMake files. Probably a question for @mknaranja

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more a comment than a full answer: Yes, this is METIS from Karypis, it is used for mesh / graph partitioning which is used in direct solvers such as MUMPS. But: I couldn't tell you anything about the technical config file question, I never looked at it at that level.

Copy link
Copy Markdown
Collaborator

@julianlitz julianlitz Apr 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I never tested Mumps without Metis, but Mumps could be used without it by setting ICNTL(7)=7 if have have issues with that library.

https://github.com/SciCompMod/GMGPolar/blob/main/src/LinearAlgebra/Solvers/coo_mumps_solver.cpp#L107

Comment thread src/InputFunctions/CMakeLists.txt Outdated
target_include_directories(InputFunctions INTERFACE
${CMAKE_SOURCE_DIR}/include/InputFunctions
)
${GMGPOLAR_INCLUDE_DIRS}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question, is it possible to replace by target_link_libraries(InputFunctions_BoundaryConditions PUBLIC GMGPolarLib) ?

Comment on lines +21 to +30
install(TARGETS
InputFunctions
InputFunctions_BoundaryConditions
InputFunctions_DensityProfileCoefficients
InputFunctions_DomainGeometry
InputFunctions_ExactSolution
InputFunctions_SourceTerms
EXPORT GMGPolarTargets
ARCHIVE DESTINATION lib
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do they actually need to be installed ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure. This is a question for @mknaranja . It depends on what you see as being the main functionality of the library.

I would lean towards them not needing to be installed. But if they are I would probably use them for testing GMGPolar vs other solvers

${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/include/InputFunctions/DomainGeometry
) No newline at end of file
${GMGPOLAR_INCLUDE_DIRS}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question, is it possible to replace by target_link_libraries(InputFunctions_BoundaryConditions PUBLIC GMGPolarLib) ?

Comment thread CMakeLists.txt Outdated
Comment thread src/CMakeLists.txt
${STENCIL_SOURCES}
${INTERPOLATION_SOURCES}
${CONFIG_PARSER_SOURCES}
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we should add add_library(GMGPolar::GMGPolarLib ALIAS GMGPolarLib)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done : 4ee7dbb

@julianlitz
Copy link
Copy Markdown
Collaborator

julianlitz commented Apr 22, 2026

Compiles on my machine 👍🏼

Co-authored-by: Thomas Padioleau <thomas.padioleau@cea.fr>
Copy link
Copy Markdown

@HenrZu HenrZu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mknaranja requested me to have a look at this. Looks great :) The structure is much cleaner. I left a few minor comments (most are questions as im not really familiar with the structure).

Comment thread CMakeLists.txt Outdated
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -pedantic -Wno-unused -Wno-psabi -Wfloat-conversion")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -mtune=generic -Wno-psabi")

set(CMAKE_CXX_STANDARD 20 CACHE INTERNAL "The C++ standard whose features are requested to build this project.")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why? Already set in line 19+20

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! I put this in when I removed target_compile_features(gmgpolar_tests PRIVATE cxx_std_20) from src/CMakeLists.txt. I must have assumed that the standard was only set once.
Fixed : f33f81d

Copy link
Copy Markdown

@tpadioleau tpadioleau Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine with targets not being installed but we need this target_compile_features(<target> INTERFACE cxx_std_20) if at least one installed header of the associated <target> requires C++20. This is the CMake way to inform the consumer of GMGPolar::GMGPolarLib of the minimum required.

Copy link
Copy Markdown

@tpadioleau tpadioleau Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With Kokkos C++17, when I build a project including GMGPolar without target_compile_features(GMGPolarLib INTERFACE cxx_std_20), I get

[1/2] /usr/bin/g++-10 -DKOKKOS_DEPENDENCE -isystem /local/home/tpadiole/Codes/GMGPolar/opt/include -isystem /local/home/tpadiole/Codes/GMGPolar/my_env/.spack-env/view/include -std=gnu++17 -fopenmp -MD -MT CMakeFiles/test.dir/main.cpp.o -MF CMakeFiles/test.dir/main.cpp.o.d -o CMakeFiles/test.dir/main.cpp.o -c /local/home/tpadiole/Codes/GMGPolar/subproject/main.cpp
FAILED: CMakeFiles/test.dir/main.cpp.o 
/usr/bin/g++-10 -DKOKKOS_DEPENDENCE -isystem /local/home/tpadiole/Codes/GMGPolar/opt/include -isystem /local/home/tpadiole/Codes/GMGPolar/my_env/.spack-env/view/include -std=gnu++17 -fopenmp -MD -MT CMakeFiles/test.dir/main.cpp.o -MF CMakeFiles/test.dir/main.cpp.o.d -o CMakeFiles/test.dir/main.cpp.o -c /local/home/tpadiole/Codes/GMGPolar/subproject/main.cpp
In file included from /local/home/tpadiole/Codes/GMGPolar/opt/include/GMGPolar/gmgpolar.h:8,
                 from /local/home/tpadiole/Codes/GMGPolar/subproject/main.cpp:1:
/local/home/tpadiole/Codes/GMGPolar/opt/include/InputFunctions/densityProfileCoefficients.h:7:1: error: ‘concept’ does not name a type; did you mean ‘concepts’?
    7 | concept DensityProfileCoefficients = requires(const T coeffs, double r, double theta) {
      | ^~~~~~~
      | concepts

whereas with target_compile_features(GMGPolarLib INTERFACE cxx_std_20) I get

[1/2] /usr/bin/g++-10 -DKOKKOS_DEPENDENCE -isystem /local/home/tpadiole/Codes/GMGPolar/opt/include -isystem /local/home/tpadiole/Codes/GMGPolar/my_env/.spack-env/view/include -std=gnu++2a -fopenmp -MD -MT CMakeFiles/test.dir/main.cpp.o -MF CMakeFiles/test.dir/main.cpp.o.d -o CMakeFiles/test.dir/main.cpp.o -c /local/home/tpadiole/Codes/GMGPolar/subproject/main.cpp
[2/2] : && /usr/bin/g++-10  -DKOKKOS_DEPENDENCE CMakeFiles/test.dir/main.cpp.o -o test  -Wl,-rpath,/local/home/tpadiole/Codes/GMGPolar/my_env/.spack-env/view/lib  /local/home/tpadiole/Codes/GMGPolar/opt/lib/libGMGPolarLib.a  /usr/lib/gcc/x86_64-linux-gnu/10/libgomp.so  /usr/lib/x86_64-linux-gnu/libpthread.so  /local/home/tpadiole/Codes/GMGPolar/my_env/.spack-env/view/lib/libkokkoscontainers.so.4.7.2  /local/home/tpadiole/Codes/GMGPolar/my_env/.spack-env/view/lib/libkokkosalgorithms.so.4.7.2  /local/home/tpadiole/Codes/GMGPolar/my_env/.spack-env/view/lib/libkokkoscore.so.4.7.2  -ldl  /local/home/tpadiole/Codes/GMGPolar/my_env/.spack-env/view/lib/libkokkossimd.so.4.7.2 && :

Comment thread tests/CMakeLists.txt Outdated
@@ -32,7 +32,7 @@ add_executable(gmgpolar_tests

# Set the compile features and link libraries
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we use the project() at the top of this file?
This way, we need to set CMAKE_CXX_STANDARD 20 again.

This is already included due tothe add_subdirectory(tests). Maybe we can remove the the configuration lines from the tests/CmakeLists

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somehow I missed this, I agree that there does not need to be a second project : 0bacedc

Comment thread CMakeLists.txt Outdated
if(GMGPOLAR_BUILD_TESTS)
enable_testing()
add_subdirectory(third-party)
find_package(GTest 1.17)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we explictly handle if Gtest is not found, we might use find_package(GTest 1.17 QUIET) here.
See https://cmake.org/cmake/help/latest/command/find_package.html

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done : 063b52c

Comment thread tests/CMakeLists.txt Outdated
@@ -32,7 +32,7 @@ add_executable(gmgpolar_tests

# Set the compile features and link libraries
target_compile_features(gmgpolar_tests PRIVATE cxx_std_20)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be redundant?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree : b101c71

Comment thread CMakeLists.txt
target_link_libraries(convergence_order PRIVATE GMGPolarLib)
target_link_libraries(weak_scaling PRIVATE GMGPolarLib)
target_link_libraries(strong_scaling PRIVATE GMGPolarLib)
target_link_libraries(gmgpolar PRIVATE GMGPolarLib GMGPolarInterface)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im not really familiar with the structure. But these executables are built but not installed. Is this intentional? If yes, maybe add a comment :)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where we need feedback from the GMGPolar team. It is related to the comment above : #214 (comment)

It depends on how you see GMGPolar.
Is it a library? I.e. something designed to provide tools to other bigger tools (e.g. simulations, gyselalib++, etc)
Or is it a tool in its own right? I.e. does it make sense to have access to the executables but not the code?

My impression was that it is more of a library so I have implemented it like this for now. But that also raises the question of whether GMGPolarInterface should be included in that library or not?
In any case I suspect that it does not make sense to install convergence_order, weak_scaling and strong_scaling as I'm not sure these are particularly useful if you can't modify the code to try different test cases?

Copy link
Copy Markdown
Collaborator

@julianlitz julianlitz Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if you would export it as a library than you might need the sourceTerm.h concept definitions, but not all source term specific test case examples.

And the main.cpp etc are just for testing purposes and are probably also not part of a library.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current setup is:

  • All include files are installed
  • Everything except src/ConfigParser/* and src/InputFunctions/* is compiled into the GMGPolarLib target
  • src/ConfigParser/* and src/InputFunctions/* are compiled into a GMGPolarInterface library

As an example of end users:

  • gyselalib++ would use GMGPolarLib to provide a solver for the equation and would be happy to not have to compile GMGPolarInterface
  • gysela-mini-app_poisson (a mini-app designed to compare different solvers) would do the same but could also use GMGPolarInterface to avoid having to write our own test cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants