Skip to content
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
8 changes: 6 additions & 2 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Checks: >
modernize-use-using

WarningsAsErrors: '*'
HeaderFilterRegex: 'src/.*'
# capi and fortran api headers are c headers and clang-tidy produces not useful errors
ExcludeHeaderFilterRegex: '.*(capi|fortranapi|pythonapi).*'
# skip c, fortran, and interface creation files
# this is actually needed by run-clang-tidy, so it cannot be included here :(
#ExcludeSourceFilterRegex: '\.(c|i|f90)$'
FormatStyle: none
InheritParentConfig: true
InheritParentConfig: true
40 changes: 13 additions & 27 deletions .github/workflows/clang-tidy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ jobs:
- name: Install cmake
run: sudo apt-get install -yq cmake

- name: Install clang-tidy
run: |
sudo apt-get update
sudo apt-get install -yq clang-tidy-20

- uses: actions/checkout@v4

- name: build Catch2
Expand Down Expand Up @@ -191,9 +196,6 @@ jobs:

- name: Install fftw3
run: sudo apt-get install -yq libfftw3-dev pkg-config

- name: Install Bear
run: sudo apt-get install -yq bear

- name: configure pcms
run : |
Expand All @@ -217,29 +219,13 @@ jobs:
-Dperfstubs_DIR=${{ runner.temp }}/build-perfstubs-openmpi/install/lib/cmake \
-DKokkos_DIR=${{ runner.temp }}/build-kokkos-openmpi/install/lib/cmake/Kokkos \
-DKokkosKernels_DIR=${{ runner.temp }}/build-kokkos-kernels-openmpi/install/lib/cmake/KokkosKernels/ \
-DPCMS_TEST_DATA_DIR=$PWD/pcms_testcases

- name: Configure pcms with Bear
run: |
cd ${{ runner.temp }}/build-pcms
bear -- make

- name: Install clang-tidy
run: |
sudo apt-get update
sudo apt-get install -yq clang-tidy-18

-DPCMS_TEST_DATA_DIR=$PWD/pcms_testcases \
-DPCMS_ENABLE_CLANG_TIDY=ON \
-DCLANG_TIDY_EXECUTABLE="$(command -v clang-tidy-20)" \
-DRUN_CLANG_TIDY_EXECUTABLE="$(command -v run-clang-tidy-20)"

# TODO need to capture the error code from this
- name: Run clang-tidy
run: |
EXIT_CODE=0
while read file; do
if ! clang-tidy -p ${{ runner.temp }}/build-pcms "$file" --quiet; then
echo "$file has clang-tidy issues"
EXIT_CODE=1
fi
done < <(find src -name "*.cpp" -o -name "*.hpp" -o -name "*.c" -o -name "*.h" -o -name "*.cc" -o -name "*.cxx" | grep -v 'src/pcms/capi/' | grep -v 'src/pcms/fortranapi/' | grep -v 'src/pcms/pythonapi/')
if [ $EXIT_CODE -eq 1 ]; then
echo "Some C/C++ files have clang-tidy issues. Please fix them with clang-tidy-18."
exit 1
fi
echo "All C/C++ files pass clang-tidy checks"
clang-tidy-20 --version
VERBOSE=1 cmake --build ${{ runner.temp }}/build-pcms -t run-clang-tidy
56 changes: 56 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,27 @@ set(PCMS_HAS_ASAN OFF)
if(PCMS_ENABLE_ASAN AND CMAKE_COMPILER_IS_GNUCXX MATCHES 1)
set(PCMS_HAS_ASAN ON)
endif()
option(PCMS_ENABLE_CLANG_TIDY "enable clang tidy target" OFF)

# based on Professional CMake: A Practical Guide
# this approach works around some issues with CMakes internal handling using co-compilation
# this approach affords a separate clang-tidy run step in the CI
if(PROJECT_IS_TOP_LEVEL)
if(PCMS_ENABLE_CLANG_TIDY)
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)

find_program(CLANG_TIDY_EXECUTABLE clang-tidy REQUIRED)
find_program(RUN_CLANG_TIDY_EXECUTABLE run-clang-tidy REQUIRED)

set(CLANG_TIDY_CONFIG_FILE ${CMAKE_CURRENT_LIST_DIR}/.clang-tidy)
set(CLANG_TIDY_SOURCE_FILTER [=[^(?!.*(\.c|\.i|\.f90)$).*$]=])

message(STATUS "CLANG_TIDY_EXECUTABLE=${CLANG_TIDY_EXECUTABLE}")
message(STATUS "RUN_CLANG_TIDY_EXECUTABLE= ${RUN_CLANG_TIDY_EXECUTABLE}")
message(STATUS "CLANG_TIDY_CONFIG_FILE=${CLANG_TIDY_CONFIG_FILE}")
message(STATUS "CLANG_TIDY_SOURCE_FILTER=${CLANG_TIDY_SOURCE_FILTER}")
endif()
endif()

option(PCMS_ENABLE_SERVER "enable the coupling server implementation" ON)
option(PCMS_ENABLE_CLIENT "enable the coupling client implementation" ON)
Expand Down Expand Up @@ -56,6 +77,41 @@ endif()

set(MPI_CXX_SKIP_MPICXX ON)
find_package(MPI REQUIRED)

# Create the run-clang-tidy target here (after find_package(MPI)) so we can
# forward any MPI include paths that are missing from compile_commands.json.
# When CMAKE_CXX_COMPILER is an MPI wrapper (e.g. mpicxx), FindMPI may leave
# MPI_CXX_INCLUDE_DIRS empty because the wrapper handles includes implicitly,
# meaning compile_commands.json has no explicit -I flags for mpi.h.
if(PROJECT_IS_TOP_LEVEL)
if(PCMS_ENABLE_CLANG_TIDY)
set(_clang_tidy_extra_args "")
get_target_property(_mpi_cxx_incs MPI::MPI_CXX INTERFACE_INCLUDE_DIRECTORIES)
if(NOT _mpi_cxx_incs)
execute_process(
COMMAND ${MPI_CXX_COMPILER} -show
OUTPUT_VARIABLE _mpi_show
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
string(REGEX MATCHALL "-I([^ ]+)" _mpi_inc_flags "${_mpi_show}")
foreach(_flag IN LISTS _mpi_inc_flags)
list(APPEND _clang_tidy_extra_args "-extra-arg=${_flag}")
endforeach()
message(STATUS "clang-tidy MPI extra args: ${_clang_tidy_extra_args}")
endif()

add_custom_target(run-clang-tidy
VERBATIM COMMAND ${RUN_CLANG_TIDY_EXECUTABLE}
-clang-tidy-binary ${CLANG_TIDY_EXECUTABLE}
-p ${CMAKE_BINARY_DIR}
-quiet
-config-file ${CLANG_TIDY_CONFIG_FILE}
-source-filter ${CLANG_TIDY_SOURCE_FILTER}
${_clang_tidy_extra_args}
)
endif()
endif()

message(STATUS "Found redev: ${redev_DIR} (found version ${redev_VERSION})")
if(PCMS_ENABLE_OMEGA_H)
find_package(Omega_h REQUIRED VERSION 10)
Expand Down
4 changes: 2 additions & 2 deletions src/pcms/coupler.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class Application
bool participates = true)
{
PCMS_FUNCTION_TIMER;
auto [it, inserted] = fields_.template try_emplace(
auto [it, inserted] = fields_.try_emplace(
name, name, std::forward<FieldAdapterT>(field_adapter), mpi_comm_, redev_,
channel_, participates);
if (!inserted) {
Expand Down Expand Up @@ -238,7 +238,7 @@ class Coupler
{
PCMS_FUNCTION_TIMER;
auto key = path + name;
auto [it, inserted] = applications_.template try_emplace(
auto [it, inserted] = applications_.try_emplace(
key, std::move(name), mpi_comm_, redev_, std::move(params),
transport_type, std::move(path));
if (!inserted) {
Expand Down
2 changes: 1 addition & 1 deletion test/test_interpolation_on_ltx_mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ std::vector<double> read_xgc_mesh_nodes(std::string filename)
assert(dim == 2 && "Expected 2D coordinates in the file");

std::vector<double> nodes;
nodes.reserve(num_nodes * dim);
nodes.reserve(static_cast<std::size_t>(num_nodes) * dim);

while (std::getline(file, line)) {
std::istringstream line_stream(line);
Expand Down
11 changes: 3 additions & 8 deletions test/test_ohOverlap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,9 @@ OMEGA_H_DEVICE Omega_h::I8 isModelEntInOverlap(const int dim, const int id)
// the TOMMS generated geometric model has
// entity IDs that increase with the distance
// from the magnetic axis
if (dim == 2 && (id >= 22 && id <= 34)) {
return 1;
} else if (dim == 1 && (id >= 21 && id <= 34)) {
return 1;
} else if (dim == 0 && (id >= 21 && id <= 34)) {
return 1;
}
return 0;
const bool inOverlap = ((dim == 2) && (id >= 22 && id <= 34)) ||
((dim == 1 || dim == 0) && (id >= 21 && id <= 34));
return inOverlap;
}

/**
Expand Down
1 change: 0 additions & 1 deletion test/test_proxy_coupling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ int main(int argc, char** argv)
Omega_h::Mesh mesh(&lib);
Omega_h::binary::read(meshFile, lib.world(), &mesh);
MPI_Comm mpi_comm = lib.world()->get_impl();
const std::string name = "meshVtxIds";
switch (clientId) {
case -1: xgc_coupler(mpi_comm, mesh, classPartitionFile); break;
case 0: xgc_delta_f(mpi_comm, mesh); break;
Expand Down
6 changes: 4 additions & 2 deletions test/test_spline_interpolator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ void dotest1(int ns, Rank1View<double, TestMemorySpace> x,
using std::data;
using std::size;

Kokkos::View<double*, TestMemorySpace> splinv_view("splinv_view", 3 * nt);
Kokkos::View<double*, TestMemorySpace> splinv_view(
"splinv_view", static_cast<std::size_t>(3) * nt);
auto splinv = Rank2View<double, TestMemorySpace>(splinv_view.data(), nt, 3);
reset_2dspan(splinv);

Expand Down Expand Up @@ -246,7 +247,8 @@ void dotest2(Rank1View<double, TestMemorySpace> x,
Kokkos::View<double*, HostMemorySpace> res_2d)
{

Kokkos::View<double*, TestMemorySpace> values_view("values_view", nth * nx);
Kokkos::View<double*, TestMemorySpace> values_view(
"values_view", static_cast<std::size_t>(nth) * nx);
Kokkos::parallel_for(
Kokkos::MDRangePolicy<Kokkos::Rank<2>>({0, 0}, {nth, nx}),
KOKKOS_LAMBDA(const int ith, const int ix) {
Expand Down
2 changes: 1 addition & 1 deletion test/test_support.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ void migrateMeshElms(Omega_h::Mesh& mesh,
std::map<ModelEnt, int> modelEntToRank;
for (int i = 0; i < partition.ranks.size(); i++)
modelEntToRank[partition.modelEnts[i]] = partition.ranks[i];
typedef std::map<int, std::vector<int>> miv;
using miv = std::map<int, std::vector<int>>;
miv elemsPerRank;
for (int i = 0; i < mesh.nelems(); i++) {
const ModelEnt ent({class_dims_h[i], class_ids_h[i]});
Expand Down
11 changes: 3 additions & 8 deletions test/test_twoClientOverlap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,9 @@ OMEGA_H_DEVICE Omega_h::I8 isModelEntInOverlap(const int dim, const int id)
// the TOMMS generated geometric model has
// entity IDs that increase with the distance
// from the magnetic axis
if (dim == 2 && (id >= 22 && id <= 34)) {
return 1;
} else if (dim == 1 && (id >= 21 && id <= 34)) {
return 1;
} else if (dim == 0 && (id >= 21 && id <= 34)) {
return 1;
}
return 0;
const bool inOverlap = ((dim == 2) && (id >= 22 && id <= 34)) ||
((dim == 1 || dim == 0) && (id >= 21 && id <= 34));
return inOverlap;
}

/**
Expand Down