From b6e02ab88cd02e8f8177b931a299a6b765bf1da0 Mon Sep 17 00:00:00 2001 From: Joris Belier Date: Fri, 30 Aug 2024 16:44:31 +0200 Subject: [PATCH] Move memory management into Julia domain using MATFrostMemory concept. --- src/juliacall.jl | 55 +++++++-------------- src/matfrostjuliacall/matfrostjuliacall.cpp | 21 ++++---- 2 files changed, 28 insertions(+), 48 deletions(-) diff --git a/src/juliacall.jl b/src/juliacall.jl index b2d7dc9..9cfa9e7 100644 --- a/src/juliacall.jl +++ b/src/juliacall.jl @@ -14,18 +14,11 @@ module _JuliaCall end struct MATFrostOutput - value::MATFrostArray - data::Any + value::Any exception::Bool - end - - struct MATFrostOutputUnwrap - exception::Bool - value::MATFrostArray - end + end - # module MATFrostPackage - # end + const MATFROSTMEMORY = Dict{MATFrostArray, Any}() function juliacall(mfa::MATFrostArray) @@ -33,8 +26,7 @@ module _JuliaCall fns = [Symbol(unsafe_string(unsafe_load(mfa.fieldnames, i))) for i in 1:mfa.nfields] if !(:package in fns && :func in fns && :args in fns) - s = _ConvertToMATLAB.convert("Not working2" * string(fns)) - return MATFrostOutput(s.matfrostarray, s, false) + throw(MATFrostException("matfrostjulia:incorrectInputSignature", "Missing either field: 'package', 'func' or 'args'.")) end package_i = findfirst(fn -> fn == :package, fns) @@ -88,41 +80,32 @@ module _JuliaCall # The main Julia call vo = func(args...) - vom = _ConvertToMATLAB.convert(vo) - - return MATFrostOutput(vom.matfrostarray, vom, false) + vom = _ConvertToMATLAB.convert(MATFrostOutput(vo, false)) + MATFROSTMEMORY[vom.matfrostarray] = vom + return vom.matfrostarray catch e if isa(e, MATFrostException) - mfe = _ConvertToMATLAB.convert(e) - return MATFrostOutput(mfe.matfrostarray, mfe, true) + mfe = _ConvertToMATLAB.convert(MATFrostOutput(e, true)) + MATFROSTMEMORY[mfe.matfrostarray] = mfe + return mfe.matfrostarray else - s = _ConvertToMATLAB.convert(MATFrostException("matfrostjulia:crashed", sprint(showerror, e, catch_backtrace()))) - return MATFrostOutput(s.matfrostarray, s, true) + mfe = _ConvertToMATLAB.convert(MATfrostOutput(MATFrostException("matfrostjulia:crashed", sprint(showerror, e, catch_backtrace())), true)) + MATFROSTMEMORY[mfe.matfrostarray] = mfe + return mfe.matfrostarray end end - end + end - function juliacall_test(mfa::MATFrostArray) - s = _ConvertToMATLAB.convert("Is this working on Linux?") + juliacall_c() = @cfunction(juliacall, MATFrostArray, (MATFrostArray,)) - MATFrostOutput(s.matfrostarray, s, false) + function freematfrostmemory(mfa::MATFrostArray) + delete!(MATFROSTMEMORY, mfa) + return nothing end - juliacall_c() = @cfunction(juliacall, Any, (MATFrostArray,)) - + freematfrostmemory_c() = @cfunction(freematfrostmemory, Cvoid, (MATFrostArray,)) - unwrap(val::MATFrostOutput) = MATFrostOutputUnwrap(val.exception, val.value) - unwrap_c() = @cfunction(unwrap, MATFrostOutputUnwrap, (Any,)) - - - - test2 = ["SDF", "SDFS", "FD"] - - mfa = MATFrostArray(0, 0, 0, 0, 0, 0) - - test1 = juliacall(mfa) - end diff --git a/src/matfrostjuliacall/matfrostjuliacall.cpp b/src/matfrostjuliacall/matfrostjuliacall.cpp index 79875cc..2a1322c 100644 --- a/src/matfrostjuliacall/matfrostjuliacall.cpp +++ b/src/matfrostjuliacall/matfrostjuliacall.cpp @@ -121,27 +121,24 @@ class MexFunction : public matlab::mex::Function { auto mfa = MATFrost::ConvertToJulia::convert(inputs[0]); - auto juliacall = (jl_value_t* (*)(MATFrostArray)) jl_unbox_voidpointer(jl_eval_string("MATFrost._JuliaCall.juliacall_c()")); - auto unwrap = (MATFrostOutputUnwrap (*)(jl_value_t*)) jl_unbox_voidpointer(jl_eval_string("MATFrost._JuliaCall.unwrap_c()")); + auto juliacall = (MATFrostArray (*)(MATFrostArray)) jl_unbox_voidpointer(jl_eval_string("MATFrost._JuliaCall.juliacall_c()")); + auto freematfrostmemory = (void (*)(MATFrostArray)) jl_unbox_voidpointer(jl_eval_string("MATFrost._JuliaCall.freematfrostmemory_c()")); - jl_value_t* jlo = juliacall(mfa->matfrostarray); + MATFrostArray jlo = juliacall(mfa->matfrostarray); - JL_GC_PUSH1(jlo); + const matlab::data::StructArray mato = MATFrost::ConvertToMATLAB::convert(jlo); - const MATFrostOutputUnwrap mfao = unwrap(jlo); + freematfrostmemory(jlo); - const matlab::data::Array mato = MATFrost::ConvertToMATLAB::convert(mfao.value); - - JL_GC_POP(); - - if (mfao.exception) { - const matlab::data::StructArray matso = mato; + const matlab::data::TypedArray exception_b = mato[0]["exception"]; + if (exception_b[0]) { + const matlab::data::StructArray matso = mato[0]["value"]; const matlab::data::StringArray exception_id = matso[0]["id"]; const matlab::data::StringArray exception_message = matso[0]["message"]; throw matlab::engine::MATLABException(exception_id[0], exception_message[0]); } - outputs[0] = mato; + outputs[0] = mato[0]["value"]; } catch(const matlab::engine::MATLABException& ex)