Eigen  5.0.1
 
Loading...
Searching...
No Matches
Serializer.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2021 The Eigen Team
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_SERIALIZER_H
12#define EIGEN_SERIALIZER_H
13
14#include <type_traits>
15
16// The Serializer class encodes data into a memory buffer so it can be later
17// reconstructed. This is mainly used to send objects back-and-forth between
18// the CPU and GPU.
19
20namespace Eigen {
21
27template <typename T, typename EnableIf = void>
29
30// Specialization for POD types.
31template <typename T>
32class Serializer<T, std::enable_if_t<std::is_trivially_copyable<T>::value && std::is_standard_layout<T>::value>> {
33 public:
40 EIGEN_DEVICE_FUNC size_t size(const T& value) const { return sizeof(value); }
41
49 EIGEN_DEVICE_FUNC uint8_t* serialize(uint8_t* dest, uint8_t* end, const T& value) const {
50 if (EIGEN_PREDICT_FALSE(dest == nullptr)) return nullptr;
51 if (EIGEN_PREDICT_FALSE(dest + sizeof(value) > end)) return nullptr;
52 EIGEN_USING_STD(memcpy)
53 memcpy(dest, &value, sizeof(value));
54 return dest + sizeof(value);
55 }
56
64 EIGEN_DEVICE_FUNC const uint8_t* deserialize(const uint8_t* src, const uint8_t* end, T& value) const {
65 if (EIGEN_PREDICT_FALSE(src == nullptr)) return nullptr;
66 if (EIGEN_PREDICT_FALSE(src + sizeof(value) > end)) return nullptr;
67 EIGEN_USING_STD(memcpy)
68 memcpy(&value, src, sizeof(value));
69 return src + sizeof(value);
70 }
71};
72
73// Specialization for DenseBase.
74// Serializes [rows, cols, data...].
75template <typename Derived>
76class Serializer<DenseBase<Derived>, void> {
77 public:
78 using Scalar = typename Derived::Scalar;
79
80 struct Header {
81 typename Derived::Index rows;
82 typename Derived::Index cols;
83 };
84
85 EIGEN_DEVICE_FUNC size_t size(const Derived& value) const { return sizeof(Header) + sizeof(Scalar) * value.size(); }
86
87 EIGEN_DEVICE_FUNC uint8_t* serialize(uint8_t* dest, uint8_t* end, const Derived& value) const {
88 if (EIGEN_PREDICT_FALSE(dest == nullptr)) return nullptr;
89 if (EIGEN_PREDICT_FALSE(dest + size(value) > end)) return nullptr;
90 const size_t header_bytes = sizeof(Header);
91 const size_t data_bytes = sizeof(Scalar) * value.size();
92 Header header = {value.rows(), value.cols()};
93 EIGEN_USING_STD(memcpy)
94 memcpy(dest, &header, header_bytes);
95 dest += header_bytes;
96 memcpy(dest, value.data(), data_bytes);
97 return dest + data_bytes;
98 }
99
100 EIGEN_DEVICE_FUNC const uint8_t* deserialize(const uint8_t* src, const uint8_t* end, Derived& value) const {
101 if (EIGEN_PREDICT_FALSE(src == nullptr)) return nullptr;
102 if (EIGEN_PREDICT_FALSE(src + sizeof(Header) > end)) return nullptr;
103 const size_t header_bytes = sizeof(Header);
104 Header header;
105 EIGEN_USING_STD(memcpy)
106 memcpy(&header, src, header_bytes);
107 src += header_bytes;
108 const size_t data_bytes = sizeof(Scalar) * header.rows * header.cols;
109 if (EIGEN_PREDICT_FALSE(src + data_bytes > end)) return nullptr;
110 value.resize(header.rows, header.cols);
111 memcpy(value.data(), src, data_bytes);
112 return src + data_bytes;
113 }
114};
115
116template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
117class Serializer<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>
118 : public Serializer<DenseBase<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>> {};
119
120template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
121class Serializer<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>
122 : public Serializer<DenseBase<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols>>> {};
123
124namespace internal {
125
126template <typename Arg>
127EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size_one(const Arg& arg) {
128 Serializer<std::decay_t<Arg>> serializer;
129 return serializer.size(arg);
130}
131
132template <typename Arg>
133EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize_one(uint8_t* dest, uint8_t* end, const Arg& arg) {
134 Serializer<std::decay_t<Arg>> serializer;
135 return serializer.serialize(dest, end, arg);
136}
137
138template <typename Arg>
139EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize_one(const uint8_t* src, const uint8_t* end, Arg& arg) {
140 Serializer<std::decay_t<Arg>> serializer;
141 return serializer.deserialize(src, end, arg);
142}
143
144} // namespace internal
145
152template <typename... Args>
153EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE size_t serialize_size(const Args&... args) {
154 size_t size = 0;
155 int unused[] = {0, (size += internal::serialize_size_one(args), 0)...};
156 EIGEN_UNUSED_VARIABLE(unused);
157 return size;
158}
159
168template <typename... Args>
169EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE uint8_t* serialize(uint8_t* dest, uint8_t* end, const Args&... args) {
170 EIGEN_UNUSED_VARIABLE(end);
171 int unused[] = {0, (dest = internal::serialize_one(dest, end, args), 0)...};
172 EIGEN_UNUSED_VARIABLE(unused);
173 return dest;
174}
175
184template <typename... Args>
185EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const uint8_t* deserialize(const uint8_t* src, const uint8_t* end,
186 Args&... args) {
187 EIGEN_UNUSED_VARIABLE(end);
188 int unused[] = {0, (src = internal::deserialize_one(src, end, args), 0)...};
189 EIGEN_UNUSED_VARIABLE(unused);
190 return src;
191}
192
193} // namespace Eigen
194
195#endif // EIGEN_SERIALIZER_H
General-purpose arrays with easy API for coefficient-wise operations.
Definition Array.h:55
Base class for all dense matrices, vectors, and arrays.
Definition DenseBase.h:45
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:188
Definition Serializer.h:28