跳到主要内容

推理池 API

提交图像、等待结果、关闭池、设置 GPU 并发槽。打开见 打开

调度

darra_sched_set_gpu_slots()

void darra_sched_set_gpu_slots(int32_t gpu_device, int32_t slots);

同一 GPU 同时 InferImage 上限(张)。gpu_device 对应会话 / worker 的 gpu_device

参数:

  • gpu_device (int32_t) — GPU 序号,0 = 第一块
  • slots (int32_t) — 0(默认)= 不限制。大于 0 时按 weight 份额排队:某 owner 最多同时跑 max(1, slots * weight / 100) 路,全局仍不超过 slots

这不是 CUDA SM 占用百分比,是并发推理槽。线程安全。通常在 darra_pool_open 之前调用。

示例:

darra_sched_set_gpu_slots(0, 4);

进图

darra_pool_submit()

int32_t darra_pool_submit(darra_pool* pool,
const uint8_t* image_bytes,
size_t len,
const darra_image_desc* desc,
uint64_t* out_ticket);

提交一张图。成功时 *out_ticket > 0。图像字节会被拷走,调用方可立即释放入参。desc 契约同 darra_session_infer_image

参数:

  • pool (darra_pool*) — 已打开的池
  • image_bytes (const uint8_t*) — AUTO/ENCODED = 编码文件字节流;裸缓冲 = 像素内存
  • len (size_t) — 字节长度。裸缓冲必须 ≥ stride*height(stride 为 0 时:RGB888/BGR888=width*3,GRAY8=width*1,RGBA8888=width*4
  • desc (const darra_image_desc*) — 图像描述;desc->size 必填
  • out_ticket (uint64_t*) — 成功时写入票号,大于 0

返回值:

  • int32_tDARRA_OK 成功

典型错误:DARRA_BUSYOVERFLOW_FAIL 且队列满)/ DARRA_INTERNAL(NULL 句柄、desc->size 未填、裸缓冲缺宽高、len 不足)。OVERFLOW_BLOCK 时本函数会卡住直到有空位,不返回 DARRA_BUSY

示例:

uint64_t ticket = 0;
int32_t rc = darra_pool_submit(pool, jpeg, jpeg_len, &desc, &ticket);

等待

darra_pool_wait()

int32_t darra_pool_wait(darra_pool* pool,
uint64_t ticket,
char** out_results_json);

阻塞等待一张图的 JSON。SDK 分配,用完 darra_string_free。被 DROP_OLDEST 挤掉的票返回 DARRA_BUSY。结果 envelope 同 推理

参数:

  • pool (darra_pool*) — 已打开的池
  • ticket (uint64_t) — darra_pool_submit 返回的票
  • out_results_json (char**) — 结果 JSON,SDK 分配

返回值:

  • int32_tDARRA_OK 成功;DARRA_BUSY 票被挤掉

示例:

char* json = NULL;
int32_t rc = darra_pool_wait(pool, ticket, &json);
if (rc == DARRA_OK) {
puts(json);
darra_string_free(json);
}

darra_pool_try_wait()

int32_t darra_pool_try_wait(darra_pool* pool,
uint64_t ticket,
char** out_results_json);

非阻塞。还没好返回 DARRA_BUSYmessage 说明仍在队列或推理)。已完成则语义同 darra_pool_wait。被 DROP_OLDEST 挤掉同样 DARRA_BUSY

参数:

  • pool (darra_pool*) — 已打开的池
  • ticket (uint64_t) — darra_pool_submit 返回的票
  • out_results_json (char**) — 结果 JSON,SDK 分配;未完成时不会写入

返回值:

  • int32_tDARRA_OK 已完成;DARRA_BUSY 仍在跑或被挤掉

示例:

char* json = NULL;
int32_t rc = darra_pool_try_wait(pool, ticket, &json);
if (rc == DARRA_BUSY) {
/* 仍在队列或推理,稍后再试 */
} else if (rc == DARRA_OK) {
darra_string_free(json);
}

关闭

darra_pool_close()

void darra_pool_close(darra_pool* pool);

关闭池:拒新任务、等在飞 Infer 结束、关全部会话。NULL 安全。close 后句柄失效,再用 = 未定义行为。禁止与 submit / wait / try_wait 并发。

参数:

  • pool (darra_pool*) — 要关闭的池;NULL 安全

示例:

darra_pool_close(pool);

完整示例

突发进图:队列 ≥ 张数,overflow=BLOCKmax_workers 硬顶 8,这里用 2。

#include <stdio.h>
#include <string.h>
#include "darra_ai.h"

int main(void) {
darra_pool_options opt;
memset(&opt, 0, sizeof(opt));
opt.size = sizeof(opt);
opt.max_workers = 2;
opt.queue_capacity = 128;
opt.overflow = DARRA_OVERFLOW_BLOCK;
opt.worker.size = sizeof(opt.worker);
opt.worker.gpu_device = 0;

darra_pool* pool = NULL;
int32_t rc = darra_pool_open("inspect.darmodel", NULL, NULL, NULL, &opt, &pool);
if (rc != DARRA_OK) {
darra_error_t err; err.size = sizeof(err);
darra_last_error(&err);
fprintf(stderr, "[%d] %s\n建议: %s\n", err.code, err.message, err.hint);
return (int)rc;
}

darra_image_desc desc;
memset(&desc, 0, sizeof(desc));
desc.size = sizeof(desc);
desc.format = DARRA_IMAGE_AUTO;

uint64_t ticket = 0;
rc = darra_pool_submit(pool, jpeg_bytes, jpeg_len, &desc, &ticket);
if (rc != DARRA_OK) {
darra_pool_close(pool);
return (int)rc;
}

char* json = NULL;
rc = darra_pool_wait(pool, ticket, &json);
if (rc == DARRA_OK) {
puts(json);
darra_string_free(json);
}

darra_pool_close(pool);
return (int)rc;
}

同卡两个模型:先定槽再按 weight 分。

darra_sched_set_gpu_slots(0, 4);

darra_pool_options det;
memset(&det, 0, sizeof(det));
det.size = sizeof(det);
det.max_workers = 2;
det.weight = 70;
det.worker.size = sizeof(det.worker);
det.worker.gpu_device = 0;

darra_pool_options cls;
memset(&cls, 0, sizeof(cls));
cls.size = sizeof(cls);
cls.max_workers = 1;
cls.weight = 30;
cls.worker.size = sizeof(cls.worker);
cls.worker.gpu_device = 0;

darra_pool* detect = NULL;
darra_pool* classify = NULL;
darra_pool_open("detect.darmodel", NULL, NULL, NULL, &det, &detect);
darra_pool_open("cls.darmodel", NULL, NULL, NULL, &cls, &classify);