char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
2b4cbd283
char/aliceai-t5-moe
1#pragma once 2 3#include <string> 4#include <sstream> 5#include <algorithm> 6#include <cstdint> 7#include <cstring> 8 9namespace jinja { 10 11static void string_replace_all (std ::string & s ,const std ::string & search ,const std ::string & replace ) { 12if (search .empty ()) { 13return ; 14 } 15std ::string builder ; 16builder .reserve (s .length ()); 17size_t pos = 0 ; 18size_t last_pos = 0 ; 19while ((pos = s .find (search ,last_pos ))!= std ::string ::npos ) { 20builder .append (s ,last_pos ,pos - last_pos ); 21builder .append (replace ); 22last_pos = pos + search .length (); 23 } 24builder .append (s ,last_pos ,std ::string ::npos ); 25s = std ::move (builder ); 26} 27 28// for displaying source code around error position 29static std ::string peak_source (const std ::string & source ,size_t pos ,size_t max_peak_chars = 40 ) { 30if (source .empty ()) { 31return "(no source available)" ; 32 } 33std ::string output ; 34size_t start = (pos >=max_peak_chars ) ? (pos - max_peak_chars ) :0 ; 35size_t end = std ::min (pos + max_peak_chars ,source .length ()); 36std ::string substr = source .substr (start ,end - start ); 37string_replace_all (substr ,"\n" ,"↵" ); 38output += "..." + substr + "...\n" ; 39std ::string spaces (pos - start + 3 ,' ' ); 40output += spaces + "^" ; 41return output ; 42} 43 44static std ::string fmt_error_with_source (const std ::string & tag ,const std ::string & msg ,const std ::string & source ,size_t pos ) { 45std ::ostringstream oss ; 46oss <<tag <<": " <<msg <<"\n" ; 47oss <<peak_source (source ,pos ); 48return oss .str (); 49} 50 51// Note: this is a simple hasher, not cryptographically secure, just for hash table usage 52struct hasher { 53static constexpr autosize_t_digits = sizeof (size_t )* 8 ; 54static constexprsize_t prime = size_t_digits == 64 ?0x100000001b3 :0x01000193 ; 55static constexprsize_t seed = size_t_digits == 64 ?0xcbf29ce484222325 :0x811c9dc5 ; 56static constexpr autoblock_size = sizeof (size_t );// in bytes; allowing the compiler to vectorize the computation 57 58static_assert (size_t_digits == 64 || size_t_digits == 32 ); 59static_assert (block_size == 8 || block_size == 4 ); 60 61uint8_t buffer [block_size ]; 62size_t idx = 0 ;// current index in buffer 63size_t state = seed ; 64 65hasher ()= default ; 66hasher (const std ::type_info & type_inf )noexcept { 67const autotype_hash = type_inf .hash_code (); 68update (& type_hash ,sizeof (type_hash )); 69 } 70 71// Properties: 72// - update is not associative: update(a).update(b) != update(b).update(a) 73// - update(a ~ b) == update(a).update(b) with ~ as concatenation operator --> useful for streaming 74// - update("", 0) --> state unchanged with empty input 75hasher & update (void const * bytes ,size_t len )noexcept { 76const uint8_t * c = static_cast < uint8_t const *> (bytes ); 77if (len == 0 ) { 78return * this ; 79 } 80size_t processed = 0 ; 81 82// first, fill the existing buffer if it's partial 83if (idx > 0 ) { 84size_t to_fill = block_size - idx ; 85if (to_fill > len ) { 86to_fill = len ; 87 } 88std ::memcpy (buffer + idx ,c ,to_fill ); 89idx += to_fill ; 90processed += to_fill ; 91if (idx == block_size ) { 92update_block (buffer ); 93idx = 0 ; 94 } 95 } 96 97// process full blocks from the remaining input 98for (;processed + block_size <=len ;processed += block_size ) { 99update_block (c + processed ); 100 } 101 102// buffer any remaining bytes 103size_t remaining = len - processed ; 104if (remaining > 0 ) { 105std ::memcpy (buffer ,c + processed ,remaining ); 106idx = remaining ; 107 } 108return * this ; 109 } 110 111// convenience function for testing only 112hasher & update (const std ::string & s )noexcept { 113return update (s .data (),s .size ()); 114 } 115 116// finalize and get the hash value 117// note: after calling digest, the hasher state is modified, do not call update() again 118size_t digest ()noexcept { 119// if there are remaining bytes in buffer, fill the rest with zeros and process 120if (idx > 0 ) { 121for (size_t i = idx ;i < block_size ;++ i ) { 122buffer [i ]= 0 ; 123 } 124update_block (buffer ); 125idx = 0 ; 126 } 127 128return state ; 129 } 130 131private : 132// IMPORTANT: block must have at least block_size bytes 133void update_block (const uint8_t * block )noexcept { 134size_t blk = static_cast < uint32_t > (block [0 ]) 135 | (static_cast < uint32_t > (block [1 ]) <<8 ) 136 | (static_cast < uint32_t > (block [2 ]) <<16 ) 137 | (static_cast < uint32_t > (block [3 ]) <<24 ); 138if constexpr (block_size == 8 ) { 139blk = blk | (static_cast < uint64_t > (block [4 ]) <<32 ) 140 | (static_cast < uint64_t > (block [5 ]) <<40 ) 141 | (static_cast < uint64_t > (block [6 ]) <<48 ) 142 | (static_cast < uint64_t > (block [7 ]) <<56 ); 143 } 144state ^=blk ; 145state *=prime ; 146 } 147}; 148 149}// namespace jinja