Skip to content

Commit 27c19c4

Browse files
Implement write byteswap for tests
1 parent 088f9a6 commit 27c19c4

File tree

2 files changed

+158
-2
lines changed

2 files changed

+158
-2
lines changed

ggml/src/gguf.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,13 @@ struct gguf_writer {
11841184
template <typename T>
11851185
void write(const T & val) const {
11861186
for (size_t i = 0; i < sizeof(val); ++i) {
1187+
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
11871188
buf.push_back(reinterpret_cast<const int8_t *>(&val)[i]);
1189+
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1190+
buf.push_back(reinterpret_cast<const int8_t *>(&val)[sizeof(val) - i - 1]);
1191+
#else
1192+
#error Unexpected or undefined __BYTE_ORDER__
1193+
#endif
11881194
}
11891195
}
11901196

@@ -1233,6 +1239,7 @@ struct gguf_writer {
12331239
}
12341240

12351241
switch (kv.get_type()) {
1242+
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
12361243
case GGUF_TYPE_UINT8:
12371244
case GGUF_TYPE_INT8:
12381245
case GGUF_TYPE_UINT16:
@@ -1245,6 +1252,60 @@ struct gguf_writer {
12451252
case GGUF_TYPE_FLOAT64: {
12461253
write(kv.data);
12471254
} break;
1255+
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1256+
case GGUF_TYPE_UINT8: {
1257+
for (size_t i = 0; i < ne; ++i) {
1258+
write(kv.get_val<uint8_t>(i));
1259+
}
1260+
} break;
1261+
case GGUF_TYPE_INT8: {
1262+
for (size_t i = 0; i < ne; ++i) {
1263+
write(kv.get_val<int8_t>(i));
1264+
}
1265+
} break;
1266+
case GGUF_TYPE_UINT16: {
1267+
for (size_t i = 0; i < ne; ++i) {
1268+
write(kv.get_val<uint16_t>(i));
1269+
}
1270+
} break;
1271+
case GGUF_TYPE_INT16: {
1272+
for (size_t i = 0; i < ne; ++i) {
1273+
write(kv.get_val<int16_t>(i));
1274+
}
1275+
} break;
1276+
case GGUF_TYPE_UINT32: {
1277+
for (size_t i = 0; i < ne; ++i) {
1278+
write(kv.get_val<uint32_t>(i));
1279+
}
1280+
} break;
1281+
case GGUF_TYPE_INT32: {
1282+
for (size_t i = 0; i < ne; ++i) {
1283+
write(kv.get_val<int32_t>(i));
1284+
}
1285+
} break;
1286+
case GGUF_TYPE_FLOAT32: {
1287+
for (size_t i = 0; i < ne; ++i) {
1288+
write(kv.get_val<float>(i));
1289+
}
1290+
} break;
1291+
case GGUF_TYPE_UINT64: {
1292+
for (size_t i = 0; i < ne; ++i) {
1293+
write(kv.get_val<uint64_t>(i));
1294+
}
1295+
} break;
1296+
case GGUF_TYPE_INT64: {
1297+
for (size_t i = 0; i < ne; ++i) {
1298+
write(kv.get_val<int64_t>(i));
1299+
}
1300+
} break;
1301+
case GGUF_TYPE_FLOAT64: {
1302+
for (size_t i = 0; i < ne; ++i) {
1303+
write(kv.get_val<double>(i));
1304+
}
1305+
} break;
1306+
#else
1307+
#error Unexpected or undefined __BYTE_ORDER__
1308+
#endif
12481309
case GGUF_TYPE_BOOL: {
12491310
for (size_t i = 0; i < ne; ++i) {
12501311
write(kv.get_val<bool>(i));
@@ -1295,6 +1356,13 @@ struct gguf_writer {
12951356
memcpy(buf.data() + offset, info.t.data, nbytes);
12961357
}
12971358

1359+
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
1360+
auto byteswap = ggml_get_type_traits(info.t.type)->byteswap;
1361+
if (byteswap != nullptr) {
1362+
byteswap(buf.data() + offset, ggml_nelements(&(info.t)) / ggml_blck_size(info.t.type));
1363+
}
1364+
#endif
1365+
12981366
pad(alignment);
12991367
}
13001368
};

tests/test-gguf.cpp

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,43 @@
1010
#include <string>
1111
#include <vector>
1212

13+
#if defined(__gnu_linux__)
14+
#include <endian.h>
15+
#else
16+
#define le64toh(x) (x)
17+
#define le32toh(x) (x)
18+
#define le16toh(x) (x)
19+
#endif
20+
21+
// endianness conversion
22+
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
23+
#define convert_to_le(x)
24+
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
25+
#include <type_traits>
26+
27+
template <typename T, std::enable_if_t<sizeof(T) == 1, int> = 0>
28+
static inline void convert_to_le(T * /*value*/)
29+
{
30+
}
31+
32+
template <typename T, std::enable_if_t<sizeof(T) == 2, int> = 0>
33+
static inline void convert_to_le(T * value) {
34+
*((uint16_t*)value) = htole16(*((uint16_t*)value));
35+
}
36+
37+
template <typename T, std::enable_if_t<sizeof(T) == 4, int> = 0>
38+
static inline void convert_to_le(T * value) {
39+
*((uint32_t*)value) = htole32(*((uint32_t*)value));
40+
}
41+
42+
template <typename T, std::enable_if_t<sizeof(T) == 8, int> = 0>
43+
static inline void convert_to_le(T * value) {
44+
*((uint64_t*)value) = htole64(*((uint64_t*)value));
45+
}
46+
#else
47+
#error Unexpected or undefined __BYTE_ORDER__
48+
#endif
49+
1350
constexpr int offset_has_kv = 1000;
1451
constexpr int offset_has_tensors = 2000;
1552
constexpr int offset_has_data = 3000;
@@ -146,7 +183,8 @@ static std::vector<std::pair<enum gguf_type, enum gguf_type>> get_kv_types(std::
146183
}
147184

148185
template <typename T>
149-
static void helper_write(FILE * file, const T & val) {
186+
static void helper_write(FILE * file, T val) {
187+
convert_to_le(&val);
150188
GGML_ASSERT(fwrite(&val, 1, sizeof(val), file) == sizeof(val));
151189
}
152190

@@ -363,7 +401,9 @@ static FILE * get_handcrafted_file(const unsigned int seed, const enum handcraft
363401
helper_write(file, big_dim);
364402
}
365403
} else {
366-
helper_write(file, shape.data(), n_dims*sizeof(int64_t));
404+
for (uint32_t j = 0; j < n_dims; ++j) {
405+
helper_write(file, shape[j]);
406+
}
367407
}
368408

369409
{
@@ -533,6 +573,33 @@ static bool handcrafted_check_kv(const gguf_context * gguf_ctx, const unsigned i
533573
continue;
534574
}
535575

576+
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
577+
switch (type_arr) {
578+
case GGUF_TYPE_UINT16:
579+
case GGUF_TYPE_INT16:
580+
for (size_t j = 0; j < arr_n; ++j) {
581+
convert_to_le((uint16_t*)(data8 + j * 2));
582+
}
583+
break;
584+
585+
case GGUF_TYPE_UINT32:
586+
case GGUF_TYPE_INT32:
587+
case GGUF_TYPE_FLOAT32:
588+
for (size_t j = 0; j < arr_n; ++j) {
589+
convert_to_le((uint32_t*)(data8 + j * 4));
590+
}
591+
break;
592+
593+
case GGUF_TYPE_UINT64:
594+
case GGUF_TYPE_INT64:
595+
case GGUF_TYPE_FLOAT64:
596+
for (size_t j = 0; j < arr_n; ++j) {
597+
convert_to_le((uint64_t*)(data8 + j * 8));
598+
}
599+
break;
600+
}
601+
#endif
602+
536603
if (!std::equal(data8, data8 + arr_n*type_size, data_gguf)) {
537604
ok = false;
538605
}
@@ -548,6 +615,27 @@ static bool handcrafted_check_kv(const gguf_context * gguf_ctx, const unsigned i
548615
continue;
549616
}
550617

618+
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
619+
switch (type) {
620+
case GGUF_TYPE_UINT16:
621+
case GGUF_TYPE_INT16:
622+
convert_to_le((uint16_t*)(data8));
623+
break;
624+
625+
case GGUF_TYPE_UINT32:
626+
case GGUF_TYPE_INT32:
627+
case GGUF_TYPE_FLOAT32:
628+
convert_to_le((uint32_t*)(data8));
629+
break;
630+
631+
case GGUF_TYPE_UINT64:
632+
case GGUF_TYPE_INT64:
633+
case GGUF_TYPE_FLOAT64:
634+
convert_to_le((uint64_t*)(data8));
635+
break;
636+
}
637+
#endif
638+
551639
if (!std::equal(data8, data8 + gguf_type_size(type), data_gguf)) {
552640
ok = false;
553641
}

0 commit comments

Comments
 (0)