char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
5d5cb4c3a
char/aliceai-t5-moe
1#include "ggml.h" 2#include "ggml-impl.h" 3#include "ggml-backend.h" 4#include "ggml-backend-impl.h" 5#include "ggml-alloc.h" 6#include "ggml-cpp.h" 7 8#include <algorithm> 9#include <cassert> 10#include <cmath> 11#include <cstddef> 12#include <cstdint> 13#include <cstring> 14#include <map> 15#include <memory> 16#include <set> 17#include <string> 18#include <tuple> 19#include <utility> 20#include <vector> 21 22struct ggml_backend_meta_device ; 23struct ggml_backend_meta_buffer_type ; 24struct ggml_backend_meta_buffer ; 25struct ggml_backend_meta ; 26 27const char * ggml_backend_meta_split_axis_name (enum ggml_backend_meta_split_axis split_axis ) { 28switch (split_axis ) { 29case GGML_BACKEND_SPLIT_AXIS_0 : 30return "0" ; 31case GGML_BACKEND_SPLIT_AXIS_1 : 32return "1" ; 33case GGML_BACKEND_SPLIT_AXIS_2 : 34return "2" ; 35case GGML_BACKEND_SPLIT_AXIS_3 : 36return "3" ; 37case GGML_BACKEND_SPLIT_AXIS_MIRRORED : 38return "MIRRORED" ; 39case GGML_BACKEND_SPLIT_AXIS_PARTIAL : 40return "PARTIAL" ; 41case GGML_BACKEND_SPLIT_AXIS_NONE : 42return "NONE" ; 43case GGML_BACKEND_SPLIT_AXIS_UNKNOWN : 44return "UNKNOWN" ; 45default : 46GGML_ABORT ("fatal error" ); 47 } 48} 49 50// 51// meta backend device 52// 53 54struct ggml_backend_meta_device_context { 55 std::vector < ggml_backend_dev_t > simple_devs ; 56ggml_backend_meta_get_split_state_t get_split_state ; 57void * get_split_state_ud ; 58 59 std::string name ; 60 std::string description ; 61 62ggml_backend_meta_device_context ( 63 std::vector < ggml_backend_dev_t > simple_devs ,ggml_backend_meta_get_split_state_t get_split_state ,void * get_split_state_ud ) : 64simple_devs (std::move (simple_devs )),get_split_state (get_split_state ),get_split_state_ud (get_split_state_ud ) { 65name = std::string ("Meta(" ); 66description = std::string ("Meta(" ); 67for (size_t i = 0 ;i < simple_devs .size ();i ++ ) { 68if (i > 0 ) { 69name += "," ; 70description += "," ; 71 } 72name += ggml_backend_dev_name (simple_devs [i ]); 73description += ggml_backend_dev_description (simple_devs [i ]); 74 } 75name += ")" ; 76description += ")" ; 77 } 78 79bool operator< (const ggml_backend_meta_device_context & other )const { 80return std::tie (simple_devs ,get_split_state ,get_split_state_ud ) 81< std::tie (other .simple_devs ,other .get_split_state ,other .get_split_state_ud ); 82 } 83}; 84 85static bool ggml_backend_dev_is_meta (ggml_backend_dev_t dev ); 86 87static const char * ggml_backend_meta_device_get_name (ggml_backend_dev_t dev ) { 88GGML_ASSERT (ggml_backend_dev_is_meta (dev )); 89const ggml_backend_meta_device_context * meta_dev_ctx = (const ggml_backend_meta_device_context * )dev -> context ; 90return meta_dev_ctx -> name .c_str (); 91} 92 93static const char * ggml_backend_meta_device_get_description (ggml_backend_dev_t dev ) { 94GGML_ASSERT (ggml_backend_dev_is_meta (dev )); 95const ggml_backend_meta_device_context * meta_dev_ctx = (const ggml_backend_meta_device_context * )dev -> context ; 96return meta_dev_ctx -> description .c_str (); 97} 98 99static void ggml_backend_meta_device_get_memory (ggml_backend_dev_t dev ,size_t * free ,size_t * total ) { 100GGML_ASSERT (ggml_backend_dev_is_meta (dev )); 101const ggml_backend_meta_device_context * meta_dev_ctx = (const ggml_backend_meta_device_context * )dev -> context ; 102* free = 0 ; 103* total = 0 ; 104for (ggml_backend_dev_t dev :meta_dev_ctx -> simple_devs ) { 105size_t tmp_free ,tmp_total ; 106ggml_backend_dev_memory (dev ,& tmp_free ,& tmp_total ); 107* free += tmp_free ; 108* total += tmp_total ; 109 } 110} 111 112static enum ggml_backend_dev_type ggml_backend_meta_device_get_type (ggml_backend_dev_t dev ) { 113return GGML_BACKEND_DEVICE_TYPE_META ; 114 115GGML_UNUSED (dev ); 116} 117 118static void ggml_backend_meta_device_get_props (ggml_backend_dev_t dev ,ggml_backend_dev_props * props ) { 119GGML_ASSERT (ggml_backend_dev_is_meta (dev )); 120const ggml_backend_meta_device_context * meta_dev_ctx = (const ggml_backend_meta_device_context * )dev -> context ; 121 122// TODO replace placeholders 123props -> name = ggml_backend_meta_device_get_name (dev ); 124props -> description = ggml_backend_meta_device_get_description (dev ); 125props -> type = ggml_backend_meta_device_get_type (dev ); 126props -> device_id = 0 ; 127 128ggml_backend_meta_device_get_memory (dev ,& props -> memory_free ,& props -> memory_total ); 129 130props -> caps = { 131/* .async = */ true, 132/* .host_buffer = */ false,// Not implemented. 133/* .buffer_from_host_ptr = */ false,// Not implemented. 134/* .events = */ false,// Not implemented. 135/* .mmap_support = */ true, 136 }; 137for (ggml_backend_dev_t simple_dev :meta_dev_ctx -> simple_devs ) { 138ggml_backend_dev_props tmp_props ; 139ggml_backend_dev_get_props (simple_dev ,& tmp_props ); 140props -> caps .async = props -> caps .async && tmp_props .caps .async ; 141props -> caps .host_buffer = props -> caps .host_buffer && tmp_props .caps .host_buffer ; 142props -> caps .buffer_from_host_ptr = props -> caps .buffer_from_host_ptr && tmp_props .caps .buffer_from_host_ptr ; 143props -> caps .events = props -> caps .events && tmp_props .caps .events ; 144props -> caps .mmap_support = props -> caps .mmap_support && tmp_props .caps .mmap_support ; 145 } 146} 147 148static ggml_backend_t ggml_backend_meta_device_init_backend (ggml_backend_dev_t dev ,const char * params ); 149 150static ggml_backend_buffer_type_t ggml_backend_meta_device_get_buffer_type (ggml_backend_dev_t dev ); 151 152static ggml_backend_buffer_type_t ggml_backend_meta_device_get_host_buffer_type (ggml_backend_dev_t dev ); 153 154static bool ggml_backend_meta_device_supports_op (ggml_backend_dev_t dev ,const ggml_tensor * op ) { 155GGML_ASSERT (ggml_backend_dev_is_meta (dev )); 156const ggml_backend_meta_device_context * meta_dev_ctx = (const ggml_backend_meta_device_context * )dev -> context ; 157return std::all_of (meta_dev_ctx -> simple_devs .begin (),meta_dev_ctx -> simple_devs .end (), 158 [op ](ggml_backend_dev_t simple_dev ) {return ggml_backend_dev_supports_op (simple_dev ,op ); }); 159} 160 161static bool ggml_backend_meta_device_supports_buft (ggml_backend_dev_t dev ,ggml_backend_buffer_type_t buft ) { 162GGML_ASSERT (ggml_backend_dev_is_meta (dev )); 163ggml_backend_dev_t dev_buft = ggml_backend_buft_get_device (buft ); 164if (!ggml_backend_dev_is_meta (dev_buft )) { 165return false; 166 } 167const ggml_backend_meta_device_context * meta_dev_ctx = (const ggml_backend_meta_device_context * )dev -> context ; 168const ggml_backend_meta_device_context * meta_buft_dev_ctx = (const ggml_backend_meta_device_context * )dev_buft -> context ; 169if (meta_dev_ctx -> simple_devs .size ()!= meta_buft_dev_ctx -> simple_devs .size ()) { 170return false; 171 } 172for (size_t i = 0 ;i < meta_dev_ctx -> simple_devs .size ();i ++ ) { 173if (meta_dev_ctx -> simple_devs [i ]!= meta_buft_dev_ctx -> simple_devs [i ]) { 174return false; 175 } 176 } 177return true; 178} 179 180static const ggml_backend_device_i ggml_backend_meta_device_iface = { 181/* .get_name = */ ggml_backend_meta_device_get_name , 182/* .get_description = */ ggml_backend_meta_device_get_description , 183/* .get_memory = */ ggml_backend_meta_device_get_memory , 184/* .get_type = */ ggml_backend_meta_device_get_type , 185/* .get_props = */ ggml_backend_meta_device_get_props , 186/* .init_backend = */ ggml_backend_meta_device_init_backend , 187/* .get_buffer_type = */ ggml_backend_meta_device_get_buffer_type , 188/* .get_host_buffer_type = */ ggml_backend_meta_device_get_host_buffer_type , 189/* .buffer_from_host_ptr = */ nullptr , 190/* .supports_op = */ ggml_backend_meta_device_supports_op , 191/* .supports_buft = */ ggml_backend_meta_device_supports_buft , 192/* .offload_op = */ nullptr , 193/* .event_new = */ nullptr , 194/* .event_free = */ nullptr , 195/* .event_synchronize = */ nullptr , 196}; 197 198static bool ggml_backend_dev_is_meta (ggml_backend_dev_t dev ) { 199return dev != nullptr && dev -> iface .get_name == ggml_backend_meta_device_iface .get_name ; 200} 201 202static size_t ggml_backend_meta_dev_n_devs (ggml_backend_dev_t meta_dev ) { 203GGML_ASSERT (ggml_backend_dev_is_meta (meta_dev )); 204const ggml_backend_meta_device_context * meta_dev_ctx = (const ggml_backend_meta_device_context * )meta_dev -> context ; 205return meta_dev_ctx -> simple_devs .size (); 206} 207 208static ggml_backend_dev_t ggml_backend_meta_dev_simple_dev (ggml_backend_dev_t meta_dev ,size_t index ) { 209GGML_ASSERT (ggml_backend_dev_is_meta (meta_dev )); 210const ggml_backend_meta_device_context * meta_dev_ctx = (const ggml_backend_meta_device_context * )meta_dev -> context ; 211GGML_ASSERT (index < meta_dev_ctx -> simple_devs .size ()); 212return meta_dev_ctx -> simple_devs [index ]; 213} 214 215ggml_backend_dev_t ggml_backend_meta_device ( 216ggml_backend_dev_t * devs ,size_t n_devs ,ggml_backend_meta_get_split_state_t get_split_state ,void * get_split_state_ud ) { 217GGML_ASSERT (n_devs <=GGML_BACKEND_META_MAX_DEVICES ); 218// TODO: this is not thread-safe - needs to be fixed 219static std::vector < std::unique_ptr < ggml_backend_meta_device_context >> ctxs ; 220static std::map < ggml_backend_meta_device_context ,struct ggml_backend_device > meta_devs ; 221 222 std::vector < ggml_backend_dev_t > simple_devs ; 223simple_devs .reserve (n_devs ); 224for (size_t i = 0 ;i < n_devs ;i ++ ) { 225simple_devs .push_back (devs [i ]); 226 } 227ggml_backend_meta_device_context ctx (simple_devs ,get_split_state ,get_split_state_ud ); 228 229 { 230auto it = meta_devs .find (ctx ); 231if (it != meta_devs .end ()) { 232return & it -> second ; 233 } 234 } 235ctxs .push_back (std::make_unique < ggml_backend_meta_device_context > (ctx )); 236 237struct ggml_backend_device meta_dev = { 238/*iface =*/ ggml_backend_meta_device_iface , 239/*reg =*/ nullptr , 240/*ctx =*/ ctxs .back ().get (), 241 }; 242 243auto result = meta_devs .emplace (* ctxs .back (),meta_dev ); 244return & result .first -> second ; 245} 246 247// 248// meta backend buffer type 249// 250 251struct ggml_backend_meta_buffer_type_context { 252 std::vector < ggml_backend_buffer_type_t > simple_bufts ; 253 254 std::string name ; 255 256ggml_backend_meta_buffer_type_context (std::vector < ggml_backend_buffer_type_t > simple_bufts ) :simple_bufts (std::move (simple_bufts )) { 257name = "Meta(" ; 258for (size_t i = 0 ;i < simple_bufts .size ();i ++ ) { 259if (i > 0 ) { 260name += "," ; 261 } 262name += ggml_backend_buft_name (simple_bufts [i ]); 263 } 264name += ")" ; 265 } 266 267bool operator< (const ggml_backend_meta_buffer_type_context & other )const { 268return simple_bufts < other .simple_bufts ; 269 } 270}; 271 272static size_t ggml_backend_meta_buft_n_bufts (ggml_backend_buffer_type_t meta_buft ) { 273GGML_ASSERT (ggml_backend_buft_is_meta (meta_buft )); 274const ggml_backend_meta_buffer_type_context * meta_buft_ctx = (const ggml_backend_meta_buffer_type_context * )meta_buft -> context ; 275return meta_buft_ctx -> simple_bufts .size (); 276} 277 278static const char * ggml_backend_meta_buffer_type_get_name (ggml_backend_buffer_type_t buft ) { 279GGML_ASSERT (ggml_backend_buft_is_meta (buft )); 280const ggml_backend_meta_buffer_type_context * meta_buft_ctx = (const ggml_backend_meta_buffer_type_context * )buft -> context ; 281return meta_buft_ctx -> name .c_str (); 282} 283 284static ggml_backend_buffer_type_t ggml_backend_meta_buft_simple_buft (ggml_backend_buffer_type_t meta_buft ,size_t index ) { 285GGML_ASSERT (ggml_backend_buft_is_meta (meta_buft )); 286const ggml_backend_meta_buffer_type_context * meta_buft_ctx = (const ggml_backend_meta_buffer_type_context * )meta_buft -> context ; 287GGML_ASSERT (index < meta_buft_ctx -> simple_bufts .size ()); 288return meta_buft_ctx -> simple_bufts [index ]; 289} 290 291static ggml_backend_buffer_t ggml_backend_meta_buffer_type_alloc_buffer (ggml_backend_buffer_type_t buft ,size_t size ); 292 293static size_t ggml_backend_meta_buffer_type_get_alignment (ggml_backend_buffer_type_t buft ) { 294const size_t n_simple_bufts = ggml_backend_meta_buft_n_bufts (buft ); 295size_t max_alignment = 1 ; 296for (size_t i = 0 ;i < n_simple_bufts ;i ++ ) { 297const size_t alignment = ggml_backend_buft_get_alignment (ggml_backend_meta_buft_simple_buft (buft ,i )); 298max_alignment = std::max (max_alignment ,alignment ); 299GGML_ASSERT (max_alignment %alignment == 0 ); 300 } 301return max_alignment ; 302} 303 304static size_t ggml_backend_meta_buffer_type_get_max_size (ggml_backend_buffer_type_t buft ) { 305const size_t n_simple_bufts = ggml_backend_meta_buft_n_bufts (buft ); 306size_t max_size = SIZE_MAX ; 307for (size_t i = 0 ;i < n_simple_bufts ;i ++ ) { 308max_size = std::min (max_size ,ggml_backend_buft_get_max_size (ggml_backend_meta_buft_simple_buft (buft ,i ))); 309 } 310return max_size ; 311} 312 313static size_t ggml_backend_meta_buffer_type_get_alloc_size (ggml_backend_buffer_type_t buft ,const ggml_tensor * tensor ) { 314const size_t n_simple_bufts = ggml_backend_meta_buft_n_bufts (buft ); 315size_t max_alloc_size = 0 ; 316for (size_t i = 0 ;i < n_simple_bufts ;i ++ ) { 317const size_t alloc_size = ggml_backend_buft_get_alloc_size (ggml_backend_meta_buft_simple_buft (buft ,i ),tensor ); 318max_alloc_size = std::max (max_alloc_size ,alloc_size ); 319 } 320return max_alloc_size ; 321} 322 323static bool ggml_backend_meta_buffer_type_is_host (ggml_backend_buffer_type_t buft ) { 324const size_t n_simple_bufts = ggml_backend_meta_buft_n_bufts (buft ); 325for (size_t i = 0 ;i < n_simple_bufts ;i ++ ) { 326if (!ggml_backend_buft_is_host (ggml_backend_meta_buft_simple_buft (buft ,i ))) { 327return false; 328 } 329 } 330return true; 331} 332 333static const struct ggml_backend_buffer_type_i ggml_backend_meta_buffer_type_iface = { 334/* .get_name = */ ggml_backend_meta_buffer_type_get_name , 335/* .alloc_buffer = */ ggml_backend_meta_buffer_type_alloc_buffer , 336/* .get_alignment = */ ggml_backend_meta_buffer_type_get_alignment , 337/* .get_max_size = */ ggml_backend_meta_buffer_type_get_max_size , 338/* .get_alloc_size = */ ggml_backend_meta_buffer_type_get_alloc_size , 339/* .is_host = */ ggml_backend_meta_buffer_type_is_host , 340}; 341 342bool ggml_backend_buft_is_meta (ggml_backend_buffer_type_t buft ) { 343return buft != nullptr && buft -> iface .get_name == ggml_backend_meta_buffer_type_iface .get_name ; 344} 345 346static ggml_backend_buffer_type_t ggml_backend_meta_device_get_buffer_type (ggml_backend_dev_t dev ) { 347static std::map < ggml_backend_dev_t ,struct ggml_backend_buffer_type > meta_bufts ; 348GGML_ASSERT (ggml_backend_dev_is_meta (dev )); 349 { 350auto it = meta_bufts .find (dev ); 351if (it != meta_bufts .end ()) { 352return & it -> second ; 353 } 354 } 355 356const size_t n_devs = ggml_backend_meta_dev_n_devs (dev ); 357 std::vector < ggml_backend_buffer_type_t > simple_bufts ; 358simple_bufts .reserve (n_devs ); 359for (size_t i = 0 ;i < n_devs ;i ++ ) { 360simple_bufts .push_back (ggml_backend_dev_buffer_type (ggml_backend_meta_dev_simple_dev (dev ,i ))); 361 } 362ggml_backend_meta_buffer_type_context * buft_ctx = new ggml_backend_meta_buffer_type_context (simple_bufts ); 363 364struct ggml_backend_buffer_type meta_buft = { 365/*iface =*/ ggml_backend_meta_buffer_type_iface , 366/*device =*/ dev , 367/*ctx =*/ buft_ctx , 368 }; 369auto result = meta_bufts .emplace (dev ,meta_buft ); 370return & result .first -> second ; 371} 372 373static ggml_backend_buffer_type_t ggml_backend_meta_device_get_host_buffer_type (ggml_backend_dev_t dev ) { 374GGML_ASSERT (ggml_backend_dev_is_meta (dev )); 375const ggml_backend_meta_device_context * meta_dev_ctx = (const ggml_backend_meta_device_context * )dev -> context ; 376 377ggml_backend_buffer_type_t host_buft = nullptr ; 378for (ggml_backend_dev_t simple_dev :meta_dev_ctx -> simple_devs ) { 379ggml_backend_buffer_type_t simple_host_buft = ggml_backend_dev_host_buffer_type (simple_dev ); 380if (simple_host_buft == nullptr ) { 381return nullptr ; 382 } 383if (host_buft == nullptr ) { 384host_buft = simple_host_buft ; 385 }else if (host_buft != simple_host_buft ) { 386// if different simple devices have different host buffer types, 387// we cannot provide a single host buffer type for the meta device 388return nullptr ; 389 } 390 } 391return host_buft ; 392} 393 394// 395// meta backend buffer 396// 397 398// Container to hold the tensor slices per simple ggml backend buffer. 399struct ggml_backend_meta_simple_tensor_container { 400 std::vector < ggml_context_ptr > ctxs ; 401 std::map < const ggml_tensor * , std::vector < ggml_tensor *>> simple_tensors ; 402 403ggml_backend_meta_simple_tensor_container (const ggml_init_params & params ,const int n_simple ) { 404ctxs .reserve (n_simple ); 405for (int i = 0 ;i < n_simple ;i ++ ) { 406ctxs .emplace_back (ggml_init (params )); 407 } 408 } 409ggml_backend_meta_simple_tensor_container () {} 410}; 411 412struct ggml_backend_meta_buffer_context { 413// FIXME 414// Most tensors can simply be stored statically in their own buffer. 415// Externally created views however also need a mapping to simple tensors but they use the buffer of the view source. 416// If external views are simply using that buffer they will slowly deplete its memory. 417// Current solution: rotating set of 2 "compute" containers to hold external views, works correctly for llama.cpp. 418// Long-term: tie the lifetime of external views to the meta backend executing the graph instead, 419// currently not possible due to graph-external operations in the backend scheduler. 420ggml_backend_meta_simple_tensor_container stc_static ; 421ggml_backend_meta_simple_tensor_container stc_compute [2 ]; 422int stc_compute_index = 0 ; 423int stc_compute_index_next = 0 ; 424 std::vector < ggml_backend_buffer_ptr > bufs ; 425 426// FIXME 427// The size of the split state cache is unbounded and can theoretically grow infinitely large. 428// However, it is also expensive to build and clearing it on every rebuild in ggml_backend_meta_graph_compute is too expensive. 429static constexpr size_t nbtc = GGML_TENSOR_SIZE - sizeof (ggml_tensor::padding ); 430 std::map < std::pair < const ggml_tensor * ,bool > , std::pair < ggml_backend_meta_split_state ,char [nbtc ]>> split_state_cache ; 431 432int debug ; 433 434ggml_backend_meta_buffer_context ( 435ggml_backend_meta_simple_tensor_container & stc_static , 436ggml_backend_meta_simple_tensor_container & stc_compute_0 , 437ggml_backend_meta_simple_tensor_container & stc_compute_1 , 438const std::vector < ggml_backend_buffer_t > & bufs ) 439 :stc_static (std::move (stc_static )),stc_compute {std::move (stc_compute_0 ), std::move (stc_compute_1 )} { 440this -> bufs .reserve (bufs .size ()); 441for (ggml_backend_buffer_t buf :bufs ) { 442this -> bufs .emplace_back (buf ); 443 } 444const char * GGML_META_DEBUG = getenv ("GGML_META_DEBUG" ); 445debug = GGML_META_DEBUG ?atoi (GGML_META_DEBUG ) :0 ; 446 } 447 448ggml_backend_meta_simple_tensor_container & get_simple_tensor_container (const ggml_tensor * tensor ) { 449if (stc_static .simple_tensors .find (tensor )!= stc_static .simple_tensors .end ()) { 450return stc_static ; 451 } 452return stc_compute [stc_compute_index ]; 453 } 454}; 455 456static void ggml_backend_meta_buffer_free_buffer (ggml_backend_buffer_t buffer ) { 457GGML_ASSERT (ggml_backend_buffer_is_meta (buffer )); 458ggml_backend_meta_buffer_context * buf_ctx = (ggml_backend_meta_buffer_context * )buffer -> context ; 459delete buf_ctx ; 460} 461 462static size_t ggml_backend_meta_buffer_n_bufs (ggml_backend_buffer_t meta_buf ) { 463GGML_ASSERT (ggml_backend_buffer_is_meta (meta_buf )); 464ggml_backend_meta_buffer_context * buf_ctx = (ggml_backend_meta_buffer_context * )meta_buf -> context ; 465return buf_ctx -> bufs .size (); 466} 467 468static ggml_backend_buffer_t ggml_backend_meta_buffer_simple_buffer (ggml_backend_buffer_t meta_buf ,size_t index ) { 469GGML_ASSERT (ggml_backend_buffer_is_meta (meta_buf )); 470ggml_backend_meta_buffer_context * buf_ctx = (ggml_backend_meta_buffer_context * )meta_buf -> context ; 471GGML_ASSERT (index < buf_ctx -> bufs .size ()); 472return buf_ctx -> bufs [index ].get (); 473} 474 475static struct ggml_tensor * ggml_backend_meta_buffer_simple_tensor (const struct ggml_tensor * tensor ,size_t index ) { 476GGML_ASSERT (ggml_backend_buffer_is_meta (tensor -> buffer )); 477ggml_backend_meta_buffer_context * buf_ctx = (ggml_backend_meta_buffer_context * )tensor -> buffer -> context ; 478GGML_ASSERT (index < buf_ctx -> bufs .size ()); 479 480ggml_backend_meta_simple_tensor_container & stc = buf_ctx -> get_simple_tensor_container (tensor ); 481auto it = stc .simple_tensors .find (tensor ); 482if (it == stc .simple_tensors .end ()) { 483return nullptr ; 484 } 485return it -> second [index ]; 486} 487 488static struct ggml_backend_meta_split_state ggml_backend_meta_get_split_state (const struct ggml_tensor * tensor ,bool assume_sync ); 489 490static struct ggml_backend_meta_split_state ggml_backend_meta_get_split_state ( 491ggml_backend_meta_simple_tensor_container & stc ,const struct ggml_tensor * tensor ,bool assume_sync ) { 492// FIXME Currently this function preserves/erases the information in n_segments and nr in an inconsistent way. 493// Since the operations in question are developed specifically for llama.cpp this currently does not manifest as a bug there. 494// However, in a broader ggml context with arbitrary ggml graphs this can lead to unexpected results. 495const size_t n_bufs = ggml_backend_meta_buffer_n_bufs (tensor -> buffer ); 496ggml_backend_meta_buffer_context * buf_ctx = (ggml_backend_meta_buffer_context * )tensor -> buffer -> context ; 497 498auto split_states_equal = [& ](const ggml_backend_meta_split_state & a ,const ggml_backend_meta_split_state & b )-> bool { 499if (a .axis != b .axis ) { 500return false; 501 } 502for (size_t j = 0 ;j < n_bufs ;j ++ ) { 503int64_t sum_a = 0 ; 504for (size_t s = 0 ;s < a .n_segments ;s ++ ) { 505sum_a += a .ne [s * n_bufs + j ]* a .nr [s ]; 506 } 507int64_t sum_b = 0 ; 508for (size_t s = 0 ;s < b .n_segments ;s ++ ) { 509sum_b += b .ne [s * n_bufs + j ]* b .nr [s ]; 510 } 511if (sum_a != sum_b ) { 512return false; 513 } 514 } 515return true; 516 }; 517 518auto handle_generic = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss ,bool scalar_only )-> ggml_backend_meta_split_state { 519ggml_backend_meta_split_state ret = {GGML_BACKEND_SPLIT_AXIS_NONE , {0 }, {1 },1 }; 520for (size_t i = 0 ;i < GGML_MAX_SRC ;i ++ ) { 521if (tensor -> src [i ]== nullptr || tensor -> src [i ]== tensor ) { 522continue ; 523 } 524if (ret .axis == GGML_BACKEND_SPLIT_AXIS_NONE ) { 525ret = src_ss [i ]; 526 }else if (!split_states_equal (src_ss [i ],ret )) { 527ret = {GGML_BACKEND_SPLIT_AXIS_UNKNOWN , {0 }, {1 },1 }; 528break ; 529 } 530 } 531if (ret .axis == GGML_BACKEND_SPLIT_AXIS_NONE ) { 532ret = {GGML_BACKEND_SPLIT_AXIS_UNKNOWN , {0 }, {1 },1 }; 533 } 534if (scalar_only && ret .axis >=0 && ret .axis < GGML_MAX_DIMS ) { 535ret = {GGML_BACKEND_SPLIT_AXIS_UNKNOWN , {0 }, {1 },1 }; 536 } 537GGML_ASSERT (ret .axis != GGML_BACKEND_SPLIT_AXIS_UNKNOWN ); 538return ret ; 539 }; 540 541// Some ops process data on a per-row bases: 542auto handle_per_row = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 543GGML_ASSERT (src_ss [0 ].axis != GGML_BACKEND_SPLIT_AXIS_0 ); 544return src_ss [0 ]; 545 }; 546 547// Some ops broadcast the src1 data across src0: 548auto handle_bin_bcast = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 549if (src_ss [0 ].axis >=0 && src_ss [0 ].axis < GGML_MAX_DIMS && 550tensor -> src [1 ]-> ne [src_ss [0 ].axis ]== 1 && src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 551return src_ss [0 ]; 552 } 553if (src_ss [2 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED && (src_ss [0 ].axis == src_ss [1 ].axis || 554 (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED && (src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_PARTIAL )))) { 555return src_ss [0 ];// GGML_OP_ADD_ID 556 } 557GGML_ASSERT (tensor -> src [2 ]== nullptr || src_ss [2 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ); 558return handle_generic (src_ss ,/*scalar_only =*/ false); 559 }; 560 561auto handle_concat = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 562const ggml_backend_meta_split_axis concat_axis = ggml_backend_meta_split_axis (ggml_get_op_params_i32 (tensor ,0 )); 563if (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED && src_ss [1 ].axis >=0 && src_ss [1 ].axis < GGML_MAX_DIMS ) { 564GGML_ASSERT (concat_axis != src_ss [1 ].axis ); 565return src_ss [1 ]; 566 } 567if (src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED && src_ss [0 ].axis >=0 && src_ss [0 ].axis < GGML_MAX_DIMS ) { 568GGML_ASSERT (concat_axis != src_ss [0 ].axis ); 569return src_ss [0 ]; 570 } 571if (src_ss [0 ].axis == src_ss [1 ].axis && src_ss [0 ].axis != concat_axis ) { 572return src_ss [0 ]; 573 } 574return handle_generic (src_ss ,/*scalar_only =*/ true); 575 }; 576 577auto handle_mul_mat = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 578if (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED && src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 579return {GGML_BACKEND_SPLIT_AXIS_MIRRORED , {0 }, {1 },1 }; 580 } 581if (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_1 && src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 582ggml_backend_meta_split_state ret = src_ss [0 ]; 583ret .axis = GGML_BACKEND_SPLIT_AXIS_0 ; 584ret .nr [0 ]= 1 ; 585ret .n_segments = 1 ; 586return ret ; 587 } 588if (src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_1 && src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 589return src_ss [1 ]; 590 } 591if (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_0 && src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_0 ) { 592GGML_ASSERT (split_states_equal (src_ss [0 ],src_ss [1 ])); 593return {assume_sync ?GGML_BACKEND_SPLIT_AXIS_MIRRORED :GGML_BACKEND_SPLIT_AXIS_PARTIAL , {0 }, {1 },1 }; 594 } 595if (src_ss [0 ].axis == src_ss [1 ].axis && src_ss [0 ].axis >=GGML_BACKEND_SPLIT_AXIS_2 && 596src_ss [0 ].axis < GGML_MAX_DIMS ) { 597GGML_ASSERT (split_states_equal (src_ss [0 ],src_ss [1 ])); 598return src_ss [0 ]; 599 } 600// batched matmul with the batches split across devices and a replicated activation 601if (src_ss [0 ].axis >=GGML_BACKEND_SPLIT_AXIS_2 && src_ss [0 ].axis < GGML_MAX_DIMS && 602src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 603return src_ss [0 ]; 604 } 605GGML_ABORT ("unsupported mul_mat split states: node=%s src0=%s axis=%d src1=%s axis=%d" , 606tensor -> name ,tensor -> src [0 ]-> name , (int )src_ss [0 ].axis ,tensor -> src [1 ]-> name , (int )src_ss [1 ].axis ); 607//return {GGML_BACKEND_SPLIT_AXIS_UNKNOWN, {0}, {1}, 1}; 608 }; 609 610auto handle_reshape = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 611switch (src_ss [0 ].axis ) { 612case GGML_BACKEND_SPLIT_AXIS_0 : 613case GGML_BACKEND_SPLIT_AXIS_1 : 614case GGML_BACKEND_SPLIT_AXIS_2 : 615case GGML_BACKEND_SPLIT_AXIS_3 : { 616int64_t base_ne_in = 1 ; 617for (int dim = 0 ;dim <=src_ss [0 ].axis ;dim ++ ) { 618base_ne_in *=tensor -> src [0 ]-> ne [dim ]; 619 } 620if (src_ss [0 ].n_segments == 1 ) { 621base_ne_in /=src_ss [0 ].nr [0 ]; 622if (src_ss [0 ].axis == ggml_n_dims (tensor -> src [0 ])- 1 && src_ss [0 ].nr [0 ]== 1 ) { 623return {ggml_backend_meta_split_axis (ggml_n_dims (tensor )- 1 ), {0 }, {1 },1 }; 624 } 625if (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_0 && tensor -> ne [0 ]== tensor -> src [0 ]-> ne [0 ]&& 626tensor -> ne [1 ]== 1 && src_ss [0 ].nr [0 ]== 1 ) { 627bool complete_rows = true; 628for (size_t j = 0 ;j < n_bufs ;j ++ ) { 629const int64_t ne = src_ss [0 ].ne [j ]; 630complete_rows = complete_rows && (ne == 0 || ne == tensor -> src [0 ]-> ne [0 ]); 631 } 632if (complete_rows ) { 633// Move a complete dim-0 split to the following singleton dimension. 634return {GGML_BACKEND_SPLIT_AXIS_1 , {0 }, {1 },1 }; 635 } 636 } 637 } 638// Reshape outputs use one segment; split-state propagation merges source segments. 639int64_t base_ne_out = 1 ; 640for (int dim = 0 ;dim < GGML_MAX_DIMS ;dim ++ ) { 641base_ne_out *=tensor -> ne [dim ]; 642if (base_ne_out %base_ne_in == 0 ) { 643return {ggml_backend_meta_split_axis (dim ), {0 }, {uint32_t (base_ne_out /base_ne_in )},1 }; 644 } 645if (base_ne_out > base_ne_in ) { 646GGML_ASSERT (src_ss [0 ].n_segments == 1 ); 647GGML_ASSERT (src_ss [0 ].nr [0 ]== 1 ); 648return {ggml_backend_meta_split_axis (dim ), {0 }, {1 },1 }; 649 } 650 } 651GGML_ABORT ("shape mismatch for %s" ,ggml_op_name (tensor -> op )); 652 } 653case GGML_BACKEND_SPLIT_AXIS_MIRRORED : 654case GGML_BACKEND_SPLIT_AXIS_PARTIAL : { 655return src_ss [0 ]; 656 } 657default : { 658GGML_ABORT ("fatal error" ); 659//return {GGML_BACKEND_SPLIT_AXIS_UNKNOWN, {0}, {1}, 1}; 660 } 661 } 662 }; 663 664auto handle_cpy = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 665if (src_ss [0 ].axis >=0 && src_ss [0 ].axis < GGML_MAX_DIMS ) { 666return handle_reshape (src_ss ); 667 } 668return handle_generic (src_ss ,/*scalar_only =*/ false); 669 }; 670 671auto handle_view = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 672if (ggml_is_contiguous (tensor )&& ggml_is_contiguous (tensor -> src [0 ])) { 673return handle_reshape (src_ss ); 674 } 675const int axis = src_ss [0 ].axis ; 676 { 677bool all_strides_the_same = true; 678for (int dim = 0 ;dim < GGML_MAX_DIMS ;dim ++ ) { 679if (tensor -> ne [dim ]== 1 && tensor -> src [0 ]-> ne [dim ]== 1 ) { 680continue ; 681 } 682if (tensor -> nb [dim ]!= tensor -> src [0 ]-> nb [dim ]) { 683all_strides_the_same = false; 684break ; 685 } 686 } 687if (all_strides_the_same ) { 688return src_ss [0 ]; 689 } 690 } 691if (!ggml_is_permuted (tensor )&& !ggml_is_permuted (tensor -> src [0 ])&& axis >=0 && axis < GGML_MAX_DIMS - 1 ) { 692for (int dim = 0 ;dim < GGML_MAX_DIMS - 1 ;dim ++ ) { 693if (tensor -> nb [dim + 1 ]== tensor -> src [0 ]-> nb [axis + 1 ]) { 694return {ggml_backend_meta_split_axis (dim ), {0 }, {1 },1 }; 695 } 696 } 697GGML_ABORT ("fatal error" ); 698 } 699if (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED || src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_PARTIAL ) { 700return src_ss [0 ]; 701 } 702GGML_ABORT ("view of permuted tensor not implemented" ); 703//return {GGML_BACKEND_SPLIT_AXIS_UNKNOWN, {0}, {1}, 1}; 704 }; 705 706auto handle_permute = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 707switch (src_ss [0 ].axis ) { 708case GGML_BACKEND_SPLIT_AXIS_0 : 709case GGML_BACKEND_SPLIT_AXIS_1 : 710case GGML_BACKEND_SPLIT_AXIS_2 : 711case GGML_BACKEND_SPLIT_AXIS_3 : { 712GGML_ASSERT (src_ss [0 ].n_segments == 1 || src_ss [0 ].nr [0 ]== 1 ); 713return {ggml_backend_meta_split_axis (tensor -> op_params [src_ss [0 ].axis ]), {0 }, {src_ss [0 ].nr [0 ]},1 }; 714 } 715case GGML_BACKEND_SPLIT_AXIS_MIRRORED : 716case GGML_BACKEND_SPLIT_AXIS_PARTIAL : { 717return src_ss [0 ]; 718 } 719default : { 720GGML_ABORT ("fatal error" ); 721//return {GGML_BACKEND_SPLIT_AXIS_UNKNOWN, {0}, {1}, 1}; 722 } 723 } 724 }; 725 726auto handle_transpose = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 727switch (src_ss [0 ].axis ) { 728case GGML_BACKEND_SPLIT_AXIS_0 : 729case GGML_BACKEND_SPLIT_AXIS_1 : { 730GGML_ASSERT (src_ss [0 ].n_segments == 1 || src_ss [0 ].nr [0 ]== 1 ); 731return {ggml_backend_meta_split_axis (int (src_ss [0 ].axis ) ^1 ), {0 }, {src_ss [0 ].nr [0 ]},1 }; 732 } 733case GGML_BACKEND_SPLIT_AXIS_2 : 734case GGML_BACKEND_SPLIT_AXIS_3 : 735case GGML_BACKEND_SPLIT_AXIS_MIRRORED : 736case GGML_BACKEND_SPLIT_AXIS_PARTIAL : { 737return src_ss [0 ]; 738 } 739default : { 740GGML_ABORT ("fatal error" ); 741//return {GGML_BACKEND_SPLIT_AXIS_UNKNOWN, {0}, {1}, 1}; 742 } 743 } 744 }; 745 746auto handle_get_rows = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 747if (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_0 && src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 748return src_ss [0 ]; 749 } 750return handle_generic (src_ss ,/*scalar_only =*/ true); 751 }; 752 753auto handle_set_rows = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 754GGML_ASSERT (src_ss [0 ].axis != GGML_BACKEND_SPLIT_AXIS_1 ); 755GGML_ASSERT (src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ); 756GGML_ASSERT (split_states_equal (src_ss [0 ],src_ss [2 ])); 757return src_ss [0 ]; 758 }; 759 760auto handle_rope = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 761GGML_ASSERT (src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ); 762return src_ss [0 ]; 763 }; 764 765auto handle_pad = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 766if (src_ss [0 ].axis >=0 && src_ss [0 ].axis < GGML_MAX_DIMS ) { 767GGML_ASSERT (tensor -> op_params [2 * src_ss [0 ].axis + 0 ]== 0 ); 768GGML_ASSERT (tensor -> op_params [2 * src_ss [0 ].axis + 1 ]== 0 ); 769 } 770return src_ss [0 ]; 771 }; 772 773auto handle_flash_attn_ext = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 774GGML_ASSERT (tensor -> src [3 ]== nullptr || src_ss [3 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ); 775 776if (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 777GGML_ASSERT (src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ); 778GGML_ASSERT (src_ss [2 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ); 779GGML_ASSERT (tensor -> src [4 ]== nullptr || src_ss [4 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ); 780return {GGML_BACKEND_SPLIT_AXIS_MIRRORED , {0 }, {1 },1 }; 781 } 782 783GGML_ASSERT (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_2 ); 784const bool kv_split = src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_2 && 785src_ss [2 ].axis == GGML_BACKEND_SPLIT_AXIS_2 ; 786const bool kv_mirrored = src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED && 787src_ss [2 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ; 788GGML_ASSERT (kv_split || kv_mirrored ); 789GGML_ASSERT (tensor -> src [4 ]== nullptr || src_ss [4 ].axis == GGML_BACKEND_SPLIT_AXIS_0 ); 790return {GGML_BACKEND_SPLIT_AXIS_1 , {0 }, {1 },1 }; 791 }; 792 793auto handle_lightning_indexer = [& ]( 794const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 795for (size_t i = 0 ;i < 4 ;i ++ ) { 796GGML_ASSERT (src_ss [i ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ); 797 } 798return {GGML_BACKEND_SPLIT_AXIS_MIRRORED , {0 }, {1 },1 }; 799 }; 800 801auto handle_ssm_conv = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 802if (src_ss [0 ].axis == src_ss [1 ].axis ) { 803if (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_0 ) { 804return {GGML_BACKEND_SPLIT_AXIS_1 , {0 }, {1 },1 }; 805 } 806if (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_1 ) { 807return {GGML_BACKEND_SPLIT_AXIS_0 , {0 }, {1 },1 }; 808 } 809 } 810return handle_generic (src_ss ,/*scalar_only =*/ false); 811 }; 812 813auto handle_gated_delta_net = [& ](const std::vector < ggml_backend_meta_split_state > & src_ss )-> ggml_backend_meta_split_state { 814if (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED && src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED && 815src_ss [2 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED && src_ss [3 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED && 816src_ss [4 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED && src_ss [5 ].axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 817return src_ss [0 ]; 818 } 819GGML_ASSERT (src_ss [0 ].axis == GGML_BACKEND_SPLIT_AXIS_1 ); 820GGML_ASSERT (src_ss [1 ].axis == GGML_BACKEND_SPLIT_AXIS_1 ); 821GGML_ASSERT (src_ss [2 ].axis == GGML_BACKEND_SPLIT_AXIS_1 ); 822GGML_ASSERT (src_ss [3 ].axis == GGML_BACKEND_SPLIT_AXIS_1 ); 823GGML_ASSERT (src_ss [4 ].axis == GGML_BACKEND_SPLIT_AXIS_1 ); 824// state shape is [S_v, S_v, H_v, n_seqs] (s0 only); the heads dim is its own axis 2, 825// so a head-aligned split on the input cache lands on axis 2 here. 826GGML_ASSERT (src_ss [5 ].axis == GGML_BACKEND_SPLIT_AXIS_2 || src_ss [5 ].axis == GGML_BACKEND_SPLIT_AXIS_1 || src_ss [5 ].axis == GGML_BACKEND_SPLIT_AXIS_0 ); 827return {GGML_BACKEND_SPLIT_AXIS_0 , {0 }, {1 },1 }; 828 }; 829 830auto calculate_split_state = [& ]()-> ggml_backend_meta_split_state { 831if (ggml_nelements (tensor )== 0 ) { 832return {GGML_BACKEND_SPLIT_AXIS_UNKNOWN , {0 }, {1 },1 }; 833 } 834if (ggml_backend_buffer_get_usage (tensor -> buffer )!= GGML_BACKEND_BUFFER_USAGE_COMPUTE && tensor -> view_src == nullptr ) { 835ggml_backend_dev_t dev = ggml_backend_buft_get_device (ggml_backend_buffer_get_type (tensor -> buffer )); 836const ggml_backend_meta_device_context * dev_ctx = (const ggml_backend_meta_device_context * )dev -> context ; 837ggml_backend_meta_split_state ret = dev_ctx -> get_split_state (tensor ,dev_ctx -> get_split_state_ud ); 838if (ret .axis >=0 && ret .axis < GGML_MAX_DIMS ) { 839const int64_t granularity = ret .axis == GGML_BACKEND_SPLIT_AXIS_0 ?ggml_blck_size (tensor -> type ) :1 ; 840int64_t ne_sum = 0 ; 841for (size_t s = 0 ;s < ret .n_segments ;s ++ ) { 842for (size_t j = 0 ;j < n_bufs ;j ++ ) { 843GGML_ASSERT (ret .ne [s * n_bufs + j ] %granularity == 0 ); 844ne_sum += ret .ne [s * n_bufs + j ]* ret .nr [s ]; 845 } 846 } 847GGML_ASSERT (ne_sum == tensor -> ne [ret .axis ]); 848 }else if (ret .axis == GGML_BACKEND_SPLIT_AXIS_PARTIAL ) { 849GGML_ASSERT (ret .n_segments == 1 ); 850GGML_ASSERT (ret .nr [0 ]== 1 ); 851 } 852return ret ; 853 } 854 855 std::vector < ggml_backend_meta_split_state > src_ss (GGML_MAX_SRC , {GGML_BACKEND_SPLIT_AXIS_NONE , {0 }, {1 },1 }); 856for (size_t i = 0 ;i < GGML_MAX_SRC ;i ++ ) { 857if (tensor -> src [i ]== nullptr || tensor -> src [i ]== tensor ) { 858src_ss [i ]= {GGML_BACKEND_SPLIT_AXIS_UNKNOWN , {0 }, {1 },1 }; 859continue ; 860 } 861src_ss [i ]= ggml_backend_meta_get_split_state (stc ,tensor -> src [i ],/*assume_sync =*/ true); 862GGML_ASSERT (src_ss [i ].axis != GGML_BACKEND_SPLIT_AXIS_UNKNOWN ); 863 } 864 865ggml_backend_meta_split_state split_state ; 866switch (tensor -> op ) { 867case GGML_OP_NONE : { 868split_state = {GGML_BACKEND_SPLIT_AXIS_MIRRORED , {0 }, {1 },1 }; 869 }break ; 870case GGML_OP_DUP : { 871split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 872 }break ; 873case GGML_OP_ADD : 874case GGML_OP_ADD_ID : { 875split_state = handle_bin_bcast (src_ss ); 876 }break ; 877case GGML_OP_ADD1 : 878case GGML_OP_ACC : { 879split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 880 }break ; 881case GGML_OP_SUB : 882case GGML_OP_MUL : 883case GGML_OP_DIV : { 884split_state = handle_bin_bcast (src_ss ); 885 }break ; 886case GGML_OP_SQR : 887case GGML_OP_SQRT : 888case GGML_OP_LOG : 889case GGML_OP_SIN : 890case GGML_OP_COS : { 891split_state = handle_generic (src_ss ,/*scalar_only =*/ false); 892 }break ; 893case GGML_OP_SUM : { 894split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 895 }break ; 896case GGML_OP_SUM_ROWS : 897case GGML_OP_CUMSUM : 898case GGML_OP_MEAN : 899case GGML_OP_ARGMAX : 900case GGML_OP_COUNT_EQUAL : { 901split_state = handle_per_row (src_ss ); 902 }break ; 903case GGML_OP_REPEAT : 904case GGML_OP_REPEAT_BACK : { 905split_state = handle_generic (src_ss ,/*scalar_only =*/ false); 906 }break ; 907case GGML_OP_CONCAT : { 908split_state = handle_concat (src_ss ); 909 }break ; 910case GGML_OP_SILU_BACK : { 911split_state = handle_generic (src_ss ,/*scalar_only =*/ false); 912 }break ; 913case GGML_OP_NORM : 914case GGML_OP_RMS_NORM : 915case GGML_OP_RMS_NORM_BACK : 916case GGML_OP_GROUP_NORM : 917case GGML_OP_L2_NORM : { 918split_state = handle_per_row (src_ss ); 919 }break ; 920case GGML_OP_MUL_MAT : 921case GGML_OP_MUL_MAT_ID : { 922split_state = handle_mul_mat (src_ss ); 923 }break ; 924case GGML_OP_OUT_PROD : { 925split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 926 }break ; 927case GGML_OP_SCALE : { 928split_state = handle_generic (src_ss ,/*scalar_only =*/ false); 929 }break ; 930case GGML_OP_SET : { 931split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 932 }break ; 933case GGML_OP_CPY : { 934split_state = handle_cpy (src_ss ); 935 }break ; 936case GGML_OP_CONT : 937case GGML_OP_RESHAPE : { 938split_state = handle_reshape (src_ss ); 939 }break ; 940case GGML_OP_VIEW : { 941split_state = handle_view (src_ss ); 942 }break ; 943case GGML_OP_PERMUTE : { 944split_state = handle_permute (src_ss ); 945 }break ; 946case GGML_OP_TRANSPOSE : { 947split_state = handle_transpose (src_ss ); 948 }break ; 949case GGML_OP_GET_ROWS : { 950split_state = handle_get_rows (src_ss ); 951 }break ; 952case GGML_OP_GET_ROWS_BACK : { 953split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 954 }break ; 955case GGML_OP_SET_ROWS : { 956split_state = handle_set_rows (src_ss ); 957 }break ; 958case GGML_OP_DIAG : 959case GGML_OP_DIAG_MASK_INF : 960case GGML_OP_DIAG_MASK_ZERO : { 961split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 962 }break ; 963case GGML_OP_SOFT_MAX : 964case GGML_OP_SOFT_MAX_BACK : { 965split_state = handle_generic (src_ss ,/*scalar_only =*/ false); 966 }break ; 967case GGML_OP_ROPE : { 968split_state = handle_rope (src_ss ); 969 }break ; 970case GGML_OP_ROPE_BACK : { 971split_state = handle_rope (src_ss ); 972 }break ; 973case GGML_OP_CLAMP : { 974split_state = handle_generic (src_ss ,/*scalar_only =*/ false); 975 }break ; 976case GGML_OP_CONV_TRANSPOSE_1D : 977case GGML_OP_IM2COL : 978case GGML_OP_IM2COL_BACK : 979case GGML_OP_IM2COL_3D : 980case GGML_OP_CONV_2D : 981case GGML_OP_CONV_3D : 982case GGML_OP_CONV_2D_DW : 983case GGML_OP_CONV_TRANSPOSE_2D : 984case GGML_OP_POOL_1D : 985case GGML_OP_POOL_2D : 986case GGML_OP_POOL_2D_BACK : 987case GGML_OP_UPSCALE : { 988split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 989 }break ; 990case GGML_OP_PAD : { 991split_state = handle_pad (src_ss ); 992 }break ; 993case GGML_OP_PAD_REFLECT_1D : 994case GGML_OP_ROLL : 995case GGML_OP_ARANGE : 996case GGML_OP_TIMESTEP_EMBEDDING : { 997split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 998 }break ; 999case GGML_OP_ARGSORT : 1000case GGML_OP_TOP_K : { 1001split_state = handle_per_row (src_ss ); 1002 }break ; 1003case GGML_OP_LEAKY_RELU : { 1004split_state = handle_generic (src_ss ,/*scalar_only =*/ false); 1005 }break ; 1006case GGML_OP_TRI : { 1007split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 1008 }break ; 1009case GGML_OP_FILL : { 1010split_state = handle_generic (src_ss ,/*scalar_only =*/ false); 1011 }break ; 1012case GGML_OP_FLASH_ATTN_EXT : { 1013split_state = handle_flash_attn_ext (src_ss ); 1014 }break ; 1015case GGML_OP_FLASH_ATTN_BACK : { 1016split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 1017 }break ; 1018case GGML_OP_SSM_CONV : { 1019split_state = handle_ssm_conv (src_ss ); 1020 }break ; 1021case GGML_OP_SSM_SCAN : 1022case GGML_OP_WIN_PART : 1023case GGML_OP_WIN_UNPART : 1024case GGML_OP_GET_REL_POS : 1025case GGML_OP_ADD_REL_POS : 1026case GGML_OP_RWKV_WKV6 : 1027case GGML_OP_GATED_LINEAR_ATTN : 1028case GGML_OP_RWKV_WKV7 : 1029case GGML_OP_SOLVE_TRI : { 1030split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 1031 }break ; 1032case GGML_OP_GATED_DELTA_NET : { 1033split_state = handle_gated_delta_net (src_ss ); 1034 }break ; 1035case GGML_OP_LIGHTNING_INDEXER : { 1036split_state = handle_lightning_indexer (src_ss ); 1037 }break ; 1038case GGML_OP_DSV4_HC_COMB : 1039case GGML_OP_DSV4_HC_PRE : 1040case GGML_OP_DSV4_HC_POST : { 1041split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 1042 }break ; 1043case GGML_OP_UNARY : { 1044split_state = handle_generic (src_ss ,/*scalar_only =*/ false); 1045 }break ; 1046case GGML_OP_MAP_CUSTOM1 : 1047case GGML_OP_MAP_CUSTOM2 : 1048case GGML_OP_MAP_CUSTOM3 : 1049case GGML_OP_CUSTOM : { 1050split_state = handle_generic (src_ss ,/*scalar_only =*/ true); 1051 }break ; 1052case GGML_OP_CROSS_ENTROPY_LOSS : 1053case GGML_OP_CROSS_ENTROPY_LOSS_BACK : { 1054split_state = handle_per_row (src_ss ); 1055 }break ; 1056case GGML_OP_OPT_STEP_ADAMW : 1057case GGML_OP_OPT_STEP_SGD : 1058case GGML_OP_GLU : { 1059split_state = handle_generic (src_ss ,/*scalar_only =*/ false); 1060 }break ; 1061default : { 1062GGML_ABORT ("ggml op not implemented: %s" ,ggml_op_name (tensor -> op )); 1063split_state = {GGML_BACKEND_SPLIT_AXIS_UNKNOWN , {0 }, {1 },1 }; 1064 }break ; 1065 } 1066if (split_state .axis >=0 && split_state .axis < GGML_MAX_DIMS ) { 1067bool first_src_split_by_axis = true; 1068const size_t n_bufs = ggml_backend_meta_buffer_n_bufs (tensor -> buffer ); 1069 1070for (size_t i = 0 ;i < GGML_MAX_SRC ;i ++ ) { 1071if (tensor -> src [i ]== nullptr || src_ss [i ].axis < 0 || src_ss [i ].axis >=GGML_MAX_DIMS ) { 1072continue ; 1073 } 1074if (first_src_split_by_axis ) { 1075for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1076// Take over ratio from src: 1077for (size_t s = 0 ;s < src_ss [i ].n_segments ;s ++ ) { 1078split_state .ne [s * n_bufs + j ]= 0 ; 1079 } 1080for (size_t s = 0 ;s < src_ss [i ].n_segments ;s ++ ) { 1081split_state .ne [j ]+= src_ss [i ].ne [s * n_bufs + j ]* src_ss [i ].nr [s ]; 1082 } 1083split_state .ne [j ] *=tensor -> ne [split_state .axis ]; 1084if (split_state .ne [j ]!= 0 || tensor -> src [i ]-> ne [src_ss [i ].axis ]!= 0 ) { 1085const int64_t div = tensor -> src [i ]-> ne [src_ss [i ].axis ]* split_state .nr [0 ]; 1086GGML_ASSERT (split_state .ne [j ] %div == 0 ); 1087split_state .ne [j ] /=div ; 1088 } 1089 } 1090 }else { 1091GGML_ASSERT (split_state .n_segments == 1 ); 1092for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1093// Assert that ratio is consistent: 1094int64_t sum = 0 ; 1095for (size_t s = 0 ;s < src_ss [i ].n_segments ;s ++ ) { 1096sum += src_ss [i ].ne [s * n_bufs + j ]* src_ss [i ].nr [s ]; 1097 } 1098GGML_ASSERT (split_state .ne [j ]* split_state .nr [0 ]* tensor -> src [i ]-> ne [src_ss [i ].axis ] 1099== sum * tensor -> ne [split_state .axis ]); 1100 } 1101 } 1102first_src_split_by_axis = false; 1103 } 1104GGML_ASSERT (!first_src_split_by_axis ); 1105 } 1106return split_state ; 1107 }; 1108 1109const std::pair key = std::make_pair (tensor ,assume_sync ); 1110auto it = buf_ctx -> split_state_cache .find (key ); 1111if (it != buf_ctx -> split_state_cache .end ()&& memcmp (it -> second .second , (const char * )tensor ,sizeof (it -> second .second ))!= 0 ) { 1112buf_ctx -> split_state_cache .clear (); 1113it = buf_ctx -> split_state_cache .end (); 1114 } 1115 1116if (it == buf_ctx -> split_state_cache .end ()) { 1117buf_ctx -> split_state_cache [key ].first = calculate_split_state (); 1118memcpy (buf_ctx -> split_state_cache [key ].second ,tensor ,sizeof (buf_ctx -> split_state_cache [key ].second )); 1119if (buf_ctx -> debug > 0 ) { 1120 std::string srcs_info ; 1121for (size_t i = 0 ;i < GGML_MAX_SRC ;i ++ ) { 1122if (tensor -> src [i ]== nullptr || tensor -> src [i ]== tensor ) { 1123continue ; 1124 } 1125if (!srcs_info .empty ()) { 1126srcs_info += ", " ; 1127 } 1128const ggml_backend_meta_split_state split_state = 1129ggml_backend_meta_get_split_state (tensor -> src [i ], true); 1130GGML_ASSERT (split_state .n_segments == 1 ); 1131const char * axis_name = ggml_backend_meta_split_axis_name (split_state .axis ); 1132 std::string ne_info ; 1133for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1134if (!ne_info .empty ()) { 1135ne_info += ", " ; 1136 } 1137ne_info += std::to_string (split_state .ne [j ])+ "x" + std::to_string (split_state .nr [0 ]); 1138 } 1139srcs_info += std::string (tensor -> src [i ]-> name )+ "[" + ggml_op_name (tensor -> src [i ]-> op )+ ", " + axis_name + ", {" + ne_info + "}]" ; 1140 } 1141 std::string ne_info ; 1142for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1143if (!ne_info .empty ()) { 1144ne_info += ", " ; 1145 } 1146const ggml_backend_meta_split_state & ss = buf_ctx -> split_state_cache [key ].first ; 1147ne_info += std::to_string (ss .ne [j ])+ "x" + std::to_string (ss .nr [0 ]); 1148 } 1149GGML_LOG_DEBUG ("SPLIT_STATE: {%s} -> %s[%s, %s, {%s}]\n" ,srcs_info .c_str (),tensor -> name ,ggml_op_name (tensor -> op ), 1150ggml_backend_meta_split_axis_name (buf_ctx -> split_state_cache [key ].first .axis ),ne_info .c_str ()); 1151 } 1152 } 1153 1154ggml_backend_meta_split_state ret = buf_ctx -> split_state_cache [key ].first ; 1155GGML_ASSERT (ret .axis != GGML_BACKEND_SPLIT_AXIS_NONE ); 1156#ifndef NDEBUG 1157if (ret .axis >=0 && ret .axis < GGML_MAX_DIMS ) { 1158int64_t ne_ret = 0 ; 1159for (size_t s = 0 ;s < ret .n_segments ;s ++ ) { 1160for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1161ne_ret += ret .ne [s * n_bufs + j ]* ret .nr [s ]; 1162 } 1163 } 1164assert (ne_ret == tensor -> ne [int (ret .axis )]); 1165 } 1166#endif // NDEBUG 1167return ret ; 1168} 1169 1170static struct ggml_backend_meta_split_state ggml_backend_meta_get_split_state (const struct ggml_tensor * tensor ,bool assume_sync ) { 1171ggml_backend_meta_buffer_context * buf_ctx = (ggml_backend_meta_buffer_context * )tensor -> buffer -> context ; 1172return ggml_backend_meta_get_split_state (buf_ctx -> get_simple_tensor_container (tensor ),tensor ,assume_sync ); 1173} 1174 1175static void * ggml_backend_meta_buffer_get_base (ggml_backend_buffer_t buffer ) { 1176GGML_UNUSED (buffer ); 1177return (void * )0x1000000000000000 ;// FIXME 1178} 1179 1180static enum ggml_status ggml_backend_meta_buffer_init_tensor_impl (ggml_backend_meta_simple_tensor_container & stc ,ggml_tensor * tensor ) { 1181GGML_ASSERT (ggml_backend_buffer_is_meta (tensor -> buffer )); 1182ggml_backend_meta_buffer_context * buf_ctx = (ggml_backend_meta_buffer_context * )tensor -> buffer -> context ; 1183const size_t n_simple_bufs = ggml_backend_meta_buffer_n_bufs (tensor -> buffer ); 1184 1185const ggml_backend_meta_split_state split_state = ggml_backend_meta_get_split_state (stc ,tensor ,/*assume_sync =*/ true); 1186GGML_ASSERT (ggml_nelements (tensor )== 0 || split_state .axis != GGML_BACKEND_SPLIT_AXIS_UNKNOWN ); 1187GGML_ASSERT (split_state .n_segments <=16 ); 1188 1189int split_dim = split_state .axis ; 1190int64_t ne [GGML_MAX_DIMS ]; 1191size_t nb [GGML_MAX_DIMS ]; 1192for (size_t k = 0 ;k < GGML_MAX_DIMS ;k ++ ) { 1193ne [k ]= tensor -> ne [k ]; 1194nb [k ]= tensor -> nb [k ]; 1195 } 1196 1197 std::vector < ggml_tensor *> simple_tensors ; 1198simple_tensors .reserve (n_simple_bufs ); 1199for (size_t j = 0 ;j < n_simple_bufs ;j ++ ) { 1200ggml_context * simple_ctx = stc .ctxs [j ].get (); 1201ggml_backend_buffer_t simple_buf = buf_ctx -> bufs [j ].get (); 1202 1203if ((simple_buf != nullptr )&& ggml_backend_buffer_is_multi_buffer (simple_buf )) { 1204// see https://github.com/ggml-org/llama.cpp/issues/22197 1205GGML_ABORT ("multi buffers are not supported by the meta backend" ); 1206 } 1207 1208if (split_dim >=0 && split_dim < GGML_MAX_DIMS ) { 1209// TODO: the following assert fails for llama-parallel even though the results are correct: 1210// GGML_ASSERT(ggml_is_contiguously_allocated(tensor)); 1211ne [split_dim ]= 0 ; 1212for (size_t s = 0 ;s < split_state .n_segments ;s ++ ) { 1213ne [split_dim ]+= split_state .ne [s * n_simple_bufs + j ]* split_state .nr [s ]; 1214 } 1215for (int i = 0 ;i < GGML_MAX_DIMS ;i ++ ) { 1216if (tensor -> nb [i ]> tensor -> nb [split_dim ]) { 1217nb [i ]= tensor -> nb [i ]* ne [split_dim ]/tensor -> ne [split_dim ]; 1218 } 1219 } 1220 } 1221 1222ggml_tensor * t_ij = ggml_new_tensor (simple_ctx ,tensor -> type ,GGML_MAX_DIMS ,ne ); 1223t_ij -> op = tensor -> op ; 1224for (int i = 0 ;i < GGML_MAX_DIMS ;i ++ ) { 1225t_ij -> nb [i ]= nb [i ]; 1226 } 1227t_ij -> flags = tensor -> flags ; 1228memcpy (t_ij -> op_params ,tensor -> op_params ,sizeof (tensor -> op_params )); 1229ggml_set_name (t_ij ,tensor -> name ); 1230t_ij -> buffer = simple_buf ; 1231t_ij -> view_src = tensor -> view_src ; 1232t_ij -> view_offs = tensor -> view_offs ; 1233if (t_ij -> view_src != nullptr && ggml_backend_buffer_is_meta (t_ij -> view_src -> buffer )) { 1234t_ij -> view_src = ggml_backend_meta_buffer_simple_tensor (tensor -> view_src ,j ); 1235if (t_ij -> view_offs > 0 && split_dim >=0 && split_dim < GGML_MAX_DIMS ) { 1236GGML_ASSERT (tensor -> ne [split_dim ]!= 0 ); 1237const int split_dim_view_src = ggml_backend_meta_get_split_state (tensor -> view_src ,/*assume_sync =*/ true).axis ; 1238GGML_ASSERT (split_dim_view_src >=0 && split_dim_view_src < GGML_MAX_DIMS ); 1239 1240// The offset can be internal to the data split, in those cases the view offset should not be scaled. 1241// If however, the offset is larger than the data split then it needs to be scaled proportionally. 1242bool split_internal_offset = t_ij -> view_offs <=tensor -> view_src -> nb [split_dim_view_src ]; 1243for (int i = 0 ;i < GGML_MAX_DIMS ;i ++ ) { 1244const size_t dim_size = tensor -> ne [i ]* tensor -> nb [i ]; 1245if (tensor -> view_offs <=dim_size && dim_size < tensor -> nb [split_dim ]) { 1246split_internal_offset = true; 1247break ; 1248 } 1249 } 1250if (!split_internal_offset ) { 1251t_ij -> view_offs = t_ij -> view_offs * ne [split_dim ]/tensor -> ne [split_dim ]; 1252 } 1253 } 1254 } 1255if (t_ij -> view_src != nullptr ) { 1256t_ij -> data = (char * )t_ij -> view_src -> data + t_ij -> view_offs ; 1257 }else if (simple_buf != nullptr ) { 1258t_ij -> data = (char * )ggml_backend_buffer_get_base (simple_buf ) 1259+ size_t (tensor -> data )- size_t (ggml_backend_buffer_get_base (tensor -> buffer )); 1260 } 1261 1262if (simple_buf ) { 1263// the backend that owns the buffer will set .extra 1264ggml_backend_buffer_init_tensor (simple_buf ,t_ij ); 1265 }else { 1266t_ij -> extra = tensor -> extra ; 1267 } 1268 1269for (int i = 0 ;i < GGML_MAX_SRC ;i ++ ) { 1270t_ij -> src [i ]= tensor -> src [i ]; 1271if (tensor -> src [i ]== tensor ) { 1272t_ij -> src [i ]= t_ij ; 1273 }else if (t_ij -> src [i ]!= nullptr && ggml_backend_buffer_is_meta (t_ij -> src [i ]-> buffer )) { 1274t_ij -> src [i ]= ggml_backend_meta_buffer_simple_tensor (tensor -> src [i ],j ); 1275 } 1276 } 1277 1278simple_tensors .push_back (t_ij ); 1279 } 1280 1281// If one of the sources has a zero-sized slice, disable the computation: 1282for (int i = 0 ;i < GGML_MAX_SRC ;i ++ ) { 1283if (tensor -> src [i ]== nullptr || !ggml_backend_buffer_is_meta (tensor -> src [i ]-> buffer )) { 1284continue ; 1285 } 1286 1287const ggml_backend_meta_split_state split_state_src = ggml_backend_meta_get_split_state (tensor -> src [i ],/*assume_sync =*/ true); 1288if (split_state_src .axis < 0 || split_state_src .axis >=GGML_MAX_DIMS ) { 1289continue ; 1290 } 1291for (size_t j = 0 ;j < n_simple_bufs ;j ++ ) { 1292int64_t ne_sum = 0 ; 1293for (size_t s = 0 ;s < split_state_src .n_segments ;s ++ ) { 1294ne_sum += split_state_src .ne [s * n_simple_bufs + j ]* split_state_src .nr [s ]; 1295 } 1296if (ne_sum == 0 ) { 1297simple_tensors [j ]-> flags &= ~GGML_TENSOR_FLAG_COMPUTE ; 1298 } 1299 } 1300 } 1301 1302stc .simple_tensors [tensor ]= simple_tensors ; 1303 1304return GGML_STATUS_SUCCESS ; 1305} 1306 1307static enum ggml_status ggml_backend_meta_buffer_init_tensor (ggml_backend_buffer_t buffer ,ggml_tensor * tensor ) { 1308GGML_ASSERT (ggml_backend_buffer_is_meta (buffer )); 1309ggml_backend_meta_buffer_context * buf_ctx = (ggml_backend_meta_buffer_context * )buffer -> context ; 1310buf_ctx -> stc_compute_index = buf_ctx -> stc_compute_index_next ; 1311return ggml_backend_meta_buffer_init_tensor_impl (buf_ctx -> get_simple_tensor_container (tensor ),tensor ); 1312} 1313 1314static void ggml_backend_meta_buffer_memset_tensor ( 1315ggml_backend_buffer_t buffer ,ggml_tensor * tensor ,uint8_t value ,size_t offset ,size_t size ) { 1316const size_t n_bufs = ggml_backend_meta_buffer_n_bufs (buffer ); 1317const ggml_backend_meta_split_state split_state = 1318ggml_backend_meta_get_split_state (tensor ,/*assume_sync =*/ false); 1319GGML_ASSERT (ggml_is_contiguous (tensor )|| split_state .axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ); 1320 1321if (split_state .n_segments != 1 || split_state .nr [0 ]!= 1 ) { 1322GGML_ASSERT (split_state .axis >=0 && split_state .axis < GGML_MAX_DIMS ); 1323GGML_ASSERT (split_state .nr [0 ]!= 0 ); 1324GGML_ASSERT (tensor -> ne [3 ]== 1 ); 1325 1326 std::vector < size_t > simple_offsets (n_bufs ,0 ); 1327if (split_state .axis == GGML_BACKEND_SPLIT_AXIS_0 ) { 1328GGML_ASSERT (tensor -> ne [2 ]== 1 ); 1329 1330const size_t row_stride = tensor -> nb [1 ]; 1331GGML_ASSERT (offset %row_stride == 0 ); 1332GGML_ASSERT (size %row_stride == 0 ); 1333const int64_t row_start = offset /row_stride ; 1334const int64_t row_count = size /row_stride ; 1335GGML_ASSERT (row_start + row_count <=tensor -> ne [1 ]); 1336 1337const int64_t blck_size = ggml_blck_size (tensor -> type ); 1338for (size_t s = 0 ;s < split_state .n_segments ;s ++ ) { 1339for (size_t r = 0 ;r < split_state .nr [s ];r ++ ) { 1340for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1341ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1342GGML_ASSERT (split_state .ne [s * n_bufs + j ] %blck_size == 0 ); 1343const size_t nbytes = split_state .ne [s * n_bufs + j ]/blck_size * tensor -> nb [0 ]; 1344for (int64_t row = 0 ;row < row_count ;row ++ ) { 1345ggml_backend_tensor_memset (simple_tensor ,value , 1346simple_offsets [j ]+ (row_start + row )* simple_tensor -> nb [1 ],nbytes ); 1347 } 1348simple_offsets [j ]+= nbytes ; 1349 } 1350 } 1351 } 1352return ; 1353 } 1354 1355GGML_ASSERT (split_state .axis == GGML_BACKEND_SPLIT_AXIS_1 ); 1356 1357const size_t row_stride = tensor -> nb [2 ]; 1358GGML_ASSERT (offset %row_stride == 0 ); 1359GGML_ASSERT (size %row_stride == 0 ); 1360const int64_t row_start = offset /row_stride ; 1361const int64_t row_count = size /row_stride ; 1362GGML_ASSERT (row_start + row_count <=tensor -> ne [2 ]); 1363 1364for (size_t s = 0 ;s < split_state .n_segments ;s ++ ) { 1365for (size_t r = 0 ;r < split_state .nr [s ];r ++ ) { 1366for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1367ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1368const size_t nbytes = split_state .ne [s * n_bufs + j ]* tensor -> nb [1 ]; 1369for (int64_t row = 0 ;row < row_count ;row ++ ) { 1370ggml_backend_tensor_memset (simple_tensor ,value , 1371simple_offsets [j ]+ (row_start + row )* simple_tensor -> nb [2 ],nbytes ); 1372 } 1373simple_offsets [j ]+= nbytes ; 1374 } 1375 } 1376 } 1377return ; 1378 } 1379 1380switch (split_state .axis ) { 1381case GGML_BACKEND_SPLIT_AXIS_0 : 1382case GGML_BACKEND_SPLIT_AXIS_1 : 1383case GGML_BACKEND_SPLIT_AXIS_2 : { 1384const size_t chunk_size_full = tensor -> nb [split_state .axis + 1 ]; 1385GGML_ASSERT (offset %chunk_size_full == 0 ); 1386GGML_ASSERT (size %chunk_size_full == 0 ); 1387const int64_t i_start = offset /chunk_size_full ; 1388const int64_t i_stop = (offset + size ) /chunk_size_full ; 1389for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1390ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1391const size_t chunk_size = simple_tensor -> nb [split_state .axis + 1 ]; 1392if (chunk_size == 0 ) { 1393continue ; 1394 } 1395for (int64_t i = i_start ;i < i_stop ;i ++ ) { 1396ggml_backend_tensor_memset (simple_tensor ,value ,i * chunk_size ,chunk_size ); 1397 } 1398 } 1399 }break ; 1400case GGML_BACKEND_SPLIT_AXIS_PARTIAL : { 1401GGML_ASSERT (value == 0 ); 1402 [[fallthrough ]]; 1403 } 1404case GGML_BACKEND_SPLIT_AXIS_MIRRORED : { 1405for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1406ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1407ggml_backend_tensor_memset (simple_tensor ,value ,offset ,size ); 1408 } 1409 }break ; 1410default : { 1411GGML_ABORT ("fatal error" ); 1412 } 1413 } 1414} 1415 1416static void ggml_backend_meta_buffer_set_tensor (ggml_backend_buffer_t buffer ,ggml_tensor * tensor ,const void * data ,size_t offset ,size_t size ) { 1417const size_t n_bufs = ggml_backend_meta_buffer_n_bufs (buffer ); 1418const ggml_backend_meta_split_state split_state = ggml_backend_meta_get_split_state (tensor ,/*assume_sync =*/ false); 1419GGML_ASSERT (ggml_is_contiguous (tensor )|| split_state .axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ); 1420 1421if (split_state .n_segments != 1 || split_state .nr [0 ]!= 1 ) { 1422GGML_ASSERT (split_state .axis >=0 && split_state .axis < GGML_MAX_DIMS ); 1423GGML_ASSERT (split_state .nr [0 ]!= 0 ); 1424GGML_ASSERT (tensor -> ne [3 ]== 1 ); 1425 1426size_t offset_data = 0 ; 1427 std::vector < size_t > simple_offsets (n_bufs ,0 ); 1428if (split_state .axis == GGML_BACKEND_SPLIT_AXIS_0 ) { 1429GGML_ASSERT (tensor -> ne [2 ]== 1 ); 1430 1431const size_t row_stride = tensor -> nb [1 ]; 1432GGML_ASSERT (offset %row_stride == 0 ); 1433GGML_ASSERT (size %row_stride == 0 ); 1434const int64_t row_start = offset /row_stride ; 1435const int64_t row_count = size /row_stride ; 1436GGML_ASSERT (row_start + row_count <=tensor -> ne [1 ]); 1437 1438const int64_t blck_size = ggml_blck_size (tensor -> type ); 1439for (size_t s = 0 ;s < split_state .n_segments ;s ++ ) { 1440for (size_t r = 0 ;r < split_state .nr [s ];r ++ ) { 1441for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1442ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1443GGML_ASSERT (split_state .ne [s * n_bufs + j ] %blck_size == 0 ); 1444const size_t nbytes = split_state .ne [s * n_bufs + j ]/blck_size * tensor -> nb [0 ]; 1445ggml_backend_tensor_set_2d (simple_tensor , (const char * )data + offset_data , 1446simple_offsets [j ]+ row_start * simple_tensor -> nb [1 ],nbytes , 1447row_count ,simple_tensor -> nb [1 ],tensor -> nb [1 ]); 1448offset_data += nbytes ; 1449simple_offsets [j ]+= nbytes ; 1450 } 1451 } 1452 } 1453GGML_ASSERT (offset_data * row_count == size ); 1454return ; 1455 } 1456GGML_ASSERT (split_state .axis == GGML_BACKEND_SPLIT_AXIS_1 ); 1457 1458const size_t row_stride = tensor -> nb [2 ]; 1459GGML_ASSERT (offset %row_stride == 0 ); 1460GGML_ASSERT (size %row_stride == 0 ); 1461const int64_t row_start = offset /row_stride ; 1462const int64_t row_count = size /row_stride ; 1463GGML_ASSERT (row_start + row_count <=tensor -> ne [2 ]); 1464 1465for (size_t s = 0 ;s < split_state .n_segments ;s ++ ) { 1466for (size_t r = 0 ;r < split_state .nr [s ];r ++ ) { 1467for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1468ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1469const size_t nbytes = split_state .ne [s * n_bufs + j ]* tensor -> nb [1 ]; 1470ggml_backend_tensor_set_2d (simple_tensor , (const char * )data + offset_data , 1471simple_offsets [j ]+ row_start * simple_tensor -> nb [2 ],nbytes , 1472row_count ,simple_tensor -> nb [2 ],tensor -> nb [2 ]); 1473offset_data += nbytes ; 1474simple_offsets [j ]+= nbytes ; 1475 } 1476 } 1477 } 1478GGML_ASSERT (offset_data * row_count == size ); 1479return ; 1480 } 1481 1482switch (split_state .axis ) { 1483case GGML_BACKEND_SPLIT_AXIS_0 : 1484case GGML_BACKEND_SPLIT_AXIS_1 : 1485case GGML_BACKEND_SPLIT_AXIS_2 : { 1486// Exploit that tensors are contiguous to splice it with simple tensors as "chunks". 1487const size_t chunk_size_full = tensor -> nb [split_state .axis + 1 ]; 1488GGML_ASSERT (offset %chunk_size_full == 0 ); 1489GGML_ASSERT (size %chunk_size_full == 0 ); 1490const int64_t i_start = offset /chunk_size_full ; 1491const int64_t i_stop = (offset + size )/chunk_size_full ; 1492size_t offset_j = 0 ; 1493for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1494ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1495const size_t chunk_size_j = simple_tensor -> nb [split_state .axis + 1 ]; 1496if (chunk_size_j == 0 ) { 1497continue ; 1498 } 1499const size_t simple_offset = i_start * chunk_size_j ; 1500ggml_backend_tensor_set_2d (simple_tensor , (const char * )data + offset_j ,simple_offset ,chunk_size_j ,i_stop - i_start ,chunk_size_j ,chunk_size_full ); 1501offset_j += chunk_size_j ; 1502 } 1503GGML_ASSERT (offset_j == chunk_size_full ); 1504 }break ; 1505case GGML_BACKEND_SPLIT_AXIS_MIRRORED : { 1506for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1507ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1508ggml_backend_tensor_set (simple_tensor ,data ,offset ,size ); 1509 } 1510 }break ; 1511case GGML_BACKEND_SPLIT_AXIS_PARTIAL : { 1512GGML_ASSERT (tensor -> type == GGML_TYPE_F32 ); 1513GGML_ASSERT (offset %sizeof (float )== 0 ); 1514GGML_ASSERT (size %sizeof (float )== 0 ); 1515const size_t n_values = size /sizeof (float ); 1516size_t n_contributors = 0 ; 1517for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1518n_contributors += split_state .ne [j ]!= 0 ; 1519 } 1520const bool has_contributor_mask = n_contributors != 0 ; 1521if (!has_contributor_mask ) { 1522n_contributors = n_bufs ; 1523 } 1524 std::vector < float > tmp (n_values ); 1525for (size_t i = 0 ;i < n_values ;i ++ ) { 1526tmp [i ]= ((const float * )data )[i ] /n_contributors ; 1527 } 1528 std::vector < float > zero ; 1529if (has_contributor_mask ) { 1530zero .resize (n_values ,0.0f ); 1531 } 1532for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1533ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1534const float * partial = has_contributor_mask && split_state .ne [j ]== 0 ?zero .data () :tmp .data (); 1535ggml_backend_tensor_set (simple_tensor ,partial ,offset ,size ); 1536 } 1537 }break ; 1538default : { 1539GGML_ABORT ("fatal error" ); 1540 } 1541 } 1542} 1543 1544static void ggml_backend_meta_buffer_get_tensor (ggml_backend_buffer_t buffer ,const ggml_tensor * tensor ,void * data ,size_t offset ,size_t size ) { 1545const size_t n_bufs = ggml_backend_meta_buffer_n_bufs (buffer ); 1546const ggml_backend_meta_split_state split_state = ggml_backend_meta_get_split_state (tensor ,/*assume_sync =*/ false); 1547GGML_ASSERT (ggml_is_contiguous (tensor )|| split_state .axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ); 1548 1549if (split_state .n_segments != 1 || split_state .nr [0 ]!= 1 ) { 1550GGML_ASSERT (split_state .axis >=0 && split_state .axis < GGML_MAX_DIMS ); 1551GGML_ASSERT (split_state .nr [0 ]!= 0 ); 1552GGML_ASSERT (tensor -> ne [3 ]== 1 ); 1553 1554size_t offset_data = 0 ; 1555 std::vector < size_t > simple_offsets (n_bufs ,0 ); 1556if (split_state .axis == GGML_BACKEND_SPLIT_AXIS_0 ) { 1557GGML_ASSERT (tensor -> ne [2 ]== 1 ); 1558 1559const size_t row_stride = tensor -> nb [1 ]; 1560GGML_ASSERT (offset %row_stride == 0 ); 1561GGML_ASSERT (size %row_stride == 0 ); 1562const int64_t row_start = offset /row_stride ; 1563const int64_t row_count = size /row_stride ; 1564GGML_ASSERT (row_start + row_count <=tensor -> ne [1 ]); 1565 1566const int64_t blck_size = ggml_blck_size (tensor -> type ); 1567for (size_t s = 0 ;s < split_state .n_segments ;s ++ ) { 1568for (size_t r = 0 ;r < split_state .nr [s ];r ++ ) { 1569for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1570const ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1571GGML_ASSERT (split_state .ne [s * n_bufs + j ] %blck_size == 0 ); 1572const size_t nbytes = split_state .ne [s * n_bufs + j ]/blck_size * tensor -> nb [0 ]; 1573ggml_backend_tensor_get_2d (simple_tensor , (char * )data + offset_data , 1574simple_offsets [j ]+ row_start * simple_tensor -> nb [1 ],nbytes , 1575row_count ,simple_tensor -> nb [1 ],tensor -> nb [1 ]); 1576offset_data += nbytes ; 1577simple_offsets [j ]+= nbytes ; 1578 } 1579 } 1580 } 1581GGML_ASSERT (offset_data * row_count == size ); 1582return ; 1583 } 1584GGML_ASSERT (split_state .axis == GGML_BACKEND_SPLIT_AXIS_1 ); 1585 1586const size_t row_stride = tensor -> nb [2 ]; 1587GGML_ASSERT (offset %row_stride == 0 ); 1588GGML_ASSERT (size %row_stride == 0 ); 1589const int64_t row_start = offset /row_stride ; 1590const int64_t row_count = size /row_stride ; 1591GGML_ASSERT (row_start + row_count <=tensor -> ne [2 ]); 1592 1593for (size_t s = 0 ;s < split_state .n_segments ;s ++ ) { 1594for (size_t r = 0 ;r < split_state .nr [s ];r ++ ) { 1595for (size_t j = 0 ;j < n_bufs ;j ++ ) { 1596const ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1597const size_t nbytes = split_state .ne [s * n_bufs + j ]* tensor -> nb [1 ]; 1598ggml_backend_tensor_get_2d (simple_tensor , (char * )data + offset_data , 1599simple_offsets [j ]+ row_start * simple_tensor -> nb [2 ],nbytes , 1600row_count ,simple_tensor -> nb [2 ],tensor -> nb [2 ]); 1601offset_data += nbytes ; 1602simple_offsets [j ]+= nbytes ; 1603 } 1604 } 1605 } 1606GGML_ASSERT (offset_data * row_count == size ); 1607return ; 1608 } 1609 1610switch (split_state .axis ) { 1611case GGML_BACKEND_SPLIT_AXIS_0 : 1612case GGML_BACKEND_SPLIT_AXIS_1 : 1613case GGML_BACKEND_SPLIT_AXIS_2 : { 1614// Exploit that tensors are contiguous to splice it with simple tensors as "chunks". 1615const size_t chunk_size_full = tensor -> nb [split_state .axis + 1 ]; 1616GGML_ASSERT (offset %chunk_size_full == 0 ); 1617GGML_ASSERT (size %chunk_size_full == 0 ); 1618const int64_t i_start = offset /chunk_size_full ; 1619const int64_t i_stop = (offset + size )/chunk_size_full ; 1620size_t offset_j = 0 ; 1621for (size_t j = 0 ;j < n_bufs ;j ++ ){ 1622const ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1623const size_t chunk_size_j = simple_tensor -> nb [split_state .axis + 1 ]; 1624if (chunk_size_j == 0 ) { 1625continue ; 1626 } 1627const size_t simple_offset = i_start * chunk_size_j ; 1628ggml_backend_tensor_get_2d (simple_tensor , (char * )data + offset_j ,simple_offset ,chunk_size_j ,i_stop - i_start ,chunk_size_j ,chunk_size_full ); 1629offset_j += chunk_size_j ; 1630 } 1631GGML_ASSERT (offset_j == chunk_size_full ); 1632 }break ; 1633case GGML_BACKEND_SPLIT_AXIS_MIRRORED : { 1634// TODO other simple backend may be better 1635const ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,0 ); 1636ggml_backend_tensor_get (simple_tensor ,data ,offset ,size ); 1637 }break ; 1638default : { 1639GGML_ABORT ("fatal error" ); 1640 } 1641 } 1642} 1643 1644static void ggml_backend_meta_buffer_clear (ggml_backend_buffer_t buffer ,uint8_t value ) { 1645const size_t n_buffers = ggml_backend_meta_buffer_n_bufs (buffer ); 1646for (size_t i = 0 ;i < n_buffers ;i ++ ) { 1647ggml_backend_buffer_clear (ggml_backend_meta_buffer_simple_buffer (buffer ,i ),value ); 1648 } 1649} 1650 1651static void ggml_backend_meta_buffer_reset (ggml_backend_buffer_t buffer ) { 1652GGML_ASSERT (ggml_backend_buffer_is_meta (buffer )); 1653ggml_backend_meta_buffer_context * buf_ctx = (ggml_backend_meta_buffer_context * )buffer -> context ; 1654for (size_t i = 0 ;i < buf_ctx -> bufs .size ();i ++ ) { 1655ggml_backend_buffer_reset (ggml_backend_meta_buffer_simple_buffer (buffer ,i )); 1656 } 1657} 1658 1659static const ggml_backend_buffer_i ggml_backend_meta_buffer_iface = { 1660/* .free_buffer = */ ggml_backend_meta_buffer_free_buffer , 1661/* .get_base = */ ggml_backend_meta_buffer_get_base , 1662/* .init_tensor = */ ggml_backend_meta_buffer_init_tensor , 1663/* .memset_tensor = */ ggml_backend_meta_buffer_memset_tensor , 1664/* .set_tensor = */ ggml_backend_meta_buffer_set_tensor , 1665/* .get_tensor = */ ggml_backend_meta_buffer_get_tensor , 1666/* .set_tensor_2d = */ nullptr , 1667/* .get_tensor_2d = */ nullptr , 1668/* .cpy_tensor = */ nullptr , 1669/* .clear = */ ggml_backend_meta_buffer_clear , 1670/* .reset = */ ggml_backend_meta_buffer_reset , 1671}; 1672 1673bool ggml_backend_buffer_is_meta (ggml_backend_buffer_t buf ) { 1674return buf != nullptr && buf -> iface .free_buffer == ggml_backend_meta_buffer_iface .free_buffer ; 1675} 1676 1677void ggml_backend_meta_buffer_set_usage (ggml_backend_buffer_t buffer ,enum ggml_backend_buffer_usage usage ) { 1678GGML_ASSERT (ggml_backend_buffer_is_meta (buffer )); 1679ggml_backend_meta_buffer_context * buf_ctx = (ggml_backend_meta_buffer_context * )buffer -> context ; 1680for (size_t i = 0 ;i < buf_ctx -> bufs .size ();i ++ ) { 1681if (buf_ctx -> bufs [i ]) { 1682ggml_backend_buffer_set_usage (buf_ctx -> bufs [i ].get (),usage ); 1683 } 1684 } 1685} 1686 1687static ggml_backend_buffer_t ggml_backend_meta_buffer_type_alloc_buffer (ggml_backend_buffer_type_t buft ,size_t size ) { 1688const size_t n_simple_bufts = ggml_backend_meta_buft_n_bufts (buft ); 1689 1690const ggml_init_params params = { 1691/*.mem_size =*/ 1024 * 1024 * ggml_tensor_overhead (),// FIXME 1692/*.mem_buffer =*/ nullptr , 1693/*.no_alloc =*/ true, 1694 }; 1695ggml_backend_meta_simple_tensor_container stc_static ; 1696ggml_backend_meta_simple_tensor_container stc_compute_0 (params ,n_simple_bufts ); 1697ggml_backend_meta_simple_tensor_container stc_compute_1 (params ,n_simple_bufts ); 1698 1699size_t max_size = 0 ; 1700 std::vector < ggml_backend_buffer_t > bufs ; 1701bufs .reserve (n_simple_bufts ); 1702for (size_t i = 0 ;i < n_simple_bufts ;i ++ ) { 1703bufs .push_back (ggml_backend_buft_alloc_buffer (ggml_backend_meta_buft_simple_buft (buft ,i ),size )); 1704GGML_ASSERT (bufs .back ()!= nullptr ); 1705max_size = std::max (max_size ,ggml_backend_buffer_get_size (bufs .back ())); 1706 } 1707ggml_backend_meta_buffer_context * buf_ctx = new ggml_backend_meta_buffer_context (stc_static ,stc_compute_0 ,stc_compute_1 ,bufs ); 1708 1709return ggml_backend_buffer_init (buft ,ggml_backend_meta_buffer_iface ,buf_ctx ,max_size ); 1710} 1711 1712struct ggml_backend_buffer * ggml_backend_meta_alloc_ctx_tensors_from_buft (struct ggml_context * ctx ,ggml_backend_buffer_type_t buft ) { 1713const size_t n_simple_bufts = ggml_backend_meta_buft_n_bufts (buft ); 1714 1715constexpr size_t compute_headroom = 16 ;// Maximum number of views per statically allocated tensor that can be created between evals. 1716const ggml_init_params params_static = { 1717/*.mem_size =*/ ggml_get_mem_size (ctx ), 1718/*.mem_buffer =*/ nullptr , 1719/*.no_alloc =*/ true, 1720 }; 1721const ggml_init_params params_compute = { 1722/*.mem_size =*/ compute_headroom * ggml_get_mem_size (ctx ), 1723/*.mem_buffer =*/ nullptr , 1724/*.no_alloc =*/ true, 1725 }; 1726ggml_backend_meta_simple_tensor_container stc_static (params_static ,n_simple_bufts ); 1727ggml_backend_meta_simple_tensor_container stc_compute_0 (params_compute ,n_simple_bufts ); 1728ggml_backend_meta_simple_tensor_container stc_compute_1 (params_compute ,n_simple_bufts ); 1729 1730 std::vector < ggml_backend_buffer_t > bufs (n_simple_bufts ,nullptr ); 1731ggml_backend_meta_buffer_context * meta_buf_ctx = new ggml_backend_meta_buffer_context (stc_static ,stc_compute_0 ,stc_compute_1 ,bufs ); 1732 1733ggml_backend_buffer_t meta_buf = ggml_backend_buffer_init (buft ,ggml_backend_meta_buffer_iface ,meta_buf_ctx ,0 ); 1734for (ggml_tensor * t = ggml_get_first_tensor (ctx );t != nullptr ;t = ggml_get_next_tensor (ctx ,t )) { 1735t -> buffer = meta_buf ; 1736ggml_backend_meta_buffer_init_tensor_impl (meta_buf_ctx -> stc_static ,t ); 1737t -> data = (void * )0x2000000000000000 ;// FIXME 1738 } 1739for (size_t i = 0 ;i < n_simple_bufts ;i ++ ) { 1740ggml_context * ctx = meta_buf_ctx -> stc_static .ctxs [i ].get (); 1741ggml_backend_buffer_type_t simple_buft = ggml_backend_meta_buft_simple_buft (buft ,i ); 1742 1743// If a ggml_context only has zero-sized tensors, ggml_backend_alloc_ctx_tensors_from_buft returns NULL. 1744// For those edge cases, allocate a dummy buffer instead. 1745bool any_nonzero_slice = false; 1746for (ggml_tensor * t = ggml_get_first_tensor (ctx );t != nullptr ;t = ggml_get_next_tensor (ctx ,t )) { 1747if (ggml_nelements (t )!= 0 ) { 1748any_nonzero_slice = true; 1749break ; 1750 } 1751 } 1752if (any_nonzero_slice ) { 1753meta_buf_ctx -> bufs [i ].reset (ggml_backend_alloc_ctx_tensors_from_buft (ctx ,simple_buft )); 1754 }else { 1755meta_buf_ctx -> bufs [i ].reset (ggml_backend_buft_alloc_buffer (simple_buft ,0 )); 1756for (ggml_tensor * t = ggml_get_first_tensor (ctx );t != nullptr ;t = ggml_get_next_tensor (ctx ,t )) { 1757t -> buffer = meta_buf_ctx -> bufs [i ].get (); 1758 } 1759 } 1760GGML_ASSERT (meta_buf_ctx -> bufs [i ]); 1761meta_buf -> size = std::max (meta_buf -> size ,ggml_backend_buffer_get_size (meta_buf_ctx -> bufs [i ].get ())); 1762 } 1763return meta_buf ; 1764} 1765 1766// 1767// meta backend 1768// 1769 1770static ggml_guid_t ggml_backend_meta_guid () { 1771static ggml_guid guid = {0xf1 ,0x0e ,0x34 ,0xcf ,0x9c ,0x6f ,0x43 ,0xcb ,0x96 ,0x92 ,0xbe ,0x8e ,0xbb ,0x71 ,0x3f ,0xda }; 1772return & guid ; 1773} 1774 1775struct ggml_backend_meta_context { 1776struct cgraph_config { 1777ggml_cgraph * cgraph_main = nullptr ; 1778int offset = 0 ;// Node offset vs. original graph 1779 1780 std::vector < ggml_cgraph *> cgraphs_aux ; 1781 }; 1782struct backend_config { 1783ggml_backend_t backend ; 1784 1785 std::vector < cgraph_config > cgraphs ; 1786 std::vector < ggml_tensor *> nodes ; 1787 std::vector < ggml_backend_buffer_ptr > bufs ; 1788 1789backend_config (ggml_backend_t backend ,const size_t n_reduce_steps ) :backend (backend ) { 1790bufs .resize (n_reduce_steps ); 1791 } 1792 }; 1793 std::string name ; 1794 std::vector < backend_config > backend_configs ; 1795ggml_context_ptr ctx ; 1796 std::vector < ggml_cgraph *> cgraphs_aux ; 1797 std::vector < ggml_tensor *> nodes_aux ; 1798size_t n_reduce_steps ; 1799int max_nnodes = 0 ; 1800size_t max_tmp_size = 0 ; 1801size_t max_subgraphs = 0 ; 1802size_t n_subgraphs = 0 ; 1803uint64_t uid = 0 ; 1804 1805void * comm_ctx = nullptr ; 1806ggml_backend_comm_allreduce_tensor_t comm_allreduce = nullptr ; 1807 1808ggml_backend_meta_context (ggml_backend_dev_t meta_dev ,const char * params ) { 1809const size_t n_devs = ggml_backend_meta_dev_n_devs (meta_dev ); 1810n_reduce_steps = std::ceil (std::log2 (n_devs )); 1811name = "Meta(" ; 1812 std::vector < ggml_backend_t > simple_backends ; 1813backend_configs .reserve (n_devs ); 1814simple_backends .reserve (n_devs ); 1815for (size_t i = 0 ;i < n_devs ;i ++ ) { 1816ggml_backend_dev_t simple_dev = ggml_backend_meta_dev_simple_dev (meta_dev ,i ); 1817if (i > 0 ) { 1818name += "," ; 1819 } 1820name += ggml_backend_dev_name (simple_dev ); 1821simple_backends .push_back (ggml_backend_dev_init (simple_dev ,params )); 1822backend_configs .emplace_back (simple_backends .back (),n_reduce_steps ); 1823 } 1824name += ")" ; 1825 1826if (n_devs > 1 ) { 1827ggml_backend_comm_init_t comm_init = (ggml_backend_comm_init_t )ggml_backend_reg_get_proc_address ( 1828ggml_backend_dev_backend_reg (ggml_backend_get_device (simple_backends [0 ])),"ggml_backend_comm_init" ); 1829if (comm_init != nullptr ) { 1830comm_ctx = comm_init (simple_backends .data (),simple_backends .size ()); 1831 } 1832 } 1833if (comm_ctx != nullptr ) { 1834comm_allreduce = (ggml_backend_comm_allreduce_tensor_t ) 1835ggml_backend_reg_get_proc_address (ggml_backend_dev_backend_reg ( 1836ggml_backend_get_device (simple_backends [0 ])),"ggml_backend_comm_allreduce_tensor" ); 1837GGML_ASSERT (comm_allreduce != nullptr ); 1838 } 1839 } 1840 1841 ~ggml_backend_meta_context () { 1842if (comm_ctx != nullptr ) { 1843ggml_backend_comm_free_t comm_free = (ggml_backend_comm_free_t )ggml_backend_reg_get_proc_address ( 1844ggml_backend_dev_backend_reg (ggml_backend_get_device (backend_configs [0 ].backend )),"ggml_backend_comm_free" ); 1845GGML_ASSERT (comm_free != nullptr ); 1846comm_free (comm_ctx ); 1847 } 1848for (auto & bc :backend_configs ) { 1849ggml_backend_free (bc .backend ); 1850 } 1851 } 1852}; 1853 1854static const char * ggml_backend_meta_get_name (ggml_backend_t backend ) { 1855GGML_ASSERT (ggml_backend_is_meta (backend )); 1856const ggml_backend_meta_context * backend_ctx = (const ggml_backend_meta_context * )backend -> context ; 1857return backend_ctx -> name .c_str (); 1858} 1859 1860static void ggml_backend_meta_free (ggml_backend_t backend ) { 1861GGML_ASSERT (ggml_backend_is_meta (backend )); 1862ggml_backend_meta_context * backend_ctx = (ggml_backend_meta_context * )backend -> context ; 1863delete backend_ctx ; 1864delete backend ; 1865} 1866 1867static void ggml_backend_meta_set_tensor_async (ggml_backend_t backend ,ggml_tensor * tensor ,const void * data ,size_t offset ,size_t size ) { 1868const size_t n_backends = ggml_backend_meta_n_backends (backend ); 1869GGML_ASSERT (offset == 0 ); 1870GGML_ASSERT (ggml_is_contiguous (tensor )); 1871 1872const ggml_backend_meta_split_state split_state = ggml_backend_meta_get_split_state (tensor ,/*assume_sync =*/ false); 1873GGML_ASSERT (split_state .n_segments == 1 ); 1874GGML_ASSERT (split_state .nr [0 ]== 1 ); 1875 1876switch (split_state .axis ) { 1877case GGML_BACKEND_SPLIT_AXIS_0 : 1878case GGML_BACKEND_SPLIT_AXIS_1 : 1879case GGML_BACKEND_SPLIT_AXIS_2 : { 1880// Exploit that tensors are contiguous to splice it with simple tensors as "chunks". 1881const size_t chunk_size_full = tensor -> nb [split_state .axis + 1 ]; 1882GGML_ASSERT (offset %chunk_size_full == 0 ); 1883GGML_ASSERT (size %chunk_size_full == 0 ); 1884const int64_t i_start = offset /chunk_size_full ; 1885const int64_t i_stop = (offset + size )/chunk_size_full ; 1886size_t offset_j = 0 ; 1887for (size_t j = 0 ;j < n_backends ;j ++ ){ 1888ggml_backend_t simple_backend = ggml_backend_meta_simple_backend (backend ,j ); 1889ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1890const size_t chunk_size_j = simple_tensor -> nb [split_state .axis + 1 ]; 1891if (chunk_size_j == 0 ) { 1892continue ; 1893 } 1894ggml_backend_tensor_set_2d_async (simple_backend ,simple_tensor , (const char * )data + offset_j ,offset ,chunk_size_j , 1895i_stop - i_start ,chunk_size_j ,chunk_size_full ); 1896offset_j += chunk_size_j ; 1897 } 1898GGML_ASSERT (offset_j == chunk_size_full ); 1899 }break ; 1900case GGML_BACKEND_SPLIT_AXIS_MIRRORED : { 1901for (size_t j = 0 ;j < n_backends ;j ++ ) { 1902ggml_backend_tensor_set_async ( 1903ggml_backend_meta_simple_backend (backend ,j ),ggml_backend_meta_buffer_simple_tensor (tensor ,j ),data ,offset ,size ); 1904 } 1905 }break ; 1906default : { 1907GGML_ABORT ("fatal error" ); 1908 } 1909 } 1910} 1911 1912static void ggml_backend_meta_get_tensor_async (ggml_backend_t backend ,const ggml_tensor * tensor ,void * data ,size_t offset ,size_t size ) { 1913const size_t n_backends = ggml_backend_meta_n_backends (backend ); 1914GGML_ASSERT (offset == 0 ); 1915GGML_ASSERT (ggml_is_contiguous (tensor )); 1916 1917const ggml_backend_meta_split_state split_state = ggml_backend_meta_get_split_state (tensor ,/*assume_sync =*/ false); 1918GGML_ASSERT (split_state .n_segments == 1 ); 1919GGML_ASSERT (split_state .nr [0 ]== 1 ); 1920 1921switch (split_state .axis ) { 1922case GGML_BACKEND_SPLIT_AXIS_0 : 1923case GGML_BACKEND_SPLIT_AXIS_1 : 1924case GGML_BACKEND_SPLIT_AXIS_2 : { 1925// Exploit that tensors are contiguous to splice it with simple tensors as "chunks". 1926const size_t chunk_size_full = tensor -> nb [split_state .axis + 1 ]; 1927GGML_ASSERT (offset %chunk_size_full == 0 ); 1928GGML_ASSERT (size %chunk_size_full == 0 ); 1929const int64_t i_start = offset /chunk_size_full ; 1930const int64_t i_stop = (offset + size )/chunk_size_full ; 1931size_t offset_j = 0 ; 1932for (size_t j = 0 ;j < n_backends ;j ++ ){ 1933ggml_backend_t simple_backend = ggml_backend_meta_simple_backend (backend ,j ); 1934const ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,j ); 1935const size_t chunk_size_j = simple_tensor -> nb [split_state .axis + 1 ]; 1936if (chunk_size_j == 0 ) { 1937continue ; 1938 } 1939ggml_backend_tensor_get_2d_async (simple_backend ,simple_tensor , (char * )data + offset_j ,offset ,chunk_size_j , 1940i_stop - i_start ,chunk_size_j ,chunk_size_full ); 1941offset_j += chunk_size_j ; 1942 } 1943GGML_ASSERT (offset_j == chunk_size_full ); 1944 }break ; 1945case GGML_BACKEND_SPLIT_AXIS_MIRRORED : { 1946// TODO other simple backend may be better 1947ggml_backend_t simple_backend = ggml_backend_meta_simple_backend (backend ,0 ); 1948const ggml_tensor * simple_tensor = ggml_backend_meta_buffer_simple_tensor (tensor ,0 ); 1949ggml_backend_tensor_get_async (simple_backend ,simple_tensor ,data ,offset ,size ); 1950 }break ; 1951default : { 1952GGML_ABORT ("fatal error" ); 1953 } 1954 } 1955} 1956 1957static void ggml_backend_meta_synchronize (ggml_backend_t backend ) { 1958const size_t n_backends = ggml_backend_meta_n_backends (backend ); 1959for (size_t i = 0 ;i < n_backends ;i ++ ) { 1960ggml_backend_synchronize (ggml_backend_meta_simple_backend (backend ,i )); 1961 } 1962} 1963 1964static enum ggml_status ggml_backend_meta_graph_compute (ggml_backend_t backend ,struct ggml_cgraph * cgraph ) { 1965GGML_ASSERT (cgraph -> grads == nullptr ); 1966const size_t n_backends = ggml_backend_meta_n_backends (backend ); 1967ggml_backend_meta_context * backend_ctx = (ggml_backend_meta_context * )backend -> context ; 1968 1969// If the previous cgraph had a defined UID it can be used to skip rebuilding the subgraphs per simple backend. 1970const bool needs_rebuild = (cgraph -> uid == 0 )|| (cgraph -> uid != backend_ctx -> uid ); 1971 1972bool max_nnodes_raised = false; 1973if (cgraph -> n_nodes > backend_ctx -> max_nnodes ) { 1974for (size_t j = 0 ;j < n_backends ;j ++ ) { 1975auto & bcj = backend_ctx -> backend_configs [j ]; 1976bcj .nodes .resize (cgraph -> n_nodes ); 1977bcj .cgraphs .resize (cgraph -> n_nodes ); 1978 } 1979backend_ctx -> max_nnodes = cgraph -> n_nodes ; 1980max_nnodes_raised = true; 1981assert (needs_rebuild ); 1982 } 1983 1984if (needs_rebuild ) { 1985 std::set < ggml_backend_buffer_t > used_buffers ; 1986for (int i = 0 ;i < cgraph -> n_leafs ;i ++ ) { 1987if (ggml_backend_buffer_is_meta (cgraph -> leafs [i ]-> buffer )) { 1988used_buffers .emplace (cgraph -> leafs [i ]-> buffer ); 1989 } 1990 } 1991for (int i = 0 ;i < cgraph -> n_nodes ;i ++ ) { 1992if (ggml_backend_buffer_is_meta (cgraph -> nodes [i ]-> buffer )) { 1993used_buffers .emplace (cgraph -> nodes [i ]-> buffer ); 1994 } 1995 } 1996for (ggml_backend_buffer_t buf :used_buffers ) { 1997ggml_backend_meta_buffer_context * buf_ctx = (ggml_backend_meta_buffer_context * )buf -> context ; 1998buf_ctx -> stc_compute_index_next = buf_ctx -> stc_compute_index ^1 ; 1999ggml_backend_meta_simple_tensor_container & stc = buf_ctx -> stc_compute [buf_ctx -> stc_compute_index_next ]; 2000for (ggml_context_ptr & ctx :stc .ctxs ) { 2001ggml_reset (ctx .get ()); 2002 } 2003stc .simple_tensors .clear (); 2004 } 2005size_t n_subgraphs = 0 ; 2006size_t max_tmp_size = 0 ; 2007 2008for (size_t j = 0 ;j < n_backends ;j ++ ) { 2009auto & bcj = backend_ctx -> backend_configs [j ]; 2010 2011for (int i = 0 ;i < cgraph -> n_nodes ;i ++ ) { 2012ggml_tensor * node = cgraph -> nodes [i ]; 2013if (node -> view_src != nullptr && node -> view_src -> op == GGML_OP_NONE && ggml_backend_buffer_is_host (node -> view_src -> buffer )) { 2014// FIXME s_copy_main is on the CPU and its view seems to be incorrectly added to the graph nodes. 2015// For regular usage this doesn't matter since it's a noop but trying to call ggml_backend_meta_buffer_simple_tensor results in a crash. 2016bcj .nodes [i ]= node ; 2017continue ; 2018 } 2019bcj .nodes [i ]= ggml_backend_meta_buffer_simple_tensor (node ,j ); 2020GGML_ASSERT (bcj .nodes [i ]); 2021 } 2022 } 2023 2024 { 2025// For MoE models it may make sense to delay the AllReduce in order to reduce I/O: 2026auto get_i_delayed_branch = [& ](const int i )-> int { 2027int id = i ;// i_delayed 2028int idr = i ;// i_delayed return, last safe return value 2029 2030ggml_tensor * node = cgraph -> nodes [id ]; 2031int32_t n_used = ggml_node_get_use_count (cgraph ,id ); 2032 2033// Skip MIRRORED nodes that don't consume node 2034auto skip_unrelated = [& ]() { 2035while (id + 1 < cgraph -> n_nodes ) { 2036ggml_tensor * next = cgraph -> nodes [id + 1 ]; 2037if (ggml_backend_meta_get_split_state (next , false).axis != GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 2038break ; 2039 } 2040bool safe = true; 2041for (int s = 0 ;s < GGML_MAX_SRC ;s ++ ) { 2042if (next -> src [s ]== nullptr ) { 2043continue ; 2044 } 2045if (next -> src [s ]== node ) { 2046safe = false; 2047break ; 2048 } 2049if (ggml_backend_meta_get_split_state (next -> src [s ], false).axis != GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 2050safe = false; 2051break ; 2052 } 2053 } 2054if (!safe ) { 2055break ; 2056 } 2057id ++ ; 2058 } 2059 }; 2060 2061skip_unrelated (); 2062if (id + 1 >=cgraph -> n_nodes ) { 2063return idr ; 2064 } 2065 { 2066ggml_tensor * next = cgraph -> nodes [id + 1 ]; 2067if (next -> op == GGML_OP_ADD_ID && next -> src [0 ]== node && 2068ggml_backend_meta_get_split_state (next -> src [1 ], false).axis == GGML_BACKEND_SPLIT_AXIS_PARTIAL && 2069ggml_backend_meta_get_split_state (next -> src [2 ], false).axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 2070node = next ; 2071id ++ ; 2072idr = id ; 2073n_used = ggml_node_get_use_count (cgraph ,id ); 2074 } 2075 } 2076// Chain of MULs with MIRRORED src[1] 2077while (true) { 2078skip_unrelated (); 2079if (id + 1 >=cgraph -> n_nodes ) { 2080return idr ; 2081 } 2082ggml_tensor * next = cgraph -> nodes [id + 1 ]; 2083if (next -> op == GGML_OP_MUL && next -> src [0 ]== node && 2084ggml_backend_meta_get_split_state (next -> src [1 ], false).axis == GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 2085node = next ; 2086id ++ ; 2087idr = id ; 2088n_used = ggml_node_get_use_count (cgraph ,id ); 2089 }else { 2090break ; 2091 } 2092 } 2093 2094if (n_used != node -> ne [1 ]|| id + 2 * n_used - 1 >=cgraph -> n_nodes ) { 2095return idr ; 2096 } 2097for (int32_t k = 0 ;k < n_used ;k ++ ) { 2098ggml_tensor * next = cgraph -> nodes [id + 1 ]; 2099if (next -> op != GGML_OP_VIEW || next -> view_src != node || next -> view_offs != k * node -> nb [1 ]|| 2100next -> ne [0 ]!= node -> ne [0 ]|| next -> ne [1 ]!= node -> ne [2 ]|| next -> nb [1 ]!= node -> nb [2 ]|| 2101ggml_node_get_use_count (cgraph ,id + 1 )!= 1 ) { 2102return idr ; 2103 } 2104id ++ ; 2105 } 2106 { 2107ggml_tensor * next = cgraph -> nodes [id + 1 ]; 2108if (next -> op != GGML_OP_ADD || next -> src [0 ]!= cgraph -> nodes [id - (n_used - 1 )]|| 2109next -> src [1 ]!= cgraph -> nodes [id - (n_used - 2 )]|| ggml_node_get_use_count (cgraph ,id + 1 )!= 1 ) { 2110return idr ; 2111 } 2112id ++ ; 2113 } 2114for (int32_t k = 0 ;k < n_used - 2 ;k ++ ) { 2115ggml_tensor * next = cgraph -> nodes [id + 1 ]; 2116if (next -> op != GGML_OP_ADD || next -> src [0 ]!= cgraph -> nodes [id ]|| 2117next -> src [1 ]!= cgraph -> nodes [id - (n_used - 2 )]|| ggml_node_get_use_count (cgraph ,id + 1 )!= 1 ) { 2118return idr ; 2119 } 2120id ++ ; 2121 } 2122idr = id ; 2123return idr ; 2124 }; 2125 2126// AllReduce(a) + AllReduce(b) == AllReduce(a + b) for independent partial branches. 2127auto get_i_delayed = [& ](const int i )-> int { 2128const int i_delayed = get_i_delayed_branch (i ); 2129ggml_tensor * node = cgraph -> nodes [i_delayed ]; 2130 2131if (ggml_node_get_use_count (cgraph ,i_delayed )!= 1 ) { 2132return i_delayed ; 2133 } 2134 2135for (int id = i_delayed + 1 ;id < cgraph -> n_nodes ;id ++ ) { 2136ggml_tensor * next = cgraph -> nodes [id ]; 2137if (next -> view_src == node ) { 2138return i_delayed ; 2139 } 2140for (int s = 0 ;s < GGML_MAX_SRC ;s ++ ) { 2141if (next -> src [s ]== node ) { 2142return i_delayed ; 2143 } 2144 } 2145 2146if (next -> view_src != nullptr && next -> view_src -> op == GGML_OP_NONE && ggml_backend_buffer_is_host (next -> view_src -> buffer )) { 2147continue ; 2148 } 2149if (ggml_backend_meta_get_split_state (next , false).axis != GGML_BACKEND_SPLIT_AXIS_PARTIAL ) { 2150continue ; 2151 } 2152 2153const int i_other = id ; 2154const int i_other_delayed = get_i_delayed_branch (i_other ); 2155ggml_tensor * other = cgraph -> nodes [i_other_delayed ]; 2156if (ggml_node_get_use_count (cgraph ,i_other_delayed )!= 1 || i_other_delayed + 1 >=cgraph -> n_nodes ) { 2157return i_delayed ; 2158 } 2159 2160ggml_tensor * sum = cgraph -> nodes [i_other_delayed + 1 ]; 2161if (sum -> op != GGML_OP_ADD || 2162 !ggml_are_same_shape (node ,other )|| node -> type != other -> type || sum -> type != node -> type || 2163 !((sum -> src [0 ]== node && sum -> src [1 ]== other )|| 2164 (sum -> src [0 ]== other && sum -> src [1 ]== node ))|| 2165ggml_backend_meta_get_split_state (sum , false).axis != GGML_BACKEND_SPLIT_AXIS_MIRRORED ) { 2166return i_delayed ; 2167 } 2168 2169for (size_t j = 0 ;j < n_backends ;j ++ ) { 2170auto & bcj = backend_ctx -> backend_configs [j ]; 2171const bool compute = bcj .nodes [i ]-> flags & GGML_TENSOR_FLAG_COMPUTE ; 2172const bool compute_other = bcj .nodes [i_other ]-> flags & GGML_TENSOR_FLAG_COMPUTE ; 2173if (compute != compute_other ) { 2174return i_delayed ; 2175 } 2176 } 2177return i_other_delayed + 1 ; 2178 } 2179return i_delayed ; 2180 }; 2181 2182int i_start = 0 ; 2183for (int i = 0 ;i < cgraph -> n_nodes ;i ++ ) { 2184ggml_tensor * node = cgraph -> nodes [i ]; 2185if (node -> view_src != nullptr && node -> view_src -> op == GGML_OP_NONE && ggml_backend_buffer_is_host (node -> view_src -> buffer )) { 2186continue ; 2187 } 2188const ggml_backend_meta_split_state split_state = ggml_backend_meta_get_split_state (node ,/*assume_sync =*/ false); 2189if (split_state .axis == GGML_BACKEND_SPLIT_AXIS_PARTIAL ) { 2190max_tmp_size = std::max (max_tmp_size ,ggml_nbytes (node )); 2191 } 2192const bool new_subgraph = i + 1 == cgraph -> n_nodes || split_state .axis == GGML_BACKEND_SPLIT_AXIS_PARTIAL ; 2193if (!new_subgraph ) { 2194continue ; 2195 } 2196 2197const int i_delayed = get_i_delayed (i ); 2198 2199// If we can delay the AllReduce we need to consider the interaction with zero-sized tensor slices. 2200// A backend with such a slice would normally have valid data after participating in the AllReduce with a node that has 2201// its compute flag disabled and thus gets its data zeroed out. 2202// If the AllReduce is delayed then the nodes until that point also need to have their compute flag disabled. 2203if (i_delayed > i ) { 2204for (size_t j = 0 ;j < n_backends ;j ++ ) { 2205auto & bcj = backend_ctx -> backend_configs [j ]; 2206if ((bcj .nodes [i ]-> flags & GGML_TENSOR_FLAG_COMPUTE )== 0 ) { 2207for (int ii = i + 1 ;ii <=i_delayed ;ii ++ ) { 2208bcj .nodes [ii ]-> flags &= ~GGML_TENSOR_FLAG_COMPUTE ; 2209 } 2210 } 2211 } 2212 } 2213 2214i = i_delayed ; 2215 2216for (size_t j = 0 ;j < n_backends ;j ++ ) { 2217auto & bcj = backend_ctx -> backend_configs [j ]; 2218bcj .cgraphs [n_subgraphs ].offset = i_start ; 2219 } 2220n_subgraphs ++ ; 2221i_start = i + 1 ; 2222 } 2223GGML_ASSERT (i_start == cgraph -> n_nodes ); 2224 } 2225 2226backend_ctx -> uid = cgraph -> uid ; 2227backend_ctx -> n_subgraphs = n_subgraphs ; 2228 2229if (max_tmp_size > backend_ctx -> max_tmp_size ) { 2230for (size_t j = 0 ;j < n_backends ;j ++ ) { 2231auto & bcj = backend_ctx -> backend_configs [j ]; 2232for (size_t i = 0 ;i < backend_ctx -> n_reduce_steps ;i ++ ) { 2233bcj .bufs [i ].reset (ggml_backend_alloc_buffer (bcj .backend ,max_tmp_size )); 2234 } 2235 } 2236backend_ctx -> max_tmp_size = max_tmp_size ; 2237 } 2238 2239if (max_nnodes_raised || n_subgraphs > backend_ctx -> max_subgraphs ) { 2240backend_ctx -> max_subgraphs = std::max (backend_ctx -> max_subgraphs ,n_subgraphs ); 2241const size_t n_nodes_per_device = 3 * backend_ctx -> n_reduce_steps ;// tmp + ADD (+zeroing) graph per step and device 2242const size_t n_cgraphs_per_device = 2 * backend_ctx -> n_reduce_steps ;// ADD ( + zeroing) graph per step and device 2243const size_t mem_per_device_graphs_main = backend_ctx -> max_subgraphs * ggml_graph_overhead_custom (backend_ctx -> max_nnodes ,cgraph -> grads ); 2244const size_t mem_per_device_graphs_aux = n_cgraphs_per_device * backend_ctx -> max_subgraphs * ggml_graph_overhead_custom (1 ,cgraph -> grads ); 2245const size_t mem_per_device_nodes_aux = n_nodes_per_device * backend_ctx -> max_subgraphs * ggml_tensor_overhead (); 2246const ggml_init_params params = { 2247/*.mem_size =*/ n_backends * (mem_per_device_graphs_main + mem_per_device_graphs_aux + mem_per_device_nodes_aux ), 2248/*.mem_buffer =*/ nullptr , 2249/*.no_alloc =*/ true, 2250 }; 2251backend_ctx -> ctx .reset (ggml_init (params )); 2252for (size_t j = 0 ;j < n_backends ;j ++ ) { 2253auto & bcj = backend_ctx -> backend_configs [j ]; 2254for (size_t i = 0 ;i < n_subgraphs ;i ++ ) { 2255bcj .cgraphs [i ].cgraph_main = ggml_new_graph_custom (backend_ctx -> ctx .get (),cgraph -> n_nodes ,/*grads =*/ false); 2256 } 2257 } 2258backend_ctx -> cgraphs_aux .resize (n_backends * n_cgraphs_per_device * backend_ctx -> max_subgraphs ); 2259for (size_t k = 0 ;k < backend_ctx -> cgraphs_aux .size ();k ++ ) { 2260backend_ctx -> cgraphs_aux [k ]= ggml_new_graph_custom (backend_ctx -> ctx .get (),1 ,cgraph -> grads ); 2261 } 2262backend_ctx -> nodes_aux .resize (n_backends * n_nodes_per_device * backend_ctx -> max_subgraphs ); 2263for (size_t k = 0 ;k < backend_ctx -> nodes_aux .size ();k ++ ) { 2264backend_ctx -> nodes_aux [k ]= ggml_new_tensor_1d (backend_ctx -> ctx .get (),GGML_TYPE_F32 ,1 ); 2265 } 2266 } 2267 2268for (size_t j = 0 ;j < n_backends ;j ++ ) { 2269auto & bcj = backend_ctx -> backend_configs [j ]; 2270for (size_t i_graph = 0 ;i_graph < n_subgraphs ;i_graph ++ ) { 2271ggml_cgraph * cgraph_ij = bcj .cgraphs [i_graph ].cgraph_main ; 2272const size_t i_node_start = bcj .cgraphs [i_graph ].offset ; 2273const size_t i_node_stop = i_graph + 1 < n_subgraphs ?bcj .cgraphs [i_graph + 1 ].offset :cgraph -> n_nodes ; 2274cgraph_ij -> n_nodes = i_node_stop - i_node_start ; 2275ggml_hash_set_reset (& cgraph_ij -> visited_hash_set ); 2276for (size_t i_node = i_node_start ;i_node < i_node_stop ;i_node ++ ) { 2277ggml_tensor * node_ij = bcj .nodes [i_node ]; 2278cgraph_ij -> nodes [i_node - i_node_start ]= node_ij ; 2279const size_t hash_pos_orig = ggml_hash_find (& cgraph -> visited_hash_set ,cgraph -> nodes [i_node ]); 2280const size_t hash_pos_ij = ggml_hash_insert (& cgraph_ij -> visited_hash_set ,node_ij ); 2281cgraph_ij -> use_counts [hash_pos_ij ]= cgraph -> use_counts [hash_pos_orig ]; 2282 } 2283cgraph_ij -> uid = ggml_graph_next_uid (); 2284 } 2285 } 2286 } 2287 2288size_t iga = 0 ;// i graph aux 2289size_t ina = 0 ;// i node aux 2290 2291auto get_node_aux = [& ](ggml_tensor * t )-> ggml_tensor * { 2292ggml_tensor * ret = backend_ctx -> nodes_aux [ina ++ ]; 2293memset (ret ,0 ,sizeof (ggml_tensor )); 2294ret -> op = GGML_OP_NONE ; 2295ret -> type = t -> type ; 2296for (size_t k = 0 ;k < GGML_MAX_DIMS ;k ++ ) { 2297ret -> ne [k ]= t -> ne [k ]; 2298ret -> nb [k ]= t -> nb [k ]; 2299 } 2300return ret ; 2301 }; 2302auto set_tmp_data = [& ](ggml_tensor * tensor ,const size_t j ,const size_t i_buf ) { 2303auto & bcj = backend_ctx -> backend_configs [j ]; 2304ggml_backend_buffer_ptr & buf_ptr = bcj .bufs [i_buf ]; 2305if (!buf_ptr || ggml_backend_buffer_get_size (buf_ptr .get ())< backend_ctx -> max_tmp_size ) { 2306buf_ptr .reset (ggml_backend_alloc_buffer (bcj .backend ,backend_ctx -> max_tmp_size )); 2307 } 2308tensor -> buffer = buf_ptr .get (); 2309tensor -> data = ggml_backend_buffer_get_base (buf_ptr .get ()); 2310 }; 2311// FIXME usage_counts 2312auto get_cgraph_aux = [& ]()-> ggml_cgraph * { 2313ggml_cgraph * ret = backend_ctx -> cgraphs_aux [iga ++ ]; 2314return ret ; 2315 }; 2316 2317// Preferentially use backend-specific allreduce_tensor_async (e.g. NCCL for CUDA), use a generic fallback if unavailable: 2318auto allreduce_fallback = [& ](size_t i )-> ggml_status { 2319 std::vector < ggml_cgraph *> step_cgraphs (n_backends ,nullptr ); 2320 2321// Zero out nodes that were disabled due to having a zero-sized slice: 2322for (size_t j = 0 ;j < n_backends ;j ++ ) { 2323auto & bcj = backend_ctx -> backend_configs [j ]; 2324ggml_tensor * node = bcj .cgraphs [i ].cgraph_main -> nodes [bcj .cgraphs [i ].cgraph_main -> n_nodes - 1 ]; 2325if (node -> flags & GGML_TENSOR_FLAG_COMPUTE ) { 2326continue ; 2327 } 2328ggml_tensor * node_zero = get_node_aux (node ); 2329node_zero -> op = GGML_OP_SCALE ;// FIXME 0.0f * NaN == NaN 2330node_zero -> src [0 ]= node ; 2331ggml_set_op_params_f32 (node_zero ,0 ,0.0f ); 2332node_zero -> data = node -> data ; 2333node_zero -> buffer = node -> buffer ; 2334node_zero -> flags |=GGML_TENSOR_FLAG_COMPUTE ; 2335 2336step_cgraphs [j ]= get_cgraph_aux (); 2337step_cgraphs [j ]-> nodes [0 ]= node_zero ; 2338step_cgraphs [j ]-> n_nodes = 1 ; 2339const ggml_status status = ggml_backend_graph_compute_async (bcj .backend ,step_cgraphs [j ]); 2340if (status != GGML_STATUS_SUCCESS ) { 2341return status ; 2342 } 2343 } 2344 std::fill (step_cgraphs .begin (),step_cgraphs .end (),nullptr ); 2345 2346auto push_data = [& ](const size_t j_src ,const size_t j_dst ,const size_t i_buf ) { 2347assert (step_cgraphs [j_dst ]== nullptr ); 2348auto & bcj_src = backend_ctx -> backend_configs [j_src ]; 2349auto & bcj_dst = backend_ctx -> backend_configs [j_dst ]; 2350 2351ggml_tensor * node_src = bcj_src .cgraphs [i ].cgraph_main -> nodes [bcj_src .cgraphs [i ].cgraph_main -> n_nodes - 1 ]; 2352ggml_tensor * node_dst = bcj_dst .cgraphs [i ].cgraph_main -> nodes [bcj_dst .cgraphs [i ].cgraph_main -> n_nodes - 1 ]; 2353GGML_ASSERT (ggml_is_contiguous (node_src )); 2354GGML_ASSERT (ggml_is_contiguous (node_dst )); 2355 2356ggml_tensor * node_tmp = get_node_aux (node_dst ); 2357set_tmp_data (node_tmp ,j_dst ,i_buf ); 2358 2359ggml_backend_tensor_copy_async (bcj_src .backend ,bcj_dst .backend ,node_src ,node_tmp ); 2360 2361ggml_tensor * node_red = get_node_aux (node_dst ); 2362node_red -> view_src = node_dst -> view_src == nullptr ?node_dst :node_dst -> view_src ; 2363node_red -> view_offs = node_dst -> view_offs ; 2364node_red -> op = GGML_OP_ADD ; 2365node_red -> src [0 ]= node_dst ; 2366node_red -> src [1 ]= node_tmp ; 2367node_red -> flags |=GGML_TENSOR_FLAG_COMPUTE ; 2368ggml_backend_view_init (node_red ); 2369 2370ggml_cgraph * cgraph_aux = get_cgraph_aux (); 2371cgraph_aux -> nodes [0 ]= node_red ; 2372cgraph_aux -> n_nodes = 1 ; 2373step_cgraphs [j_dst ]= cgraph_aux ; 2374 }; 2375 2376size_t offset_j = n_backends /2 ; 2377while ((offset_j & (offset_j - 1 ))!= 0 ) { 2378offset_j -- ; 2379 } 2380const size_t offset_j_max = offset_j ; 2381size_t i_buf = 0 ; 2382 2383// If n_backends is not a power of 2, fold in the excess prior to butterfly reduction: 2384for (size_t j_src = 2 * offset_j_max ;j_src < n_backends ;j_src ++ ) { 2385const size_t j_dst = j_src - 2 * offset_j_max ; 2386push_data (j_src ,j_dst ,i_buf ); 2387const ggml_status status = ggml_backend_graph_compute_async (backend_ctx -> backend_configs [j_dst ].backend ,step_cgraphs [j_dst ]); 2388if (status != GGML_STATUS_SUCCESS ) { 2389return status ; 2390 } 2391i_buf = 1 ; 2392 } 2393 2394// Butterfly reduction: 2395for (;offset_j >=1 ;offset_j /=2 ) { 2396 std::fill (step_cgraphs .begin (),step_cgraphs .end (),nullptr ); 2397 2398for (size_t j = 0 ;j < 2 * offset_j_max ;j ++ ) { 2399const size_t j_other = j ^offset_j ; 2400if (j_other >=n_backends ) { 2401continue ; 2402 } 2403push_data (j ,j_other ,i_buf ); 2404 } 2405 2406for (size_t j = 0 ;j < 2 * offset_j_max ;j ++ ) { 2407if (step_cgraphs [j ]== nullptr ) { 2408continue ; 2409 } 2410auto & bcj = backend_ctx -> backend_configs [j ]; 2411const ggml_status status = ggml_backend_graph_compute_async (bcj .backend ,step_cgraphs [j ]); 2412if (status != GGML_STATUS_SUCCESS ) { 2413return status ; 2414 } 2415 } 2416i_buf ++ ; 2417 } 2418assert (i_buf == backend_ctx -> n_reduce_steps ); 2419 2420// If n_backends is not a power of 2, copy back the reduced tensors to the excess: 2421for (size_t j = 2 * offset_j_max ;j < n_backends ;j ++ ) { 2422auto & bcj_src = backend_ctx -> backend_configs [j - 2 * offset_j_max ]; 2423auto & bcj_dst = backend_ctx -> backend_configs [j ]; 2424 2425ggml_tensor * node_src = bcj_src .cgraphs [i ].cgraph_main -> nodes [bcj_src .cgraphs [i ].cgraph_main -> n_nodes - 1 ]; 2426ggml_tensor * node_dst = bcj_dst .cgraphs [i ].cgraph_main -> nodes [bcj_dst .cgraphs [i ].cgraph_main -> n_nodes - 1 ]; 2427ggml_backend_tensor_copy_async (bcj_src .backend ,bcj_dst .backend ,node_src ,node_dst ); 2428 } 2429 2430return GGML_STATUS_SUCCESS ; 2431 }; 2432 2433 2434for (size_t i = 0 ;i < backend_ctx -> n_subgraphs ;i ++ ) { 2435for (size_t j = 0 ;j < n_backends ;j ++ ) { 2436auto & bcj = backend_ctx -> backend_configs [j ]; 2437const ggml_status status = ggml_backend_graph_compute_async (bcj .backend ,bcj .cgraphs [i ].cgraph_main ); 2438if (status != GGML_STATUS_SUCCESS ) { 2439return status ; 2440 } 2441 } 2442 2443if (n_backends > 1 && i < backend_ctx -> n_subgraphs - 1 ) { 2444bool backend_allreduce_success = false; 2445if (backend_ctx -> comm_ctx ) { 2446 std::vector < ggml_tensor *> nodes ; 2447nodes .reserve (n_backends ); 2448for (size_t j = 0 ;j < n_backends ;j ++ ) { 2449auto & bcj = backend_ctx -> backend_configs [j ]; 2450ggml_cgraph * cgraph_ij = bcj .cgraphs [i ].cgraph_main ; 2451nodes .push_back (cgraph_ij -> nodes [cgraph_ij -> n_nodes - 1 ]); 2452 } 2453backend_allreduce_success = backend_ctx -> comm_allreduce (backend_ctx -> comm_ctx ,nodes .data ()); 2454 } 2455 2456if (!backend_allreduce_success ) { 2457const ggml_status status = allreduce_fallback (i ); 2458if (status != GGML_STATUS_SUCCESS ) { 2459return status ; 2460 } 2461 } 2462 } 2463 } 2464return GGML_STATUS_SUCCESS ; 2465} 2466 2467static const ggml_backend_i ggml_backend_meta_i = { 2468/* .get_name = */ ggml_backend_meta_get_name , 2469/* .free = */ ggml_backend_meta_free , 2470/* .set_tensor_async = */ ggml_backend_meta_set_tensor_async , 2471/* .get_tensor_async = */ ggml_backend_meta_get_tensor_async , 2472/* .set_tensor_2d_async = */ nullptr , 2473/* .get_tensor_2d_async = */ nullptr , 2474/* .cpy_tensor_async = */ nullptr , 2475/* .synchronize = */ ggml_backend_meta_synchronize , 2476/* .graph_plan_create = */ nullptr , 2477/* .graph_plan_free = */ nullptr , 2478/* .graph_plan_update = */ nullptr , 2479/* .graph_plan_compute = */ nullptr , 2480/* .graph_compute = */ ggml_backend_meta_graph_compute , 2481/* .event_record = */ nullptr , 2482/* .event_wait = */ nullptr , 2483/* .graph_optimize = */ nullptr , 2484}; 2485 2486bool ggml_backend_is_meta (ggml_backend_t backend ) { 2487return backend != nullptr && backend -> iface .get_name == ggml_backend_meta_i .get_name ; 2488} 2489 2490static ggml_backend_t ggml_backend_meta_device_init_backend (ggml_backend_dev_t dev ,const char * params ) { 2491ggml_backend_meta_context * backend_ctx = new ggml_backend_meta_context (dev ,params ); 2492 2493ggml_backend_t backend = new struct ggml_backend ; 2494backend -> guid = ggml_backend_meta_guid (); 2495backend -> iface = ggml_backend_meta_i ; 2496backend -> device = dev ; 2497backend -> context = backend_ctx ; 2498return backend ; 2499} 2500 2501size_t ggml_backend_meta_n_backends (ggml_backend_t meta_backend ) { 2502GGML_ASSERT (ggml_backend_is_meta (meta_backend )); 2503const ggml_backend_meta_context * backend_ctx = (const ggml_backend_meta_context * )meta_backend -> context ; 2504return backend_ctx -> backend_configs .size (); 2505} 2506 2507ggml_backend_t ggml_backend_meta_simple_backend (ggml_backend_t meta_backend ,size_t index ) { 2508GGML_ASSERT (ggml_backend_is_meta (meta_backend )); 2509const ggml_backend_meta_context * backend_ctx = (const ggml_backend_meta_context * )meta_backend -> context ; 2510return backend_ctx -> backend_configs [index ].backend ; 2511}