Skip to content

Commit 9b9626b

Browse files
jartjordankanter
authored andcommitted
ggml : introduce GGML_CALL function annotation (ggml-org#4850)
This change makes it possible to build ggml-cuda.cu and ggml-metal.m as independent dynamic shared objects, that may be conditionally linked at runtime in a multiplatform binary. It introduces a GGML_CALL annotation that documents which functions have a cyclic call relationship, between the application code and GPU modules. This change does nothing, unless the build defines -DGGML_MULTIPLATFORM which causes back-references and function pointers to conform to MS ABI which is supported by NVCC, ROCm, XCode, GCC and Clang across platforms
1 parent c6657cd commit 9b9626b

9 files changed

+244
-235
lines changed

ggml-backend-impl.h

+30-30
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ extern "C" {
1616
typedef void * ggml_backend_buffer_type_context_t;
1717

1818
struct ggml_backend_buffer_type_i {
19-
const char * (*get_name) (ggml_backend_buffer_type_t buft);
20-
ggml_backend_buffer_t (*alloc_buffer) (ggml_backend_buffer_type_t buft, size_t size);
21-
size_t (*get_alignment) (ggml_backend_buffer_type_t buft); // tensor alignment
22-
size_t (*get_alloc_size) (ggml_backend_buffer_type_t buft, const struct ggml_tensor * tensor); // data size needed to allocate the tensor, including padding
23-
bool (*supports_backend)(ggml_backend_buffer_type_t buft, ggml_backend_t backend); // check if the buffer type is usable by the backend
19+
const char * (*GGML_CALL get_name) (ggml_backend_buffer_type_t buft);
20+
ggml_backend_buffer_t (*GGML_CALL alloc_buffer) (ggml_backend_buffer_type_t buft, size_t size);
21+
size_t (*GGML_CALL get_alignment) (ggml_backend_buffer_type_t buft); // tensor alignment
22+
size_t (*GGML_CALL get_alloc_size) (ggml_backend_buffer_type_t buft, const struct ggml_tensor * tensor); // data size needed to allocate the tensor, including padding
23+
bool (*GGML_CALL supports_backend)(ggml_backend_buffer_type_t buft, ggml_backend_t backend); // check if the buffer type is usable by the backend
2424
// check if tensor data is in host memory
2525
// should be equivalent to supports_backend(buft, ggml_backend_cpu_init())
26-
bool (*is_host) (ggml_backend_buffer_type_t buft);
26+
bool (*GGML_CALL is_host) (ggml_backend_buffer_type_t buft);
2727
};
2828

2929
struct ggml_backend_buffer_type {
@@ -35,15 +35,15 @@ extern "C" {
3535
typedef void * ggml_backend_buffer_context_t;
3636

3737
struct ggml_backend_buffer_i {
38-
const char * (*get_name) (ggml_backend_buffer_t buffer);
39-
void (*free_buffer)(ggml_backend_buffer_t buffer);
40-
void * (*get_base) (ggml_backend_buffer_t buffer);
41-
void (*init_tensor)(ggml_backend_buffer_t buffer, struct ggml_tensor * tensor);
42-
void (*set_tensor) (ggml_backend_buffer_t buffer, struct ggml_tensor * tensor, const void * data, size_t offset, size_t size);
43-
void (*get_tensor) (ggml_backend_buffer_t buffer, const struct ggml_tensor * tensor, void * data, size_t offset, size_t size);
44-
bool (*cpy_tensor) (ggml_backend_buffer_t buffer, const struct ggml_tensor * src, struct ggml_tensor * dst); // dst is in the buffer, src may be in any buffer
45-
void (*clear) (ggml_backend_buffer_t buffer, uint8_t value);
46-
void (*reset) (ggml_backend_buffer_t buffer); // reset any internal state due to tensor initialization, such as tensor extras
38+
const char * (*GGML_CALL get_name) (ggml_backend_buffer_t buffer);
39+
void (*GGML_CALL free_buffer)(ggml_backend_buffer_t buffer);
40+
void * (*GGML_CALL get_base) (ggml_backend_buffer_t buffer);
41+
void (*GGML_CALL init_tensor)(ggml_backend_buffer_t buffer, struct ggml_tensor * tensor);
42+
void (*GGML_CALL set_tensor) (ggml_backend_buffer_t buffer, struct ggml_tensor * tensor, const void * data, size_t offset, size_t size);
43+
void (*GGML_CALL get_tensor) (ggml_backend_buffer_t buffer, const struct ggml_tensor * tensor, void * data, size_t offset, size_t size);
44+
bool (*GGML_CALL cpy_tensor) (ggml_backend_buffer_t buffer, const struct ggml_tensor * src, struct ggml_tensor * dst); // dst is in the buffer, src may be in any buffer
45+
void (*GGML_CALL clear) (ggml_backend_buffer_t buffer, uint8_t value);
46+
void (*GGML_CALL reset) (ggml_backend_buffer_t buffer); // reset any internal state due to tensor initialization, such as tensor extras
4747
};
4848

4949
struct ggml_backend_buffer {
@@ -54,7 +54,7 @@ extern "C" {
5454
enum ggml_backend_buffer_usage usage;
5555
};
5656

57-
ggml_backend_buffer_t ggml_backend_buffer_init(
57+
GGML_CALL ggml_backend_buffer_t ggml_backend_buffer_init(
5858
ggml_backend_buffer_type_t buft,
5959
struct ggml_backend_buffer_i iface,
6060
ggml_backend_buffer_context_t context,
@@ -70,31 +70,31 @@ extern "C" {
7070
typedef void * ggml_backend_context_t;
7171

7272
struct ggml_backend_i {
73-
const char * (*get_name)(ggml_backend_t backend);
73+
const char * (*GGML_CALL get_name)(ggml_backend_t backend);
7474

75-
void (*free)(ggml_backend_t backend);
75+
void (*GGML_CALL free)(ggml_backend_t backend);
7676

7777
// buffer allocation
78-
ggml_backend_buffer_type_t (*get_default_buffer_type)(ggml_backend_t backend);
78+
ggml_backend_buffer_type_t (*GGML_CALL get_default_buffer_type)(ggml_backend_t backend);
7979

8080
// (optional) asynchronous tensor data access
81-
void (*set_tensor_async)(ggml_backend_t backend, struct ggml_tensor * tensor, const void * data, size_t offset, size_t size);
82-
void (*get_tensor_async)(ggml_backend_t backend, const struct ggml_tensor * tensor, void * data, size_t offset, size_t size);
83-
bool (*cpy_tensor_async)(ggml_backend_t backend, const struct ggml_tensor * src, struct ggml_tensor * dst);
81+
void (*GGML_CALL set_tensor_async)(ggml_backend_t backend, struct ggml_tensor * tensor, const void * data, size_t offset, size_t size);
82+
void (*GGML_CALL get_tensor_async)(ggml_backend_t backend, const struct ggml_tensor * tensor, void * data, size_t offset, size_t size);
83+
bool (*GGML_CALL cpy_tensor_async)(ggml_backend_t backend, const struct ggml_tensor * src, struct ggml_tensor * dst);
8484

8585
// (optional) complete all pending operations
86-
void (*synchronize)(ggml_backend_t backend);
86+
void (*GGML_CALL synchronize)(ggml_backend_t backend);
8787

8888
// compute graph with a plan
89-
ggml_backend_graph_plan_t (*graph_plan_create) (ggml_backend_t backend, const struct ggml_cgraph * cgraph);
90-
void (*graph_plan_free) (ggml_backend_t backend, ggml_backend_graph_plan_t plan);
91-
void (*graph_plan_compute)(ggml_backend_t backend, ggml_backend_graph_plan_t plan);
89+
ggml_backend_graph_plan_t (*GGML_CALL graph_plan_create) (ggml_backend_t backend, const struct ggml_cgraph * cgraph);
90+
void (*GGML_CALL graph_plan_free) (ggml_backend_t backend, ggml_backend_graph_plan_t plan);
91+
void (*GGML_CALL graph_plan_compute)(ggml_backend_t backend, ggml_backend_graph_plan_t plan);
9292

9393
// compute graph without a plan (async)
94-
bool (*graph_compute)(ggml_backend_t backend, struct ggml_cgraph * cgraph);
94+
bool (*GGML_CALL graph_compute)(ggml_backend_t backend, struct ggml_cgraph * cgraph);
9595

9696
// check if the backend supports an operation
97-
bool (*supports_op)(ggml_backend_t backend, const struct ggml_tensor * op);
97+
bool (*GGML_CALL supports_op)(ggml_backend_t backend, const struct ggml_tensor * op);
9898
};
9999

100100
struct ggml_backend {
@@ -107,9 +107,9 @@ extern "C" {
107107
// Backend registry
108108
//
109109

110-
typedef ggml_backend_t (*ggml_backend_init_fn)(const char * params, void * user_data);
110+
typedef ggml_backend_t (*GGML_CALL ggml_backend_init_fn)(const char * params, void * user_data);
111111

112-
void ggml_backend_register(const char * name, ggml_backend_init_fn init_fn, ggml_backend_buffer_type_t default_buffer_type, void * user_data);
112+
GGML_CALL void ggml_backend_register(const char * name, ggml_backend_init_fn init_fn, ggml_backend_buffer_type_t default_buffer_type, void * user_data);
113113

114114
#ifdef __cplusplus
115115
}

0 commit comments

Comments
 (0)