char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
64a155d24
char/aliceai-t5-moe
1#pragma once 2 3#include "ggml.h" 4#include "ggml-alloc.h" 5 6#ifdef GGML_BACKEND_SHARED 7# if defined(_WIN32 )&& !defined(__MINGW32__ ) 8# ifdef GGML_BACKEND_BUILD 9# define GGML_BACKEND_API __declspec(dllexport) extern 10# else 11# define GGML_BACKEND_API __declspec(dllimport) extern 12# endif 13# else 14# define GGML_BACKEND_API __attribute__ ((visibility ("default"))) extern 15# endif 16#else 17# define GGML_BACKEND_API extern 18#endif 19 20#ifdef __cplusplus 21extern "C" { 22#endif 23 24typedef struct ggml_backend_buffer_type * ggml_backend_buffer_type_t ; 25typedef struct ggml_backend_buffer * ggml_backend_buffer_t ; 26typedef struct ggml_backend_event * ggml_backend_event_t ; 27typedef struct ggml_backend * ggml_backend_t ; 28typedef void * ggml_backend_graph_plan_t ; 29typedef struct ggml_backend_reg * ggml_backend_reg_t ; 30typedef struct ggml_backend_device * ggml_backend_dev_t ; 31 32 33// 34// Backend buffer type 35// 36 37GGML_API const char * ggml_backend_buft_name (ggml_backend_buffer_type_t buft ); 38GGML_API ggml_backend_buffer_t ggml_backend_buft_alloc_buffer (ggml_backend_buffer_type_t buft ,size_t size ); 39GGML_API size_t ggml_backend_buft_get_alignment (ggml_backend_buffer_type_t buft ); 40GGML_API size_t ggml_backend_buft_get_max_size (ggml_backend_buffer_type_t buft ); 41GGML_API size_t ggml_backend_buft_get_alloc_size (ggml_backend_buffer_type_t buft ,const struct ggml_tensor * tensor ); 42GGML_API bool ggml_backend_buft_is_host (ggml_backend_buffer_type_t buft ); 43GGML_API ggml_backend_dev_t ggml_backend_buft_get_device (ggml_backend_buffer_type_t buft ); 44 45// 46// Backend buffer 47// 48 49enum ggml_backend_buffer_usage { 50GGML_BACKEND_BUFFER_USAGE_ANY = 0 , 51GGML_BACKEND_BUFFER_USAGE_WEIGHTS = 1 , 52GGML_BACKEND_BUFFER_USAGE_COMPUTE = 2 , 53 }; 54 55GGML_API const char * ggml_backend_buffer_name (ggml_backend_buffer_t buffer ); 56GGML_API void ggml_backend_buffer_free (ggml_backend_buffer_t buffer ); 57GGML_API void * ggml_backend_buffer_get_base (ggml_backend_buffer_t buffer ); 58GGML_API size_t ggml_backend_buffer_get_size (ggml_backend_buffer_t buffer ); 59GGML_API enum ggml_status ggml_backend_buffer_init_tensor (ggml_backend_buffer_t buffer ,struct ggml_tensor * tensor ); 60GGML_API size_t ggml_backend_buffer_get_alignment (ggml_backend_buffer_t buffer ); 61GGML_API size_t ggml_backend_buffer_get_max_size (ggml_backend_buffer_t buffer ); 62GGML_API size_t ggml_backend_buffer_get_alloc_size (ggml_backend_buffer_t buffer ,const struct ggml_tensor * tensor ); 63GGML_API void ggml_backend_buffer_clear (ggml_backend_buffer_t buffer ,uint8_t value ); 64GGML_API bool ggml_backend_buffer_is_host (ggml_backend_buffer_t buffer ); 65GGML_API void ggml_backend_buffer_set_usage (ggml_backend_buffer_t buffer ,enum ggml_backend_buffer_usage usage ); 66GGML_API enum ggml_backend_buffer_usage ggml_backend_buffer_get_usage (ggml_backend_buffer_t buffer ); 67GGML_API ggml_backend_buffer_type_t ggml_backend_buffer_get_type (ggml_backend_buffer_t buffer ); 68GGML_API void ggml_backend_buffer_reset (ggml_backend_buffer_t buffer ); 69 70// tensor copy between different backends 71GGML_API void ggml_backend_tensor_copy (const struct ggml_tensor * src ,struct ggml_tensor * dst ); 72 73// 74// Backend (stream) 75// 76 77GGML_API ggml_guid_t ggml_backend_guid (ggml_backend_t backend ); 78GGML_API const char * ggml_backend_name (ggml_backend_t backend ); 79GGML_API void ggml_backend_free (ggml_backend_t backend ); 80 81GGML_API ggml_backend_buffer_type_t ggml_backend_get_default_buffer_type (ggml_backend_t backend ); 82GGML_API ggml_backend_buffer_t ggml_backend_alloc_buffer (ggml_backend_t backend ,size_t size ); 83GGML_API size_t ggml_backend_get_alignment (ggml_backend_t backend ); 84GGML_API size_t ggml_backend_get_max_size (ggml_backend_t backend ); 85 86GGML_API void ggml_backend_tensor_set_async (ggml_backend_t backend ,struct ggml_tensor * tensor ,const void * data ,size_t offset ,size_t size ); 87GGML_API void ggml_backend_tensor_get_async (ggml_backend_t backend ,const struct ggml_tensor * tensor ,void * data ,size_t offset ,size_t size ); 88GGML_API void ggml_backend_tensor_set_2d_async (ggml_backend_t backend ,struct ggml_tensor * tensor ,const void * data ,size_t offset ,size_t size ,size_t n_copies ,size_t stride_tensor ,size_t stride_data ); 89GGML_API void ggml_backend_tensor_get_2d_async (ggml_backend_t backend ,const struct ggml_tensor * tensor ,void * data ,size_t offset ,size_t size ,size_t n_copies ,size_t stride_tensor ,size_t stride_data ); 90 91// "offset" refers to the offset in tensor->data for setting/getting data 92GGML_API void ggml_backend_tensor_set (struct ggml_tensor * tensor ,const void * data ,size_t offset ,size_t size ); 93GGML_API void ggml_backend_tensor_get (const struct ggml_tensor * tensor ,void * data ,size_t offset ,size_t size ); 94GGML_API void ggml_backend_tensor_set_2d (struct ggml_tensor * tensor ,const void * data ,size_t offset ,size_t size ,size_t n_copies ,size_t stride_tensor ,size_t stride_data ); 95GGML_API void ggml_backend_tensor_get_2d (const struct ggml_tensor * tensor ,void * data ,size_t offset ,size_t size ,size_t n_copies ,size_t stride_tensor ,size_t stride_data ); 96GGML_API void ggml_backend_tensor_memset (struct ggml_tensor * tensor ,uint8_t value ,size_t offset ,size_t size ); 97 98GGML_API void ggml_backend_synchronize (ggml_backend_t backend ); 99 100GGML_API ggml_backend_graph_plan_t ggml_backend_graph_plan_create (ggml_backend_t backend ,struct ggml_cgraph * cgraph ); 101GGML_API void ggml_backend_graph_plan_free (ggml_backend_t backend ,ggml_backend_graph_plan_t plan ); 102 103GGML_API enum ggml_status ggml_backend_graph_plan_compute (ggml_backend_t backend ,ggml_backend_graph_plan_t plan ); 104GGML_API enum ggml_status ggml_backend_graph_compute (ggml_backend_t backend ,struct ggml_cgraph * cgraph ); 105GGML_API enum ggml_status ggml_backend_graph_compute_async (ggml_backend_t backend ,struct ggml_cgraph * cgraph ); 106 107// NOTE: will be removed, use device version instead 108GGML_API bool ggml_backend_supports_op (ggml_backend_t backend ,const struct ggml_tensor * op ); 109GGML_API bool ggml_backend_supports_buft (ggml_backend_t backend ,ggml_backend_buffer_type_t buft ); 110GGML_API bool ggml_backend_offload_op (ggml_backend_t backend ,const struct ggml_tensor * op ); 111 112// asynchronous copy 113// the copy is performed after all the currently queued operations in backend_src 114// backend_dst will wait for the copy to complete before performing other operations 115// automatic fallback to sync copy if async is not supported 116GGML_API void ggml_backend_tensor_copy_async (ggml_backend_t backend_src ,ggml_backend_t backend_dst ,const struct ggml_tensor * src ,struct ggml_tensor * dst ); 117 118GGML_API ggml_backend_dev_t ggml_backend_get_device (ggml_backend_t backend ); 119 120// 121// Events 122// 123 124GGML_API ggml_backend_event_t ggml_backend_event_new (ggml_backend_dev_t device ); 125GGML_API void ggml_backend_event_free (ggml_backend_event_t event ); 126GGML_API void ggml_backend_event_record (ggml_backend_event_t event ,ggml_backend_t backend ); 127GGML_API void ggml_backend_event_synchronize (ggml_backend_event_t event ); 128GGML_API void ggml_backend_event_wait (ggml_backend_t backend ,ggml_backend_event_t event ); 129 130// 131// Backend device 132// 133 134enum ggml_backend_dev_type { 135// CPU device using system memory 136GGML_BACKEND_DEVICE_TYPE_CPU , 137// GPU device using dedicated memory 138GGML_BACKEND_DEVICE_TYPE_GPU , 139// integrated GPU device using host memory 140GGML_BACKEND_DEVICE_TYPE_IGPU , 141// accelerator devices intended to be used together with the CPU backend (e.g. BLAS or AMX) 142GGML_BACKEND_DEVICE_TYPE_ACCEL , 143// "meta" device wrapping multiple other devices for tensor parallelism 144GGML_BACKEND_DEVICE_TYPE_META , 145 }; 146 147// functionality supported by the device 148struct ggml_backend_dev_caps { 149// asynchronous operations 150bool async ; 151// pinned host buffer 152bool host_buffer ; 153// creating buffers from host ptr 154bool buffer_from_host_ptr ; 155// event synchronization 156bool events ; 157// mmap is supported for loading 158bool mmap_support ; 159 }; 160 161// all the device properties 162struct ggml_backend_dev_props { 163// device name 164const char * name ; 165// device description 166const char * description ; 167// device free memory in bytes 168size_t memory_free ; 169// device total memory in bytes 170size_t memory_total ; 171// device type 172enum ggml_backend_dev_type type ; 173// device id 174// for PCI devices, this should be the lower-case PCI bus id formatted as "domain:bus:device.function" (e.g. "0000:c1:00.0") 175// if the id is unknown, this should be NULL 176const char * device_id ; 177// device capabilities 178struct ggml_backend_dev_caps caps ; 179 }; 180 181GGML_API const char * ggml_backend_dev_name (ggml_backend_dev_t device ); 182GGML_API const char * ggml_backend_dev_description (ggml_backend_dev_t device ); 183GGML_API void ggml_backend_dev_memory (ggml_backend_dev_t device ,size_t * free ,size_t * total ); 184GGML_API enum ggml_backend_dev_type ggml_backend_dev_type (ggml_backend_dev_t device ); 185GGML_API void ggml_backend_dev_get_props (ggml_backend_dev_t device ,struct ggml_backend_dev_props * props ); 186GGML_API ggml_backend_reg_t ggml_backend_dev_backend_reg (ggml_backend_dev_t device ); 187GGML_API ggml_backend_t ggml_backend_dev_init (ggml_backend_dev_t device ,const char * params ); 188GGML_API ggml_backend_buffer_type_t ggml_backend_dev_buffer_type (ggml_backend_dev_t device ); 189GGML_API ggml_backend_buffer_type_t ggml_backend_dev_host_buffer_type (ggml_backend_dev_t device ); 190GGML_API ggml_backend_buffer_t ggml_backend_dev_buffer_from_host_ptr (ggml_backend_dev_t device ,void * ptr ,size_t size ,size_t max_tensor_size ); 191 192GGML_API bool ggml_backend_dev_supports_op (ggml_backend_dev_t device ,const struct ggml_tensor * op ); 193GGML_API bool ggml_backend_dev_supports_buft (ggml_backend_dev_t device ,ggml_backend_buffer_type_t buft ); 194GGML_API bool ggml_backend_dev_offload_op (ggml_backend_dev_t device ,const struct ggml_tensor * op ); 195 196// 197// Backend (reg) 198// 199 200GGML_API const char * ggml_backend_reg_name (ggml_backend_reg_t reg ); 201GGML_API size_t ggml_backend_reg_dev_count (ggml_backend_reg_t reg ); 202GGML_API ggml_backend_dev_t ggml_backend_reg_dev_get (ggml_backend_reg_t reg ,size_t index ); 203GGML_API void * ggml_backend_reg_get_proc_address (ggml_backend_reg_t reg ,const char * name ); 204 205// Common functions that may be obtained using ggml_backend_reg_get_proc_address 206 207// Context management and operations for faster communication between backends, used for tensor parallelism (meta backend) 208typedef void * (* ggml_backend_comm_init_t )(ggml_backend_t * backends ,size_t n_backends ); 209typedef void (* ggml_backend_comm_free_t )(void * comm_ctx ); 210typedef bool (* ggml_backend_comm_allreduce_tensor_t )(void * comm_ctx ,struct ggml_tensor ** tensors ); 211 212// Split buffer type for tensor parallelism (old) 213typedef ggml_backend_buffer_type_t (* ggml_backend_split_buffer_type_t )(int main_device ,const float * tensor_split ); 214// Set the number of threads for the backend 215typedef void (* ggml_backend_set_n_threads_t )(ggml_backend_t backend ,int n_threads ); 216// Get additional buffer types provided by the device (returns a NULL-terminated array) 217typedef ggml_backend_buffer_type_t * (* ggml_backend_dev_get_extra_bufts_t )(ggml_backend_dev_t device ); 218// Set the abort callback for the backend 219typedef void (* ggml_backend_set_abort_callback_t )(ggml_backend_t backend ,ggml_abort_callback abort_callback ,void * abort_callback_data ); 220// Get a list of feature flags supported by the backend (returns a NULL-terminated array) 221struct ggml_backend_feature { 222const char * name ; 223const char * value ; 224 }; 225typedef struct ggml_backend_feature * (* ggml_backend_get_features_t )(ggml_backend_reg_t reg ); 226 227// 228// Backend registry 229// 230 231GGML_API void ggml_backend_register (ggml_backend_reg_t reg ); 232 233GGML_API void ggml_backend_device_register (ggml_backend_dev_t device ); 234 235// Backend (reg) enumeration 236GGML_API size_t ggml_backend_reg_count (void ); 237GGML_API ggml_backend_reg_t ggml_backend_reg_get (size_t index ); 238GGML_API ggml_backend_reg_t ggml_backend_reg_by_name (const char * name ); 239 240// Device enumeration 241GGML_API size_t ggml_backend_dev_count (void ); 242GGML_API ggml_backend_dev_t ggml_backend_dev_get (size_t index ); 243GGML_API ggml_backend_dev_t ggml_backend_dev_by_name (const char * name ); 244GGML_API ggml_backend_dev_t ggml_backend_dev_by_type (enum ggml_backend_dev_type type ); 245 246// Direct backend (stream) initialization 247// = ggml_backend_dev_init(ggml_backend_dev_by_name(name), params) 248GGML_API ggml_backend_t ggml_backend_init_by_name (const char * name ,const char * params ); 249// = ggml_backend_dev_init(ggml_backend_dev_by_type(type), params) 250GGML_API ggml_backend_t ggml_backend_init_by_type (enum ggml_backend_dev_type type ,const char * params ); 251// = ggml_backend_dev_init(ggml_backend_dev_by_type(GPU) OR ggml_backend_dev_by_type(CPU), NULL) 252GGML_API ggml_backend_t ggml_backend_init_best (void ); 253 254// Load a backend from a dynamic library and register it 255GGML_API ggml_backend_reg_t ggml_backend_load (const char * path ); 256// Unload a backend if loaded dynamically and unregister it 257GGML_API void ggml_backend_unload (ggml_backend_reg_t reg ); 258// Load all known backends from dynamic libraries 259GGML_API void ggml_backend_load_all (void ); 260GGML_API void ggml_backend_load_all_from_path (const char * dir_path ); 261 262// 263// Backend scheduler 264// 265 266// The backend scheduler allows for multiple backend devices to be used together 267// Handles compute buffer allocation, assignment of tensors to backends, and copying of tensors between backends 268// The backends are selected based on: 269// - the backend that supports the operation 270// - the location of the pre-allocated tensors (e.g. the weights) 271/* 272Example usage: 273 274// operations that use tensors allocated in a buffer with USAGE_WEIGHTS will be assigned 275// preferably to run on the same backend as the buffer 276ggml_backend_buffer_set_usage(buf_weights, GGML_BACKEND_BUFFER_USAGE_WEIGHTS); 277 278sched = ggml_backend_sched_new({backend_gpu, backend_gpu2, backend_cpu}, NULL, num_backends, GGML_DEFAULT_GRAPH_SIZE, false, true); 279 280// initialize buffers from a max size graph (optional) 281reserve_graph = build_graph(sched, max_batch_size); 282 283// manually assign nodes to a backend (optional, should not be needed in most cases) 284struct ggml_tensor * node = ggml_mul_mat(ctx, ...); 285ggml_backend_sched_set_tensor_backend(sched, node, backend_gpu); 286 287ggml_backend_sched_reserve(sched, reserve_graph); 288 289// compute 290graph = build_graph(sched); // the graph and its tensors are single-use in terms of allocation, multi-use in terms of computation 291for (int i = 0; i < 10; ++i) { 292ggml_backend_sched_graph_compute(sched, graph); // on the first iteration the graph is allocated automatically 293} 294 295// if there are graph inputs: 296graph = build_graph(sched); // get a new graph that is not allocated (the metadata for the old graph is freed once ggml_free is called) 297ggml_backend_sched_reset(sched); // clear the allocation of the previous graph 298ggml_backend_sched_alloc_graph(sched, graph); // explicitly allocate the new graph but do not execute it 299ggml_backend_tensor_set(input_tensor, ...); // copy data to the newly allocated graph tensors 300ggml_backend_sched_graph_compute(sched, graph); // execute the graph 301 302// as an alternative to the above it is also possible to assign the inputs to a dedicated context and 303// allocate them statically via ggml_backend_alloc_ctx_tensors 304} 305*/ 306 307typedef struct ggml_backend_sched * ggml_backend_sched_t ; 308 309// Evaluation callback for each node in the graph (set with ggml_backend_sched_set_eval_callback) 310// when ask == true, the scheduler wants to know if the user wants to observe this node 311// this allows the scheduler to batch nodes together in order to evaluate them in a single call 312// 313// when ask == false, the scheduler is passing the node tensor to the user for observation 314// if the user returns false, the scheduler will cancel the graph compute 315// 316typedef bool (* ggml_backend_sched_eval_callback )(struct ggml_tensor * t ,bool ask ,void * user_data ); 317 318// Initialize a backend scheduler, backends with low index are given priority over backends with high index 319GGML_API ggml_backend_sched_t ggml_backend_sched_new (ggml_backend_t * backends ,ggml_backend_buffer_type_t * bufts ,int n_backends ,size_t graph_size ,bool parallel ,bool op_offload ); 320GGML_API void ggml_backend_sched_free (ggml_backend_sched_t sched ); 321 322// Initialize backend buffers from a measure graph 323GGML_API void ggml_backend_sched_reserve_size (ggml_backend_sched_t sched ,struct ggml_cgraph * measure_graph ,size_t * sizes ); 324GGML_API bool ggml_backend_sched_reserve (ggml_backend_sched_t sched ,struct ggml_cgraph * measure_graph );// returns success 325 326GGML_API int ggml_backend_sched_get_n_backends (ggml_backend_sched_t sched ); 327GGML_API ggml_backend_t ggml_backend_sched_get_backend (ggml_backend_sched_t sched ,int i ); 328 329// Get the number of splits of the last graph 330GGML_API int ggml_backend_sched_get_n_splits (ggml_backend_sched_t sched ); 331GGML_API int ggml_backend_sched_get_n_copies (ggml_backend_sched_t sched ); 332 333GGML_API ggml_backend_buffer_type_t ggml_backend_sched_get_buffer_type (ggml_backend_sched_t sched ,ggml_backend_t backend ); 334GGML_API size_t ggml_backend_sched_get_buffer_size (ggml_backend_sched_t sched ,ggml_backend_t backend ); 335 336GGML_API void ggml_backend_sched_set_tensor_backend (ggml_backend_sched_t sched ,struct ggml_tensor * node ,ggml_backend_t backend ); 337GGML_API ggml_backend_t ggml_backend_sched_get_tensor_backend (ggml_backend_sched_t sched ,struct ggml_tensor * node ); 338 339// Split graph without allocating it 340GGML_API void ggml_backend_sched_split_graph (ggml_backend_sched_t sched ,struct ggml_cgraph * graph ); 341 342// Allocate and compute graph on the backend scheduler 343GGML_API bool ggml_backend_sched_alloc_graph (ggml_backend_sched_t sched ,struct ggml_cgraph * graph );// returns success 344GGML_API enum ggml_status ggml_backend_sched_graph_compute (ggml_backend_sched_t sched ,struct ggml_cgraph * graph ); 345GGML_API enum ggml_status ggml_backend_sched_graph_compute_async (ggml_backend_sched_t sched ,struct ggml_cgraph * graph ); 346GGML_API void ggml_backend_sched_synchronize (ggml_backend_sched_t sched ); 347 348// Reset all assignments and allocators - must be called before changing the node backends or allocating a new graph. 349// This in effect deallocates all tensors that were previously allocated and leaves them with dangling pointers. 350// The correct way to use this API is to discard the deallocated tensors and create new ones. 351GGML_API void ggml_backend_sched_reset (ggml_backend_sched_t sched ); 352 353// Set a callback to be called for each resulting node during graph compute 354GGML_API void ggml_backend_sched_set_eval_callback (ggml_backend_sched_t sched ,ggml_backend_sched_eval_callback callback ,void * user_data ); 355 356// 357// Meta backend 358// 359 360#define GGML_BACKEND_META_MAX_DEVICES 16 361 362enum ggml_backend_meta_split_axis { 363// tensor split by tensor dimensions: 364GGML_BACKEND_SPLIT_AXIS_0 = 0 , 365GGML_BACKEND_SPLIT_AXIS_1 = 1 , 366GGML_BACKEND_SPLIT_AXIS_2 = 2 , 367GGML_BACKEND_SPLIT_AXIS_3 = 3 , 368 369GGML_BACKEND_SPLIT_AXIS_MIRRORED = 10 ,// all values on all backends 370GGML_BACKEND_SPLIT_AXIS_PARTIAL = 11 ,// each backend has a partial sum 371 372// for internal bookkeeping only: 373GGML_BACKEND_SPLIT_AXIS_NONE = 98 , 374GGML_BACKEND_SPLIT_AXIS_UNKNOWN = 99 , 375 }; 376GGML_API const char * ggml_backend_meta_split_axis_name (enum ggml_backend_meta_split_axis split_axis ); 377 378struct ggml_backend_meta_split_state { 379enum ggml_backend_meta_split_axis axis ; 380 381// for tensors with axis >= 0 && axis < GGML_MAX_DIMS: 382// - each device has a slice of the tensor along the split axis 383// - most tensors have n_segments == 1 and a contiguous slice of the tensor data 384// - some tensors have an inhomogenenous data layout along the split axis, 385// those tensors are divided into segments which are each individually split across devices 386// - ne has one entry per segment and device and that segment repeats nr times, 387// in total when accounting for repetitions the segments add up to ggml_tensor::ne for that axis, 388// the outer/inner loops are over segments/devices like [seg0_dev0_r0, seg0_dev1_r0, seg0_dev0_r1, seg0_dev1_r1, seg1_dev0_r0, seg1_dev1_r0], 389// - for example, a transformer may have a fused QKV matrix rather than 3 matrices, those would be 3 separate segments 390// that each need to be split individually across devices so that each device gets a slice of Q, K, and V, 391// the Q matrix can be larger than the K and V matrices so this can either be expressed as 3 segments or as 2 segments 392// where the segment for K/V repeats twice 393int64_t ne [16 * GGML_BACKEND_META_MAX_DEVICES ]; 394uint32_t nr [16 ]; 395uint32_t n_segments ; 396 }; 397 398// function to assign split states for statically allocated tensors, compute tensor split states will be assigned to be compatible: 399typedef struct ggml_backend_meta_split_state (* ggml_backend_meta_get_split_state_t )(const struct ggml_tensor * tensor ,void * userdata ); 400 401// create a new meta device from "simple" devices, meta buffer type/buffer/backend is then derived from this: 402// TODO: this looks a bit strange - a backend API creates a device. I think we should try 403// express this as a backend registry functionality instead 404GGML_API ggml_backend_dev_t ggml_backend_meta_device ( 405ggml_backend_dev_t * devs ,size_t n_devs ,ggml_backend_meta_get_split_state_t get_split_state ,void * get_split_state_ud ); 406 407// 408// Utils 409// 410 411struct ggml_backend_graph_copy { 412ggml_backend_buffer_t buffer ; 413struct ggml_context * ctx_allocated ; 414struct ggml_context * ctx_unallocated ; 415struct ggml_cgraph * graph ; 416 }; 417 418// Copy a graph to a different backend 419GGML_API struct ggml_backend_graph_copy ggml_backend_graph_copy (ggml_backend_t backend ,struct ggml_cgraph * graph ); 420GGML_API void ggml_backend_graph_copy_free (struct ggml_backend_graph_copy copy ); 421 422typedef bool (* ggml_backend_eval_callback )(int node_index ,struct ggml_tensor * t1 ,struct ggml_tensor * t2 ,void * user_data ); 423 424// Compare the output of two backends 425GGML_API bool ggml_backend_compare_graph_backend (ggml_backend_t backend1 ,ggml_backend_t backend2 ,struct ggml_cgraph * graph ,ggml_backend_eval_callback callback ,void * user_data ,struct ggml_tensor const * const * test_nodes ,size_t num_test_nodes ); 426 427// Tensor initialization 428GGML_API enum ggml_status ggml_backend_tensor_alloc (ggml_backend_buffer_t buffer ,struct ggml_tensor * tensor ,void * addr ); 429GGML_API enum ggml_status ggml_backend_view_init (struct ggml_tensor * tensor ); 430 431// CPU buffer types are always available 432GGML_API ggml_backend_buffer_t ggml_backend_cpu_buffer_from_ptr (void * ptr ,size_t size ); 433GGML_API ggml_backend_buffer_type_t ggml_backend_cpu_buffer_type (void ); 434 435#ifdef __cplusplus 436} 437#endif