diff --git a/CMake/julia/AppendSerialization.cmake b/CMake/julia/AppendSerialization.cmake index 08e248c757..bce65ac507 100644 --- a/CMake/julia/AppendSerialization.cmake +++ b/CMake/julia/AppendSerialization.cmake @@ -69,8 +69,8 @@ function(append_serialization SERIALIZATION_FILE PROGRAM_NAME PROGRAM_MAIN_FILE) "${SERIALIZATION_FILE}" "serialize(stream::IO, model::${MODEL_SAFE_TYPE}Ptr) =\n" " _Internal.${PROGRAM_NAME}_internal.serialize${MODEL_SAFE_TYPE}Ptr(stream, model)\n" - "deserialize!(model::${MODEL_SAFE_TYPE}Ptr, stream::IO) =\n" - " model = _Internal.${PROGRAM_NAME}_internal.deserialize${MODEL_SAFE_TYPE}Ptr(stream)\n" + "_deserialize_internal(model::${MODEL_SAFE_TYPE}Ptr, stream::IO) =\n" + " _Internal.${PROGRAM_NAME}_internal.deserialize${MODEL_SAFE_TYPE}Ptr(stream)\n" "\n") endif () endforeach () diff --git a/CMake/julia/ConfigureJuliaHCPP.cmake b/CMake/julia/ConfigureJuliaHCPP.cmake index 55fff3ad00..4279cf2dc8 100644 --- a/CMake/julia/ConfigureJuliaHCPP.cmake +++ b/CMake/julia/ConfigureJuliaHCPP.cmake @@ -62,7 +62,7 @@ void* CLI_GetParam${MODEL_SAFE_TYPE}Ptr(const char* paramName); // Set the pointer to a ${MODEL_TYPE} parameter. void CLI_SetParam${MODEL_SAFE_TYPE}Ptr(const char* paramName, void* ptr); // Serialize a ${MODEL_TYPE} pointer. -const char* Serialize${MODEL_SAFE_TYPE}Ptr(void* ptr, size_t* length); +char* Serialize${MODEL_SAFE_TYPE}Ptr(void* ptr, size_t* length); // Deserialize a ${MODEL_TYPE} pointer. void* Deserialize${MODEL_SAFE_TYPE}Ptr(const char* buffer, const size_t length); ") @@ -88,11 +88,16 @@ const char* Serialize${MODEL_SAFE_TYPE}Ptr(void* ptr, size_t* length) std::ostringstream oss; { boost::archive::binary_oarchive oa(oss); - oa << ((${MODEL_TYPE}*) ptr); + oa << boost::serialization::make_nvp(\"${MODEL_SAFE_TYPE}\", ((${MODEL_TYPE}*) ptr); } *length = oss.str().length(); - return oss.str().data(); + + // Copy the string buffer so we can return one that won't get deallocated when + // we exit this function. Julia will be responsible for freeing this. + char* buffer = new char[*length]; + memcpy(buffer, oss.str().data(), *length); + return buffer; } // Deserialize a ${MODEL_TYPE} pointer. @@ -103,9 +108,10 @@ void* Deserialize${MODEL_SAFE_TYPE}Ptr(const char* buffer, const size_t length) std::istringstream iss(std::string(buffer, length)); { boost::archive::binary_iarchive ia(iss); - ia >> boost::serialization::make_nvp(\"${MODEL_SAFE_TYPE}\", *t); + ia >> boost::serialization::make_nvp(\"${MODEL_SAFE_TYPE}\", t); } + // Julia will be responsible for freeing this. return (void*) t; } ") diff --git a/src/mlpack/bindings/julia/CMakeLists.txt b/src/mlpack/bindings/julia/CMakeLists.txt index 935b5d604f..323e33f5c3 100644 --- a/src/mlpack/bindings/julia/CMakeLists.txt +++ b/src/mlpack/bindings/julia/CMakeLists.txt @@ -73,6 +73,10 @@ if (BUILD_JULIA_BINDINGS) "${CMAKE_BINARY_DIR}/src/mlpack/bindings/julia/mlpack/src/serialization.jl" "# This file imports all serialization and deserialization functions\n" "# from internal modules." + "\n\n" + "# Deserialize an mlpack model type. This passes to other functions.\n" + "function deserialize(t::Type, stream::IO) = " + "_deserialize_internal(t(0), stream))" "\n\n") endif () diff --git a/src/mlpack/bindings/julia/print_param_defn.hpp b/src/mlpack/bindings/julia/print_param_defn.hpp index 377878bc97..6616a43ac2 100644 --- a/src/mlpack/bindings/julia/print_param_defn.hpp +++ b/src/mlpack/bindings/julia/print_param_defn.hpp @@ -69,8 +69,11 @@ void PrintParamDefn( // end // // function serializePtr(stream::IO, model::Ptr) + // buf_len = UInt[0] // buffer = ccall((:SerializePtr, Library), - // Vector{UInt8}, (Ptr{Nothing},), model.ptr) + // Vector{UInt8}, (Ptr{Nothing}, Ptr{UInt8}), model.ptr, + // Base.pointer(buf_len)) + // buf = Base.unsafe_wrap(buf_ptr, buf_len[0]; own=true) // write(stream, buf) // end // @@ -112,11 +115,11 @@ void PrintParamDefn( std::cout << "# Serialize a model to the given stream." << std::endl; std::cout << "function serialize" << type << "Ptr(stream::IO, model::" << type << "Ptr)" << std::endl; - std::cout << " buf_len::UInt = 0" << std::endl; + std::cout << " buf_len = UInt[0]" << std::endl; std::cout << " buf_ptr = ccall((:Serialize" << type << "Ptr, " << programName - << "Library), Ptr{UInt8}, (Ptr{Nothing}, Ref{UInt}), model.ptr, " - << "Ref(buf_len))" << std::endl; - std::cout << " buf = Base.unsafe_wrap(buf_ptr, buf_len; own=true)" + << "Library), Ptr{UInt8}, (Ptr{Nothing}, Ptr{UInt}), model.ptr, " + << "Base.pointer(buf_len))" << std::endl; + std::cout << " buf = Base.unsafe_wrap(buf_ptr, buf_len[0]; own=true)" << std::endl; std::cout << " write(stream, buf)" << std::endl; std::cout << "end" << std::endl;