Skip to content

Commit ae1dd3a

Browse files
committed
Update serializer
1 parent c272ab1 commit ae1dd3a

File tree

4 files changed

+149
-139
lines changed

4 files changed

+149
-139
lines changed

CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ if (${SKBUILD})
188188
)
189189

190190
# If using MSVC with GitHub, set /Zm512 to reduce memory usage
191-
if (MSVC AND $ENV{GITHUB_ACTIONS})
191+
if (MSVC AND "$ENV{CI}")
192192
target_compile_options(${module_name} PRIVATE /Zm512)
193193
endif ()
194194

@@ -351,7 +351,7 @@ if (LIBRAPID_USE_OPENCL)
351351

352352
# Define CL_HPP_TARGET_OPENCL_VERSION to the version of OpenCL being used
353353
message(STATUS "[ LIBRAPID ] OpenCL Version: ${OpenCL_VERSION_MAJOR}${OpenCL_VERSION_MINOR}0")
354-
set(OpenCLVersion ${OpenCL_VERSION_MAJOR} ${OpenCL_VERSION_MINOR}0)
354+
set(OpenCLVersion ${OpenCL_VERSION_MAJOR}${OpenCL_VERSION_MINOR}0)
355355
target_compile_definitions(${module_name} PUBLIC CL_HPP_TARGET_OPENCL_VERSION=${OpenCLVersion})
356356
target_compile_definitions(${module_name} PUBLIC CL_HPP_MINIMUM_OPENCL_VERSION=${OpenCLVersion})
357357

librapid/include/librapid/array/arraySerialize.hpp

+29-31
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@ namespace librapid::serialize {
2222

2323
DimType numDims = shape.ndim();
2424
size_t hashed = hasher();
25-
std::memcpy(serialized.data(), &numDims, sizeof(DimType));
26-
std::memcpy(serialized.data() + sizeof(DimType),
27-
shape.data().begin(),
28-
sizeof(SizeType) * LIBRAPID_MAX_ARRAY_DIMS);
29-
std::memcpy(serialized.data() + sizeof(DimType) +
30-
sizeof(SizeType) * LIBRAPID_MAX_ARRAY_DIMS,
31-
&hashed,
32-
sizeof(size_t));
25+
memcpy(serialized.data(), &numDims, sizeof(DimType));
26+
memcpy(serialized.data() + sizeof(DimType),
27+
shape.data().begin(),
28+
sizeof(SizeType) * LIBRAPID_MAX_ARRAY_DIMS);
29+
memcpy(serialized.data() + sizeof(DimType) + sizeof(SizeType) * LIBRAPID_MAX_ARRAY_DIMS,
30+
&hashed,
31+
sizeof(size_t));
3332
return serialized;
3433
}
3534

@@ -43,14 +42,14 @@ namespace librapid::serialize {
4342

4443
DimType numDims;
4544
size_t hashed;
46-
std::memcpy(&numDims, data.data(), sizeof(DimType));
45+
memcpy(&numDims, data.data(), sizeof(DimType));
4746
Shape shape = Shape::zeros(numDims);
48-
std::memcpy(shape.data().begin(),
49-
data.data() + sizeof(DimType),
50-
sizeof(SizeType) * LIBRAPID_MAX_ARRAY_DIMS);
51-
std::memcpy(&hashed,
52-
data.data() + sizeof(DimType) + sizeof(SizeType) * LIBRAPID_MAX_ARRAY_DIMS,
53-
sizeof(size_t));
47+
memcpy(shape.data().begin(),
48+
data.data() + sizeof(DimType),
49+
sizeof(SizeType) * LIBRAPID_MAX_ARRAY_DIMS);
50+
memcpy(&hashed,
51+
data.data() + sizeof(DimType) + sizeof(SizeType) * LIBRAPID_MAX_ARRAY_DIMS,
52+
sizeof(size_t));
5453

5554
LIBRAPID_ASSERT(
5655
hashed == hasher(),
@@ -78,12 +77,12 @@ namespace librapid::serialize {
7877

7978
size_t elements = storage.size();
8079
size_t hashed = hasher();
81-
std::memcpy(serialized.data(), &elements, sizeof(size_t));
82-
std::memcpy(
80+
memcpy(serialized.data(), &elements, sizeof(size_t));
81+
memcpy(
8382
serialized.data() + sizeof(size_t), storage.data(), sizeof(Scalar) * storage.size());
84-
std::memcpy(serialized.data() + sizeof(size_t) + sizeof(Scalar) * storage.size(),
85-
&hashed,
86-
sizeof(size_t));
83+
memcpy(serialized.data() + sizeof(size_t) + sizeof(Scalar) * storage.size(),
84+
&hashed,
85+
sizeof(size_t));
8786
return serialized;
8887
}
8988

@@ -95,13 +94,12 @@ namespace librapid::serialize {
9594

9695
size_t elements;
9796
size_t hashed;
98-
std::memcpy(&elements, data.data(), sizeof(size_t));
97+
memcpy(&elements, data.data(), sizeof(size_t));
9998
Storage<Scalar> storage(elements);
100-
std::memcpy(
101-
storage.data(), data.data() + sizeof(size_t), sizeof(Scalar) * storage.size());
102-
std::memcpy(&hashed,
103-
data.data() + sizeof(size_t) + sizeof(Scalar) * storage.size(),
104-
sizeof(size_t));
99+
memcpy(storage.data(), data.data() + sizeof(size_t), sizeof(Scalar) * storage.size());
100+
memcpy(&hashed,
101+
data.data() + sizeof(size_t) + sizeof(Scalar) * storage.size(),
102+
sizeof(size_t));
105103

106104
LIBRAPID_ASSERT(
107105
hashed == hasher(),
@@ -150,12 +148,12 @@ namespace librapid::serialize {
150148
std::vector<uint8_t> serialized;
151149
serialized.resize(shapeBytes + storageBytes);
152150

153-
std::memcpy(
151+
memcpy(
154152
serialized.data(), SerializerImpl<ShapeType>::serialize(shape).data(), shapeBytes);
155-
std::memcpy(serialized.data() + shapeBytes,
156-
SerializerImpl<StorageType>::serialize(storage).data(),
157-
storageBytes);
158-
std::memcpy(serialized.data() + shapeBytes + storageBytes, &hashed, sizeof(size_t));
153+
memcpy(serialized.data() + shapeBytes,
154+
SerializerImpl<StorageType>::serialize(storage).data(),
155+
storageBytes);
156+
memcpy(serialized.data() + shapeBytes + storageBytes, &hashed, sizeof(size_t));
159157

160158
return serialized;
161159
}

librapid/include/librapid/utils/memUtils.hpp

+114-102
Original file line numberDiff line numberDiff line change
@@ -2,126 +2,138 @@
22
#define LIBRAPID_UTILS_MEMUTILS_HPP
33

44
namespace librapid {
5-
/// Cast the bits of one value directly into another type -- no conversion is performed
6-
/// \tparam To The type to cast to
7-
/// \tparam From The type to cast from
8-
/// \param val The value to cast
9-
/// \return The value bitwise mapped to the new type
10-
template<typename To, typename From>
11-
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE constexpr To bitCast(const From &val) noexcept {
12-
static_assert(
13-
sizeof(To) == sizeof(From),
14-
"Types have different sizes, and cannot be cast bit-for-bit between each other");
5+
/// Cast the bits of one value directly into another type -- no conversion is performed
6+
/// \tparam To The type to cast to
7+
/// \tparam From The type to cast from
8+
/// \param val The value to cast
9+
/// \return The value bitwise mapped to the new type
10+
template<typename To, typename From>
11+
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE constexpr To bitCast(const From &val) noexcept {
12+
static_assert(
13+
sizeof(To) == sizeof(From),
14+
"Types have different sizes, and cannot be cast bit-for-bit between each other");
1515

1616
#if defined(__CUDACC__)
17-
To toOjb; // assumes default-init
18-
::std::memcpy(::std::memcpy::addressof(toOjb), ::std::memcpy::addressof(val), sizeof(To));
19-
return _To_obj;
17+
To toOjb; // assumes default-init
18+
::std::memcpy(::std::memcpy::addressof(toOjb), ::std::memcpy::addressof(val), sizeof(To));
19+
return _To_obj;
2020
#elif defined(LIBRAPID_MSVC)
21-
// MSVC doesn't support std::bit_cast until C++20
22-
return *(To *)(&val);
21+
// MSVC doesn't support std::bit_cast until C++20
22+
return *(To *)(&val);
2323
#elif defined(LIBRAPID_GCC) || defined(LIBRAPID_CLANG)
24-
# if __cplusplus > 201703l && __has_builtin(__builtin_bit_cast)
25-
return __builtin_bit_cast(To, val);
26-
# else
27-
// Fallback option
28-
return *(To *)(&val);
29-
# endif // __has_builtin(__builtin_bit_cast)
24+
# if __cplusplus > 201703l && __has_builtin(__builtin_bit_cast)
25+
return __builtin_bit_cast(To, val);
26+
# else
27+
// Fallback option
28+
return *(To *)(&val);
29+
# endif // __has_builtin(__builtin_bit_cast)
3030
#else
31-
// Further fallback option
32-
return *(To *)(&val);
31+
// Further fallback option
32+
return *(To *)(&val);
3333
#endif
34-
}
34+
}
3535

36-
/// Returns true if the input value is NaN
37-
/// \tparam T The type of the value
38-
/// \param val The value to check
39-
/// \return True if the value is NaN, false otherwise
40-
template<typename T>
41-
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isNaN(const T &val) noexcept {
42-
return std::isnan(val);
43-
}
36+
/// Returns true if the input value is NaN
37+
/// \tparam T The type of the value
38+
/// \param val The value to check
39+
/// \return True if the value is NaN, false otherwise
40+
template<typename T>
41+
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isNaN(const T &val) noexcept {
42+
return std::isnan(val);
43+
}
4444

45-
/// Returns true if the input value is finite
46-
/// \tparam T The type of the value
47-
/// \param val The value to check
48-
/// \return True if the value is finite,
49-
template<typename T>
50-
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isFinite(const T &val) noexcept {
51-
return std::isfinite(val);
52-
}
45+
/// Returns true if the input value is finite
46+
/// \tparam T The type of the value
47+
/// \param val The value to check
48+
/// \return True if the value is finite,
49+
template<typename T>
50+
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isFinite(const T &val) noexcept {
51+
return std::isfinite(val);
52+
}
5353

54-
/// Returns true if the input value is infinite
55-
/// \tparam T The type of the value
56-
/// \param val The value to check
57-
/// \return True if the value is infinite,
58-
template<typename T>
59-
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isInf(const T &val) noexcept {
60-
return std::isinf(val);
61-
}
54+
/// Returns true if the input value is infinite
55+
/// \tparam T The type of the value
56+
/// \param val The value to check
57+
/// \return True if the value is infinite,
58+
template<typename T>
59+
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool isInf(const T &val) noexcept {
60+
return std::isinf(val);
61+
}
6262

63-
/// Create a new number with a given magnitude and sign
64-
/// \tparam T The type of the magnitude
65-
/// \tparam M The type of the sign
66-
/// \param mag The magnitude of the number
67-
/// \param sign The value from which to copy the sign
68-
/// \return
69-
template<typename T, typename M>
70-
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE T copySign(const T &mag, const M &sign) noexcept {
63+
/// Create a new number with a given magnitude and sign
64+
/// \tparam T The type of the magnitude
65+
/// \tparam M The type of the sign
66+
/// \param mag The magnitude of the number
67+
/// \param sign The value from which to copy the sign
68+
/// \return
69+
template<typename T, typename M>
70+
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE T copySign(const T &mag, const M &sign) noexcept {
7171
#if defined(LIBRAPID_MSVC)
72-
return std::copysign(mag, static_cast<T>(sign));
72+
return std::copysign(mag, static_cast<T>(sign));
7373
#else
74-
if constexpr (std::is_fundamental_v<T> && std::is_fundamental_v<M>) {
75-
return std::copysign(mag, static_cast<T>(sign));
76-
} else {
77-
if (sign < 0) return -mag;
78-
return mag;
79-
}
74+
if constexpr (std::is_fundamental_v<T> && std::is_fundamental_v<M>) {
75+
return std::copysign(mag, static_cast<T>(sign));
76+
} else {
77+
if (sign < 0) return -mag;
78+
return mag;
79+
}
8080
#endif
81-
}
81+
}
8282

83-
/// Extract the sign bit from a value
84-
/// \tparam T The type of the value
85-
/// \param val The value to extract the sign bit from
86-
/// \return The sign bit of the value
87-
template<typename T>
88-
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit(const T &val) noexcept {
89-
return signBit((double)val);
90-
}
83+
/// Extract the sign bit from a value
84+
/// \tparam T The type of the value
85+
/// \param val The value to extract the sign bit from
86+
/// \return The sign bit of the value
87+
template<typename T>
88+
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit(const T &val) noexcept {
89+
return signBit((double)val);
90+
}
9191

92-
/// Extract the sign bit from a value
93-
/// \param val The value to extract the sign bit from
94-
/// \return The sign bit of the value
95-
template<>
96-
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit(const long double &val) noexcept {
97-
return std::signbit(val);
98-
}
92+
/// Extract the sign bit from a value
93+
/// \param val The value to extract the sign bit from
94+
/// \return The sign bit of the value
95+
template<>
96+
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit(const long double &val) noexcept {
97+
return std::signbit(val);
98+
}
9999

100-
/// Extract the sign bit from a value
101-
/// \param val The value to extract the sign bit from
102-
/// \return The sign bit of the value
103-
template<>
104-
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit(const double &val) noexcept {
105-
return std::signbit(val);
106-
}
100+
/// Extract the sign bit from a value
101+
/// \param val The value to extract the sign bit from
102+
/// \return The sign bit of the value
103+
template<>
104+
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit(const double &val) noexcept {
105+
return std::signbit(val);
106+
}
107107

108-
/// Extract the sign bit from a value
109-
/// \param val The value to extract the sign bit from
110-
/// \return The sign bit of the value
111-
template<>
112-
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit(const float &val) noexcept {
113-
return std::signbit(val);
114-
}
108+
/// Extract the sign bit from a value
109+
/// \param val The value to extract the sign bit from
110+
/// \return The sign bit of the value
111+
template<>
112+
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE bool signBit(const float &val) noexcept {
113+
return std::signbit(val);
114+
}
115115

116-
/// Return a value multiplied by 2 raised to the power of an exponent
117-
/// \tparam T The type of the value
118-
/// \param x The value to multiply
119-
/// \param exp The exponent to raise 2 to
120-
/// \return x * 2^exp
121-
template<typename T>
122-
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE T ldexp(const T &x, const int64_t exp) noexcept {
123-
return std::ldexp(x, (int)exp);
124-
}
116+
/// Return a value multiplied by 2 raised to the power of an exponent
117+
/// \tparam T The type of the value
118+
/// \param x The value to multiply
119+
/// \param exp The exponent to raise 2 to
120+
/// \return x * 2^exp
121+
template<typename T>
122+
LIBRAPID_NODISCARD LIBRAPID_ALWAYS_INLINE T ldexp(const T &x, const int64_t exp) noexcept {
123+
return std::ldexp(x, (int)exp);
124+
}
125+
126+
/// \brief Copy \p bytes bytes from \p src to \p dest, ignoring the datatypes. There are no
127+
/// conversions performed and no error checking.
128+
/// \tparam A First type
129+
/// \tparam B Second type
130+
/// \param dest Destination pointer
131+
/// \param src Source pointer
132+
/// \param bytes Number of bytes to copy
133+
template<typename A, typename B>
134+
void memcpy(A *dest, const B *src, size_t bytes) {
135+
std::memcpy((void *)dest, (void *)src, bytes);
136+
}
125137
} // namespace librapid
126138

127139
#endif // LIBRAPID_UTILS_MEMUTILS_HPP

librapid/include/librapid/utils/serialize.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,20 @@ namespace librapid::serialize {
2727
std::vector<uint8_t> data;
2828
data.resize(sizeof(T) + sizeof(size_t));
2929
size_t hashed = hasher();
30-
std::memcpy(data.data() + sizeof(T), &hashed, sizeof(size_t));
31-
std::memcpy(data.data(), &obj, sizeof(T));
30+
memcpy(data.data() + sizeof(T), &hashed, sizeof(size_t));
31+
memcpy(data.data(), &obj, sizeof(T));
3232
return data;
3333
}
3434

3535
LIBRAPID_NODISCARD static T deserialize(const std::vector<uint8_t> &data) {
3636
size_t hashed;
37-
std::memcpy(&hashed, data.data() + sizeof(T), sizeof(size_t));
37+
memcpy(&hashed, data.data() + sizeof(T), sizeof(size_t));
3838
LIBRAPID_ASSERT(
3939
hasher() == hashed,
4040
"Hash mismatch. Ensure the types are the same and the data is not corrupted.");
4141

4242
T obj;
43-
std::memcpy(&obj, data.data(), sizeof(T));
43+
memcpy(&obj, data.data(), sizeof(T));
4444
return obj;
4545
}
4646
};

0 commit comments

Comments
 (0)