File: ConfigureRCPP.cmake

package info (click to toggle)
mlpack 4.7.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 32,064 kB
  • sloc: cpp: 233,202; python: 1,940; sh: 1,201; lisp: 414; makefile: 85
file content (108 lines) | stat: -rw-r--r-- 3,665 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# ConfigureRCPP.cmake: generate an mlpack .cpp file for a R binding given
# input arguments.
#
# This file depends on the following variables being set:
#
#  * PROGRAM_NAME: name of the binding
#  * PROGRAM_MAIN_FILE: the file containing the mlpackMain() function.
#  * R_CPP_IN: path of the r_method.cpp.in file.
#  * R_CPP_OUT: name of the output .cpp file.
include("${SOURCE_DIR}/CMake/StripType.cmake")
strip_type("${PROGRAM_MAIN_FILE}")

# Extract the required part from *main.cpp.
# Example: mlpack/methods/adaboost/adaboost_main.cpp
string(REGEX REPLACE "${SOURCE_DIR}\\/src\\/" "" INCLUDE_FILE 
    "${PROGRAM_MAIN_FILE}")

file(READ "${MODEL_FILE}" MODEL_FILE_TYPE)
if (NOT (MODEL_FILE_TYPE MATCHES "\"${MODEL_SAFE_TYPES}\""))
  file(APPEND "${MODEL_FILE}" "\"${MODEL_SAFE_TYPES}\"\n")
  # Now, generate the implementation of the functions we need.
  set(MODEL_PTR_IMPLS "")
  list(LENGTH MODEL_TYPES NUM_MODEL_TYPES)
  # Append content to the list.
  if (${NUM_MODEL_TYPES} GREATER 0)
    math(EXPR LOOP_MAX "${NUM_MODEL_TYPES}-1")
    foreach (INDEX RANGE ${LOOP_MAX})
      list(GET MODEL_TYPES ${INDEX} MODEL_TYPE)
      list(GET MODEL_SAFE_TYPES ${INDEX} MODEL_SAFE_TYPE)

      # Define typedef for the model.
      set(MODEL_PTR_TYPEDEF "${MODEL_PTR_TYPEDEF}Rcpp::XPtr<${MODEL_TYPE}>")

      # Generate the implementation.
      set(MODEL_PTR_IMPLS "${MODEL_PTR_IMPLS}
// Get the pointer to a ${MODEL_TYPE} parameter.
// [[Rcpp::export]]
SEXP GetParam${MODEL_SAFE_TYPE}Ptr(SEXP params,
                                   const std::string& paramName,
                                   SEXP inputModels)
{
  util::Params& p = *Rcpp::as<Rcpp::XPtr<util::Params>>(params);
  Rcpp::List inputModelsList(inputModels);
  ${MODEL_TYPE}* modelPtr = p.Get<${MODEL_TYPE}*>(paramName);
  for (int i = 0; i < inputModelsList.length(); ++i)
  {
    ${MODEL_PTR_TYPEDEF} inputModel =
        Rcpp::as<${MODEL_PTR_TYPEDEF}>(inputModelsList[i]);
    // Don't create a new XPtr---just reuse the one given as input, so that we
    // don't end up deleting it twice.
    if (inputModel.get() == modelPtr)
      return inputModel;
  }

  return std::move((${MODEL_PTR_TYPEDEF}) p.Get<${MODEL_TYPE}*>(paramName));
}

// Set the pointer to a ${MODEL_TYPE} parameter.
// [[Rcpp::export]]
void SetParam${MODEL_SAFE_TYPE}Ptr(SEXP params, const std::string& paramName, SEXP ptr)
{
  util::Params& p = *Rcpp::as<Rcpp::XPtr<util::Params>>(params);
  p.Get<${MODEL_TYPE}*>(paramName) = Rcpp::as<${MODEL_PTR_TYPEDEF}>(ptr);
  p.SetPassed(paramName);
}

// Serialize a ${MODEL_TYPE} pointer.
// [[Rcpp::export]]
Rcpp::RawVector Serialize${MODEL_SAFE_TYPE}Ptr(SEXP ptr)
{
  std::ostringstream oss;
  {
    cereal::BinaryOutputArchive oa(oss);
    oa(cereal::make_nvp(\"${MODEL_SAFE_TYPE}\",
          *Rcpp::as<${MODEL_PTR_TYPEDEF}>(ptr)));
  }

  Rcpp::RawVector raw_vec(oss.str().size());

  // Copy the string buffer so we can return one that won't get deallocated when
  // we exit this function.
  memcpy(&raw_vec[0], oss.str().c_str(), oss.str().size());
  raw_vec.attr(\"type\") = \"${MODEL_SAFE_TYPE}\";
  return raw_vec;
}

// Deserialize a ${MODEL_TYPE} pointer.
// [[Rcpp::export]]
SEXP Deserialize${MODEL_SAFE_TYPE}Ptr(Rcpp::RawVector str)
{
  ${MODEL_TYPE}* ptr = new ${MODEL_TYPE}();

  std::istringstream iss(std::string((char *) &str[0], str.size()));
  {
    cereal::BinaryInputArchive ia(iss);
    ia(cereal::make_nvp(\"${MODEL_SAFE_TYPE}\", *ptr));
  }

  // R will be responsible for freeing this.
  return std::move((${MODEL_PTR_TYPEDEF})ptr);
}
")
    endforeach ()
  endif()
endif()

# Now configure the files.
configure_file("${R_CPP_IN}" "${R_CPP_OUT}")