Skip to content

Commit 8680d90

Browse files
authored
Merge pull request #46 from jmsexton03/ci_with_cmake
Build Improvements and CI
2 parents f1cac61 + 84ea488 commit 8680d90

20 files changed

Lines changed: 721 additions & 105 deletions

File tree

.github/workflows/ci.yml

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
name: ELEQTRONeX CI
2+
3+
on:
4+
push:
5+
# branches: [development]
6+
paths-ignore:
7+
- Docs
8+
- README.md
9+
- license.txt
10+
11+
pull_request:
12+
branches: [development]
13+
14+
concurrency:
15+
group: ${{ github.ref }}-${{ github.head_ref }}-ci
16+
cancel-in-progress: true
17+
18+
jobs:
19+
20+
Build:
21+
runs-on: ${{matrix.os}}
22+
name: OS ${{matrix.os}} - HYPRE ${{matrix.hypre}} - AMReX ${{matrix.amrex_mode}}
23+
strategy:
24+
matrix:
25+
os: [ubuntu-22.04]
26+
hypre: [OFF, ON]
27+
amrex_mode: [internal, external_src]
28+
include:
29+
- os: ubuntu-22.04
30+
install_deps: sudo apt-get install mpich libmpich-dev
31+
comp: gnu
32+
procs: $(nproc)
33+
- hypre: ON
34+
hypre_version: "2.32.0"
35+
36+
steps:
37+
38+
- uses: actions/checkout@v4
39+
with:
40+
submodules: true
41+
42+
- name: Clone AMReX for dependency scripts
43+
run: |
44+
git clone https://github.com/AMReX-Codes/amrex.git ${{runner.workspace}}/amrex
45+
46+
- name: Setup
47+
run: |
48+
# echo "::add-matcher::.github/problem-matchers/gcc.json"
49+
echo "NPROCS=${{matrix.procs}}" >> $GITHUB_ENV
50+
if [ "${{matrix.amrex_mode}}" == "external_src" ]; then
51+
echo "AMREX_SRC_DIR=${{runner.workspace}}/amrex" >> $GITHUB_ENV
52+
fi
53+
54+
- name: Handle Dependencies
55+
run: |
56+
# Install MPI
57+
${{matrix.install_deps}}
58+
59+
- name: Install CCache
60+
run: ${{runner.workspace}}/amrex/.github/workflows/dependencies/dependencies_ccache.sh
61+
62+
- name: Set Up Cache
63+
uses: actions/cache@v4
64+
with:
65+
path: |
66+
~/.cache/ccache
67+
~/.cache/hypre-${{matrix.hypre_version}}
68+
key: ccache-${{ github.workflow }}-${{ github.job }}-git-${{ github.sha }}
69+
restore-keys: |
70+
ccache-${{ github.workflow }}-${{ github.job }}-git-
71+
72+
- name: Build Hypre
73+
if: matrix.hypre == 'ON'
74+
run: |
75+
export HYPRE_HOME=~/.cache/hypre-${{matrix.hypre_version}}
76+
if [ ! -d "${HYPRE_HOME}" ]; then
77+
wget -q https://github.com/hypre-space/hypre/archive/refs/tags/v${{matrix.hypre_version}}.tar.gz
78+
tar xfz v${{matrix.hypre_version}}.tar.gz
79+
cd hypre-${{matrix.hypre_version}}/src
80+
./configure --with-cxxstandard=17 --enable-bigint --prefix=${HYPRE_HOME}
81+
make -j ${{matrix.procs}}
82+
make install
83+
cd ../../
84+
fi
85+
echo "HYPRE_ROOT=${HYPRE_HOME}" >> $GITHUB_ENV
86+
87+
- name: Configure CMake
88+
run: |
89+
HYPRE_ARG=""
90+
if [ "${{matrix.hypre}}" == "ON" ]; then
91+
HYPRE_ARG="-DHYPRE_ROOT=${HYPRE_ROOT}"
92+
fi
93+
94+
if [ "${{matrix.amrex_mode}}" == "external_src" ]; then
95+
cmake \
96+
-B${{runner.workspace}}/ELEQTRONeX/build-${{matrix.os}}-${{matrix.hypre}}-${{matrix.amrex_mode}} \
97+
-DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/ELEQTRONeX/install \
98+
-DCMAKE_BUILD_TYPE:STRING=Debug \
99+
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
100+
-DELEQTRONeX_MPI:BOOL=ON \
101+
-DELEQTRONeX_EB:BOOL=ON \
102+
-DELEQTRONeX_TRANSPORT:BOOL=ON \
103+
-DELEQTRONeX_TIME_DEPENDENT:BOOL=ON \
104+
-DELEQTRONeX_BROYDEN_PARALLEL:BOOL=ON \
105+
-DELEQTRONeX_HYPRE:BOOL=${{matrix.hypre}} \
106+
${HYPRE_ARG} \
107+
-DELEQTRONeX_amrex_src:PATH=${{env.AMREX_SRC_DIR}} \
108+
${{github.workspace}};
109+
else
110+
cmake \
111+
-B${{runner.workspace}}/ELEQTRONeX/build-${{matrix.os}}-${{matrix.hypre}}-${{matrix.amrex_mode}} \
112+
-DCMAKE_INSTALL_PREFIX:PATH=${{runner.workspace}}/ELEQTRONeX/install \
113+
-DCMAKE_BUILD_TYPE:STRING=Debug \
114+
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
115+
-DELEQTRONeX_MPI:BOOL=ON \
116+
-DELEQTRONeX_EB:BOOL=ON \
117+
-DELEQTRONeX_TRANSPORT:BOOL=ON \
118+
-DELEQTRONeX_TIME_DEPENDENT:BOOL=ON \
119+
-DELEQTRONeX_BROYDEN_PARALLEL:BOOL=ON \
120+
-DELEQTRONeX_HYPRE:BOOL=${{matrix.hypre}} \
121+
${HYPRE_ARG} \
122+
${{github.workspace}};
123+
fi
124+
125+
- name: Build
126+
run: |
127+
export CCACHE_COMPRESS=1
128+
export CCACHE_COMPRESSLEVEL=10
129+
export CCACHE_MAXSIZE=600M
130+
ccache -z
131+
132+
cmake \
133+
--build ${{runner.workspace}}/ELEQTRONeX/build-${{matrix.os}}-${{matrix.hypre}}-${{matrix.amrex_mode}} \
134+
--parallel ${{env.NPROCS}} \
135+
2>&1 | tee -a ${{runner.workspace}}/build-output-${{matrix.hypre}}-${{matrix.amrex_mode}}.txt;
136+
137+
ccache -s
138+
du -hs ~/.cache/ccache
139+
140+
- name: Report
141+
run: |
142+
egrep "warning:|error:" ${{runner.workspace}}/build-output-${{matrix.hypre}}-${{matrix.amrex_mode}}.txt \
143+
| egrep -v "_deps/.*amrex" | egrep -v "_deps/.*hypre" | egrep -v "${{runner.workspace}}/amrex" | egrep -v "${{runner.workspace}}/hypre" | egrep -v "lto-wrapper: warning:" | sort | uniq \
144+
| awk 'BEGIN{i=0}{print $0}{i++}END{print "Warnings: "i}' > ${{runner.workspace}}/build-output-warnings-${{matrix.hypre}}-${{matrix.amrex_mode}}.txt
145+
cat ${{runner.workspace}}/build-output-warnings-${{matrix.hypre}}-${{matrix.amrex_mode}}.txt
146+
export return=$(tail -n 1 ${{runner.workspace}}/build-output-warnings-${{matrix.hypre}}-${{matrix.amrex_mode}}.txt | awk '{print $2}')
147+
exit ${return}

CMakeLists.txt

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
cmake_minimum_required(VERSION 3.24.0)
2+
project(ELEQTRONeX VERSION 1.0.0)
3+
4+
# In-source tree builds are not supported
5+
if(CMAKE_BINARY_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
6+
message(FATAL_ERROR "Building in-source is not supported! "
7+
"Create a build directory and remove "
8+
"${CMAKE_SOURCE_DIR}/CMakeCache.txt ${CMAKE_SOURCE_DIR}/CMakeFiles/")
9+
endif()
10+
11+
# Set C++17 standard
12+
set(CMAKE_CXX_STANDARD 17)
13+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
14+
set(CMAKE_CXX_EXTENSIONS OFF)
15+
16+
# Change default build type to Release
17+
if(NOT CMAKE_BUILD_TYPE)
18+
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE)
19+
endif()
20+
21+
# Options - mirror GNUmakefile defaults but allow flexibility
22+
option(ELEQTRONeX_APP "Build the ELEQTRONeX executable application" ON)
23+
option(ELEQTRONeX_MPI "Multi-node support (message-passing)" ON)
24+
option(ELEQTRONeX_EB "Embedded boundary support" ON)
25+
option(ELEQTRONeX_TRANSPORT "Transport support" ON)
26+
option(ELEQTRONeX_TIME_DEPENDENT "Time-dependent support" ON)
27+
option(ELEQTRONeX_BROYDEN_PARALLEL "Broyden parallel support" ON)
28+
option(ELEQTRONeX_HYPRE "HYPRE support" OFF)
29+
30+
# Dependency options
31+
option(ELEQTRONeX_amrex_internal "Download & build AMReX" ON)
32+
33+
# Print options
34+
option(ELEQTRONeX_PRINT_HIGH "Enable high level debug printing" OFF)
35+
option(ELEQTRONeX_PRINT_MEDIUM "Enable medium level debug printing" OFF)
36+
option(ELEQTRONeX_PRINT_LOW "Enable low level debug printing" OFF)
37+
option(ELEQTRONeX_PRINT_NAME "Enable function name debug printing" OFF)
38+
39+
# Compute backend selection
40+
set(ELEQTRONeX_COMPUTE_VALUES NOACC OMP CUDA HIP)
41+
set(ELEQTRONeX_COMPUTE NOACC CACHE STRING "On-node, accelerated computing backend (NOACC/OMP/CUDA/HIP)")
42+
set_property(CACHE ELEQTRONeX_COMPUTE PROPERTY STRINGS ${ELEQTRONeX_COMPUTE_VALUES})
43+
if(NOT ELEQTRONeX_COMPUTE IN_LIST ELEQTRONeX_COMPUTE_VALUES)
44+
message(FATAL_ERROR "ELEQTRONeX_COMPUTE (${ELEQTRONeX_COMPUTE}) must be one of ${ELEQTRONeX_COMPUTE_VALUES}")
45+
endif()
46+
47+
# Set dimensions (3D only for ELEQTRONeX)
48+
set(ELEQTRONeX_DIMS 3 CACHE STRING "Simulation dimensionality (3D only)")
49+
50+
# Include AMReX dependency management
51+
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/dependencies/AMReX.cmake)
52+
53+
# Create executable with sophisticated naming like other codes
54+
if(ELEQTRONeX_APP)
55+
# Build binary name
56+
set(binary_name "main3d")
57+
58+
# Add compiler info
59+
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
60+
set(binary_name "${binary_name}.gnu")
61+
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
62+
set(binary_name "${binary_name}.intel")
63+
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
64+
set(binary_name "${binary_name}.clang")
65+
endif()
66+
67+
# Add MPI support
68+
if(ELEQTRONeX_MPI)
69+
set(binary_name "${binary_name}.MPI")
70+
endif()
71+
72+
# Add EB support
73+
if(ELEQTRONeX_EB)
74+
set(binary_name "${binary_name}.EB")
75+
endif()
76+
77+
# Add time-dependent support
78+
if(ELEQTRONeX_TIME_DEPENDENT)
79+
set(binary_name "${binary_name}.TD")
80+
endif()
81+
82+
# Add transport support
83+
if(ELEQTRONeX_TRANSPORT)
84+
set(binary_name "${binary_name}.TRAN")
85+
endif()
86+
87+
# Add Broyden parallel support
88+
if(ELEQTRONeX_BROYDEN_PARALLEL)
89+
set(binary_name "${binary_name}.BROYPRLL")
90+
endif()
91+
92+
# Add SKIPGPU suffix when not using GPU backend (matching gnumake logic)
93+
if(NOT ELEQTRONeX_COMPUTE STREQUAL "CUDA" AND NOT ELEQTRONeX_COMPUTE STREQUAL "HIP")
94+
set(binary_name "${binary_name}.SKIPGPU")
95+
endif()
96+
97+
# Add compute backend
98+
if(ELEQTRONeX_COMPUTE STREQUAL "OMP")
99+
set(binary_name "${binary_name}.OMP")
100+
elseif(ELEQTRONeX_COMPUTE STREQUAL "CUDA")
101+
set(binary_name "${binary_name}.CUDA")
102+
elseif(ELEQTRONeX_COMPUTE STREQUAL "HIP")
103+
set(binary_name "${binary_name}.HIP")
104+
endif()
105+
106+
# Add HYPRE support
107+
if(ELEQTRONeX_HYPRE)
108+
set(binary_name "${binary_name}.HYPRE")
109+
endif()
110+
111+
set(binary_name "${binary_name}.ex")
112+
113+
add_executable(${binary_name})
114+
115+
# Add main source files
116+
target_sources(${binary_name} PRIVATE
117+
Source/main.cpp
118+
Source/Code.cpp
119+
)
120+
121+
# Add all subdirectory sources recursively
122+
file(GLOB_RECURSE ELEQTRONeX_SOURCES
123+
"Source/Diagnostics/*.cpp"
124+
"Source/Input/*.cpp"
125+
"Source/Output/*.cpp"
126+
"Source/PostProcessor/*.cpp"
127+
"Source/Solver/*.cpp"
128+
"Source/Utils/*.cpp"
129+
)
130+
target_sources(${binary_name} PRIVATE ${ELEQTRONeX_SOURCES})
131+
132+
# Include directories
133+
target_include_directories(${binary_name} PRIVATE
134+
${CMAKE_CURRENT_SOURCE_DIR}/Source
135+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Diagnostics
136+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Input
137+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Input/BoundaryConditions
138+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Input/GeometryProperties
139+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Input/MacroscopicProperties
140+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Output
141+
${CMAKE_CURRENT_SOURCE_DIR}/Source/PostProcessor
142+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Solver
143+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Solver/Electrostatics
144+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Solver/Transport
145+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Utils
146+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Utils/CodeUtils
147+
${CMAKE_CURRENT_SOURCE_DIR}/Source/Utils/SelectWarpXUtils
148+
)
149+
150+
# Link AMReX (AMReX will automatically link HYPRE if it was built with HYPRE support)
151+
target_link_libraries(${binary_name} PRIVATE AMReX::amrex)
152+
153+
# Set compile definitions based on options
154+
# Matching gnumake here - this will be a redefinition as a workaround for nonstandard code
155+
if(ELEQTRONeX_EB)
156+
target_compile_definitions(${binary_name} PRIVATE AMREX_USE_EB)
157+
endif()
158+
159+
if(ELEQTRONeX_TIME_DEPENDENT)
160+
target_compile_definitions(${binary_name} PRIVATE TIME_DEPENDENT)
161+
endif()
162+
163+
if(ELEQTRONeX_TRANSPORT)
164+
target_compile_definitions(${binary_name} PRIVATE USE_TRANSPORT)
165+
endif()
166+
167+
if(ELEQTRONeX_BROYDEN_PARALLEL)
168+
target_compile_definitions(${binary_name} PRIVATE BROYDEN_PARALLEL)
169+
endif()
170+
171+
# Matching gnumake logic: skip GPU optimization when not using GPU backend
172+
if(NOT ELEQTRONeX_COMPUTE STREQUAL "CUDA" AND NOT ELEQTRONeX_COMPUTE STREQUAL "HIP")
173+
target_compile_definitions(${binary_name} PRIVATE BROYDEN_SKIP_GPU_OPTIMIZATION)
174+
endif()
175+
176+
# Print debug options - matches Make.Code logic
177+
if(ELEQTRONeX_PRINT_HIGH)
178+
target_compile_definitions(${binary_name} PRIVATE PRINT_HIGH PRINT_MEDIUM PRINT_LOW PRINT_NAME)
179+
elseif(ELEQTRONeX_PRINT_MEDIUM)
180+
target_compile_definitions(${binary_name} PRIVATE PRINT_MEDIUM PRINT_LOW PRINT_NAME)
181+
elseif(ELEQTRONeX_PRINT_LOW)
182+
target_compile_definitions(${binary_name} PRIVATE PRINT_LOW PRINT_NAME)
183+
elseif(ELEQTRONeX_PRINT_NAME)
184+
target_compile_definitions(${binary_name} PRIVATE PRINT_NAME)
185+
endif()
186+
187+
# Handle CUDA compilation like MagneX and FerroX
188+
if(ELEQTRONeX_COMPUTE STREQUAL "CUDA")
189+
# AMReX helper function: propagate CUDA specific target & source properties
190+
setup_target_for_cuda_compilation(${binary_name})
191+
target_compile_features(${binary_name} PUBLIC cuda_std_17)
192+
set_target_properties(${binary_name} PROPERTIES
193+
CUDA_EXTENSIONS OFF
194+
CUDA_STANDARD_REQUIRED ON
195+
)
196+
else()
197+
target_compile_features(${binary_name} PUBLIC cxx_std_17)
198+
set_target_properties(${binary_name} PROPERTIES
199+
CXX_EXTENSIONS OFF
200+
CXX_STANDARD_REQUIRED ON
201+
)
202+
endif()
203+
204+
# Set output directory
205+
set_target_properties(${binary_name} PROPERTIES
206+
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
207+
)
208+
209+
# Create simple symlink for convenience
210+
add_custom_command(TARGET ${binary_name} POST_BUILD
211+
COMMAND ${CMAKE_COMMAND} -E create_symlink
212+
${binary_name}
213+
${CMAKE_BINARY_DIR}/eleqtronex
214+
COMMENT "Creating symlink eleqtronex -> ${binary_name}"
215+
)
216+
endif()

0 commit comments

Comments
 (0)