@@ -55,6 +55,7 @@ typedef enum {
5555
5656struct hash_params {
5757 std::string input;
58+ bool fnv = false ;
5859 bool xxh64 = false ;
5960 bool sha1 = false ;
6061 bool sha256 = false ;
@@ -103,6 +104,7 @@ static void hash_print_usage(const char * executable) {
103104 printf (" \n " );
104105 printf (" options:\n " );
105106 printf (" -h, --help show this help message and exit\n " );
107+ printf (" --fnv use FNV-1a hash\n " );
106108 printf (" --xxh64 use xxh64 hash\n " );
107109 printf (" --sha1 use sha1 hash\n " );
108110 printf (" --sha256 use sha256 hash\n " );
@@ -131,6 +133,11 @@ static void hash_params_parse_ex(int argc, const char ** argv, hash_params & par
131133 exit (0 );
132134 }
133135
136+ if (arg == " --fnv" ) {
137+ arg_found = true ;
138+ params.fnv = true ;
139+ }
140+
134141 if (arg == " --xxh64" ) {
135142 arg_found = true ;
136143 params.xxh64 = true ;
@@ -283,6 +290,18 @@ static void generate_uuidv5(const unsigned char sha1_digest[20], unsigned char u
283290 uuid[ 8 ] |= (0x8 << 4 );
284291}
285292
293+ // Computes FNV-1a hash of the data
294+ static uint64_t fnv_hash (const uint8_t * data, size_t len) {
295+ const uint64_t fnv_prime = 0x100000001b3ULL ;
296+ uint64_t hash = 0xcbf29ce484222325ULL ;
297+
298+ for (size_t i = 0 ; i < len; ++i) {
299+ hash ^= data[i];
300+ hash *= fnv_prime;
301+ }
302+ return hash;
303+ }
304+
286305static hash_exit_code_t gguf_hash (const hash_params & hash_params) {
287306 const std::string & fname = hash_params.input ;
288307 struct ggml_context * ctx_data = NULL ;
@@ -326,7 +345,11 @@ static hash_exit_code_t gguf_hash(const hash_params & hash_params) {
326345 SHA1Update ( &sha1_for_uuid_ctx, (unsigned char const *)uuidv5_namespace, sizeof (uuidv5_namespace));
327346 }
328347
348+ struct gguf_context * ctx_out = gguf_init_empty ();
329349 struct gguf_context * ctx = gguf_init_from_file (fname.c_str (), params);
350+
351+ gguf_set_kv (ctx_out, ctx);
352+
330353 const int n_tensors = gguf_get_n_tensors (ctx);
331354 bool tensor_layer_in_manifest = false ;
332355 bool model_in_manifest = false ;
@@ -335,10 +358,19 @@ static hash_exit_code_t gguf_hash(const hash_params & hash_params) {
335358 for (int i = 0 ; i < n_tensors; ++i) {
336359 const char * name = gguf_get_tensor_name (ctx, i);
337360 struct ggml_tensor * cur = ggml_get_tensor (ctx_data, name);
361+ gguf_add_tensor (ctx_out, cur);
338362 auto n_bytes = ggml_nbytes (cur);
339363 auto *raw_data = cur->data ;
340364 const std::string tensor_layer_name = fname + " :" + name;
341365
366+ if (hash_params.fnv ) {
367+ uint64_t hash = fnv_hash ((const uint8_t *)raw_data, n_bytes);
368+ printf (" %016lx %s\n " , hash, tensor_layer_name.c_str ());
369+ char hash_key[128 ];
370+ snprintf (hash_key, sizeof (hash_key), " %s_hash" , name);
371+ gguf_set_val_u64 (ctx_out, hash_key, hash);
372+ }
373+
342374 if (hash_params.xxh64 ) {
343375
344376 if (!hash_params.no_layer ) {
@@ -580,6 +612,9 @@ static hash_exit_code_t gguf_hash(const hash_params & hash_params) {
580612 }
581613 }
582614
615+ auto fname_out = fname + " .rpc" ;
616+ gguf_write_to_file (ctx_out, fname_out.c_str (), false );
617+ gguf_free (ctx_out);
583618
584619 ggml_free (ctx_data);
585620 gguf_free (ctx);
@@ -663,7 +698,7 @@ int main(int argc, const char ** argv) {
663698
664699 // Autoselect the highest security hash if manifest is provided but
665700 // the user has not specifically defined the hash they care about
666- if (!params.xxh64 && !params.sha1 && !params.uuid && !params.sha256 ) {
701+ if (!params.fnv && !params. xxh64 && !params.sha1 && !params.uuid && !params.sha256 ) {
667702 // User has not selected a specific value, pick most secure hash
668703 if (manifest_check.sha256 ) {
669704 params.sha256 = true ;
@@ -680,7 +715,7 @@ int main(int argc, const char ** argv) {
680715 }
681716
682717 // By default if no swich argument provided, assume xxh64
683- if (!params.xxh64 && !params.sha1 && !params.uuid && !params.sha256 ) {
718+ if (!params.fnv && !params. xxh64 && !params.sha1 && !params.uuid && !params.sha256 ) {
684719 params.xxh64 = true ;
685720 }
686721
0 commit comments