Skip to content

Commit 987d99f

Browse files
Merge pull request #11 from TimGoTheCreator/MPI-PR
Add MPI
2 parents 967a6b3 + d759c41 commit 987d99f

File tree

6 files changed

+335
-121
lines changed

6 files changed

+335
-121
lines changed

.github/workflows/mpi.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: MPI Galaxy Demo
2+
3+
permissions:
4+
contents: read
5+
6+
on:
7+
push:
8+
branches: [ main ]
9+
pull_request:
10+
11+
concurrency:
12+
group: mpi-${{ github.ref }}
13+
cancel-in-progress: true
14+
15+
jobs:
16+
mpi-galaxy:
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v4
22+
23+
- name: Install dependencies (MPI + HDF5 + Python)
24+
run: |
25+
sudo apt-get update
26+
sudo apt-get install -y mpich libhdf5-dev libomp-dev cmake build-essential python3
27+
28+
- name: Configure project (CMake)
29+
run: |
30+
mkdir -p build
31+
cd build
32+
cmake .. -DCMAKE_BUILD_TYPE=Release -DNEXT_FP64=ON -DNEXT_MPI=ON
33+
34+
- name: Build project
35+
run: |
36+
cd build
37+
cmake --build . -- -j$(nproc)
38+
39+
- name: Run Galaxy demo (timed)
40+
run: |
41+
# Go back to project root
42+
cd $GITHUB_WORKSPACE/examples/GalaxyDemo
43+
python3 galaxy.py
44+
# Run with 2 MPI ranks and 2 OpenMP threads, stop after 20s
45+
timeout 60s mpiexec -n 2 ../../next galaxy.txt 1 0.01 0.1 hdf5 || true
46+
47+
- name: Upload simulation outputs
48+
uses: actions/upload-artifact@v4
49+
with:
50+
name: galaxy-dumps
51+
path: |
52+
examples/GalaxyDemo/dump_*.hdf5
53+
examples/GalaxyDemo/dump_*.xdmf

CMakeLists.txt

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,41 +11,41 @@ if (MINGW)
1111
elseif (MSVC)
1212
message(STATUS "Detected MSVC — using MSVC settings")
1313
set(USING_MSVC TRUE)
14+
elseif (APPLE)
15+
message(STATUS "Detected macOS — limited MPI support")
16+
set(USING_APPLE TRUE)
17+
elseif (UNIX)
18+
message(STATUS "Detected Linux/UNIX — using standard settings")
19+
set(USING_UNIX TRUE)
1420
endif()
1521

1622
# ============================
1723
# Options
1824
# ============================
1925
option(NEXT_FP32 "Use 32-bit floats (scalar)" OFF)
2026
option(NEXT_FP64 "Use 64-bit floats (scalar)" ON)
27+
option(NEXT_MPI "Enable MPI support" OFF)
2128

22-
# Option: copy final executable to source dir
2329
option(NEXT_COPY_TO_CMAKE_SOURCE_DIR "Copy final executable from build dir to source dir" ON)
2430

2531
# ============================
2632
# Precision modes
2733
# ============================
28-
set(NEXT_MODES
29-
NEXT_FP32
30-
NEXT_FP64
31-
)
34+
set(NEXT_MODES NEXT_FP32 NEXT_FP64)
3235

33-
# Count enabled modes
3436
set(NEXT_MODE_COUNT 0)
3537
foreach(m ${NEXT_MODES})
3638
if(${m})
3739
math(EXPR NEXT_MODE_COUNT "${NEXT_MODE_COUNT} + 1")
3840
endif()
3941
endforeach()
4042

41-
# Enforce exactly one mode
4243
if(NEXT_MODE_COUNT EQUAL 0)
4344
message(FATAL_ERROR "You must enable NEXT_FP64 or NEXT_FP32.")
4445
elseif(NEXT_MODE_COUNT GREATER 1)
4546
message(FATAL_ERROR "Enable only one precision mode.")
4647
endif()
4748

48-
# Apply compile definitions
4949
if(NEXT_FP32)
5050
add_compile_definitions(NEXT_FP32)
5151
elseif(NEXT_FP64)
@@ -62,7 +62,10 @@ file(GLOB ARGPARSE_FILES ${CMAKE_SOURCE_DIR}/argparse/*.cpp)
6262

6363
add_executable(next ${SRC_FILES} ${ARGPARSE_FILES})
6464

65-
option(ENABLE_VEC_REPORT "Enable compiler vectorization reports" ON)
65+
# ============================
66+
# Vectorization reports
67+
# ============================
68+
option(ENABLE_VEC_REPORT "Enable compiler vectorization reports" OFF)
6669

6770
if(ENABLE_VEC_REPORT)
6871
if(CMAKE_CXX_COMPILER_ID MATCHES "IntelLLVM")
@@ -74,38 +77,56 @@ if(ENABLE_VEC_REPORT)
7477
endif()
7578
endif()
7679

77-
7880
# ============================
7981
# OpenMP
8082
# ============================
8183
find_package(OpenMP QUIET)
8284
if(OpenMP_CXX_FOUND)
8385
message(STATUS "OpenMP detected — enabling multithreading.")
84-
8586
if(MSVC)
86-
# Force MSVC to use the modern LLVM backend (supports OpenMP 3.0+ and size_t)
87-
# We add it as a compiler option because MSVC's default find_package
88-
# often defaults to the legacy /openmp flag.
8987
target_compile_options(next PRIVATE /openmp:llvm)
9088
else()
9189
target_link_libraries(next PRIVATE OpenMP::OpenMP_CXX)
9290
endif()
93-
9491
else()
9592
message(STATUS "OpenMP not found — building in single-threaded mode.")
9693
endif()
9794

95+
# ============================
96+
# MPI detection
97+
# ============================
98+
if(NEXT_MPI)
99+
if(USING_UNIX)
100+
# Linux: standard OpenMPI
101+
find_package(MPI REQUIRED)
102+
message(STATUS "MPI (OpenMPI) detected — enabling distributed memory parallelism.")
103+
target_compile_definitions(next PRIVATE NEXT_MPI)
104+
target_link_libraries(next PRIVATE MPI::MPI_CXX)
105+
106+
elseif(USING_MSVC OR USING_MINGW)
107+
# Windows: Microsoft MPI
108+
find_package(MPI REQUIRED)
109+
message(STATUS "MPI (MS-MPI) detected — enabling distributed memory parallelism.")
110+
target_compile_definitions(next PRIVATE NEXT_MPI)
111+
target_link_libraries(next PRIVATE MPI::MPI_CXX)
112+
113+
elseif(USING_APPLE)
114+
message(WARNING "MPI requested, but macOS does not ship MPI by default. Please install OpenMPI via Homebrew (brew install open-mpi).")
115+
find_package(MPI REQUIRED)
116+
target_compile_definitions(next PRIVATE NEXT_MPI)
117+
target_link_libraries(next PRIVATE MPI::MPI_CXX)
118+
endif()
119+
endif()
120+
98121
# ============================
99122
# HDF5 detection
100123
# ============================
101-
# MSVC: use vcpkg or prebuilt binaries
102124
if (USING_MSVC AND DEFINED ENV{HDF5_DIR})
103125
set(HDF5_ROOT "$ENV{HDF5_DIR}")
104126
set(CMAKE_PREFIX_PATH "${HDF5_ROOT};${CMAKE_PREFIX_PATH}")
105127
endif()
106128

107129
if (USING_MINGW)
108-
# MSYS2 MinGW installs HDF5 here
109130
set(CMAKE_PREFIX_PATH "C:/tools/msys64/mingw64")
110131
message(STATUS "Using MSYS2 MinGW HDF5 path: ${CMAKE_PREFIX_PATH}")
111132
endif()

argparse/argparse.cpp

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,59 @@
1+
// This program is free software: you can redistribute it and/or modify
2+
// it under the terms of the GNU General Public License as published by
3+
// the Free Software Foundation, either version 3 of the License, or
4+
// (at your option) any later version.
5+
// This program is distributed in the hope that it will be useful,
6+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
7+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8+
// GNU General Public License for more details.
9+
// You should have received a copy of the GNU General Public License
10+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
11+
112
#include "argparse.hpp"
213
#include <iostream>
314
#include <stdexcept>
15+
#ifdef NEXT_MPI
16+
#include <mpi.h>
17+
#endif
418

519
namespace next {
620

7-
Arguments parse_arguments(int argc, char** argv)
21+
Arguments parse_arguments(int argc, char** argv, int rank)
822
{
923
if (argc != 6) {
10-
std::cerr << "Usage: next <input.txt> <threads> <dt> <dump_interval> <vtk|vtu|hdf5>\n";
24+
// Only rank 0 prints usage
25+
if (rank == 0) {
26+
std::cerr << "Usage: next <input.txt> <threads> <dt> <dump_interval> <vtk|vtu|hdf5>\n";
27+
}
28+
29+
#ifdef NEXT_MPI
30+
MPI_Finalize();
31+
#endif
1132
std::exit(1);
1233
}
1334

1435
Arguments args;
1536

16-
args.input_file = argv[1];
17-
args.threads = std::stoi(argv[2]);
18-
args.dt = std::stod(argv[3]);
37+
args.input_file = argv[1];
38+
args.threads = std::stoi(argv[2]);
39+
args.dt = std::stod(argv[3]);
1940
args.dump_interval = std::stod(argv[4]);
2041

2142
std::string fmt = argv[5];
2243

23-
if (fmt == "vtk")
44+
if (fmt == "vtk") {
2445
args.format = OutputFormat::VTK;
25-
else if (fmt == "vtu")
46+
} else if (fmt == "vtu") {
2647
args.format = OutputFormat::VTU;
27-
else if (fmt == "hdf5")
48+
} else if (fmt == "hdf5") {
2849
args.format = OutputFormat::HDF5;
29-
else {
30-
std::cerr << "Choose a file format: vtk, vtu, or hdf5\n";
50+
} else {
51+
if (rank == 0) {
52+
std::cerr << "Choose a file format: vtk, vtu, or hdf5\n";
53+
}
54+
#ifdef NEXT_MPI
55+
MPI_Finalize();
56+
#endif
3157
std::exit(1);
3258
}
3359

argparse/argparse.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ struct Arguments {
1717
OutputFormat format;
1818
};
1919

20-
Arguments parse_arguments(int argc, char** argv);
20+
Arguments parse_arguments(int argc, char** argv, int rank);
2121

2222
}

0 commit comments

Comments
 (0)