An open API service indexing awesome lists of open source software.

https://github.com/r-barnes/swiftscape


https://github.com/r-barnes/swiftscape

Last synced: 2 months ago
JSON representation

Awesome Lists containing this project

README

        

# Overview

This is a landscape evolution model that evolves a height field forward through
time including uplift and erosion. A benchmarking script is included.

Each cell is modeled as contributing flow to at most one downstream neighbor.

The erosion part of the model uses Newton-Rhapson iteration to solve a backwards
Euler equation between a cell and its downstream neighbor to determine the new
elevation of the cell.

The edge of the domain is taken as fixed. This forms the boundary condition for
the backwards Euler.

There are several steps to the model.

1. Receivers are calculated - the cells that receive the flow. If the receivers do not change from one step to the next
then the donors, ordering, and flow accumulation don't need to be recalculated. However, for some models the
receivers will change frequently, so it's important that these steps still be as performant as possible.

2. Donors are calculated - all the cells that flow into a given cell

3. A processing order is determined. Since each cell flows into one downstream
cell (and a downstream cell can have several upstream cells flowing into it)
the flow directions form a directed acyclic graph (DAG). We need, explicitly
or implicitly, a topological ordering for this graph. There are two ways we
could generate it: by starting at local maxima and working to the edge of the
domain or by starting at the edge of the domain and working towards local
maxima.

Starting at local maxima and working to the edge of the domain doesn't seem like
it would work well since downstream cells can depend on more than one upstream
cell, so some array with atomic accesses might be needed to keep track of how
many upstream cells each downstream cell needs to have resolved before it can go
into the ordering.

Starting at the edge of the domain and working towards local maxima is therefore
the route we choose. The cells at the edge form the first "level" of the
ordering and add the cells that flow into them to make the second level. This
continues until the local maxima are all reached.

I have a kernel for this which uses shared memory to do stream compaction
locally, but it doesn't seem faster than doing stream compaction to global
memory directly.

4. Flow accumulation. In parallel each level adds its flow (number of upstream
cells) to the level below it. Levels are processed from the maxima to the
edge.

5. Uplift. Height is added to each cell

6. Erosion. In parallel each level erodes the height of the cells above it.
Levels are processed from the edge to the maxima.

Eventually, the erosion step can be accelerated by learning a function to replace the
Newton-Rhapson iteration with a non-iterative calculation. My preliminary investigations show
that there are some regimes for which the mapping is almost linear, which can be a massive speed-up.

# Prerequisites

Install
```
pip3 install pybind11
```

# Building Python Package

```
cd wrappers/python
# Note, you may need to edit pyproject.toml for your GPU's compute capability
pip install .
```

# Compiling C++ Code

The code uses `cmake` to compile.

Compile with:
```
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ..
make -j 6
```
For performance reasons, it is advisable to add
`-DCMAKE_CUDA_ARCHITECTURES=` to the above. Possible values include:
```
Machine GPU ARCH VALUE
Thinkpad P1 Gen 1 Quadro P2000 61
Google Colabs T4 75
```

This produces:
* `benchmark.exe`: Benchmarks the model
* `test.exe`: Tests the model and all the functions. If the test successfully reaches something
like `### Test Step = 13`, it has run successfully, even if it appears to fail.
Floating-point differences between the CPU and GPU cause slow divergence.
* `example.exe`: An example that allows varying sizes of domain and initial seeds

# Misc

Reformat all files:
```
clang-format -i `find . | grep -E "\.(cu|cpp|h|hpp)$" | grep -v build`
```
or in the build directory type
```
make format
```