OpenPFC  0.1.4
Phase Field Crystal simulation framework
Loading...
Searching...
No Matches
sparse_vector_ops.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2025 VTT Technical Research Centre of Finland Ltd
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
36#pragma once
37
38#include <initializer_list>
39#include <vector>
40
43
44#if defined(OpenPFC_ENABLE_CUDA)
45#include <cuda_runtime.h>
46#endif
47
48namespace pfc {
49namespace core {
50
63template <typename BackendTag, typename T>
65 size_t source_size) {
66 if (sparse_vector.empty()) {
67 return;
68 }
69
70 if constexpr (std::is_same_v<BackendTag, backend::CpuTag>) {
71 // CPU: Direct indexed access
72 const auto &indices = sparse_vector.indices();
73 T *data = sparse_vector.data().data();
74 for (size_t i = 0; i < sparse_vector.size(); ++i) {
75 size_t idx = indices.data()[i];
76 if (idx >= source_size) {
77 throw std::runtime_error("gather: index out of bounds");
78 }
79 data[i] = source[idx];
80 }
81 }
82#if defined(OpenPFC_ENABLE_CUDA)
83 else if constexpr (std::is_same_v<BackendTag, backend::CudaTag>) {
84 // CUDA: Use kernel for indexed gather
85 // TODO: Implement CUDA kernel
86 throw std::runtime_error("CUDA gather not yet implemented");
87 }
88#endif
89}
90
94template <typename T>
96 const std::vector<T> &source) {
97 gather(sparse_vector, source.data(), source.size());
98}
99
103template <typename T>
105 std::initializer_list<T> source) {
106 std::vector<T> vec(source);
108}
109
122template <typename BackendTag, typename T>
124 size_t dest_size) {
125 if (sparse_vector.empty()) {
126 return;
127 }
128
129 if constexpr (std::is_same_v<BackendTag, backend::CpuTag>) {
130 // CPU: Direct indexed access
131 const auto &indices = sparse_vector.indices();
132 const T *data = sparse_vector.data().data();
133 for (size_t i = 0; i < sparse_vector.size(); ++i) {
134 size_t idx = indices.data()[i];
135 if (idx >= dest_size) {
136 throw std::runtime_error("scatter: index out of bounds");
137 }
138 dest[idx] = data[i];
139 }
140 }
141#if defined(OpenPFC_ENABLE_CUDA)
142 else if constexpr (std::is_same_v<BackendTag, backend::CudaTag>) {
143 // CUDA: Use kernel for indexed scatter
144 // TODO: Implement CUDA kernel
145 throw std::runtime_error("CUDA scatter not yet implemented");
146 }
147#endif
148}
149
153template <typename T>
155 std::vector<T> &dest) {
156 scatter(sparse_vector, dest.data(), dest.size());
157}
158
159} // namespace core
160
161// Make gather/scatter available in global namespace for backward compatibility
162using core::gather;
163using core::scatter;
164
165} // namespace pfc
Backend tags for compile-time backend selection.
Sparse vector for indexed data views.
Definition sparse_vector.hpp:66
Sparse vector for halo exchange and indexed data views.
void gather(SparseVector< BackendTag, T > &sparse_vector, const T *source, size_t source_size)
Gather: Collect values from dense array into SparseVector.
Definition sparse_vector_ops.hpp:64
void scatter(const SparseVector< BackendTag, T > &sparse_vector, T *dest, size_t dest_size)
Scatter: Write values from SparseVector into dense array.
Definition sparse_vector_ops.hpp:123
Represents the global simulation domain (the "world").
Definition world.hpp:91