2
2
#include " ggml-backend.h"
3
3
#include " ggml-impl.h"
4
4
#include " gguf.h"
5
+ #include " uint8-buff-stream.h"
5
6
6
7
#include < cinttypes>
7
8
#include < cstddef>
@@ -216,14 +217,79 @@ struct gguf_context {
216
217
void * data = nullptr ;
217
218
};
218
219
219
- struct gguf_reader {
220
+ struct gguf_bytes_reader {
221
+ // / @brief Reads up to `count` objects into the array `buffer`.
222
+ // / The position of the underlying stream implementation is advanced
223
+ // / by the number of characters read.
224
+ // /
225
+ // / @note If an error occurs, the resulting value of the underlying stream
226
+ // / position indicator is indeterminate.
227
+ virtual size_t read (void * buffer, size_t size, size_t count) = 0;
228
+
229
+ // / @brief Seeks to a position aligned to the given alignment boundary.
230
+ // / @return The current position after alignment, or 0 on error.
231
+ virtual size_t align (size_t alignment) = 0;
232
+
233
+ virtual ~gguf_bytes_reader () = 0 ;
234
+ };
235
+
236
+ gguf_bytes_reader::~gguf_bytes_reader () {}
237
+
238
+ struct gguf_bytes_buffer_reader : public gguf_bytes_reader {
239
+ gguf_bytes_buffer_reader (std::basic_streambuf<uint8_t > & streambuf) : streambuf(streambuf), offset(0 ) {}
240
+
241
+ ~gguf_bytes_buffer_reader () {}
242
+
243
+ size_t read (void * buffer, size_t size, size_t count) override {
244
+ size_t total_size = size * count;
245
+ auto bytes_read = streambuf.sgetn (static_cast <uint8_t *>(buffer), total_size);
246
+ offset += bytes_read;
247
+ return bytes_read;
248
+ }
249
+
250
+ size_t align (size_t alignment) override {
251
+ size_t new_offset = GGML_PAD (offset, alignment);
252
+ size_t seek_offset = new_offset - offset;
253
+
254
+ auto result = streambuf.pubseekoff (seek_offset, std::ios_base::cur);
255
+ if (result == std::streampos (-1 )) {
256
+ return 0 ;
257
+ }
258
+ offset = new_offset;
259
+ return offset;
260
+ }
261
+
262
+ private:
263
+ std::basic_streambuf<uint8_t > & streambuf;
264
+ size_t offset;
265
+ };
266
+
267
+ struct gguf_bytes_file_reader : public gguf_bytes_reader {
268
+ gguf_bytes_file_reader (FILE * file) : file(file) {}
269
+
270
+ ~gguf_bytes_file_reader () {}
271
+
272
+ size_t read (void * buffer, size_t size, size_t count) override { return fread (buffer, 1 , size * count, file); }
273
+
274
+ size_t align (size_t alignment) override {
275
+ if (fseek (file, GGML_PAD (ftell (file), alignment), SEEK_SET) != 0 ) {
276
+ return 0 ;
277
+ }
278
+ return ftell (file);
279
+ }
280
+
281
+ private:
220
282
FILE * file;
283
+ };
221
284
222
- gguf_reader (FILE * file) : file(file) {}
285
+ struct gguf_reader {
286
+ gguf_bytes_reader& bytes_reader;
287
+
288
+ gguf_reader (gguf_bytes_reader& bytes_reader) : bytes_reader(bytes_reader) {}
223
289
224
290
template <typename T>
225
291
bool read (T & dst) const {
226
- return fread (&dst, 1 , sizeof (dst), file ) == sizeof (dst);
292
+ return bytes_reader. read (&dst, 1 , sizeof (dst)) == sizeof (dst);
227
293
}
228
294
229
295
template <typename T>
@@ -278,11 +344,11 @@ struct gguf_reader {
278
344
return false ;
279
345
}
280
346
dst.resize (size);
281
- return fread (dst.data (), 1 , dst.length (), file ) == dst.length ();
347
+ return bytes_reader. read (dst.data (), 1 , dst.length ()) == dst.length ();
282
348
}
283
349
284
350
bool read (void * dst, const size_t size) const {
285
- return fread (dst, 1 , size, file ) == size;
351
+ return bytes_reader. read (dst, 1 , size) == size;
286
352
}
287
353
};
288
354
@@ -316,8 +382,8 @@ bool gguf_read_emplace_helper(const struct gguf_reader & gr, std::vector<struct
316
382
return true ;
317
383
}
318
384
319
- struct gguf_context * gguf_init_from_file_impl (FILE * file, struct gguf_init_params params) {
320
- const struct gguf_reader gr (file);
385
+ namespace {
386
+ struct gguf_context * gguf_init_from_reader_impl ( const struct gguf_reader & gr, struct gguf_init_params params) {
321
387
struct gguf_context * ctx = new gguf_context;
322
388
323
389
bool ok = true ;
@@ -606,15 +672,14 @@ struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_par
606
672
GGML_ASSERT (int64_t (ctx->info .size ()) == n_tensors);
607
673
608
674
// we require the data section to be aligned, so take into account any padding
609
- if (fseek (file, GGML_PAD (ftell (file), ctx->alignment ), SEEK_SET) != 0 ) {
610
- GGML_LOG_ERROR (" %s: failed to seek to beginning of data section\n " , __func__);
675
+ // store the current file offset - this is where the data section starts
676
+ ctx->offset = gr.bytes_reader .align (ctx->alignment );
677
+ if (ctx->offset == 0 ) {
678
+ GGML_LOG_ERROR (" %s: failed to align data section\n " , __func__);
611
679
gguf_free (ctx);
612
680
return nullptr ;
613
681
}
614
682
615
- // store the current file offset - this is where the data section starts
616
- ctx->offset = ftell (file);
617
-
618
683
// compute the total size of the data section, taking into account the alignment
619
684
{
620
685
ctx->size = 0 ;
@@ -718,6 +783,13 @@ struct gguf_context * gguf_init_from_file_impl(FILE * file, struct gguf_init_par
718
783
719
784
return ctx;
720
785
}
786
+ }
787
+
788
+ struct gguf_context * gguf_init_from_file_impl (FILE * file, struct gguf_init_params params) {
789
+ gguf_bytes_file_reader bytes_reader (file);
790
+ gguf_reader reader (bytes_reader);
791
+ return gguf_init_from_reader_impl (reader, params);
792
+ }
721
793
722
794
struct gguf_context * gguf_init_from_file (const char * fname, struct gguf_init_params params) {
723
795
FILE * file = ggml_fopen (fname, " rb" );
@@ -732,6 +804,12 @@ struct gguf_context * gguf_init_from_file(const char * fname, struct gguf_init_p
732
804
return result;
733
805
}
734
806
807
+ struct gguf_context * gguf_init_from_buffer (std::basic_streambuf<uint8_t > & streambuf, struct gguf_init_params params) {
808
+ gguf_bytes_buffer_reader bytes_reader (streambuf);
809
+ gguf_reader reader (bytes_reader);
810
+ return gguf_init_from_reader_impl (reader, params);
811
+ }
812
+
735
813
void gguf_free (struct gguf_context * ctx) {
736
814
if (ctx == nullptr ) {
737
815
return ;
0 commit comments