Skip to content

Commit 39d349d

Browse files
committed
[GenAI] Fix cgo callback pointer handling in genai
- wrap Sequence in cgo.Handle before passing into C callbacks - unwrap handle in goCallbackBridge and delete after generation - prevents cgo “Go pointer to Go pointer” panic during OpenVINO runs - make cgo compatible accross different openvino versions
1 parent 0d51353 commit 39d349d

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

modules/ollama_openvino/genai/genai.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ typedef int (*callback_function)(const char*, void*);
2323
2424
extern int goCallbackBridge(char* input, void* ptr);
2525
26+
// Backward compatibility: older headers used the misspelled STREAMMING constants.
27+
#ifndef OV_GENAI_STREAMING_STATUS_RUNNING
28+
#define OV_GENAI_STREAMING_STATUS_RUNNING OV_GENAI_STREAMMING_STATUS_RUNNING
29+
#endif
30+
#ifndef OV_GENAI_STREAMING_STATUS_STOP
31+
#define OV_GENAI_STREAMING_STATUS_STOP OV_GENAI_STREAMMING_STATUS_STOP
32+
#endif
33+
#ifndef OV_GENAI_STREAMMING_STATUS_RUNNING
34+
#define OV_GENAI_STREAMMING_STATUS_RUNNING OV_GENAI_STREAMING_STATUS_RUNNING
35+
#endif
36+
#ifndef OV_GENAI_STREAMMING_STATUS_STOP
37+
#define OV_GENAI_STREAMMING_STATUS_STOP OV_GENAI_STREAMING_STATUS_STOP
38+
#endif
39+
2640
static ov_status_e ov_genai_llm_pipeline_create_npu_output_2048(const char* models_path,
2741
const char* device,
2842
ov_genai_llm_pipeline** pipe) {
@@ -49,6 +63,7 @@ import (
4963
"os"
5064
"path/filepath"
5165
"strconv"
66+
"runtime/cgo"
5267
"unsafe"
5368
)
5469

@@ -307,7 +322,10 @@ func GenerateTextWithMetrics(pipeline *C.ov_genai_llm_pipeline, input string, sa
307322
var streamer_callback C.streamer_callback
308323
streamer_callback.callback_func = (C.callback_function)(unsafe.Pointer(C.goCallbackBridge))
309324

310-
streamer_callback.args = unsafe.Pointer(seq)
325+
// Use cgo.Handle to safely pass Go pointer through C without violating cgo rules.
326+
handle := cgo.NewHandle(seq)
327+
defer handle.Delete()
328+
streamer_callback.args = unsafe.Pointer(uintptr(handle))
311329

312330
C.ov_genai_llm_pipeline_start_chat(pipeline)
313331
C.ov_genai_llm_pipeline_generate(pipeline, cInput, (*C.ov_genai_generation_config)(cConfig), &streamer_callback, &result)
@@ -402,7 +420,8 @@ func GetOvVersion() {
402420
func goCallbackBridge(args *C.char, gen_result unsafe.Pointer) C.int {
403421
if args != nil {
404422
// 将 unsafe.Pointer 转换回结构体指针
405-
result := (*Sequence)(gen_result)
423+
handle := cgo.Handle(uintptr(gen_result))
424+
result := handle.Value().(*Sequence)
406425

407426
// 将 C 字符串转换为 Go 字符串并追加到切片中
408427
goStr := C.GoString(args)
@@ -411,10 +430,12 @@ func goCallbackBridge(args *C.char, gen_result unsafe.Pointer) C.int {
411430
// fmt.Printf("%s", goStr)
412431
// os.Stdout.Sync()
413432
FlushPending((*Sequence)(result))
414-
return C.OV_GENAI_STREAMMING_STATUS_RUNNING
433+
// return C.OV_GENAI_STREAMMING_STATUS_RUNNING
434+
return C.OV_GENAI_STREAMING_STATUS_RUNNING
415435
} else {
416436
fmt.Println("Callback executed with NULL message!")
417-
return C.OV_GENAI_STREAMMING_STATUS_STOP
437+
// return C.OV_GENAI_STREAMMING_STATUS_STOP
438+
return C.OV_GENAI_STREAMING_STATUS_STOP
418439
}
419440
}
420441

0 commit comments

Comments
 (0)