diff --git a/CMake/R/ConfigureRCPP.cmake b/CMake/R/ConfigureRCPP.cmake index e728c73d34..c85e14f3a1 100644 --- a/CMake/R/ConfigureRCPP.cmake +++ b/CMake/R/ConfigureRCPP.cmake @@ -35,17 +35,19 @@ if (NOT (MODEL_FILE_TYPE MATCHES "\"${MODEL_SAFE_TYPES}\"")) set(MODEL_PTR_IMPLS "${MODEL_PTR_IMPLS} // Get the pointer to a ${MODEL_TYPE} parameter. // [[Rcpp::export]] -SEXP IO_GetParam${MODEL_SAFE_TYPE}Ptr(const std::string& paramName) +SEXP GetParam${MODEL_SAFE_TYPE}Ptr(SEXP params, const std::string& paramName) { - return std::move((${MODEL_PTR_TYPEDEF}) IO::GetParam<${MODEL_TYPE}*>(paramName)); + util::Params& p = *Rcpp::as>(params); + return std::move((${MODEL_PTR_TYPEDEF}) p.Get<${MODEL_TYPE}*>(paramName)); } // Set the pointer to a ${MODEL_TYPE} parameter. // [[Rcpp::export]] -void IO_SetParam${MODEL_SAFE_TYPE}Ptr(const std::string& paramName, SEXP ptr) +void SetParam${MODEL_SAFE_TYPE}Ptr(SEXP params, const std::string& paramName, SEXP ptr) { - IO::GetParam<${MODEL_TYPE}*>(paramName) = Rcpp::as<${MODEL_PTR_TYPEDEF}>(ptr); - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get<${MODEL_TYPE}*>(paramName) = Rcpp::as<${MODEL_PTR_TYPEDEF}>(ptr); + p.SetPassed(paramName); } // Serialize a ${MODEL_TYPE} pointer. diff --git a/src/mlpack/bindings/R/R_option.hpp b/src/mlpack/bindings/R/R_option.hpp index 77f74c091f..598beb321b 100644 --- a/src/mlpack/bindings/R/R_option.hpp +++ b/src/mlpack/bindings/R/R_option.hpp @@ -47,7 +47,7 @@ class ROption * @param input Whether or not the option is an input option. * @param noTranspose If the parameter is a matrix and this is true, then the * matrix will not be transposed on loading. - * @param * (testName) Is not used and added for compatibility reasons. + * @param bindingName Name of the binding that this parameter is for. */ ROption(const T defaultValue, const std::string& identifier, @@ -57,7 +57,7 @@ class ROption const bool required = false, const bool input = true, const bool noTranspose = false, - const std::string& /* testName */ = "") + const std::string& bindingName = "") { // Create the ParamData object to give to IO. util::ParamData data; @@ -75,36 +75,35 @@ class ROption // Every parameter we'll get from R will have the correct type. data.value = boost::any(defaultValue); - // Restore the parameters for this program. - if (identifier != "verbose") - IO::RestoreSettings(IO::ProgramName(), false); - // Set the function pointers that we'll need. All of these function // pointers will be used by both the program that generates the R, and // also the binding itself. (The binding itself will only use GetParam, // GetPrintableParam, and GetRawParam.) - IO::GetSingleton().functionMap[data.tname]["GetParam"] = &GetParam; - IO::GetSingleton().functionMap[data.tname]["GetPrintableParam"] = - &GetPrintableParam; + IO::AddFunction(data.tname, "GetParam", &GetParam); + IO::AddFunction(data.tname, "GetPrintableParam", &GetPrintableParam); // These are used by the R generator. - IO::GetSingleton().functionMap[data.tname]["PrintDoc"] = &PrintDoc; - IO::GetSingleton().functionMap[data.tname]["PrintInputParam"] = - &PrintInputParam; - IO::GetSingleton().functionMap[data.tname]["PrintOutputProcessing"] = - &PrintOutputProcessing; - IO::GetSingleton().functionMap[data.tname]["PrintInputProcessing"] = - &PrintInputProcessing; - IO::GetSingleton().functionMap[data.tname]["PrintSerializeUtil"] = - &PrintSerializeUtil; + IO::AddFunction(data.tname, "PrintDoc", &PrintDoc); + IO::AddFunction(data.tname, "PrintInputParam", &PrintInputParam); + IO::AddFunction(data.tname, "PrintOutputProcessing", + &PrintOutputProcessing); + IO::AddFunction(data.tname, "PrintInputProcessing", + &PrintInputProcessing); + IO::AddFunction(data.tname, "PrintSerializeUtil", &PrintSerializeUtil); - // Add the ParamData object, then store. This is necessary because we may - // import more than one .so or .o that uses IO, so we have to keep the - // options separate. programName is a global variable from mlpack_main.hpp. - IO::Add(std::move(data)); + // Add the ParamData object. if (identifier != "verbose") - IO::StoreSettings(IO::ProgramName()); - IO::ClearSettings(); + { + IO::AddParameter(bindingName, std::move(data)); + } + else + { + // This is a total hack! + // TODO: remove this when the macro solution in mlpack_main.hpp is fixed. + util::Params p = IO::Parameters(""); + if (p.Parameters().count("verbose") == 0) + IO::AddParameter("", std::move(data)); + } } }; diff --git a/src/mlpack/bindings/R/generate_R.cpp.in b/src/mlpack/bindings/R/generate_R.cpp.in index 632fe554bb..93c5db6b96 100644 --- a/src/mlpack/bindings/R/generate_R.cpp.in +++ b/src/mlpack/bindings/R/generate_R.cpp.in @@ -31,9 +31,8 @@ using namespace mlpack::util; int main(int /* argc */, char** /* argv */) { - // All the parameters are registered, but stored, so restore them. - // programName is defined in mlpack_main.hpp. - IO::RestoreSettings(IO::ProgramName()); + // All the parameters are registered; get a copy of them. + util::Params params = IO::Parameters(STRINGIFY(BINDING_NAME)); - PrintR(IO::GetSingleton().doc, "${NAME}"); + PrintR(params, "${NAME}", STRINGIFY(BINDING_NAME)); } diff --git a/src/mlpack/bindings/R/mlpack/R/matrix_utils.R b/src/mlpack/bindings/R/mlpack/R/matrix_utils.R index b6ae94b132..c2b6def269 100644 --- a/src/mlpack/bindings/R/mlpack/R/matrix_utils.R +++ b/src/mlpack/bindings/R/mlpack/R/matrix_utils.R @@ -38,13 +38,13 @@ mark_categorical_variable = function(x) { # Given some matrix-like x (which should be either a matrix or # data.frame), convert it into a matrix. to_matrix_with_info <- function(x) { - + # Handle transformation transformed_x <- to_matrix(x) # Figure out categoricals info <- mark_categorical_variable(x) - - # Return needed data. + + # Return needed data. return(list("info" = info, "data" = transformed_x)) } diff --git a/src/mlpack/bindings/R/mlpack/src/r_util.cpp b/src/mlpack/bindings/R/mlpack/src/r_util.cpp index 0da7e78bd1..a42eee50a3 100644 --- a/src/mlpack/bindings/R/mlpack/src/r_util.cpp +++ b/src/mlpack/bindings/R/mlpack/src/r_util.cpp @@ -30,271 +30,321 @@ bool inline inplace_transpose(arma::Mat& X) } } -// Call IO::RestoreSettings() for a given program name. +// Create a new util::Params object. // [[Rcpp::export]] -void IO_RestoreSettings(const std::string& programName) +SEXP CreateParams(const std::string& bindingName) { - IO::RestoreSettings(programName); + util::Params* p = new util::Params(IO::Parameters(bindingName)); + std::cout << "create params " << p << "\n"; + return std::move(Rcpp::XPtr(p)); } -// Call IO::SetParam(). +// Create a new util::Timers object. // [[Rcpp::export]] -void IO_SetParamInt(const std::string& paramName, int paramValue) +SEXP CreateTimers() { - IO::GetParam(paramName) = paramValue; - IO::SetPassed(paramName); + util::Timers* t = new util::Timers(); + std::cout << "create timers " << t << "\n"; + return std::move(Rcpp::XPtr(t)); } -// Call IO::SetParam(). +// Call params.Get() to set the value of a parameter. // [[Rcpp::export]] -void IO_SetParamDouble(const std::string& paramName, double paramValue) +void SetParamInt(SEXP params, const std::string& paramName, int paramValue) { - IO::GetParam(paramName) = paramValue; - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get(paramName) = paramValue; + p.SetPassed(paramName); } -// Call IO::SetParam(). +// Call params.Get() to set the value of a parameter. // [[Rcpp::export]] -void IO_SetParamString(const std::string& paramName, std::string& paramValue) +void SetParamDouble(SEXP params, + const std::string& paramName, + double paramValue) { - IO::GetParam(paramName) = paramValue; - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get(paramName) = paramValue; + p.SetPassed(paramName); } -// Call IO::SetParam(). +// Call params.Get() to set the value of a parameter. // [[Rcpp::export]] -void IO_SetParamBool(const std::string& paramName, bool paramValue) +void SetParamString(SEXP params, + const std::string& paramName, + std::string& paramValue) { - IO::GetParam(paramName) = paramValue; - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get(paramName) = paramValue; + p.SetPassed(paramName); } -// Call IO::SetParam>(). +// Call params.Get() to set the value of a parameter. // [[Rcpp::export]] -void IO_SetParamVecString(const std::string& paramName, +void SetParamBool(SEXP params, const std::string& paramName, bool paramValue) +{ + util::Params& p = *Rcpp::as>(params); + p.Get(paramName) = paramValue; + p.SetPassed(paramName); +} + +// Call params.Get>() to set the value of a parameter. +// [[Rcpp::export]] +void SetParamVecString(SEXP params, + const std::string& paramName, const std::vector& str) { - IO::GetParam>(paramName) = std::move(str); - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get>(paramName) = std::move(str); + p.SetPassed(paramName); } -// Call IO::SetParam>(). +// Call params.Get>() to set the value of a parameter. // [[Rcpp::export]] -void IO_SetParamVecInt(const std::string& paramName, +void SetParamVecInt(SEXP params, + const std::string& paramName, const std::vector& ints) { - IO::GetParam>(paramName) = std::move(ints); - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get>(paramName) = std::move(ints); + p.SetPassed(paramName); } -// Call IO::SetParam(). +// Call params.Get() to set the value of a parameter. // [[Rcpp::export]] -void IO_SetParamMat(const std::string& paramName, +void SetParamMat(SEXP params, + const std::string& paramName, const arma::mat& paramValue) { - IO::GetParam(paramName) = paramValue.t(); - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get(paramName) = paramValue.t(); + p.SetPassed(paramName); } -// Call IO::SetParam>(). +// Call params.Get>() to set the value of a parameter. // [[Rcpp::export]] -void IO_SetParamUMat(const std::string& paramName, +void SetParamUMat(SEXP params, + const std::string& paramName, const arma::Mat& paramValue) { - IO::GetParam>(paramName) = paramValue.t(); - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get>(paramName) = paramValue.t(); + p.SetPassed(paramName); } -// Call IO::SetParam(). +// Call params.Get() to set the value of a parameter. // [[Rcpp::export]] -void IO_SetParamRow(const std::string& paramName, +void SetParamRow(SEXP params, + const std::string& paramName, const arma::rowvec& paramValue) { - IO::GetParam(paramName) = std::move(paramValue); - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get(paramName) = std::move(paramValue); + p.SetPassed(paramName); } -// Call IO::SetParam>(). +// Call params.Get>() to set the value of a parameter. // [[Rcpp::export]] -void IO_SetParamURow(const std::string& paramName, +void SetParamURow(SEXP params, + const std::string& paramName, const arma::Row& paramValue) { - IO::GetParam>(paramName) = paramValue - 1; - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get>(paramName) = paramValue - 1; + p.SetPassed(paramName); } -// Call IO::SetParam(). +// Call params.Get() to set the value of a parameter. // [[Rcpp::export]] -void IO_SetParamCol(const std::string& paramName, +void SetParamCol(SEXP params, + const std::string& paramName, const arma::vec& paramValue) { - IO::GetParam(paramName) = std::move(paramValue); - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get(paramName) = std::move(paramValue); + p.SetPassed(paramName); } -// Call IO::SetParam>(). +// Call params.Get>() to set the value of a parameter. // [[Rcpp::export]] -void IO_SetParamUCol(const std::string& paramName, +void SetParamUCol(SEXP params, + const std::string& paramName, const arma::Col& paramValue) { - IO::GetParam>(paramName) = paramValue - 1; - IO::SetPassed(paramName); + util::Params& p = *Rcpp::as>(params); + p.Get>(paramName) = paramValue - 1; + p.SetPassed(paramName); } -// Call IO::SetParam>(). +// Call params.Get>() to set the value +// of a parameter. // [[Rcpp::export]] -void IO_SetParamMatWithInfo(const std::string& paramName, +void SetParamMatWithInfo(SEXP params, + const std::string& paramName, const LogicalVector& dimensions, const arma::mat& paramValue) { + util::Params& p = *Rcpp::as>(params); data::DatasetInfo d(paramValue.n_cols); for (size_t i = 0; i < d.Dimensionality(); ++i) { d.Type(i) = (dimensions[i]) ? data::Datatype::categorical : data::Datatype::numeric; } - std::get<0>(IO::GetParam>( + std::get<0>(p.Get>( paramName)) = std::move(d); - std::get<1>(IO::GetParam>( + std::get<1>(p.Get>( paramName)) = paramValue.t(); - IO::SetPassed(paramName); + p.SetPassed(paramName); } -// Call IO::GetParam(). +// Call p.Get(). // [[Rcpp::export]] -int IO_GetParamInt(const std::string& paramName) +int GetParamInt(SEXP params, const std::string& paramName) { - return IO::GetParam(paramName); + util::Params& p = *Rcpp::as>(params); + return p.Get(paramName); } -// Call IO::GetParam(). +// Call p.Get(). // [[Rcpp::export]] -double IO_GetParamDouble(const std::string& paramName) +double GetParamDouble(SEXP params, const std::string& paramName) { - return IO::GetParam(paramName); + util::Params& p = *Rcpp::as>(params); + return p.Get(paramName); } -// Call IO::GetParam(). +// Call p.Get(). // [[Rcpp::export]] -std::string& IO_GetParamString(const std::string& paramName) +std::string& GetParamString(SEXP params, const std::string& paramName) { - return IO::GetParam(paramName); + util::Params& p = *Rcpp::as>(params); + return p.Get(paramName); } -// Call IO::GetParam(). +// Call p.Get(). // [[Rcpp::export]] -bool IO_GetParamBool(const std::string& paramName) +bool GetParamBool(SEXP params, const std::string& paramName) { - return IO::GetParam(paramName); + util::Params& p = *Rcpp::as>(params); + return p.Get(paramName); } -// Call IO::GetParam>(). +// Call p.Get>(). // [[Rcpp::export]] -const std::vector& IO_GetParamVecString(const - std::string& paramName) +const std::vector& GetParamVecString( + SEXP params, + const std::string& paramName) { - return std::move(IO::GetParam>(paramName)); + util::Params& p = *Rcpp::as>(params); + return std::move(p.Get>(paramName)); } -// Call IO::GetParam>(). +// Call p.Get>(). // [[Rcpp::export]] -const std::vector& IO_GetParamVecInt(const std::string& paramName) +const std::vector& GetParamVecInt(SEXP params, + const std::string& paramName) { - return std::move(IO::GetParam>(paramName)); + util::Params& p = *Rcpp::as>(params); + return std::move(p.Get>(paramName)); } -// Call IO::GetParam(). +// Call p.Get(). // [[Rcpp::export]] -const arma::mat& IO_GetParamMat(const std::string& paramName) +const arma::mat& GetParamMat(SEXP params, const std::string& paramName) { - inplace_transpose(IO::GetParam(paramName)); - return std::move(IO::GetParam(paramName)); + util::Params& p = *Rcpp::as>(params); + inplace_transpose(p.Get(paramName)); + return std::move(p.Get(paramName)); } -// Call IO::GetParam>(). +// Call p.Get>(). // [[Rcpp::export]] -const arma::Mat& IO_GetParamUMat(const std::string& paramName) +const arma::Mat& GetParamUMat(SEXP params, + const std::string& paramName) { - inplace_transpose(IO::GetParam>(paramName)); - return std::move(IO::GetParam>(paramName)); + util::Params& p = *Rcpp::as>(params); + inplace_transpose(p.Get>(paramName)); + return std::move(p.Get>(paramName)); } -// Call IO::GetParam(). +// Call p.Get(). // [[Rcpp::export]] -const arma::vec IO_GetParamRow(const std::string& paramName) +const arma::vec GetParamRow(SEXP params, const std::string& paramName) { - return IO::GetParam(paramName).t(); + util::Params& p = *Rcpp::as>(params); + return p.Get(paramName).t(); } -// Call IO::GetParam>(). +// Call p.Get>(). // [[Rcpp::export]] -const arma::Col IO_GetParamURow(const std::string& paramName) +const arma::Col GetParamURow(SEXP params, + const std::string& paramName) { - return IO::GetParam>(paramName).t() + 1; + util::Params& p = *Rcpp::as>(params); + return p.Get>(paramName).t() + 1; } -// Call IO::GetParam(). +// Call p.Get(). // [[Rcpp::export]] -const arma::rowvec IO_GetParamCol(const std::string& paramName) +const arma::rowvec GetParamCol(SEXP params, const std::string& paramName) { - return IO::GetParam(paramName).t(); + util::Params& p = *Rcpp::as>(params); + return p.Get(paramName).t(); } -// Call IO::GetParam>(). +// Call p.Get>(). // [[Rcpp::export]] -const arma::Row IO_GetParamUCol(const std::string& paramName) +const arma::Row GetParamUCol(SEXP params, + const std::string& paramName) { - return IO::GetParam>(paramName).t() + 1; + util::Params& p = *Rcpp::as>(params); + return p.Get>(paramName).t() + 1; } -// Call IO::GetParam>(). +// Call p.Get>(). // [[Rcpp::export]] -List IO_GetParamMatWithInfo(const std::string& paramName) +List IO_GetParamMatWithInfo(SEXP params, const std::string& paramName) { + util::Params& p = *Rcpp::as>(params); const data::DatasetInfo& d = std::get<0>( - IO::GetParam>(paramName)); + p.Get>(paramName)); const arma::mat& m = std::get<1>( - IO::GetParam>(paramName)).t(); + p.Get>(paramName)).t(); LogicalVector dims(d.Dimensionality()); for (size_t i = 0; i < d.Dimensionality(); ++i) dims[i] = (d.Type(i) == data::Datatype::numeric) ? false : true; - return List::create (Rcpp::Named("Info") = std::move(dims), - Rcpp::Named("Data") = std::move(m)); + return List::create(Rcpp::Named("Info") = std::move(dims), + Rcpp::Named("Data") = std::move(m)); } // Enable verbose output. // [[Rcpp::export]] -void IO_EnableVerbose() +void EnableVerbose() { Log::Info.ignoreInput = false; } // Disable verbose output. // [[Rcpp::export]] -void IO_DisableVerbose() +void DisableVerbose() { Log::Info.ignoreInput = true; } // Reset the state of all timers. // [[Rcpp::export]] -void IO_ResetTimers() +void ResetTimers() { - IO::GetSingleton().timer.Reset(); + Timer::ResetAll(); } // Set an argument as passed to the IO object. // [[Rcpp::export]] -void IO_SetPassed(const std::string& paramName) +void SetPassed(SEXP params, const std::string& paramName) { - IO::SetPassed(paramName); -} - -// Clear settings. -// [[Rcpp::export]] -void IO_ClearSettings() -{ - IO::ClearSettings(); + util::Params& p = *Rcpp::as>(params); + p.SetPassed(paramName); } diff --git a/src/mlpack/bindings/R/print_R.cpp b/src/mlpack/bindings/R/print_R.cpp index 5b089cbd28..8f6e3ed8ab 100644 --- a/src/mlpack/bindings/R/print_R.cpp +++ b/src/mlpack/bindings/R/print_R.cpp @@ -21,20 +21,20 @@ namespace mlpack { namespace bindings { namespace r { - /** * Print the code for a .R binding for an mlpack program to stdout. * - * @param doc Documentation for the binding. + * @param params Instantiated Params object for this binding. * @param functionName Name of the function (i.e. "pca"). + * @param bindingName Name of the binding (as specified by BINDING_NAME). */ -void PrintR(const util::BindingDetails& doc, - const string& functionName) +void PrintR(util::Params& params, + const string& functionName, + const string& bindingName) { - // Restore parameters. - IO::RestoreSettings(doc.programName); + const util::BindingDetails& doc = params.Doc(); - map& parameters = IO::Parameters(); + map& parameters = params.Parameters(); typedef map::iterator ParamIter; // First, let's get a list of input and output options. We'll take two passes @@ -68,7 +68,7 @@ void PrintR(const util::BindingDetails& doc, // Print the documentation. // Print programName as @title. cout << "#' @title "; - cout << util::HyphenateString(doc.programName, "#' ") << endl; + cout << util::HyphenateString(doc.name, "#' ") << endl; cout << "#'" << endl; // Next print the short description as @description. @@ -85,7 +85,7 @@ void PrintR(const util::BindingDetails& doc, util::ParamData& d = parameters.at(opt); bool out = false; - IO::GetSingleton().functionMap[d.tname]["PrintDoc"](d, NULL, (void*) &out); + params.functionMap[d.tname]["PrintDoc"](d, NULL, (void*) &out); cout << endl; } @@ -101,7 +101,7 @@ void PrintR(const util::BindingDetails& doc, util::ParamData& d = parameters.at(opt); bool out = true; - IO::GetSingleton().functionMap[d.tname]["PrintDoc"](d, NULL, (void*) &out); + params.functionMap[d.tname]["PrintDoc"](d, NULL, (void*) &out); cout << endl; } @@ -162,36 +162,35 @@ void PrintR(const util::BindingDetails& doc, if (i != 0) cout << "," << endl << std::string(indent, ' '); - IO::GetSingleton().functionMap[d.tname]["PrintInputParam"](d, NULL, NULL); + params.functionMap[d.tname]["PrintInputParam"](d, NULL, NULL); } // Print closing brace for function definition. cout << ") {" << endl; - // Restore IO settings. - cout << " # Restore IO settings." << endl; - cout << " IO_RestoreSettings(\"" << IO::ProgramName() - << "\")" << endl; + // Create timers and parameters objects. + cout << " # Create parameters and timers objects." << endl; + cout << " p <- CreateParams(\"" << bindingName << "\")" << endl; + cout << " t <- CreateTimers()" << endl; cout << endl; - // Handle each input argument's processing before calling mlpackMain(). - cout << " # Process each input argument before calling mlpackMain()." + // Handle each input argument's processing before calling the binding. + cout << " # Process each input argument before calling the binding." << endl; for (const string& opt : inputOptions) { if (opt != "verbose") { util::ParamData& d = parameters.at(opt); - IO::GetSingleton().functionMap[d.tname]["PrintInputProcessing"](d, - NULL, NULL); + params.functionMap[d.tname]["PrintInputProcessing"](d, NULL, NULL); } } // Special handling for verbose output. cout << " if (verbose) {" << endl; - cout << " IO_EnableVerbose()" << endl; + cout << " EnableVerbose()" << endl; cout << " } else {" << endl; - cout << " IO_DisableVerbose()" << endl; + cout << " DisableVerbose()" << endl; cout << " }" << endl; cout << endl; @@ -200,13 +199,13 @@ void PrintR(const util::BindingDetails& doc, for (const string& opt : outputOptions) { util::ParamData& d = parameters.at(opt); - cout << " IO_SetPassed(\"" << d.name << "\")" << endl; + cout << " SetPassed(p, \"" << d.name << "\")" << endl; } cout << endl; // Call the program. cout << " # Call the program." << endl; - cout << " " << functionName << "_mlpackMain()" << endl << endl; + cout << " " << functionName << "_call(p, t)" << endl << endl; // Add ModelType as attr to the model pointer. cout << " # Add ModelType as attribute to the model pointer, if needed." @@ -214,8 +213,7 @@ void PrintR(const util::BindingDetails& doc, for (size_t i = 0; i < outputOptions.size(); ++i) { util::ParamData& d = parameters.at(outputOptions[i]); - IO::GetSingleton().functionMap[d.tname]["PrintSerializeUtil"](d, - NULL, NULL); + params.functionMap[d.tname]["PrintSerializeUtil"](d, NULL, NULL); } cout << endl; @@ -228,17 +226,13 @@ void PrintR(const util::BindingDetails& doc, if (i == 0) cout << indentStr; util::ParamData& d = parameters.at(outputOptions[i]); - IO::GetSingleton().functionMap[d.tname]["PrintOutputProcessing"](d, - NULL, NULL); + params.functionMap[d.tname]["PrintOutputProcessing"](d, NULL, NULL); // Print newlines if we are returning multiple output options. if (i + 1 < outputOptions.size()) cout << "," << endl << indentStr; } cout << endl << " )" << endl << endl; - // Clear the parameters. - cout << " # Clear the parameters." << endl; - cout << " IO_ClearSettings()" << endl; cout << endl; cout << " return(out)" << endl << "}" << endl; } diff --git a/src/mlpack/bindings/R/print_R.hpp b/src/mlpack/bindings/R/print_R.hpp index 76689420cd..a36ab7421d 100644 --- a/src/mlpack/bindings/R/print_R.hpp +++ b/src/mlpack/bindings/R/print_R.hpp @@ -21,11 +21,13 @@ namespace r { /** * Print the code for a .R binding for an mlpack program to stdout. * - * @param doc Documentation for the binding. + * @param params Instantiated Params object for this binding. * @param functionName Name of the function (i.e. "pca"). + * @param bindingName Name of the binding (as specified by BINDING_NAME). */ -void PrintR(const util::BindingDetails& doc, - const std::string& functionName); +void PrintR(util::Params& params, + const std::string& functionName, + const std::string& bindingName); } // namespace r } // namespace bindings diff --git a/src/mlpack/bindings/R/print_doc_functions.hpp b/src/mlpack/bindings/R/print_doc_functions.hpp index 27fafff169..bc67700136 100644 --- a/src/mlpack/bindings/R/print_doc_functions.hpp +++ b/src/mlpack/bindings/R/print_doc_functions.hpp @@ -54,29 +54,33 @@ inline std::string PrintValue(const bool& value, bool quotes); /** * Given a parameter name, print its corresponding default value. */ -inline std::string PrintDefault(const std::string& paramName); +inline std::string PrintDefault(const std::string& bindingName, + const std::string& paramName); /** * Recursion base case. */ -inline std::string PrintInputOptions(); +inline std::string PrintInputOptions(util::Params& /* p */); /** * Print an input option. This will throw an exception if the parameter does * not exist in IO. */ template -std::string PrintInputOptions(const std::string& paramName, +std::string PrintInputOptions(util::Params& p, + const std::string& paramName, const T& value, Args... args); /** * Recursion base case. */ -inline std::string PrintOutputOptions(const bool /* markdown */); +inline std::string PrintOutputOptions(util::Params& /* p */, + const bool /* markdown */); template -std::string PrintOutputOptions(const bool markdown, +std::string PrintOutputOptions(util::Params& p, + const bool markdown, const std::string& paramName, const T& value, Args... args); diff --git a/src/mlpack/bindings/R/print_doc_functions_impl.hpp b/src/mlpack/bindings/R/print_doc_functions_impl.hpp index fab8904eec..0ddfb20d65 100644 --- a/src/mlpack/bindings/R/print_doc_functions_impl.hpp +++ b/src/mlpack/bindings/R/print_doc_functions_impl.hpp @@ -93,16 +93,17 @@ inline std::string PrintValue(const std::vector& value, bool quotes) /** * Given a parameter name, print its corresponding default value. */ -inline std::string PrintDefault(const std::string& paramName) +inline std::string PrintDefault(const std::string& bindingName, + const std::string& paramName) { - if (IO::Parameters().count(paramName) == 0) + util::Params p = IO::Parameters(bindingName); + if (p.Parameters().count(paramName) == 0) throw std::invalid_argument("unknown parameter " + paramName + "!"); - util::ParamData& d = IO::Parameters()[paramName]; + util::ParamData& d = p.Parameters()[paramName]; std::string defaultValue; - IO::GetSingleton().functionMap[d.tname]["DefaultParam"](d, NULL, - (void*) &defaultValue); + p.functionMap[d.tname]["DefaultParam"](d, NULL, (void*) &defaultValue); return defaultValue; } @@ -126,22 +127,23 @@ inline std::string PrintValue(const bool& value, bool quotes) /** * Recursion base case. */ -std::string PrintInputOptions() { return ""; } +std::string PrintInputOptions(util::Params& /* p */) { return ""; } /** * Print an input option. This will throw an exception if the parameter does * not exist in IO. */ template -std::string PrintInputOptions(const std::string& paramName, +std::string PrintInputOptions(util::Params& p, + const std::string& paramName, const T& value, Args... args) { // See if this is part of the program. std::string result = ""; - if (IO::Parameters().count(paramName) > 0) + if (p.Parameters().count(paramName) > 0) { - util::ParamData& d = IO::Parameters()[paramName]; + util::ParamData& d = p.Parameters()[paramName]; if (d.input) { // Print the input option. @@ -160,7 +162,7 @@ std::string PrintInputOptions(const std::string& paramName, } // Continue recursion. - std::string rest = PrintInputOptions(args...); + std::string rest = PrintInputOptions(p, args...); if (rest != "" && result != "") result += ", " + rest; else if (result == "") @@ -172,10 +174,15 @@ std::string PrintInputOptions(const std::string& paramName, /** * Recursion base case. */ -inline std::string PrintOutputOptions(const bool /* markdown */) { return ""; } +inline std::string PrintOutputOptions(util::Params& /* p */, + const bool /* markdown */) +{ + return ""; +} template -std::string PrintOutputOptions(const bool markdown, +std::string PrintOutputOptions(util::Params& p, + const bool markdown, const std::string& paramName, const T& value, Args... args) @@ -183,9 +190,9 @@ std::string PrintOutputOptions(const bool markdown, // See if this is part of the program. std::string result = ""; std::string command_prefix = "R> "; - if (IO::Parameters().count(paramName) > 0) + if (p.Parameters().count(paramName) > 0) { - util::ParamData& d = IO::Parameters()[paramName]; + util::ParamData& d = p.Parameters()[paramName]; if (!d.input) { // Print a new line for the output option. @@ -205,7 +212,7 @@ std::string PrintOutputOptions(const bool markdown, } // Continue recursion. - std::string rest = PrintOutputOptions(markdown, args...); + std::string rest = PrintOutputOptions(p, markdown, args...); if (rest != "" && result != "") result += "\n"; result += rest; @@ -223,26 +230,27 @@ std::string ProgramCall(const bool markdown, const std::string& programName, Args... args) { + util::Params p = IO::Parameters(programName); std::ostringstream oss; if (markdown) oss << "R> "; // Find out if we have any output options first. std::ostringstream ossOutput; - ossOutput << PrintOutputOptions(markdown, args...); + ossOutput << PrintOutputOptions(p, markdown, args...); if (ossOutput.str() != "") oss << "output <- "; oss << programName << "("; // Now process each input option. - oss << PrintInputOptions(args...); + oss << PrintInputOptions(p, args...); oss << ")"; std::string call = oss.str(); oss.str(""); // Reset it. // Now process each output option. - oss << PrintOutputOptions(markdown, args...); + oss << PrintOutputOptions(p, markdown, args...); if (markdown) { if (oss.str() == "") @@ -269,7 +277,8 @@ inline std::string ProgramCall(const std::string& programName) oss << command_prefix; // Determine if we have any output options. - std::map& parameters = IO::Parameters(); + util::Params p = IO::Parameters(programName); + std::map& parameters = p.Parameters(); bool hasOutput = false; for (auto it = parameters.begin(); it != parameters.end(); ++it) { @@ -301,8 +310,8 @@ inline std::string ProgramCall(const std::string& programName) oss << it->second.name << "="; std::string value; - IO::GetSingleton().functionMap[it->second.tname]["DefaultParam"]( - it->second, NULL, (void*) &value); + p.functionMap[it->second.tname]["DefaultParam"]( it->second, NULL, + (void*) &value); oss << value; } oss << ")"; @@ -373,16 +382,20 @@ inline std::string ParamString(const std::string& paramName, const T& value) return oss.str(); } -inline bool IgnoreCheck(const std::string& paramName) +inline bool IgnoreCheck(const std::string& bindingName, + const std::string& paramName) { - return !IO::Parameters()[paramName].input; + util::Params p = IO::Parameters(bindingName); + return !p.Parameters()[paramName].input; } -inline bool IgnoreCheck(const std::vector& constraints) +inline bool IgnoreCheck(const std::string& bindingName, + const std::vector& constraints) { + util::Params p = IO::Parameters(bindingName); for (size_t i = 0; i < constraints.size(); ++i) { - if (!IO::Parameters()[constraints[i]].input) + if (!p.Parameters()[constraints[i]].input) return true; } @@ -390,16 +403,18 @@ inline bool IgnoreCheck(const std::vector& constraints) } inline bool IgnoreCheck( + const std::string& bindingName, const std::vector>& constraints, const std::string& paramName) { + util::Params p = IO::Parameters(bindingName); for (size_t i = 0; i < constraints.size(); ++i) { - if (!IO::Parameters()[constraints[i].first].input) + if (!p.Parameters()[constraints[i].first].input) return true; } - return !IO::Parameters()[paramName].input; + return !p.Parameters()[paramName].input; } } // namespace r diff --git a/src/mlpack/bindings/R/print_input_processing.hpp b/src/mlpack/bindings/R/print_input_processing.hpp index 4565a6d503..7c992b5e80 100644 --- a/src/mlpack/bindings/R/print_input_processing.hpp +++ b/src/mlpack/bindings/R/print_input_processing.hpp @@ -37,7 +37,7 @@ void PrintInputProcessing( * This gives us code like: * * if (!identical(, NA)) { - * IO_SetParam("", ) + * SetParam(p, "", ) * } */ MLPACK_COUT_STREAM << " if (!identical(" << d.name; @@ -49,7 +49,7 @@ void PrintInputProcessing( { MLPACK_COUT_STREAM << ", NA)) {" << std::endl; } - MLPACK_COUT_STREAM << " IO_SetParam" << GetType(d) << "(\"" + MLPACK_COUT_STREAM << " SetParam" << GetType(d) << "(p, \"" << d.name << "\", " << d.name << ")" << std::endl; MLPACK_COUT_STREAM << " }" << std::endl; // Closing brace. } @@ -58,9 +58,9 @@ void PrintInputProcessing( /** * This gives us code like: * - * IO_SetParam("", ) + * SetParam(p, "", ) */ - MLPACK_COUT_STREAM << " IO_SetParam" << GetType(d) << "(\"" + MLPACK_COUT_STREAM << " SetParam" << GetType(d) << "(p, \"" << d.name << "\", " << d.name << ")" << std::endl; } MLPACK_COUT_STREAM << std::endl; // Extra line is to clear up the code a bit. @@ -80,12 +80,12 @@ void PrintInputProcessing( * This gives us code like: * * if (!identical(, NA)) { - * IO_SetParam("", to_matrix()) + * SetParam(p, "", to_matrix()) * } */ MLPACK_COUT_STREAM << " if (!identical(" << d.name << ", NA)) {" << std::endl; - MLPACK_COUT_STREAM << " IO_SetParam" << GetType(d) << "(\"" + MLPACK_COUT_STREAM << " SetParam" << GetType(d) << "(p, \"" << d.name << "\", to_matrix(" << d.name << "))" << std::endl; MLPACK_COUT_STREAM << " }" << std::endl; // Closing brace. } @@ -94,9 +94,9 @@ void PrintInputProcessing( /** * This gives us code like: * - * IO_SetParam("", to_matrix()) + * SetParam(p, "", to_matrix()) */ - MLPACK_COUT_STREAM << " IO_SetParam" << GetType(d) << "(\"" + MLPACK_COUT_STREAM << " SetParam" << GetType(d) << "(p, \"" << d.name << "\", to_matrix(" << d.name << "))" << std::endl; } MLPACK_COUT_STREAM << std::endl; // Extra line is to clear up the code a bit. @@ -118,15 +118,15 @@ void PrintInputProcessing( * * if (!identical(, NA)) { * = to_matrix_with_info() - * IO_SetParam("", $info, - * $data) + * SetParam(p, "", $info, + * $data) * } */ MLPACK_COUT_STREAM << " if (!identical(" << d.name << ", NA)) {" << std::endl; MLPACK_COUT_STREAM << " " << d.name << " <- to_matrix_with_info(" << d.name << ")" << std::endl; - MLPACK_COUT_STREAM << " IO_SetParam" << GetType(d) << "(\"" + MLPACK_COUT_STREAM << " SetParam" << GetType(d) << "(p, \"" << d.name << "\", " << d.name << "$info, " << d.name << "$data)" << std::endl; MLPACK_COUT_STREAM << " }" << std::endl; // Closing brace. @@ -137,12 +137,12 @@ void PrintInputProcessing( * This gives us code like: * * = to_matrix_with_info() - * IO_SetParam("", $info, - * $data) + * SetParam(p, "", $info, + * $data) */ MLPACK_COUT_STREAM << " " << d.name << " <- to_matrix_with_info(" << d.name << ")" << std::endl; - MLPACK_COUT_STREAM << " IO_SetParam" << GetType(d) << "(\"" + MLPACK_COUT_STREAM << " SetParam" << GetType(d) << "(p, \"" << d.name << "\", " << d.name << "$info, " << d.name << "$data)" << std::endl; } @@ -164,13 +164,13 @@ void PrintInputProcessing( * This gives us code like: * * if (!identical(, NA)) { - * IO_SetParamPtr("", ) + * SetParamPtr(p, "", ) * } */ MLPACK_COUT_STREAM << " if (!identical(" << d.name << ", NA)) {" << std::endl; - MLPACK_COUT_STREAM << " IO_SetParam" << util::StripType(d.cppType) - << "Ptr(\"" << d.name << "\", " << d.name << ")" << std::endl; + MLPACK_COUT_STREAM << " SetParam" << util::StripType(d.cppType) + << "Ptr(p, \"" << d.name << "\", " << d.name << ")" << std::endl; MLPACK_COUT_STREAM << " }" << std::endl; // Closing brace. } else @@ -178,10 +178,10 @@ void PrintInputProcessing( /** * This gives us code like: * - * IO_SetParamPtr("", ) + * SetParamPtr(p, "", ) */ - MLPACK_COUT_STREAM << " IO_SetParam" << util::StripType(d.cppType) - << "Ptr(\"" << d.name << "\", " << d.name << ")" << std::endl; + MLPACK_COUT_STREAM << " SetParam" << util::StripType(d.cppType) + << "Ptr(p, \"" << d.name << "\", " << d.name << ")" << std::endl; } MLPACK_COUT_STREAM << std::endl; // Extra line is to clear up the code a bit. } diff --git a/src/mlpack/bindings/R/print_output_processing.hpp b/src/mlpack/bindings/R/print_output_processing.hpp index 3345f6e437..3a470856d4 100644 --- a/src/mlpack/bindings/R/print_output_processing.hpp +++ b/src/mlpack/bindings/R/print_output_processing.hpp @@ -34,12 +34,12 @@ void PrintOutputProcessing( /** * This gives us code like: * - * "" = IO_GetParam("param_name") + * "" = GetParam(p, "param_name") * */ - MLPACK_COUT_STREAM << " \"" << d.name << "\" = IO_GetParam" << GetType(d) - << "(\"" << d.name << "\")"; + MLPACK_COUT_STREAM << " \"" << d.name << "\" = GetParam" << GetType(d) + << "(p, \"" << d.name << "\")"; } /** @@ -55,12 +55,12 @@ void PrintOutputProcessing( /** * This gives us code like: * - * "" = IO_GetParam("param_name") + * "" = GetParam(p, "param_name") * */ - MLPACK_COUT_STREAM << " \"" << d.name << "\" = IO_GetParam" << GetType(d) - << "(\"" << d.name << "\")"; + MLPACK_COUT_STREAM << " \"" << d.name << "\" = GetParam" << GetType(d) + << "(p, \"" << d.name << "\")"; } /** @@ -75,12 +75,12 @@ void PrintOutputProcessing( /** * This gives us code like: * - * "" = IO_GetParam("param_name") + * "" = GetParam(p, "param_name") * */ - MLPACK_COUT_STREAM << " \"" << d.name << "\" = IO_GetParam" << GetType(d) - << "(\"" << d.name << "\")"; + MLPACK_COUT_STREAM << " \"" << d.name << "\" = GetParam" << GetType(d) + << "(p, \"" << d.name << "\")"; } /** diff --git a/src/mlpack/bindings/R/print_serialize_util.hpp b/src/mlpack/bindings/R/print_serialize_util.hpp index a899f2b8ed..da0fa372de 100644 --- a/src/mlpack/bindings/R/print_serialize_util.hpp +++ b/src/mlpack/bindings/R/print_serialize_util.hpp @@ -54,12 +54,12 @@ void PrintSerializeUtil( /** * This gives us code like: * - * <- IO_GetParamPtr("") + * <- GetParamPtr(p, "") * attr(, "type") <- "" * */ - MLPACK_COUT_STREAM << " " << d.name << " <- IO_GetParam" - << util::StripType(d.cppType) << "Ptr(\"" << d.name << "\")"; + MLPACK_COUT_STREAM << " " << d.name << " <- GetParam" + << util::StripType(d.cppType) << "Ptr(p, \"" << d.name << "\")"; MLPACK_COUT_STREAM << std::endl; MLPACK_COUT_STREAM << " attr(" << d.name << ", \"type\") <- \"" << util::StripType(d.cppType) << "\""; diff --git a/src/mlpack/bindings/R/r_method.cpp.in b/src/mlpack/bindings/R/r_method.cpp.in index b9612bce06..68e1928da9 100644 --- a/src/mlpack/bindings/R/r_method.cpp.in +++ b/src/mlpack/bindings/R/r_method.cpp.in @@ -12,9 +12,12 @@ #define Free(p) (R_chk_free( (void *)(p) ), (p) = NULL) // [[Rcpp::export]] -void ${PROGRAM_NAME}_mlpackMain() +void ${PROGRAM_NAME}_call(SEXP params, SEXP timers) { - mlpackMain(); + util::Params& p = *Rcpp::as>(params); + util::Timers& t = *Rcpp::as>(timers); + + BINDING_FUNCTION(p, t); } // Any implementations of methods for dealing with model pointers will be put diff --git a/src/mlpack/bindings/R/tests/test_r_binding_main.cpp b/src/mlpack/bindings/R/tests/test_r_binding_main.cpp index 8bd78992b6..7e90328e95 100644 --- a/src/mlpack/bindings/R/tests/test_r_binding_main.cpp +++ b/src/mlpack/bindings/R/tests/test_r_binding_main.cpp @@ -11,6 +11,12 @@ */ #include #include + +#ifdef BINDING_NAME + #undef BINDING_NAME +#endif +#define BINDING_NAME test_R_binding + #include #include @@ -19,7 +25,7 @@ using namespace mlpack; using namespace mlpack::kernel; // Program Name. -BINDING_NAME("R binding test"); +BINDING_USER_NAME("R binding test"); // Short description. BINDING_SHORT_DESC( @@ -65,110 +71,110 @@ PARAM_MODEL_OUT(GaussianKernel, "model_out", "Output model, with twice the " "bandwidth.", ""); PARAM_DOUBLE_OUT("model_bw_out", "The bandwidth of the model."); -static void mlpackMain() +void BINDING_FUNCTION(util::Params& params, util::Timers& /* timers */) { - const string s = IO::GetParam("string_in"); - const int i = IO::GetParam("int_in"); - const double d = IO::GetParam("double_in"); + const string s = params.Get("string_in"); + const int i = params.Get("int_in"); + const double d = params.Get("double_in"); - IO::GetParam("string_out") = "wrong"; - IO::GetParam("int_out") = 11; - IO::GetParam("double_out") = 3.0; + params.Get("string_out") = "wrong"; + params.Get("int_out") = 11; + params.Get("double_out") = 3.0; // Check that everything is right on the input, and then set output // accordingly. - if (!IO::HasParam("flag2") && IO::HasParam("flag1")) + if (!params.Has("flag2") && params.Has("flag1")) { if (s == "hello") - IO::GetParam("string_out") = "hello2"; + params.Get("string_out") = "hello2"; if (i == 12) - IO::GetParam("int_out") = 13; + params.Get("int_out") = 13; if (d == 4.0) - IO::GetParam("double_out") = 5.0; + params.Get("double_out") = 5.0; } // Input matrices should be at least 5 rows; the 5th row will be dropped and // the 3rd row will be multiplied by two. - if (IO::HasParam("matrix_in")) + if (params.Has("matrix_in")) { - arma::mat out = move(IO::GetParam("matrix_in")); + arma::mat out = move(params.Get("matrix_in")); out.shed_row(4); out.row(2) *= 2.0; - IO::GetParam("matrix_out") = move(out); + params.Get("matrix_out") = move(out); } // Input matrices should be at least 5 rows; the 5th row will be dropped and // the 3rd row will be multiplied by two. - if (IO::HasParam("umatrix_in")) + if (params.Has("umatrix_in")) { arma::Mat out = - move(IO::GetParam>("umatrix_in")); + move(params.Get>("umatrix_in")); out.shed_row(4); out.row(2) *= 2; - IO::GetParam>("umatrix_out") = move(out); + params.Get>("umatrix_out") = move(out); } // An input column or row should have all elements multiplied by two. - if (IO::HasParam("col_in")) + if (params.Has("col_in")) { - arma::vec out = move(IO::GetParam("col_in")); + arma::vec out = move(params.Get("col_in")); out *= 2.0; - IO::GetParam("col_out") = move(out); + params.Get("col_out") = move(out); } - if (IO::HasParam("ucol_in")) + if (params.Has("ucol_in")) { arma::Col out = - move(IO::GetParam>("ucol_in")); + move(params.Get>("ucol_in")); out += 1; - IO::GetParam>("ucol_out") = move(out); + params.Get>("ucol_out") = move(out); } - if (IO::HasParam("row_in")) + if (params.Has("row_in")) { - arma::rowvec out = move(IO::GetParam("row_in")); + arma::rowvec out = move(params.Get("row_in")); out *= 2.0; - IO::GetParam("row_out") = move(out); + params.Get("row_out") = move(out); } - if (IO::HasParam("urow_in")) + if (params.Has("urow_in")) { arma::Row out = - move(IO::GetParam>("urow_in")); + move(params.Get>("urow_in")); out += 1; - IO::GetParam>("urow_out") = move(out); + params.Get>("urow_out") = move(out); } // Vector arguments should have the last element removed. - if (IO::HasParam("vector_in")) + if (params.Has("vector_in")) { - vector out = move(IO::GetParam>("vector_in")); + vector out = move(params.Get>("vector_in")); out.pop_back(); - IO::GetParam>("vector_out") = move(out); + params.Get>("vector_out") = move(out); } - if (IO::HasParam("str_vector_in")) + if (params.Has("str_vector_in")) { - vector out = move(IO::GetParam>("str_vector_in")); + vector out = move(params.Get>("str_vector_in")); out.pop_back(); - IO::GetParam>("str_vector_out") = move(out); + params.Get>("str_vector_out") = move(out); } // All numeric elements should be multiplied by 3. - if (IO::HasParam("matrix_and_info_in")) + if (params.Has("matrix_and_info_in")) { typedef tuple TupleType; - TupleType tuple = move(IO::GetParam("matrix_and_info_in")); + TupleType tuple = move(params.Get("matrix_and_info_in")); const data::DatasetInfo& di = std::get<0>(tuple); arma::mat& m = std::get<1>(tuple); @@ -179,19 +185,19 @@ static void mlpackMain() m.row(i) *= 2.0; } - IO::GetParam("matrix_and_info_out") = move(m); + params.Get("matrix_and_info_out") = move(m); } // If we got a request to build a model, then build it. - if (IO::HasParam("build_model")) + if (params.Has("build_model")) { - IO::GetParam("model_out") = new GaussianKernel(10.0); + params.Get("model_out") = new GaussianKernel(10.0); } // If we got an input model, double the bandwidth and output that. - if (IO::HasParam("model_in")) + if (params.Has("model_in")) { - IO::GetParam("model_bw_out") = - IO::GetParam("model_in")->Bandwidth() * 2.0; + params.Get("model_bw_out") = + params.Get("model_in")->Bandwidth() * 2.0; } } diff --git a/src/mlpack/core/util/mlpack_main.hpp b/src/mlpack/core/util/mlpack_main.hpp index bd690e1560..48a8f178b8 100644 --- a/src/mlpack/core/util/mlpack_main.hpp +++ b/src/mlpack/core/util/mlpack_main.hpp @@ -348,7 +348,8 @@ PARAM_FLAG("verbose", "Display informational messages and the full list of " #define PRINT_DATASET mlpack::bindings::r::PrintDataset #define PRINT_MODEL mlpack::bindings::r::PrintModel #define PRINT_CALL(...) mlpack::bindings::r::ProgramCall(false, __VA_ARGS__) -#define BINDING_IGNORE_CHECK mlpack::bindings::r::IgnoreCheck +#define BINDING_IGNORE_CHECK(...) mlpack::bindings::r::IgnoreCheck( \ + STRINGIFY(BINDING_NAME), __VA_ARGS__) namespace mlpack { namespace util { @@ -359,12 +360,14 @@ using Option = mlpack::bindings::r::ROption; } } -static const std::string testName = ""; #include PARAM_FLAG("verbose", "Display informational messages and the full list of " "parameters and timers at the end of execution.", "v"); +#undef BINDING_FUNCTION +#define BINDING_FUNCTION(...) JOIN(mlpack_, BINDING_NAME)(__VA_ARGS__) + // Nothing else needs to be defined---the binding will use mlpackMain() as-is. #elif BINDING_TYPE == BINDING_TYPE_MARKDOWN