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
222220struct 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
705699struct 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
710712void 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
11341136struct 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
12931299bool 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
13051314size_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
13131321void 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