Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GSoC 6-7 #8

Merged
merged 15 commits into from
Jul 21, 2020
10 changes: 8 additions & 2 deletions CMake/FindRModule.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ function(find_r_module module)
OUTPUT_VARIABLE _${module}_location
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)

# Some cleanup in location of R Module.
string(REGEX MATCHALL "\".*\"" _${module}_location "${_${module}_location}" )
string(REGEX REPLACE "\"" "" _${module}_location "${_${module}_location}" )

if (NOT _${module}_status)
# Now we have to check the version.
if (VERSION_REQ)
Expand All @@ -25,8 +29,10 @@ function(find_r_module module)
string(REGEX REPLACE "‘" "" _version_compare "${_version_compare}")
string(REGEX REPLACE "’" "" _version_compare "${_version_compare}")
if ("${_version_compare}" GREATER_EQUAL "${VERSION_REQ}")
set(R_${module_upper} ${_${module}_location} CACHE STRING
"Location of R module ${module}")
set(R_${module_upper}
"${_${module}_location} (found suitable version \"${_version_compare}\", minimum required is \"${VERSION_REQ}\")"
CACHE STRING "Location of R module ${module}"
)
else ()
message(WARNING "Unsuitable version of R module ${module} (${VERSION_REQ} or greater required).")
endif ()
Expand Down
2 changes: 1 addition & 1 deletion CMake/R/AppendSerialization.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#
# * PROGRAM_MAIN_FILE: the file containing the mlpackMain() function.
# * SERIALIZATION_FILE: file to append types to
# * SERIALIZE: It is of bool type. If SERIALIZE is true we have to print
# * SERIALIZE: It is of bool type. If SERIALIZE is true we have to print
# Serialize, else Deserialize.
#
function(append_serialization SERIALIZATION_FILE PROGRAM_MAIN_FILE SERIALIZE)
Expand Down
10 changes: 5 additions & 5 deletions CMake/R/ConfigureRCPP.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ 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 CLI_GetParam${MODEL_SAFE_TYPE}Ptr(const std::string& paramName)
SEXP IO_GetParam${MODEL_SAFE_TYPE}Ptr(const std::string& paramName)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking the time to do this---I know it is a bit of a tedious refactoring. :)

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)

{
return std::move((${MODEL_PTR_TYPEDEF}) CLI::GetParam<${MODEL_TYPE}*>(paramName));
return std::move((${MODEL_PTR_TYPEDEF}) IO::GetParam<${MODEL_TYPE}*>(paramName));
}

// Set the pointer to a ${MODEL_TYPE} parameter.
// [[Rcpp::export]]
void CLI_SetParam${MODEL_SAFE_TYPE}Ptr(const std::string& paramName, SEXP ptr)
void IO_SetParam${MODEL_SAFE_TYPE}Ptr(const std::string& paramName, SEXP ptr)
{
CLI::GetParam<${MODEL_TYPE}*>(paramName) = Rcpp::as<${MODEL_PTR_TYPEDEF}>(ptr);
CLI::SetPassed(paramName);
IO::GetParam<${MODEL_TYPE}*>(paramName) = Rcpp::as<${MODEL_PTR_TYPEDEF}>(ptr);
IO::SetPassed(paramName);
}

// Serialize a ${MODEL_TYPE} pointer.
Expand Down
2 changes: 1 addition & 1 deletion doc/guide/cli_quickstart.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ The example above has only shown a little bit of the functionality of mlpack.
Lots of other commands are available with different functionality. A full list
of commands and full documentation for each can be found on the following page:

- <a href="https://mlpack.org/doc/mlpack-git/cli_documentation.html">IO documentation</a>
- <a href="https://mlpack.org/doc/mlpack-git/cli_documentation.html">CLI documentation</a>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhh, thank you. Actually do you want to submit this one as a patch batch to the mlpack repository?


For more information on what mlpack does, see https://www.mlpack.org/. Next,
let's go through another example for providing movie recommendations with
Expand Down
6 changes: 3 additions & 3 deletions doc/guide/iodoc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ once that is done, it will call \c mlpackMain().

@code
#include <mlpack/core.hpp>
#include <mlpack/core/util/cli.hpp>
#include <mlpack/core/util/io.hpp>
// This definition below means we will only compile for the command line.
#define BINDING_TYPE BINDING_TYPE_CLI
#include <mlpack/core/util/mlpack_main.hpp>
Expand Down Expand Up @@ -117,7 +117,7 @@ Aborted
These four outputs can be very useful for both providing informational output
and debugging output for your mlpack program.

@section simplecli Simple IO Example
@section simpleio Simple IO Example

Through the mlpack::IO object, command-line parameters can be easily added
with the PROGRAM_INFO, PARAM_INT, PARAM_DOUBLE, PARAM_STRING, and PARAM_FLAG
Expand All @@ -128,7 +128,7 @@ Here is a sample use of those macros, extracted from methods/pca/pca_main.cpp.

@code
#include <mlpack/core.hpp>
#include <mlpack/core/util/cli.hpp>
#include <mlpack/core/util/io.hpp>
#include <mlpack/core/util/mlpack_main.hpp>

// Document program.
Expand Down
2 changes: 1 addition & 1 deletion doc/guide/timer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Below is a very simple example of timer usage in code.

@code
#include <mlpack/core.hpp>
#include <mlpack/core/util/cli.hpp>
#include <mlpack/core/util/io.hpp>
#define BINDING_TYPE BINDING_TYPE_CLI
#include <mlpack/core/util/mlpack_main.hpp>

Expand Down
2 changes: 1 addition & 1 deletion src/mlpack/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ if (BUILD_R_BINDINGS)
foreach(r_src_file ${R_SRC_FILES})
if ("${r_src_file}" MATCHES "methods/" OR
"${r_src_file}" MATCHES "core/" OR
"${r_src_file}" MATCHES "bindings/utils" )
"${r_src_file}" MATCHES "bindings/util" )
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/${r_src_file}
Expand Down
37 changes: 24 additions & 13 deletions src/mlpack/bindings/R/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,32 @@ if (BUILD_R_BINDINGS)
# Import find_r_module.
include(${CMAKE_SOURCE_DIR}/CMake/FindRModule.cmake)

# If mlpack upgrade the version of dependencies, then we also have to update the version here.
set(RcppArmadillo_Version "0.8.400.0.0")
set(RcppEnsmallen_Version "0.2.10.0")
set(BH_Version "1.58.0")

## We need to check here if R is even available. Although actually
## technically, I'm not sure if we even need to know! For the tests though we
## do. So it's probably a good idea to check.
if (FORCE_BUILD_R_BINDINGS)
find_package(R 3.2)
find_package(R 3.5)
find_r_module(roxygen2)
find_r_module(Rcpp)
find_r_module(RcppArmadillo)
find_r_module(RcppEnsmallen)
find_r_module(BH)
find_r_module(Rcpp 0.12.12)
find_r_module(RcppArmadillo "${RcppArmadillo_Version}")
find_r_module(RcppEnsmallen "${RcppEnsmallen_Version}")
find_r_module(BH "${BH_Version}")
if (NOT R_FOUND OR NOT R_RCPP OR NOT R_RCPPARMADILLO OR NOT R_RCPPENSMALLEN OR NOT R_BH OR NOT R_ROXYGEN2)
unset(BUILD_R_BINDINGS CACHE)
message(FATAL_ERROR "Could not Build R Bindings")
endif()
else ()
find_package(R 3.2)
find_package(R 3.5)
find_r_module(roxygen2)
find_r_module(Rcpp)
find_r_module(RcppArmadillo)
find_r_module(RcppEnsmallen)
find_r_module(BH)
find_r_module(Rcpp 0.12.12)
find_r_module(RcppArmadillo "${RcppArmadillo_Version}")
find_r_module(RcppEnsmallen "${RcppEnsmallen_Version}")
find_r_module(BH "${BH_Version}")
if (NOT R_FOUND OR NOT R_RCPP OR NOT R_RCPPARMADILLO OR NOT R_RCPPENSMALLEN OR NOT R_BH OR NOT R_ROXYGEN2)
unset(BUILD_R_BINDINGS CACHE)
endif()
Expand Down Expand Up @@ -80,7 +85,8 @@ if (BUILD_R_BINDINGS)
string(TIMESTAMP PACKAGE_DATE "%Y-%m-%d")

configure_file(${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/mlpack/DESCRIPTION.in
${CMAKE_CURRENT_BINARY_DIR}/mlpack/DESCRIPTION)
${CMAKE_CURRENT_BINARY_DIR}/mlpack/DESCRIPTION
@ONLY)

# Create the empty NAMESPACE file that will include all export functions.
file(WRITE
Expand Down Expand Up @@ -129,8 +135,13 @@ if (BUILD_R_BINDINGS)

set(BINDINGS_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/get_type.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/ignore_check.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/print_doc.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/print_doc_functions.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/print_doc_functions_impl.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/print_input_param.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/get_param.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/get_printable_param.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/get_r_type.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/print_input_processing.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/print_output_processing.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/print_serialize_util.hpp"
Expand Down Expand Up @@ -247,7 +258,7 @@ if (BUILD_R_BINDINGS)
add_dependencies(R r_build)
endif ()

# Define a global list of models, use for building serialization.R file.
# Define a global list of models, use for building serialization.R file.
define_property(GLOBAL PROPERTY R_MODELS
BRIEF_DOCS "Global list of models"
FULL_DOCS "Global list of models"
Expand Down
34 changes: 23 additions & 11 deletions src/mlpack/bindings/R/R_option.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
#ifndef MLPACK_BINDINGS_R_R_OPTION_HPP
#define MLPACK_BINDINGS_R_R_OPTION_HPP
#include <mlpack/core/util/param_data.hpp>
#include "get_param.hpp"
#include "get_printable_param.hpp"
#include "print_input_param.hpp"
#include "print_input_processing.hpp"
#include "print_output_processing.hpp"
#include "print_doc.hpp"
#include "print_serialize_util.hpp"

namespace mlpack {
Expand All @@ -30,7 +33,7 @@ class ROption
public:
/**
* Construct a ROption object. When constructed, it will register itself
* with CLI. The testName parameter is not used and added for compatibility
* with IO. The testName parameter is not used and added for compatibility
* reasons.
*
* @param defaultValue Default value this parameter will be initialized to
Expand All @@ -56,7 +59,7 @@ class ROption
const bool noTranspose = false,
const std::string& /* testName */ = "")
{
// Create the ParamData object to give to CLI.
// Create the ParamData object to give to IO.
util::ParamData data;
data.desc = description;
data.name = identifier;
Expand All @@ -80,25 +83,34 @@ class ROption

// Restore the parameters for this program.
if (identifier != "verbose")
CLI::RestoreSettings(CLI::ProgramName(), false);
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<T>;
IO::GetSingleton().functionMap[data.tname]["GetPrintableParam"] =
&GetPrintableParam<T>;

// These are used by the R generator.
CLI::GetSingleton().functionMap[data.tname]["PrintInputParam"] =
IO::GetSingleton().functionMap[data.tname]["PrintDoc"] = &PrintDoc<T>;
IO::GetSingleton().functionMap[data.tname]["PrintInputParam"] =
&PrintInputParam<T>;
CLI::GetSingleton().functionMap[data.tname]["PrintOutputProcessing"] =
IO::GetSingleton().functionMap[data.tname]["PrintOutputProcessing"] =
&PrintOutputProcessing<T>;
CLI::GetSingleton().functionMap[data.tname]["PrintInputProcessing"] =
IO::GetSingleton().functionMap[data.tname]["PrintInputProcessing"] =
&PrintInputProcessing<T>;
CLI::GetSingleton().functionMap[data.tname]["PrintSerializeUtil"] =
IO::GetSingleton().functionMap[data.tname]["PrintSerializeUtil"] =
&PrintSerializeUtil<T>;

// Add the ParamData object, then store. This is necessary because we may
// import more than one .so or .o that uses CLI, so we have to keep the options
// 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.
CLI::Add(std::move(data));
IO::Add(std::move(data));
if (identifier != "verbose")
CLI::StoreSettings(CLI::ProgramName());
CLI::ClearSettings();
IO::StoreSettings(IO::ProgramName());
IO::ClearSettings();
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/mlpack/bindings/R/generate_R.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ int main(int /* argc */, char** /* argv */)
{
// All the parameters are registered, but stored, so restore them.
// programName is defined in mlpack_main.hpp.
CLI::RestoreSettings(CLI::ProgramName());
IO::RestoreSettings(IO::ProgramName());

PrintR(*CLI::GetSingleton().doc, "${NAME}");
PrintR(*IO::GetSingleton().doc, "${NAME}");
}
37 changes: 37 additions & 0 deletions src/mlpack/bindings/R/get_param.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* @file bindings/R/get_param.hpp
* @author Yashwant Singh Parihar
*
* Get a parameter for a R binding.
*
* mlpack is free software; you may redistribute it and/or modify it under the
* terms of the 3-clause BSD license. You should have received a copy of the
* 3-clause BSD license along with mlpack. If not, see
* http://www.opensource.org/licenses/BSD-3-Clause for more information.
*/
#ifndef MLPACK_BINDINGS_R_GET_PARAM_HPP
#define MLPACK_BINDINGS_R_GET_PARAM_HPP

#include <mlpack/prereqs.hpp>

namespace mlpack {
namespace bindings {
namespace r {

/**
* All R binding types are exactly what is held in the ParamData, so no
* special handling is necessary.
*/
template<typename T>
void GetParam(util::ParamData& d,
const void* /* input */,
void* output)
{
*((T**) output) = const_cast<T*>(boost::any_cast<T>(&d.value));
}

} // namespace r
} // namespace bindings
} // namespace mlpack

#endif
Loading