gotch/ts/error.go

51 lines
1.3 KiB
Go
Raw Permalink Normal View History

2022-03-12 07:20:20 +00:00
package ts
2020-06-02 10:29:24 +01:00
2020-06-03 02:03:38 +01:00
// #include <stdlib.h>
import "C"
import (
"fmt"
"runtime/debug"
2020-06-03 02:03:38 +01:00
"unsafe"
2024-04-21 15:15:00 +01:00
lib "git.andr3h3nriqu3s.com/andr3/gotch/libtch"
2020-06-03 02:03:38 +01:00
)
// ptrToString check C pointer for null. If not null, get value
// the pointer points to and frees up C memory. It is used for
// getting error message C pointer points to and clean up C memory.
//
2020-06-03 02:03:38 +01:00
// NOTE: C does not have exception design. C++ throws exception
// to stderr. This code to check stderr for any err message,
// if it exists, takes it and frees up C memory.
2020-06-03 02:03:38 +01:00
func ptrToString(cptr *C.char) string {
var str string = ""
2020-06-03 02:03:38 +01:00
if cptr != nil {
str = C.GoString(cptr)
2020-06-03 02:03:38 +01:00
C.free(unsafe.Pointer(cptr))
}
return str
2020-06-03 02:03:38 +01:00
}
// TorchErr checks and retrieves last error message from
// C `thread_local` if existing and frees up C memory the C pointer
// points to.
//
// NOTE: Go language atm does not have generic function something
// similar to `macro` in Rust language, does it? So we have to
// wrap this function to any Libtorch C function call to check error
// instead of doing the other way around.
// See Go2 proposal: https://github.com/golang/go/issues/32620
func TorchErr() error {
cptr := (*C.char)(lib.GetAndResetLastErr())
errStr := ptrToString(cptr)
if errStr != "" {
trace := string(debug.Stack())
return fmt.Errorf("Libtorch API Error: %v\n%v\n", errStr, trace)
2020-06-03 02:03:38 +01:00
}
return nil
}