24#ifndef COMMUNICATABLE_H
25#define COMMUNICATABLE_H
39 const std::size_t _size;
43 _base(base), _size(
size) { }
59 const T*
end()
const {
79 std::uint8_t* buffer)
const = 0;
86 const std::uint8_t* buffer) = 0;
89template <
typename COMMUNICATEE>
92 COMMUNICATEE& _communicatee;
96 _communicatee{communicatee} { }
101 return indices.
size() *
sizeof(
typename COMMUNICATEE::value_type);
106 std::uint8_t* buffer)
const override
108 if (meta::is_aligned<typename COMMUNICATEE::value_type>(buffer)) {
109 auto* target =
reinterpret_cast<typename COMMUNICATEE::value_type*
>(buffer);
110 for (
CellID index : indices) {
111 *(target++) = _communicatee[index];
114 std::uint8_t* target = buffer;
115 for (
CellID index : indices) {
117 reinterpret_cast<const void*
>(&_communicatee[index]),
118 sizeof(
typename COMMUNICATEE::value_type));
119 target +=
sizeof(
typename COMMUNICATEE::value_type);
122 return indices.
size() *
sizeof(
typename COMMUNICATEE::value_type);
127 const std::uint8_t* buffer)
override
129 if (meta::is_aligned<typename COMMUNICATEE::value_type>(buffer)) {
130 const auto* source =
reinterpret_cast<const typename COMMUNICATEE::value_type*
>(buffer);
131 for (
CellID index : indices) {
132 _communicatee[index] = *(source++);
135 const std::uint8_t* source = buffer;
136 for (
CellID index : indices) {
137 std::memcpy(
reinterpret_cast<void*
>(&_communicatee[index]),
139 sizeof(
typename COMMUNICATEE::value_type));
140 source +=
sizeof(
typename COMMUNICATEE::value_type);
143 return indices.
size() *
sizeof(
typename COMMUNICATEE::value_type);
157 return std::tuple_size<COMMUNICATEE>::value *
sizeof(
typename COMMUNICATEE::value_type);
163 std::size_t noI = std::tuple_size<COMMUNICATEE>::value;
164 if (meta::is_aligned<typename COMMUNICATEE::value_type>(buffer)) {
165 auto* target =
reinterpret_cast<typename COMMUNICATEE::value_type*
>(buffer);
166 for (
CellID index=0; index<noI; ++index) {
167 *(target++) = _communicatee[index];
170 std::uint8_t* target = buffer;
171 for (
CellID index=0; index<noI; ++index) {
173 reinterpret_cast<const void*
>(&_communicatee[index]),
174 sizeof(
typename COMMUNICATEE::value_type));
175 target +=
sizeof(
typename COMMUNICATEE::value_type);
178 return noI *
sizeof(
typename COMMUNICATEE::value_type);
184 std::size_t noI = std::tuple_size<COMMUNICATEE>::value;
185 if (meta::is_aligned<typename COMMUNICATEE::value_type>(buffer)) {
186 const auto* source =
reinterpret_cast<const typename COMMUNICATEE::value_type*
>(buffer);
187 for (
CellID index=0; index<noI; ++index) {
188 _communicatee[index] = *(source++);
191 const std::uint8_t* source = buffer;
192 for (
CellID index=0; index<noI; ++index) {
193 std::memcpy(
reinterpret_cast<void*
>(&_communicatee[index]),
195 sizeof(
typename COMMUNICATEE::value_type));
196 source +=
sizeof(
typename COMMUNICATEE::value_type);
199 return noI *
sizeof(
typename COMMUNICATEE::value_type);
204template <
typename COLUMN>
207 std::vector<COLUMN>& _vector;
216 std::size_t
size = 0;
217 for (
unsigned iD=0; iD < _vector.size(); ++iD) {
225 std::uint8_t* buffer)
const
228 std::uint8_t* curr = buffer;
229 #ifdef PARALLEL_MODE_OMP
230 #pragma omp parallel for schedule(static,1)
232 for (
unsigned iD=0; iD < _vector.size(); ++iD) {
235 return _vector.size() *
size;
240 const std::uint8_t* buffer)
243 const std::uint8_t* curr = buffer;
244 #ifdef PARALLEL_MODE_OMP
245 #pragma omp parallel for schedule(static,1)
247 for (
unsigned iD=0; iD < _vector.size(); ++iD) {
250 return _vector.size() *
size;
255template <
typename COMMUNICATEE>
258 COMMUNICATEE& _communicatee;
259 const std::vector<std::type_index>& _fields;
263 const std::vector<std::type_index>& fields):
264 _communicatee{communicatee},
270 std::size_t
size = 0;
271 for (
auto& field : _fields) {
272 size += _communicatee.getCommunicatable(field).size(indices);
279 std::uint8_t* buffer)
const override
281 std::uint8_t* curr = buffer;
282 for (
auto& field : _fields) {
283 curr += _communicatee.getCommunicatable(field).serialize(indices, curr);
285 return curr - buffer;
290 const std::uint8_t* buffer)
override
292 const std::uint8_t* curr = buffer;
293 for (
auto& field : _fields) {
294 curr += _communicatee.getCommunicatable(field).deserialize(indices, curr);
296 return curr - buffer;
std::size_t serialize(ConstSpan< CellID > indices, std::uint8_t *buffer) const
Serialize data at locations indices to buffer
ConcreteCommunicatable(std::vector< COLUMN > &vector)
std::size_t deserialize(ConstSpan< CellID > indices, const std::uint8_t *buffer)
Deserialize data at locations indices to buffer
std::size_t size(ConstSpan< CellID > indices) const
Get serialized size for data at locations indices
std::size_t size() const
ADDITIONAL NON OVERWITTEN CALLS: Removing the necessity to provide indices.
std::size_t deserialize(ConstSpan< CellID > indices, const std::uint8_t *buffer) override
Deserialize data at locations indices to buffer
std::size_t serialize(std::uint8_t *buffer) const
Serialize complete data.
std::size_t deserialize(const std::uint8_t *buffer)
Deserialize complete data.
std::size_t serialize(ConstSpan< CellID > indices, std::uint8_t *buffer) const override
Serialize data at locations indices to buffer
ConcreteCommunicatable(COMMUNICATEE &communicatee)
std::size_t size(ConstSpan< CellID > indices) const override
Get serialized size for data at locations indices
ConstSpan(const std::vector< T > &v)
T operator[](std::size_t i) const
ConstSpan(const T *base, std::size_t size)
std::size_t serialize(ConstSpan< CellID > indices, std::uint8_t *buffer) const override
Serialize data at locations indices to buffer
MultiConcreteCommunicatable(COMMUNICATEE &communicatee, const std::vector< std::type_index > &fields)
std::size_t size(ConstSpan< CellID > indices) const override
Get serialized size for data at locations indices
std::size_t deserialize(ConstSpan< CellID > indices, const std::uint8_t *buffer) override
Deserialize data at locations indices to buffer
Top level namespace for all of OpenLB.
std::uint32_t CellID
Type for sequential block-local cell indices.
virtual ~Communicatable()
virtual std::size_t size(ConstSpan< CellID > indices) const =0
virtual std::size_t serialize(ConstSpan< CellID > indices, std::uint8_t *buffer) const =0
Serialize data at locations indices to buffer
virtual std::size_t deserialize(ConstSpan< CellID > indices, const std::uint8_t *buffer)=0
Deserialize data at locations indices to buffer