Skip to content

Commit 1fb9667

Browse files
authored
Merge pull request #556 from lanl/jdolence/iterative_tasks
Iterative Tasks
2 parents a4356fc + 91a455c commit 1fb9667

22 files changed

+1112
-44
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Current develop
44

55
### Added (new features/APIs/variables/...)
6+
- [[PR 556]](https://github.com/lanl/parthenon/pull/556) Introduce iterative tasks and regionally dependent tasks
67
- [[PR 578]](https://github.com/lanl/parthenon/pull/578) Add some profiling regions to tasks in particles example
78
- [[PR 577]](https://github.com/lanl/parthenon/pull/577) Update invalid indices to allow for no-op loops
89
- [[PR 564]](https://github.com/lanl/parthenon/pull/564) Add EstimateTimestep to particles example task list

CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ include(cmake/Format.cmake)
6767
include(cmake/Lint.cmake)
6868

6969
# regression test reference data
70-
set(REGRESSION_GOLD_STANDARD_VER 10 CACHE STRING "Version of gold standard to download and use")
70+
set(REGRESSION_GOLD_STANDARD_VER 11 CACHE STRING "Version of gold standard to download and use")
7171
set(REGRESSION_GOLD_STANDARD_HASH
72-
"SHA512=59c0eec495bab38629edae9c99e1da51d68f7a2815087638d0b6b2fb7558e5d34171caae32b552fa52c10abe0fb3b720723c3b2a12645f8e144e7d134e7fe98b"
72+
"SHA512=11fdcb9e42457f41f2f4d4cce4636a73cdab601eac9638fb63f9284c10dc90f5719b190e075a079c13804d8126e56a80590ffc71c6cc5eeb0d0afa72cbeaa9a1"
7373
CACHE STRING "Hash of default gold standard file to download")
7474
option(REGRESSION_GOLD_STANDARD_SYNC "Automatically sync gold standard files." ON)
7575

docs/tasks.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Tasks
22

33
## TaskList
4-
The `TaskList` class implements methods to build and execute a set of tasks with associated dependencies. The main functionality of the class is implemented in two member functions:
4+
The `TaskList` class implements methods to build and execute a set of tasks with associated dependencies. The class implements a few public facing member functions that provide useful functionality for downstream apps:
55

66
### AddTask
77
`AddTask` is a templated variadic function that takes the task function to be executed, the task dependencies (see `TaskID` below), and the arguments to the task function as it's arguments. All arguments are captured by value in a lambda for later execution.
@@ -10,14 +10,17 @@ When adding functions that are non-static class member functions, a slightly dif
1010

1111
Examples of both `AddTask` calls can be found in the advection example [here](../example/advection/advection_driver.cpp).
1212

13+
### AddIteration
14+
`AddIteration` provides a means of grouping a set of tasks together that will be executed repeatedly until stopping criteria are satisfied. `AddIteration` returns an `IterativeTasks` object which provides overloaded `AddTask` functions as described above, but internally handles the bookkeeping necessary to maintain the association of all the tasks associated with the iterative process. A special function `SetCompletionTask`, which behaves identically to `AddTask`, allows a task to be defined that evaluates the stopping criteria. The maximum number of iterations can be controlled through the `SetMaxIterations` member function and the number of iterations between evaluating the stopping criteria can be set with the `SetCheckInterval` function.
15+
1316
### DoAvailable
14-
`DoAvailable` loops over the task list once, executing all tasks whose dependencies are satisfied. The function returns either `TaskListStatus::complete` if all tasks have been executed (and the task list is therefore empty) or `TaskListStatus::running` if tasks remain to be completed.
17+
`DoAvailable` loops over the task list once, executing all tasks whose dependencies are satisfied. Completed tasks are removed from the task list.
1518

1619
## TaskID
1720
The `TaskID` class implements methods that allow Parthenon to keep track of tasks, their dependencies, and what remains to be completed. The main way application code will interact with this object is as a returned object from `TaskList::AddTask` and as an argument to subsequent calls to `TaskList::AddTask` as a dependency for other tasks. When used as a dependency, `TaskID` objects can be combined with the bitwise or operator (`|`) to specify multiple dependencies.
1821

1922
## TaskRegion
20-
`TaskRegion` is defined via a simple using statement as a `std::vector<TaskList>`. During task execution (described below), all task lists in a `TaskRegion` can be operated on concurrently. For example, a `TaskRegion` can be used to construct independent task lists for each `MeshBlock`.
23+
`TaskRegion` is a lightweight class that wraps `std::vector<TaskList>`, providing a little extra functionality. During task execution (described below), all task lists in a `TaskRegion` can be operated on concurrently. For example, a `TaskRegion` can be used to construct independent task lists for each `MeshBlock`. Occasionally, it is useful to have a task not be considered complete until that task completes in all lists of a region. For example, a global iterative solver cannot be considered complete until the stopping criteria are satisfied everywhere, which may require evaluating those criteria in tasks that live in different lists within a region. An example of this use case is shown[here](../example/poisson/poisson_driver.cpp).
2124

2225
## TaskCollection
2326
A `TaskCollection` contains a `std::vector<TaskRegion>`, i.e. an ordered list of `TaskRegion`s. Importantly, each `TaskRegion` will be executed to completion before subsequent `TaskRegion`s, introducing a notion of sequential execution and enabling flexibility in task granularity. For example, the following code fragment uses the `TaskCollection` and `TaskRegion` abstractions to express work that can be done asynchronously across blocks, followed by a bulk synchronous task involving all blocks, and finally another round of asynchronous work.

example/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ add_subdirectory(kokkos_pi)
1919
add_subdirectory(particles)
2020
add_subdirectory(particle_leapfrog)
2121
add_subdirectory(particle_tracers)
22+
add_subdirectory(poisson)

example/poisson/CMakeLists.txt

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#=========================================================================================
2+
# (C) (or copyright) 2021. Triad National Security, LLC. All rights reserved.
3+
#
4+
# This program was produced under U.S. Government contract 89233218CNA000001 for Los
5+
# Alamos National Laboratory (LANL), which is operated by Triad National Security, LLC
6+
# for the U.S. Department of Energy/National Nuclear Security Administration. All rights
7+
# in the program are reserved by Triad National Security, LLC, and the U.S. Department
8+
# of Energy/National Nuclear Security Administration. The Government is granted for
9+
# itself and others acting on its behalf a nonexclusive, paid-up, irrevocable worldwide
10+
# license in this material to reproduce, prepare derivative works, distribute copies to
11+
# the public, perform publicly and display publicly, and to permit others to do so.
12+
#=========================================================================================
13+
14+
get_property(DRIVER_LIST GLOBAL PROPERTY DRIVERS_USED_IN_TESTS)
15+
if( "poisson-example" IN_LIST DRIVER_LIST OR NOT PARTHENON_DISABLE_EXAMPLES)
16+
add_executable(
17+
poisson-example
18+
poisson_driver.cpp
19+
poisson_driver.hpp
20+
poisson_package.cpp
21+
poisson_package.hpp
22+
main.cpp
23+
parthenon_app_inputs.cpp
24+
)
25+
target_link_libraries(poisson-example PRIVATE Parthenon::parthenon)
26+
lint_target(poisson-example)
27+
endif()

example/poisson/main.cpp

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//========================================================================================
2+
// (C) (or copyright) 2021. Triad National Security, LLC. All rights reserved.
3+
//
4+
// This program was produced under U.S. Government contract 89233218CNA000001 for Los
5+
// Alamos National Laboratory (LANL), which is operated by Triad National Security, LLC
6+
// for the U.S. Department of Energy/National Nuclear Security Administration. All rights
7+
// in the program are reserved by Triad National Security, LLC, and the U.S. Department
8+
// of Energy/National Nuclear Security Administration. The Government is granted for
9+
// itself and others acting on its behalf a nonexclusive, paid-up, irrevocable worldwide
10+
// license in this material to reproduce, prepare derivative works, distribute copies to
11+
// the public, perform publicly and display publicly, and to permit others to do so.
12+
//========================================================================================
13+
14+
#include "parthenon_manager.hpp"
15+
16+
#include "poisson_driver.hpp"
17+
18+
int main(int argc, char *argv[]) {
19+
using parthenon::ParthenonManager;
20+
using parthenon::ParthenonStatus;
21+
ParthenonManager pman;
22+
23+
// Redefine parthenon defaults
24+
pman.app_input->ProcessPackages = poisson_example::ProcessPackages;
25+
pman.app_input->ProblemGenerator = poisson_example::ProblemGenerator;
26+
27+
// call ParthenonInit to initialize MPI and Kokkos, parse the input deck, and set up
28+
auto manager_status = pman.ParthenonInit(argc, argv);
29+
if (manager_status == ParthenonStatus::complete) {
30+
pman.ParthenonFinalize();
31+
return 0;
32+
}
33+
if (manager_status == ParthenonStatus::error) {
34+
pman.ParthenonFinalize();
35+
return 1;
36+
}
37+
// Now that ParthenonInit has been called and setup succeeded, the code can now
38+
// make use of MPI and Kokkos
39+
40+
// Initialize the driver
41+
poisson_example::PoissonDriver driver(pman.pinput.get(), pman.app_input.get(),
42+
pman.pmesh.get());
43+
44+
// This line actually runs the simulation
45+
auto driver_status = driver.Execute();
46+
47+
// call MPI_Finalize and Kokkos::finalize if necessary
48+
pman.ParthenonFinalize();
49+
50+
// MPI and Kokkos can no longer be used
51+
52+
return (0);
53+
}
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//========================================================================================
2+
// (C) (or copyright) 2021. Triad National Security, LLC. All rights reserved.
3+
//
4+
// This program was produced under U.S. Government contract 89233218CNA000001 for Los
5+
// Alamos National Laboratory (LANL), which is operated by Triad National Security, LLC
6+
// for the U.S. Department of Energy/National Nuclear Security Administration. All rights
7+
// in the program are reserved by Triad National Security, LLC, and the U.S. Department
8+
// of Energy/National Nuclear Security Administration. The Government is granted for
9+
// itself and others acting on its behalf a nonexclusive, paid-up, irrevocable worldwide
10+
// license in this material to reproduce, prepare derivative works, distribute copies to
11+
// the public, perform publicly and display publicly, and to permit others to do so.
12+
//========================================================================================
13+
14+
#include <sstream>
15+
#include <string>
16+
17+
#include <parthenon/package.hpp>
18+
19+
#include "config.hpp"
20+
#include "defs.hpp"
21+
#include "poisson_package.hpp"
22+
#include "utils/error_checking.hpp"
23+
24+
using namespace parthenon::package::prelude;
25+
using namespace parthenon;
26+
27+
// *************************************************//
28+
// redefine some weakly linked parthenon functions *//
29+
// *************************************************//
30+
31+
namespace poisson_example {
32+
33+
void ProblemGenerator(MeshBlock *pmb, ParameterInput *pin) {
34+
auto &data = pmb->meshblock_data.Get();
35+
36+
Real x0 = pin->GetOrAddReal("poisson", "x0", 0.0);
37+
Real y0 = pin->GetOrAddReal("poisson", "y0", 0.0);
38+
Real z0 = pin->GetOrAddReal("poisson", "z0", 0.0);
39+
Real radius = pin->GetOrAddReal("poisson", "radius", 0.1);
40+
41+
auto cellbounds = pmb->cellbounds;
42+
IndexRange ib = cellbounds.GetBoundsI(IndexDomain::entire);
43+
IndexRange jb = cellbounds.GetBoundsJ(IndexDomain::entire);
44+
IndexRange kb = cellbounds.GetBoundsK(IndexDomain::entire);
45+
46+
auto coords = pmb->coords;
47+
PackIndexMap imap;
48+
const std::vector<std::string> vars({"density", "potential"});
49+
const auto &q = data->PackVariables(vars, imap);
50+
const int irho = imap["density"].first;
51+
const int iphi = imap["potential"].first;
52+
53+
pmb->par_for(
54+
"Poisson::ProblemGenerator", kb.s, kb.e, jb.s, jb.e, ib.s, ib.e,
55+
KOKKOS_LAMBDA(const int k, const int j, const int i) {
56+
Real dist2 = std::pow(coords.x1v(i) - x0, 2) + std::pow(coords.x2v(j) - y0, 2) +
57+
std::pow(coords.x3v(k) - z0, 2);
58+
if (dist2 < radius * radius) {
59+
q(irho, k, j, i) = 1.0 / (4.0 / 3.0 * M_PI * std::pow(radius, 3));
60+
} else {
61+
q(irho, k, j, i) = 0.0;
62+
}
63+
q(iphi, k, j, i) = 0.0;
64+
});
65+
}
66+
67+
Packages_t ProcessPackages(std::unique_ptr<ParameterInput> &pin) {
68+
Packages_t packages;
69+
auto pkg = poisson_package::Initialize(pin.get());
70+
packages.Add(pkg);
71+
72+
return packages;
73+
}
74+
75+
} // namespace poisson_example

example/poisson/parthinput.poisson

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# ========================================================================================
2+
# Athena++ astrophysical MHD code
3+
# Copyright(C) 2014 James M. Stone <[email protected]> and other code contributors
4+
# Licensed under the 3-clause BSD License, see LICENSE file for details
5+
# ========================================================================================
6+
# (C) (or copyright) 21. Triad National Security, LLC. All rights reserved.
7+
#
8+
# This program was produced under U.S. Government contract 89233218CNA000001 for Los
9+
# Alamos National Laboratory (LANL), which is operated by Triad National Security, LLC
10+
# for the U.S. Department of Energy/National Nuclear Security Administration. All rights
11+
# in the program are reserved by Triad National Security, LLC, and the U.S. Department
12+
# of Energy/National Nuclear Security Administration. The Government is granted for
13+
# itself and others acting on its behalf a nonexclusive, paid-up, irrevocable worldwide
14+
# license in this material to reproduce, prepare derivative works, distribute copies to
15+
# the public, perform publicly and display publicly, and to permit others to do so.
16+
# ========================================================================================
17+
18+
<parthenon/job>
19+
problem_id = poisson
20+
21+
<parthenon/mesh>
22+
23+
nx1 = 64
24+
x1min = -1.0
25+
x1max = 1.0
26+
ix1_bc = outflow
27+
ox1_bc = outflow
28+
29+
nx2 = 64
30+
x2min = -1.0
31+
x2max = 1.0
32+
ix2_bc = outflow
33+
ox2_bc = outflow
34+
35+
nx3 = 1
36+
x3min = -0.5
37+
x3max = 0.5
38+
ix3_bc = periodic
39+
ox3_bc = periodic
40+
41+
<parthenon/meshblock>
42+
nx1 = 16
43+
nx2 = 16
44+
nx3 = 1
45+
46+
<parthenon/time>
47+
#nlim = -1
48+
#tlim = 1.0
49+
#integrator = rk2
50+
#ncycle_out_mesh = -10000
51+
52+
<parthenon/output0>
53+
file_type = hdf5
54+
dt = 0.05
55+
variables = potential, density
56+
57+
<poisson>
58+
max_iterations = 100000
59+
check_interval = 100
60+
error_tolerance = 1.e-8
61+
fail_without_convergence = false
62+
warn_without_convergence = true

example/poisson/poisson_driver.cpp

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
//========================================================================================
2+
// (C) (or copyright) 2021. Triad National Security, LLC. All rights reserved.
3+
//
4+
// This program was produced under U.S. Government contract 89233218CNA000001 for Los
5+
// Alamos National Laboratory (LANL), which is operated by Triad National Security, LLC
6+
// for the U.S. Department of Energy/National Nuclear Security Administration. All rights
7+
// in the program are reserved by Triad National Security, LLC, and the U.S. Department
8+
// of Energy/National Nuclear Security Administration. The Government is granted for
9+
// itself and others acting on its behalf a nonexclusive, paid-up, irrevocable worldwide
10+
// license in this material to reproduce, prepare derivative works, distribute copies to
11+
// the public, perform publicly and display publicly, and to permit others to do so.
12+
//========================================================================================
13+
14+
#include <memory>
15+
#include <string>
16+
#include <vector>
17+
18+
// Local Includes
19+
#include "bvals/cc/bvals_cc_in_one.hpp"
20+
#include "interface/metadata.hpp"
21+
#include "interface/update.hpp"
22+
#include "mesh/meshblock_pack.hpp"
23+
#include "mesh/refinement_cc_in_one.hpp"
24+
#include "parthenon/driver.hpp"
25+
#include "poisson_driver.hpp"
26+
#include "poisson_package.hpp"
27+
#include "refinement/refinement.hpp"
28+
29+
using namespace parthenon::driver::prelude;
30+
31+
namespace poisson_example {
32+
33+
parthenon::DriverStatus PoissonDriver::Execute() {
34+
pouts->MakeOutputs(pmesh, pinput);
35+
ConstructAndExecuteTaskLists<>(this);
36+
pouts->MakeOutputs(pmesh, pinput);
37+
return DriverStatus::complete;
38+
}
39+
40+
TaskCollection PoissonDriver::MakeTaskCollection(BlockList_t &blocks) {
41+
using namespace parthenon::Update;
42+
TaskCollection tc;
43+
TaskID none(0);
44+
45+
for (int i = 0; i < blocks.size(); i++) {
46+
auto &pmb = blocks[i];
47+
auto &base = pmb->meshblock_data.Get();
48+
pmb->meshblock_data.Add("delta", base);
49+
}
50+
51+
int max_iters = pmesh->packages.Get("poisson_package")->Param<int>("max_iterations");
52+
int check_interval =
53+
pmesh->packages.Get("poisson_package")->Param<int>("check_interval");
54+
bool fail_flag =
55+
pmesh->packages.Get("poisson_package")->Param<bool>("fail_without_convergence");
56+
bool warn_flag =
57+
pmesh->packages.Get("poisson_package")->Param<bool>("warn_without_convergence");
58+
59+
const int num_partitions = pmesh->DefaultNumPartitions();
60+
TaskRegion &solver_region = tc.AddRegion(num_partitions);
61+
62+
for (int i = 0; i < num_partitions; i++) {
63+
// make/get a mesh_data container for the state
64+
auto &md = pmesh->mesh_data.GetOrAdd("base", i);
65+
auto &mdelta = pmesh->mesh_data.GetOrAdd("delta", i);
66+
67+
TaskList &tl = solver_region[i];
68+
69+
auto &solver = tl.AddIteration("poisson solver");
70+
solver.SetMaxIterations(max_iters);
71+
solver.SetCheckInterval(check_interval);
72+
solver.SetFailWithMaxIterations(fail_flag);
73+
solver.SetWarnWithMaxIterations(warn_flag);
74+
auto start_recv = solver.AddTask(none, &MeshData<Real>::StartReceiving, md.get(),
75+
BoundaryCommSubset::all);
76+
77+
auto update = solver.AddTask(none, poisson_package::UpdatePhi<MeshData<Real>>,
78+
md.get(), mdelta.get());
79+
80+
auto send =
81+
solver.AddTask(update, parthenon::cell_centered_bvars::SendBoundaryBuffers, md);
82+
83+
auto recv = solver.AddTask(
84+
start_recv, parthenon::cell_centered_bvars::ReceiveBoundaryBuffers, md);
85+
86+
auto setb =
87+
solver.AddTask(recv | update, parthenon::cell_centered_bvars::SetBoundaries, md);
88+
89+
auto clear = solver.AddTask(send | setb, &MeshData<Real>::ClearBoundary, md.get(),
90+
BoundaryCommSubset::all);
91+
92+
auto check = solver.SetCompletionTask(
93+
clear, poisson_package::CheckConvergence<MeshData<Real>>, md.get(), mdelta.get());
94+
// mark task so that dependent tasks (below) won't execute
95+
// until all task lists have completed it
96+
solver_region.AddRegionalDependencies(0, i, check);
97+
98+
auto print = tl.AddTask(check, poisson_package::PrintComplete);
99+
}
100+
101+
return tc;
102+
}
103+
104+
} // namespace poisson_example

0 commit comments

Comments
 (0)