From 9c48f1649cbdbe42304257e0897baaa59e7aa545 Mon Sep 17 00:00:00 2001 From: Acly Date: Wed, 13 Aug 2025 17:24:41 +0200 Subject: [PATCH 1/2] image: fix missing export --- include/visp/image.h | 2 +- src/visp/vision.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/visp/image.h b/include/visp/image.h index a2b01fd..cb766cb 100644 --- a/include/visp/image.h +++ b/include/visp/image.h @@ -101,7 +101,7 @@ struct image_data { VISP_API image_data image_alloc(i32x2 extent, image_format format); // Set all pixels to zero. -void image_clear(image_span const&); +VISP_API void image_clear(image_span const&); // Load image from file (PNG, JPEG, etc.) VISP_API image_data image_load(char const* filepath); diff --git a/src/visp/vision.cpp b/src/visp/vision.cpp index a743311..7c9c424 100644 --- a/src/visp/vision.cpp +++ b/src/visp/vision.cpp @@ -91,7 +91,7 @@ birefnet_model birefnet_load_model(char const* filepath, backend_device const& d image_data birefnet_compute(birefnet_model& model, image_view image) { i32x2 res = birefnet_image_extent(image.extent, model.params); - if (!model.input || res != model.params.image_extent) { + if (!model.graph || res != model.params.image_extent) { model.params.image_extent = res; model.graph = compute_graph_init(6 * 1024); From 2700c140f5380b99054661b7f8c3132690fb7271 Mon Sep 17 00:00:00 2001 From: Acly Date: Wed, 13 Aug 2025 21:30:36 +0200 Subject: [PATCH 2/2] birefnet: make sure pre-computed buffer memory is not reused for intermediate graph results --- src/visp/arch/birefnet.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/visp/arch/birefnet.cpp b/src/visp/arch/birefnet.cpp index 9c9ad37..43bee9b 100644 --- a/src/visp/arch/birefnet.cpp +++ b/src/visp/arch/birefnet.cpp @@ -16,6 +16,14 @@ tensor mlp(model_ref m, tensor x) { return named(m, x); } +// Ensures that the tensor's data is not overwritten during computation. +tensor make_constant(tensor x, tensor_name name) { + ggml_set_name(x, name.c_str()); + ggml_set_input(x); // allocate at the beginning of the graph buffer + ggml_set_output(x); // don't reuse memory for computations + return x; +} + void compute_relative_position_index(span dst, int window_size) { int n = window_size; int n2 = n * n; @@ -34,7 +42,7 @@ tensor_data create_relative_position_index(ggml_context* ctx, int window_size) { auto result = tensor_alloc(ggml_new_tensor_1d(ctx, GGML_TYPE_I32, n * n * n * n)); auto name = format("window_attention_{}.rel_pos_index", n); compute_relative_position_index(result.as_i32(), n); - ggml_set_name(result.x, name.c_str()); + make_constant(result.x, name); return result; } @@ -226,7 +234,7 @@ tensor_data create_attention_mask(ggml_context* ctx, int64_t w, int64_t h, int w auto result = tensor_alloc(ggml_new_tensor_3d(ctx, GGML_TYPE_F32, n * n, n * n, nw_x * nw_y)); auto name = format("swin_layer_{}x{}.attn_mask", w, h); compute_attention_mask(result.as_f32(), w, h, window_size); - ggml_set_name(result.x, name.c_str()); + make_constant(result.x, name); return result; }