Skip to content

Commit 5d2a393

Browse files
revert to using FILE *
1 parent b6c4b5a commit 5d2a393

File tree

3 files changed

+145
-133
lines changed

3 files changed

+145
-133
lines changed

ggml/src/ggml-impl.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -558,10 +558,10 @@ static inline ggml_bf16_t ggml_compute_fp32_to_bf16(float s) {
558558
#endif
559559

560560
#ifdef __cplusplus
561-
#include <iostream>
561+
#include <vector>
562562

563563
// expose GGUF internals for test code
564564
GGML_API size_t gguf_type_size(enum gguf_type type);
565-
GGML_API struct gguf_context * gguf_init_from_file_impl(std::istream & is, struct gguf_init_params params);
566-
GGML_API void gguf_write_to_buf(const struct gguf_context * ctx, std::ostream & os, bool only_meta);
565+
GGML_API struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_params params);
566+
GGML_API void gguf_write_to_buf(const struct gguf_context * ctx, std::vector<int8_t> & buf, bool only_meta);
567567
#endif // __cplusplus

ggml/src/gguf.cpp

Lines changed: 67 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
#include <cstdio>
1010
#include <cstdlib>
1111
#include <cstring>
12-
#include <fstream>
13-
#include <iostream>
1412
#include <map>
1513
#include <new>
1614
#include <sstream>
@@ -220,14 +218,13 @@ struct gguf_context {
220218
};
221219

222220
struct gguf_reader {
223-
std::istream & is;
221+
FILE * file;
224222

225-
gguf_reader(std::istream & is) : is(is) {}
223+
gguf_reader(FILE * file) : file(file) {}
226224

227225
template <typename T>
228226
bool read(T & dst) {
229-
is.read(reinterpret_cast<char *>(&dst), sizeof(dst));
230-
return is.good();
227+
return fread(&dst, 1, sizeof(dst), file) == sizeof(dst);
231228
}
232229

233230
template <typename T>
@@ -246,7 +243,7 @@ struct gguf_reader {
246243
}
247244
}
248245
}
249-
return is.good();
246+
return true;
250247
}
251248

252249
bool read(bool & dst) {
@@ -255,7 +252,7 @@ struct gguf_reader {
255252
return false;
256253
}
257254
dst = tmp != 0;
258-
return is.good();
255+
return true;
259256
}
260257

261258
bool read(enum ggml_type & dst) {
@@ -264,7 +261,7 @@ struct gguf_reader {
264261
return false;
265262
}
266263
dst = ggml_type(tmp);
267-
return is.good();
264+
return true;
268265
}
269266

270267
bool read(enum gguf_type & dst) {
@@ -273,7 +270,7 @@ struct gguf_reader {
273270
return false;
274271
}
275272
dst = gguf_type(tmp);
276-
return is.good();
273+
return true;
277274
}
278275

279276
bool read(std::string & dst) {
@@ -282,13 +279,11 @@ struct gguf_reader {
282279
return false;
283280
}
284281
dst.resize(size);
285-
is.read(dst.data(), dst.length());
286-
return is.good();
282+
return fread(dst.data(), 1, dst.length(), file) == dst.length();
287283
}
288284

289285
bool read(void * dst, const size_t size) {
290-
is.read(reinterpret_cast<char *>(dst), size);
291-
return is.good();
286+
return fread(dst, 1, size, file) == size;
292287
}
293288
};
294289

@@ -322,8 +317,8 @@ bool gguf_read_emplace_helper(struct gguf_reader & gr, std::vector<struct gguf_k
322317
return true;
323318
}
324319

325-
struct gguf_context * gguf_init_from_file_impl(std::istream & is, struct gguf_init_params params) {
326-
struct gguf_reader gr(is);
320+
struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_params params) {
321+
struct gguf_reader gr(file);
327322
struct gguf_context * ctx = new gguf_context;
328323

329324
bool ok = true;
@@ -430,18 +425,18 @@ struct gguf_context * gguf_init_from_file_impl(std::istream & is, struct gguf_in
430425
}
431426

432427
switch (type) {
433-
case GGUF_TYPE_UINT8: ok = ok && gguf_read_emplace_helper<uint8_t> (gr, ctx->kv, key, is_array, n); break;
434-
case GGUF_TYPE_INT8: ok = ok && gguf_read_emplace_helper<int8_t> (gr, ctx->kv, key, is_array, n); break;
435-
case GGUF_TYPE_UINT16: ok = ok && gguf_read_emplace_helper<uint16_t> (gr, ctx->kv, key, is_array, n); break;
436-
case GGUF_TYPE_INT16: ok = ok && gguf_read_emplace_helper<int16_t> (gr, ctx->kv, key, is_array, n); break;
437-
case GGUF_TYPE_UINT32: ok = ok && gguf_read_emplace_helper<uint32_t> (gr, ctx->kv, key, is_array, n); break;
438-
case GGUF_TYPE_INT32: ok = ok && gguf_read_emplace_helper<int32_t> (gr, ctx->kv, key, is_array, n); break;
439-
case GGUF_TYPE_FLOAT32: ok = ok && gguf_read_emplace_helper<float> (gr, ctx->kv, key, is_array, n); break;
440-
case GGUF_TYPE_BOOL: ok = ok && gguf_read_emplace_helper<bool> (gr, ctx->kv, key, is_array, n); break;
441-
case GGUF_TYPE_STRING: ok = ok && gguf_read_emplace_helper<std::string>(gr, ctx->kv, key, is_array, n); break;
442-
case GGUF_TYPE_UINT64: ok = ok && gguf_read_emplace_helper<uint64_t> (gr, ctx->kv, key, is_array, n); break;
443-
case GGUF_TYPE_INT64: ok = ok && gguf_read_emplace_helper<int64_t> (gr, ctx->kv, key, is_array, n); break;
444-
case GGUF_TYPE_FLOAT64: ok = ok && gguf_read_emplace_helper<double> (gr, ctx->kv, key, is_array, n); break;
428+
case GGUF_TYPE_UINT8: ok = ok && gguf_read_emplace_helper<uint8_t> (gr, ctx->kv, key, is_array, n); break;
429+
case GGUF_TYPE_INT8: ok = ok && gguf_read_emplace_helper<int8_t> (gr, ctx->kv, key, is_array, n); break;
430+
case GGUF_TYPE_UINT16: ok = ok && gguf_read_emplace_helper<uint16_t> (gr, ctx->kv, key, is_array, n); break;
431+
case GGUF_TYPE_INT16: ok = ok && gguf_read_emplace_helper<int16_t> (gr, ctx->kv, key, is_array, n); break;
432+
case GGUF_TYPE_UINT32: ok = ok && gguf_read_emplace_helper<uint32_t> (gr, ctx->kv, key, is_array, n); break;
433+
case GGUF_TYPE_INT32: ok = ok && gguf_read_emplace_helper<int32_t> (gr, ctx->kv, key, is_array, n); break;
434+
case GGUF_TYPE_FLOAT32: ok = ok && gguf_read_emplace_helper<float> (gr, ctx->kv, key, is_array, n); break;
435+
case GGUF_TYPE_BOOL: ok = ok && gguf_read_emplace_helper<bool> (gr, ctx->kv, key, is_array, n); break;
436+
case GGUF_TYPE_STRING: ok = ok && gguf_read_emplace_helper<std::string>(gr, ctx->kv, key, is_array, n); break;
437+
case GGUF_TYPE_UINT64: ok = ok && gguf_read_emplace_helper<uint64_t> (gr, ctx->kv, key, is_array, n); break;
438+
case GGUF_TYPE_INT64: ok = ok && gguf_read_emplace_helper<int64_t> (gr, ctx->kv, key, is_array, n); break;
439+
case GGUF_TYPE_FLOAT64: ok = ok && gguf_read_emplace_helper<double> (gr, ctx->kv, key, is_array, n); break;
445440
case GGUF_TYPE_ARRAY:
446441
default:
447442
{
@@ -593,15 +588,14 @@ struct gguf_context * gguf_init_from_file_impl(std::istream & is, struct gguf_in
593588
GGML_ASSERT(ctx->info.size() == n_tensors);
594589

595590
// we require the data section to be aligned, so take into account any padding
596-
gr.is.seekg(GGML_PAD(size_t(gr.is.tellg()), ctx->alignment), std::ifstream::beg);
597-
if (gr.is.bad()) {
591+
if (fseek(file, GGML_PAD(ftell(file), ctx->alignment), SEEK_SET) != 0) {
598592
fprintf(stderr, "%s: failed to seek to beginning of data section\n", __func__);
599593
gguf_free(ctx);
600594
return nullptr;
601595
}
602596

603597
// store the current file offset - this is where the data section starts
604-
ctx->offset = gr.is.tellg();
598+
ctx->offset = ftell(file);
605599

606600
// compute the total size of the data section, taking into account the alignment
607601
{
@@ -703,8 +697,16 @@ struct gguf_context * gguf_init_from_file_impl(std::istream & is, struct gguf_in
703697
}
704698

705699
struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_params params) {
706-
std::ifstream ifs(fname, std::ios::binary);
707-
return gguf_init_from_file_impl(ifs, params);
700+
FILE * file = ggml_fopen(fname, "rb");
701+
702+
if (!file) {
703+
fprintf(stderr, "%s: failed to open GGUF file '%s'\n", __func__, fname);
704+
return nullptr;
705+
}
706+
707+
struct gguf_context * result = gguf_init_from_file_impl(file, params);
708+
fclose(file);
709+
return result;
708710
}
709711

710712
void gguf_free(struct gguf_context * ctx) {
@@ -1132,17 +1134,19 @@ void gguf_set_tensor_data(struct gguf_context * ctx, const char * name, const vo
11321134
}
11331135

11341136
struct gguf_writer {
1135-
std::ostream & os;
1137+
std::vector<int8_t> & buf;
11361138

1137-
gguf_writer(std::ostream & os) : os(os) {}
1139+
gguf_writer(std::vector<int8_t> & buf) : buf(buf) {}
11381140

11391141
template <typename T>
11401142
void write(const T & val) {
1141-
os.write(reinterpret_cast<const char *>(&val), sizeof(val));
1143+
for (size_t i = 0; i < sizeof(val); ++i) {
1144+
buf.push_back(reinterpret_cast<const int8_t *>(&val)[i]);
1145+
}
11421146
}
11431147

11441148
void write(const std::vector<int8_t> & val) {
1145-
os.write(reinterpret_cast<const char *>(val.data()), val.size());
1149+
buf.insert(buf.end(), val.begin(), val.end());
11461150
}
11471151

11481152
void write(const bool & val) {
@@ -1155,7 +1159,9 @@ struct gguf_writer {
11551159
const uint64_t n = val.length();
11561160
write(n);
11571161
}
1158-
os.write(val.data(), val.size());
1162+
for (size_t i = 0; i < val.length(); ++i) {
1163+
buf.push_back(reinterpret_cast<const int8_t *>(val.data())[i]);
1164+
}
11591165
}
11601166

11611167
void write(const char * val) {
@@ -1225,33 +1231,33 @@ struct gguf_writer {
12251231
}
12261232

12271233
void pad(const size_t alignment) {
1228-
while (size_t(os.tellp()) % alignment != 0) {
1234+
while (buf.size() % alignment != 0) {
12291235
const int8_t zero = 0;
12301236
write(zero);
12311237
}
12321238
}
12331239

12341240
void write_tensor_data(const struct gguf_tensor_info & info, const size_t offset_data, const size_t alignment) {
1235-
GGML_ASSERT(size_t(os.tellp()) - offset_data == info.offset);
1241+
GGML_ASSERT(buf.size() - offset_data == info.offset);
12361242

12371243
GGML_ASSERT(ggml_is_contiguous(&info.t));
1244+
const size_t offset = buf.size();
12381245
const size_t nbytes = ggml_nbytes(&info.t);
12391246

1240-
std::vector<int8_t> tmp(nbytes);
1247+
buf.resize(offset + nbytes);
12411248
if (info.t.buffer) {
1242-
ggml_backend_tensor_get(&info.t, tmp.data(), 0, nbytes);
1249+
ggml_backend_tensor_get(&info.t, buf.data() + offset, 0, nbytes);
12431250
} else {
12441251
GGML_ASSERT(info.t.data);
1245-
memcpy(tmp.data(), info.t.data, nbytes);
1252+
memcpy(buf.data() + offset, info.t.data, nbytes);
12461253
}
1247-
write(tmp);
12481254

12491255
pad(alignment);
12501256
}
12511257
};
12521258

1253-
void gguf_write_to_buf(const struct gguf_context * ctx, std::ostream & os, bool only_meta) {
1254-
struct gguf_writer gw(os);
1259+
void gguf_write_to_buf(const struct gguf_context * ctx, std::vector<int8_t> & buf, bool only_meta) {
1260+
struct gguf_writer gw(buf);
12551261

12561262
const uint64_t n_kv = ctx->kv.size();
12571263
const uint64_t n_tensors = ctx->info.size();
@@ -1282,7 +1288,7 @@ void gguf_write_to_buf(const struct gguf_context * ctx, std::ostream & os, bool
12821288
return;
12831289
}
12841290

1285-
const size_t offset_data = gw.os.tellp();
1291+
const size_t offset_data = gw.buf.size();
12861292

12871293
// write tensor data
12881294
for (uint64_t i = 0; i < n_tensors; ++i) {
@@ -1291,28 +1297,29 @@ void gguf_write_to_buf(const struct gguf_context * ctx, std::ostream & os, bool
12911297
}
12921298

12931299
bool gguf_write_to_file(const struct gguf_context * ctx, const char * fname, bool only_meta) {
1294-
std::ofstream fout(fname, std::ios::binary);
1300+
FILE * file = ggml_fopen(fname, "wb");
12951301

1296-
if (!fout) {
1297-
fprintf(stderr, "%s: failed to open '%s' for writing GGUF data\n", __func__, fname);
1302+
if (!file) {
1303+
fprintf(stderr, "%s: failed to open file '%s' for writing GGUF data\n", __func__, fname);
12981304
return false;
12991305
}
13001306

1301-
gguf_write_to_buf(ctx, fout, only_meta);
1302-
return fout.good();
1307+
std::vector<int8_t> buf;
1308+
gguf_write_to_buf(ctx, buf, only_meta);
1309+
const bool ok = fwrite(buf.data(), 1, buf.size(), file) == buf.size();
1310+
fclose(file);
1311+
return ok;
13031312
}
13041313

13051314
size_t gguf_get_meta_size(const struct gguf_context * ctx) {
13061315
// only return size
1307-
std::stringstream ss;
1308-
gguf_write_to_buf(ctx, ss, /*only_meta =*/ true);
1309-
GGML_ASSERT(ss.good());
1310-
return ss.tellp();
1316+
std::vector<int8_t> buf;
1317+
gguf_write_to_buf(ctx, buf, /*only_meta =*/ true);
1318+
return buf.size();
13111319
}
13121320

13131321
void gguf_get_meta_data(const struct gguf_context * ctx, void * data) {
1314-
std::stringstream ss;
1315-
gguf_write_to_buf(ctx, ss, /*only_meta =*/ true);
1316-
GGML_ASSERT(ss.good());
1317-
memcpy(data, ss.rdbuf()->str().data(), ss.tellp());
1322+
std::vector<int8_t> buf;
1323+
gguf_write_to_buf(ctx, buf, /*only_meta =*/ true);
1324+
memcpy(data, buf.data(), buf.size());
13181325
}

0 commit comments

Comments
 (0)