Skip to content

Commit

Permalink
Modernize stencil example
Browse files Browse the repository at this point in the history
  • Loading branch information
hkaiser committed May 29, 2023
1 parent 5940aad commit 1639f20
Show file tree
Hide file tree
Showing 13 changed files with 333 additions and 308 deletions.
4 changes: 2 additions & 2 deletions examples/03_stencil/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.14)

project(stencil CXX)

find_package(HPX 1.7.0 REQUIRED)
find_package(HPX 1.9.0 REQUIRED)

add_executable(stencil_serial stencil_serial.cpp)
target_link_libraries(stencil_serial PRIVATE HPX::hpx HPX::wrap_main)
Expand Down
50 changes: 29 additions & 21 deletions examples/03_stencil/communicator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef STENCIL_COMMUNICATOR_HPP
#define STENCIL_COMMUNICATOR_HPP
#pragma once

#include <hpx/include/lcos.hpp>

Expand All @@ -13,45 +12,56 @@
template <typename T>
struct communicator
{
enum neighbor {
enum neighbor
{
up = 0,
down = 1,
};

typedef hpx::lcos::channel<T> channel_type;
using channel_type = hpx::lcos::channel<T>;

// rank: our rank in the system
// num: number of participating partners
communicator(std::size_t rank, std::size_t num)
{
static const char* up_name = "/stencil/up/";
static const char* down_name = "/stencil/down/";

// Only set up channels if we have more than one partner
if (num > 1)
{
constexpr char const* down_name = "/stencil/down/";
constexpr char const* up_name = "/stencil/up/";

// We have an upper neighbor if our rank is greater than zero.
if (rank > 0)
{
// Retrieve the channel from our upper neighbor from which we receive
// the row we need to update the first row in our partition.
recv[up] = hpx::find_from_basename<channel_type>(down_name, rank - 1);
// Retrieve the channel from our upper neighbor from which we
// receive the row we need to update the first row in our
// partition.
recv[up] =
hpx::find_from_basename<channel_type>(down_name, rank - 1);

// Create the channel we use to send our first row to our upper
// neighbor
send[up] = channel_type(hpx::find_here());
// Register the channel with a name such that our neighbor can find it.

// Register the channel with a name such that our neighbor can
// find it.
hpx::register_with_basename(up_name, send[up], rank);
}

if (rank < num - 1)
{
// Retrieve the channel from our neighbor below from which we receive
// the row we need to update the last row in our partition.
recv[down] = hpx::find_from_basename<channel_type>(up_name, rank + 1);
// Create the channel we use to send our last row to our neighbor
// below
// Retrieve the channel from our neighbor below from which we
// receive the row we need to update the last row in our
// partition.
recv[down] =
hpx::find_from_basename<channel_type>(up_name, rank + 1);

// Create the channel we use to send our last row to our
// neighbor below
send[down] = channel_type(hpx::find_here());
// Register the channel with a name such that our neighbor can find it.

// Register the channel with a name such that our neighbor can
// find it.
hpx::register_with_basename(down_name, send[down], rank);
}
}
Expand All @@ -76,8 +86,6 @@ struct communicator
return recv[n].get(hpx::launch::async, step);
}

std::array<hpx::lcos::channel<T>, 2> recv;
std::array<hpx::lcos::channel<T>, 2> send;
std::array<hpx::distributed::channel<T>, 2> recv;
std::array<hpx::distributed::channel<T>, 2> send;
};

#endif
37 changes: 16 additions & 21 deletions examples/03_stencil/line_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,40 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef STENCIL_LINE_ITERATOR_HPP
#define STENCIL_LINE_ITERATOR_HPP
#pragma once

#include <hpx/include/util.hpp>

template <typename UpIter, typename MiddleIter = UpIter, typename DownIter = UpIter>
template <typename UpIter, typename MiddleIter = UpIter,
typename DownIter = UpIter>
struct line_iterator
// iterator_facade is a facade class that defines the boilerplate needed for
// a proper standard C++ iterator. As a user, we only have to define basic
// functions
// iterator_facade is a facade class that defines the boilerplate needed for a
// proper standard C++ iterator. As a user, we only have to define basic
// functions
: hpx::util::iterator_facade<
// Our type:
line_iterator<UpIter, MiddleIter, DownIter>,
// Value type (When dereferencing the iterator)
double,
// Our iterator is random access.
std::random_access_iterator_tag
>
std::random_access_iterator_tag>
{
private:
typedef
hpx::util::iterator_facade<
// Our type:
line_iterator<UpIter, MiddleIter, DownIter>,
// Value type (When dereferencing the iterator)
double,
// Our iterator is random access.
std::random_access_iterator_tag
>
base_type;
using base_type = hpx::util::iterator_facade<
// Our type:
line_iterator<UpIter, MiddleIter, DownIter>,
// Value type (When dereferencing the iterator)
double,
// Our iterator is random access.
std::random_access_iterator_tag>;

public:
line_iterator(UpIter up_, MiddleIter middle_, DownIter down_)
: up(up_)
, middle(middle_)
, down(down_)
{}
{
}

UpIter up;
MiddleIter middle;
Expand Down Expand Up @@ -84,5 +81,3 @@ struct line_iterator
return other.middle - middle;
}
};

#endif
13 changes: 5 additions & 8 deletions examples/03_stencil/output.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,21 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef STENCIL_OUTPUT_HPP
#define STENCIL_OUTPUT_HPP
#pragma once

#include <fstream>
#include <string>

template <typename Container>
void output(std::string name, Container const& data, std::size_t Nx, std::size_t Ny)
void output(std::string const& name, Container const& data, std::size_t Nx,
std::size_t Ny)
{
std::ofstream file(name);

for(std::size_t y = 0; y != Ny; ++y)
for (std::size_t y = 0; y != Ny; ++y)
{
for(std::size_t x = 0; x != Nx; ++x)
for (std::size_t x = 0; x != Nx; ++x)
{
file << x << " " << y << " " << data[y * Nx + x] << '\n';
}
}
}

#endif
34 changes: 16 additions & 18 deletions examples/03_stencil/row_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#ifndef STENCIL_ROW_ITERATOR_HPP
#define STENCIL_ROW_ITERATOR_HPP
#pragma once

#include "line_iterator.hpp"

#include <hpx/include/util.hpp>

template <typename UpIter, typename MiddleIter = UpIter, typename DownIter = UpIter>
template <typename UpIter, typename MiddleIter = UpIter,
typename DownIter = UpIter>
struct row_iterator
// iterator_facade is a facade class that defines the boilerplate needed for
// a proper standard C++ iterator. As a user, we only have to define basic
// functions
// iterator_facade is a facade class that defines the boilerplate needed for a
// proper standard C++ iterator. As a user, we only have to define basic
// functions
: hpx::util::iterator_facade<
// Our type:
row_iterator<UpIter, MiddleIter, DownIter>,
Expand All @@ -24,17 +24,17 @@ struct row_iterator
std::random_access_iterator_tag,
// Since dereferencing should return a new line_iterator, we need to
// explicitly set the reference type.
line_iterator<UpIter, MiddleIter, DownIter>
>
line_iterator<UpIter, MiddleIter, DownIter>>
{
typedef line_iterator<UpIter, MiddleIter, DownIter> line_iterator_type;
using line_iterator_type = line_iterator<UpIter, MiddleIter, DownIter>;

row_iterator(std::size_t Nx, MiddleIter middle_)
: up_(middle - Nx)
, middle(middle_)
: middle(middle_)
, up_(middle - Nx)
, down_(middle + Nx)
, Nx_(Nx)
{}
{
}

line_iterator<UpIter, MiddleIter, DownIter> line() const
{
Expand All @@ -45,16 +45,16 @@ struct row_iterator
line_iterator<typename Container::const_iterator, MiddleIter, DownIter>
top_boundary(Container const& cont) const
{
return line_iterator<typename Container::const_iterator, MiddleIter, DownIter>(
cont.begin(), middle, down_);
return line_iterator<typename Container::const_iterator, MiddleIter,
DownIter>(cont.begin(), middle, down_);
}

template <typename Container>
line_iterator<UpIter, MiddleIter, typename Container::const_iterator>
bottom_boundary(Container const& cont) const
{
return line_iterator<UpIter, MiddleIter, typename Container::const_iterator>(
up_, middle, cont.begin());
return line_iterator<UpIter, MiddleIter,
typename Container::const_iterator>(up_, middle, cont.begin());
}

MiddleIter middle;
Expand Down Expand Up @@ -102,5 +102,3 @@ struct row_iterator
DownIter down_;
std::size_t Nx_;
};

#endif
15 changes: 10 additions & 5 deletions examples/03_stencil/stencil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#pragma once

#include "line_iterator.hpp"
#include "row_iterator.hpp"

#include <algorithm>
#include <array>

template <typename Container>
void init(
std::array<Container, 2>& U, std::size_t Nx, std::size_t Ny,
void init(std::array<Container, 2>& U, std::size_t Nx, std::size_t Ny,
std::size_t rank = 0, std::size_t num_localities = 1)
{
// Initialize: Boundaries are set to 1, interior is 0
Expand All @@ -20,6 +21,7 @@ void init(
std::fill(U[0].begin(), U[0].begin() + Nx, 1.0);
std::fill(U[1].begin(), U[1].begin() + Nx, 1.0);
}

for (std::size_t y = 0; y < Ny; ++y)
{
U[0][y * Nx + 0] = 1.0;
Expand All @@ -28,6 +30,7 @@ void init(
U[0][y * Nx + (Nx - 1)] = 1.0;
U[1][y * Nx + (Nx - 1)] = 1.0;
}

if (rank == num_localities - 1)
{
std::fill(U[0].end() - Nx, U[0].end(), 1.0);
Expand All @@ -39,12 +42,14 @@ template <typename InIter, typename OutIter>
OutIter line_update(InIter begin, InIter end, OutIter result)
{
++result;

// Iterate over the interior: skip the last and first element
for(InIter it = begin + 1; it != end - 1; ++it, ++result)
for (InIter it = begin + 1; it != end - 1; ++it, ++result)
{
*result = 0.25 * (it.up[-1] + it.up[+1] + it.down[-1] + it.down[+1])
- *it.middle;
*result = 0.25 * (it.up[-1] + it.up[+1] + it.down[-1] + it.down[+1]) -
*it.middle;
}

++result;

return result;
Expand Down
Loading

0 comments on commit 1639f20

Please sign in to comment.