@@ -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