Skip to content

Commit f5b9bd3

Browse files
authored
RPC: add tensor_memset (#25912)
1 parent 60bccc3 commit f5b9bd3

2 files changed

Lines changed: 84 additions & 3 deletions

File tree

‎ggml/include/ggml-rpc.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
extern "C" {
77
#endif
88

9-
#define RPC_PROTO_MAJOR_VERSION 4
9+
#define RPC_PROTO_MAJOR_VERSION 5
1010
#define RPC_PROTO_MINOR_VERSION 0
11-
#define RPC_PROTO_PATCH_VERSION 3
11+
#define RPC_PROTO_PATCH_VERSION 0
1212

1313
#ifdef __cplusplus
1414
static_assert(GGML_OP_COUNT == 101, "GGML_OP_COUNT has changed - update RPC_PROTO_PATCH_VERSION");

‎ggml/src/ggml-rpc/ggml-rpc.cpp‎

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ enum rpc_cmd {
7171
RPC_CMD_HELLO,
7272
RPC_CMD_DEVICE_COUNT,
7373
RPC_CMD_GRAPH_RECOMPUTE,
74+
RPC_CMD_MEMSET_TENSOR,
7475
RPC_CMD_COUNT,
7576
};
7677

@@ -152,6 +153,13 @@ struct rpc_msg_buffer_clear_req {
152153
uint8_t value;
153154
};
154155

156+
struct rpc_msg_memset_tensor_req {
157+
rpc_tensor tensor;
158+
uint64_t offset;
159+
uint64_t size;
160+
uint8_t value;
161+
};
162+
155163
struct rpc_msg_set_tensor_hash_req {
156164
rpc_tensor tensor;
157165
uint64_t offset;
@@ -462,6 +470,19 @@ static enum ggml_status ggml_backend_rpc_buffer_init_tensor(ggml_backend_buffer_
462470
return GGML_STATUS_SUCCESS;
463471
}
464472

473+
static void ggml_backend_rpc_buffer_memset_tensor(
474+
ggml_backend_buffer_t buffer, ggml_tensor * tensor, uint8_t value, size_t offset, size_t size) {
475+
ggml_backend_rpc_buffer_context * ctx = (ggml_backend_rpc_buffer_context *)buffer->context;
476+
rpc_msg_memset_tensor_req request = {
477+
/* .tensor = */ serialize_tensor(tensor),
478+
/* .offset = */ offset,
479+
/* .size = */ size,
480+
/* .value = */ value,
481+
};
482+
bool status = send_rpc_cmd(ctx->sock, RPC_CMD_MEMSET_TENSOR, &request, sizeof(request), nullptr, 0);
483+
RPC_STATUS_ASSERT(status);
484+
}
485+
465486
static void ggml_backend_rpc_buffer_set_tensor(ggml_backend_buffer_t buffer, ggml_tensor * tensor, const void * data, size_t offset, size_t size) {
466487
ggml_backend_rpc_buffer_context * ctx = (ggml_backend_rpc_buffer_context *)buffer->context;
467488
rpc_tensor rpc_tensor = serialize_tensor(tensor);
@@ -531,7 +552,7 @@ static ggml_backend_buffer_i ggml_backend_rpc_buffer_interface = {
531552
/* .free_buffer = */ ggml_backend_rpc_buffer_free_buffer,
532553
/* .get_base = */ ggml_backend_rpc_buffer_get_base,
533554
/* .init_tensor = */ ggml_backend_rpc_buffer_init_tensor,
534-
/* .memset_tensor = */ NULL,
555+
/* .memset_tensor = */ ggml_backend_rpc_buffer_memset_tensor,
535556
/* .set_tensor = */ ggml_backend_rpc_buffer_set_tensor,
536557
/* .get_tensor = */ ggml_backend_rpc_buffer_get_tensor,
537558
/* .set_tensor_2d = */ NULL,
@@ -831,6 +852,7 @@ class rpc_server {
831852
bool buffer_get_base(const rpc_msg_buffer_get_base_req & request, rpc_msg_buffer_get_base_rsp & response);
832853
bool free_buffer(const rpc_msg_free_buffer_req & request);
833854
bool buffer_clear(const rpc_msg_buffer_clear_req & request);
855+
bool memset_tensor(const rpc_msg_memset_tensor_req & request);
834856
bool set_tensor(const std::vector<uint8_t> & input);
835857
bool set_tensor_hash(const rpc_msg_set_tensor_hash_req & request, rpc_msg_set_tensor_hash_rsp & response);
836858
bool get_tensor(const rpc_msg_get_tensor_req & request, std::vector<uint8_t> & response);
@@ -989,6 +1011,52 @@ bool rpc_server::buffer_clear(const rpc_msg_buffer_clear_req & request) {
9891011
return true;
9901012
}
9911013

1014+
bool rpc_server::memset_tensor(const rpc_msg_memset_tensor_req & request) {
1015+
struct ggml_init_params params {
1016+
/*.mem_size =*/ ggml_tensor_overhead(),
1017+
/*.mem_buffer =*/ NULL,
1018+
/*.no_alloc =*/ true,
1019+
};
1020+
ggml_context_ptr ctx_ptr { ggml_init(params) };
1021+
GGML_ASSERT(ctx_ptr != nullptr);
1022+
ggml_context * ctx = ctx_ptr.get();
1023+
ggml_tensor * tensor = deserialize_tensor(ctx, &request.tensor);
1024+
if (tensor == nullptr || tensor->buffer == nullptr) {
1025+
GGML_LOG_ERROR("[%s] error deserializing tensor\n", __func__);
1026+
return false;
1027+
}
1028+
1029+
const uint64_t tensor_size = ggml_nbytes(tensor);
1030+
if (request.offset > tensor_size || request.size > tensor_size - request.offset) {
1031+
GGML_LOG_ERROR("[%s] tensor region (offset=%" PRIu64 ", size=%" PRIu64 ") out of tensor bounds [0, %" PRIu64 ")\n",
1032+
__func__, request.offset, request.size, tensor_size);
1033+
return false;
1034+
}
1035+
1036+
const uint64_t buffer_start = (uint64_t) ggml_backend_buffer_get_base(tensor->buffer);
1037+
const uint64_t buffer_size = ggml_backend_buffer_get_size(tensor->buffer);
1038+
if (request.tensor.data < buffer_start) {
1039+
GGML_LOG_ERROR("[%s] tensor data before buffer start\n", __func__);
1040+
return false;
1041+
}
1042+
const uint64_t data_offset = request.tensor.data - buffer_start;
1043+
if (data_offset > buffer_size ||
1044+
request.offset > buffer_size - data_offset ||
1045+
request.size > buffer_size - data_offset - request.offset) {
1046+
GGML_LOG_ERROR("[%s] tensor region out of buffer bounds\n", __func__);
1047+
return false;
1048+
}
1049+
if (tensor->buffer->iface.memset_tensor == nullptr) {
1050+
GGML_LOG_ERROR("[%s] memset not implemented by backend buffer\n", __func__);
1051+
return false;
1052+
}
1053+
1054+
LOG_DBG("[%s] buffer: %p, data: %p, offset: %" PRIu64 ", size: %" PRIu64 ", value: %u\n",
1055+
__func__, (void *) tensor->buffer, tensor->data, request.offset, request.size, request.value);
1056+
ggml_backend_tensor_memset(tensor, request.value, request.offset, request.size);
1057+
return true;
1058+
}
1059+
9921060
ggml_tensor * rpc_server::deserialize_tensor(struct ggml_context * ctx, const rpc_tensor * tensor) {
9931061
// Validate tensor type before using it
9941062
if (tensor->type >= GGML_TYPE_COUNT) {
@@ -1585,6 +1653,19 @@ static void rpc_serve_client(const std::vector<ggml_backend_t> & backends, const
15851653
}
15861654
break;
15871655
}
1656+
case RPC_CMD_MEMSET_TENSOR: {
1657+
rpc_msg_memset_tensor_req request;
1658+
if (!recv_msg(sock, &request, sizeof(request))) {
1659+
return;
1660+
}
1661+
if (!server.memset_tensor(request)) {
1662+
return;
1663+
}
1664+
if (!send_msg(sock, nullptr, 0)) {
1665+
return;
1666+
}
1667+
break;
1668+
}
15881669
case RPC_CMD_SET_TENSOR: {
15891670
std::vector<uint8_t> input;
15901671
if (!recv_msg(sock, input)) {

0 commit comments

Comments
 (0)