Skip to content

Commit e7a958a

Browse files
committed
Merge pull request #46 from memmett/feature/mpi-pf
Add first pass at PFASST algorithm. Closes #32 as well.
2 parents 823d0f6 + 13a85a7 commit e7a958a

File tree

15 files changed

+665
-67
lines changed

15 files changed

+665
-67
lines changed

.travis.yml

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
language:
22
- cpp
33

4-
compiler:
5-
- gcc
6-
- clang
7-
4+
# why does Travis not allow for multi-dimensional build matrices?!?
5+
# -> https://github.com/travis-ci/travis-ci/issues/1519
86
env:
9-
- CMAKE_BUILD_TYPE="Release"
10-
- CMAKE_BUILD_TYPE="Debug"
7+
matrix:
8+
- CMAKE_BUILD_TYPE="Release" WITH_MPI=OFF CXX=clang++
9+
- CMAKE_BUILD_TYPE="Release" WITH_MPI=OFF CXX=g++
10+
- CMAKE_BUILD_TYPE="Release" WITH_MPI=ON CXX=g++
11+
- CMAKE_BUILD_TYPE="Debug" WITH_MPI=OFF CXX=clang++
12+
- CMAKE_BUILD_TYPE="Debug" WITH_MPI=OFF CXX=g++
13+
- CMAKE_BUILD_TYPE="Debug" WITH_MPI=ON CXX=g++
1114

1215
before_install:
1316
- sudo add-apt-repository ppa:apokluda/boost1.53 --yes
1417
- sudo add-apt-repository ppa:ubuntu-toolchain-r/test --yes # libstdc++-4.8
15-
- if [ "${CXX}" == "clang++" ]; then sudo add-apt-repository --yes ppa:h-rayflood/llvm; fi # clang++-3.2
18+
- if [ "${CXX}" == "clang++" ]; then sudo add-apt-repository --yes ppa:h-rayflood/llvm; fi # clang++-3.2
1619
- sudo apt-get update
1720

21+
1822
install:
23+
# note: clang needs g++-4.8 it for libstdc++ update
1924
- if [ "${CXX}" == "clang++" ]; then sudo apt-get -qq install clang-3.2; fi
25+
- if [ "${WITH_MPI}" == "ON" ]; then sudo apt-get -qq install mpich2 libmpich2-dev; fi
2026
- sudo apt-get install g++-4.8 # clang need it for libstdc++ update
2127
- sudo apt-get install libboost1.53-all-dev libfftw3-3 libfftw3-dev
2228

@@ -28,7 +34,7 @@ before_script:
2834
script:
2935
- mkdir build
3036
- cd build
31-
- cmake -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -Dpfasst_DISABLE_LIBCXX=ON -Dpfasst_BUILD_TESTS=ON -Dpfasst_BUILD_EXAMPLES=ON ..
37+
- cmake -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -Dpfasst_WITH_MPI=${WITH_MPI} -Dpfasst_DISABLE_LIBCXX=ON -Dpfasst_BUILD_TESTS=ON -Dpfasst_BUILD_EXAMPLES=ON ..
3238
- make
3339
- make test
34-
40+
- make run_example_all

CMakeLists.txt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
cmake_minimum_required(VERSION 2.8)
2-
3-
set(CMAKE_VERBOSE_MAKEFILE ON)
4-
52
project(pfasst)
63

74
list(APPEND CMAKE_MODULE_PATH ${pfasst_SOURCE_DIR}/cmake)
@@ -11,15 +8,23 @@ include(ExternalProject)
118
# Set default ExternalProject root directory
129
set_directory_properties(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/3rdparty)
1310

14-
option(pfasst_DISABLE_LIBCXX "Disable use of LLVM's libc++ when compiling with Clang." ON)
15-
option(pfasst_BUILD_EXAMPLES "Build example programs." ON)
16-
option(pfasst_BUILD_TESTS "Build test suite for PFASST." ON)
11+
option(pfasst_DISABLE_LIBCXX "Disable use of LLVM's libc++ when compiling with Clang." ON )
12+
option(pfasst_BUILD_EXAMPLES "Build example programs." ON )
13+
option(pfasst_BUILD_TESTS "Build test suite for PFASST." ON )
14+
option(pfasst_WITH_MPI "Build with MPI enabled." OFF)
1715

1816
# output directories
1917
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${pfasst_SOURCE_DIR}/dist/bin")
2018
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${pfasst_SOURCE_DIR}/dist/lib")
2119
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${pfasst_SOURCE_DIR}/dist/lib")
2220

21+
if(${pfasst_WITH_MPI})
22+
find_package(MPI REQUIRED)
23+
# set(CMAKE_C_COMPILER ${MPI_C_COMPILER})
24+
# set(CMAKE_CXX_COMPILER ${MPI_CXX_COMPILER})
25+
message(STATUS "Using MPI C++ Compiler: ${MPI_CXX_COMPILER}")
26+
endif()
27+
2328
# check for C++11 support
2429
if(${CMAKE_CXX_COMPILER_ID} MATCHES GNU)
2530
check_cxx_compiler_flag(-std=c++11 HAVE_STD11)
@@ -97,5 +102,7 @@ endif()
97102
message(STATUS "********************************************************************************")
98103

99104
message(STATUS "C++ Compiler ID: ${CMAKE_CXX_COMPILER_ID}")
105+
message(STATUS "C++ Compiler Names: ${CMAKE_CXX_COMPILER_NAMES}")
106+
message(STATUS "C++ Compiler Version: ${CMAKE_CXX_COMPILER_VERSION}")
100107
message(STATUS "C++ Flags: ${CMAKE_CXX_FLAGS}")
101108
message(STATUS "C++ link flags: ${CMAKE_CXX_LINK_FLAGS}")

examples/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
1+
set(all_example_runs)
2+
13
add_subdirectory(advection_diffusion)
4+
5+
add_custom_target(run_example_all
6+
DEPENDS ${all_example_runs}
7+
COMMENT "Running all examples" VERBATIM
8+
)
9+
message(STATUS " - run_example_all")

examples/advection_diffusion/CMakeLists.txt

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
set(all_example_runs ${all_example_runs})
2+
set(all_advec_example_runs)
3+
14
message(STATUS " advection_diffusion")
25
include_directories(
36
${3rdparty_INCLUDES}
@@ -11,7 +14,20 @@ set(advec_examples
1114
serial_mlsdc_autobuild
1215
)
1316

14-
foreach(example ${advec_examples})
17+
set(advec_mpi_examples)
18+
19+
if(${pfasst_WITH_MPI})
20+
set(advec_mpi_examples
21+
mpi_pfasst
22+
)
23+
endif()
24+
25+
set(all_advec_examples
26+
${advec_examples}
27+
${advec_mpi_examples}
28+
)
29+
30+
foreach(example ${all_advec_examples})
1531
add_executable(${example} ${CMAKE_CURRENT_SOURCE_DIR}/${example}.cpp)
1632
if(NOT FFTW_FOUND)
1733
add_dependencies(${example} fftw3)
@@ -23,3 +39,47 @@ foreach(example ${advec_examples})
2339
PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/advection_diffusion
2440
)
2541
endforeach(example)
42+
43+
message(STATUS " creating make targets to run examples")
44+
foreach(example ${advec_examples})
45+
add_custom_target(run_example_advec_${example}
46+
COMMAND ${example}
47+
DEPENDS ${example}
48+
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/advection_diffusion
49+
COMMENT "Running Advection-Diffusion example: ${example}" VERBATIM
50+
)
51+
list(APPEND all_advec_example_runs run_example_advec_${example})
52+
message(STATUS " - run_example_advec_${example}")
53+
endforeach(example)
54+
55+
if(${pfasst_WITH_MPI})
56+
include_directories(${MPI_CXX_INCLUDE_PATH})
57+
foreach(example ${advec_mpi_examples})
58+
if(MPI_COMPILE_FLAGS)
59+
set_target_properties(${example} PROPERTIES COMPILE_FLAGS "${MPI_COMPILE_FLAGS}")
60+
endif()
61+
if(MPI_LINK_FLAGS)
62+
set_target_properties(${example} PROPERTIES LINK_FLAGS "${MPI_LINK_FLAGS}")
63+
endif()
64+
target_link_libraries(${example} ${MPI_CXX_LIBRARIES})
65+
endforeach(example)
66+
message(STATUS " creating make targets to run MPI examples")
67+
foreach(example ${advec_mpi_examples})
68+
add_custom_target(run_example_advec_${example}
69+
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 4 ${MPIEXEC_PREFLAGS} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/advection_diffusion/${example} ${MPIEXEC_POSTFLAGS}
70+
DEPENDS ${example}
71+
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/examples/advection_diffusion
72+
COMMENT "Running Advection-Diffusion example: ${example}" VERBATIM
73+
)
74+
list(APPEND all_advec_example_runs run_example_advec_${example})
75+
message(STATUS " - run_example_advec_${example}")
76+
endforeach(example)
77+
endif()
78+
79+
add_custom_target(run_example_advec_all
80+
DEPENDS ${all_advec_example_runs}
81+
COMMENT "Running all Advection-Diffusion examples" VERBATIM
82+
)
83+
message(STATUS " - run_example_advec_all")
84+
85+
set(all_example_runs ${all_advec_example_runs} PARENT_SCOPE)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Advection/diffusion example using an encapsulated IMEX sweeper.
3+
*
4+
* This example uses MPI PFASST.
5+
*/
6+
7+
#include <memory>
8+
#include <cassert>
9+
10+
#include <mpi.h>
11+
#include <fftw3.h>
12+
13+
#include <pfasst.hpp>
14+
#include <pfasst/pfasst.hpp>
15+
#include <pfasst/mpi_communicator.hpp>
16+
#include <pfasst/encap/automagic.hpp>
17+
#include <pfasst/encap/mpi_vector.hpp>
18+
19+
#include "advection_diffusion_sweeper.hpp"
20+
#include "spectral_transfer_1d.hpp"
21+
22+
using namespace std;
23+
using namespace pfasst;
24+
using namespace pfasst::encap;
25+
using namespace pfasst::mpi;
26+
27+
int main(int argc, char** argv)
28+
{
29+
MPI_Init(&argc, &argv);
30+
31+
const size_t nsteps = 4;
32+
const double dt = 0.01;
33+
const size_t niters = 4;
34+
35+
vector<pair<size_t, string>> nodes = {
36+
{ 3, "gauss-lobatto" },
37+
{ 5, "gauss-lobatto" }
38+
};
39+
40+
vector<size_t> ndofs = { 64, 128 };
41+
42+
auto build_level = [ndofs](size_t level) {
43+
auto factory = make_shared<MPIVectorFactory<double>>(ndofs[level]);
44+
auto sweeper = make_shared<AdvectionDiffusionSweeper<>>(ndofs[level]);
45+
auto transfer = make_shared<SpectralTransfer1D<>>();
46+
47+
return AutoBuildTuple<>(sweeper, transfer, factory);
48+
};
49+
50+
auto initial = [](shared_ptr<EncapSweeper<>> sweeper, shared_ptr<Encapsulation<>> q0) {
51+
auto ad = dynamic_pointer_cast<AdvectionDiffusionSweeper<>>(sweeper);
52+
assert(ad);
53+
ad->exact(q0, 0.0);
54+
};
55+
56+
MPICommunicator comm(MPI_COMM_WORLD);
57+
PFASST<> pf;
58+
59+
auto_build(pf, nodes, build_level);
60+
auto_setup(pf, initial);
61+
62+
pf.set_comm(&comm);
63+
pf.set_duration(0.0, nsteps * dt, dt, niters);
64+
pf.run();
65+
66+
fftw_cleanup();
67+
68+
MPI_Finalize();
69+
}

include/pfasst/controller.hpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <memory>
1010
#include <cassert>
1111
#include <iterator>
12+
#include <iostream>
1213

1314
#include "interfaces.hpp"
1415

@@ -31,7 +32,7 @@ namespace pfasst
3132

3233
public:
3334
//! @{
34-
void setup()
35+
virtual void setup()
3536
{
3637
for (auto l = coarsest(); l <= finest(); ++l) {
3738
l.current()->set_controller(this);
@@ -108,24 +109,24 @@ namespace pfasst
108109
* implementing a `RandomAccessIterator`.
109110
*/
110111
class LevelIter
111-
: iterator<random_access_iterator_tag, shared_ptr<ISweeper<time>>, size_t,
112+
: iterator<random_access_iterator_tag, shared_ptr<ISweeper<time>>, int,
112113
ISweeper<time>*, ISweeper<time>>
113114
{
114115
Controller* ts;
115116

116117
public:
117-
typedef size_t difference_type;
118+
typedef int difference_type;
118119
typedef shared_ptr<ISweeper<time>> value_type;
119120
typedef ISweeper<time>* pointer;
120121
typedef ISweeper<time> reference;
121122
typedef random_access_iterator_tag iterator_category;
122123

123-
size_t level;
124+
int level;
124125

125126
//! @{
126-
LevelIter(size_t level, Controller* ts)
127+
LevelIter(int level, Controller* ts)
127128
: ts(ts), level(level)
128-
{}
129+
{ }
129130
//! @}
130131

131132
//! @{
@@ -187,6 +188,12 @@ namespace pfasst
187188
return step;
188189
}
189190

191+
void set_step(size_t n)
192+
{
193+
t += (n - step)*dt;
194+
step = n;
195+
}
196+
190197
time get_time_step()
191198
{
192199
return dt;

include/pfasst/encap/encap_sweeper.hpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,29 @@ namespace pfasst
2525

2626
public:
2727

28+
virtual void post(ICommunicator* comm, int tag)
29+
{
30+
this->get_state(0)->post(comm, tag);
31+
}
32+
33+
virtual void send(ICommunicator* comm, int tag, bool blocking)
34+
{
35+
this->get_state(this->get_nodes().size() - 1)->send(comm, tag, blocking);
36+
}
37+
38+
virtual void recv(ICommunicator* comm, int tag, bool blocking)
39+
{
40+
this->get_state(0)->recv(comm, tag, blocking);
41+
}
42+
43+
virtual void broadcast(ICommunicator* comm)
44+
{
45+
if (comm->rank() == comm->size() - 1) {
46+
this->get_state(0)->copy(this->get_state(this->get_nodes().size() - 1));
47+
}
48+
this->get_state(0)->broadcast(comm);
49+
}
50+
2851
void set_nodes(vector<time> nodes)
2952
{
3053
this->nodes = nodes;
@@ -73,7 +96,7 @@ namespace pfasst
7396
return this->get_state(this->get_nodes().size() - 1);
7497
}
7598

76-
virtual void evaluate(size_t /*m*/)
99+
virtual void evaluate(size_t /*m*/)
77100
{
78101
throw NotImplementedYet("sweeper");
79102
}

include/pfasst/encap/encapsulation.hpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace pfasst
2121
typedef enum EncapType { solution, function } EncapType;
2222

2323
/**
24-
* basic encapsulation.
24+
* Data/solution encapsulation.
2525
*
2626
* An Encapsulation provides basic functionality of the user data used by PFASST such as
2727
* mathematical operation @em axpy \\(y=ax+y\\) and packing/unpacking for message passing.
@@ -38,11 +38,19 @@ namespace pfasst
3838

3939
//! @{
4040
// required for time-parallel communications
41-
virtual void send()
41+
virtual void post(ICommunicator* /*comm*/, int /*tag*/) { }
42+
43+
virtual void send(ICommunicator* /*comm*/, int /*tag*/, bool /*blocking*/)
44+
{
45+
throw NotImplementedYet("pfasst");
46+
}
47+
48+
virtual void recv(ICommunicator* /*comm*/, int /*tag*/, bool /*blocking*/)
4249
{
4350
throw NotImplementedYet("pfasst");
4451
}
45-
virtual void recv()
52+
53+
virtual void broadcast(ICommunicator* /*comm*/)
4654
{
4755
throw NotImplementedYet("pfasst");
4856
}

0 commit comments

Comments
 (0)