Skip to content

Commit

Permalink
Replace std::transform with std::ranges::transform (FEniCS#3297)
Browse files Browse the repository at this point in the history
* Use std::for_each over std::transform for in place operations

* Fix missing ranges

* Fix plaza

* Switch to std::ranges::transform instead of for_each

* Switch to const version of array

* std::transform -> std::ranges::transform

* Apply suggestions from code review

Co-authored-by: Garth N. Wells <gnw20@cam.ac.uk>

* Apply suggestion

Co-authored-by: Garth N. Wells <gnw20@cam.ac.uk>

---------

Co-authored-by: Garth N. Wells <gnw20@cam.ac.uk>
  • Loading branch information
schnellerhase and garth-wells authored Jul 15, 2024
1 parent 4ee1aa5 commit 830a9e9
Show file tree
Hide file tree
Showing 34 changed files with 321 additions and 371 deletions.
3 changes: 1 addition & 2 deletions cpp/demo/interpolation-io/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ void interpolate_nedelec(std::shared_ptr<mesh::Mesh<U>> mesh,
{
std::vector<T> f(2 * x.extent(1), 0.0);
std::copy_n(x.data_handle(), f.size(), f.begin());
std::transform(f.cbegin(), f.cend(), f.begin(),
[](auto x) { return x + T(1); });
std::ranges::transform(f, f.begin(), [](auto x) { return x + T(1); });
return {f, {2, x.extent(1)}};
},
cells1);
Expand Down
5 changes: 2 additions & 3 deletions cpp/demo/poisson_matrix_free/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ namespace linalg
/// @param[in] y
void axpy(auto&& r, auto alpha, auto&& x, auto&& y)
{
std::transform(x.array().begin(), x.array().end(), y.array().begin(),
r.mutable_array().begin(),
[alpha](auto x, auto y) { return alpha * x + y; });
std::ranges::transform(x.array(), y.array(), r.mutable_array().begin(),
[alpha](auto x, auto y) { return alpha * x + y; });
}

/// @brief Solve problem A.x = b using the conjugate gradient (CG)
Expand Down
111 changes: 52 additions & 59 deletions cpp/dolfinx/common/IndexMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,8 @@ communicate_ghosts_to_owners(MPI_Comm comm, std::span<const int> src,
}

// Count number of ghosts per dest
std::transform(send_data.begin(), send_data.end(),
std::back_inserter(send_sizes),
[](auto& d) { return d.size(); });
std::ranges::transform(send_data, std::back_inserter(send_sizes),
[](auto& d) { return d.size(); });

// Send how many indices I ghost to each owner, and receive how many
// of my indices other ranks ghost
Expand Down Expand Up @@ -560,14 +559,13 @@ common::compute_owned_indices(std::span<const std::int32_t> indices,
std::vector<std::int32_t> owned;
owned.reserve(num_ghost_indices + recv_buffer.size());
std::copy(indices.begin(), it_owned_end, std::back_inserter(owned));
std::transform(recv_buffer.begin(), recv_buffer.end(),
std::back_inserter(owned),
[range = map.local_range()](auto idx)
{
assert(idx >= range[0]);
assert(idx < range[1]);
return idx - range[0];
});
std::ranges::transform(recv_buffer, std::back_inserter(owned),
[range = map.local_range()](auto idx)
{
assert(idx >= range[0]);
assert(idx < range[1]);
return idx - range[0];
});

std::ranges::sort(owned);
owned.erase(std::unique(owned.begin(), owned.end()), owned.end());
Expand All @@ -590,9 +588,8 @@ common::stack_index_maps(

// Get local offset (into new map) for each index map
std::vector<std::int32_t> local_sizes;
std::transform(maps.begin(), maps.end(), std::back_inserter(local_sizes),
[](auto map)
{ return map.second * map.first.get().size_local(); });
std::ranges::transform(maps, std::back_inserter(local_sizes), [](auto& map)
{ return map.second * map.first.get().size_local(); });
std::vector<std::int32_t> local_offset(local_sizes.size() + 1, 0);
std::partial_sum(local_sizes.begin(), local_sizes.end(),
std::next(local_offset.begin()));
Expand Down Expand Up @@ -657,9 +654,8 @@ common::stack_index_maps(
}

// Count number of ghosts per dest
std::transform(ghost_by_rank.begin(), ghost_by_rank.end(),
std::back_inserter(send_sizes),
[](auto& g) { return g.size(); });
std::ranges::transform(ghost_by_rank, std::back_inserter(send_sizes),
[](auto& g) { return g.size(); });

// Send buffer and ghost position to send buffer position
for (auto& g : ghost_by_rank)
Expand Down Expand Up @@ -880,8 +876,8 @@ void IndexMap::local_to_global(std::span<const std::int32_t> local,
{
assert(local.size() <= global.size());
const std::int32_t local_size = _local_range[1] - _local_range[0];
std::transform(
local.begin(), local.end(), global.begin(),
std::ranges::transform(
local, global.begin(),
[local_size, local_range = _local_range[0], &ghosts = _ghosts](auto local)
{
if (local < local_size)
Expand All @@ -904,22 +900,23 @@ void IndexMap::global_to_local(std::span<const std::int64_t> global,
global_to_local[i] = {_ghosts[i], i + local_size};

std::ranges::sort(global_to_local);
std::transform(global.begin(), global.end(), local.begin(),
[range = _local_range,
&global_to_local](std::int64_t index) -> std::int32_t
{
if (index >= range[0] and index < range[1])
return index - range[0];
else
{
auto it = std::ranges::lower_bound(
global_to_local, index, std::ranges::less(),
[](auto& e) { return e.first; });
return (it != global_to_local.end() and it->first == index)
? it->second
: -1;
}
});
std::ranges::transform(
global, local.begin(),
[range = _local_range,
&global_to_local](std::int64_t index) -> std::int32_t
{
if (index >= range[0] and index < range[1])
return index - range[0];
else
{
auto it = std::ranges::lower_bound(global_to_local, index,
std::ranges::less(),
[](auto e) { return e.first; });
return (it != global_to_local.end() and it->first == index)
? it->second
: -1;
}
});
}
//-----------------------------------------------------------------------------
std::vector<std::int64_t> IndexMap::global_indices() const
Expand Down Expand Up @@ -957,19 +954,17 @@ graph::AdjacencyList<int> IndexMap::index_to_dest_ranks() const
{
// Build list of (owner rank, index) pairs for each ghost index, and sort
std::vector<std::pair<int, std::int64_t>> owner_to_ghost;
std::transform(_ghosts.begin(), _ghosts.end(), _owners.begin(),
std::back_inserter(owner_to_ghost),
[](auto idx, auto r) -> std::pair<int, std::int64_t>
{ return {r, idx}; });
std::ranges::transform(_ghosts, _owners, std::back_inserter(owner_to_ghost),
[](auto idx, auto r) -> std::pair<int, std::int64_t>
{ return {r, idx}; });
std::ranges::sort(owner_to_ghost);

// Build send buffer (the second component of each pair in
// owner_to_ghost) to send to rank that owns the index
std::vector<std::int64_t> send_buffer;
send_buffer.reserve(owner_to_ghost.size());
std::transform(owner_to_ghost.begin(), owner_to_ghost.end(),
std::back_inserter(send_buffer),
[](auto x) { return x.second; });
std::ranges::transform(owner_to_ghost, std::back_inserter(send_buffer),
[](auto x) { return x.second; });

// Compute send sizes and displacements
std::vector<int> send_sizes, send_disp{0};
Expand Down Expand Up @@ -1023,8 +1018,8 @@ graph::AdjacencyList<int> IndexMap::index_to_dest_ranks() const

// Build adjacency list data for (owned index) -> (ghosting ranks)
data.reserve(idx_to_rank.size());
std::transform(idx_to_rank.begin(), idx_to_rank.end(),
std::back_inserter(data), [](auto x) { return x.second; });
std::ranges::transform(idx_to_rank, std::back_inserter(data),
[](auto x) { return x.second; });
offsets.reserve(this->size_local() + this->num_ghosts() + 1);
{
auto it = idx_to_rank.begin();
Expand Down Expand Up @@ -1074,9 +1069,8 @@ graph::AdjacencyList<int> IndexMap::index_to_dest_ranks() const
}

// Count number of ghosts per destination and build send buffer
std::transform(dest_idx_to_rank.begin(), dest_idx_to_rank.end(),
std::back_inserter(send_sizes),
[](auto& x) { return x.size(); });
std::ranges::transform(dest_idx_to_rank, std::back_inserter(send_sizes),
[](auto& x) { return x.size(); });
for (auto& d : dest_idx_to_rank)
send_buffer.insert(send_buffer.end(), d.begin(), d.end());

Expand Down Expand Up @@ -1138,8 +1132,8 @@ graph::AdjacencyList<int> IndexMap::index_to_dest_ranks() const

// Add processed received data to adjacency list data array, and
// extend offset array
std::transform(idxpos_to_rank.begin(), idxpos_to_rank.end(),
std::back_inserter(data), [](auto x) { return x.second; });
std::ranges::transform(idxpos_to_rank, std::back_inserter(data),
[](auto x) { return x.second; });
auto it = idxpos_to_rank.begin();
for (std::size_t i = 0; i < _ghosts.size(); ++i)
{
Expand All @@ -1153,8 +1147,8 @@ graph::AdjacencyList<int> IndexMap::index_to_dest_ranks() const
}

// Convert ranks for owned indices from neighbour to global ranks
std::transform(idx_to_rank.begin(), idx_to_rank.end(), data.begin(),
[&dest](auto x) { return dest[x.second]; });
std::ranges::transform(idx_to_rank, data.begin(),
[&dest](auto x) { return dest[x.second]; });

return graph::AdjacencyList(std::move(data), std::move(offsets));
}
Expand Down Expand Up @@ -1214,14 +1208,13 @@ std::vector<std::int32_t> IndexMap::shared_indices() const

std::vector<std::int32_t> shared;
shared.reserve(recv_buffer.size());
std::transform(recv_buffer.begin(), recv_buffer.end(),
std::back_inserter(shared),
[range = _local_range](auto idx)
{
assert(idx >= range[0]);
assert(idx < range[1]);
return idx - range[0];
});
std::ranges::transform(recv_buffer, std::back_inserter(shared),
[range = _local_range](auto idx)
{
assert(idx >= range[0]);
assert(idx < range[1]);
return idx - range[0];
});

// Sort and remove duplicates
std::ranges::sort(shared);
Expand Down
9 changes: 4 additions & 5 deletions cpp/dolfinx/common/MPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,8 @@ distribute_to_postoffice(MPI_Comm comm, const U& x,
// Convert to local indices
const std::int64_t r0 = MPI::local_range(rank, shape[0], size)[0];
std::vector<std::int32_t> index_local(recv_buffer_index.size());
std::transform(recv_buffer_index.cbegin(), recv_buffer_index.cend(),
index_local.begin(), [r0](auto idx) { return idx - r0; });
std::ranges::transform(recv_buffer_index, index_local.begin(),
[r0](auto idx) { return idx - r0; });

return {index_local, recv_buffer_data};
}
Expand Down Expand Up @@ -549,9 +549,8 @@ distribute_from_postoffice(MPI_Comm comm, std::span<const std::int64_t> indices,
// post offices
assert(send_disp.back() == (int)src_to_index.size());
std::vector<std::int64_t> send_buffer_index(src_to_index.size());
std::transform(src_to_index.cbegin(), src_to_index.cend(),
send_buffer_index.begin(),
[](auto& x) { return std::get<1>(x); });
std::ranges::transform(src_to_index, send_buffer_index.begin(),
[](auto x) { return std::get<1>(x); });

// Prepare the receive buffer
std::vector<std::int64_t> recv_buffer_index(recv_disp.back());
Expand Down
14 changes: 6 additions & 8 deletions cpp/dolfinx/common/Scatterer.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ class Scatterer
std::span ghosts = map.ghosts();
std::vector<int> owners_sorted(owners.size());
std::vector<std::int64_t> ghosts_sorted(owners.size());
std::transform(perm.begin(), perm.end(), owners_sorted.begin(),
[&owners](auto idx) { return owners[idx]; });
std::transform(perm.begin(), perm.end(), ghosts_sorted.begin(),
[&ghosts](auto idx) { return ghosts[idx]; });
std::ranges::transform(perm, owners_sorted.begin(),
[&owners](auto idx) { return owners[idx]; });
std::ranges::transform(perm, ghosts_sorted.begin(),
[&ghosts](auto idx) { return ghosts[idx]; });

// For data associated with ghost indices, packed by owning
// (neighbourhood) rank, compute sizes and displacements. I.e.,
Expand Down Expand Up @@ -145,10 +145,8 @@ class Scatterer

// Scale sizes and displacements by block size
{
auto rescale = [](auto& x, int bs)
{
std::transform(x.begin(), x.end(), x.begin(),
[bs](auto e) { return e *= bs; });
auto rescale = [](auto& x, int bs) {
std::ranges::transform(x, x.begin(), [bs](auto e) { return e *= bs; });
};
rescale(_sizes_local, bs);
rescale(_displs_local, bs);
Expand Down
4 changes: 2 additions & 2 deletions cpp/dolfinx/common/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ sort_unique(const U& indices, const V& values)

using T = typename std::pair<typename U::value_type, typename V::value_type>;
std::vector<T> data(indices.size());
std::transform(indices.begin(), indices.end(), values.begin(), data.begin(),
[](auto& idx, auto& v) -> T { return {idx, v}; });
std::ranges::transform(indices, values, data.begin(),
[](auto& idx, auto& v) -> T { return {idx, v}; });

// Sort make unique
std::ranges::sort(data);
Expand Down
4 changes: 2 additions & 2 deletions cpp/dolfinx/fem/CoordinateElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ void CoordinateElement<T>::pull_back_nonaffine(mdspan2_t<T> X,
dX[i] += K(i, j) * (x(p, j) - xk[j]);

// Compute Xk += dX
std::transform(dX.begin(), dX.end(), Xk_b.begin(), Xk_b.begin(),
[](auto a, auto b) { return a + b; });
std::ranges::transform(dX, Xk_b, Xk_b.begin(),
[](auto a, auto b) { return a + b; });

// Compute norm(dX)
if (auto dX_squared
Expand Down
24 changes: 12 additions & 12 deletions cpp/dolfinx/fem/DirichletBC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,17 @@ get_remote_dofs(MPI_Comm comm, const common::IndexMap& map, int bs_map,
// Convert dofs indices to 'block' map indices
std::vector<std::int32_t> dofs_local_m;
dofs_local_m.reserve(dofs_local.size());
std::transform(dofs_local.begin(), dofs_local.end(),
std::back_inserter(dofs_local_m),
[bs_map](auto dof) { return dof / bs_map; });
std::ranges::transform(dofs_local, std::back_inserter(dofs_local_m),
[bs_map](auto dof) { return dof / bs_map; });

// Compute global index of each block
map.local_to_global(dofs_local_m, dofs_global);

// Add offset
std::transform(dofs_global.begin(), dofs_global.end(), dofs_local.begin(),
dofs_global.begin(),
[bs_map](auto global_block, auto local_dof)
{ return bs_map * global_block + (local_dof % bs_map); });
std::ranges::transform(
dofs_global, dofs_local, dofs_global.begin(),
[bs_map](auto global_block, auto local_dof)
{ return bs_map * global_block + (local_dof % bs_map); });
}

MPI_Wait(&request, MPI_STATUS_IGNORE);
Expand Down Expand Up @@ -360,8 +359,9 @@ std::array<std::vector<std::int32_t>, 2> fem::locate_dofs_topological(
std::array<std::vector<std::int32_t>, 2> sorted_bc_dofs = bc_dofs;
for (std::size_t b = 0; b < 2; ++b)
{
std::transform(perm.cbegin(), perm.cend(), sorted_bc_dofs[b].begin(),
[&bc_dofs = bc_dofs[b]](auto p) { return bc_dofs[p]; });
std::ranges::transform(perm, sorted_bc_dofs[b].begin(),
[&bc_dofs = bc_dofs[b]](auto p)
{ return bc_dofs[p]; });
sorted_bc_dofs[b].erase(
std::unique(sorted_bc_dofs[b].begin(), sorted_bc_dofs[b].end()),
sorted_bc_dofs[b].end());
Expand Down Expand Up @@ -414,9 +414,9 @@ std::array<std::vector<std::int32_t>, 2> fem::locate_dofs_topological(
std::array<std::vector<std::int32_t>, 2> out_dofs = sorted_bc_dofs;
for (std::size_t b = 0; b < 2; ++b)
{
std::transform(perm.cbegin(), perm.cend(), out_dofs[b].begin(),
[&sorted_dofs = sorted_bc_dofs[b]](auto p)
{ return sorted_dofs[p]; });
std::ranges::transform(perm, out_dofs[b].begin(),
[&sorted_dofs = sorted_bc_dofs[b]](auto p)
{ return sorted_dofs[p]; });
out_dofs[b].erase(std::unique(out_dofs[b].begin(), out_dofs[b].end()),
out_dofs[b].end());
}
Expand Down
8 changes: 4 additions & 4 deletions cpp/dolfinx/fem/DirichletBC.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,10 @@ std::array<std::vector<std::int32_t>, 2> locate_dofs_geometrical(
// Copy to separate array
std::array dofs = {std::vector<std::int32_t>(bc_dofs.size()),
std::vector<std::int32_t>(bc_dofs.size())};
std::transform(bc_dofs.cbegin(), bc_dofs.cend(), dofs[0].begin(),
[](auto dof) { return dof[0]; });
std::transform(bc_dofs.cbegin(), bc_dofs.cend(), dofs[1].begin(),
[](auto dof) { return dof[1]; });
std::ranges::transform(bc_dofs, dofs[0].begin(),
[](auto dof) { return dof[0]; });
std::ranges::transform(bc_dofs, dofs[1].begin(),
[](auto dof) { return dof[1]; });

return dofs;
}
Expand Down
5 changes: 2 additions & 3 deletions cpp/dolfinx/fem/DofMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,8 @@ fem::DofMap build_collapsed_dofmap(const DofMap& dofmap_view,
{
std::vector<std::int32_t> indices;
indices.reserve(dofs_view.size());
std::transform(dofs_view.begin(), dofs_view.end(),
std::back_inserter(indices),
[bs_view](auto idx) { return idx / bs_view; });
std::ranges::transform(dofs_view, std::back_inserter(indices),
[bs_view](auto idx) { return idx / bs_view; });
auto [_index_map, _sub_imap_to_imap] = common::create_sub_index_map(
*dofmap_view.index_map, indices, common::IndexMapOrder::preserve);
index_map = std::make_shared<common::IndexMap>(std::move(_index_map));
Expand Down
9 changes: 4 additions & 5 deletions cpp/dolfinx/fem/Form.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,8 @@ class Form
{
std::vector<int> ids;
const auto& integrals = _integrals[static_cast<std::size_t>(type)];
std::transform(integrals.begin(), integrals.end(), std::back_inserter(ids),
[](auto& integral) { return integral.id; });
std::ranges::transform(integrals, std::back_inserter(ids),
[](auto& integral) { return integral.id; });
return ids;
}

Expand Down Expand Up @@ -385,9 +385,8 @@ class Form
{
case IntegralType::cell:
{
std::transform(entities.begin(), entities.end(),
std::back_inserter(mapped_entities),
[&entity_map](auto e) { return entity_map[e]; });
std::ranges::transform(entities, std::back_inserter(mapped_entities),
[&entity_map](auto e) { return entity_map[e]; });
break;
}
case IntegralType::exterior_facet:
Expand Down
Loading

0 comments on commit 830a9e9

Please sign in to comment.