ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
field_layout_helpers.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024-2026 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#pragma once
21
22#include "for_each_3d.hpp"
23
24#include <utils/Vector.hpp>
25#include <utils/index.hpp>
26
27#include <algorithm>
28#include <cassert>
29#include <complex>
30#include <cstddef>
31#include <iterator>
32#include <memory>
33#include <new>
34#include <span>
35#include <type_traits>
36#include <utility>
37#include <vector>
38
39/**
40 * @brief Extract a 3D block from the halo field into a caller-provided buffer.
41 * @c out must hold at least @c product(stop - start) elements; the block is
42 * written in full, so its prior contents are irrelevant.
43 */
45 Utils::MemoryOrder output_memory_order, typename Container,
46 typename OutValue>
47void extract_block_into(OutValue *out, Container const &in_array,
49 Utils::Vector3i const &start,
50 Utils::Vector3i const &stop) {
51 auto const block_dim = stop - start;
52
53 // Extract the block
56 auto const plane_src = dimensions[2] * dimensions[1];
57 auto const lane_src = dimensions[2];
58 auto const lane_dst = block_dim[2];
59 auto const *const src = in_array.data();
60 auto *const dst = out;
61 auto const n_y = stop[1] - start[1];
62 // Explicit destination offset per (x, y) lane lets the outer loop run in
63 // parallel: each x writes a disjoint set of contiguous lanes, so the copy
64 // is thread-safe and bitwise-identical to the serial version.
65 _Pragma("omp parallel for") for (int x = start[0]; x < stop[0]; ++x) {
66 for (int y = start[1]; y < stop[1]; ++y) {
67 auto const offset_src = x * plane_src + y * lane_src + start[2];
68 auto const offset_dst =
69 (static_cast<std::size_t>(x - start[0]) * n_y + (y - start[1])) *
71 std::copy_n(src + offset_src, lane_dst, dst + offset_dst);
72 }
73 }
74 } else {
76 start, stop, [&](Utils::Vector3i const &indices, int out_index) {
77 // Compute indices for input and output arrays
78 auto const in_index =
79 Utils::get_linear_index<memory_order>(indices, dimensions);
80 assert(out_index == Utils::get_linear_index<output_memory_order>(
81 indices - start, block_dim));
82 // Copy the value
84 });
85 }
86}
87
88/** @brief Pad a 3D matrix with zeros to restore halo regions, writing into a
89 * caller-provided buffer of @c product(cropped_dim+pad_left+pad_right)
90 * elements. Every element is written exactly once (halo shells are zeroed,
91 * the interior is copied), so the buffer's prior contents are irrelevant and
92 * a persistent buffer can be reused across calls without an allocation or a
93 * full-volume zero-fill.
94 */
100 Utils::Vector3i const &pad_right) {
101
102 auto constexpr get_real = [](auto const &v) { return std::real(v); };
103 // Calculate dimensions and strides
104 auto const padded_dim = cropped_dim + pad_left + pad_right;
105
108 auto const plane_dst = padded_dim[2] * padded_dim[1];
109 auto const lane_dst = padded_dim[2];
110 auto const lane_src = cropped_dim[2];
111 auto *const dst = out;
112 auto const *const src = cropped_array.data();
113 // One parallel sweep over the padded x-planes: each x writes a disjoint
114 // plane (fully zeroed in the x-halo, per-lane zero/copy/zero otherwise),
115 // so the sweep is thread-safe and bitwise-identical to the serial version.
116 _Pragma("omp parallel for") for (int x = 0; x < padded_dim[0]; ++x) {
117 auto *const plane = dst + static_cast<std::size_t>(x) * plane_dst;
118 if (x < pad_left[0] or x >= pad_left[0] + cropped_dim[0]) {
119 std::fill_n(plane, plane_dst, OutValue{});
120 continue;
121 }
122 auto const src_x = x - pad_left[0];
123 for (int y = 0; y < padded_dim[1]; ++y) {
124 auto *const lane = plane + static_cast<std::size_t>(y) * lane_dst;
125 if (y < pad_left[1] or y >= pad_left[1] + cropped_dim[1]) {
126 std::fill_n(lane, lane_dst, OutValue{});
127 continue;
128 }
129 auto const src_y = y - pad_left[1];
130 auto const offset_src =
131 (static_cast<std::size_t>(src_x) * cropped_dim[1] + src_y) *
132 lane_src;
133 std::fill_n(lane, pad_left[2], OutValue{});
134 if constexpr (std::is_floating_point_v<T>) {
135 std::copy_n(src + offset_src, lane_src, lane + pad_left[2]);
136 } else {
137 std::transform(src + offset_src, src + offset_src + lane_src,
138 lane + pad_left[2], get_real);
139 }
140 std::fill_n(lane + pad_left[2] + lane_src, pad_right[2], OutValue{});
141 }
142 }
143 } else {
144 std::fill_n(out, Utils::product(padded_dim), OutValue{});
147 [&](Utils::Vector3i const &indices, int in_index) {
148 // Compute indices for input and output arrays
149 auto const out_index = Utils::get_linear_index<output_memory_order>(
151 // Copy the value
152 out[out_index] = std::real(cropped_array[in_index]);
153 });
154 }
155}
Vector implementation and trait types for boost qvm interoperability.
DEVICE_QUALIFIER constexpr pointer data() noexcept
Definition Array.hpp:132
cudaStream_t stream[1]
CUDA streams for parallel computing on CPU and GPU.
void extract_block_into(OutValue *out, Container const &in_array, Utils::Vector3i const &dimensions, Utils::Vector3i const &start, Utils::Vector3i const &stop)
Extract a 3D block from the halo field into a caller-provided buffer.
void pad_with_zeros_discard_imag_into(OutValue *out, std::span< T > cropped_array, Utils::Vector3i const &cropped_dim, Utils::Vector3i const &pad_left, Utils::Vector3i const &pad_right)
Pad a 3D matrix with zeros to restore halo regions, writing into a caller-provided buffer of product(...
T product(Vector< T, N > const &v)
Definition Vector.hpp:383
MemoryOrder
Definition index.hpp:33