33#ifndef TVM_SUPPORT_SERIALIZER_H_
34#define TVM_SUPPORT_SERIALIZER_H_
36#include <dlpack/dlpack.h>
37#include <tvm/ffi/container/array.h>
38#include <tvm/ffi/container/map.h>
39#include <tvm/ffi/endian.h>
40#include <tvm/ffi/string.h>
47#include <unordered_map>
56struct Serializer<T, std::enable_if_t<std::is_arithmetic_v<T>>> {
57 static constexpr bool enabled =
true;
59 static void Write(Stream* strm,
const T& data) {
60 if constexpr (TVM_FFI_IO_NO_ENDIAN_SWAP) {
61 strm->Write(&data,
sizeof(T));
64 ffi::ByteSwap(©,
sizeof(T), 1);
65 strm->Write(©,
sizeof(T));
69 static bool Read(Stream* strm, T* data) {
70 bool ok = strm->Read(data,
sizeof(T)) ==
sizeof(T);
71 if constexpr (!TVM_FFI_IO_NO_ENDIAN_SWAP) {
72 ffi::ByteSwap(data,
sizeof(T), 1);
80struct Serializer<T, std::enable_if_t<std::is_enum_v<T>>> {
81 static constexpr bool enabled =
true;
82 using U = std::underlying_type_t<T>;
84 static void Write(Stream* strm,
const T& data) {
85 Serializer<U>::Write(strm,
static_cast<U
>(data));
88 static bool Read(Stream* strm, T* data) {
90 if (!Serializer<U>::Read(strm, &val))
return false;
91 *data =
static_cast<T
>(val);
98struct Serializer<std::string> {
99 static constexpr bool enabled =
true;
101 static void Write(Stream* strm,
const std::string& data) {
102 uint64_t sz =
static_cast<uint64_t
>(data.size());
103 Serializer<uint64_t>::Write(strm, sz);
105 strm->Write(data.data(), data.size());
109 static bool Read(Stream* strm, std::string* data) {
111 if (!Serializer<uint64_t>::Read(strm, &sz))
return false;
112 data->resize(
static_cast<size_t>(sz));
114 size_t nbytes =
static_cast<size_t>(sz);
115 return strm->Read(&(*data)[0], nbytes) == nbytes;
123struct Serializer<std::vector<T>> {
124 static constexpr bool enabled =
true;
126 static void Write(Stream* strm,
const std::vector<T>& vec) {
127 uint64_t sz =
static_cast<uint64_t
>(vec.size());
128 Serializer<uint64_t>::Write(strm, sz);
129 if constexpr (std::is_arithmetic_v<T> && TVM_FFI_IO_NO_ENDIAN_SWAP) {
131 strm->Write(vec.data(),
sizeof(T) * vec.size());
134 for (
const auto& v : vec) {
135 Serializer<T>::Write(strm, v);
140 static bool Read(Stream* strm, std::vector<T>* vec) {
142 if (!Serializer<uint64_t>::Read(strm, &sz))
return false;
143 vec->resize(
static_cast<size_t>(sz));
144 if constexpr (std::is_arithmetic_v<T> && TVM_FFI_IO_NO_ENDIAN_SWAP) {
146 size_t nbytes =
sizeof(T) *
static_cast<size_t>(sz);
147 return strm->Read(vec->data(), nbytes) == nbytes;
151 for (
size_t i = 0; i < static_cast<size_t>(sz); ++i) {
152 if (!Serializer<T>::Read(strm, &(*vec)[i]))
return false;
160template <
typename A,
typename B>
161struct Serializer<std::pair<A, B>> {
162 static constexpr bool enabled =
true;
164 static void Write(Stream* strm,
const std::pair<A, B>& data) {
165 Serializer<A>::Write(strm, data.first);
166 Serializer<B>::Write(strm, data.second);
169 static bool Read(Stream* strm, std::pair<A, B>* data) {
170 return Serializer<A>::Read(strm, &data->first) && Serializer<B>::Read(strm, &data->second);
175template <
typename K,
typename V>
176struct Serializer<std::unordered_map<K, V>> {
177 static constexpr bool enabled =
true;
179 static void Write(Stream* strm,
const std::unordered_map<K, V>& data) {
180 std::vector<std::pair<K, V>> vec(data.begin(), data.end());
181 Serializer<std::vector<std::pair<K, V>>>::Write(strm, vec);
184 static bool Read(Stream* strm, std::unordered_map<K, V>* data) {
185 std::vector<std::pair<K, V>> vec;
186 if (!Serializer<std::vector<std::pair<K, V>>>::Read(strm, &vec))
return false;
188 data->insert(vec.begin(), vec.end());
202 strm->Write(data.data(), data.size());
209 *data = ffi::String(std::move(
s));
223 strm->Write(data.data(), data.size());
230 *data = ffi::Bytes(std::move(
s));
243 for (
size_t i = 0;
i <
arr.size(); ++
i) {
251 *
arr = ffi::Array<T>();
255 arr->push_back(std::move(
val));
262template <
typename K,
typename V>
269 for (
const auto&
kv : data) {
278 *data = ffi::Map<K, V>();
284 data->Set(std::move(key), std::move(
val));
RAII wrapper function to enter and exit a context object similar to python's with syntax.
Definition with_context.h:59
Abstract binary stream for serialization.
Definition io.h:57
Binary stream I/O interface.
const Op & copy()
See pesudo code below:
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition analyzer.h:40
static bool Read(Stream *strm, DLDataType *dtype)
Definition serializer.h:301
static void Write(Stream *strm, const DLDataType &dtype)
Definition serializer.h:295
static void Write(Stream *strm, const DLDevice &dev)
Definition serializer.h:314
static bool Read(Stream *strm, DLDevice *dev)
Definition serializer.h:320
static void Write(Stream *strm, const ffi::Array< T > &arr)
Definition serializer.h:240
static bool Read(Stream *strm, ffi::Array< T > *arr)
Definition serializer.h:248
static void Write(Stream *strm, const ffi::Bytes &data)
Definition serializer.h:219
static bool Read(Stream *strm, ffi::Bytes *data)
Definition serializer.h:227
static bool Read(Stream *strm, ffi::Map< K, V > *data)
Definition serializer.h:275
static void Write(Stream *strm, const ffi::Map< K, V > &data)
Definition serializer.h:266
static bool Read(Stream *strm, ffi::String *data)
Definition serializer.h:206
static void Write(Stream *strm, const ffi::String &data)
Definition serializer.h:198
Primary Serializer template. Specialize for each serializable type.
Definition io.h:42
static constexpr bool enabled
Definition io.h:43