Merge remote-tracking branch 'origin/master' into negative-log-likelihood-numclasses
This commit is contained in:
+13
-51
@@ -1,16 +1,10 @@
|
||||
clone_depth: 10
|
||||
|
||||
environment:
|
||||
BOOST_PROG_OPTION : "C:/projects/mlpack/\
|
||||
boost_program_options-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*"
|
||||
BOOST_MATH : "C:/projects/mlpack/\
|
||||
boost_math_c99-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*"
|
||||
BOOST_RANDOM : "C:/projects/mlpack/\
|
||||
boost_random-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*"
|
||||
BOOST_SERIALIZATION : "C:/projects/mlpack/\
|
||||
boost_serialization-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*"
|
||||
BOOST_UNIT_TEST : "C:/projects/mlpack/\
|
||||
boost_unit_test_framework-vc140.1.60.0.0/lib/native/address-model-64/lib/*.*"
|
||||
ARMADILLO_DOWNLOAD : "https://data.kurg.org/armadillo-8.400.0.tar.xz"
|
||||
ARMADILLO_LIBRARY : "C:/projects/mlpack/armadillo-8.400.0/\
|
||||
build/Debug/armadillo.lib"
|
||||
@@ -22,50 +16,36 @@ environment:
|
||||
JENKINS_DOC : "C:/projects/mlpack/dist/win-installer/jenkinsdoc.zip"
|
||||
GIT_VERSION_FILE : "C:/projects/mlpack/src/mlpack/core/util/gitversion.hpp"
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
VSVER: Visual Studio 14 2015 Win64
|
||||
MSBUILD: C:\Program Files (x86)\MSBuild\14.0\bin\MSBuild.exe
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
VSVER: Visual Studio 15 2017 Win64
|
||||
MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe
|
||||
# Currently, the VS2019 build seems to always time out. This seems to be an
|
||||
# AppVeyor issue.
|
||||
# - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
# VSVER: Visual Studio 16 2019
|
||||
# MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
VSVER: Visual Studio 16 2019
|
||||
MSBUILD: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe
|
||||
|
||||
# We have removed the VS studio 15 2017 build since it is not possible to complete
|
||||
# or finish the build due to the `compiler out of heap space issues`.
|
||||
# Therefore, in the meanwhile, we are only doing the installation for VS 16 2019.
|
||||
|
||||
configuration: Release
|
||||
|
||||
os: Visual Studio 2015
|
||||
os: Visual Studio 2019
|
||||
|
||||
install:
|
||||
- ps: nuget install boost -o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0
|
||||
- ps: >
|
||||
nuget install boost_unit_test_framework-vc140
|
||||
-o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0
|
||||
- ps: >
|
||||
nuget install boost_program_options-vc140
|
||||
-o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0
|
||||
- ps: >
|
||||
nuget install boost_random-vc140
|
||||
-o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0
|
||||
- ps: >
|
||||
nuget install boost_serialization-vc140
|
||||
-o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0
|
||||
- ps: >
|
||||
nuget install boost_math_c99-vc140
|
||||
-o "${env:APPVEYOR_BUILD_FOLDER}" -Version 1.60.0
|
||||
- ps: >
|
||||
nuget install unofficial-flayan-cereal
|
||||
-o "${env:APPVEYOR_BUILD_FOLDER}"
|
||||
- ps: nuget install OpenBLAS -o "${env:APPVEYOR_BUILD_FOLDER}"
|
||||
- set path=C:\Program Files (x86)\WiX Toolset v3.11\bin;%path%
|
||||
|
||||
build_script:
|
||||
- mkdir boost_libs
|
||||
- ps: cp ${env:BOOST_PROG_OPTION} C:\projects\mlpack\boost_libs\
|
||||
- ps: cp ${env:BOOST_MATH} C:\projects\mlpack\boost_libs\
|
||||
- ps: cp ${env:BOOST_RANDOM} C:\projects\mlpack\boost_libs\
|
||||
- ps: cp ${env:BOOST_SERIALIZATION} C:\projects\mlpack\boost_libs\
|
||||
- ps: cp ${env:BOOST_UNIT_TEST} C:\projects\mlpack\boost_libs\
|
||||
- echo TEST_ARMA is %ARMADILLO_DOWNLOAD%
|
||||
- >
|
||||
appveyor DownloadFile %ARMADILLO_DOWNLOAD%
|
||||
@@ -89,12 +69,14 @@ build_script:
|
||||
-DLAPACK_LIBRARIES:FILEPATH=%BLAS_LIBRARY%
|
||||
-DARMADILLO_INCLUDE_DIR="C:/projects/mlpack/armadillo-8.400.0/include"
|
||||
-DARMADILLO_LIBRARY:FILEPATH=%ARMADILLO_LIBRARY%
|
||||
-DCEREAL_INCLUDE_DIR="C:/projects/mlpack/unofficial-flayan-cereal.1.2.2/build/native/include"
|
||||
-DBOOST_INCLUDEDIR:PATH=%BOOST_INCLUDE%
|
||||
-DBOOST_LIBRARYDIR:PATH="C:/projects/mlpack/boost_libs"
|
||||
-DDEBUG=OFF
|
||||
-DPROFILE=OFF
|
||||
-DBUILD_PYTHON_BINDINGS=OFF
|
||||
-DBUILD_GO_BINDINGS=OFF
|
||||
-DBUILD_R_BINDINGS=OFF
|
||||
-DBUILD_TESTS=OFF
|
||||
-DCMAKE_BUILD_TYPE=Release ..
|
||||
- >
|
||||
"%MSBUILD%" "C:\projects\mlpack\build\mlpack.sln"
|
||||
@@ -138,9 +120,6 @@ build_script:
|
||||
- ps: >
|
||||
cp C:\projects\mlpack\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll
|
||||
C:\projects\mlpack\dist\win-installer\staging\
|
||||
- ps: >
|
||||
cp C:\projects\mlpack\boost_libs\boost_unit_test_framework-vc*.dll
|
||||
C:\projects\mlpack\dist\win-installer\staging\
|
||||
- ps: >
|
||||
cp C:\projects\mlpack\build\include\mlpack
|
||||
C:\projects\mlpack\dist\win-installer\staging -recurse
|
||||
@@ -238,20 +217,3 @@ cache:
|
||||
- packages -> **\packages.config
|
||||
- armadillo.tar.xz -> appveyor.yaml
|
||||
|
||||
test_script:
|
||||
# Copy all DLLs into the right place before running the test.
|
||||
- ps: cp C:\projects\mlpack\boost_libs\*.* C:\projects\mlpack\build\
|
||||
- ps: >
|
||||
cp C:\projects\mlpack\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.*
|
||||
C:\projects\mlpack\build\
|
||||
- cd "%APPVEYOR_BUILD_FOLDER%/build/"
|
||||
- >
|
||||
Release\mlpack_test.exe
|
||||
--report_level=detailed
|
||||
--log_level=test_suite --log_format=XML > mlpack_test.xml & exit 0
|
||||
# Attempt to upload results to AppVeyor.
|
||||
- ps: >
|
||||
$wc = New-Object 'System.Net.WebClient';
|
||||
$wc.UploadFile(
|
||||
"https://ci.appveyor.com/api/testresults/xunit/$($env:APPVEYOR_JOB_ID)",
|
||||
(Resolve-Path .\mlpack_test.xml));
|
||||
|
||||
+15
-31
@@ -15,18 +15,20 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
Plain:
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF'
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF'
|
||||
Python:
|
||||
binding: 'python'
|
||||
python.version: '3.7'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DPYTHON_EXECUTABLE=/opt/hostedtoolcache/Python/3.7.7/x64/bin/python3 -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DPYTHON_EXECUTABLE=/usr/bin/python3 -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF'
|
||||
Julia:
|
||||
julia.version: '1.3.0'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_GO_BINDINGS=OFF -DJULIA_EXECUTABLE=/opt/julia-1.3.0/bin/julia'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_GO_BINDINGS=OFF -DJULIA_EXECUTABLE=/opt/julia-1.3.0/bin/julia -DBUILD_R_BINDINGS=OFF'
|
||||
Go:
|
||||
binding: 'go'
|
||||
go.version: '1.11.0'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF'
|
||||
Markdown:
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_MARKDOWN_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_MARKDOWN_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF'
|
||||
|
||||
steps:
|
||||
- template: linux-steps.yaml
|
||||
@@ -34,47 +36,29 @@ jobs:
|
||||
- job: macOS
|
||||
timeoutInMinutes: 360
|
||||
pool:
|
||||
vmImage: macOS-10.14
|
||||
vmImage: macOS-latest
|
||||
strategy:
|
||||
matrix:
|
||||
Plain:
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF'
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF'
|
||||
python.version: '2.7'
|
||||
Python:
|
||||
binding: 'python'
|
||||
python.version: '3.7'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF'
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=ON -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF'
|
||||
Julia:
|
||||
python.version: '2.7'
|
||||
julia.version: '1.3.0'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF'
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_JULIA_BINDINGS=ON -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF'
|
||||
Go:
|
||||
binding: 'go'
|
||||
python.version: '2.7'
|
||||
go.version: '1.11.0'
|
||||
CMakeArgs: '-DDEBUG=OFF -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON'
|
||||
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=ON -DBUILD_R_BINDINGS=OFF'
|
||||
|
||||
steps:
|
||||
- template: macos-steps.yaml
|
||||
|
||||
- job: WindowsVS15
|
||||
timeoutInMinutes: 360
|
||||
displayName: Windows VS15
|
||||
pool:
|
||||
vmImage: vs2017-win2016
|
||||
strategy:
|
||||
matrix:
|
||||
Plain:
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF'
|
||||
python.version: '2.7'
|
||||
CMakeGenerator: '-G "Visual Studio 15 2017 Win64"'
|
||||
MSBuildVersion: '15.0'
|
||||
ArchiveNoLibs: 'mlpack-windows-vs15-no-libs.zip'
|
||||
ArchiveLibs: 'mlpack-windows-vs15.zip'
|
||||
ArchiveTests: 'mlpack_test-vs15.xml'
|
||||
|
||||
steps:
|
||||
- template: windows-steps.yaml
|
||||
|
||||
- job: WindowsVS16
|
||||
timeoutInMinutes: 360
|
||||
displayName: Windows VS16
|
||||
@@ -83,7 +67,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
Plain:
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF'
|
||||
CMakeArgs: '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF'
|
||||
python.version: '2.7'
|
||||
CMakeGenerator: '-G "Visual Studio 16 2019"'
|
||||
MSBuildVersion: '16.0'
|
||||
|
||||
+18
-11
@@ -22,14 +22,14 @@ steps:
|
||||
echo "##vso[task.setvariable variable=BOOST_ROOT]"$BOOST_ROOT
|
||||
|
||||
sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost1.70-dev libarmadillo-dev xz-utils
|
||||
sudo apt-get install -y --allow-unauthenticated python3-pip python3-numpy
|
||||
|
||||
if [ "$(binding)" == "python" ]; then
|
||||
export PYBIN=$(which python)
|
||||
$PYBIN -m pip install --upgrade pip
|
||||
$PYBIN -m pip install --upgrade --ignore-installed setuptools cython pandas
|
||||
fi
|
||||
|
||||
sudo /opt/hostedtoolcache/Python/3.7.7/x64/bin/python3 -m pip install "Cython>0.24"
|
||||
sudo /opt/hostedtoolcache/Python/3.7.7/x64/bin/python3 -m pip install --upgrade --ignore-installed setuptools
|
||||
sudo /opt/hostedtoolcache/Python/3.7.7/x64/bin/python3 -m pip install pandas
|
||||
|
||||
if [ 'a$(julia.version)' != 'a' ]; then
|
||||
if [ "a$(julia.version)" != "a" ]; then
|
||||
wget https://julialang-s3.julialang.org/bin/linux/x64/1.3/julia-1.3.0-linux-x86_64.tar.gz
|
||||
sudo tar -C /opt/ -xvpf julia-1.3.0-linux-x86_64.tar.gz
|
||||
fi
|
||||
@@ -37,25 +37,32 @@ steps:
|
||||
# Install armadillo.
|
||||
curl https://data.kurg.org/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo*
|
||||
cmake . && make && sudo make install && cd ..
|
||||
|
||||
# Install cereal.
|
||||
wget https://github.com/USCiLab/cereal/archive/v1.3.0.tar.gz
|
||||
tar -xvzpf v1.3.0.tar.gz # Unpack into cereal-1.3.0/.
|
||||
cd cereal-1.3.0/
|
||||
displayName: 'Install Build Dependencies'
|
||||
|
||||
# Configure mlpack (CMake)
|
||||
- script: |
|
||||
unset BOOST_ROOT
|
||||
mkdir build && cd build
|
||||
export GOPATH=$PWD/src/mlpack/bindings/go
|
||||
go get -u -t gonum.org/v1/gonum/...
|
||||
cmake $(CMakeArgs) ..
|
||||
if [ "$(binding)" == "go" ]; then
|
||||
export GOPATH=$PWD/src/mlpack/bindings/go
|
||||
go get -u -t gonum.org/v1/gonum/...
|
||||
fi
|
||||
cmake $(CMakeArgs) -DPYTHON_EXECUTABLE=`which python` -DCEREAL_INCLUDE_DIR=../cereal-1.3.0/include/ ..
|
||||
displayName: 'CMake'
|
||||
|
||||
# Build mlpack
|
||||
- script: cd build && make
|
||||
condition: eq(variables['CMakeArgs'], '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF')
|
||||
condition: eq(variables['CMakeArgs'], '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF')
|
||||
displayName: 'Build'
|
||||
|
||||
# Build mlpack
|
||||
- script: cd build && make -j2
|
||||
condition: ne(variables['CMakeArgs'], '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF')
|
||||
condition: ne(variables['CMakeArgs'], '-DDEBUG=ON -DPROFILE=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=OFF')
|
||||
displayName: 'Build'
|
||||
|
||||
# Run tests via ctest.
|
||||
|
||||
+17
-7
@@ -12,10 +12,14 @@ steps:
|
||||
# Install Build Dependencies
|
||||
- script: |
|
||||
set -e
|
||||
sudo xcode-select --switch /Applications/Xcode_10.1.app/Contents/Developer
|
||||
sudo xcode-select --switch /Applications/Xcode_12.2.app/Contents/Developer
|
||||
unset BOOST_ROOT
|
||||
pip install cython numpy pandas zipp configparser
|
||||
brew install openblas armadillo boost
|
||||
brew install openblas armadillo boost cereal
|
||||
|
||||
if [ "$(binding)" == "python" ]; then
|
||||
pip install --upgrade pip
|
||||
pip install cython numpy pandas zipp configparser
|
||||
fi
|
||||
|
||||
if [ "a$(julia.version)" != "a" ]; then
|
||||
brew cask install julia
|
||||
@@ -28,10 +32,16 @@ steps:
|
||||
- script: |
|
||||
unset BOOST_ROOT
|
||||
mkdir build && cd build
|
||||
export GOPATH=$PWD/src/mlpack/bindings/go
|
||||
go get -u -t gonum.org/v1/gonum/...
|
||||
export PYPATH=$(which python)
|
||||
cmake $(CMakeArgs) -DPYTHON_EXECUTABLE=$PYPATH ..
|
||||
if [ "$(binding)" == "go" ]; then
|
||||
export GOPATH=$PWD/src/mlpack/bindings/go
|
||||
go get -u -t gonum.org/v1/gonum/...
|
||||
fi
|
||||
if [ "$(binding)" == "python" ]; then
|
||||
export PYPATH=$(which python)
|
||||
cmake $(CMakeArgs) -DPYTHON_EXECUTABLE=$PYPATH ..
|
||||
else
|
||||
cmake $(CMakeArgs) ..
|
||||
fi
|
||||
displayName: 'CMake'
|
||||
|
||||
# Build mlpack
|
||||
|
||||
+58
-8
@@ -10,19 +10,14 @@ steps:
|
||||
- powershell: |
|
||||
nuget install OpenBLAS -o $(Agent.ToolsDirectory)
|
||||
nuget install boost -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install boost_unit_test_framework-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install boost_program_options-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install boost_random-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install boost_serialization-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install boost_math_c99-vc140 -o $(Agent.ToolsDirectory) -Version 1.60.0
|
||||
nuget install OpenBLAS -o $(Agent.ToolsDirectory)
|
||||
nuget install unofficial-flayan-cereal -o $(Agent.ToolsDirectory)
|
||||
|
||||
mkdir -p $(Agent.ToolsDirectory)/boost_libs
|
||||
cp $(Agent.ToolsDirectory)/boost_program_options-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs
|
||||
cp $(Agent.ToolsDirectory)/boost_math_c99-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs
|
||||
cp $(Agent.ToolsDirectory)/boost_random-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs
|
||||
cp $(Agent.ToolsDirectory)/boost_serialization-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs
|
||||
cp $(Agent.ToolsDirectory)/boost_unit_test_framework-vc140.1.60.0.0/lib/native/address-model-64/lib/*.* $(Agent.ToolsDirectory)/boost_libs
|
||||
displayName: 'Fetch build dependencies'
|
||||
|
||||
# Configure armadillo
|
||||
@@ -66,6 +61,7 @@ steps:
|
||||
-DARMADILLO_LIBRARY="..\armadillo-8.400.0\Release\armadillo.lib" `
|
||||
-DBOOST_INCLUDEDIR=$(Agent.ToolsDirectory)\boost.1.60.0.0\lib\native\include `
|
||||
-DBOOST_LIBRARYDIR=$(Agent.ToolsDirectory)\boost_libs `
|
||||
-DCEREAL_INCLUDE_DIR=$(Agent.ToolsDirectory)\unofficial-flayan-cereal.1.2.2\build\native\include `
|
||||
-DBUILD_JULIA_BINDINGS=OFF `
|
||||
-DCMAKE_BUILD_TYPE=Release ..
|
||||
displayName: 'Configure mlpack'
|
||||
@@ -78,7 +74,6 @@ steps:
|
||||
msbuildVersion: $(MSBuildVersion)
|
||||
configuration: 'Release'
|
||||
msbuildArchitecture: 'x64'
|
||||
msbuildArguments: /m /p:BuildInParallel=true
|
||||
maximumCpuCount: false
|
||||
clean: false
|
||||
displayName: 'Build mlpack'
|
||||
@@ -93,7 +88,7 @@ steps:
|
||||
# Run tests via ctest.
|
||||
- bash: |
|
||||
cd build
|
||||
CTEST_OUTPUT_ON_FAILURE=1 ctest -T Test -C Release .
|
||||
CTEST_OUTPUT_ON_FAILURE=1 ctest -T Test -C Release . -j1
|
||||
displayName: 'Run tests via ctest'
|
||||
|
||||
# Copy artifacts
|
||||
@@ -121,6 +116,56 @@ steps:
|
||||
replaceExistingArchive: true
|
||||
displayName: 'Build artifacts'
|
||||
|
||||
# Build MSI installer.
|
||||
- powershell: |
|
||||
# Pull the documentation for the installer.
|
||||
try {
|
||||
$url = "http://ci.mlpack.org/job/mlpack%20-%20doxygen%20build/lastSuccessfulBuild/artifact/build/doc/html/*zip*/html.zip"
|
||||
(new-object net.webclient).DownloadFile($url, 'dist\win-installer\jenkinsdoc.zip')
|
||||
}
|
||||
catch {
|
||||
Write-Output "Unable to download precompiled Doxygen documentation from Jenkins!"
|
||||
}
|
||||
try {
|
||||
(Add-Type -AssemblyName System.IO.Compression.FileSystem);
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory('dist\win-installer\jenkinsdoc.zip', 'dist\win-installer\mlpack-win-installer\Sources\doc')
|
||||
}
|
||||
catch{Write-Output "Unable to add doc to installer, skipping!"}
|
||||
# Preparing installer staging.
|
||||
mkdir dist\win-installer\mlpack-win-installer\Sources\lib
|
||||
cp build\Release\*.lib dist\win-installer\mlpack-win-installer\Sources\lib\
|
||||
cp build\Release\*.exp dist\win-installer\mlpack-win-installer\Sources\lib\
|
||||
cp build\Release\*.dll dist\win-installer\mlpack-win-installer\Sources\
|
||||
cp build\Release\*.exe dist\win-installer\mlpack-win-installer\Sources\
|
||||
cp $(Agent.ToolsDirectory)\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll dist\win-installer\mlpack-win-installer\Sources\
|
||||
cp build\include\mlpack dist\win-installer\mlpack-win-installer\Sources -recurse
|
||||
cp doc\examples dist\win-installer\mlpack-win-installer\Sources -recurse
|
||||
cp src\mlpack\tests\data\german.csv dist\win-installer\mlpack-win-installer\Sources\examples\sample-ml-app\sample-ml-app\data\
|
||||
# Check current git version or mlpack version.
|
||||
$ver = (Get-Content "src\mlpack\core\util\version.hpp" | where {$_ -like "*MLPACK_VERSION*"});
|
||||
$env:MLPACK_VERSION += $ver[0].substring($ver[0].length - 1, 1) + '.';
|
||||
$env:MLPACK_VERSION += $ver[1].substring($ver[1].length - 1, 1) + '.';
|
||||
$env:MLPACK_VERSION += $ver[2].substring($ver[2].length - 1, 1);
|
||||
|
||||
if (Test-Path "src/mlpack/core/util/gitversion.hpp")
|
||||
{
|
||||
$ver = (Get-Content "src/mlpack/core/util/gitversion.hpp");
|
||||
$env:INSTALL_VERSION = $ver.Split('"')[1].Split(' ')[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$env:INSTALL_VERSION = $env:MLPACK_VERSION;
|
||||
}
|
||||
|
||||
# Build the MSI installer.
|
||||
cd dist\win-installer\mlpack-win-installer
|
||||
& 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe' `
|
||||
-t:rebuild `
|
||||
-p:Configuration=Release `
|
||||
-p:TreatWarningsAsErrors=True `
|
||||
mlpack-win-installer.wixproj
|
||||
displayName: 'Build MSI Windows installer'
|
||||
|
||||
# Publish artifacts to Azure Pipelines
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
@@ -137,6 +182,11 @@ steps:
|
||||
pathtoPublish: 'build/Testing/'
|
||||
artifactName: 'Tests'
|
||||
displayName: 'Publish artifacts test results'
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathtoPublish: 'dist\win-installer\mlpack-win-installer\bin\Release\mlpack-windows.msi'
|
||||
artifactName: mlpack-windows-installer
|
||||
displayName: 'Publish Windows MSI installer'
|
||||
|
||||
# Publish test results to Azure Pipelines
|
||||
- task: PublishTestResults@2
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
release:
|
||||
types: [published, created, edited]
|
||||
name: mlpack.mlpack
|
||||
|
||||
jobs:
|
||||
jobR:
|
||||
name: mlpack R tarball
|
||||
if: ${{ github.repository == 'mlpack/mlpack' }}
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
outputs:
|
||||
r_bindings: ${{ steps.mlpack_version.outputs.mlpack_r_package }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Extract mlpack version
|
||||
id: mlpack_version
|
||||
run: |
|
||||
MLPACK_VERSION_MAJOR=$(grep -i ".*#define MLPACK_VERSION_MAJOR.*" src/mlpack/core/util/version.hpp | grep -o "[0-9]*")
|
||||
MLPACK_VERSION_MINOR=$(grep -i ".*#define MLPACK_VERSION_MINOR.*" src/mlpack/core/util/version.hpp | grep -o "[0-9]*")
|
||||
MLPACK_VERSION_PATCH=$(grep -i ".*#define MLPACK_VERSION_PATCH.*" src/mlpack/core/util/version.hpp | grep -o "[0-9]*")
|
||||
MLPACK_VERSION_VALUE=${MLPACK_VERSION_MAJOR}.${MLPACK_VERSION_MINOR}.${MLPACK_VERSION_PATCH}
|
||||
echo ::set-output name=mlpack_r_package::$(echo mlpack_"$MLPACK_VERSION_VALUE".tar.gz)
|
||||
|
||||
- uses: r-lib/actions/setup-r@master
|
||||
with:
|
||||
r-version: release
|
||||
|
||||
- name: Query dependencies
|
||||
run: |
|
||||
cp src/mlpack/bindings/R/mlpack/DESCRIPTION.in DESCRIPTION
|
||||
Rscript -e "install.packages('remotes')" -e "saveRDS(remotes::dev_package_deps(dependencies = TRUE), 'depends.Rds')"
|
||||
|
||||
- name: Cache R packages
|
||||
if: runner.os != 'Windows'
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ env.R_LIBS_USER }}
|
||||
key: ${{ runner.os }}-r-release-${{ hashFiles('depends.Rds') }}
|
||||
restore-keys: ${{ runner.os }}-r-release-
|
||||
|
||||
- name: Install Build Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --allow-unauthenticated libopenblas-dev liblapack-dev g++ libboost-all-dev libcereal-dev
|
||||
curl https://data.kurg.org/armadillo-8.400.0.tar.xz | tar -xvJ && cd armadillo*
|
||||
cmake . && make && sudo make install && cd ..
|
||||
|
||||
- name: Install R-bindings dependencies
|
||||
run: |
|
||||
remotes::install_deps(dependencies = TRUE)
|
||||
remotes::install_cran("roxygen2")
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: CMake
|
||||
run: |
|
||||
mkdir build
|
||||
cd build && cmake -DDEBUG=OFF -DPROFILE=OFF -DBUILD_CLI_EXECUTABLES=OFF -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_JULIA_BINDINGS=OFF -DBUILD_GO_BINDINGS=OFF -DBUILD_R_BINDINGS=ON ..
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cd build && make -j2
|
||||
|
||||
- name: Run tests via ctest
|
||||
run: |
|
||||
cd build && CTEST_OUTPUT_ON_FAILURE=1 ctest -T Test .
|
||||
|
||||
- name: Upload R packages
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: mlpack_r_tarball
|
||||
path: build/src/mlpack/bindings/R/${{ steps.mlpack_version.outputs.mlpack_r_package }}
|
||||
|
||||
R-CMD-check:
|
||||
needs: jobR
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
|
||||
name: ${{ matrix.config.name }}
|
||||
if: ${{ github.repository == 'mlpack/mlpack' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- {os: windows-latest, r: '4.0', name: 'Windows R'}
|
||||
- {os: macOS-latest, r: 'release', name: 'macOS R'}
|
||||
- {os: ubuntu-20.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest", name: 'Linux R'}
|
||||
|
||||
|
||||
env:
|
||||
MAKEFLAGS: "-j 2"
|
||||
R_BUILD_ARGS: "--no-build-vignettes"
|
||||
R_CHECK_ARGS: "--no-build-vignettes"
|
||||
_R_CHECK_FORCE_SUGGESTS: 0
|
||||
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
|
||||
RSPM: ${{ matrix.config.rspm }}
|
||||
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
steps:
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: mlpack_r_tarball
|
||||
|
||||
- uses: r-lib/actions/setup-r@master
|
||||
with:
|
||||
r-version: ${{ matrix.config.r }}
|
||||
|
||||
- uses: r-lib/actions/setup-pandoc@master
|
||||
|
||||
- name: Query dependencies
|
||||
run: Rscript -e "install.packages('remotes')" -e "saveRDS(remotes::dev_package_deps('${{ needs.jobR.outputs.r_bindings }}', dependencies = TRUE), 'depends.Rds')"
|
||||
|
||||
- name: Cache R packages
|
||||
if: runner.os != 'Windows'
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ env.R_LIBS_USER }}
|
||||
key: ${{ runner.os }}-r-${{ matrix.config.r }}-${{ hashFiles('depends.Rds') }}
|
||||
restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
remotes::install_deps('${{ needs.jobR.outputs.r_bindings }}', dependencies = TRUE)
|
||||
remotes::install_cran("rcmdcheck")
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: Check
|
||||
run: Rscript -e "rcmdcheck::rcmdcheck('${{ needs.jobR.outputs.r_bindings }}', args = c('--no-manual','--as-cran'), error_on = 'warning', check_dir = 'check')"
|
||||
|
||||
- name: Upload check results
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: ${{ runner.os }}-r${{ matrix.config.r }}-results
|
||||
path: |
|
||||
check/mlpack.Rcheck/00check.log
|
||||
check/mlpack.Rcheck/00install.out
|
||||
@@ -0,0 +1,49 @@
|
||||
name: Update Catch
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 10 1/16 * *'
|
||||
jobs:
|
||||
updateCatch:
|
||||
if: ${{ github.repository == 'mlpack/mlpack' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Get Latest Catch Tagged Release
|
||||
id: catch-header
|
||||
run: |
|
||||
# Ping version information upstream.
|
||||
CATCH_RELEASE_JSON=$(curl -sL https://api.github.com/repos/catchorg/Catch2/releases/latest)
|
||||
CATCH_RELEASE_VERSION=$(jq -r ".tag_name" <<< "$CATCH_RELEASE_JSON" | tr -d v)
|
||||
echo ::set-output name=release_tag::$(echo $CATCH_RELEASE_VERSION)
|
||||
# Extract out version information from git repository.
|
||||
CATCH_VERSION_MAJOR=$(grep -i ".*#define CATCH_VERSION_MAJOR.*" src/mlpack/tests/catch.hpp | grep -o "[0-9]*")
|
||||
CATCH_VERSION_MINOR=$(grep -i ".*#define CATCH_VERSION_MINOR.*" src/mlpack/tests/catch.hpp | grep -o "[0-9]*")
|
||||
CATCH_VERSION_PATCH=$(grep -i ".*#define CATCH_VERSION_PATCH.*" src/mlpack/tests/catch.hpp | grep -o "[0-9]*")
|
||||
# Combine values to match release tag information.
|
||||
CATCH_VERSION_VALUE=${CATCH_VERSION_MAJOR}.${CATCH_VERSION_MINOR}.${CATCH_VERSION_PATCH}
|
||||
# Set the current release tag.
|
||||
echo ::set-output name=current_tag::$(echo $CATCH_VERSION_VALUE)
|
||||
|
||||
- name: Update Catch
|
||||
if: steps.catch-header.outputs.current_tag != steps.catch-header.outputs.release_tag
|
||||
env:
|
||||
CURRENT_TAG: ${{ steps.catch-header.outputs.current_tag }}
|
||||
RELEASE_TAG: ${{ steps.catch-header.outputs.release_tag }}
|
||||
run: |
|
||||
# Delete the catch.hpp.
|
||||
rm -f src/mlpack/tests/catch.hpp
|
||||
# Download the release.
|
||||
curl -sL https://github.com/catchorg/Catch2/releases/latest/download/catch.hpp -o src/mlpack/tests/catch.hpp
|
||||
|
||||
- name: Create Pull Request For Catch
|
||||
if: steps.catch-header.outputs.current_tag != steps.catch-header.outputs.release_tag
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
commit-message: Upgrade Catch to ${{ steps.catch-header.outputs.release_tag }}
|
||||
title: Upgrade Catch to ${{ steps.catch-header.outputs.release_tag }}
|
||||
body: |
|
||||
Updates [catchorg/Catch2](https://github.com/catchorg/Catch2) to ${{ steps.catch-header.outputs.release_tag }}.
|
||||
Auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request).
|
||||
labels: update dependencies, automated PR
|
||||
branch: catch-header-updates-${{ steps.catch-header.outputs.release_tag }}
|
||||
@@ -0,0 +1,45 @@
|
||||
name: Update CLI11
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 10 1/16 * *'
|
||||
jobs:
|
||||
updateCLI11:
|
||||
if: ${{ github.repository == 'mlpack/mlpack' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Get Latest CLI11 Tagged Release
|
||||
id: cli11-header
|
||||
run: |
|
||||
# Ping version information upstream.
|
||||
CLI11_RELEASE_JSON=$(curl -sL https://api.github.com/repos/CLIUtils/CLI11/releases/latest)
|
||||
CLI11_RELEASE_VERSION=$(jq -r ".tag_name" <<< "$CLI11_RELEASE_JSON" | tr -d v)
|
||||
echo ::set-output name=release_tag::$(echo $CLI11_RELEASE_VERSION)
|
||||
# Extract out version information from git repository.
|
||||
CLI11_VERSION_VALUE=$(grep -i ".*#define CLI11_VERSION.*" src/mlpack/bindings/cli/third_party/CLI/CLI11.hpp | grep -Po "(\d+\.)+\d+")
|
||||
# Set the current release tag.
|
||||
echo ::set-output name=current_tag::$(echo $CLI11_VERSION_VALUE)
|
||||
|
||||
- name: Update CLI11
|
||||
if: steps.cli11-header.outputs.current_tag != steps.cli11-header.outputs.release_tag
|
||||
env:
|
||||
CURRENT_TAG: ${{ steps.cli11-header.outputs.current_tag }}
|
||||
RELEASE_TAG: ${{ steps.cli11-header.outputs.release_tag }}
|
||||
run: |
|
||||
# Delete the CLI11.hpp.
|
||||
rm -f src/mlpack/bindings/cli/third_party/CLI/CLI11.hpp
|
||||
# Download the release.
|
||||
curl -sL https://github.com/CLIUtils/CLI11/releases/latest/download/CLI11.hpp -o src/mlpack/bindings/cli/third_party/CLI/CLI11.hpp
|
||||
|
||||
- name: Create Pull Request For CLI11
|
||||
if: steps.cli11-header.outputs.current_tag != steps.cli11-header.outputs.release_tag
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
commit-message: Upgrade CLI11 to ${{ steps.cli11-header.outputs.release_tag }}
|
||||
title: Upgrade CLI11 to ${{ steps.cli11-header.outputs.release_tag }}
|
||||
body: |
|
||||
Updates [CLIUtils/CLI11](https://github.com/CLIUtils/CLI11) to ${{ steps.cli11-header.outputs.release_tag }}.
|
||||
Auto-generated by [create-pull-request](https://github.com/peter-evans/create-pull-request).
|
||||
labels: update dependencies, automated PR
|
||||
branch: cli11-header-updates-${{ steps.cli11-header.outputs.release_tag }}
|
||||
@@ -1,4 +1,4 @@
|
||||
# ConfigureGenerate.cmake: generate an mlpack binding file given input
|
||||
# ConfigureFile.cmake: generate an mlpack binding file given input
|
||||
# arguments.
|
||||
#
|
||||
# This file depends on the following variables being set:
|
||||
+2
-2
@@ -14,9 +14,9 @@ if (GO_EXECUTABLE)
|
||||
RESULT_VARIABLE RESULT
|
||||
)
|
||||
if (RESULT EQUAL 0)
|
||||
string(REGEX REPLACE ".*([0-9]+\\.[0-9]+\\.[0-9]+).*" "\\1"
|
||||
string(REGEX REPLACE ".*([0-9]+\\.[0-9]+\(\\.[0-9]+\)?).*" "\\1"
|
||||
GO_VERSION_STRING ${GO_VERSION_STRING})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# FindR.cmkae
|
||||
# Make sure find package macros are included
|
||||
set(TEMP_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE})
|
||||
set(CMAKE_FIND_APPBUNDLE "NEVER")
|
||||
|
||||
# Find R.
|
||||
find_program(R_EXECUTABLE R DOC "R executable.")
|
||||
|
||||
if(R_EXECUTABLE)
|
||||
# Get the location of R.
|
||||
execute_process(
|
||||
WORKING_DIRECTORY .
|
||||
COMMAND ${R_EXECUTABLE} RHOME
|
||||
OUTPUT_VARIABLE R_BASE_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Get the R version.
|
||||
execute_process(
|
||||
COMMAND ${R_EXECUTABLE} --version
|
||||
OUTPUT_VARIABLE R_VERSION_STRING
|
||||
RESULT_VARIABLE RESULT
|
||||
)
|
||||
if (RESULT EQUAL 0)
|
||||
string(REGEX REPLACE ".*([0-9]+\\.[0-9]+\\.[0-9]+).*" "\\1"
|
||||
R_VERSION_STRING ${R_VERSION_STRING})
|
||||
endif ()
|
||||
|
||||
set(R_HOME ${R_BASE_DIR} CACHE PATH "R home directory obtained from R RHOME")
|
||||
mark_as_advanced(R_HOME)
|
||||
endif()
|
||||
|
||||
# Find the Rscript program.
|
||||
find_program(RSCRIPT_EXECUTABLE Rscript DOC "Rscript executable.")
|
||||
|
||||
set(CMAKE_FIND_APPBUNDLE ${TEMP_CMAKE_FIND_APPBUNDLE})
|
||||
|
||||
mark_as_advanced(RSCRIPT_EXECUTABLE R_EXECUTABLE)
|
||||
set( _REQUIRED_R_VARIABLES R_EXECUTABLE )
|
||||
|
||||
include( FindPackageHandleStandardArgs )
|
||||
find_package_handle_standard_args(
|
||||
R
|
||||
REQUIRED_VARS ${_REQUIRED_R_VARIABLES}
|
||||
VERSION_VAR R_VERSION_STRING
|
||||
FAIL_MESSAGE "R not found"
|
||||
)
|
||||
@@ -0,0 +1,58 @@
|
||||
# FindRModule.cmake: find a specific R module.
|
||||
function(find_r_module module)
|
||||
string(TOUPPER ${module} module_upper)
|
||||
if (NOT R_${module_upper})
|
||||
if (ARGC GREATER 1)
|
||||
# Not required but we have version constraints.
|
||||
set(VERSION_REQ ${ARGV1})
|
||||
endif ()
|
||||
# A module's location is usually a directory, but for binary modules
|
||||
# it's a .so file.
|
||||
execute_process(COMMAND ${RSCRIPT_EXECUTABLE} "-e" "find.package('${module}')"
|
||||
RESULT_VARIABLE _${module}_status
|
||||
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)
|
||||
execute_process(COMMAND ${RSCRIPT_EXECUTABLE} "-e" "packageVersion('${module}')"
|
||||
RESULT_VARIABLE _version_status
|
||||
OUTPUT_VARIABLE _version_compare
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
string(REGEX MATCHALL "‘[0-9._]*’" _version_compare "${_version_compare}")
|
||||
string(REGEX REPLACE "‘" "" _version_compare "${_version_compare}")
|
||||
string(REGEX REPLACE "’" "" _version_compare "${_version_compare}")
|
||||
|
||||
# Compare the version of the package using compareVersion().
|
||||
execute_process(COMMAND ${RSCRIPT_EXECUTABLE} "-e"
|
||||
"compareVersion('${_version_compare}', '${VERSION_REQ}')"
|
||||
RESULT_VARIABLE _compareVersion_status
|
||||
OUTPUT_VARIABLE _compareVersion_result
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
# Extract compareVersion() result i.e. 1 -> Newer, 0 -> Equal and -1 -> Later.
|
||||
string(REGEX REPLACE "\\[\\1\\]" "" _compareVersion_result "${_compareVersion_result}")
|
||||
if ("${_compareVersion_result}" GREATER "-1")
|
||||
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 ()
|
||||
else ()
|
||||
# No version requirement so we are done.
|
||||
set(R_${module_upper} ${_${module}_location} CACHE STRING "Location of R module ${module}")
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(R_${module} DEFAULT_MSG R_${module_upper})
|
||||
endfunction ()
|
||||
@@ -0,0 +1,56 @@
|
||||
#Findcereal.cmake
|
||||
find_path(CEREAL_INCLUDE_DIR
|
||||
NAMES cereal
|
||||
PATHS "$ENV{ProgramFiles}/cereal/include"
|
||||
)
|
||||
|
||||
if(CEREAL_INCLUDE_DIR)
|
||||
# ------------------------------------------------------------------------
|
||||
# Extract version information from <CEREAL>
|
||||
# ------------------------------------------------------------------------
|
||||
set(CEREAL_FOUND YES)
|
||||
set(CEREAL_VERSION_MAJOR 0)
|
||||
set(CEREAL_VERSION_MINOR 0)
|
||||
set(CEREAL_VERSION_PATCH 0)
|
||||
|
||||
if(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/version.hpp")
|
||||
|
||||
# Read and parse cereal version header file for version number
|
||||
file(READ "${CEREAL_INCLUDE_DIR}/cereal/version.hpp"
|
||||
_CEREAL_HEADER_CONTENTS)
|
||||
string(REGEX REPLACE ".*#define CEREAL_VERSION_MAJOR ([0-9]+).*" "\\1"
|
||||
CEREAL_VERSION_MAJOR "${_CEREAL_HEADER_CONTENTS}")
|
||||
string(REGEX REPLACE ".*#define CEREAL_VERSION_MINOR ([0-9]+).*" "\\1"
|
||||
CEREAL_VERSION_MINOR "${_CEREAL_HEADER_CONTENTS}")
|
||||
string(REGEX REPLACE ".*#define CEREAL_VERSION_PATCH ([0-9]+).*" "\\1"
|
||||
CEREAL_VERSION_PATCH "${_CEREAL_HEADER_CONTENTS}")
|
||||
|
||||
elseif(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/details/polymorphic_impl_fwd.hpp")
|
||||
|
||||
set(CEREAL_VERSION_MAJOR 1)
|
||||
set(CEREAL_VERSION_MINOR 2)
|
||||
set(CEREAL_VERSION_PATCH 0)
|
||||
elseif(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/types/valarray.hpp")
|
||||
|
||||
set(CEREAL_VERSION_MAJOR 1)
|
||||
set(CEREAL_VERSION_MINOR 1)
|
||||
set(CEREAL_VERSION_PATCH 2)
|
||||
elseif(EXISTS "${CEREAL_INCLUDE_DIR}/cereal/cereal.hpp")
|
||||
|
||||
set(CEREAL_VERSION_MAJOR 1)
|
||||
set(CEREAL_VERSION_MINOR 1)
|
||||
set(CEREAL_VERSION_PATCH 1)
|
||||
else()
|
||||
|
||||
set(CEREAL_FOUND NO)
|
||||
endif()
|
||||
set(CEREAL_VERSION_STRING "${CEREAL_VERSION_MAJOR}.${CEREAL_VERSION_MINOR}.${CEREAL_VERSION_PATCH}")
|
||||
endif ()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(cereal
|
||||
REQUIRED_VARS CEREAL_INCLUDE_DIR
|
||||
VERSION_VAR CEREAL_VERSION_STRING
|
||||
)
|
||||
|
||||
mark_as_advanced(CEREAL_INCLUDE_DIR)
|
||||
@@ -1,13 +0,0 @@
|
||||
# GenerateGoBinding.cmake: a CMake script that actually runs the given program to
|
||||
# generate an mlpack binding file.
|
||||
#
|
||||
# This script depends on the following arguments:
|
||||
#
|
||||
# GENERATE_H_PROGRAM: the program to run to generate the .h file.
|
||||
# H_OUTPUT_FILE: the file to store the output in.
|
||||
# GENERATE_GO_PROGRAM: the program to run to generate the .go file.
|
||||
# GO_OUTPUT_FILE: the file to store the output in.
|
||||
# GENERATE_CPP_PROGRAM: the program to run to generate the .cpp file.
|
||||
# CPP_OUTPUT_FILE: the file to store the output in.
|
||||
execute_process(COMMAND ${GENERATE_BINDING_PROGRAM}
|
||||
OUTPUT_FILE ${BINDING_OUTPUT_FILE})
|
||||
@@ -0,0 +1,56 @@
|
||||
# AppendSerialization.cmake: append imports for serialization and
|
||||
# deserialization for mlpack model types to the existing list of serialization
|
||||
# and deserialization imports.
|
||||
|
||||
# This function depends on the following variables being set:
|
||||
#
|
||||
# * 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, else Deserialize.
|
||||
#
|
||||
function(append_serialization SERIALIZATION_FILE PROGRAM_MAIN_FILE SERIALIZE)
|
||||
include("${CMAKE_SOURCE_DIR}/CMake/StripType.cmake")
|
||||
strip_type("${PROGRAM_MAIN_FILE}")
|
||||
|
||||
list(LENGTH MODEL_TYPES NUM_MODEL_TYPES)
|
||||
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)
|
||||
file(READ "${SERIALIZATION_FILE}" SERIALIZATION_FILE_CONTENTS)
|
||||
if (SERIALIZE)
|
||||
# See if the model type already exists.
|
||||
string(FIND
|
||||
"${SERIALIZATION_FILE_CONTENTS}"
|
||||
"\"${MODEL_SAFE_TYPE}\" = Serialize${MODEL_SAFE_TYPE}Ptr,"
|
||||
FIND_OUT)
|
||||
|
||||
# If it doesn't exist, append it.
|
||||
if (${FIND_OUT} EQUAL -1)
|
||||
# Now append the type to the list of types, and define any serialization
|
||||
# function.
|
||||
file(APPEND
|
||||
"${SERIALIZATION_FILE}"
|
||||
" \"${MODEL_SAFE_TYPE}\" = Serialize${MODEL_SAFE_TYPE}Ptr,\n")
|
||||
endif()
|
||||
elseif (NOT SERIALIZE)
|
||||
# See if the model type already exists.
|
||||
string(FIND
|
||||
"${SERIALIZATION_FILE_CONTENTS}"
|
||||
"\"${MODEL_SAFE_TYPE}\" = Deserialize${MODEL_SAFE_TYPE}Ptr,"
|
||||
FIND_OUT)
|
||||
|
||||
# If it doesn't exist, append it.
|
||||
if (${FIND_OUT} EQUAL -1)
|
||||
# Now append the type to the list of types, and define any deserialization
|
||||
# function.
|
||||
file(APPEND
|
||||
"${SERIALIZATION_FILE}"
|
||||
" \"${MODEL_SAFE_TYPE}\" = Deserialize${MODEL_SAFE_TYPE}Ptr,\n")
|
||||
endif()
|
||||
endif()
|
||||
endforeach ()
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -0,0 +1,92 @@
|
||||
# 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 IO_GetParam${MODEL_SAFE_TYPE}Ptr(const std::string& paramName)
|
||||
{
|
||||
return std::move((${MODEL_PTR_TYPEDEF}) IO::GetParam<${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)
|
||||
{
|
||||
IO::GetParam<${MODEL_TYPE}*>(paramName) = Rcpp::as<${MODEL_PTR_TYPEDEF}>(ptr);
|
||||
IO::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}")
|
||||
@@ -0,0 +1,47 @@
|
||||
# StripType.cmake: Extract ModelType from the main file and turn it into
|
||||
# something that has no special characters that can simply be used.
|
||||
|
||||
# This function depends on the following variables being set:
|
||||
#
|
||||
# * PROGRAM_MAIN_FILE: the file containing the mlpackMain() function.
|
||||
#
|
||||
function(strip_type PROGRAM_MAIN_FILE)
|
||||
# We need to parse the main file and find any PARAM_MODEL_* lines.
|
||||
file(READ "${PROGRAM_MAIN_FILE}" MAIN_FILE)
|
||||
|
||||
# Grab all "PARAM_MODEL_IN(Model,", "PARAM_MODEL_IN_REQ(Model,",
|
||||
# "PARAM_MODEL_OUT(Model,".
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN\\([A-Za-z_<>]*," MODELS_IN
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN_REQ\\([A-Za-z_<>]*," MODELS_IN_REQ
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_OUT\\([A-Za-z_]*," MODELS_OUT "${MAIN_FILE}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN\\(" "" MODELS_IN_STRIP1 "${MODELS_IN}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_SAFE_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN_REQ\\(" "" MODELS_IN_REQ_STRIP1
|
||||
"${MODELS_IN_REQ}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_REQ_STRIP2 "${MODELS_IN_REQ_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_REQ_SAFE_STRIP2
|
||||
"${MODELS_IN_REQ_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_OUT\\(" "" MODELS_OUT_STRIP1 "${MODELS_OUT}")
|
||||
string(REGEX REPLACE "," "" MODELS_OUT_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_OUT_SAFE_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
|
||||
set(MODEL_TYPES ${MODELS_IN_STRIP2} ${MODELS_IN_REQ_STRIP2}
|
||||
${MODELS_OUT_STRIP2})
|
||||
set(MODEL_SAFE_TYPES ${MODELS_IN_SAFE_STRIP2} ${MODELS_IN_REQ_SAFE_STRIP2}
|
||||
${MODELS_OUT_SAFE_STRIP2})
|
||||
if (MODEL_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_TYPES)
|
||||
endif ()
|
||||
if (MODEL_SAFE_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_SAFE_TYPES)
|
||||
endif ()
|
||||
|
||||
set(MODEL_TYPES ${MODEL_TYPES} PARENT_SCOPE)
|
||||
set(MODEL_SAFE_TYPES ${MODEL_SAFE_TYPES} PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -6,42 +6,9 @@
|
||||
# * PROGRAM_MAIN_FILE: the file containing the mlpackMain() function.
|
||||
# * SERIALIZATION_FILE: file to append types to
|
||||
#
|
||||
# We need to parse the main file and find any PARAM_MODEL_* lines.
|
||||
function(append_model SERIALIZATION_FILE PROGRAM_MAIN_FILE)
|
||||
file(READ "${PROGRAM_MAIN_FILE}" MAIN_FILE)
|
||||
|
||||
# Grab all "PARAM_MODEL_IN(Model,", "PARAM_MODEL_IN_REQ(Model,",
|
||||
# "PARAM_MODEL_OUT(Model,".
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN\\([A-Za-z_<>]*," MODELS_IN
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN_REQ\\([A-Za-z_<>]*," MODELS_IN_REQ
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_OUT\\([A-Za-z_]*," MODELS_OUT "${MAIN_FILE}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN\\(" "" MODELS_IN_STRIP1 "${MODELS_IN}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_SAFE_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN_REQ\\(" "" MODELS_IN_REQ_STRIP1
|
||||
"${MODELS_IN_REQ}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_REQ_STRIP2 "${MODELS_IN_REQ_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_REQ_SAFE_STRIP2
|
||||
"${MODELS_IN_REQ_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_OUT\\(" "" MODELS_OUT_STRIP1 "${MODELS_OUT}")
|
||||
string(REGEX REPLACE "," "" MODELS_OUT_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_OUT_SAFE_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
|
||||
set(MODEL_TYPES ${MODELS_IN_STRIP2} ${MODELS_IN_REQ_STRIP2}
|
||||
${MODELS_OUT_STRIP2})
|
||||
set(MODEL_SAFE_TYPES ${MODELS_IN_SAFE_STRIP2} ${MODELS_IN_REQ_SAFE_STRIP2}
|
||||
${MODELS_OUT_SAFE_STRIP2})
|
||||
if (MODEL_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_TYPES)
|
||||
endif ()
|
||||
if (MODEL_SAFE_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_SAFE_TYPES)
|
||||
endif ()
|
||||
include("${CMAKE_SOURCE_DIR}/CMake/StripType.cmake")
|
||||
strip_type("${PROGRAM_MAIN_FILE}")
|
||||
|
||||
# Now, generate the definitions of the functions we need.
|
||||
set(MODEL_PTR_DEFNS "")
|
||||
|
||||
@@ -8,41 +8,8 @@
|
||||
# * GO_IN: path of the go_method.h.in/go_method.cpp.in file.
|
||||
# * GO_OUT: name of the output .h/.cpp file.
|
||||
#
|
||||
# We need to parse the main file and find any PARAM_MODEL_* lines.
|
||||
file(READ "${PROGRAM_MAIN_FILE}" MAIN_FILE)
|
||||
|
||||
# Grab all "PARAM_MODEL_IN(Model,", "PARAM_MODEL_IN_REQ(Model,",
|
||||
# "PARAM_MODEL_OUT(Model,".
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN\\([A-Za-z_<>]*," MODELS_IN
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN_REQ\\([A-Za-z_<>]*," MODELS_IN_REQ
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_OUT\\([A-Za-z_]*," MODELS_OUT "${MAIN_FILE}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN\\(" "" MODELS_IN_STRIP1 "${MODELS_IN}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_SAFE_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN_REQ\\(" "" MODELS_IN_REQ_STRIP1
|
||||
"${MODELS_IN_REQ}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_REQ_STRIP2 "${MODELS_IN_REQ_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_REQ_SAFE_STRIP2
|
||||
"${MODELS_IN_REQ_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_OUT\\(" "" MODELS_OUT_STRIP1 "${MODELS_OUT}")
|
||||
string(REGEX REPLACE "," "" MODELS_OUT_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_OUT_SAFE_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
|
||||
set(MODEL_TYPES ${MODELS_IN_STRIP2} ${MODELS_IN_REQ_STRIP2}
|
||||
${MODELS_OUT_STRIP2})
|
||||
set(MODEL_SAFE_TYPES ${MODELS_IN_SAFE_STRIP2} ${MODELS_IN_REQ_SAFE_STRIP2}
|
||||
${MODELS_OUT_SAFE_STRIP2})
|
||||
if (MODEL_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_TYPES)
|
||||
endif ()
|
||||
if (MODEL_SAFE_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_SAFE_TYPES)
|
||||
endif ()
|
||||
include("${SOURCE_DIR}/CMake/StripType.cmake")
|
||||
strip_type("${PROGRAM_MAIN_FILE}")
|
||||
|
||||
# Now, generate the definitions of the functions we need.
|
||||
set(MODEL_PTR_DEFNS "")
|
||||
|
||||
@@ -8,42 +8,9 @@
|
||||
# * PROGRAM_MAIN_FILE: the file containing the mlpackMain() function.
|
||||
# * SERIALIZATION_FILE: file to append types to
|
||||
#
|
||||
# We need to parse the main file and find any PARAM_MODEL_* lines.
|
||||
function(append_serialization SERIALIZATION_FILE PROGRAM_NAME PROGRAM_MAIN_FILE)
|
||||
file(READ "${PROGRAM_MAIN_FILE}" MAIN_FILE)
|
||||
|
||||
# Grab all "PARAM_MODEL_IN(Model,", "PARAM_MODEL_IN_REQ(Model,",
|
||||
# "PARAM_MODEL_OUT(Model,".
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN\\([A-Za-z_<>]*," MODELS_IN
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN_REQ\\([A-Za-z_<>]*," MODELS_IN_REQ
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_OUT\\([A-Za-z_]*," MODELS_OUT "${MAIN_FILE}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN\\(" "" MODELS_IN_STRIP1 "${MODELS_IN}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_SAFE_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN_REQ\\(" "" MODELS_IN_REQ_STRIP1
|
||||
"${MODELS_IN_REQ}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_REQ_STRIP2 "${MODELS_IN_REQ_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_REQ_SAFE_STRIP2
|
||||
"${MODELS_IN_REQ_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_OUT\\(" "" MODELS_OUT_STRIP1 "${MODELS_OUT}")
|
||||
string(REGEX REPLACE "," "" MODELS_OUT_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_OUT_SAFE_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
|
||||
set(MODEL_TYPES ${MODELS_IN_STRIP2} ${MODELS_IN_REQ_STRIP2}
|
||||
${MODELS_OUT_STRIP2})
|
||||
set(MODEL_SAFE_TYPES ${MODELS_IN_SAFE_STRIP2} ${MODELS_IN_REQ_SAFE_STRIP2}
|
||||
${MODELS_OUT_SAFE_STRIP2})
|
||||
if (MODEL_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_TYPES)
|
||||
endif ()
|
||||
if (MODEL_SAFE_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_SAFE_TYPES)
|
||||
endif ()
|
||||
include("${CMAKE_SOURCE_DIR}/CMake/StripType.cmake")
|
||||
strip_type("${PROGRAM_MAIN_FILE}")
|
||||
|
||||
# Now, generate the definitions of the functions we need.
|
||||
set(MODEL_PTR_DEFNS "")
|
||||
|
||||
@@ -7,42 +7,9 @@
|
||||
# * PROGRAM_MAIN_FILE: the file containing the mlpackMain() function.
|
||||
# * TYPES_FILE: file to append types to
|
||||
#
|
||||
# We need to parse the main file and find any PARAM_MODEL_* lines.
|
||||
function(append_type TYPES_FILE PROGRAM_NAME PROGRAM_MAIN_FILE)
|
||||
file(READ "${PROGRAM_MAIN_FILE}" MAIN_FILE)
|
||||
|
||||
# Grab all "PARAM_MODEL_IN(Model,", "PARAM_MODEL_IN_REQ(Model,",
|
||||
# "PARAM_MODEL_OUT(Model,".
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN\\([A-Za-z_<>]*," MODELS_IN
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN_REQ\\([A-Za-z_<>]*," MODELS_IN_REQ
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_OUT\\([A-Za-z_]*," MODELS_OUT "${MAIN_FILE}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN\\(" "" MODELS_IN_STRIP1 "${MODELS_IN}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_SAFE_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN_REQ\\(" "" MODELS_IN_REQ_STRIP1
|
||||
"${MODELS_IN_REQ}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_REQ_STRIP2 "${MODELS_IN_REQ_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_REQ_SAFE_STRIP2
|
||||
"${MODELS_IN_REQ_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_OUT\\(" "" MODELS_OUT_STRIP1 "${MODELS_OUT}")
|
||||
string(REGEX REPLACE "," "" MODELS_OUT_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_OUT_SAFE_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
|
||||
set(MODEL_TYPES ${MODELS_IN_STRIP2} ${MODELS_IN_REQ_STRIP2}
|
||||
${MODELS_OUT_STRIP2})
|
||||
set(MODEL_SAFE_TYPES ${MODELS_IN_SAFE_STRIP2} ${MODELS_IN_REQ_SAFE_STRIP2}
|
||||
${MODELS_OUT_SAFE_STRIP2})
|
||||
if (MODEL_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_TYPES)
|
||||
endif ()
|
||||
if (MODEL_SAFE_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_SAFE_TYPES)
|
||||
endif ()
|
||||
include("${CMAKE_SOURCE_DIR}/CMake/StripType.cmake")
|
||||
strip_type("${PROGRAM_MAIN_FILE}")
|
||||
|
||||
# Now, generate the definitions of the functions we need.
|
||||
set(MODEL_PTR_DEFNS "")
|
||||
|
||||
@@ -10,41 +10,8 @@
|
||||
# * JULIA_CPP_IN: path of the julia_method.cpp.in file.
|
||||
# * JULIA_CPP_OUT: name of the output .cpp file.
|
||||
#
|
||||
# We need to parse the main file and find any PARAM_MODEL_* lines.
|
||||
file(READ "${PROGRAM_MAIN_FILE}" MAIN_FILE)
|
||||
|
||||
# Grab all "PARAM_MODEL_IN(Model,", "PARAM_MODEL_IN_REQ(Model,",
|
||||
# "PARAM_MODEL_OUT(Model,".
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN\\([A-Za-z_<>]*," MODELS_IN
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_IN_REQ\\([A-Za-z_<>]*," MODELS_IN_REQ
|
||||
"${MAIN_FILE}")
|
||||
string(REGEX MATCHALL "PARAM_MODEL_OUT\\([A-Za-z_]*," MODELS_OUT "${MAIN_FILE}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN\\(" "" MODELS_IN_STRIP1 "${MODELS_IN}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_SAFE_STRIP2 "${MODELS_IN_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_IN_REQ\\(" "" MODELS_IN_REQ_STRIP1
|
||||
"${MODELS_IN_REQ}")
|
||||
string(REGEX REPLACE "," "" MODELS_IN_REQ_STRIP2 "${MODELS_IN_REQ_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_IN_REQ_SAFE_STRIP2
|
||||
"${MODELS_IN_REQ_STRIP1}")
|
||||
|
||||
string(REGEX REPLACE "PARAM_MODEL_OUT\\(" "" MODELS_OUT_STRIP1 "${MODELS_OUT}")
|
||||
string(REGEX REPLACE "," "" MODELS_OUT_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
string(REGEX REPLACE "[<>,]" "" MODELS_OUT_SAFE_STRIP2 "${MODELS_OUT_STRIP1}")
|
||||
|
||||
set(MODEL_TYPES ${MODELS_IN_STRIP2} ${MODELS_IN_REQ_STRIP2}
|
||||
${MODELS_OUT_STRIP2})
|
||||
set(MODEL_SAFE_TYPES ${MODELS_IN_SAFE_STRIP2} ${MODELS_IN_REQ_SAFE_STRIP2}
|
||||
${MODELS_OUT_SAFE_STRIP2})
|
||||
if (MODEL_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_TYPES)
|
||||
endif ()
|
||||
if (MODEL_SAFE_TYPES)
|
||||
list(REMOVE_DUPLICATES MODEL_SAFE_TYPES)
|
||||
endif ()
|
||||
include("${SOURCE_DIR}/CMake/StripType.cmake")
|
||||
strip_type("${PROGRAM_MAIN_FILE}")
|
||||
|
||||
# Now, generate the definitions of the functions we need.
|
||||
set(MODEL_PTR_DEFNS "")
|
||||
@@ -88,9 +55,9 @@ char* Serialize${MODEL_SAFE_TYPE}Ptr(void* ptr, size_t* length)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
{
|
||||
boost::archive::binary_oarchive oa(oss);
|
||||
cereal::BinaryOutputArchive oa(oss);
|
||||
${MODEL_TYPE}* model = (${MODEL_TYPE}*) ptr;
|
||||
oa << boost::serialization::make_nvp(\"${MODEL_SAFE_TYPE}\", model);
|
||||
oa(CEREAL_POINTER(model));
|
||||
}
|
||||
|
||||
*length = oss.str().length();
|
||||
@@ -105,16 +72,16 @@ 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)
|
||||
{
|
||||
${MODEL_TYPE}* t = new ${MODEL_TYPE}();
|
||||
${MODEL_TYPE}* model = new ${MODEL_TYPE}();
|
||||
|
||||
std::istringstream iss(std::string(buffer, length));
|
||||
{
|
||||
boost::archive::binary_iarchive ia(iss);
|
||||
ia >> boost::serialization::make_nvp(\"${MODEL_SAFE_TYPE}\", t);
|
||||
cereal::BinaryInputArchive ia(iss);
|
||||
ia(CEREAL_POINTER(model));
|
||||
}
|
||||
|
||||
// Julia will be responsible for freeing this.
|
||||
return (void*) t;
|
||||
return (void*) model;
|
||||
}
|
||||
")
|
||||
endforeach ()
|
||||
|
||||
+74
-67
@@ -16,8 +16,14 @@ option(BUILD_CLI_EXECUTABLES "Build command-line executables." ON)
|
||||
option(DISABLE_DOWNLOADS "Disable downloads of dependencies during build." OFF)
|
||||
option(DOWNLOAD_ENSMALLEN "If ensmallen is not found, download it." ON)
|
||||
option(DOWNLOAD_STB_IMAGE "Download stb_image for image loading." ON)
|
||||
option(BUILD_PYTHON_BINDINGS "Build Python bindings." ON)
|
||||
option(BUILD_GO_SHLIB "Build Go shared library." OFF)
|
||||
option(BUILD_DOCS "Build doxygen documentation (if doxygen is available)." ON)
|
||||
|
||||
# Set minimum library version required by mlpack.
|
||||
set(ARMADILLO_VERSION "8.400.0")
|
||||
set(ENSMALLEN_VERSION "2.10.0")
|
||||
set(BOOST_VERSION "1.58")
|
||||
set(CEREAL_VERSION "1.1.2")
|
||||
|
||||
if (WIN32)
|
||||
option(BUILD_SHARED_LIBS
|
||||
@@ -30,6 +36,15 @@ else ()
|
||||
"Compile shared libraries (if OFF, static libraries are compiled)." ON)
|
||||
endif()
|
||||
|
||||
# Detect whether the user passed BUILD_PYTHON_BINDINGS in order to determine if
|
||||
# we should fail if Python isn't found.
|
||||
if (BUILD_PYTHON_BINDINGS)
|
||||
set(FORCE_BUILD_PYTHON_BINDINGS ON)
|
||||
else()
|
||||
set(FORCE_BUILD_PYTHON_BINDINGS OFF)
|
||||
endif()
|
||||
option(BUILD_PYTHON_BINDINGS "Build Python bindings." OFF)
|
||||
|
||||
# Detect whether the user passed BUILD_JULIA_BINDINGS in order to determine if
|
||||
# we should fail if Julia isn't found.
|
||||
if (BUILD_JULIA_BINDINGS)
|
||||
@@ -48,11 +63,19 @@ else()
|
||||
endif()
|
||||
option(BUILD_GO_BINDINGS "Build Go bindings." ON)
|
||||
|
||||
# If building Go bindings then build go shared libraries.
|
||||
# If building Go bindings then build go shared libraries.
|
||||
if (BUILD_GO_BINDINGS)
|
||||
set(BUILD_GO_SHLIB ON)
|
||||
endif()
|
||||
|
||||
# Detect whether the user passed BUILD_R_BINDINGS in order to determine if
|
||||
# we should fail if R isn't found.
|
||||
if (BUILD_R_BINDINGS)
|
||||
set(FORCE_BUILD_R_BINDINGS ON)
|
||||
else()
|
||||
set(FORCE_BUILD_R_BINDINGS OFF)
|
||||
endif()
|
||||
option(BUILD_R_BINDINGS "Build R bindings." ON)
|
||||
# Build Markdown bindings for documentation. This is used as part of website
|
||||
# generation.
|
||||
option(BUILD_MARKDOWN_BINDINGS "Build Markdown bindings for website documentation." OFF)
|
||||
@@ -119,7 +142,7 @@ set(COMPILER_SUPPORT_LIBRARIES "")
|
||||
|
||||
# If we are using MSVC, we need /bigobj.
|
||||
if (MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /Zm400")
|
||||
endif ()
|
||||
|
||||
# If we are using MINGW, we need sections and big-obj, otherwise we create too
|
||||
@@ -266,11 +289,10 @@ endif()
|
||||
# ARMADILLO_INCLUDE_DIRS - directories necessary for Armadillo includes
|
||||
# BOOST_ROOT - root of Boost installation
|
||||
# BOOST_INCLUDEDIR - include directory for Boost
|
||||
# BOOST_LIBRARYDIR - library directory for Boost
|
||||
# ENSMALLEN_INCLUDE_DIR - include directory for ensmallen
|
||||
# STB_IMAGE_INCLUDE_DIR - include directory for STB image library
|
||||
# MATHJAX_ROOT - root of MathJax installation
|
||||
find_package(Armadillo 8.400.0 REQUIRED)
|
||||
find_package(Armadillo "${ARMADILLO_VERSION}" REQUIRED)
|
||||
|
||||
# Include directories for the previous dependencies.
|
||||
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${ARMADILLO_INCLUDE_DIRS})
|
||||
@@ -332,11 +354,10 @@ else ()
|
||||
set(STB_AVAILABLE "1")
|
||||
endif ()
|
||||
|
||||
|
||||
# Find ensmallen.
|
||||
# Once ensmallen is readily available in package repos, the automatic downloader
|
||||
# here can be removed.
|
||||
find_package(Ensmallen 2.10.0)
|
||||
find_package(Ensmallen "${ENSMALLEN_VERSION}")
|
||||
if (NOT ENSMALLEN_FOUND)
|
||||
if (DOWNLOAD_ENSMALLEN)
|
||||
file(DOWNLOAD http://www.ensmallen.org/files/ensmallen-latest.tar.gz
|
||||
@@ -392,9 +413,14 @@ else ()
|
||||
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} "${ENSMALLEN_INCLUDE_DIR}")
|
||||
endif ()
|
||||
|
||||
find_package(cereal "${CEREAL_VERSION}" REQUIRED)
|
||||
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${CEREAL_INCLUDE_DIR})
|
||||
|
||||
# Unfortunately this configuration variable is necessary and will need to be
|
||||
# updated as time goes on and new versions are released.
|
||||
set(Boost_ADDITIONAL_VERSIONS
|
||||
"1.74.0" "1.74"
|
||||
"17.3.0" "17.3"
|
||||
"1.72.0" "1.72"
|
||||
"1.71.0" "1.71"
|
||||
"1.70.0" "1.70"
|
||||
@@ -416,33 +442,11 @@ set(Boost_ADDITIONAL_VERSIONS
|
||||
# TODO for the brave: transition all mlpack's CMake to 'target-based modern
|
||||
# CMake'. Good luck! You'll need it.
|
||||
set(Boost_NO_BOOST_CMAKE 1)
|
||||
find_package(Boost 1.58
|
||||
COMPONENTS
|
||||
unit_test_framework
|
||||
serialization
|
||||
REQUIRED
|
||||
)
|
||||
|
||||
link_directories(${Boost_LIBRARY_DIRS})
|
||||
|
||||
# In Visual Studio, automatic linking is performed, so we don't need to worry
|
||||
# about it. Clear the list of libraries to link against and let Visual Studio
|
||||
# handle it.
|
||||
if (MSVC)
|
||||
link_directories(${Boost_LIBRARY_DIRS})
|
||||
set(CMAKE_MSVCIDE_RUN_PATH ${CMAKE_MSVCIDE_RUN_PATH} ${Boost_LIBRARY_DIRS})
|
||||
message("boost lib dirs ${Boost_LIBRARY_DIRS}")
|
||||
set(Boost_LIBRARIES "")
|
||||
endif ()
|
||||
find_package(Boost "${BOOST_VERSION}")
|
||||
|
||||
set(MLPACK_INCLUDE_DIRS ${MLPACK_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
|
||||
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES} ${Boost_LIBRARIES})
|
||||
set(MLPACK_LIBRARY_DIRS ${MLPACK_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS})
|
||||
|
||||
# For Boost testing framework (will have no effect on non-testing executables).
|
||||
# This specifies to Boost that we are dynamically linking to the Boost test
|
||||
# library.
|
||||
add_definitions(-DBOOST_TEST_DYN_LINK)
|
||||
set(MLPACK_LIBRARIES ${MLPACK_LIBRARIES})
|
||||
set(MLPACK_LIBRARY_DIRS ${MLPACK_LIBRARY_DIRS})
|
||||
|
||||
# Detect OpenMP support in a compiler. If the compiler supports OpenMP, flags
|
||||
# to compile with OpenMP are returned and added and the HAS_OPENMP definition
|
||||
@@ -545,6 +549,7 @@ add_custom_target(mlpack_arma_config ALL
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D ARMADILLO_INCLUDE_DIR="${ARMADILLO_INCLUDE_DIR}"
|
||||
-D OPENMP_FOUND="${OPENMP_FOUND}"
|
||||
-D CMAKE_SIZEOF_VOID_P="${CMAKE_SIZEOF_VOID_P}"
|
||||
-P CMake/CreateArmaConfigInfo.cmake
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Updating arma_config.hpp (if necessary)")
|
||||
@@ -592,43 +597,45 @@ add_dependencies(mlpack_headers mlpack_arma_config)
|
||||
|
||||
# Make a target to generate the documentation. If Doxygen isn't installed, then
|
||||
# I guess this option will just be unavailable.
|
||||
find_package(Doxygen)
|
||||
if (DOXYGEN_FOUND)
|
||||
if (MATHJAX)
|
||||
find_package(MathJax)
|
||||
if (NOT MATHJAX_FOUND)
|
||||
message(STATUS "Using MathJax at the MathJax Content Delivery Network. "
|
||||
"Be careful, formulas will not be shown without the internet.")
|
||||
if (BUILD_DOCS)
|
||||
find_package(Doxygen)
|
||||
if (DOXYGEN_FOUND)
|
||||
if (MATHJAX)
|
||||
find_package(MathJax)
|
||||
if (NOT MATHJAX_FOUND)
|
||||
message(STATUS "Using MathJax at the MathJax Content Delivery Network. "
|
||||
"Be careful, formulas will not be shown without the internet.")
|
||||
endif ()
|
||||
endif ()
|
||||
# Preprocess the Doxyfile. This is done before 'make doc'.
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/Doxyfile
|
||||
PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D DESTDIR=${CMAKE_BINARY_DIR}
|
||||
-D MATHJAX="${MATHJAX}"
|
||||
-D MATHJAX_FOUND="${MATHJAX_FOUND}"
|
||||
-D MATHJAX_PATH="${MATHJAX_PATH}"
|
||||
-P "${CMAKE_CURRENT_SOURCE_DIR}/CMake/GenerateDoxyfile.cmake"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile"
|
||||
COMMENT "Creating Doxyfile to generate Doxygen documentation"
|
||||
)
|
||||
|
||||
# Generate documentation.
|
||||
add_custom_target(doc
|
||||
COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/Doxyfile"
|
||||
DEPENDS "${CMAKE_BINARY_DIR}/Doxyfile"
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
COMMENT "Generating API documentation with Doxygen"
|
||||
)
|
||||
|
||||
install(DIRECTORY "${CMAKE_BINARY_DIR}/doc/html"
|
||||
DESTINATION "${CMAKE_INSTALL_DOCDIR}"
|
||||
COMPONENT doc
|
||||
OPTIONAL
|
||||
)
|
||||
endif ()
|
||||
# Preprocess the Doxyfile. This is done before 'make doc'.
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/Doxyfile
|
||||
PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D DESTDIR=${CMAKE_BINARY_DIR}
|
||||
-D MATHJAX="${MATHJAX}"
|
||||
-D MATHJAX_FOUND="${MATHJAX_FOUND}"
|
||||
-D MATHJAX_PATH="${MATHJAX_PATH}"
|
||||
-P "${CMAKE_CURRENT_SOURCE_DIR}/CMake/GenerateDoxyfile.cmake"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile"
|
||||
COMMENT "Creating Doxyfile to generate Doxygen documentation"
|
||||
)
|
||||
|
||||
# Generate documentation.
|
||||
add_custom_target(doc
|
||||
COMMAND "${DOXYGEN_EXECUTABLE}" "${CMAKE_BINARY_DIR}/Doxyfile"
|
||||
DEPENDS "${CMAKE_BINARY_DIR}/Doxyfile"
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
COMMENT "Generating API documentation with Doxygen"
|
||||
)
|
||||
|
||||
install(DIRECTORY "${CMAKE_BINARY_DIR}/doc/html"
|
||||
DESTINATION "${CMAKE_INSTALL_DOCDIR}"
|
||||
COMPONENT doc
|
||||
OPTIONAL
|
||||
)
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
# Create the pkg-config file, if we have pkg-config.
|
||||
find_package(PkgConfig)
|
||||
|
||||
+19
-11
@@ -7,7 +7,7 @@ Source:
|
||||
|
||||
Files: *
|
||||
Copyright:
|
||||
Copyright 2008-2018, Ryan Curtin <ryan@ratml.org>
|
||||
Copyright 2008-2020, Ryan Curtin <ryan@ratml.org>
|
||||
Copyright 2008-2013, Bill March <march@gatech.edu>
|
||||
Copyright 2008-2012, Dongryeol Lee <dongryel@cc.gatech.edu>
|
||||
Copyright 2008-2013, Nishant Mehta <niche@cc.gatech.edu>
|
||||
@@ -22,11 +22,11 @@ Copyright:
|
||||
Copyright 2012, Rajendran Mohan <rmohan88@gatech.edu>
|
||||
Copyright 2012, Trironk Kiatkungwanglai <trironk@gmail.com>
|
||||
Copyright 2012, Patrick Mason <patrick.s.mason@gmail.com>
|
||||
Copyright 2013-2018, Marcus Edel <marcus.edel@fu-berlin.de>
|
||||
Copyright 2013-2020, Marcus Edel <marcus.edel@fu-berlin.de>
|
||||
Copyright 2013, Mudit Raj Gupta <mudit.raaj.gupta@gmail.com>
|
||||
Copyright 2013-2018, Sumedh Ghaisas <sumedhghaisas@gmail.com>
|
||||
Copyright 2014, Michael Fox <michaelfox99@gmail.com>
|
||||
Copyright 2014, Ryan Birmingham <birm@gatech.edu>
|
||||
Copyright 2014,2020 Ryan Birmingham <birm@gatech.edu>
|
||||
Copyright 2014, Siddharth Agrawal <siddharth.950@gmail.com>
|
||||
Copyright 2014, Saheb Motiani <saheb210692@gmail.com>
|
||||
Copyright 2014, Yash Vadalia <yashdv@gmail.com>
|
||||
@@ -37,7 +37,7 @@ Copyright:
|
||||
Copyright 2014, Udit Saxena <saxenda.udit@gmail.com>
|
||||
Copyright 2014-2015, Stephen Tu <tu.stephenl@gmail.com>
|
||||
Copyright 2014-2015, Jaskaran Singh <jaskaranvirdi@ymail.com>
|
||||
Copyright 2015&2017, Shangtong Zhang <zhangshangtong.cpp@gmail.com>
|
||||
Copyright 2015,2017, Shangtong Zhang <zhangshangtong.cpp@gmail.com>
|
||||
Copyright 2015, Hritik Jain <hritik.jain.cse13@itbhu.ac.in>
|
||||
Copyright 2015, Vladimir Glazachev <glazachev.vladimir@gmail.com>
|
||||
Copyright 2015, QiaoAn Chen <kazenoyumechen@gmail.com>
|
||||
@@ -55,7 +55,7 @@ Copyright:
|
||||
Copyright 2016, Palash Ahuja <abhor902@gmail.com>
|
||||
Copyright 2016, Yannis Mentekidis <mentekid@gmail.com>
|
||||
Copyright 2016, Ranjan Mondal <ranjan.rev@gmail.com>
|
||||
Copyright 2016-2018, Mikhail Lozhnikov <lozhnikovma@gmail.com>
|
||||
Copyright 2016-2020, Mikhail Lozhnikov <lozhnikovma@gmail.com>
|
||||
Copyright 2016, Marcos Pividori <marcos.pividori@gmail.com>
|
||||
Copyright 2016, Keon Kim <kwk236@gmail.com>
|
||||
Copyright 2016, Nilay Jain <nilayjain13@gmail.com>
|
||||
@@ -84,14 +84,14 @@ Copyright:
|
||||
Copyright 2017, N Rajiv Vaidyanathan <rajivvaidyanathan4@gmail.com>
|
||||
Copyright 2017, Kartik Nighania <kartiknighania@gmail.com>
|
||||
Copyright 2017-2018, Eugene Freyman <evg.freyman@gmail.com>
|
||||
Copyright 2017-2018, Manish Kumar <manish887kr@gmail.com>
|
||||
Copyright 2017-2019, Manish Kumar <manish887kr@gmail.com>
|
||||
Copyright 2017-2018, Haritha Sreedharan Nair <haritha1313@gmail.com>
|
||||
Copyright 2017-2018, Sourabh Varshney <sourabhvarshney111@gmail.com>
|
||||
Copyright 2018, Projyal Dev <projyal@gmail.com>
|
||||
Copyright 2018, Nikhil Goel <nikhilgoel199797@gmail.com>
|
||||
Copyright 2018, Shikhar Jaiswal <jaiswalshikhar87@gmail.com>
|
||||
Copyright 2018-2020 Shikhar Jaiswal <jaiswalshikhar87@gmail.com>
|
||||
Copyright 2018, B Kartheek Reddy <bkartheekreddy@gmail.com>
|
||||
Copyright 2018, Atharva Khandait <akhandait45@gmail.com>
|
||||
Copyright 2018-2019 Atharva Khandait <akhandait45@gmail.com>
|
||||
Copyright 2018, Wenhao Huang <wenhao.huang.work@gmail.com>
|
||||
Copyright 2018-2019, Roberto Hueso <robertohueso96@gmail.com>
|
||||
Copyright 2018, Prabhat Sharma <prabhatsharma7298@gmail.com>
|
||||
@@ -114,9 +114,9 @@ Copyright:
|
||||
Copyright 2019, Miguel Canteras <mcanteras@gmail.com>
|
||||
Copyright 2019, Bishwa Karki <karkeebishwa1@gmail.com>
|
||||
Copyright 2019, Mehul Kumar Nirala <mehulkumarnirala@gmail.com>
|
||||
Copyright 2019, Yashwant Singh Parihar <yashwantsingh.sngh@gmail.com>
|
||||
Copyright 2019-2020 Yashwant Singh Parihar <yashwantsingh.sngh@gmail.com>
|
||||
Copyright 2019, Heet Sankesara <heetsankesara3@gmail.com>
|
||||
Copyright 2019, Jeffin Sam <sam.jeffin@gmail.com>
|
||||
Copyright 2019-2020 Jeffin Sam <sam.jeffin@gmail.com>
|
||||
Copyright 2019, Vikas S Shetty <shettyvikas209@gmail.com>
|
||||
Copyright 2019, Khizir Siddiqui <khizirsiddiqui@gmail.com>
|
||||
Copyright 2019, Tejasvi Tomar <tstomar@outlook.com>
|
||||
@@ -124,7 +124,7 @@ Copyright:
|
||||
Copyright 2019, Ziyang Jiang <zij004@alumni.stanford.edu>
|
||||
Copyright 2019, Rohit Kartik <rohit.audrey@gmail.com>
|
||||
Copyright 2019, Aditya Viki <adityaviki01@gmail.com>
|
||||
Copyright 2019, Kartik Dutt <kartikdutt@live.in>
|
||||
Copyright 2019-2020 Kartik Dutt <kartikdutt@live.in>
|
||||
Copyright 2020, Sriram S K <sriramsk1999@gmail.com>
|
||||
Copyright 2020, Manoranjan Kumar Bharti ( Nakul Bharti ) <knakul853@gmail.com>
|
||||
Copyright 2020, Saraansh Tandon <saraanshtandon1999@gmail.com>
|
||||
@@ -132,6 +132,14 @@ Copyright:
|
||||
Copyright 2020, Lakshya Ojha <ojhalakshya@gmail.com>
|
||||
Copyright 2020, Bisakh Mondal <bisakhmondal00@gmail.com>
|
||||
Copyright 2020, Benson Muite <benson_muite@emailplus.org>
|
||||
Copyright 2020, Sarthak Bhardwaj <7sarthakbhardwaj@gmail.com>
|
||||
Copyright 2020, Aakash Kaushik <kaushikaakash7539@gmail.com>
|
||||
Copyright 2020, Anush Kini <anushkini@gmail.com>
|
||||
Copyright 2020, Nippun Sharma <inbox.nippun@gmail.com>
|
||||
Copyright 2020, Rishabh Garg <rishabhgarg108@gmail.com>
|
||||
Copyright 2020, Sudhakar Brar <dxhrmhall1449@tutanota.com>
|
||||
Copyright 2020, Alex Nguyen <alexvn.edu@gmail.com>
|
||||
Copyright 2020, Gaurav Ghati <gauravghatii@gmail.com>
|
||||
|
||||
License: BSD-3-clause
|
||||
All rights reserved.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = mlpack
|
||||
PROJECT_NUMBER = 3.2.2
|
||||
PROJECT_NUMBER = 3.4.2
|
||||
OUTPUT_DIRECTORY = ./doc
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
@@ -75,7 +75,8 @@ FILE_VERSION_FILTER =
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_AS_ERROR = YES
|
||||
# This will be set to YES for the Jenkins doxygen check build.
|
||||
WARN_AS_ERROR = NO
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = YES
|
||||
@@ -106,7 +107,8 @@ EXCLUDE_PATTERNS = */build/* \
|
||||
*.cc \
|
||||
*_test.cpp \
|
||||
*CLI11.hpp \
|
||||
*/tests/catch.hpp
|
||||
*/tests/catch.hpp \
|
||||
*/boost/serialization/*
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
|
||||
+63
@@ -1,5 +1,57 @@
|
||||
### mlpack ?.?.?
|
||||
###### ????-??-??
|
||||
* Added an implementation to Stratify Data (#2671).
|
||||
|
||||
* Add `BUILD_DOCS` CMake option to control whether Doxygen documentation is
|
||||
built (default ON) (#2730).
|
||||
|
||||
### mlpack 3.4.2
|
||||
###### 2020-10-26
|
||||
* Added Mean Absolute Percentage Error.
|
||||
|
||||
* Added Softmin activation function as layer in ann/layer.
|
||||
|
||||
* Fix spurious ARMA_64BIT_WORD compilation warnings on 32-bit systems (#2665).
|
||||
|
||||
### mlpack 3.4.1
|
||||
###### 2020-09-07
|
||||
* Fix incorrect parsing of required matrix/model parameters for command-line
|
||||
bindings (#2600).
|
||||
|
||||
* Add manual type specification support to `data::Load()` and `data::Save()`
|
||||
(#2084, #2135, #2602).
|
||||
|
||||
* Remove use of internal Armadillo functionality (#2596, #2601, #2602).
|
||||
|
||||
### mlpack 3.4.0
|
||||
###### 2020-09-01
|
||||
|
||||
* Issue warnings when metrics produce NaNs in KFoldCV (#2595).
|
||||
|
||||
* Added bindings for _R_ during Google Summer of Code (#2556).
|
||||
|
||||
* Added common striptype function for all bindings (#2556).
|
||||
|
||||
* Refactored common utility function of bindings to bindings/util (#2556).
|
||||
|
||||
* Renamed InformationGain to HoeffdingInformationGain in
|
||||
methods/hoeffding_trees/information_gain.hpp (#2556).
|
||||
|
||||
* Added macro for changing stream of printing and warnings/errors (#2556).
|
||||
|
||||
* Added Spatial Dropout layer (#2564).
|
||||
|
||||
* Force CMake to show error when it didn't find Python/modules (#2568).
|
||||
|
||||
* Refactor `ProgramInfo()` to separate out all the different
|
||||
information (#2558).
|
||||
|
||||
* Add bindings for one-hot encoding (#2325).
|
||||
|
||||
* Added Soft Actor-Critic to RL methods (#2487).
|
||||
|
||||
* Added Categorical DQN to q_networks (#2454).
|
||||
|
||||
* Added N-step DQN to q_networks (#2461).
|
||||
|
||||
* Add Silhoutte Score metric and Pairwise Distances (#2406).
|
||||
@@ -11,6 +63,17 @@
|
||||
* Additional functionality for the ARFF loader (#2486); use case sensitive
|
||||
categories (#2516).
|
||||
|
||||
* Add `bayesian_linear_regression` binding for the command-line, Python,
|
||||
Julia, and Go. Also called "Bayesian Ridge", this is equivalent to a
|
||||
version of linear regression where the regularization parameter is
|
||||
automatically tuned (#2030).
|
||||
|
||||
* Fix defeatist search for spill tree traversals (#2566, #1269).
|
||||
|
||||
* Fix incremental training of logistic regression models (#2560).
|
||||
|
||||
* Change default configuration of `BUILD_PYTHON_BINDINGS` to `OFF` (#2575).
|
||||
|
||||
### mlpack 3.3.2
|
||||
###### 2020-06-18
|
||||
* Added Noisy DQN to q_networks (#2446).
|
||||
|
||||
@@ -23,7 +23,7 @@ src="https://cdn.rawgit.com/mlpack/mlpack.org/e7d36ed8/mlpack-black.svg" style="
|
||||
<p align="center">
|
||||
<em>
|
||||
Download:
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.2.2.tar.gz">current stable version (3.2.2)</a>
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.4.2.tar.gz">current stable version (3.4.2)</a>
|
||||
</em>
|
||||
</p>
|
||||
|
||||
@@ -32,7 +32,7 @@ bindings to other languages. It is meant to be a machine learning analog to
|
||||
LAPACK, and aims to implement a wide array of machine learning methods and
|
||||
functions as a "swiss army knife" for machine learning researchers. In addition
|
||||
to its powerful C++ interface, mlpack also provides command-line programs,
|
||||
Python bindings, and Julia bindings.
|
||||
Python bindings, Julia bindings, Go bindings and R bindings.
|
||||
|
||||
[//]: # (numfocus-fiscal-sponsor-attribution)
|
||||
|
||||
@@ -101,10 +101,10 @@ Citations are beneficial for the growth and improvement of mlpack.
|
||||
mlpack has the following dependencies:
|
||||
|
||||
Armadillo >= 8.400.0
|
||||
Boost (math_c99, unit_test_framework, serialization,
|
||||
spirit) >= 1.58.0
|
||||
Boost (math_c99, spirit) >= 1.58.0
|
||||
CMake >= 3.2.2
|
||||
ensmallen >= 2.10.0
|
||||
cereal >= 1.1.2
|
||||
|
||||
All of those should be available in your distribution's package manager. If
|
||||
not, you will have to compile each of them by hand. See the documentation for
|
||||
@@ -121,6 +121,20 @@ following Python packages are installed:
|
||||
If you would like to build the Julia bindings, make sure that Julia >= 1.3.0 is
|
||||
installed.
|
||||
|
||||
If you would like to build the Go bindings, make sure that Go >= 1.11.0 is
|
||||
installed with this package:
|
||||
|
||||
Gonum
|
||||
|
||||
If you would like to build the R bindings, make sure that R >= 4.0 is
|
||||
installed with these R packages.
|
||||
|
||||
Rcpp >= 0.12.12
|
||||
RcppArmadillo >= 0.8.400.0
|
||||
RcppEnsmallen >= 0.2.10.0
|
||||
BH >= 1.58
|
||||
roxygen2
|
||||
|
||||
If the STB library headers are available, image loading support will be
|
||||
compiled.
|
||||
|
||||
@@ -132,13 +146,17 @@ This document discusses how to build mlpack from source. These build directions
|
||||
will work for any Linux-like shell environment (for example Ubuntu, macOS,
|
||||
FreeBSD etc). However, mlpack is in the repositories of many Linux distributions
|
||||
and so it may be easier to use the package manager for your system. For example,
|
||||
on Ubuntu, you can install mlpack with the following command:
|
||||
on Ubuntu, you can install the mlpack library and command-line executables (e.g.
|
||||
mlpack_pca, mlpack_kmeans etc.) with the following command:
|
||||
|
||||
$ sudo apt-get install libmlpack-dev
|
||||
$ sudo apt-get install libmlpack-dev mlpack-bin
|
||||
|
||||
On Fedora or Red Hat (EPEL):
|
||||
$ sudo dnf install mlpack-devel mlpack-bin
|
||||
|
||||
Note: Older Ubuntu versions may not have the most recent version of mlpack
|
||||
available---for instance, at the time of this writing, Ubuntu 16.04 only has
|
||||
mlpack 3.2.2 available. Options include upgrading your Ubuntu version, finding
|
||||
mlpack 3.4.2 available. Options include upgrading your Ubuntu version, finding
|
||||
a PPA or other non-official sources, or installing with a manual build.
|
||||
|
||||
There are some useful pages to consult in addition to this section:
|
||||
@@ -190,6 +208,8 @@ Options are specified with the -D flag. The allowed options include:
|
||||
BUILD_GO_BINDINGS=(ON/OFF): whether or not to build Go bindings
|
||||
GO_EXECUTABLE=(/path/to/go): Path to specific Go executable
|
||||
BUILD_GO_SHLIB=(ON/OFF): whether or not to build shared libraries required by Go bindings
|
||||
BUILD_R_BINDINGS=(ON/OFF): whether or not to build R bindings
|
||||
R_EXECUTABLE=(/path/to/R): Path to specific R executable
|
||||
BUILD_TESTS=(ON/OFF): whether or not to build tests
|
||||
BUILD_SHARED_LIBS=(ON/OFF): compile shared libraries as opposed to
|
||||
static libraries
|
||||
@@ -201,6 +221,8 @@ Options are specified with the -D flag. The allowed options include:
|
||||
STB_IMAGE_INCLUDE_DIR=(/path/to/stb/include): path to include directory for
|
||||
STB image library
|
||||
USE_OPENMP=(ON/OFF): whether or not to use OpenMP if available
|
||||
BUILD_DOCS=(ON/OFF): build Doxygen documentation, if Doxygen is available
|
||||
(default ON)
|
||||
|
||||
Other tools can also be used to configure CMake, but those are not documented
|
||||
here. See [this section of the build guide](https://www.mlpack.org/doc/mlpack-git/doxygen/build.html#build_config)
|
||||
|
||||
+30
-39
@@ -2,47 +2,38 @@
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<!-- 1) DO NOT CHANGE the product GUID! It is forever -->
|
||||
<!-- 2) %MLPACK_VERSION env var is set by .appveyor.yml -->
|
||||
<Product Id="02A00C77-197D-4E91-B7D9-5836220E92E9"
|
||||
UpgradeCode="6C2D7EC0-6F10-40CB-9703-1DC160A62662"
|
||||
Name="mlpack"
|
||||
Language="1033"
|
||||
Version="$(env.MLPACK_VERSION)"
|
||||
Manufacturer="mlpack">
|
||||
|
||||
<Package InstallerVersion="200"
|
||||
Description="mlpack Windows Installer"
|
||||
Compressed="yes"
|
||||
InstallScope="perMachine"
|
||||
Platform="x64"/>
|
||||
<Product Id="02A00C77-197D-4E91-B7D9-5836220E92E9"
|
||||
UpgradeCode="6C2D7EC0-6F10-40CB-9703-1DC160A62662"
|
||||
Name="mlpack"
|
||||
Language="1033"
|
||||
Version="$(env.MLPACK_VERSION)"
|
||||
Manufacturer="mlpack">
|
||||
<Package InstallerVersion="200"
|
||||
Description="mlpack Windows Installer"
|
||||
Compressed="yes"
|
||||
InstallScope="perMachine"
|
||||
Platform="x64"/>
|
||||
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
|
||||
|
||||
<MediaTemplate EmbedCab="yes"/>
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
|
||||
<MediaTemplate EmbedCab="yes"/>
|
||||
|
||||
<Feature Id="ProductFeature" Title="mlpackWindows" Level="1">
|
||||
<ComponentGroupRef Id="ProductComponents" />
|
||||
</Feature>
|
||||
<Property Id="MLPACK_VERSION">$(env.MLPACK_VERSION)</Property>
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
|
||||
<WixVariable Id="WixUILicenseRtf" Value="..\staging\license.rtf"/>
|
||||
<WixVariable Id="WixUIBannerBmp" Value="..\res\banner.jpg"/>
|
||||
<WixVariable Id="WixUIDialogBmp" Value="..\res\dialog_white.jpg"/>
|
||||
<UIRef Id="WixUI_InstallDir" />
|
||||
</Product>
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="ProgramFilesFolder" Name="PFiles">
|
||||
<Directory Id="INSTALLDIR" Name="mlpack">
|
||||
<Directory Id="Sources" />
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
|
||||
<Fragment>
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="ProgramFiles64Folder">
|
||||
<Directory Id="INSTALLFOLDER" Name="mlpack" />
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Fragment>
|
||||
|
||||
<Fragment>
|
||||
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
|
||||
<!-- This references the list of mlpack files automatically generated using Heat (see .wixproj BeforeBuild Target) -->
|
||||
<ComponentGroupRef Id="HeatGenerated"/>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
<Feature Id="ProductFeature" Title="mlpackWindows" ConfigurableDirectory="INSTALLDIR" Level="1">
|
||||
<ComponentGroupRef Id="Sources" />
|
||||
</Feature>
|
||||
|
||||
<Property Id="MLPACK_VERSION">$(env.MLPACK_VERSION)</Property>
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
|
||||
<WixVariable Id="WixUILicenseRtf" Value="..\staging\license.rtf"/>
|
||||
<WixVariable Id="WixUIBannerBmp" Value="..\res\banner.jpg"/>
|
||||
<WixVariable Id="WixUIDialogBmp" Value="..\res\dialog_white.jpg"/>
|
||||
<UIRef Id="WixUI_InstallDir" />
|
||||
</Product>
|
||||
</Wix>
|
||||
|
||||
@@ -9,33 +9,36 @@
|
||||
<OutputName>mlpack-windows</OutputName>
|
||||
<OutputType>Package</OutputType>
|
||||
<Name>mlpack-win-installer</Name>
|
||||
<DefineSolutionProperties>false</DefineSolutionProperties>
|
||||
<DefineConstants>SourceDir=.\Sources</DefineConstants>
|
||||
<WixTargetsPath Condition=" '$(WixTargetsPath' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>Debug</DefineConstants>
|
||||
<DefineConstants>Debug;$(DefineConstants)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<DefineConstants>Debug</DefineConstants>
|
||||
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>Debug;$(DefineConstants)</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<DefineConstants>HarvestPath=..\staging</DefineConstants>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Product.wxs" />
|
||||
<Compile Include="HeatGeneratedFileList.wxs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<HarvestDirectory Include=".\Sources">
|
||||
<DirectoryRefId>Sources</DirectoryRefId>
|
||||
<ComponentGroupName>Sources</ComponentGroupName>
|
||||
<PreprocessorVariable>var.SourceDir</PreprocessorVariable>
|
||||
<SuppressRegistry>true</SuppressRegistry>
|
||||
</HarvestDirectory>
|
||||
<WixExtension Include="WixUIExtension">
|
||||
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
|
||||
<Name>WixUIExtension</Name>
|
||||
@@ -46,14 +49,4 @@
|
||||
<Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
|
||||
<Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" />
|
||||
</Target>
|
||||
<!--
|
||||
To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Wix.targets.-->
|
||||
<Target Name="BeforeBuild">
|
||||
<HeatDirectory Directory="..\staging" PreprocessorVariable="var.HarvestPath" OutputFile="HeatGeneratedFileList.wxs" ComponentGroupName="HeatGenerated" DirectoryRefId="INSTALLFOLDER" AutogenerateGuids="true" ToolPath="$(WixToolPath)" SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" />
|
||||
</Target>
|
||||
<!--
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -104,16 +104,16 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>C:\boost\boost_1_66_0;C:\mlpack\armadillo-8.500.1\include;C:\mlpack\mlpack-3.2.2\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\boost\boost_1_66_0;C:\mlpack\armadillo-8.500.1\include;C:\mlpack\mlpack-3.4.2\build\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>C:\mlpack\mlpack-3.2.2\build\Debug\mlpack.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_serialization-vc141-mt-gd-x64-1_66.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>C:\mlpack\mlpack-3.4.2\build\Debug\mlpack.lib;C:\boost\boost_1_66_0\lib64-msvc-14.1\libboost_serialization-vc141-mt-gd-x64-1_66.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y "C:\mlpack\mlpack-3.2.2\build\Debug\mlpack.dll" $(OutDir)
|
||||
xcopy /y "C:\mlpack\mlpack-3.2.2\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
<Command>xcopy /y "C:\mlpack\mlpack-3.4.2\build\Debug\mlpack.dll" $(OutDir)
|
||||
xcopy /y "C:\mlpack\mlpack-3.4.2\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
xcopy /y "$(ProjectDir)..\..\..\..\src\mlpack\tests\data\german.csv" "$(ProjectDir)data\german.csv*"</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
+199
-58
@@ -19,7 +19,7 @@ The document is split into several sections:
|
||||
- @ref bindings_intro
|
||||
- @ref bindings_code
|
||||
- @ref bindings_general
|
||||
- @ref bindings_general_program_info
|
||||
- @ref bindings_general_program_doc
|
||||
- @ref bindings_general_define_params
|
||||
- @ref bindings_general_functions
|
||||
- @ref bindings_general_more
|
||||
@@ -128,12 +128,18 @@ using namespace std;
|
||||
// being used. Note that the macros must have + on either side of them. We
|
||||
// provide some extra references with the "SEE_ALSO()" macro, which is used to
|
||||
// generate documentation for the website.
|
||||
PROGRAM_INFO("Mean Shift Clustering",
|
||||
// Short description.
|
||||
|
||||
// Program Name.
|
||||
BINDING_NAME("Mean Shift Clustering");
|
||||
|
||||
// Short description.
|
||||
BINDING_SHORT_DESC(
|
||||
"A fast implementation of mean-shift clustering using dual-tree range "
|
||||
"search. Given a dataset, this uses the mean shift algorithm to produce "
|
||||
"and return a clustering of the data.",
|
||||
// Long description.
|
||||
"and return a clustering of the data.");
|
||||
|
||||
// Long description.
|
||||
BINDING_LONG_DESC(
|
||||
"This program performs mean shift clustering on the given dataset, storing "
|
||||
"the learned cluster assignments either as a column of labels in the input "
|
||||
"dataset or separately."
|
||||
@@ -147,22 +153,26 @@ PROGRAM_INFO("Mean Shift Clustering",
|
||||
"\n\n"
|
||||
"The output labels may be saved with the " + PRINT_PARAM_STRING("output") +
|
||||
" output parameter and the centroids of each cluster may be saved with the"
|
||||
" " + PRINT_PARAM_STRING("centroid") + " output parameter."
|
||||
"\n\n"
|
||||
" " + PRINT_PARAM_STRING("centroid") + " output parameter.");
|
||||
|
||||
// Example.
|
||||
BINDING_EXAMPLE(
|
||||
"For example, to run mean shift clustering on the dataset " +
|
||||
PRINT_DATASET("data") + " and store the centroids to " +
|
||||
PRINT_DATASET("centroids") + ", the following command may be used: "
|
||||
"\n\n" +
|
||||
PRINT_CALL("mean_shift", "input", "data", "centroid", "centroids"),
|
||||
SEE_ALSO("@kmeans", "#kmeans"),
|
||||
SEE_ALSO("@dbscan", "#dbscan"),
|
||||
SEE_ALSO("Mean shift on Wikipedia",
|
||||
"https://en.wikipedia.org/wiki/Mean_shift"),
|
||||
SEE_ALSO("Mean Shift, Mode Seeking, and Clustering (pdf)",
|
||||
PRINT_CALL("mean_shift", "input", "data", "centroid", "centroids"));
|
||||
|
||||
// See also...
|
||||
BINDING_SEE_ALSO("@kmeans", "#kmeans");
|
||||
BINDING_SEE_ALSO("@dbscan", "#dbscan");
|
||||
BINDING_SEE_ALSO("Mean shift on Wikipedia",
|
||||
"https://en.wikipedia.org/wiki/Mean_shift");
|
||||
BINDING_SEE_ALSO("Mean Shift, Mode Seeking, and Clustering (pdf)",
|
||||
"http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.510.1222"
|
||||
"&rep=rep1&type=pdf"),
|
||||
SEE_ALSO("mlpack::mean_shift::MeanShift C++ class documentation",
|
||||
"@doxygen/classmlpack_1_1meanshift_1_1MeanShift.html"));
|
||||
"&rep=rep1&type=pdf");
|
||||
BINDING_SEE_ALSO("mlpack::mean_shift::MeanShift C++ class documentation",
|
||||
"@doxygen/classmlpack_1_1meanshift_1_1MeanShift.html");
|
||||
|
||||
// Define parameters for the executable.
|
||||
|
||||
@@ -228,9 +238,10 @@ void mlpackMain()
|
||||
@endcode
|
||||
|
||||
We can see that we have defined the basic program information in the
|
||||
@c PROGRAM_INFO() macro. This is, for instance, what is displayed to describe
|
||||
the binding if the user passed the <tt>\--help</tt> option for a
|
||||
command-line program.
|
||||
@c BINDING_NAME(), @c BINDING_SHORT_DESC(), @c BINDING_LONG_DESC(),
|
||||
@c BINDING_EXAMPLE() and @c BINDING_SEE_ALSO() macros. This is, for instance,
|
||||
what is displayed to describe the binding if the user passed the
|
||||
<tt>\--help</tt> option for a command-line program.
|
||||
|
||||
Then, we define five parameters, three input and two output, that define the
|
||||
data and options that the mean shift clustering will function on. These
|
||||
@@ -247,10 +258,12 @@ whether the parameter is input or output. Some examples:
|
||||
Note that each of these macros may have slightly different syntax. See the
|
||||
links above for further documentation.
|
||||
|
||||
In order to write a new binding, then, you simply must write a @c PROGRAM_INFO()
|
||||
definition of the program with some docuentation, define the input and output
|
||||
parameters as @c PARAM macros, and then write an @c mlpackMain() function that
|
||||
actually performs the functionality of the binding. Inside of @c mlpackMain():
|
||||
In order to write a new binding, then, you simply must write @c BINDING_NAME(),
|
||||
@c BINDING_SHORT_DESC(), @c BINDING_LONG_DESC(), @c BINDING_EXAMPLE() and
|
||||
@c BINDING_SEE_ALSO() definitions of the program with some docuentation, define
|
||||
the input and output parameters as @c PARAM macros, and then write an
|
||||
@c mlpackMain() function that actually performs the functionality of the binding.
|
||||
Inside of @c mlpackMain():
|
||||
|
||||
- All input parameters are accessible through @c IO::GetParam<type>("name").
|
||||
- All output parameters should be set by the end of the function with the
|
||||
@@ -278,15 +291,27 @@ relatively clear how one could use the @c IO functionality along with CMake to
|
||||
add a binding for a new mlpack machine learning method. If it is not clear,
|
||||
then the examples in the following sections should clarify.
|
||||
|
||||
@subsection bindings_general_program_info Documenting a program with PROGRAM_INFO()
|
||||
@subsection bindings_general_program_doc Documenting a program with
|
||||
@c BINDING_NAME(), @c BINDING_SHORT_DESC(), @c BINDING_LONG_DESC(),
|
||||
@c BINDING_EXAMPLE() and @c BINDING_SEE_ALSO().
|
||||
|
||||
Any mlpack program should be documented with the @c PROGRAM_INFO() macro, which
|
||||
is available from the @c <mlpack/core/util/mlpack_main.hpp> header. The macro
|
||||
is of the form
|
||||
Any mlpack program should be documented with the @c BINDING_NAME(),
|
||||
@c BINDING_SHORT_DESC(), @c BINDING_LONG_DESC() , @c BINDING_EXAMPLE() and
|
||||
@c BINDING_SEE_ALSO() macros, which is available from the
|
||||
@c <mlpack/core/util/mlpack_main.hpp> header. The macros
|
||||
are of the form
|
||||
|
||||
@code
|
||||
PROGRAM_INFO("program name", "short documentation", "long documentation",
|
||||
SEE_ALSO("link", "description"), ...)
|
||||
BINDING_NAME("program name");
|
||||
BINDING_SHORT_DESC("This is a short, two-sentence description of what the program does.");
|
||||
BINDING_LONG_DESC("This is a long description of what the program does."
|
||||
" It might be many lines long and have lots of details about different options.");
|
||||
BINDING_EXAMPLE("This contains one example for this particular binding.\n" +
|
||||
PROGRAM_CALL(...));
|
||||
BINDING_EXAMPLE("This contains another example for this particular binding.\n" +
|
||||
PROGRAM_CALL(...));
|
||||
// There could be many of these "see alsos".
|
||||
BINDING_SEE_ALSO("https://en.wikipedia.org/wiki/Machine_learning");
|
||||
@endcode
|
||||
|
||||
The short documentation should be two sentences indicating what the program
|
||||
@@ -368,6 +393,14 @@ Command-line program output (snippet):
|
||||
Python binding output (snippet):
|
||||
|
||||
The parameter 'shuffle', if set, will shuffle the data before learning.
|
||||
|
||||
Julia binding output (snippet):
|
||||
|
||||
The parameter `shuffle`, if set, will shuffle the data before learning.
|
||||
|
||||
Go binding output (snippet):
|
||||
|
||||
The parameter "Shuffle", if set, will shuffle the data before learning.
|
||||
@endcode
|
||||
|
||||
@code
|
||||
@@ -383,6 +416,14 @@ Command-line program output (snippet):
|
||||
Python binding output (snippet):
|
||||
|
||||
The output matrix can be saved with the 'output' output parameter.
|
||||
|
||||
Julia binding output (snippet):
|
||||
|
||||
The output matrix can be saved with the `output` output parameter.
|
||||
|
||||
Go binding output (snippet):
|
||||
|
||||
The output matrix can be saved with the "output" output parameter.
|
||||
@endcode
|
||||
|
||||
@code
|
||||
@@ -408,12 +449,38 @@ Python binding output (snippet):
|
||||
|
||||
>>> output = program(input=x)
|
||||
>>> model = output['output_model']
|
||||
|
||||
Julia binding output (snippet):
|
||||
|
||||
For example, to train a model on the dataset `x` and save the output model to
|
||||
`model`, the following command can be used:
|
||||
|
||||
julia> model = program(input=x)
|
||||
|
||||
Go binding output (snippet):
|
||||
|
||||
For example, to train a model on the dataset "x" and save the output model to
|
||||
"model", the following command can be used:
|
||||
|
||||
// Initialize optional parameters for Program().
|
||||
param := mlpack.ProgramOptions()
|
||||
param.Input = x
|
||||
|
||||
model := mlpack.Program(param)
|
||||
@endcode
|
||||
|
||||
@code
|
||||
Input C++ (full program, 'random_numbers_main.cpp'):
|
||||
|
||||
PROGRAM_INFO("Random Numbers", "This program generates random numbers with a "
|
||||
// Program Name.
|
||||
BINDING_NAME("Random Numbers");
|
||||
|
||||
// Short description.
|
||||
BINDING_SHORT_DESC("An implementation of Random Numbers");
|
||||
|
||||
// Long description.
|
||||
BINDING_LONG_DESC(
|
||||
"This program generates random numbers with a "
|
||||
"variety of nonsensical techniques and example parameters. The input "
|
||||
"dataset, which will be ignored, can be specified with the " +
|
||||
PRINT_PARAM_STRING("input") + " parameter. If you would like to subtract"
|
||||
@@ -425,8 +492,10 @@ Input C++ (full program, 'random_numbers_main.cpp'):
|
||||
"The output random numbers can be saved with the " +
|
||||
PRINT_PARAM_STRING("output") + " output parameter. In addition, a "
|
||||
"randomly generated linear regression model can be saved with the " +
|
||||
PRINT_PARAM_STRING("output_model") + " output parameter."
|
||||
"\n\n"
|
||||
PRINT_PARAM_STRING("output_model") + " output parameter.");
|
||||
|
||||
// Example.
|
||||
BINDING_EXAMPLE(
|
||||
"For example, to generate 100 random numbers with 3 subtracted from them "
|
||||
"and save the output to " + PRINT_DATASET("rand") + " and the random "
|
||||
"model to " + PRINT_MODEL("rand_lr") + ", use the following "
|
||||
@@ -479,17 +548,66 @@ Python binding output:
|
||||
>>> output = random_numbers(num_values=100, subtract=3)
|
||||
>>> rand = output['output']
|
||||
>>> rand_lr = output['output_model']
|
||||
|
||||
Julia binding output:
|
||||
|
||||
Random Numbers
|
||||
|
||||
This program generates random numbers with a variety of nonsensical
|
||||
techniques and example parameters. The input dataset, which will be
|
||||
ignored, can be specified with the `input` parameter. If you would like to
|
||||
subtract values from each number, specify the `subtract` parameter. The
|
||||
number of random numbers to generate is specified with the `num_values`
|
||||
parameter.
|
||||
|
||||
The output random numbers can be saved with the `output` output parameter.
|
||||
In addition, a randomly generated linear regression model can be saved with
|
||||
the `output_model` output parameter.
|
||||
|
||||
For example, to generate 100 random numbers with 3 subtracted from them and
|
||||
save the output to `rand` and the random model to `rand_lr`, use the
|
||||
following command:
|
||||
|
||||
```julia
|
||||
julia> rand, rand_lr = random_numbers(num_values=100, subtract=3)
|
||||
```
|
||||
|
||||
Go binding output:
|
||||
|
||||
Random Numbers
|
||||
|
||||
This program generates random numbers with a variety of nonsensical
|
||||
techniques and example parameters. The input dataset, which will be
|
||||
ignored, can be specified with the "Input" parameter. If you would like to
|
||||
subtract values from each number, specify the "Subtract" parameter. The
|
||||
number of random numbers to generate is specified with the "NumValues"
|
||||
parameter.
|
||||
|
||||
The output random numbers can be saved with the "output" output parameter.
|
||||
In addition, a randomly generated linear regression model can be saved with
|
||||
the "outputModel" output parameter.
|
||||
|
||||
For example, to generate 100 random numbers with 3 subtracted from them and
|
||||
save the output to "rand" and the random model to "randLr", use the
|
||||
following command:
|
||||
|
||||
// Initialize optional parameters for RandomNumbers().
|
||||
param := mlpack.RandomNumbersOptions()
|
||||
param.NumValues = 100
|
||||
param.Subtract=3
|
||||
|
||||
rand, randLr := mlpack.RandomNumbers(param)
|
||||
@endcode
|
||||
|
||||
@subsection bindings_general_define_params Defining parameters for a program
|
||||
|
||||
There exist several macros that can be used after a @c PROGRAM_INFO() definition
|
||||
to define the parameters that can be specified for a given mlpack program.
|
||||
These macros all have the same general definition: the name of the macro
|
||||
specifies the type of the parameter, whether or not the parameter is required,
|
||||
and whether the parameter is an input or output parameter. Then as arguments to
|
||||
the macro, the name, description, and sometimes the single-character alias and
|
||||
the default value of the parameter.
|
||||
There exist several macros that can be used after a @c BINDING_LONG_DESC() and
|
||||
@c BINDING_EXAMPLE() definition to define the parameters that can be specified
|
||||
for a given mlpack program. These macros all have the same general definition:
|
||||
the name of the macro specifies the type of the parameter, whether or not the
|
||||
parameter is required, and whether the parameter is an input or output parameter.
|
||||
Then as arguments to the macros, the name, description, and sometimes the
|
||||
single-character alias and the default value of the parameter.
|
||||
|
||||
To give a flavor of how these definitions look, the definition
|
||||
|
||||
@@ -564,8 +682,8 @@ mlpack models. These could be used, for instance, to allow the user to save a
|
||||
trained model (like a linear regression model) or load an input model. The
|
||||
first parameter to the @c PARAM_MODEL_IN() or @c PARAM_MODEL_OUT() macro should
|
||||
be the C++ type of the model to be serialized; this type @b must have a function
|
||||
<tt>template<typename Archive> void Serialize(Archive&, const unsigned int)</tt>
|
||||
(i.e. the type must be serializable via mlpack's boost::serialization shim).
|
||||
<tt>template<typename Archive> void serialize(Archive&)</tt>
|
||||
(i.e. the type must be serializable via cereal).
|
||||
For example, to allow a user to specify an input model of type
|
||||
`LinearRegression`, the follow definition could be used:
|
||||
|
||||
@@ -620,10 +738,10 @@ Python interface to the user.
|
||||
mlpack's @c IO module provides a unified abstract interface for getting input
|
||||
from and providing output to users without needing to consider the language
|
||||
(command-line, Python, MATLAB, etc.) that the user is running the program from.
|
||||
This means that after the @c PROGRAM_INFO() macro and the @c PARAM_*() macros
|
||||
have been defined, a language-agnostic @c mlpackMain() function can be written.
|
||||
This function then can perform the actual computation that the entire program is
|
||||
meant to.
|
||||
This means that after the @c BINDING_LONG_DESC() and @c BINDING_EXAMPLE() macros
|
||||
and the @c PARAM_*() macros have been defined, a language-agnostic
|
||||
@c mlpackMain() function can be written. This function then can perform the
|
||||
actual computation that the entire program is meant to.
|
||||
|
||||
Inside of an @c mlpackMain() function, the @c mlpack::IO module can be used to
|
||||
access input parameters and set output parameters. There are two main functions
|
||||
@@ -703,7 +821,8 @@ could be created for the "random_numbers" program from earlier sections.
|
||||
@code
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
|
||||
// The PROGRAM_INFO() and PARAM_*() definitions should go here:
|
||||
// BINDING_NAME(), BINDING_SHORT_DESC(), BINDING_LONG_DESC() , BINDING_EXAMPLE(),
|
||||
// BINDING_SEE_ALSO() and PARAM_*() definitions should go here:
|
||||
// ...
|
||||
|
||||
using namespace mlpack;
|
||||
@@ -759,23 +878,43 @@ This section describes the internal functionality of the IO module and the
|
||||
associated macros. If you are only interested in writing mlpack programs, this
|
||||
section is probably not worth reading.
|
||||
|
||||
There are four main components involved with mlpack bindings:
|
||||
There are eight main components involved with mlpack bindings:
|
||||
|
||||
- the IO module, a singleton class that stores parameter information
|
||||
- the mlpackMain() function that defines the functionality of the binding
|
||||
- the PROGRAM_INFO() macro that defines the binding name and documentation
|
||||
- the BINDING_NAME() macro that defines the binding name
|
||||
- the BINDING_SHORT_DESC() macro that defines the short description
|
||||
- the BINDING_LONG_DESC() macro that defines the long description
|
||||
- (optional) the BINDING_EXAMPLE() macro that defines example usages
|
||||
- (optional) the BINDING_SEE_ALSO() macro that defines "see also" links
|
||||
- the PARAM_*() macros that define parameters for the binding
|
||||
|
||||
The mlpack::IO module is a singleton class that stores, at runtime, the binding
|
||||
name, the documentation, and the parameter information and values. In order to
|
||||
do this, each parameter and the program documentation must make themselves known
|
||||
to the IO singleton. This is accomplished by having the @c PROGRAM_INFO() and
|
||||
@c PARAM_*() macros declare global variables that, in their constructors,
|
||||
register themselves with the IO singleton.
|
||||
to the IO singleton. This is accomplished by having the @c BINDING_NAME(),
|
||||
@c BINDING_SHORT_DESC(), @c BINDING_LONG_DESC(), @c BINDING_EXAMPLE(),
|
||||
@c BINDING_SEE_ALSO() and @c PARAM_*() macros declare global variables that,
|
||||
in their constructors, register themselves with the IO singleton.
|
||||
|
||||
The @c PROGRAM_INFO() macro declares an object of type mlpack::util::ProgramDoc.
|
||||
The @c ProgramDoc class constructor calls IO::RegisterProgramDoc() in order to
|
||||
register the given program name and documentation.
|
||||
The @c BINDING_NAME() macro declares an object of type mlpack::util::ProgramName.
|
||||
The @c BINDING_SHORT_DESC() macro declares an object of type
|
||||
mlpack::util::ShortDescription.
|
||||
The @c BINDING_LONG_DESC() macro declares an object of type
|
||||
mlpack::util::LongDescription.
|
||||
The @c BINDING_EXAMPLE() macro declares an object of type mlpack::util::Example.
|
||||
The @c BINDING_SEE_ALSO() macro declares an object of type
|
||||
mlpack::util::SeeAlso.
|
||||
The @c ProgramName class constructor calls IO::RegisterProgramName() in order to
|
||||
register the given program name.
|
||||
The @c ShortDescription class constructor calls IO::RegisterShortDescription() in order to
|
||||
register the given short description.
|
||||
The @c LongDescription class constructor calls IO::RegisterLongDescription() in order to
|
||||
register the given long description.
|
||||
The @c Example class constructor calls IO::RegisterExample() in order to
|
||||
register the given example.
|
||||
The @c SeeAlso class constructor calls IO::RegisterSeeAlso() in order to
|
||||
register the given see-also link.
|
||||
|
||||
The @c PARAM_*() macros declare an object that will, in its constructor, call
|
||||
IO::Add() to register that parameter with the IO singleton. The specific type
|
||||
@@ -875,7 +1014,8 @@ binding:
|
||||
- The options defined by @c PARAM_*() macros are of type
|
||||
mlpack::bindings::cli::CLIOption.
|
||||
|
||||
- The parameter and value printing macros for @c PROGRAM_INFO() are set:
|
||||
- The parameter and value printing macros for @c BINDING_LONG_DESC()
|
||||
and BINDING_EXAMPLE() are set:
|
||||
* The @c PRINT_PARAM_STRING() macro is defined as
|
||||
mlpack::bindings::cli::ParamString().
|
||||
* The @c PRINT_DATASET() macro is defined as
|
||||
@@ -1047,9 +1187,10 @@ individually if you like). The file
|
||||
the name of the program and the @c *_main.cpp file to include correctly, then
|
||||
the @c mlpack::bindings::python::PrintPYX() function is called by the program.
|
||||
The @c PrintPYX() function uses the parameters that have been set in the IO
|
||||
singleton by the @c PROGRAM_INFO() and @c PARAM_*() macros in order to actually
|
||||
print a fully-working .pyx file that can be compiled. The file has several
|
||||
sections:
|
||||
singleton by the @c BINDING_NAME(), @c BINDING_SHORT_DESC(),
|
||||
@c BINDING_LONG_DESC(), @c BINDING_EXAMPLE(), @c BINDING_SEE_ALSO() and
|
||||
@c PARAM_*() macros in order to actually print a fully-working .pyx file that
|
||||
can be compiled. The file has several sections:
|
||||
|
||||
- Python imports (numpy/pandas/cython/etc.)
|
||||
- Cython imports of C++ utility functions and Armadillo functionality
|
||||
|
||||
+39
-23
@@ -2,11 +2,25 @@
|
||||
|
||||
@section build_buildintro Introduction
|
||||
|
||||
This document discusses how to build mlpack from source. These build directions
|
||||
This document discusses how to build mlpack from source. These build directions
|
||||
will work for any Linux-like shell environment (for example Ubuntu, macOS,
|
||||
FreeBSD etc). However, mlpack is in the repositories of many Linux distributions
|
||||
and so it may be easier to use the package manager for your system. For example,
|
||||
on Ubuntu, you can install mlpack with the following command:
|
||||
FreeBSD etc). However, mlpack is in the repositories of many Linux distributions
|
||||
and so it may be easier to use the package manager for your system. For example,
|
||||
on Ubuntu, you can install the mlpack library and command-line executables (e.g.
|
||||
mlpack_pca, mlpack_kmeans, etc.) with the following command:
|
||||
|
||||
@code
|
||||
$ sudo apt-get install libmlpack-dev mlpack-bin
|
||||
@endcode
|
||||
|
||||
On Fedora or Red Hat(EPEL):
|
||||
|
||||
@code
|
||||
$ sudo dnf install mlpack-devel mlpack-bin
|
||||
@endcode
|
||||
|
||||
For installing only the header files and library for building C++ applications
|
||||
on top of mlpack, one could use:
|
||||
|
||||
@code
|
||||
$ sudo apt-get install libmlpack-dev
|
||||
@@ -25,12 +39,12 @@ mlpack uses CMake as a build system and allows several flexible build
|
||||
configuration options. One can consult any of numerous CMake tutorials for
|
||||
further documentation, but this tutorial should be enough to get mlpack built
|
||||
and installed on most Linux and UNIX-like systems (including OS X). If you want
|
||||
to build mlpack on Windows, see \ref build_windows (alternatively, you can read
|
||||
to build mlpack on Windows, see \ref build_windows (alternatively, you can read
|
||||
<a href="https://keon.io/mlpack-on-windows/">Keon's excellent tutorial</a> which
|
||||
is based on older versions).
|
||||
|
||||
You can download the latest mlpack release from here:
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.2.2.tar.gz">mlpack-3.2.2</a>
|
||||
<a href="https://www.mlpack.org/files/mlpack-3.4.2.tar.gz">mlpack-3.4.2</a>
|
||||
|
||||
@section build_simple Simple Linux build instructions
|
||||
|
||||
@@ -38,9 +52,9 @@ Assuming all dependencies are installed in the system, you can run the commands
|
||||
below directly to build and install mlpack.
|
||||
|
||||
@code
|
||||
$ wget https://www.mlpack.org/files/mlpack-3.2.2.tar.gz
|
||||
$ tar -xvzpf mlpack-3.2.2.tar.gz
|
||||
$ mkdir mlpack-3.2.2/build && cd mlpack-3.2.2/build
|
||||
$ wget https://www.mlpack.org/files/mlpack-3.4.2.tar.gz
|
||||
$ tar -xvzpf mlpack-3.4.2.tar.gz
|
||||
$ mkdir mlpack-3.4.2/build && cd mlpack-3.4.2/build
|
||||
$ cmake ../
|
||||
$ make -j4 # The -j is the number of cores you want to use for a build.
|
||||
$ sudo make install
|
||||
@@ -65,8 +79,8 @@ configure mlpack.
|
||||
First we should unpack the mlpack source and create a build directory.
|
||||
|
||||
@code
|
||||
$ tar -xvzpf mlpack-3.2.2.tar.gz
|
||||
$ cd mlpack-3.2.2
|
||||
$ tar -xvzpf mlpack-3.4.2.tar.gz
|
||||
$ cd mlpack-3.4.2
|
||||
$ mkdir build
|
||||
@endcode
|
||||
|
||||
@@ -78,8 +92,8 @@ mlpack depends on the following libraries, which need to be installed on the
|
||||
system and have headers present:
|
||||
|
||||
- Armadillo >= 8.400.0 (with LAPACK support)
|
||||
- Boost (math_c99, serialization, unit_test_framework, heap,
|
||||
spirit) >= 1.58
|
||||
- Boost (math_c99, spirit) >= 1.58
|
||||
- cereal >= 1.1.2
|
||||
- ensmallen >= 2.10.0 (will be downloaded if not found)
|
||||
|
||||
In addition, mlpack has the following optional dependencies:
|
||||
@@ -95,13 +109,13 @@ For Python bindings, the following packages are required:
|
||||
- pandas >= 0.15.0
|
||||
- pytest-runner
|
||||
|
||||
In Ubuntu (>= 18.04) and Debian (>= 10) all of these dependencies can be
|
||||
In Ubuntu (>= 18.04) and Debian (>= 10) all of these dependencies can be
|
||||
installed through apt:
|
||||
|
||||
@code
|
||||
# apt-get install libboost-math-dev libboost-test-dev libboost-serialization-dev
|
||||
libarmadillo-dev binutils-dev python-pandas python-numpy cython
|
||||
python-setuptools
|
||||
# apt-get install libboost-math-dev libcereal-dev
|
||||
libarmadillo-dev binutils-dev python3-pandas python3-numpy cython3
|
||||
python3-setuptools
|
||||
@endcode
|
||||
|
||||
If you are using Ubuntu 19.10 or newer, you can also install @c libensmallen-dev
|
||||
@@ -112,19 +126,19 @@ packages:
|
||||
# apt-get install libensmallen-dev libstb-dev
|
||||
@endcode
|
||||
|
||||
@note For older versions of Ubuntu and Debian, Armadillo needs to be built from
|
||||
source as apt installs an older version. So you need to omit
|
||||
@note For older versions of Ubuntu and Debian, Armadillo needs to be built from
|
||||
source as apt installs an older version. So you need to omit
|
||||
\c libarmadillo-dev from the code snippet above and instead use
|
||||
<a href="http://arma.sourceforge.net/download.html">this link</a>
|
||||
to download the required file. Extract this file and follow the README in the
|
||||
to download the required file. Extract this file and follow the README in the
|
||||
uncompressed folder to build and install Armadillo.
|
||||
|
||||
On Fedora, Red Hat, or CentOS, these same dependencies can be obtained via dnf:
|
||||
|
||||
@code
|
||||
# dnf install boost-devel boost-test boost-math armadillo-devel binutils-devel
|
||||
python2-Cython python2-setuptools python2-numpy python2-pandas ensmallen-devel
|
||||
stbi-devel
|
||||
# dnf install boost-devel boost-math armadillo-devel binutils-devel
|
||||
python3-Cython python3-setuptools python3-numpy python3-pandas ensmallen-devel
|
||||
stbi-devel cereal-devel
|
||||
@endcode
|
||||
|
||||
(It's also possible to use python3 packages from the package manager---mlpack
|
||||
@@ -179,6 +193,8 @@ The full list of options mlpack allows:
|
||||
- JULIA_EXECUTABLE=(/path/to/julia): Path to specific Julia executable
|
||||
- BUILD_MARKDOWN_BINDINGS=(ON/OFF): Build Markdown bindings for website
|
||||
documentation (default OFF)
|
||||
- BUILD_DOCS=(ON/OFF): build Doxygen documentation, if Doxygen is available
|
||||
(default ON)
|
||||
- MATHJAX=(ON/OFF): use MathJax for generated Doxygen documentation (default
|
||||
OFF)
|
||||
- FORCE_CXX11=(ON/OFF): assume that the compiler supports C++11 instead of
|
||||
|
||||
+115
-10
@@ -9,8 +9,13 @@
|
||||
|
||||
@section build_windows_intro Introduction
|
||||
|
||||
This tutorial will show you how to build mlpack for Windows from source, so you can
|
||||
later create your own C++ applications. Before you try building mlpack, you may
|
||||
This tutorial will show you how to build mlpack for Windows from source, so
|
||||
you can later create your own C++ applications, using two different ways:
|
||||
|
||||
- Using CMake to generate an intermeditate Visual Studio solution (`.sln`).
|
||||
- @ref build_visual_studio_cmake_integration "Use Visual Studio's CMake integration to directly build from the `CMakeLists`."
|
||||
|
||||
Before you try building mlpack, you may
|
||||
want to install mlpack using vcpkg for Windows. If you don't want to install
|
||||
using vcpkg, skip this section and continue with the build tutorial.
|
||||
|
||||
@@ -78,6 +83,23 @@ system environment variables or manually set the PATH before running CMake)
|
||||
- Click on OpenBlas and check the mlpack project, then click Install
|
||||
- Once it has finished installing, close Visual Studio
|
||||
|
||||
<b> Building OpenBLAS from Source </b>
|
||||
|
||||
Unfortunately, the support for building `LAPACK` and `BLAS` on Windows is quite poor, due to the need for Fortran
|
||||
compiler and libraries. The easiest method to get the necessary `BLAS/LAPACK` libraries built on Windows is to
|
||||
compile OpenBLAS with LLVM's `clang-cl` and `flang` to produce the required static library (`.lib`) files
|
||||
compatible with the MSVC compiler. A comprehensive guide on the
|
||||
<a href="https://github.com/xianyi/OpenBLAS/wiki/How-to-use-OpenBLAS-in-Microsoft-Visual-Studio">compilation
|
||||
of OpenBLAS for Windows can be found here</a>.
|
||||
|
||||
One could always download prebuilt `LAPACK` and `BLAS` libraries for Windows. However, there are few official
|
||||
sources, and some of those libraries may require further `dll`s at runtime which may not be available in your
|
||||
system.
|
||||
|
||||
It you choose to build `OpenBLAS` from source, make sure that `LAPACK` functions are also built. Finally, make
|
||||
sure that the `openblas.lib` library is linked in your `Armadillo` build (see below), as well as the library
|
||||
path used for the CMake options `BLAS_LIBRARIES` and `LAPACK_LIBRARIES` in the mlpack CMake project.
|
||||
|
||||
<b> Boost Dependency </b>
|
||||
|
||||
You can either get Boost via NuGet or you can download the prebuilt Windows binaries separately.
|
||||
@@ -110,7 +132,7 @@ compiler version, check if the Visual Studio compiler and Windows SDK are instal
|
||||
- Build > Build Solution
|
||||
- Once it has successfully finished, close Visual Studio
|
||||
|
||||
@section build_windows_mlpack Building mlpack
|
||||
@section build_windows_mlpack Building mlpack with CMake-Generated Solution
|
||||
|
||||
- Create a "build" directory into "C:\mlpack\mlpack\"
|
||||
- You can generate the project using either cmake via command line or GUI. If you prefer to use GUI, refer to the \ref build_windows_appendix "appendix"
|
||||
@@ -129,6 +151,96 @@ cmake -G "Visual Studio 16 2019" -A x64 -DBLAS_LIBRARIES:FILEPATH="C:/mlpack/mlp
|
||||
|
||||
You are ready to create your first application, take a look at the @ref sample_ml_app "Sample C++ ML App"
|
||||
|
||||
@section build_visual_studio_cmake_integration Building mlpack with Visual Studio's CMake Integration
|
||||
|
||||
This project can be directly built from the `CMakeLists.txt` with the latest version of MS Visual Studio,
|
||||
given you have CMake integration via the
|
||||
<a href="https://docs.microsoft.com/en-us/cpp/build/cmake-projects-in-visual-studio?view=msvc-160">C++
|
||||
CMake tools for Windows</a>. To open the CMake project with Visual Studio, select File->Open->CMake
|
||||
in the top menu, followed by selecting the root `CMakeLists.txt` located in mlpack's root directory.
|
||||
|
||||
In order to allow Visual Studio to configure the CMake project, the CMake configuration json will have
|
||||
to be edited to provide the <a href="https://github.com/mlpack/mlpack#3-dependencies">relevant options
|
||||
shown in the `README`</a> needed to find all the dependencies. The options that you
|
||||
must provide to Visual Studio's CMake are:
|
||||
|
||||
- `ARMADILLO_INCLUDE_DIR`
|
||||
- `ARMADILLO_LIBRARY`
|
||||
- `BOOST_ROOT`
|
||||
- `CEREAL_INCLUDE_DIR`
|
||||
- `BLAS_LIBRARIES`
|
||||
- `LAPACK_LIBRARIES`
|
||||
|
||||
The CMake configuration json can be editted in Visual Studio by right clicking the root `CMakeLists.txt`
|
||||
in the project view, selecting <b>CMake settings for mlpack</b> and finally clicking on <b>edit JSON</b>.
|
||||
Adding a new CMake option can be done by adding object fields with the following format to the variables
|
||||
array in the `CMakeSettings.json`:
|
||||
|
||||
@code
|
||||
{
|
||||
"name": "options_name_string",
|
||||
"value": "options_value_string",
|
||||
"type" : "{BOOL|FILEPATH|PATH|STRING}"
|
||||
}
|
||||
@endcode
|
||||
|
||||
Here is a full example of the `CMakeSettings.json`file:
|
||||
|
||||
@code
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "x64-Debug (default)",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"variables": [
|
||||
{
|
||||
"name": "ARMADILLO_INCLUDE_DIR",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/armadillo-10.1.2/include",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "ARMADILLO_LIBBRARY",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/armadillo-10.1.2/lib/armadillo.lib",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "CEREAL_INCLUDE_DIR",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/cereal-1.3.0/include",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "BUILD_ROOT",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/boost_1_66_0",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "BOOST_INCLUDEDIR",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/boost_1_66_0",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "BLAS_LIBRARIES",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/OpenBLAS/lib/openblas.lib",
|
||||
"type": "PATH"
|
||||
},
|
||||
{
|
||||
"name": "LAPACK_LIBRARIES",
|
||||
"value": "PATH/TO/CPP/DEPENDENCY/OpenBLAS/lib/openblas.lib",
|
||||
"type": "PATH"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@endcode
|
||||
|
||||
@section build_windows_appendix Appendix
|
||||
|
||||
If you prefer to use cmake GUI, follow these instructions:
|
||||
@@ -147,13 +259,6 @@ If you prefer to use cmake GUI, follow these instructions:
|
||||
following variables and reconfigure:
|
||||
- Name: `BOOST_INCLUDEDIR`; type `PATH`; value `C:/boost/`
|
||||
- Name: `BOOST_LIBRARYDIR`; type `PATH`; value `C:/boost/lib64-msvc-14.2`
|
||||
- If Boost is still not found, try adding the following variables and
|
||||
reconfigure:
|
||||
- Name: `Boost_INCLUDE_DIR`; type `PATH`; value `C:/boost/`
|
||||
- Name: `Boost_SERIALIZATION_LIBRARY_DEBUG`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_serialization-vc142-mt-gd-x64-1_71.lib`
|
||||
- Name: `Boost_SERIALIZATION_LIBRARY_RELEASE`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_serialization-vc142-mt-x64-1_71.lib`
|
||||
- Name: `Boost_UNIT_TEST_FRAMEWORK_LIBRARY_DEBUG`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_unit_test_framework-vc142-mt-gd-x64-1_71.lib`
|
||||
- Name: `Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE`; type `FILEPATH`; value should be `C:/boost/lib64-msvc-14.2/boost_unit_test_framework-vc142-mt-x64-1_71.lib`
|
||||
- Once CMake has configured successfully, hit "Generate" to create the `.sln` file.
|
||||
|
||||
@section build_windows_additional_information Additional Information
|
||||
|
||||
@@ -10,8 +10,9 @@ This page describes how you can quickly get started using mlpack from the
|
||||
command-line and gives a few examples of usage, and pointers to deeper
|
||||
documentation.
|
||||
|
||||
This quickstart guide is also available for @ref python_quickstart "Python" and
|
||||
@ref julia_quickstart "Julia".
|
||||
This quickstart guide is also available for @ref python_quickstart "Python",
|
||||
@ref r_quickstart "R", @ref julia_quickstart "Julia" and
|
||||
@ref go_quickstart "Go".
|
||||
|
||||
@section cli_quickstart_install Installing mlpack
|
||||
|
||||
@@ -108,7 +109,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>
|
||||
|
||||
For more information on what mlpack does, see https://www.mlpack.org/. Next,
|
||||
let's go through another example for providing movie recommendations with
|
||||
|
||||
@@ -447,11 +447,11 @@ Multiple images are saved according to the vector of filenames specified.
|
||||
|
||||
@section formatmodels Loading and saving models
|
||||
|
||||
Using \c boost::serialization, mlpack is able to load and save machine learning
|
||||
Using \c cereal, mlpack is able to load and save machine learning
|
||||
models with ease. These models can currently be saved in three formats:
|
||||
|
||||
- binary (.bin); this is not human-readable, but it is small
|
||||
- text (.txt); this is sort of human-readable and relatively small
|
||||
- json (.json); this is sort of human-readable and relatively small
|
||||
- xml (.xml); this is human-readable but very verbose and large
|
||||
|
||||
The type of file to save is determined by the given file extension, as with the
|
||||
@@ -471,7 +471,7 @@ options; for more information, see the documentation for each program
|
||||
|
||||
@section formatmodelscpp Loading and saving models in C++
|
||||
|
||||
mlpack uses the \c boost::serialization library internally to perform loading
|
||||
mlpack uses the \c cereal library internally to perform loading
|
||||
and saving of models, and provides convenience overloads of mlpack::data::Load()
|
||||
and mlpack::data::Save() to load and save these models.
|
||||
|
||||
@@ -479,13 +479,12 @@ To be serializable, a class must implement the method
|
||||
|
||||
\code
|
||||
template<typename Archive>
|
||||
void serialize(Archive& ar, const unsigned int version);
|
||||
void serialize(Archive& ar);
|
||||
\endcode
|
||||
|
||||
\note
|
||||
For more information on this method and how it works, see the
|
||||
boost::serialization documentation at
|
||||
http://www.boost.org/libs/serialization/doc/.
|
||||
cereal documentation at https://uscilab.github.io/cereal/index.html.
|
||||
|
||||
\note
|
||||
Examples of serialize() methods can be found in most classes; one fairly
|
||||
@@ -503,11 +502,11 @@ mlpack::math::Range object.
|
||||
\code
|
||||
// Create range and save it.
|
||||
mlpack::math::Range r(0.0, 5.0);
|
||||
mlpack::data::Save("range.txt", "range", r);
|
||||
mlpack::data::Save("range.json", "range", r);
|
||||
|
||||
// Load into new range.
|
||||
mlpack::math::Range newRange;
|
||||
mlpack::data::Load("range.txt", "range", newRange);
|
||||
mlpack::data::Load("range.json", "range", newRange);
|
||||
\endcode
|
||||
|
||||
It is important to be sure that you load the appropriate type; if you save, for
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
This page describes how you can quickly get started using mlpack from Go and
|
||||
gives a few examples of usage, and pointers to deeper documentation.
|
||||
|
||||
This quickstart guide is also available for
|
||||
@ref cli_quickstart "the command-line", @ref python_quickstart "Python"
|
||||
and @ref julia_quickstart "Julia".
|
||||
This quickstart guide is also available for @ref python_quickstart "Python",
|
||||
@ref cli_quickstart "the command-line", @ref julia_quickstart "Julia" and
|
||||
@ref r_quickstart "R".
|
||||
|
||||
@section go_quickstart_install Installing mlpack
|
||||
|
||||
|
||||
+20
-14
@@ -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>
|
||||
@@ -117,10 +117,11 @@ 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
|
||||
with the BINDING_NAME, BINDING_SHORT_DESC, BINDING_LONG_DESC, BINDING_EXAMPLE,
|
||||
BINDING_SEE_ALSO, PARAM_INT, PARAM_DOUBLE, PARAM_STRING, and PARAM_FLAG
|
||||
macros.
|
||||
|
||||
Here is a sample use of those macros, extracted from methods/pca/pca_main.cpp.
|
||||
@@ -128,26 +129,31 @@ 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.
|
||||
PROGRAM_INFO("Principal Components Analysis",
|
||||
// Short description.
|
||||
// Program Name.
|
||||
BINDING_NAME("Principal Components Analysis");
|
||||
|
||||
// Short description.
|
||||
BINDING_SHORT_DESC(
|
||||
"An implementation of several strategies for principal components analysis "
|
||||
"(PCA), a common preprocessing step. Given a dataset and a desired new "
|
||||
"dimensionality, this can reduce the dimensionality of the data using the "
|
||||
"linear transformation determined by PCA.",
|
||||
// Long description.
|
||||
"linear transformation determined by PCA.");
|
||||
|
||||
// Long description.
|
||||
BINDING_LONG_DESC(
|
||||
"This program performs principal components analysis on the given dataset "
|
||||
"using the exact, randomized, randomized block Krylov, or QUIC SVD method. "
|
||||
"It will transform the data onto its principal components, optionally "
|
||||
"performing dimensionality reduction by ignoring the principal components "
|
||||
"with the smallest eigenvalues."
|
||||
// "See also" section for generated documentation.
|
||||
SEE_ALSO("Principal component analysis on Wikipedia",
|
||||
"https://en.wikipedia.org/wiki/Principal_component_analysis"),
|
||||
SEE_ALSO("mlpack::pca::PCA C++ class documentation",
|
||||
"with the smallest eigenvalues.");
|
||||
|
||||
// See also...
|
||||
BINDING_SEE_ALSO("Principal component analysis on Wikipedia",
|
||||
"https://en.wikipedia.org/wiki/Principal_component_analysis");
|
||||
BINDING_SEE_ALSO("mlpack::pca::PCA C++ class documentation",
|
||||
"@doxygen/classmlpack_1_1pca_1_1PCA.html"));
|
||||
|
||||
// Parameters for program.
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
This page describes how you can quickly get started using mlpack from Julia and
|
||||
gives a few examples of usage, and pointers to deeper documentation.
|
||||
|
||||
This quickstart guide is also available for
|
||||
@ref cli_quickstart "the command-line" and @ref python_quickstart "Python".
|
||||
This quickstart guide is also available for @ref python_quickstart "Python",
|
||||
@ref cli_quickstart "the command-line", @ref go_quickstart "Go" and
|
||||
@ref r_quickstart "R".
|
||||
|
||||
@section julia_quickstart_install Installing mlpack
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ build and install mlpack. You can copy-paste the commands into your shell.
|
||||
@code{.sh}
|
||||
sudo apt-get install libboost-all-dev g++ cmake libarmadillo-dev python-pip wget
|
||||
sudo pip install cython setuptools distutils numpy pandas
|
||||
wget https://www.mlpack.org/files/mlpack-3.2.2.tar.gz
|
||||
tar -xvzpf mlpack-3.2.2.tar.gz
|
||||
mkdir -p mlpack-3.2.2/build/ && cd mlpack-3.2.2/build/
|
||||
wget https://www.mlpack.org/files/mlpack-3.4.2.tar.gz
|
||||
tar -xvzpf mlpack-3.4.2.tar.gz
|
||||
mkdir -p mlpack-3.4.2/build/ && cd mlpack-3.4.2/build/
|
||||
cmake ../ && make -j4 && sudo make install
|
||||
@endcode
|
||||
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* @file r_quickstart.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
|
||||
@page r_quickstart mlpack in R quickstart guide
|
||||
|
||||
@section r_quickstart_intro Introduction
|
||||
|
||||
This page describes how you can quickly get started using mlpack from R and
|
||||
gives a few examples of usage, and pointers to deeper documentation.
|
||||
|
||||
This quickstart guide is also available for @ref python_quickstart "Python",
|
||||
@ref cli_quickstart "the command-line", @ref julia_quickstart "Julia" and
|
||||
@ref go_quickstart "Go".
|
||||
|
||||
@section r_quickstart_install Installing mlpack binary package
|
||||
|
||||
Installing the mlpack bindings for R is straightforward; you can just use
|
||||
CRAN:
|
||||
|
||||
@code{.R}
|
||||
install.packages('mlpack')
|
||||
@endcode
|
||||
|
||||
@section r_quickstart_source_install Installing mlpack package from source
|
||||
|
||||
Building the R bindings from scratch is a little more in-depth, though. For
|
||||
information on that, follow the instructions on the @ref build page, and be sure
|
||||
to specify @c -DBUILD_R_BINDINGS=ON to CMake; you may need to also set the
|
||||
location of the R program with @c -DR_EXECUTABLE=/path/to/R.
|
||||
|
||||
@section r_quickstart_example Simple mlpack quickstart example
|
||||
|
||||
As a really simple example of how to use mlpack from R, let's do some
|
||||
simple classification on a subset of the standard machine learning @c covertype
|
||||
dataset. We'll first split the dataset into a training set and a testing set,
|
||||
then we'll train an mlpack random forest on the training data, and finally we'll
|
||||
print the accuracy of the random forest on the test dataset.
|
||||
|
||||
You can copy-paste this code directly into R to run it.
|
||||
|
||||
@code{.R}
|
||||
if(!requireNamespace("data.table", quietly = TRUE)) { install.packages("data.table") }
|
||||
suppressMessages({
|
||||
library("mlpack")
|
||||
library("data.table")
|
||||
})
|
||||
|
||||
# Load the dataset from an online URL. Replace with 'covertype.csv.gz' if you
|
||||
# want to use on the full dataset.
|
||||
df <- fread("https://www.mlpack.org/datasets/covertype-small.csv.gz")
|
||||
|
||||
# Split the labels.
|
||||
labels <- df[, .(label)]
|
||||
dataset <- df[, label:=NULL]
|
||||
|
||||
# Split the dataset using mlpack.
|
||||
prepdata <- preprocess_split(input = dataset,
|
||||
input_labels = labels,
|
||||
test_ratio = 0.3,
|
||||
verbose = TRUE)
|
||||
|
||||
# Train a random forest.
|
||||
output <- random_forest(training = prepdata$training,
|
||||
labels = prepdata$training_labels,
|
||||
print_training_accuracy = TRUE,
|
||||
num_trees = 10,
|
||||
minimum_leaf_size = 3,
|
||||
verbose = TRUE)
|
||||
rf_model <- output$output_model
|
||||
|
||||
# Predict the labels of the test points.
|
||||
output <- random_forest(input_model = rf_model,
|
||||
test = prepdata$test,
|
||||
verbose = TRUE)
|
||||
|
||||
# Now print the accuracy. The third return value ('probabilities'), which we
|
||||
# ignored here, could also be used to generate an ROC curve.
|
||||
correct <- sum(output$predictions == prepdata$test_labels)
|
||||
cat(correct, "out of", length(prepdata$test_labels), "test points correct",
|
||||
correct / length(prepdata$test_labels) * 100.0, "%\n")
|
||||
@endcode
|
||||
|
||||
We can see that we achieve reasonably good accuracy on the test dataset (80%+);
|
||||
if we use the full @c covertype.csv.gz, the accuracy should increase
|
||||
significantly (but training will take longer).
|
||||
|
||||
It's easy to modify the code above to do more complex things, or to use
|
||||
different mlpack learners, or to interface with other machine learning toolkits.
|
||||
|
||||
@section r_quickstart_whatelse What else does mlpack implement?
|
||||
|
||||
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 each of these commands and full documentation can be found on the following
|
||||
page:
|
||||
|
||||
- <a href="https://www.mlpack.org/doc/mlpack-git/r_documentation.html">r documentation</a>
|
||||
|
||||
For more information on what mlpack does, see https://www.mlpack.org/.
|
||||
Next, let's go through another example for providing movie recommendations with
|
||||
mlpack.
|
||||
|
||||
@section r_quickstart_movierecs Using mlpack for movie recommendations
|
||||
|
||||
In this example, we'll train a collaborative filtering model using mlpack's
|
||||
<tt><a href="https://www.mlpack.org/doc/mlpack-git/r_documentation.html#cf">cf()</a></tt> method. We'll train this on the MovieLens dataset from
|
||||
https://grouplens.org/datasets/movielens/, and then we'll use the model that we
|
||||
train to give recommendations.
|
||||
|
||||
You can copy-paste this code directly into R to run it.
|
||||
|
||||
@code{.R}
|
||||
if(!requireNamespace("data.table", quietly = TRUE)) { install.packages("data.table") }
|
||||
suppressMessages({
|
||||
library("mlpack")
|
||||
library("data.table")
|
||||
})
|
||||
|
||||
# First, load the MovieLens dataset. This is taken from files.grouplens.org/
|
||||
# but reposted on mlpack.org as unpacked and slightly preprocessed data.
|
||||
ratings <- fread("http://www.mlpack.org/datasets/ml-20m/ratings-only.csv.gz")
|
||||
movies <- fread("http://www.mlpack.org/datasets/ml-20m/movies.csv.gz")
|
||||
|
||||
# Hold out 10% of the dataset into a test set so we can evaluate performance.
|
||||
predata <- preprocess_split(input = ratings,
|
||||
test_ratio = 0.1,
|
||||
verbose = TRUE)
|
||||
|
||||
# Train the model. Change the rank to increase/decrease the complexity of the
|
||||
# model.
|
||||
output <- cf(training = predata$training,
|
||||
test = predata$test,
|
||||
rank = 10,
|
||||
verbose = TRUE,
|
||||
max_iteration=2,
|
||||
algorithm = "RegSVD")
|
||||
cf_model <- output$output_model
|
||||
|
||||
# Now query the 5 top movies for user 1.
|
||||
output <- cf(input_model = cf_model,
|
||||
query = matrix(1),
|
||||
recommendations = 10,
|
||||
verbose = TRUE)
|
||||
|
||||
# Get the names of the movies for user 1.
|
||||
cat("Recommendations for user 1:\n")
|
||||
for (i in 1:10) {
|
||||
cat(" ", i, ":", as.character(movies[output$output[i], 3]), "\n")
|
||||
}
|
||||
@endcode
|
||||
|
||||
Here is some example output, showing that user 1 seems to have good taste in
|
||||
movies:
|
||||
|
||||
@code{.unparsed}
|
||||
Recommendations for user 1:
|
||||
0: Casablanca (1942)
|
||||
1: Pan's Labyrinth (Laberinto del fauno, El) (2006)
|
||||
2: Godfather, The (1972)
|
||||
3: Answer This! (2010)
|
||||
4: Life Is Beautiful (La Vita è bella) (1997)
|
||||
5: Adventures of Tintin, The (2011)
|
||||
6: Dark Knight, The (2008)
|
||||
7: Out for Justice (1991)
|
||||
8: Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb (1964)
|
||||
9: Schindler's List (1993)
|
||||
@endcode
|
||||
|
||||
@section r_quickstart_nextsteps Next steps with mlpack
|
||||
|
||||
After working through this overview to `mlpack`'s R package, we hope you are
|
||||
inspired to use `mlpack`' in your data science workflow. We recommend as part
|
||||
of your next steps to look at more documentation for the R mlpack bindings:
|
||||
|
||||
- <a href="https://www.mlpack.org/doc/mlpack-git/r_documentation.html">R mlpack
|
||||
binding documentation</a>
|
||||
|
||||
Also, mlpack is much more flexible from C++ and allows much greater
|
||||
functionality. So, more complicated tasks are possible if you are willing to
|
||||
write C++ (or perhaps Rcpp). To get started learning about mlpack in C++, the
|
||||
following resources might be helpful:
|
||||
|
||||
- <a href="https://www.mlpack.org/doc/mlpack-git/doxygen/tutorials.html">mlpack
|
||||
C++ tutorials</a>
|
||||
- <a href="https://www.mlpack.org/doc/mlpack-git/doxygen/build.html">mlpack
|
||||
build and installation guide</a>
|
||||
- <a href="https://www.mlpack.org/doc/mlpack-git/doxygen/sample.html">Simple
|
||||
sample C++ mlpack programs</a>
|
||||
- <a href="https://www.mlpack.org/doc/mlpack-git/doxygen/index.html">mlpack
|
||||
Doxygen documentation homepage</a>
|
||||
|
||||
*/
|
||||
+13
-10
@@ -29,17 +29,16 @@ mlpack and dependencies in Release Mode).
|
||||
@code
|
||||
- C:\boost\boost_1_71_0\lib\native\include
|
||||
- C:\mlpack\armadillo-9.800.3\include
|
||||
- C:\mlpack\mlpack-3.2.2\build\include
|
||||
- C:\mlpack\mlpack-3.4.2\build\include
|
||||
@endcode
|
||||
- Under Linker > Input > Additional Dependencies add:
|
||||
@code
|
||||
- C:\mlpack\mlpack-3.2.2\build\Debug\mlpack.lib
|
||||
- C:\boost\boost_1_71_0\lib64-msvc-14.2\libboost_serialization-vc142-mt-gd-x64-1_71.lib
|
||||
- C:\mlpack\mlpack-3.4.2\build\Debug\mlpack.lib
|
||||
@endcode
|
||||
- Under Build Events > Post-Build Event > Command Line add:
|
||||
@code
|
||||
- xcopy /y "C:\mlpack\mlpack-3.2.2\build\Debug\mlpack.dll" $(OutDir)
|
||||
- xcopy /y "C:\mlpack\mlpack-3.2.2\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
- xcopy /y "C:\mlpack\mlpack-3.4.2\build\Debug\mlpack.dll" $(OutDir)
|
||||
- xcopy /y "C:\mlpack\mlpack-3.4.2\packages\OpenBLAS.0.2.14.1\lib\native\bin\x64\*.dll" $(OutDir)
|
||||
@endcode
|
||||
|
||||
@note Recent versions of Visual Studio set "Conformance Mode" enabled by default. This causes some issues with
|
||||
@@ -94,7 +93,7 @@ copy "mlpack/tests/data/german.csv" and paste into a new "data" folder in your p
|
||||
mat dataset;
|
||||
bool loaded = mlpack::data::Load("data/german.csv", dataset);
|
||||
if (!loaded)
|
||||
return -1;
|
||||
return -1;
|
||||
@endcode
|
||||
|
||||
Then we need to extract the labels from the last dimension of the dataset and remove the
|
||||
@@ -121,7 +120,7 @@ const size_t numTrees = 10;
|
||||
RandomForest<GiniGain, RandomDimensionSelect> rf;
|
||||
|
||||
rf = RandomForest<GiniGain, RandomDimensionSelect>(dataset, labels,
|
||||
numClasses, numTrees, minimumLeafSize);
|
||||
numClasses, numTrees, minimumLeafSize);
|
||||
@endcode
|
||||
|
||||
Now that the training is completed, we quickly compute the training accuracy:
|
||||
@@ -143,7 +142,7 @@ to assess the quality of the trained model.
|
||||
@code
|
||||
const size_t k = 10;
|
||||
KFoldCV<RandomForest<GiniGain, RandomDimensionSelect>, Accuracy> cv(k,
|
||||
dataset, labels, numClasses);
|
||||
dataset, labels, numClasses);
|
||||
double cvAcc = cv.Evaluate(numTrees, minimumLeafSize);
|
||||
cout << "\nKFoldCV Accuracy: " << cvAcc;
|
||||
@endcode
|
||||
@@ -188,12 +187,16 @@ Finally, the ultimate goal is to classify a new sample using the previously trai
|
||||
Random Forest classifier provides both predictions and probabilities, we obtain both.
|
||||
|
||||
@code
|
||||
mat sample("2 12 2 13 1 2 2 1 3 24 3 1 1 1 1 1 0 1 0 1 0 0 0");
|
||||
// Create a test sample containing only one point. Because Armadillo is
|
||||
// column-major, this matrix has one column (one point) and the number of rows
|
||||
// is equal to the dimensionality of the point (23).
|
||||
mat sample("2; 12; 2; 13; 1; 2; 2; 1; 3; 24; 3; 1; 1; 1; 1; 1; 0; 1; 0; 1;"
|
||||
" 0; 0; 0");
|
||||
mat probabilities;
|
||||
rf.Classify(sample, predictions, probabilities);
|
||||
u64 result = predictions.at(0);
|
||||
cout << "\nClassification result: " << result << " , Probabilities: " <<
|
||||
probabilities.at(0) << "/" << probabilities.at(1);
|
||||
probabilities.at(0) << "/" << probabilities.at(1);
|
||||
@endcode
|
||||
|
||||
@section sample_app_conclussion Final thoughts
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
|
||||
+16
-16
@@ -225,7 +225,7 @@ class ExampleTree
|
||||
// tree using the given MetricType.
|
||||
ExampleTree(const MatType& data, MetricType& metric);
|
||||
|
||||
// Initialize the tree from a given boost::serialization archive. SFINAE (the
|
||||
// Initialize the tree from a given cereal archive. SFINAE (the
|
||||
// second argument) is necessary to ensure that the archive is loading, not
|
||||
// saving.
|
||||
template<typename Archive>
|
||||
@@ -330,16 +330,16 @@ class ExampleTree
|
||||
// Serialize the tree (load from the given archive / save to the given
|
||||
// archive, depending on its type).
|
||||
template<typename Archive>
|
||||
void Serialize(Archive& ar, const unsigned int version);
|
||||
void serialize(Archive& ar, const uint32_t version);
|
||||
|
||||
protected:
|
||||
// A default constructor; only meant to be used by boost::serialization. This
|
||||
// must be protected so that boost::serialization will work; it does not need
|
||||
// A default constructor; only meant to be used by cereal. This
|
||||
// must be protected so that cereal will work; it does not need
|
||||
// to return a valid tree.
|
||||
ExampleTree();
|
||||
|
||||
// Friend access must be given for the default constructor.
|
||||
friend class boost::serialization::access;
|
||||
friend class cereal::access;
|
||||
};
|
||||
@endcode
|
||||
|
||||
@@ -378,7 +378,7 @@ calculation, and (usually) provides a decent bound on the minimum distance
|
||||
between \f$p\f$ and any descendant point of the node.
|
||||
|
||||
- **Trees need to be able to be serialized.** mlpack uses the
|
||||
boost::serialization library for saving and loading objects. Trees---which can
|
||||
cereal library for saving and loading objects. Trees---which can
|
||||
be a part of machine learning models---therefore must have the ability to be
|
||||
saved and loaded. Making this all work requires a protected constructor (part
|
||||
of the API) and generally makes it impossible to hold references instead of
|
||||
@@ -481,10 +481,10 @@ It is possible to implement both these constructors as one by using \c
|
||||
boost::optional.
|
||||
|
||||
The third constructor requires the tree to be initializable from a \c
|
||||
boost::serialization archive:
|
||||
cereal archive:
|
||||
|
||||
@code
|
||||
// Initialize the tree from a given boost::serialization archive. SFINAE (the
|
||||
// Initialize the tree from a given cereal archive. SFINAE (the
|
||||
// second argument) is necessary to ensure that the archive is loading, not
|
||||
// saving.
|
||||
template<typename Archive>
|
||||
@@ -507,7 +507,7 @@ will be required:
|
||||
|
||||
and, if the data matrix is represented internally with a pointer, this
|
||||
destructor will need to release the memory for the data matrix (in the case that
|
||||
the tree was created via \c boost::serialization ).
|
||||
the tree was created via \c cereal ).
|
||||
|
||||
Note that these constructors are not necessarily the only constructors that a
|
||||
\c TreeType implementation can provide. One important example of when more
|
||||
@@ -778,22 +778,22 @@ the node plus one or two levels of children.
|
||||
// Serialize the tree (load from the given archive / save to the given
|
||||
// archive, depending on its type).
|
||||
template<typename Archive>
|
||||
void Serialize(Archive& ar, const unsigned int version);
|
||||
void serialize(Archive& ar);
|
||||
|
||||
protected:
|
||||
// A default constructor; only meant to be used by boost::serialization. This
|
||||
// must be protected so that boost::serialization will work; it does not need
|
||||
// A default constructor; only meant to be used by cereal. This
|
||||
// must be protected so that cereal will work; it does not need
|
||||
// to return a valid tree.
|
||||
ExampleTree();
|
||||
|
||||
// Friend access must be given for the default constructor.
|
||||
friend class boost::serialization::access;
|
||||
friend class cereal::access;
|
||||
@endcode
|
||||
|
||||
On the other hand, the specifics of the functionality required for the
|
||||
\c Serialize() function are somewhat more difficult. The \c Serialize()
|
||||
function will be called either when a tree is being saved to disk or loaded from
|
||||
disk. The \c boost::serialization documentation is fairly comprehensive, but
|
||||
disk. The \c cereal documentation is fairly comprehensive.
|
||||
when writing a \c Serialize() method for mlpack trees you should use
|
||||
\c data::CreateNVP() instead of \c BOOST_SERIALIZATION_NVP(). This is because
|
||||
mlpack classes implement \c Serialize() instead of \c serialize() in order to
|
||||
@@ -803,10 +803,10 @@ be useful to look at other \c Serialize() methods contained in other mlpack
|
||||
classes as an example.
|
||||
|
||||
An important note is that it is very difficult to use references with
|
||||
\c boost::serialization, because \c Serialize() may be called at any time during
|
||||
\c cereal, because \c serialize() may be called at any time during
|
||||
the object's lifetime, and references cannot be re-seated. In general this will
|
||||
require the use of pointers, which then require manual memory management.
|
||||
Therefore, be careful that \c Serialize() (and the tree's destructor) properly
|
||||
Therefore, be careful that \c serialize() (and the tree's destructor) properly
|
||||
handle memory management!
|
||||
|
||||
@section treetype_traits The TreeTraits trait class
|
||||
|
||||
+73
-47
@@ -573,8 +573,8 @@ a new reference set. This is functionally equivalent to creating a new model.
|
||||
|
||||
@section model_saving_loading_anntut Saving & Loading
|
||||
|
||||
Using \c boost::serialization (for more information about the internals see
|
||||
[Serialization - Boost C++ Libraries](www.boost.org/libs/serialization/doc/)),
|
||||
Using \c cereal (for more information about the internals see
|
||||
[the Cereal website](http://uscilab.github.io/cereal/)),
|
||||
mlpack is able to load and save machine learning models with ease. To save a
|
||||
trained neural network to disk. The example below builds a model on the \c
|
||||
thyroid dataset and then saves the model to the file \c model.xml for later use.
|
||||
@@ -589,7 +589,7 @@ arma::mat trainData = dataset.submat(0, 0, dataset.n_rows - 4,
|
||||
dataset.n_cols - 1);
|
||||
|
||||
// Split the data from the training set.
|
||||
arma::mat trainLabelsTemp = dataset.submat(dataset.n_rows - 3, 0,
|
||||
arma::mat trainLabels = dataset.submat(dataset.n_rows - 3, 0,
|
||||
dataset.n_rows - 1, dataset.n_cols - 1);
|
||||
|
||||
// Initialize the network.
|
||||
@@ -615,50 +615,76 @@ Now, we can look at the output model file, \c model.xml:
|
||||
|
||||
@code
|
||||
$ cat model.xml
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<!DOCTYPE boost_serialization>
|
||||
<boost_serialization signature="serialization::archive" version="15">
|
||||
<model class_id="0" tracking_level="0" version="0">
|
||||
<parameter class_id="1" tracking_level="1" version="0" object_id="_0">
|
||||
<n_rows>66</n_rows>
|
||||
<n_cols>1</n_cols>
|
||||
<n_elem>66</n_elem>
|
||||
<vec_state>0</vec_state>
|
||||
<item>-7.55971528334903642e+00</item>
|
||||
<item>-9.95435955058058930e+00</item>
|
||||
<item>9.31133928948225353e+00</item>
|
||||
<item>-5.36784434861701953e+00</item>
|
||||
...
|
||||
</parameter>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
<currentInput object_id="_1">
|
||||
<n_rows>0</n_rows>
|
||||
<n_cols>0</n_cols>
|
||||
<n_elem>0</n_elem>
|
||||
<vec_state>0</vec_state>
|
||||
</currentInput>
|
||||
<network class_id="2" tracking_level="0" version="0">
|
||||
<count>3</count>
|
||||
<item_version>0</item_version>
|
||||
<item class_id="3" tracking_level="0" version="0">
|
||||
<which>18</which>
|
||||
<value class_id="4" tracking_level="1" version="0" object_id="_2">
|
||||
<inSize>21</inSize>
|
||||
<outSize>3</outSize>
|
||||
</value>
|
||||
</item>
|
||||
<item>
|
||||
<which>2</which>
|
||||
<value class_id="5" tracking_level="1" version="0" object_id="_3"></value>
|
||||
</item>
|
||||
<item>
|
||||
<which>20</which>
|
||||
<value class_id="6" tracking_level="1" version="0" object_id="_4"></value>
|
||||
</item>
|
||||
</network>
|
||||
</model>
|
||||
</boost_serialization>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<cereal>
|
||||
<model>
|
||||
<cereal_class_version>0</cereal_class_version>
|
||||
<parameter>
|
||||
<n_rows>60</n_rows>
|
||||
<n_cols>1</n_cols>
|
||||
<vec_state>0</vec_state>
|
||||
<elem>10.461979353567767</elem>
|
||||
<elem>-10.040855482151116</elem>
|
||||
<elem>0.18048901768535316</elem>
|
||||
<elem>4.8989495084787169</elem>
|
||||
<elem>-4.4381643782652276</elem>
|
||||
<elem>0.049477846402230616</elem>
|
||||
<elem>2.5271808924795987</elem>
|
||||
<elem>-3.96993488526287</elem>
|
||||
...
|
||||
</parameter>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
<reset>true</reset>
|
||||
<value0>
|
||||
<vecSize>3</vecSize>
|
||||
<value0>
|
||||
<which>30</which>
|
||||
<value0>
|
||||
<cereal_class_version>0</cereal_class_version>
|
||||
<smartPointer>
|
||||
<ptr_wrapper>
|
||||
<valid>1</valid>
|
||||
<data>
|
||||
<cereal_class_version>0</cereal_class_version>
|
||||
<inSize>19</inSize>
|
||||
<outSize>3</outSize>
|
||||
</data>
|
||||
</ptr_wrapper>
|
||||
</smartPointer>
|
||||
</value0>
|
||||
</value0>
|
||||
<value1>
|
||||
<which>6</which>
|
||||
<value0>
|
||||
<cereal_class_version>0</cereal_class_version>
|
||||
<smartPointer>
|
||||
<ptr_wrapper>
|
||||
<valid>1</valid>
|
||||
<data>
|
||||
<cereal_class_version>0</cereal_class_version>
|
||||
</data>
|
||||
</ptr_wrapper>
|
||||
</smartPointer>
|
||||
</value0>
|
||||
</value1>
|
||||
<value2>
|
||||
<which>32</which>
|
||||
<value0>
|
||||
<cereal_class_version>0</cereal_class_version>
|
||||
<smartPointer>
|
||||
<ptr_wrapper>
|
||||
<valid>1</valid>
|
||||
<data>
|
||||
<cereal_class_version>0</cereal_class_version>
|
||||
</data>
|
||||
</ptr_wrapper>
|
||||
</smartPointer>
|
||||
</value0>
|
||||
</value2>
|
||||
</value0>
|
||||
</model>
|
||||
</cereal>
|
||||
@endcode
|
||||
|
||||
As you can see, the \c \<parameter\> section of \c model.xml contains the trained
|
||||
|
||||
@@ -15,6 +15,7 @@ get started with mlpack in different languages.
|
||||
- \ref cli_quickstart
|
||||
- \ref julia_quickstart
|
||||
- \ref go_quickstart
|
||||
- \ref r_quickstart
|
||||
|
||||
@section introd_tut Introductory Tutorials
|
||||
|
||||
|
||||
Executable
+221
@@ -0,0 +1,221 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Release a new version of mlpack.
|
||||
#
|
||||
# Usage: release-mlpack.sh X Y Z
|
||||
#
|
||||
# where X is the major version, Y is the minor version, and Z is the patch
|
||||
# version. Run this from the root of the repository.
|
||||
#
|
||||
# Make sure HISTORY.md is updated first!
|
||||
set +e
|
||||
|
||||
if [ "$#" -ne "4" ];
|
||||
then
|
||||
echo "Usage: mlpack-release.sh <github username> <major> <minor> <patch>";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# First, check for any unlicensed files.
|
||||
output=$(
|
||||
for i in $(find src/ -iname '*.[hc]pp');
|
||||
do
|
||||
echo -n $i": ";
|
||||
cat $i | grep 'mlpack is free software;' | wc -l;
|
||||
done |\
|
||||
grep -v ': 1' |\
|
||||
grep -v 'arma_extend' |\
|
||||
grep -v 'boost_backport' |\
|
||||
grep -v 'arma_config.hpp' |\
|
||||
grep -v 'gitversion.hpp' |\
|
||||
grep -v 'CLI11.hpp' |\
|
||||
grep -v 'bindings/R/mlpack/src/boost/serialization' |\
|
||||
grep -v 'tests/catch.hpp');
|
||||
lines=`echo $output | grep -v '^[ ]*$' | wc -l`;
|
||||
|
||||
if [ "0$lines" -gt "0" ];
|
||||
then
|
||||
echo "Unlicensed files found! Aborting release.";
|
||||
echo "$output";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# Now, check that there are no local changes.
|
||||
lines=`git diff | wc -l | sed -e 's/^\s*//g'`;
|
||||
if [ "$lines" != "0" ]; then
|
||||
echo "git diff returned a nonzero result!";
|
||||
echo "";
|
||||
git diff;
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# Next, make sure the origin is right.
|
||||
dest_remote_name=`git remote -v |\
|
||||
grep "mlpack/mlpack (fetch)" |\
|
||||
head -1 |\
|
||||
awk -F' ' '{ print $1 }'`;
|
||||
|
||||
if [ "a$dest_remote_name" == "a" ]; then
|
||||
echo "No git remote found for https://github.com/mlpack/mlpack!";
|
||||
echo "Make sure that you've got the ensmallen repository as a remote, and" \
|
||||
"that the master branch from that remote is checked out.";
|
||||
echo "You can do this with a fresh repository via \`git clone" \
|
||||
"https://github.com/mlpack/mlpack\`.";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# Also check that we're on the master branch, from the correct origin.
|
||||
current_branch=`git branch --no-color | grep '^\* ' | awk -F' ' '{ print $2 }'`;
|
||||
current_origin=`git rev-parse --abbrev-ref --symbolic-full-name @{u} |\
|
||||
awk -F'/' '{ print $1 }'`;
|
||||
if [ "a$current_branch" != "amaster" ]; then
|
||||
echo "Current branch is $current_branch.";
|
||||
echo "This script has to be run from the master branch.";
|
||||
exit 1;
|
||||
elif [ "a$current_origin" != "a$dest_remote_name" ]; then
|
||||
echo "Current branch does not track from remote mlpack repository!";
|
||||
echo "Instead, it tracks from $current_origin/master.";
|
||||
echo "Make sure to check out a branch that tracks $dest_remote_name/master.";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# Make sure `hub` is installed.
|
||||
hub_output="`which hub`" || true;
|
||||
if [ "a$hub_output" == "a" ]; then
|
||||
echo "The Hub command-line tool must be installed for this script to run" \
|
||||
"successfully.";
|
||||
echo "See https://hub.github.com for more details and installation" \
|
||||
"instructions.";
|
||||
echo "";
|
||||
echo "(apt-get install hub on Debian and Ubuntu)";
|
||||
echo "(brew install hub via Homebrew)";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# Check git remotes: we need to make sure we have a fork to push to.
|
||||
github_user=$1;
|
||||
remote_name`git remote -v |\
|
||||
grep "$github_user/mlpack (push)" |\
|
||||
head -1 |\
|
||||
awk -F' ' '{ print $1 }'`;
|
||||
if [ "a$remote_name" == "a" ]; then
|
||||
echo "No git remote found for $github_user/mlpack!";
|
||||
echo "Adding remote '$github_user'.";
|
||||
git remote add $github_user https://github.com/$github_user/mlpack;
|
||||
remote_name="$github_user";
|
||||
fi
|
||||
git fetch $github_user;
|
||||
|
||||
# Make sure everything is up to date.
|
||||
git pull;
|
||||
|
||||
# Make updates to files that will be needed for the release.
|
||||
MAJOR="$2";
|
||||
MINOR="$3";
|
||||
PATCH="$4";
|
||||
|
||||
# Update version.
|
||||
sed --in-place -E 's/PROJECT_NUMBER([ \t]*)= .*$/PROJECT_NUMBER\1= '$MAJOR'.'$MINOR'.'$PATCH'/' \
|
||||
Doxyfile;
|
||||
sed --in-place 's/MLPACK_VERSION_MAJOR [0-9]*$/MLPACK_VERSION_MAJOR '$MAJOR'/' \
|
||||
src/mlpack/core/util/version.hpp;
|
||||
sed --in-place 's/MLPACK_VERSION_MINOR [0-9]*$/MLPACK_VERSION_MINOR '$MINOR'/' \
|
||||
src/mlpack/core/util/version.hpp;
|
||||
sed --in-place 's/MLPACK_VERSION_PATCH [0-9]*$/MLPACK_VERSION_PATCH '$PATCH'/' \
|
||||
src/mlpack/core/util/version.hpp;
|
||||
sed --in-place 's/ VERSION [0-9]*\.[0-9]*/ VERSION '$MAJOR'.'$MINOR'/' \
|
||||
src/mlpack/CMakeLists.txt;
|
||||
|
||||
sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' \
|
||||
doc/guide/build.hpp;
|
||||
sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' \
|
||||
doc/guide/python_quickstart.hpp;
|
||||
sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' \
|
||||
doc/guide/sample_ml_app.hpp;
|
||||
sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' \
|
||||
doc/examples/sample-ml-app/sample-ml-app/sample-ml-app.vcxproj;
|
||||
|
||||
sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' \
|
||||
README.md;
|
||||
sed --in-place 's/([0-9]\.[0-9]\.[0-9])/('$MAJOR'.'$MINOR'.'$PATCH')/g' \
|
||||
README.md;
|
||||
sed --in-place 's/mlpack [0-9]\.[0-9]\.[0-9]/mlpack '$MAJOR'.'$MINOR'.'$PATCH'/g' \
|
||||
README.md;
|
||||
|
||||
sed --in-place 's/### mlpack ?[.]?[.]?/### mlpack '$MAJOR'.'$MINOR'.'$PATCH'/g' HISTORY.md;
|
||||
year=`date +%Y`;
|
||||
month=`date +%m`;
|
||||
day=`date +%d`;
|
||||
sed --in-place 's/###### ????-??-??/###### '$year'-'$month'-'$day'/g' \
|
||||
HISTORY.md;
|
||||
|
||||
# Get the latest release of ensmallen.
|
||||
git clone https://github.com/mlpack/ensmallen /tmp/ensmallen;
|
||||
cd /tmp/ensmallen;
|
||||
ens_ver=`git describe --tags $(git rev-list --tags --max-count=1)`;
|
||||
echo "Latest version of ensmallen: $ens_ver"
|
||||
cd -;
|
||||
sed --in-place "s/ensmallen-latest.tar.gz/ensmallen-$ens_ver.tar.gz/" CMakeLists.txt;
|
||||
rm -rf /tmp/ensmallen;
|
||||
|
||||
# Make these changes on a release branch.
|
||||
git checkout -b release-$MAJOR.$MINOR.$PATCH;
|
||||
|
||||
git add Doxyfile src/mlpack/core/util/version.hpp src/mlpack/CMakeLists.txt \
|
||||
doc/guide/build.hpp doc/guide/python_quickstart.hpp \
|
||||
doc/guide/sample_ml_app.hpp \
|
||||
doc/examples/sample-ml-app/sample-ml-app/sample-ml-app.vcxproj \
|
||||
CMakeLists.txt \
|
||||
README.md \
|
||||
HISTORY.md;
|
||||
|
||||
git commit -m "Update and release version $MAJOR.$MINOR.$PATCH.";
|
||||
|
||||
changelog_str=`cat HISTORY.md |\
|
||||
awk '/^### /{f=0} /^### mlpack '"$MAJOR"'.'"$MINOR"'.'"$PATCH"'/{f=1} f{print}' |\
|
||||
grep -v '^#' |\
|
||||
tr '\n' '!' |\
|
||||
sed -e 's/! [ ]*/ /g' |\
|
||||
tr '!' '\n'`;
|
||||
echo "Changelog string:"
|
||||
echo "$changelog_str"
|
||||
|
||||
# Update version again and add a new block for HISTORY.md.
|
||||
sed --in-place 's/MLPACK_VERSION_PATCH [0-9]*$/MLPACK_VERSION_PATCH '$(($PATCH + 1))'/' \
|
||||
src/mlpack/core/util/version.hpp;
|
||||
sed --in-place 's/ensmallen-'$ens_ver'.tar.gz/ensmallen-latest.tar.gz/' CMakeLists.txt;
|
||||
|
||||
echo "### mlpack ?.?.?" > HISTORY.md.new;
|
||||
echo "###### ????-??-??" >> HISTORY.md.new;
|
||||
echo "" >> HISTORY.md.new;
|
||||
cat HISTORY.md >> HISTORY.md.new;
|
||||
mv HISTORY.md.new HISTORY.md;
|
||||
|
||||
git add HISTORY.md;
|
||||
git add src/mlpack/core/util/version.hpp CMakeLists.txt;
|
||||
|
||||
git commit -m "Add new block for next release to HISTORY.md.";
|
||||
|
||||
# Push to new branch.
|
||||
git push --set-upstream $github_user release-$MAJOR.$MINOR.$PATCH;
|
||||
|
||||
# Next, we have to actually open the PR for the release.
|
||||
hub pull-request \
|
||||
-b mlpack:master \
|
||||
-h $github_user:release-$MAJOR.$MINOR.$PATCH \
|
||||
-m "Release version $MAJOR.$MINOR.$PATCH" \
|
||||
-m "This automatically-generated pull request adds the commits necessary to
|
||||
make the $MAJOR.$MINOR.$PATCH release." \
|
||||
-m "Once the PR is merged, mlpack-bot will tag the release as HEAD~1 (so
|
||||
that it doesn't include the new HISTORY block) and publish it." \
|
||||
-m "Or, well, hopefully that will happen someday." \
|
||||
-m "When you merge this PR, be sure to merge it using a *rebase*." \
|
||||
-m "### Changelog" \
|
||||
-m "$changelog_str" \
|
||||
-l "t: release"
|
||||
|
||||
echo "";
|
||||
echo "Switching back to 'master' branch.";
|
||||
echo "If you want to access the release branch again, use \`git checkout " \
|
||||
"release-$MAJOR.$MINOR.$PATCH\`.";
|
||||
echo 0;
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# This script is used to update the website after an mlpack release is made.
|
||||
# Push access to the mlpack.org website repository is needed. Generally, this
|
||||
# script will be run by mlpack-bot, so it never needs to be run by hand.
|
||||
#
|
||||
# Usage: update-website-after-release.sh <major> <minor> <patch>
|
||||
|
||||
MAJOR=$1;
|
||||
MINOR=$2;
|
||||
PATCH=$3;
|
||||
|
||||
# Make sure that the mlpack repository exists.
|
||||
dest_remote_name=`git remote -v |\
|
||||
grep "mlpack/mlpack (fetch)" |\
|
||||
head -1 |\
|
||||
awk -F' ' '{ print $1 }'`;
|
||||
|
||||
if [ "a$dest_remote_name" == "a" ]; then
|
||||
echo "No git remote found for mlpack/mlpack!";
|
||||
echo "Make sure that you've got the mlpack repository as a remote, and" \
|
||||
"that the master branch from that remote is checked out.";
|
||||
echo "You can do this with a fresh repository via \`git clone" \
|
||||
"https://github.com/mlpack/mlpack\`.";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
# Update the checked out repository, so that we can get the tags.
|
||||
git fetch $dest_remote_name;
|
||||
|
||||
# Check out a copy of the ensmallen.org repository.
|
||||
git clone git@github.com:mlpack/mlpack.org /tmp/mlpack.org/;
|
||||
|
||||
# Create the release file.
|
||||
git archive --prefix=mlpack-$MAJOR.$MINOR.$PATCH/ $MAJOR.$MINOR.$PATCH |\
|
||||
gzip > /tmp/mlpack.org/files/mlpack-$MAJOR.$MINOR.$PATCH.tar.gz;
|
||||
|
||||
# Now update the website.
|
||||
wd=`pwd`;
|
||||
cd /tmp/mlpack.org/;
|
||||
|
||||
# These may be specific to the old website.
|
||||
sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' index.md;
|
||||
sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' docs.md;
|
||||
sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' getstarted.md;
|
||||
sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' community.md;
|
||||
git add index.md docs.md getstarted.md community.md;
|
||||
|
||||
# These may be specific to the new website.
|
||||
sed --in-place 's/mlpack-[0-9]\.[0-9]\.[0-9]/mlpack-'$MAJOR'.'$MINOR'.'$PATCH'/g' html/index.html;
|
||||
sed --in-place 's/Version [0-9]\.[0-9]\.[0-9]/Version '$MAJOR'.'$MINOR'.'$PATCH'/g' html/index.html;
|
||||
sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' html/getstarted.html;
|
||||
sed --in-place 's/[0-9]\.[0-9]\.[0-9]/'$MAJOR'.'$MINOR'.'$PATCH'/g' html/config/install.md;
|
||||
git add html/index.html html/getstarted.html html/config/install.md;
|
||||
|
||||
git commit -m "Update links to latest stable version.";
|
||||
|
||||
git add files/mlpack-$MAJOR.$MINOR.$PATCH.tar.gz;
|
||||
git commit -m "Release version $MAJOR.$MINOR.$PATCH.";
|
||||
|
||||
# Finally, push, and we're done.
|
||||
git push origin;
|
||||
cd $wd;
|
||||
|
||||
rm -rf /tmp/mlpack.org;
|
||||
@@ -54,7 +54,7 @@ target_link_libraries(mlpack ${MLPACK_LIBRARIES})
|
||||
|
||||
set_target_properties(mlpack
|
||||
PROPERTIES
|
||||
VERSION 3.3
|
||||
VERSION 3.4
|
||||
SOVERSION 3
|
||||
)
|
||||
|
||||
@@ -125,69 +125,13 @@ string(REGEX REPLACE ".*#define MLPACK_VERSION_PATCH [\"]?([0-9x]+)[\"]?.*"
|
||||
set(PACKAGE_VERSION
|
||||
"${MLPACK_VERSION_MAJOR}.${MLPACK_VERSION_MINOR}.${MLPACK_VERSION_PATCH}")
|
||||
|
||||
# If we are building Python bindings, we have to configure setup.py but only
|
||||
# after we've recursed into methods/.
|
||||
if (BUILDING_PYTHON_BINDINGS)
|
||||
post_python_bindings()
|
||||
post_julia_setup()
|
||||
post_go_setup()
|
||||
|
||||
get_property(CYTHON_INCLUDE_DIRECTORIES DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PROPERTY INCLUDE_DIRECTORIES)
|
||||
add_custom_target(python_configure
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-D SETUP_PY_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/python/setup.py.in
|
||||
-D SETUP_PY_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py
|
||||
-D PACKAGE_VERSION="${PACKAGE_VERSION}"
|
||||
-D Boost_SERIALIZATION_LIBRARY="${Boost_SERIALIZATION_LIBRARY_RELEASE}"
|
||||
-D Boost_LIBRARY_DIRS="${Boost_LIBRARY_DIRS}"
|
||||
-D ARMADILLO_LIBRARIES="${ARMADILLO_LIBRARIES}"
|
||||
-D MLPACK_LIBRARY=$<TARGET_LINKER_FILE:mlpack>
|
||||
-D MLPACK_LIBDIR=$<TARGET_LINKER_FILE_DIR:mlpack>
|
||||
-D MLPACK_PYXS="${MLPACK_PYXS}"
|
||||
-D OpenMP_CXX_FLAGS="${OpenMP_CXX_FLAGS}"
|
||||
-D DISABLE_CFLAGS="${DISABLE_CFLAGS}"
|
||||
-D CYTHON_INCLUDE_DIRECTORIES="${CYTHON_INCLUDE_DIRECTORIES}"
|
||||
-D CMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
|
||||
-D OUTPUT_DIR=${CMAKE_BINARY_DIR}
|
||||
-P "${CMAKE_SOURCE_DIR}/src/mlpack/bindings/python/ConfigureSetup.cmake"
|
||||
BYPRODUCTS "${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/setup.py"
|
||||
COMMENT "Configuring setup.py...")
|
||||
add_dependencies(python_configure python_copy)
|
||||
add_dependencies(python_configured python_configure)
|
||||
|
||||
# Append the package version to __init__.py after all the imports are loaded.
|
||||
file(APPEND ${CMAKE_BINARY_DIR}/src/mlpack/bindings/python/mlpack/__init__.py
|
||||
"__version__='${PACKAGE_VERSION}'\n")
|
||||
endif ()
|
||||
|
||||
# If we are building Julia bindings, we have to end the 'module' declaration in
|
||||
# mlpack.jl
|
||||
if (BUILD_JULIA_BINDINGS)
|
||||
file(APPEND
|
||||
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/julia/mlpack/src/mlpack.jl"
|
||||
"\nend\ninclude(\"functions.jl\")\ninclude(\"serialization.jl\")\nend\n")
|
||||
endif ()
|
||||
|
||||
|
||||
# If we are building Go bindings, we have to end the 'module' declaration in
|
||||
# models.go
|
||||
if (BUILD_GO_BINDINGS)
|
||||
file(APPEND
|
||||
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/models.go"
|
||||
"*/\n"
|
||||
"import \"C\"\n\n"
|
||||
"import (\n"
|
||||
" \"runtime\"\n"
|
||||
" \"unsafe\"\n"
|
||||
")\n\n")
|
||||
|
||||
include("${CMAKE_SOURCE_DIR}/CMake/go/AppendModel.cmake")
|
||||
# Read list content.
|
||||
get_property(MODELS GLOBAL PROPERTY GO_MODELS)
|
||||
foreach (models IN LISTS MODELS)
|
||||
append_model(
|
||||
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/models.go"
|
||||
${models})
|
||||
endforeach()
|
||||
endif()
|
||||
# If we are building R-bindings, we have to run some setup after we
|
||||
# recurse into methods/. If not, this macro is empty.
|
||||
post_r_setup()
|
||||
|
||||
# If we are building Markdown documentation, we have to run some setup after we
|
||||
# recurse into methods/. If not, this function is empty.
|
||||
|
||||
@@ -5,6 +5,7 @@ set(DIRS
|
||||
markdown
|
||||
python
|
||||
go
|
||||
R
|
||||
tests
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,443 @@
|
||||
macro (not_found_return message)
|
||||
message(STATUS "${message}")
|
||||
macro (add_r_binding name)
|
||||
# Do nothing.
|
||||
endmacro ()
|
||||
|
||||
macro (post_r_setup)
|
||||
# Do nothing.
|
||||
endmacro ()
|
||||
|
||||
return()
|
||||
endmacro ()
|
||||
|
||||
# If we are not supposed to make R bindings, define the macro so it does
|
||||
# nothing and leave this file.
|
||||
if (NOT BUILD_R_BINDINGS)
|
||||
not_found_return("Not building R bindings.")
|
||||
endif ()
|
||||
|
||||
if (BUILD_R_BINDINGS)
|
||||
|
||||
# If mlpack upgrade the version of dependencies, then we also have to update the version here.
|
||||
set(RcppArmadillo_Version "0.${ARMADILLO_VERSION}")
|
||||
set(RcppEnsmallen_Version "0.${ENSMALLEN_VERSION}")
|
||||
set(BH_Version "${BOOST_VERSION}")
|
||||
|
||||
# Import find_r_module.
|
||||
include(${CMAKE_SOURCE_DIR}/CMake/FindRModule.cmake)
|
||||
find_package(R 4.0)
|
||||
if (NOT R_FOUND)
|
||||
set(R_NOT_FOUND_MSG "${R_NOT_FOUND_MSG}\n - R")
|
||||
endif ()
|
||||
find_r_module(roxygen2)
|
||||
if (NOT R_ROXYGEN2)
|
||||
set(R_NOT_FOUND_MSG "${R_NOT_FOUND_MSG}\n - roxygen2")
|
||||
endif ()
|
||||
find_r_module(Rcpp 0.12.12)
|
||||
if (NOT R_RCPP)
|
||||
set(R_NOT_FOUND_MSG "${R_NOT_FOUND_MSG}\n - Rcpp")
|
||||
endif ()
|
||||
find_r_module(RcppArmadillo "${RcppArmadillo_Version}")
|
||||
if (NOT R_RCPPARMADILLO)
|
||||
set(R_NOT_FOUND_MSG "${R_NOT_FOUND_MSG}\n - RcppArmadillo")
|
||||
endif ()
|
||||
find_r_module(RcppEnsmallen "${RcppEnsmallen_Version}")
|
||||
if (NOT R_RCPPENSMALLEN)
|
||||
set(R_NOT_FOUND_MSG "${R_NOT_FOUND_MSG}\n - RcppEnsmallen")
|
||||
endif ()
|
||||
find_r_module(BH "${BH_Version}")
|
||||
if (NOT R_BH)
|
||||
set(R_NOT_FOUND_MSG "${R_NOT_FOUND_MSG}\n - BH")
|
||||
endif ()
|
||||
find_r_module(testthat)
|
||||
if (NOT R_TESTTHAT)
|
||||
set(R_NOT_FOUND_MSG "${R_NOT_FOUND_MSG}\n - testthat")
|
||||
endif ()
|
||||
|
||||
## We need to check here if R and other dependencies is even available, as
|
||||
## it is require to build R-bindings.
|
||||
if (FORCE_BUILD_R_BINDINGS)
|
||||
if (NOT R_FOUND OR NOT R_RCPP OR NOT R_RCPPARMADILLO OR NOT R_RCPPENSMALLEN
|
||||
OR NOT R_BH OR NOT R_ROXYGEN2 OR NOT R_TESTTHAT)
|
||||
unset(BUILD_R_BINDINGS CACHE)
|
||||
message(FATAL_ERROR "Could not Build R Bindings, Following modules are not available:${R_NOT_FOUND_MSG}")
|
||||
endif()
|
||||
else ()
|
||||
if (NOT R_FOUND OR NOT R_RCPP OR NOT R_RCPPARMADILLO OR NOT R_RCPPENSMALLEN
|
||||
OR NOT R_BH OR NOT R_ROXYGEN2 OR NOT R_TESTTHAT)
|
||||
unset(BUILD_R_BINDINGS CACHE)
|
||||
not_found_return("Not building R bindings, Following modules are not available:${R_NOT_FOUND_MSG}")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
add_custom_target(R ALL)
|
||||
|
||||
# Now configure DESCRIPTION.
|
||||
file(READ "${CMAKE_SOURCE_DIR}/src/mlpack/core/util/version.hpp"
|
||||
VERSION_HPP_CONTENTS)
|
||||
string(REGEX REPLACE ".*#define MLPACK_VERSION_MAJOR ([0-9]+).*" "\\1"
|
||||
MLPACK_VERSION_MAJOR "${VERSION_HPP_CONTENTS}")
|
||||
string(REGEX REPLACE ".*#define MLPACK_VERSION_MINOR ([0-9]+).*" "\\1"
|
||||
MLPACK_VERSION_MINOR "${VERSION_HPP_CONTENTS}")
|
||||
string(REGEX REPLACE ".*#define MLPACK_VERSION_PATCH [\"]?([0-9x]+)[\"]?.*"
|
||||
"\\1" MLPACK_VERSION_PATCH "${VERSION_HPP_CONTENTS}")
|
||||
set(PACKAGE_VERSION
|
||||
"${MLPACK_VERSION_MAJOR}.${MLPACK_VERSION_MINOR}.${MLPACK_VERSION_PATCH}")
|
||||
|
||||
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
|
||||
@ONLY)
|
||||
|
||||
# Create the empty NAMESPACE file that will include all export functions.
|
||||
file(WRITE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/mlpack/NAMESPACE"
|
||||
"# Generated by roxygen2: do not edit by hand"
|
||||
"\n\n")
|
||||
|
||||
set(CPP_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/r_util.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/rcpp_mlpack.h"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/Makevars"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mlpack/src/Makevars.win"
|
||||
)
|
||||
|
||||
set(R_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mlpack/R/matrix_utils.R"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mlpack/R/package.R"
|
||||
)
|
||||
|
||||
set(BINDINGS_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/get_type.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"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/R_option.hpp"
|
||||
)
|
||||
|
||||
set(TESTS_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tests/test_r_binding_main.cpp"
|
||||
)
|
||||
|
||||
set(R_TESTTHAT_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mlpack/tests/testthat/test-R_binding.R"
|
||||
)
|
||||
|
||||
set(R_TESTS_SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mlpack/tests/testthat.R"
|
||||
)
|
||||
|
||||
set(LICENSE_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/LICENSE.txt"
|
||||
)
|
||||
add_custom_target(r_copy ALL)
|
||||
|
||||
# First we have to create all the required directories for copy.
|
||||
add_custom_command(TARGET r_copy PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mlpack/R/
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mlpack/tests/testthat
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/mlpack/bindings/R/tests
|
||||
)
|
||||
|
||||
if (BUILD_TESTS)
|
||||
add_custom_command(TARGET r_copy PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
|
||||
${TESTS_SOURCES}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/mlpack/bindings/R/tests)
|
||||
endif()
|
||||
|
||||
# Copy all necessary files for building package.
|
||||
foreach(cpp_file ${CPP_SOURCES})
|
||||
add_custom_command(TARGET r_copy PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
|
||||
${cpp_file}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/)
|
||||
endforeach()
|
||||
foreach(r_file ${R_SOURCES})
|
||||
add_custom_command(TARGET r_copy PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
|
||||
${r_file}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mlpack/R/)
|
||||
endforeach()
|
||||
foreach(bindings_file ${BINDINGS_SOURCES})
|
||||
add_custom_command(TARGET r_copy PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
|
||||
${bindings_file}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mlpack/src/mlpack/bindings/R)
|
||||
endforeach()
|
||||
add_custom_command(TARGET r_copy PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
|
||||
${R_TESTTHAT_SOURCES}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mlpack/tests/testthat)
|
||||
add_custom_command(TARGET r_copy PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
|
||||
${R_TESTS_SOURCES}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mlpack/tests)
|
||||
add_custom_command(TARGET r_copy PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different
|
||||
${LICENSE_SOURCES}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/mlpack)
|
||||
add_custom_command(TARGET r_copy PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E rename
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/mlpack/LICENSE.txt"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/mlpack/LICENSE")
|
||||
# This file will take care of multiple definition of functions in .cpp files.
|
||||
add_custom_command(TARGET r_copy PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E touch
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/mlpack/model.txt")
|
||||
|
||||
file(COPY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/mlpack/cleanup"
|
||||
DESTINATION
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/mlpack/")
|
||||
|
||||
# Do the actual build.
|
||||
add_custom_target(r_build ALL)
|
||||
|
||||
# "model.txt" is no longer useful, after generating src/.cpp files.
|
||||
# Remove this file.
|
||||
add_custom_command(TARGET r_build POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E remove -f "model.txt"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mlpack"
|
||||
)
|
||||
|
||||
# Build RcppExports.cpp/.R, NAMESPACE and man/ files.
|
||||
add_custom_command(TARGET r_build POST_BUILD
|
||||
COMMAND ${RSCRIPT_EXECUTABLE} ARGS "-e" "'Rcpp::compileAttributes()'"
|
||||
COMMAND ${RSCRIPT_EXECUTABLE} ARGS "-e" "'roxygen2::roxygenize(\".\")'"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mlpack"
|
||||
)
|
||||
|
||||
# Build mlpack_${PACKAGE_VERSION}.tar.gz package.
|
||||
add_custom_command(TARGET r_build POST_BUILD
|
||||
COMMAND ${R_EXECUTABLE} CMD build mlpack
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
|
||||
# Installation script for the packagae.
|
||||
install(CODE
|
||||
"execute_process(
|
||||
COMMAND R CMD INSTALL mlpack_${PACKAGE_VERSION}.tar.gz
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
|
||||
add_dependencies(R r_build)
|
||||
endif ()
|
||||
|
||||
# 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"
|
||||
)
|
||||
|
||||
# Initialize list of models.
|
||||
set_property(GLOBAL PROPERTY R_MODELS "")
|
||||
|
||||
macro (add_r_binding name)
|
||||
if (BUILD_R_BINDINGS)
|
||||
|
||||
# Append content to the list of models.
|
||||
set_property(GLOBAL APPEND PROPERTY R_MODELS ${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp)
|
||||
|
||||
# 1. Generate ${name}.cpp.
|
||||
add_custom_command(OUTPUT
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/src/${name}.cpp
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DMODEL_FILE=${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/model.txt
|
||||
-DPROGRAM_NAME=${name}
|
||||
-DPROGRAM_MAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp
|
||||
-DSOURCE_DIR=${CMAKE_SOURCE_DIR}
|
||||
-DR_CPP_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/r_method.cpp.in
|
||||
-DR_CPP_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/src/${name}.cpp
|
||||
-P ${CMAKE_SOURCE_DIR}/CMake/R/ConfigureRCPP.cmake
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/r_method.cpp.in
|
||||
${CMAKE_SOURCE_DIR}/CMake/R/ConfigureRCPP.cmake)
|
||||
|
||||
# 2. Generate ${name}.R.
|
||||
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/build/generate_r_${name}.cpp
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DNAME=${name}
|
||||
-DGENERATE_CPP_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/generate_R.cpp.in
|
||||
-DGENERATE_CPP_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/build/generate_r_${name}.cpp
|
||||
-DPROGRAM_MAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp
|
||||
-P ${CMAKE_SOURCE_DIR}/CMake/ConfigureFile.cmake
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/generate_R.cpp.in
|
||||
${CMAKE_SOURCE_DIR}/CMake/ConfigureFile.cmake
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/src/${name}.cpp)
|
||||
|
||||
add_executable(generate_r_${name}
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/build/generate_r_${name}.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/print_R.hpp
|
||||
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/print_R.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/get_type.hpp
|
||||
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/R_option.hpp
|
||||
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/print_input_param.hpp
|
||||
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/print_input_processing.hpp
|
||||
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/print_serialize_util.hpp
|
||||
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/print_output_processing.hpp)
|
||||
target_link_libraries(generate_r_${name} mlpack ${MLPACK_LIBRARIES})
|
||||
set_target_properties(generate_r_${name} PROPERTIES
|
||||
COMPILE_FLAGS "-DBINDING_TYPE=BINDING_TYPE_R"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/build/bin/")
|
||||
add_custom_command(TARGET generate_r_${name} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DGENERATE_BINDING_PROGRAM=${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/build/bin/generate_r_${name}
|
||||
-DBINDING_OUTPUT_FILE=${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/R/${name}.R
|
||||
-P ${CMAKE_SOURCE_DIR}/CMake/GenerateBinding.cmake)
|
||||
add_dependencies(generate_r_${name} r_copy)
|
||||
add_dependencies(r_build generate_r_${name})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro (post_r_setup)
|
||||
# In Case of R_Bindings Move all of these header and source files to
|
||||
# <package>/src/mlpack/.
|
||||
# Collect all header and source files in the library.
|
||||
file(GLOB_RECURSE R_SRC_HPP_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.hpp)
|
||||
file(GLOB_RECURSE R_SRC_CPP_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" *.cpp)
|
||||
set(R_SRC_FILES ${R_SRC_HPP_FILES} ${R_SRC_CPP_FILES})
|
||||
|
||||
# In case of R_Bindings we are copying all of these header to
|
||||
# <package>/src/cereal/ because the currently-packaged version
|
||||
# of Rcereal throws warnings on CRAN.
|
||||
# Collect all header files in the cereal folder.
|
||||
file(GLOB_RECURSE RCEREAL_SRC_H_FILES RELATIVE "${CEREAL_INCLUDE_DIR}"
|
||||
"${CEREAL_INCLUDE_DIR}/cereal/*.h")
|
||||
file(GLOB_RECURSE RCEREAL_SRC_HPP_FILES RELATIVE "${CEREAL_INCLUDE_DIR}"
|
||||
"${CEREAL_INCLUDE_DIR}/cereal/*.hpp")
|
||||
set(RCEREAL_SRC_FILES ${RCEREAL_SRC_HPP_FILES} ${RCEREAL_SRC_H_FILES})
|
||||
|
||||
# First we have to create that directory though.
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E
|
||||
make_directory ${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/src/mlpack
|
||||
)
|
||||
|
||||
# Then copy each of the header and source files over to that directory.
|
||||
set(MLPACK_SOURCES
|
||||
"${CMAKE_BINARY_DIR}/src/mlpack/mlpack_export.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/prereqs.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/core.hpp"
|
||||
)
|
||||
|
||||
foreach(mlpack_sources ${MLPACK_SOURCES})
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${mlpack_sources}
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/src/mlpack
|
||||
)
|
||||
endforeach()
|
||||
|
||||
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/util")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${r_src_file}
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/src/mlpack/${r_src_file}
|
||||
)
|
||||
|
||||
# Collect path of all source files and append to ${R_SRC}.
|
||||
if ("${r_src_file}" MATCHES ".cpp" AND
|
||||
NOT "${r_src_file}" MATCHES "main.cpp" AND
|
||||
# Note: this implementation of MVU does not work. See #189.
|
||||
NOT "${r_src_file}" MATCHES "mvu")
|
||||
string(APPEND R_SRC "#include <mlpack/${r_src_file}>\n")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Copy cereal headers for R-bindings.
|
||||
foreach(rcereal_src_file ${RCEREAL_SRC_FILES})
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${CEREAL_INCLUDE_DIR}/${rcereal_src_file}
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/src/${rcereal_src_file}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Resolve gcc Warnings.
|
||||
file(READ ${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/src/cereal/external/base64.hpp CEREAL_BASE64)
|
||||
string(REGEX REPLACE
|
||||
"\n#ifdef __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wconversion\"\n#endif\n"
|
||||
"" CEREAL_BASE64 "${CEREAL_BASE64}")
|
||||
string(REGEX REPLACE
|
||||
"#ifdef __GNUC__\n#pragma GCC diagnostic pop\n#endif"
|
||||
"" CEREAL_BASE64 "${CEREAL_BASE64}")
|
||||
file(WRITE ${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/src/cereal/external/base64.hpp "${CEREAL_BASE64}")
|
||||
|
||||
# Then configure 'mlpack.h.in' using ${R_SRC}.
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/R/mlpack/inst/include/mlpack.h.in
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/inst/include/mlpack.h
|
||||
@ONLY)
|
||||
|
||||
file(WRITE
|
||||
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/R/serialization.R"
|
||||
"#' Serialize/Unserialize an mlpack model.\n"
|
||||
"#'\n"
|
||||
"#' @param model Input model pointer.\n"
|
||||
"#' @param filename Input filename.\n"
|
||||
"#' @export\n"
|
||||
"#' @rdname mlpack-serialization\n"
|
||||
"Serialize <- function(model, filename) {\n"
|
||||
" model_serialization_function <-\n"
|
||||
" switch(attributes(model)$type,\n")
|
||||
|
||||
include("${CMAKE_SOURCE_DIR}/CMake/R/AppendSerialization.cmake")
|
||||
# Read list content.
|
||||
get_property(MODELS GLOBAL PROPERTY R_MODELS)
|
||||
foreach (models IN LISTS MODELS)
|
||||
append_serialization(
|
||||
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/R/serialization.R"
|
||||
${models}
|
||||
TRUE)
|
||||
endforeach()
|
||||
|
||||
file(APPEND
|
||||
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/R/serialization.R"
|
||||
" stop(\"Requested model type is not currently supported.\")\n )\n\n"
|
||||
" # Read in model\n"
|
||||
" con <- file(as.character(filename), \"wb\")\n"
|
||||
" serialize(model_serialization_function(model), con)\n"
|
||||
" close(con)\n}\n\n\n"
|
||||
"#' @return For Unserialize, Output model_ptr.\n"
|
||||
"#' @export\n"
|
||||
"#' @rdname mlpack-serialization\n"
|
||||
"Unserialize <- function(filename) {\n"
|
||||
" con <- file(as.character(filename), \"rb\")\n"
|
||||
" model <- unserialize(con)\n\n"
|
||||
" model_unserialization_function <-\n"
|
||||
" switch(attributes(model)$type,\n")
|
||||
foreach (models IN LISTS MODELS)
|
||||
append_serialization(
|
||||
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/R/serialization.R"
|
||||
${models}
|
||||
FALSE)
|
||||
endforeach()
|
||||
|
||||
file(APPEND
|
||||
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack/R/serialization.R"
|
||||
" stop(\"Requested model type is not currently supported.\")\n )\n\n"
|
||||
" model_ptr <- model_unserialization_function(model)\n"
|
||||
" close(con)\n"
|
||||
" return(model_ptr)\n}\n")
|
||||
endmacro()
|
||||
|
||||
if (BUILD_TESTS AND BUILD_R_BINDINGS)
|
||||
add_subdirectory(tests)
|
||||
endif ()
|
||||
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* @file bindings/R/R_option.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* The R option type.
|
||||
*
|
||||
* 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_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 {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* The R option class.
|
||||
*/
|
||||
template<typename T>
|
||||
class ROption
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct a ROption object. When constructed, it will register itself
|
||||
* with IO. The testName parameter is not used and added for compatibility
|
||||
* reasons.
|
||||
*
|
||||
* @param defaultValue Default value this parameter will be initialized to
|
||||
* (for flags, this should be false, for instance).
|
||||
* @param identifier The name of the option (no dashes in front; for --help,
|
||||
* we would pass "help").
|
||||
* @param description A short string describing the option.
|
||||
* @param alias Short name of the parameter. "" for no alias.
|
||||
* @param cppName Name of the C++ type of this parameter (i.e. "int").
|
||||
* @param required Whether or not the option is required at runtime.
|
||||
* @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.
|
||||
*/
|
||||
ROption(const T defaultValue,
|
||||
const std::string& identifier,
|
||||
const std::string& description,
|
||||
const std::string& alias,
|
||||
const std::string& cppName,
|
||||
const bool required = false,
|
||||
const bool input = true,
|
||||
const bool noTranspose = false,
|
||||
const std::string& /* testName */ = "")
|
||||
{
|
||||
// Create the ParamData object to give to IO.
|
||||
util::ParamData data;
|
||||
data.desc = description;
|
||||
data.name = identifier;
|
||||
data.tname = TYPENAME(T);
|
||||
data.alias = alias[0];
|
||||
data.wasPassed = false;
|
||||
data.noTranspose = noTranspose;
|
||||
data.required = required;
|
||||
data.input = input;
|
||||
data.loaded = false;
|
||||
|
||||
// Only "verbose" will be persistent.
|
||||
if (identifier == "verbose")
|
||||
data.persistent = true;
|
||||
else
|
||||
data.persistent = false;
|
||||
data.cppType = cppName;
|
||||
|
||||
// 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<T>;
|
||||
IO::GetSingleton().functionMap[data.tname]["GetPrintableParam"] =
|
||||
&GetPrintableParam<T>;
|
||||
|
||||
// These are used by the R generator.
|
||||
IO::GetSingleton().functionMap[data.tname]["PrintDoc"] = &PrintDoc<T>;
|
||||
IO::GetSingleton().functionMap[data.tname]["PrintInputParam"] =
|
||||
&PrintInputParam<T>;
|
||||
IO::GetSingleton().functionMap[data.tname]["PrintOutputProcessing"] =
|
||||
&PrintOutputProcessing<T>;
|
||||
IO::GetSingleton().functionMap[data.tname]["PrintInputProcessing"] =
|
||||
&PrintInputProcessing<T>;
|
||||
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 IO, so we have to keep the
|
||||
// options separate. programName is a global variable from mlpack_main.hpp.
|
||||
IO::Add(std::move(data));
|
||||
if (identifier != "verbose")
|
||||
IO::StoreSettings(IO::ProgramName());
|
||||
IO::ClearSettings();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file bindings/R/default_param.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Return the default value of a parameter, depending on its type.
|
||||
*
|
||||
* 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_DEFAULT_PARAM_HPP
|
||||
#define MLPACK_BINDINGS_R_DEFAULT_PARAM_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/param_data.hpp>
|
||||
#include <mlpack/core/util/is_std_vector.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* Return the default value of an option. This is for regular types.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string DefaultParamImpl(
|
||||
util::ParamData& data,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::disable_if<util::IsStdVector<T>>::type* = 0,
|
||||
const typename boost::disable_if<data::HasSerialize<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T, std::string>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<mlpack::data::DatasetInfo, arma::mat>>>::type* = 0);
|
||||
|
||||
/**
|
||||
* Return the default value of a vector option.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string DefaultParamImpl(
|
||||
util::ParamData& data,
|
||||
const typename boost::enable_if<util::IsStdVector<T>>::type* = 0);
|
||||
|
||||
/**
|
||||
* Return the default value of a string option.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string DefaultParamImpl(
|
||||
util::ParamData& data,
|
||||
const typename boost::enable_if<std::is_same<T, std::string>>::type* = 0);
|
||||
|
||||
/**
|
||||
* Return the default value of a matrix option, a tuple option, a
|
||||
* serializable option, or a string option (this returns the default filename,
|
||||
* or '' if the default is no file).
|
||||
*/
|
||||
template<typename T>
|
||||
std::string DefaultParamImpl(
|
||||
util::ParamData& data,
|
||||
const typename boost::enable_if_c<
|
||||
arma::is_arma_type<T>::value ||
|
||||
std::is_same<T, std::tuple<mlpack::data::DatasetInfo,
|
||||
arma::mat>>::value>::type* /* junk */ = 0);
|
||||
|
||||
/**
|
||||
* Return the default value of a model option (this returns the default
|
||||
* filename, or '' if the default is no file).
|
||||
*/
|
||||
template<typename T>
|
||||
std::string DefaultParamImpl(
|
||||
util::ParamData& data,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::enable_if<data::HasSerialize<T>>::type* = 0);
|
||||
|
||||
/**
|
||||
* Return the default value of an option. This is the function that will be
|
||||
* placed into the IO functionMap.
|
||||
*/
|
||||
template<typename T>
|
||||
void DefaultParam(util::ParamData& data,
|
||||
const void* /* input */,
|
||||
void* output)
|
||||
{
|
||||
std::string* outstr = (std::string*) output;
|
||||
*outstr = DefaultParamImpl<typename std::remove_pointer<T>::type>(data);
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
// Include implementation.
|
||||
#include "default_param_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @file bindings/R/default_param_impl.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Return the default value of a parameter, depending on its type.
|
||||
*
|
||||
* 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_DEFAULT_PARAM_IMPL_HPP
|
||||
#define MLPACK_BINDINGS_R_DEFAULT_PARAM_IMPL_HPP
|
||||
|
||||
#include "default_param.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* Return the default value of an option.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string DefaultParamImpl(
|
||||
util::ParamData& data,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* /* junk */,
|
||||
const typename boost::disable_if<util::IsStdVector<T>>::type* /* junk */,
|
||||
const typename boost::disable_if<data::HasSerialize<T>>::type* /* junk */,
|
||||
const typename boost::disable_if<std::is_same<T, std::string>>::type*,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<mlpack::data::DatasetInfo, arma::mat>>>::type* /* junk */)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
if (std::is_same<T, bool>::value)
|
||||
oss << "FALSE";
|
||||
else
|
||||
oss << boost::any_cast<T>(data.value);
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default value of a vector option.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string DefaultParamImpl(
|
||||
util::ParamData& data,
|
||||
const typename boost::enable_if<util::IsStdVector<T>>::type* /* junk */)
|
||||
{
|
||||
// Print each element in an array delimited by square brackets.
|
||||
std::ostringstream oss;
|
||||
const T& vector = boost::any_cast<T>(data.value);
|
||||
oss << "c(";
|
||||
if (std::is_same<T, std::vector<std::string>>::value)
|
||||
{
|
||||
if (vector.size() > 0)
|
||||
{
|
||||
for (size_t i = 0; i < vector.size() - 1; ++i)
|
||||
{
|
||||
oss << "'" << vector[i] << "', ";
|
||||
}
|
||||
|
||||
oss << "'" << vector[vector.size() - 1] << "'";
|
||||
}
|
||||
|
||||
oss << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vector.size() > 0)
|
||||
{
|
||||
for (size_t i = 0; i < vector.size() - 1; ++i)
|
||||
{
|
||||
oss << vector[i] << ", ";
|
||||
}
|
||||
|
||||
oss << vector[vector.size() - 1];
|
||||
}
|
||||
|
||||
oss << ")";
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default value of a string option.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string DefaultParamImpl(
|
||||
util::ParamData& data,
|
||||
const typename boost::enable_if<std::is_same<T, std::string>>::type*)
|
||||
{
|
||||
const std::string& s = *boost::any_cast<std::string>(&data.value);
|
||||
return "\"" + s + "\"";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default value of a matrix option (this returns the default
|
||||
* filename, or '' if the default is no file).
|
||||
*/
|
||||
template<typename T>
|
||||
std::string DefaultParamImpl(
|
||||
util::ParamData& /* data */,
|
||||
const typename boost::enable_if_c<
|
||||
arma::is_arma_type<T>::value ||
|
||||
std::is_same<T, std::tuple<mlpack::data::DatasetInfo,
|
||||
arma::mat>>::value>::type* /* junk */)
|
||||
{
|
||||
// Get the filename and return it, or return an empty string.
|
||||
if (std::is_same<T, arma::rowvec>::value ||
|
||||
std::is_same<T, arma::vec>::value ||
|
||||
std::is_same<T, arma::mat>::value)
|
||||
{
|
||||
return "matrix(numeric(), 0, 0)";
|
||||
}
|
||||
else if (std::is_same<T, arma::Row<size_t>>::value ||
|
||||
std::is_same<T, arma::Col<size_t>>::value ||
|
||||
std::is_same<T, arma::Mat<size_t>>::value)
|
||||
{
|
||||
return "matrix(integer(), 0, 0)";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "matrix(numeric(), 0, 0)";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default value of a model option (always "None").
|
||||
*/
|
||||
template<typename T>
|
||||
std::string DefaultParamImpl(
|
||||
util::ParamData& /* data */,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* /* junk */,
|
||||
const typename boost::enable_if<data::HasSerialize<T>>::type* /* junk */)
|
||||
{
|
||||
return "NA";
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file R/generate_R.cpp.in
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* This is a template file to call the PrintR() function for a given binding.
|
||||
*/
|
||||
#define BINDING_TYPE BINDING_TYPE_R
|
||||
// Disable debug output.
|
||||
#ifdef DEBUG
|
||||
#define HAD_DEBUG
|
||||
#undef DEBUG
|
||||
#endif
|
||||
#include <mlpack/core/util/log.hpp>
|
||||
#ifdef HAD_DEBUG
|
||||
#undef HAD_DEBUG
|
||||
#define DEBUG
|
||||
#endif
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
#include <mlpack/bindings/R/print_R.hpp>
|
||||
|
||||
// This will include the ParamData options that are part of the program.
|
||||
#include <${PROGRAM_MAIN_FILE}>
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::bindings;
|
||||
using namespace mlpack::bindings::r;
|
||||
using namespace std;
|
||||
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());
|
||||
|
||||
PrintR(IO::GetSingleton().doc, "${NAME}");
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* @file bindings/R/get_printable_param.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Get a printable version of parameters.
|
||||
*
|
||||
* 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_PRINTABLE_PARAM_HPP
|
||||
#define MLPACK_BINDINGS_R_GET_PRINTABLE_PARAM_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/is_std_vector.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* Print an option of a simple type.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string GetPrintableParam(
|
||||
util::ParamData& data,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::disable_if<util::IsStdVector<T>>::type* = 0,
|
||||
const typename boost::disable_if<data::HasSerialize<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << boost::any_cast<T>(data.value);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a vector option, with spaces between it.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string GetPrintableParam(
|
||||
util::ParamData& data,
|
||||
const typename boost::enable_if<util::IsStdVector<T>>::type* = 0)
|
||||
{
|
||||
const T& t = boost::any_cast<T>(data.value);
|
||||
|
||||
std::ostringstream oss;
|
||||
for (size_t i = 0; i < t.size(); ++i)
|
||||
oss << t[i] << " ";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a matrix option (this prints its size).
|
||||
*/
|
||||
template<typename T>
|
||||
std::string GetPrintableParam(
|
||||
util::ParamData& data,
|
||||
const typename boost::enable_if<arma::is_arma_type<T>>::type* = 0)
|
||||
{
|
||||
// Get the matrix.
|
||||
const T& matrix = boost::any_cast<T>(data.value);
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << matrix.n_rows << "x" << matrix.n_cols << " matrix";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a serializable class option (this prints the class name).
|
||||
*/
|
||||
template<typename T>
|
||||
std::string GetPrintableParam(
|
||||
util::ParamData& data,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::enable_if<data::HasSerialize<T>>::type* = 0)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << data.cppType << " model at " << boost::any_cast<T*>(data.value);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a combination DatasetInfo/matrix parameter.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string GetPrintableParam(
|
||||
util::ParamData& data,
|
||||
const typename boost::enable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
// Get the matrix.
|
||||
const T& tuple = boost::any_cast<T>(data.value);
|
||||
const arma::mat& matrix = std::get<1>(tuple);
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << matrix.n_rows << "x" << matrix.n_cols << " matrix with dimension type "
|
||||
<< "information";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an option into a std::string. This should print a short, one-line
|
||||
* representation of the object. The string will be stored in the output
|
||||
* pointer.
|
||||
*
|
||||
* @param data Parameter data struct.
|
||||
* @param * (input) Unused parameter.
|
||||
* @param output Output storage for the string.
|
||||
*/
|
||||
template<typename T>
|
||||
void GetPrintableParam(util::ParamData& data,
|
||||
const void* /* input */,
|
||||
void* output)
|
||||
{
|
||||
*((std::string*) output) =
|
||||
GetPrintableParam<typename std::remove_pointer<T>::type>(data);
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* @file bindings/R/get_printable_type.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Template metaprogramming to return the string representation of the R
|
||||
* type for a given R binding parameter.
|
||||
*
|
||||
* 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_PRINTABLE_TYPE_HPP
|
||||
#define MLPACK_BINDINGS_R_GET_PRINTABLE_TYPE_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/is_std_vector.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetPrintableType(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<T>>::type* = 0,
|
||||
const typename boost::disable_if<data::HasSerialize<T>>::type* = 0,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0);
|
||||
|
||||
template<>
|
||||
inline std::string GetPrintableType<int>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<int>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<int>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<int>>::type*,
|
||||
const typename boost::disable_if<std::is_same<int,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*);
|
||||
|
||||
template<>
|
||||
inline std::string GetPrintableType<double>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<double>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<double>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<double>>::type*,
|
||||
const typename boost::disable_if<std::is_same<double,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*);
|
||||
|
||||
template<>
|
||||
inline std::string GetPrintableType<std::string>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<std::string>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<std::string>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<std::string>>::type*,
|
||||
const typename boost::disable_if<std::is_same<std::string,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*);
|
||||
|
||||
template<>
|
||||
inline std::string GetPrintableType<size_t>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<size_t>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<size_t>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<size_t>>::type*,
|
||||
const typename boost::disable_if<std::is_same<size_t,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*);
|
||||
|
||||
template<>
|
||||
inline std::string GetPrintableType<bool>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<bool>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<bool>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<bool>>::type*,
|
||||
const typename boost::disable_if<std::is_same<bool,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*);
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetPrintableType(
|
||||
util::ParamData& d,
|
||||
const typename boost::enable_if<util::IsStdVector<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0);
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetPrintableType(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::enable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0);
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetPrintableType(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::enable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0);
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetPrintableType(
|
||||
util::ParamData& d,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::enable_if<data::HasSerialize<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0);
|
||||
|
||||
template<typename T>
|
||||
void GetPrintableType(util::ParamData& d,
|
||||
const void* /* input */,
|
||||
void* output)
|
||||
{
|
||||
*((std::string*) output) =
|
||||
GetPrintableType<typename std::remove_pointer<T>::type>(d);
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#include "get_printable_type_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* @file bindings/R/get_printable_type_impl.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Template metaprogramming to return the string representation of the R
|
||||
* type for a given R binding parameter.
|
||||
*
|
||||
* 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_PRINTABLE_TYPE_IMPL_HPP
|
||||
#define MLPACK_BINDINGS_R_GET_PRINTABLE_TYPE_IMPL_HPP
|
||||
|
||||
#include "get_printable_type.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetPrintableType(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<T>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<T>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type*,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetPrintableType<int>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<int>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<int>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<int>>::type*,
|
||||
const typename boost::disable_if<std::is_same<int,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "integer";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetPrintableType<double>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<double>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<double>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<double>>::type*,
|
||||
const typename boost::disable_if<std::is_same<double,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "numeric";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetPrintableType<std::string>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<std::string>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<std::string>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<std::string>>::type*,
|
||||
const typename boost::disable_if<std::is_same<std::string,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "character";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetPrintableType<size_t>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<size_t>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<size_t>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<size_t>>::type*,
|
||||
const typename boost::disable_if<std::is_same<size_t,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "integer";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetPrintableType<bool>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<bool>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<bool>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<bool>>::type*,
|
||||
const typename boost::disable_if<std::is_same<bool,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "logical";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetPrintableType(
|
||||
util::ParamData& d,
|
||||
const typename boost::enable_if<util::IsStdVector<T>>::type*,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "vector of " + GetPrintableType<typename T::value_type>(d) + "s";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetPrintableType(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::enable_if<arma::is_arma_type<T>>::type*,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
std::string type = "numeric matrix";
|
||||
if (std::is_same<typename T::elem_type, double>::value)
|
||||
{
|
||||
if (T::is_row || T::is_col)
|
||||
type = "numeric vector";
|
||||
}
|
||||
else if (std::is_same<typename T::elem_type, size_t>::value)
|
||||
{
|
||||
type = "integer matrix";
|
||||
if (T::is_row || T::is_col)
|
||||
type = "integer vector";
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetPrintableType(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::enable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "categorical matrix/data.frame";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetPrintableType(
|
||||
util::ParamData& d,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type*,
|
||||
const typename boost::enable_if<data::HasSerialize<T>>::type*,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
std::string type = util::StripType(d.cppType);
|
||||
if (type == "mlpackModel")
|
||||
{
|
||||
// If this is true, then we are being called from the Markdown bindings.
|
||||
// This will be printed as the general documentation for model types.
|
||||
return "<Model> (mlpack model)";
|
||||
}
|
||||
else
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* @file bindings/R/get_r_type.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Get the R-named type of an mlpack C++ type.
|
||||
*
|
||||
* 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_R_TYPE_HPP
|
||||
#define MLPACK_BINDINGS_R_GET_R_TYPE_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/is_std_vector.hpp>
|
||||
#include <mlpack/bindings/util/strip_type.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetRType(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<T>>::type* = 0,
|
||||
const typename boost::disable_if<data::HasSerialize<T>>::type* = 0,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetRType<bool>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<bool>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<bool>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<bool>>::type*,
|
||||
const typename boost::disable_if<std::is_same<bool,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "logical";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetRType<int>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<int>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<int>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<int>>::type*,
|
||||
const typename boost::disable_if<std::is_same<int,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "integer";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetRType<size_t>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<size_t>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<size_t>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<size_t>>::type*,
|
||||
const typename boost::disable_if<std::is_same<size_t,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "integer";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetRType<double>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<double>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<double>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<double>>::type*,
|
||||
const typename boost::disable_if<std::is_same<double,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "numeric";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetRType<std::string>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<std::string>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<std::string>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<std::string>>::type*,
|
||||
const typename boost::disable_if<std::is_same<std::string,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "character";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetRType(
|
||||
util::ParamData& d,
|
||||
const typename boost::enable_if<util::IsStdVector<T>>::type* = 0)
|
||||
{
|
||||
return GetRType<typename T::value_type>(d) + " vector";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetRType(
|
||||
util::ParamData& d,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0,
|
||||
const typename boost::enable_if<arma::is_arma_type<T>>::type* = 0)
|
||||
{
|
||||
std::string elemType = GetRType<typename T::elem_type>(d);
|
||||
std::string type = "matrix";
|
||||
if (T::is_row)
|
||||
type = "row";
|
||||
else if (T::is_col)
|
||||
type = "column";
|
||||
|
||||
return elemType + " " + type;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetRType(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::enable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
return "numeric matrix/data.frame with info";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetRType(
|
||||
util::ParamData& d,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::enable_if<data::HasSerialize<T>>::type* = 0)
|
||||
{
|
||||
return util::StripType(d.cppType);
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* @file bindings/R/get_type.hpp
|
||||
* @author Yashwant Singh
|
||||
*
|
||||
* Template metaprogramming to return the string representation of the type
|
||||
* for the R bindings.
|
||||
*
|
||||
* 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_TYPE_HPP
|
||||
#define MLPACK_BINDINGS_R_GET_TYPE_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/param_data.hpp>
|
||||
#include <mlpack/core/util/is_std_vector.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetType(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<T>>::type* = 0,
|
||||
const typename boost::disable_if<data::HasSerialize<T>>::type* = 0,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetType<int>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<int>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<int>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<int>>::type*,
|
||||
const typename boost::disable_if<std::is_same<int,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "Int";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetType<float>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<float>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<float>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<float>>::type*,
|
||||
const typename boost::disable_if<std::is_same<float,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "Float";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetType<double>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<double>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<double>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<double>>::type*,
|
||||
const typename boost::disable_if<std::is_same<double,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "Double";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetType<std::string>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<std::string>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<std::string>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<std::string>>::type*,
|
||||
const typename boost::disable_if<std::is_same<std::string,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "String";
|
||||
}
|
||||
|
||||
template<>
|
||||
inline std::string GetType<bool>(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::disable_if<util::IsStdVector<bool>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<bool>>::type*,
|
||||
const typename boost::disable_if<arma::is_arma_type<bool>>::type*,
|
||||
const typename boost::disable_if<std::is_same<bool,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
return "Bool";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetType(
|
||||
util::ParamData& d,
|
||||
const typename boost::enable_if<util::IsStdVector<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
return "Vec" + GetType<typename T::value_type>(d);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetType(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::enable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
std::string type = "";
|
||||
if (std::is_same<typename T::elem_type, double>::value)
|
||||
{
|
||||
if (T::is_row)
|
||||
type = "Row";
|
||||
else if (T::is_col)
|
||||
type = "Col";
|
||||
else
|
||||
type = "Mat";
|
||||
}
|
||||
else if (std::is_same<typename T::elem_type, size_t>::value)
|
||||
{
|
||||
if (T::is_row)
|
||||
type = "URow";
|
||||
else if (T::is_col)
|
||||
type = "UCol";
|
||||
else
|
||||
type = "UMat";
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetType(
|
||||
util::ParamData& /* d */,
|
||||
const typename boost::enable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
return "MatWithInfo";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::string GetType(
|
||||
util::ParamData& d,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::enable_if<data::HasSerialize<T>>::type* = 0)
|
||||
{
|
||||
return d.cppType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function is used to generate the type names that are used in calls to
|
||||
* functions like IO_SetParam<type>() or setParam<type>(), and therefore
|
||||
* what's returned isn't exactly the R native type used for that parameter
|
||||
* type.
|
||||
*
|
||||
* @param d Parameter data struct.
|
||||
* @param * (input) Unused parameter.
|
||||
* @param output Output storage for the string.
|
||||
*/
|
||||
template<typename T>
|
||||
void GetType(util::ParamData& d,
|
||||
const void* /* input */,
|
||||
void* output)
|
||||
{
|
||||
*((std::string*) output) =
|
||||
GetType<typename std::remove_pointer<T>::type>(d);
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
Package: mlpack
|
||||
Title: 'Rcpp' Integration for the 'mlpack' Library
|
||||
Version: @PACKAGE_VERSION@
|
||||
Date: @PACKAGE_DATE@
|
||||
Author: mlpack Team
|
||||
Maintainer: Ryan Curtin <ryan@ratml.org>
|
||||
Description: 'mlpack' is a fast, flexible machine learning library, written
|
||||
in C++, that aims to provide fast, extensible implementations of
|
||||
cutting-edge machine learning algorithms.
|
||||
SystemRequirements: A C++11 compiler. Versions 4.8.*, 4.9.* or later of GCC
|
||||
will be fine.
|
||||
License: BSD_3_clause + file LICENSE
|
||||
Depends: R (>= 4.0.0)
|
||||
Imports: Rcpp (>= 0.12.12)
|
||||
LinkingTo: Rcpp,
|
||||
RcppArmadillo (>= @RcppArmadillo_Version@),
|
||||
BH (>= @BH_Version@),
|
||||
RcppEnsmallen (>= @RcppEnsmallen_Version@)
|
||||
Suggests: testthat (>= 2.1.0)
|
||||
URL: https://www.mlpack.org/doc/mlpack-@PACKAGE_VERSION@/r_documentation.html,
|
||||
https://github.com/mlpack/mlpack
|
||||
BugReports: https://github.com/mlpack/mlpack/issues
|
||||
LazyData: true
|
||||
RoxygenNote: 7.1.0
|
||||
Encoding: UTF-8
|
||||
@@ -0,0 +1,50 @@
|
||||
# matrix_utils.R: utilities for matrix conversion
|
||||
#
|
||||
# This file defines the to_matrix() function, which can be used to convert
|
||||
# data.frame or other types of matrix-like objects to matrix for use in
|
||||
# mlpack bindings(IO_SetParamMat/UMat).
|
||||
#
|
||||
# This file also defines the to_matirx_with_info() function, which can be used
|
||||
# to construct dataset information vector from the given dataset for use in
|
||||
# mlpack bindings(IO_SetParamMatWithInfo).
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
|
||||
# Given some matrix-like x (which should be either a matrix or
|
||||
# data.frame), convert it into a matrix.
|
||||
to_matrix <- function(x) {
|
||||
if (!is.matrix(x) && !is.data.frame(x)) {
|
||||
stop("Input must be either a `matrix` or `data.frame` not `",
|
||||
class(x)[1], "`.", call. = FALSE)
|
||||
}
|
||||
if (is.matrix(x)) {
|
||||
return(x)
|
||||
} else if (is.data.frame(x)) {
|
||||
y <- data.matrix(x) # requires R 4.0.0 for factor conversion.
|
||||
return(y)
|
||||
}
|
||||
}
|
||||
|
||||
# Determine column classes
|
||||
mark_categorical_variable = function(x) {
|
||||
d <- sapply(x, class) %in% c("factor", "character", "logical")
|
||||
d
|
||||
}
|
||||
|
||||
# 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(list("info" = info, "data" = transformed_x))
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#' mlpack
|
||||
#'
|
||||
#' mlpack is a fast, flexible machine learning library, written in C++, that
|
||||
#' aims to provide fast, extensible implementations of cutting-edge machine
|
||||
#' learning algorithms. mlpack provides these algorithms as simple command-line
|
||||
#' programs, C++ classes and bindings for : Python, Julia, Go and R which can
|
||||
#' then be integrated into larger-scale machine learning solutions.
|
||||
#'
|
||||
#' @docType package
|
||||
#' @name mlpack
|
||||
#' @author mlpack Team
|
||||
#' @importFrom Rcpp evalCpp
|
||||
#' @useDynLib mlpack
|
||||
NULL
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
## compilation and editing objects
|
||||
rm -f src/*.o src/*.so src/*.dylib src/*~ *~
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @file inst/include/mlpack.h
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Include all of the base components required to work mlpack bindings.
|
||||
*
|
||||
* 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_RCPP_MLPACK_H
|
||||
#define MLPACK_BINDINGS_R_RCPP_MLPACK_H
|
||||
|
||||
#include <Rcpp.h>
|
||||
|
||||
// To suppress Found ‘__assert_fail’, possibly from ‘assert’ (C).
|
||||
#define BOOST_DISABLE_ASSERTS
|
||||
|
||||
// Rcpp has its own stream object which cooperates more nicely with R's i/o
|
||||
// And as of armadillo and mlpack, we can use this stream object as well.
|
||||
#if !defined(ARMA_COUT_STREAM)
|
||||
#define ARMA_COUT_STREAM Rcpp::Rcout
|
||||
#endif
|
||||
#if !defined(ARMA_CERR_STREAM)
|
||||
#define ARMA_CERR_STREAM Rcpp::Rcerr
|
||||
#endif
|
||||
#if !defined(MLPACK_COUT_STREAM)
|
||||
#define MLPACK_COUT_STREAM Rcpp::Rcout
|
||||
#endif
|
||||
#if !defined(MLPACK_CERR_STREAM)
|
||||
#define MLPACK_CERR_STREAM Rcpp::Rcerr
|
||||
#endif
|
||||
|
||||
// This define makes the R RNG have precedent over the C++11-based
|
||||
// RNG provided by Armadillo.
|
||||
#if !defined(ARMA_RNG_ALT)
|
||||
#define ARMA_RNG_ALT RcppArmadillo/Alt_R_RNG.h
|
||||
#endif
|
||||
|
||||
// To suppress warnings related to core/util/arma_util.hpp.
|
||||
#define MLPACK_CORE_UTIL_ARMA_CONFIG_HPP
|
||||
|
||||
// Undefine macro due to macro collision.
|
||||
#undef Realloc
|
||||
#undef Free
|
||||
|
||||
@R_SRC@
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
#undef ARMA_EXTRA_MAT_PROTO
|
||||
#undef ARMA_EXTRA_MAT_MEAT
|
||||
|
||||
// Define R Internal macro again after including cereal headers.
|
||||
#define Realloc(p,n,t) (t *) R_chk_realloc( (void *)(p), (R_SIZE_T)((n) * sizeof(t)) )
|
||||
#define Free(p) (R_chk_free( (void *)(p) ), (p) = NULL)
|
||||
|
||||
// instead of including RcppArmadillo.h -- which re-includes parts
|
||||
// of Armadillo already brought in by mlpack, we just include pieces
|
||||
// needed for sugar wrapping etc
|
||||
|
||||
#include <RcppArmadilloConfig.h>
|
||||
#include <RcppArmadilloWrap.h>
|
||||
#include <RcppArmadilloAs.h>
|
||||
#include <RcppArmadilloSugar.h>
|
||||
|
||||
// prevent inclusion of Rcpp.h and RcppArmadillo.h via the
|
||||
// autogenerated RcppExports.cpp
|
||||
#define Rcpp_hpp
|
||||
#define RcppArmadillo__RcppArmadillo__h
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
PKG_CXXFLAGS = -DBOOST_MATH_PROMOTE_DOUBLE_POLICY=false -I. $(SHLIB_OPENMP_CXXFLAGS)
|
||||
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
|
||||
CXX_STD = CXX11
|
||||
@@ -0,0 +1,3 @@
|
||||
PKG_CXXFLAGS = -DBOOST_MATH_PROMOTE_DOUBLE_POLICY=false -I. $(SHLIB_OPENMP_CXXFLAGS)
|
||||
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
|
||||
CXX_STD = CXX11
|
||||
@@ -0,0 +1,300 @@
|
||||
/**
|
||||
* @file src/r_util.cpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Utility functions for R-bindings.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <rcpp_mlpack.h>
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/io.hpp>
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace Rcpp;
|
||||
|
||||
template<typename eT>
|
||||
bool inline inplace_transpose(arma::Mat<eT>& X)
|
||||
{
|
||||
try
|
||||
{
|
||||
X = arma::trans(X);
|
||||
return false;
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Call IO::RestoreSettings() for a given program name.
|
||||
// [[Rcpp::export]]
|
||||
void IO_RestoreSettings(const std::string& programName)
|
||||
{
|
||||
IO::RestoreSettings(programName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<int>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamInt(const std::string& paramName, int paramValue)
|
||||
{
|
||||
IO::GetParam<int>(paramName) = paramValue;
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<double>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamDouble(const std::string& paramName, double paramValue)
|
||||
{
|
||||
IO::GetParam<double>(paramName) = paramValue;
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<std::string>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamString(const std::string& paramName, std::string& paramValue)
|
||||
{
|
||||
IO::GetParam<std::string>(paramName) = paramValue;
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<bool>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamBool(const std::string& paramName, bool paramValue)
|
||||
{
|
||||
IO::GetParam<bool>(paramName) = paramValue;
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<std::vector<std::string>>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamVecString(const std::string& paramName,
|
||||
const std::vector<std::string>& str)
|
||||
{
|
||||
IO::GetParam<std::vector<std::string>>(paramName) = std::move(str);
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<std::vector<int>>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamVecInt(const std::string& paramName,
|
||||
const std::vector<int>& ints)
|
||||
{
|
||||
IO::GetParam<std::vector<int>>(paramName) = std::move(ints);
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<arma::mat>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamMat(const std::string& paramName,
|
||||
const arma::mat& paramValue)
|
||||
{
|
||||
IO::GetParam<arma::mat>(paramName) = paramValue.t();
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<arma::Mat<size_t>>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamUMat(const std::string& paramName,
|
||||
const arma::Mat<size_t>& paramValue)
|
||||
{
|
||||
IO::GetParam<arma::Mat<size_t>>(paramName) = paramValue.t();
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<arma::rowvec>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamRow(const std::string& paramName,
|
||||
const arma::rowvec& paramValue)
|
||||
{
|
||||
IO::GetParam<arma::rowvec>(paramName) = std::move(paramValue);
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<arma::Row<size_t>>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamURow(const std::string& paramName,
|
||||
const arma::Row<size_t>& paramValue)
|
||||
{
|
||||
IO::GetParam<arma::Row<size_t>>(paramName) = paramValue - 1;
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<arma::vec>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamCol(const std::string& paramName,
|
||||
const arma::vec& paramValue)
|
||||
{
|
||||
IO::GetParam<arma::vec>(paramName) = std::move(paramValue);
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<arma::Col<size_t>>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamUCol(const std::string& paramName,
|
||||
const arma::Col<size_t>& paramValue)
|
||||
{
|
||||
IO::GetParam<arma::Col<size_t>>(paramName) = paramValue - 1;
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::SetParam<std::tuple<data::DatasetInfo, arma::mat>>().
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetParamMatWithInfo(const std::string& paramName,
|
||||
const LogicalVector& dimensions,
|
||||
const arma::mat& paramValue)
|
||||
{
|
||||
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::tuple<data::DatasetInfo, arma::mat>>(
|
||||
paramName)) = std::move(d);
|
||||
std::get<1>(IO::GetParam<std::tuple<data::DatasetInfo, arma::mat>>(
|
||||
paramName)) = paramValue.t();
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Call IO::GetParam<int>().
|
||||
// [[Rcpp::export]]
|
||||
int IO_GetParamInt(const std::string& paramName)
|
||||
{
|
||||
return IO::GetParam<int>(paramName);
|
||||
}
|
||||
|
||||
// Call IO::GetParam<double>().
|
||||
// [[Rcpp::export]]
|
||||
double IO_GetParamDouble(const std::string& paramName)
|
||||
{
|
||||
return IO::GetParam<double>(paramName);
|
||||
}
|
||||
|
||||
// Call IO::GetParam<std::string>().
|
||||
// [[Rcpp::export]]
|
||||
std::string& IO_GetParamString(const std::string& paramName)
|
||||
{
|
||||
return IO::GetParam<std::string>(paramName);
|
||||
}
|
||||
|
||||
// Call IO::GetParam<bool>().
|
||||
// [[Rcpp::export]]
|
||||
bool IO_GetParamBool(const std::string& paramName)
|
||||
{
|
||||
return IO::GetParam<bool>(paramName);
|
||||
}
|
||||
|
||||
// Call IO::GetParam<std::vector<std::string>>().
|
||||
// [[Rcpp::export]]
|
||||
const std::vector<std::string>& IO_GetParamVecString(const
|
||||
std::string& paramName)
|
||||
{
|
||||
return std::move(IO::GetParam<std::vector<std::string>>(paramName));
|
||||
}
|
||||
|
||||
// Call IO::GetParam<std::vector<int>>().
|
||||
// [[Rcpp::export]]
|
||||
const std::vector<int>& IO_GetParamVecInt(const std::string& paramName)
|
||||
{
|
||||
return std::move(IO::GetParam<std::vector<int>>(paramName));
|
||||
}
|
||||
|
||||
// Call IO::GetParam<arma::mat>().
|
||||
// [[Rcpp::export]]
|
||||
const arma::mat& IO_GetParamMat(const std::string& paramName)
|
||||
{
|
||||
inplace_transpose(IO::GetParam<arma::mat>(paramName));
|
||||
return std::move(IO::GetParam<arma::mat>(paramName));
|
||||
}
|
||||
|
||||
// Call IO::GetParam<arma::Mat<size_t>>().
|
||||
// [[Rcpp::export]]
|
||||
const arma::Mat<size_t>& IO_GetParamUMat(const std::string& paramName)
|
||||
{
|
||||
inplace_transpose(IO::GetParam<arma::Mat<size_t>>(paramName));
|
||||
return std::move(IO::GetParam<arma::Mat<size_t>>(paramName));
|
||||
}
|
||||
|
||||
// Call IO::GetParam<arma::rowvec>().
|
||||
// [[Rcpp::export]]
|
||||
const arma::vec IO_GetParamRow(const std::string& paramName)
|
||||
{
|
||||
return IO::GetParam<arma::rowvec>(paramName).t();
|
||||
}
|
||||
|
||||
// Call IO::GetParam<arma::Row<size_t>>().
|
||||
// [[Rcpp::export]]
|
||||
const arma::Col<size_t> IO_GetParamURow(const std::string& paramName)
|
||||
{
|
||||
return IO::GetParam<arma::Row<size_t>>(paramName).t() + 1;
|
||||
}
|
||||
|
||||
// Call IO::GetParam<arma::vec>().
|
||||
// [[Rcpp::export]]
|
||||
const arma::rowvec IO_GetParamCol(const std::string& paramName)
|
||||
{
|
||||
return IO::GetParam<arma::vec>(paramName).t();
|
||||
}
|
||||
|
||||
// Call IO::GetParam<arma::Col<size_t>>().
|
||||
// [[Rcpp::export]]
|
||||
const arma::Row<size_t> IO_GetParamUCol(const std::string& paramName)
|
||||
{
|
||||
return IO::GetParam<arma::Col<size_t>>(paramName).t() + 1;
|
||||
}
|
||||
|
||||
// Call IO::GetParam<std::tuple<data::DatasetInfo, arma::mat>>().
|
||||
// [[Rcpp::export]]
|
||||
List IO_GetParamMatWithInfo(const std::string& paramName)
|
||||
{
|
||||
const data::DatasetInfo& d = std::get<0>(
|
||||
IO::GetParam<std::tuple<data::DatasetInfo, arma::mat>>(paramName));
|
||||
const arma::mat& m = std::get<1>(
|
||||
IO::GetParam<std::tuple<data::DatasetInfo, arma::mat>>(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));
|
||||
}
|
||||
|
||||
// Enable verbose output.
|
||||
// [[Rcpp::export]]
|
||||
void IO_EnableVerbose()
|
||||
{
|
||||
Log::Info.ignoreInput = false;
|
||||
}
|
||||
|
||||
// Disable verbose output.
|
||||
// [[Rcpp::export]]
|
||||
void IO_DisableVerbose()
|
||||
{
|
||||
Log::Info.ignoreInput = true;
|
||||
}
|
||||
|
||||
// Reset the state of all timers.
|
||||
// [[Rcpp::export]]
|
||||
void IO_ResetTimers()
|
||||
{
|
||||
IO::GetSingleton().timer.Reset();
|
||||
}
|
||||
|
||||
// Set an argument as passed to the IO object.
|
||||
// [[Rcpp::export]]
|
||||
void IO_SetPassed(const std::string& paramName)
|
||||
{
|
||||
IO::SetPassed(paramName);
|
||||
}
|
||||
|
||||
// Clear settings.
|
||||
// [[Rcpp::export]]
|
||||
void IO_ClearSettings()
|
||||
{
|
||||
IO::ClearSettings();
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @file src/rcpp_mlpack.h
|
||||
* @author Dirk Eddelbuettel
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Include all of the base components required to work mlpack bindings.
|
||||
*
|
||||
* 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_RCPP_MLPACK_H
|
||||
#define MLPACK_BINDINGS_R_RCPP_MLPACK_H
|
||||
|
||||
#include <Rcpp.h>
|
||||
|
||||
// To suppress Found ‘__assert_fail’, possibly from ‘assert’ (C).
|
||||
#define BOOST_DISABLE_ASSERTS
|
||||
|
||||
// Rcpp has its own stream object which cooperates more nicely with R's i/o
|
||||
// And as of armadillo and mlpack, we can use this stream object as well.
|
||||
#if !defined(ARMA_COUT_STREAM)
|
||||
#define ARMA_COUT_STREAM Rcpp::Rcout
|
||||
#endif
|
||||
#if !defined(ARMA_CERR_STREAM)
|
||||
#define ARMA_CERR_STREAM Rcpp::Rcerr
|
||||
#endif
|
||||
#if !defined(MLPACK_COUT_STREAM)
|
||||
#define MLPACK_COUT_STREAM Rcpp::Rcout
|
||||
#endif
|
||||
#if !defined(MLPACK_CERR_STREAM)
|
||||
#define MLPACK_CERR_STREAM Rcpp::Rcerr
|
||||
#endif
|
||||
|
||||
// This define makes the R RNG have precedent over the C++11-based
|
||||
// RNG provided by Armadillo.
|
||||
#if !defined(ARMA_RNG_ALT)
|
||||
#define ARMA_RNG_ALT RcppArmadillo/Alt_R_RNG.h
|
||||
#endif
|
||||
|
||||
// To suppress warnings related to core/util/arma_util.hpp.
|
||||
#define MLPACK_CORE_UTIL_ARMA_CONFIG_HPP
|
||||
|
||||
// Undefine macro due to macro collision.
|
||||
#undef Realloc
|
||||
#undef Free
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
library(testthat)
|
||||
library(mlpack)
|
||||
|
||||
test_check("mlpack")
|
||||
@@ -0,0 +1,297 @@
|
||||
# Test that when we run the binding correctly (with correct input parameters),
|
||||
# we get the expected output.
|
||||
test_that("TestRunBindingCorrectly", {
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
flag1=TRUE)
|
||||
|
||||
expect_true(output$double_out == 5.0)
|
||||
expect_true(output$int_out == 13)
|
||||
expect_true(output$string_out == "hello2")
|
||||
})
|
||||
|
||||
# If we forget the mandatory flag, we should get wrong results.
|
||||
test_that("TestRunBindingNoFlag", {
|
||||
output <- test_r_binding(4.0, 12, "hello")
|
||||
|
||||
expect_true(output$double_out != 5.0)
|
||||
expect_true(output$int_out != 13)
|
||||
expect_true(output$string_out != "hello2")
|
||||
})
|
||||
|
||||
# If we give the wrong string, we should get wrong results.
|
||||
test_that("TestRunBindingWrongString", {
|
||||
output <- test_r_binding(4.0, 12, "goodbye",
|
||||
flag1=TRUE)
|
||||
|
||||
expect_true(output$string_out != "hello2")
|
||||
})
|
||||
|
||||
# If we give the wrong int, we should get wrong results.
|
||||
test_that("TestRunBindingWrongInt", {
|
||||
output <- test_r_binding(4.0, 15, "hello",
|
||||
flag1=TRUE)
|
||||
|
||||
expect_true(output$int_out != 13)
|
||||
})
|
||||
|
||||
# If we give the wrong double, we should get wrong results.
|
||||
test_that("TestRunBindingWrongDouble", {
|
||||
output <- test_r_binding(2.0, 12, "hello",
|
||||
flag1=TRUE)
|
||||
|
||||
expect_true(output$double_out != 5.0)
|
||||
})
|
||||
|
||||
# If we give the second flag, this should fail.
|
||||
test_that("TestRunBadFlag", {
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
flag1=TRUE,
|
||||
flag2=TRUE)
|
||||
|
||||
expect_true(output$double_out != 5.0)
|
||||
expect_true(output$int_out != 13)
|
||||
expect_true(output$string_out != "hello2")
|
||||
})
|
||||
|
||||
# The matrix we pass in, we should get back with the third dimension doubled and
|
||||
# the fifth forgotten.
|
||||
test_that("TestMatrix", {
|
||||
x <- matrix(rexp(500, rate = .1), ncol = 5)
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
matrix_in=x)
|
||||
|
||||
expect_identical(dim(output$matrix_out), as.integer(c(100, 4)))
|
||||
for (i in c(1, 2, 4)) {
|
||||
for (j in 1:100) {
|
||||
expect_true(output$matrix_out[j, i] == x[j, i])
|
||||
}
|
||||
}
|
||||
|
||||
for (j in 1:100) {
|
||||
expect_true(output$matrix_out[j, 3] == 2 * x[j, 3])
|
||||
}
|
||||
})
|
||||
|
||||
# The data.frame we pass in, we should get back with the third dimension doubled
|
||||
# and the fifth forgotten.
|
||||
test_that("TestDataFrame", {
|
||||
y <- matrix(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), nrow = 3)
|
||||
x <- data.frame(y)
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
matrix_in=x)
|
||||
|
||||
expect_identical(dim(output$matrix_out), as.integer(c(3, 4)))
|
||||
for (i in c(1, 2, 4)) {
|
||||
for (j in 1:3) {
|
||||
expect_true(output$matrix_out[j, i] == x[j, i])
|
||||
}
|
||||
}
|
||||
|
||||
for (j in 1:3) {
|
||||
expect_true(output$matrix_out[j, 3] == 2 * x[j, 3])
|
||||
}
|
||||
})
|
||||
|
||||
# Same as TestMatrix but with an unsigned matrix.
|
||||
test_that("TestUMatrix", {
|
||||
x <- matrix(as.integer(rexp(500, rate = .1)), ncol = 5)
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
umatrix_in=x)
|
||||
|
||||
expect_identical(dim(output$umatrix_out), as.integer(c(100, 4)))
|
||||
for (i in c(1, 2, 4)) {
|
||||
for (j in 1:100) {
|
||||
expect_true(output$umatrix_out[j, i] == x[j, i])
|
||||
}
|
||||
}
|
||||
|
||||
for (j in 1:100) {
|
||||
expect_true(output$umatrix_out[j, 3] == 2 * x[j, 3])
|
||||
}
|
||||
})
|
||||
|
||||
# Test a column vector input parameter.
|
||||
test_that("TestCol", {
|
||||
x <- matrix(rexp(100, rate = .1), nrow = 1)
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
col_in=x)
|
||||
|
||||
expect_identical(dim(output$col_out), as.integer(c(1, 100)))
|
||||
expect_identical(output$col_out, 2 * x)
|
||||
})
|
||||
|
||||
# Test an unsigned column vector input parameter.
|
||||
test_that("TestUCol", {
|
||||
x <- matrix(as.integer(rexp(100, rate = .1)), nrow = 1)
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
ucol_in=x)
|
||||
|
||||
expect_identical(dim(output$ucol_out), as.integer(c(1, 100)))
|
||||
expect_identical(output$ucol_out, 1 + x)
|
||||
})
|
||||
|
||||
# Test a row vector input parameter.
|
||||
test_that("TestRow", {
|
||||
x <- matrix(rexp(100, rate = .1), ncol = 1)
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
row_in=x)
|
||||
|
||||
expect_identical(dim(output$row_out), as.integer(c(100, 1)))
|
||||
expect_identical(output$row_out, 2 * x)
|
||||
})
|
||||
|
||||
# Test an unsigned row vector input parameter.
|
||||
test_that("TestURow", {
|
||||
x <- matrix(as.integer(rexp(100, rate = .1)), ncol = 1)
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
urow_in=x)
|
||||
|
||||
expect_identical(dim(output$urow_out), as.integer(c(100, 1)))
|
||||
expect_identical(output$urow_out, 1 + x)
|
||||
})
|
||||
|
||||
# Test that we can pass a matrix with all numeric features.
|
||||
test_that("TestMatrixAndInfo", {
|
||||
x <- matrix(rexp(500, rate = .1), ncol = 5)
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
matrix_and_info_in=x)
|
||||
|
||||
expect_identical(dim(output$matrix_and_info_out), as.integer(c(100, 5)))
|
||||
expect_identical(output$matrix_and_info_out, 2 * x)
|
||||
})
|
||||
|
||||
# Test that we can pass a data.frame with all numeric features.
|
||||
test_that("TestDataFrameWithNoInfo", {
|
||||
y <- matrix(rexp(500, rate = .1), ncol = 5)
|
||||
x <- data.frame(y)
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
matrix_and_info_in=x)
|
||||
|
||||
expect_identical(dim(output$matrix_and_info_out), as.integer(c(100, 5)))
|
||||
|
||||
for (i in 1:100) {
|
||||
for (j in 1:5) {
|
||||
expect_true(output$matrix_and_info_out[i, j] == 2 * x[i, j])
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
# Test that we can pass a data.frame with numeric and categorical features.
|
||||
test_that("TestDataFrameWithInfo", {
|
||||
y <- matrix(rexp(90, rate = .1), ncol = 9)
|
||||
x <- data.frame(y, "e" = letters[1:10])
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
matrix_and_info_in=x)
|
||||
|
||||
expect_identical(dim(output$matrix_and_info_out), as.integer(c(10, 10)))
|
||||
|
||||
for (i in 1:9) {
|
||||
for (j in 1:10) {
|
||||
expect_true(output$matrix_and_info_out[j, i] == 2 * x[j, i])
|
||||
}
|
||||
}
|
||||
|
||||
for (j in 1:10) {
|
||||
expect_true(output$matrix_and_info_out[j, 10] == j)
|
||||
}
|
||||
})
|
||||
|
||||
# Test that we can pass a data.frame with numeric and categorical features.
|
||||
test_that("TestDataFrameWithLogicalInfo", {
|
||||
y <- matrix(rexp(90, rate = .1), ncol = 9)
|
||||
x <- data.frame(y)
|
||||
x["e"] <- c(T, F, F, T, T, F, F, F, F, T)
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
matrix_and_info_in=x)
|
||||
|
||||
expect_identical(dim(output$matrix_and_info_out), as.integer(c(10, 10)))
|
||||
|
||||
for (i in 1:9) {
|
||||
for (j in 1:10) {
|
||||
expect_true(output$matrix_and_info_out[j, i] == 2 * x[j, i])
|
||||
}
|
||||
}
|
||||
expect_identical(output$matrix_and_info_out[, 10], as.numeric(x[, "e"]))
|
||||
})
|
||||
|
||||
# Test that we can pass a vector of ints and get back that same vector but with
|
||||
# the last element removed.
|
||||
test_that("TestIntVector", {
|
||||
x <- c(1, 2, 3, 4, 5)
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
vector_in=x)
|
||||
|
||||
expect_identical(output$vector_out, c(1:4))
|
||||
})
|
||||
|
||||
# Test that we can pass a vector of strings and get back that same vector but
|
||||
# with the last element removed.
|
||||
test_that("TestStringVector", {
|
||||
x <- letters[1:5]
|
||||
|
||||
output <- test_r_binding(4.0, 12, "hello",
|
||||
str_vector_in=x)
|
||||
|
||||
expect_identical(output$str_vector_out, letters[1:4])
|
||||
})
|
||||
|
||||
# If we give data other than matrix/data.frame in matrix_in/matrix_and_info_in,
|
||||
# we should get an error.
|
||||
test_that("TestNotMatrix", {
|
||||
expect_error(test_r_binding(4.0, 12, "hello",
|
||||
matrix_in="wrong"))
|
||||
|
||||
expect_error(test_r_binding(4.0, 12, "hello",
|
||||
matrix_in=12))
|
||||
|
||||
expect_error(test_r_binding(4.0, 12, "hello",
|
||||
matrix_in=1e6))
|
||||
|
||||
expect_error(test_r_binding(4.0, 12, "hello",
|
||||
matrix_and_info_in="wrong"))
|
||||
|
||||
expect_error(test_r_binding(4.0, 12, "hello",
|
||||
matrix_and_info_in=12))
|
||||
|
||||
expect_error(test_r_binding(4.0, 12, "hello",
|
||||
matrix_and_info_in=1e6))
|
||||
})
|
||||
|
||||
# First create a GaussianKernel object, then send it back and make sure we get
|
||||
# the right double value.
|
||||
test_that("TestModel", {
|
||||
output1 <- test_r_binding(4.0, 12, "hello",
|
||||
build_model=TRUE)
|
||||
|
||||
output2 <- test_r_binding(4.0, 12, "hello",
|
||||
model_in=output1$model_out)
|
||||
|
||||
expect_true(output2$model_bw_out == 20)
|
||||
})
|
||||
|
||||
# Test that we can serialize a model to disk and then use it again.
|
||||
test_that("TestSerialization", {
|
||||
output1 <- test_r_binding(4.0, 12, "hello",
|
||||
build_model=TRUE)
|
||||
|
||||
Serialize(output1$model_out, "model.bin")
|
||||
|
||||
new_model <- Unserialize("model.bin")
|
||||
unlink("model.bin")
|
||||
|
||||
output2 <- test_r_binding(4.0, 12, "hello", model_in=new_model)
|
||||
|
||||
expect_true(output2$model_bw_out == 20)
|
||||
})
|
||||
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* @file bindings/R/print_R.cpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Implementation of utility PrintR() function.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include "print_R.hpp"
|
||||
#include <mlpack/bindings/util/strip_type.hpp>
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/hyphenate_string.hpp>
|
||||
|
||||
using namespace mlpack;
|
||||
using namespace std;
|
||||
|
||||
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 functionName Name of the function (i.e. "pca").
|
||||
*/
|
||||
void PrintR(const util::BindingDetails& doc,
|
||||
const string& functionName)
|
||||
{
|
||||
// Restore parameters.
|
||||
IO::RestoreSettings(doc.programName);
|
||||
|
||||
map<string, util::ParamData>& parameters = IO::Parameters();
|
||||
typedef map<string, util::ParamData>::iterator ParamIter;
|
||||
|
||||
// First, let's get a list of input and output options. We'll take two passes
|
||||
// so that the required input options are the first in the list.
|
||||
vector<string> inputOptions, outputOptions;
|
||||
for (ParamIter it = parameters.begin(); it != parameters.end(); ++it)
|
||||
{
|
||||
util::ParamData& d = it->second;
|
||||
if (d.input && d.required)
|
||||
{
|
||||
// Ignore some parameters.
|
||||
if (d.name != "help" && d.name != "info" &&
|
||||
d.name != "version")
|
||||
inputOptions.push_back(it->first);
|
||||
}
|
||||
else if (!d.input)
|
||||
{
|
||||
outputOptions.push_back(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
for (ParamIter it = parameters.begin(); it != parameters.end(); ++it)
|
||||
{
|
||||
util::ParamData& d = it->second;
|
||||
if (d.input && !d.required &&
|
||||
d.name != "help" && d.name != "info" &&
|
||||
d.name != "version")
|
||||
inputOptions.push_back(it->first);
|
||||
}
|
||||
|
||||
// Print the documentation.
|
||||
// Print programName as @title.
|
||||
cout << "#' @title ";
|
||||
cout << util::HyphenateString(doc.programName, "#' ") << endl;
|
||||
cout << "#'" << endl;
|
||||
|
||||
// Next print the short description as @description.
|
||||
cout << "#' @description" << endl;
|
||||
cout << "#' ";
|
||||
cout << util::HyphenateString(doc.shortDescription, "#' ") << endl;
|
||||
|
||||
// Next, print information on the input options.
|
||||
cout << "#'" << endl;
|
||||
|
||||
for (size_t i = 0; i < inputOptions.size(); ++i)
|
||||
{
|
||||
const string& opt = inputOptions[i];
|
||||
util::ParamData& d = parameters.at(opt);
|
||||
|
||||
bool out = false;
|
||||
IO::GetSingleton().functionMap[d.tname]["PrintDoc"](d, NULL, (void*) &out);
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
cout << "#'" << endl;
|
||||
|
||||
// Next, print information on the output options.
|
||||
if (outputOptions.size() > 0)
|
||||
cout << "#' @return A list with several components:" << endl;
|
||||
|
||||
for (size_t i = 0; i < outputOptions.size(); ++i)
|
||||
{
|
||||
const string& opt = outputOptions[i];
|
||||
util::ParamData& d = parameters.at(opt);
|
||||
|
||||
bool out = true;
|
||||
IO::GetSingleton().functionMap[d.tname]["PrintDoc"](d, NULL, (void*) &out);
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
cout << "#'" << endl;
|
||||
|
||||
// Next print the long description as @details.
|
||||
cout << "#' @details" << endl;
|
||||
cout << "#' ";
|
||||
cout << util::HyphenateString(doc.longDescription(), "#' ") << endl;
|
||||
cout << "#'" << endl;
|
||||
cout << "#' @author" << endl;
|
||||
cout << "#' mlpack developers" << endl;
|
||||
cout << "#'" << endl;
|
||||
|
||||
// Next print the example as @examples.
|
||||
cout << "#' @export" << endl;
|
||||
if (doc.example.size() != 0)
|
||||
cout << "#' @examples" << endl;
|
||||
for (size_t j = 0; j < doc.example.size(); ++j)
|
||||
{
|
||||
const std::string str = doc.example[j]();
|
||||
size_t pos = 0;
|
||||
while (pos < str.length())
|
||||
{
|
||||
size_t splitpos = 0;
|
||||
// Find where example starts.
|
||||
splitpos = str.find("\n\\dontrun{", pos) - 1;
|
||||
// If no example left, then print all the comments that are left.
|
||||
if (splitpos == std::string::npos || splitpos > str.length())
|
||||
{
|
||||
splitpos = str.length();
|
||||
cout << util::HyphenateString(str.substr(pos, (splitpos - pos)),
|
||||
"#' # ");
|
||||
break;
|
||||
}
|
||||
if (splitpos != 0 && pos == 0)
|
||||
cout << "#' # ";
|
||||
// Print comments in the "example", if there is available.
|
||||
cout << util::HyphenateString(str.substr(pos, (splitpos - pos)),
|
||||
"#' # ", true);
|
||||
// Find where example ends.
|
||||
pos = str.find("\n}", pos) + 3;
|
||||
// Here length of example might be less 80, we must handle this carefully.
|
||||
// Print example in the "example".
|
||||
cout << util::HyphenateString(str.substr(splitpos, (pos - splitpos)),
|
||||
"#' ", true);
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
// Print the definition.
|
||||
cout << functionName << " <- function(";
|
||||
size_t indent = functionName.size() + 13 /* <- function(*/;
|
||||
for (size_t i = 0; i < inputOptions.size(); ++i)
|
||||
{
|
||||
util::ParamData& d = parameters.at(inputOptions[i]);
|
||||
|
||||
if (i != 0)
|
||||
cout << "," << endl << std::string(indent, ' ');
|
||||
|
||||
IO::GetSingleton().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;
|
||||
cout << endl;
|
||||
|
||||
// Handle each input argument's processing before calling mlpackMain().
|
||||
cout << " # Process each input argument before calling mlpackMain()."
|
||||
<< endl;
|
||||
for (const string& opt : inputOptions)
|
||||
{
|
||||
if (opt != "verbose")
|
||||
{
|
||||
util::ParamData& d = parameters.at(opt);
|
||||
IO::GetSingleton().functionMap[d.tname]["PrintInputProcessing"](d,
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Special handling for verbose output.
|
||||
cout << " if (verbose) {" << endl;
|
||||
cout << " IO_EnableVerbose()" << endl;
|
||||
cout << " } else {" << endl;
|
||||
cout << " IO_DisableVerbose()" << endl;
|
||||
cout << " }" << endl;
|
||||
cout << endl;
|
||||
|
||||
// Mark output parameters as passed.
|
||||
cout << " # Mark all output options as passed." << endl;
|
||||
for (const string& opt : outputOptions)
|
||||
{
|
||||
util::ParamData& d = parameters.at(opt);
|
||||
cout << " IO_SetPassed(\"" << d.name << "\")" << endl;
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
// Call the program.
|
||||
cout << " # Call the program." << endl;
|
||||
cout << " " << functionName << "_mlpackMain()" << endl << endl;
|
||||
|
||||
// Add ModelType as attr to the model pointer.
|
||||
cout << " # Add ModelType as attribute to the model pointer, if needed."
|
||||
<< endl;
|
||||
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);
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
// Extract the results in order.
|
||||
cout << " # Extract the results in order." << endl;
|
||||
cout << " out <- list(" << endl;
|
||||
string indentStr(4, ' ');
|
||||
for (size_t i = 0; i < outputOptions.size(); ++i)
|
||||
{
|
||||
if (i == 0)
|
||||
cout << indentStr;
|
||||
util::ParamData& d = parameters.at(outputOptions[i]);
|
||||
IO::GetSingleton().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;
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @file bindings/R/print_R.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Definition of utility PrintR() function.
|
||||
*
|
||||
* 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_PRINT_R_HPP
|
||||
#define MLPACK_BINDINGS_R_PRINT_R_HPP
|
||||
|
||||
#include <mlpack/core.hpp>
|
||||
|
||||
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 functionName Name of the function (i.e. "pca").
|
||||
*/
|
||||
void PrintR(const util::BindingDetails& doc,
|
||||
const std::string& functionName);
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @file bindings/R/print_doc.hpp
|
||||
* @author Yashwant Singh Parihar.
|
||||
*
|
||||
* Print documentation for a R binding parameter.
|
||||
*
|
||||
* 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_PRINT_DOC_HPP
|
||||
#define MLPACK_BINDINGS_R_PRINT_DOC_HPP
|
||||
|
||||
#include "get_r_type.hpp"
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/hyphenate_string.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* Print the docstring documentation for a given parameter. You are responsible
|
||||
* for setting up the line---this does not handle indentation or anything. This
|
||||
* is meant to produce a line of documentation describing a single parameter.
|
||||
*
|
||||
* The indent parameter (void* input, which should be a pointer to a size_t)
|
||||
* should be passed to know how much to indent for a new line.
|
||||
*
|
||||
* @param d Parameter data struct.
|
||||
* @param * (input) Pointer to size_t containing indent.
|
||||
* @param output Unused parameter.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintDoc(util::ParamData& d,
|
||||
const void* /* input */,
|
||||
void* output)
|
||||
{
|
||||
bool out = *((bool*) output);
|
||||
std::ostringstream oss;
|
||||
if (out)
|
||||
oss << "#' \\item{" << d.name << "}{";
|
||||
else
|
||||
oss << "#' @param " << d.name << " ";
|
||||
oss << d.desc.substr(0, d.desc.size() - 1);
|
||||
// Print a default, if possible.
|
||||
if (!d.required)
|
||||
{
|
||||
if (d.cppType == "std::string" ||
|
||||
d.cppType == "double" ||
|
||||
d.cppType == "int" ||
|
||||
d.cppType == "bool")
|
||||
{
|
||||
oss << ". Default value \"";
|
||||
if (d.cppType == "std::string")
|
||||
{
|
||||
oss << boost::any_cast<std::string>(d.value);
|
||||
}
|
||||
else if (d.cppType == "double")
|
||||
{
|
||||
oss << boost::any_cast<double>(d.value);
|
||||
}
|
||||
else if (d.cppType == "int")
|
||||
{
|
||||
oss << boost::any_cast<int>(d.value);
|
||||
}
|
||||
else if (d.cppType == "bool")
|
||||
{
|
||||
oss << (boost::any_cast<bool>(d.value) ? "TRUE" : "FALSE");
|
||||
}
|
||||
oss << "\"";
|
||||
}
|
||||
}
|
||||
|
||||
oss << " (" << GetRType<typename std::remove_pointer<T>::type>(d) << ").";
|
||||
|
||||
if (out)
|
||||
oss << "}";
|
||||
|
||||
MLPACK_COUT_STREAM << util::HyphenateString(oss.str(), "#' ");
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* @file bindings/R/print_doc_functions.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* This file contains functions useful for printing documentation strings
|
||||
* related to R bindings.
|
||||
*
|
||||
* 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_PRINT_DOC_FUNCTIONS_HPP
|
||||
#define MLPACK_BINDINGS_R_PRINT_DOC_FUNCTIONS_HPP
|
||||
|
||||
#include <mlpack/core/util/hyphenate_string.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* Given the name of a binding, print its R name.
|
||||
*/
|
||||
inline std::string GetBindingName(const std::string& bindingName);
|
||||
|
||||
/**
|
||||
* Print any import information for the R binding.
|
||||
*/
|
||||
inline std::string PrintImport();
|
||||
|
||||
/**
|
||||
* Print any special information about input options.
|
||||
*/
|
||||
inline std::string PrintInputOptionInfo();
|
||||
|
||||
/**
|
||||
* Print any special information about output options.
|
||||
*/
|
||||
inline std::string PrintOutputOptionInfo();
|
||||
|
||||
/**
|
||||
* Given a parameter type, print the corresponding value.
|
||||
*/
|
||||
template<typename T>
|
||||
inline std::string PrintValue(const T& value, bool quotes);
|
||||
|
||||
/**
|
||||
* Special overload for booleans.
|
||||
*/
|
||||
template<>
|
||||
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);
|
||||
|
||||
/**
|
||||
* Recursion base case.
|
||||
*/
|
||||
inline std::string PrintInputOptions();
|
||||
|
||||
/**
|
||||
* Print an input option. This will throw an exception if the parameter does
|
||||
* not exist in IO.
|
||||
*/
|
||||
template<typename T, typename... Args>
|
||||
std::string PrintInputOptions(const std::string& paramName,
|
||||
const T& value,
|
||||
Args... args);
|
||||
|
||||
/**
|
||||
* Recursion base case.
|
||||
*/
|
||||
inline std::string PrintOutputOptions(const bool /* markdown */);
|
||||
|
||||
template<typename T, typename... Args>
|
||||
std::string PrintOutputOptions(const bool markdown,
|
||||
const std::string& paramName,
|
||||
const T& value,
|
||||
Args... args);
|
||||
|
||||
/**
|
||||
* Given a name of a binding and a variable number of arguments (and their
|
||||
* contents), print the corresponding function call.
|
||||
*/
|
||||
template<typename... Args>
|
||||
std::string ProgramCall(const bool markdown,
|
||||
const std::string& programName,
|
||||
Args... args);
|
||||
|
||||
/**
|
||||
* Given the name of a binding, print a program call assuming that all options
|
||||
* are specified.
|
||||
*/
|
||||
inline std::string ProgramCall(const std::string& programName);
|
||||
|
||||
/**
|
||||
* Given the name of a model, print it. Here we do not need to modify anything.
|
||||
*/
|
||||
inline std::string PrintModel(const std::string& modelName);
|
||||
|
||||
/**
|
||||
* Given the name of a matrix, print it. Here we do not need to modify
|
||||
* anything.
|
||||
*/
|
||||
inline std::string PrintDataset(const std::string& datasetName);
|
||||
|
||||
/**
|
||||
* Given the parameter name, determine what it would actually be when passed to
|
||||
* the command line.
|
||||
*/
|
||||
inline std::string ParamString(const std::string& paramName);
|
||||
|
||||
/**
|
||||
* Print whether or not we should ignore a check on the given parameter.
|
||||
*/
|
||||
inline bool IgnoreCheck(const std::string& paramName);
|
||||
|
||||
/**
|
||||
* Print whether or not we should ignore a check on the given set of
|
||||
* constraints.
|
||||
*/
|
||||
inline bool IgnoreCheck(const std::vector<std::string>& constraints);
|
||||
|
||||
/**
|
||||
* Print whether or not we should ignore a check on the given set of
|
||||
* constraints.
|
||||
*/
|
||||
inline bool IgnoreCheck(
|
||||
const std::vector<std::pair<std::string, bool>>& constraints,
|
||||
const std::string& paramName);
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
// Include implementation.
|
||||
#include "print_doc_functions_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,410 @@
|
||||
/**
|
||||
* @file bindings/R/print_doc_functions_impl.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* This file contains functions useful for printing documentation strings
|
||||
* related to R bindings.
|
||||
*
|
||||
* 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_PRINT_DOC_FUNCTIONS_IMPL_HPP
|
||||
#define MLPACK_BINDINGS_R_PRINT_DOC_FUNCTIONS_IMPL_HPP
|
||||
|
||||
#include <mlpack/core/util/hyphenate_string.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* Given the name of a binding, print its R name.
|
||||
*/
|
||||
inline std::string GetBindingName(const std::string& bindingName)
|
||||
{
|
||||
// No modification is needed to the name---we just use it as-is.
|
||||
return bindingName + "()";
|
||||
}
|
||||
|
||||
/**
|
||||
* Print any import information for the R binding.
|
||||
*/
|
||||
inline std::string PrintImport()
|
||||
{
|
||||
return "library(mlpack)";
|
||||
}
|
||||
|
||||
/**
|
||||
* Print any special information about input options.
|
||||
*/
|
||||
inline std::string PrintInputOptionInfo()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Print any special information about output options.
|
||||
*/
|
||||
inline std::string PrintOutputOptionInfo()
|
||||
{
|
||||
return "Results are returned in a R list. The keys of the "
|
||||
"list are the names of the output parameters.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a parameter type, print the corresponding value.
|
||||
*/
|
||||
template<typename T>
|
||||
inline std::string PrintValue(const T& value, bool quotes)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
if (quotes)
|
||||
oss << "\"";
|
||||
oss << value;
|
||||
if (quotes)
|
||||
oss << "\"";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a vector parameter type, print the corresponding value.
|
||||
*/
|
||||
template<typename T>
|
||||
inline std::string PrintValue(const std::vector<T>& value, bool quotes)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
if (quotes)
|
||||
oss << "\"";
|
||||
oss << "c(";
|
||||
if (value.size() > 0)
|
||||
{
|
||||
oss << value[0];
|
||||
for (size_t i = 1; i < value.size(); ++i)
|
||||
oss << ", " << value[i];
|
||||
}
|
||||
oss << ")";
|
||||
if (quotes)
|
||||
oss << "\"";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a parameter name, print its corresponding default value.
|
||||
*/
|
||||
inline std::string PrintDefault(const std::string& paramName)
|
||||
{
|
||||
if (IO::Parameters().count(paramName) == 0)
|
||||
throw std::invalid_argument("unknown parameter " + paramName + "!");
|
||||
|
||||
util::ParamData& d = IO::Parameters()[paramName];
|
||||
|
||||
std::string defaultValue;
|
||||
IO::GetSingleton().functionMap[d.tname]["DefaultParam"](d, NULL,
|
||||
(void*) &defaultValue);
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special overload for booleans.
|
||||
*/
|
||||
template<>
|
||||
inline std::string PrintValue(const bool& value, bool quotes)
|
||||
{
|
||||
if (quotes && value)
|
||||
return "\"TRUE\"";
|
||||
else if (quotes && !value)
|
||||
return "\"FALSE\"";
|
||||
else if (!quotes && value)
|
||||
return "TRUE";
|
||||
else
|
||||
return "FALSE";
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursion base case.
|
||||
*/
|
||||
std::string PrintInputOptions() { return ""; }
|
||||
|
||||
/**
|
||||
* Print an input option. This will throw an exception if the parameter does
|
||||
* not exist in IO.
|
||||
*/
|
||||
template<typename T, typename... Args>
|
||||
std::string PrintInputOptions(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)
|
||||
{
|
||||
util::ParamData& d = IO::Parameters()[paramName];
|
||||
if (d.input)
|
||||
{
|
||||
// Print the input option.
|
||||
std::ostringstream oss;
|
||||
oss << paramName << "=";
|
||||
oss << PrintValue(value, d.tname == TYPENAME(std::string));
|
||||
result = oss.str();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown parameter!
|
||||
throw std::runtime_error("Unknown parameter '" + paramName + "' " +
|
||||
"encountered while assembling documentation! Check PROGRAM_INFO() " +
|
||||
"declaration.");
|
||||
}
|
||||
|
||||
// Continue recursion.
|
||||
std::string rest = PrintInputOptions(args...);
|
||||
if (rest != "" && result != "")
|
||||
result += ", " + rest;
|
||||
else if (result == "")
|
||||
result = rest;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursion base case.
|
||||
*/
|
||||
inline std::string PrintOutputOptions(const bool /* markdown */) { return ""; }
|
||||
|
||||
template<typename T, typename... Args>
|
||||
std::string PrintOutputOptions(const bool markdown,
|
||||
const std::string& paramName,
|
||||
const T& value,
|
||||
Args... args)
|
||||
{
|
||||
// See if this is part of the program.
|
||||
std::string result = "";
|
||||
std::string command_prefix = "R> ";
|
||||
if (IO::Parameters().count(paramName) > 0)
|
||||
{
|
||||
util::ParamData& d = IO::Parameters()[paramName];
|
||||
if (!d.input)
|
||||
{
|
||||
// Print a new line for the output option.
|
||||
std::ostringstream oss;
|
||||
if (markdown)
|
||||
oss << command_prefix;
|
||||
oss << value << " <- output$" << paramName;
|
||||
result = oss.str();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown parameter!
|
||||
throw std::runtime_error("Unknown parameter '" + paramName + "' " +
|
||||
"encountered while assembling documentation! Check PROGRAM_INFO() " +
|
||||
"declaration.");
|
||||
}
|
||||
|
||||
// Continue recursion.
|
||||
std::string rest = PrintOutputOptions(markdown, args...);
|
||||
if (rest != "" && result != "")
|
||||
result += "\n";
|
||||
result += rest;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a name of a binding and a variable number of arguments (and their
|
||||
* contents), print the corresponding function call.
|
||||
*/
|
||||
template<typename... Args>
|
||||
std::string ProgramCall(const bool markdown,
|
||||
const std::string& programName,
|
||||
Args... args)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
if (markdown)
|
||||
oss << "R> ";
|
||||
|
||||
// Find out if we have any output options first.
|
||||
std::ostringstream ossOutput;
|
||||
ossOutput << PrintOutputOptions(markdown, args...);
|
||||
if (ossOutput.str() != "")
|
||||
oss << "output <- ";
|
||||
oss << programName << "(";
|
||||
|
||||
// Now process each input option.
|
||||
oss << PrintInputOptions(args...);
|
||||
oss << ")";
|
||||
|
||||
std::string call = oss.str();
|
||||
oss.str(""); // Reset it.
|
||||
|
||||
// Now process each output option.
|
||||
oss << PrintOutputOptions(markdown, args...);
|
||||
if (markdown)
|
||||
{
|
||||
if (oss.str() == "")
|
||||
return util::HyphenateString(call, 2);
|
||||
else
|
||||
return util::HyphenateString(call, 2) + "\n" + oss.str();
|
||||
}
|
||||
|
||||
if (oss.str() == "")
|
||||
return "\\dontrun{\n" + util::HyphenateString(call, 2) + "\n}";
|
||||
else
|
||||
return "\\dontrun{\n" + util::HyphenateString(call, 2) + "\n" + oss.str() +
|
||||
"\n}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the name of a binding, print a program call assuming that all options
|
||||
* are specified. The programName should not be the output of GetBindingName().
|
||||
*/
|
||||
inline std::string ProgramCall(const std::string& programName)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
std::string command_prefix = "R> ";
|
||||
oss << command_prefix;
|
||||
|
||||
// Determine if we have any output options.
|
||||
std::map<std::string, util::ParamData>& parameters = IO::Parameters();
|
||||
bool hasOutput = false;
|
||||
for (auto it = parameters.begin(); it != parameters.end(); ++it)
|
||||
{
|
||||
if (!it->second.input)
|
||||
{
|
||||
hasOutput = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasOutput)
|
||||
oss << "d <- ";
|
||||
|
||||
oss << programName << "(";
|
||||
|
||||
// Now iterate over every input option.
|
||||
bool first = true;
|
||||
for (auto it = parameters.begin(); it != parameters.end(); ++it)
|
||||
{
|
||||
if (!it->second.input || (it->second.persistent &&
|
||||
it->second.name != "verbose"))
|
||||
continue;
|
||||
|
||||
if (!first)
|
||||
oss << ", ";
|
||||
else
|
||||
first = false;
|
||||
|
||||
// Print the input option.
|
||||
oss << it->second.name << "=";
|
||||
|
||||
std::string value;
|
||||
IO::GetSingleton().functionMap[it->second.tname]["DefaultParam"](
|
||||
it->second, NULL, (void*) &value);
|
||||
oss << value;
|
||||
}
|
||||
oss << ")";
|
||||
|
||||
std::string result = util::HyphenateString(oss.str(), 8);
|
||||
|
||||
oss.str("");
|
||||
oss << result;
|
||||
|
||||
// Now print output lines.
|
||||
for (auto it = parameters.begin(); it != parameters.end(); ++it)
|
||||
{
|
||||
if (it->second.input)
|
||||
continue;
|
||||
|
||||
// Print a new line for the output option.
|
||||
oss << std::endl << command_prefix << it->second.name << " <- d$"
|
||||
<< it->second.name;
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the name of a model, print it. Here we do not need to modify anything.
|
||||
*/
|
||||
inline std::string PrintModel(const std::string& modelName)
|
||||
{
|
||||
return "\"" + modelName + "\"";
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the name of a matrix, print it. Here we do not need to modify
|
||||
* anything.
|
||||
*/
|
||||
inline std::string PrintDataset(const std::string& datasetName)
|
||||
{
|
||||
return "\"" + datasetName + "\"";
|
||||
}
|
||||
|
||||
/**
|
||||
* Print any closing call to a program.
|
||||
*/
|
||||
inline std::string ProgramCallClose()
|
||||
{
|
||||
return ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the parameter name, determine what it would actually be when passed to
|
||||
* the command line.
|
||||
*/
|
||||
inline std::string ParamString(const std::string& paramName)
|
||||
{
|
||||
// For a R binding we don't need to know the type.
|
||||
return "\"" + paramName + "\"";
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the parameter name and an argument, return what should be written as
|
||||
* documentation when referencing that argument.
|
||||
*/
|
||||
template<typename T>
|
||||
inline std::string ParamString(const std::string& paramName, const T& value)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << paramName << "=" << value;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
inline bool IgnoreCheck(const std::string& paramName)
|
||||
{
|
||||
return !IO::Parameters()[paramName].input;
|
||||
}
|
||||
|
||||
inline bool IgnoreCheck(const std::vector<std::string>& constraints)
|
||||
{
|
||||
for (size_t i = 0; i < constraints.size(); ++i)
|
||||
{
|
||||
if (!IO::Parameters()[constraints[i]].input)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool IgnoreCheck(
|
||||
const std::vector<std::pair<std::string, bool>>& constraints,
|
||||
const std::string& paramName)
|
||||
{
|
||||
for (size_t i = 0; i < constraints.size(); ++i)
|
||||
{
|
||||
if (!IO::Parameters()[constraints[i].first].input)
|
||||
return true;
|
||||
}
|
||||
|
||||
return !IO::Parameters()[paramName].input;
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file bindings/R/print_input_param.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Print the declaration of an input parameter as part of a line in a R
|
||||
* function definition.
|
||||
*
|
||||
* 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_PRINT_INPUT_PARAM_HPP
|
||||
#define MLPACK_BINDINGS_R_PRINT_INPUT_PARAM_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* Print the declaration of an input parameter as part of a line in a R
|
||||
* function definition. This doesn't include any commas or anything.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintInputParam(util::ParamData& d,
|
||||
const void* /* input */,
|
||||
void* /* output */)
|
||||
{
|
||||
MLPACK_COUT_STREAM << d.name;
|
||||
if (std::is_same<T, bool>::value)
|
||||
MLPACK_COUT_STREAM << "=FALSE";
|
||||
else if (!d.required)
|
||||
MLPACK_COUT_STREAM << "=NA";
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,206 @@
|
||||
/**
|
||||
* @file bindings/R/print_input_processing.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Print R code to handle input arguments.
|
||||
*
|
||||
* 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_PRINT_INPUT_PROCESSING_IMPL_HPP
|
||||
#define MLPACK_BINDINGS_R_PRINT_INPUT_PROCESSING_IMPL_HPP
|
||||
|
||||
#include <mlpack/bindings/util/strip_type.hpp>
|
||||
#include "get_type.hpp"
|
||||
#include <mlpack/prereqs.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* Print input processing for a standard option type.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintInputProcessing(
|
||||
util::ParamData& d,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::disable_if<data::HasSerialize<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
if (!d.required)
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* if (!identical(<param_name>, NA)) {
|
||||
* IO_SetParam<type>("<param_name>", <param_name>)
|
||||
* }
|
||||
*/
|
||||
MLPACK_COUT_STREAM << " if (!identical(" << d.name;
|
||||
if (d.cppType == "bool")
|
||||
{
|
||||
MLPACK_COUT_STREAM << ", FALSE)) {" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
MLPACK_COUT_STREAM << ", NA)) {" << std::endl;
|
||||
}
|
||||
MLPACK_COUT_STREAM << " IO_SetParam" << GetType<T>(d) << "(\""
|
||||
<< d.name << "\", " << d.name << ")" << std::endl;
|
||||
MLPACK_COUT_STREAM << " }" << std::endl; // Closing brace.
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* IO_SetParam<type>("<param_name>", <param_name>)
|
||||
*/
|
||||
MLPACK_COUT_STREAM << " IO_SetParam" << GetType<T>(d) << "(\""
|
||||
<< d.name << "\", " << d.name << ")" << std::endl;
|
||||
}
|
||||
MLPACK_COUT_STREAM << std::endl; // Extra line is to clear up the code a bit.
|
||||
}
|
||||
|
||||
/**
|
||||
* Print input processing for a matrix type.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintInputProcessing(
|
||||
util::ParamData& d,
|
||||
const typename boost::enable_if<arma::is_arma_type<T>>::type* = 0)
|
||||
{
|
||||
if (!d.required)
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* if (!identical(<param_name>, NA)) {
|
||||
* IO_SetParam<type>("<param_name>", to_matrix(<param_name>))
|
||||
* }
|
||||
*/
|
||||
MLPACK_COUT_STREAM << " if (!identical(" << d.name << ", NA)) {"
|
||||
<< std::endl;
|
||||
MLPACK_COUT_STREAM << " IO_SetParam" << GetType<T>(d) << "(\""
|
||||
<< d.name << "\", to_matrix(" << d.name << "))" << std::endl;
|
||||
MLPACK_COUT_STREAM << " }" << std::endl; // Closing brace.
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* IO_SetParam<type>("<param_name>", to_matrix(<param_name>))
|
||||
*/
|
||||
MLPACK_COUT_STREAM << " IO_SetParam" << GetType<T>(d) << "(\""
|
||||
<< d.name << "\", to_matrix(" << d.name << "))" << std::endl;
|
||||
}
|
||||
MLPACK_COUT_STREAM << std::endl; // Extra line is to clear up the code a bit.
|
||||
}
|
||||
|
||||
/**
|
||||
* Print input processing for a matrix with info type.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintInputProcessing(
|
||||
util::ParamData& d,
|
||||
const typename boost::enable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
if (!d.required)
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* if (!identical(<param_name>, NA)) {
|
||||
* <param_name> = to_matrix_with_info(<param_name>)
|
||||
* IO_SetParam<type>("<param_name>", <param_name>$info,
|
||||
* <param_name>$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<T>(d) << "(\""
|
||||
<< d.name << "\", " << d.name << "$info, " << d.name
|
||||
<< "$data)" << std::endl;
|
||||
MLPACK_COUT_STREAM << " }" << std::endl; // Closing brace.
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* <param_name> = to_matrix_with_info(<param_name>)
|
||||
* IO_SetParam<type>("<param_name>", <param_name>$info,
|
||||
* <param_name>$data)
|
||||
*/
|
||||
MLPACK_COUT_STREAM << " " << d.name << " <- to_matrix_with_info("
|
||||
<< d.name << ")" << std::endl;
|
||||
MLPACK_COUT_STREAM << " IO_SetParam" << GetType<T>(d) << "(\""
|
||||
<< d.name << "\", " << d.name << "$info, " << d.name
|
||||
<< "$data)" << std::endl;
|
||||
}
|
||||
MLPACK_COUT_STREAM << std::endl; // Extra line is to clear up the code a bit.
|
||||
}
|
||||
|
||||
/**
|
||||
* Print input processing for a serializable type.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintInputProcessing(
|
||||
util::ParamData& d,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::enable_if<data::HasSerialize<T>>::type* = 0)
|
||||
{
|
||||
if (!d.required)
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* if (!identical(<param_name>, NA)) {
|
||||
* IO_SetParam<ModelType>Ptr("<param_name>", <param_name>)
|
||||
* }
|
||||
*/
|
||||
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 << " }" << std::endl; // Closing brace.
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* IO_SetParam<ModelType>Ptr("<param_name>", <param_name>)
|
||||
*/
|
||||
MLPACK_COUT_STREAM << " IO_SetParam" << util::StripType(d.cppType)
|
||||
<< "Ptr(\"" << d.name << "\", " << d.name << ")" << std::endl;
|
||||
}
|
||||
MLPACK_COUT_STREAM << std::endl; // Extra line is to clear up the code a bit.
|
||||
}
|
||||
|
||||
/**
|
||||
* @param d Parameter data struct.
|
||||
* @param * (input) Unused parameter.
|
||||
* @param * (output) Unused parameter.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintInputProcessing(util::ParamData& d,
|
||||
const void* /* input */,
|
||||
void* /* output */)
|
||||
{
|
||||
PrintInputProcessing<typename std::remove_pointer<T>::type>(d);
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* @file bindings/R/print_output_processing.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Print the output processing in a R binding .R file for a given
|
||||
* parameter.
|
||||
*
|
||||
* 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_PRINT_OUTPUT_PROCESSING_HPP
|
||||
#define MLPACK_BINDINGS_R_PRINT_OUTPUT_PROCESSING_HPP
|
||||
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include "get_type.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* Print output processing for a regular parameter type.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintOutputProcessing(
|
||||
util::ParamData& d,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::disable_if<data::HasSerialize<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* "<param_name>" = IO_GetParam<Type>("param_name")
|
||||
*
|
||||
*/
|
||||
|
||||
MLPACK_COUT_STREAM << " \"" << d.name << "\" = IO_GetParam" << GetType<T>(d)
|
||||
<< "(\"" << d.name << "\")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Print output processing for a matrix type.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintOutputProcessing(
|
||||
util::ParamData& d,
|
||||
const typename boost::enable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename std::enable_if<!std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>::value>::type* = 0)
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* "<param_name>" = IO_GetParam<Type>("param_name")
|
||||
*
|
||||
*/
|
||||
|
||||
MLPACK_COUT_STREAM << " \"" << d.name << "\" = IO_GetParam" << GetType<T>(d)
|
||||
<< "(\"" << d.name << "\")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Print output processing for a matrix with info type.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintOutputProcessing(
|
||||
util::ParamData& d,
|
||||
const typename boost::enable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0)
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* "<param_name>" = IO_GetParam<Type>("param_name")
|
||||
*
|
||||
*/
|
||||
|
||||
MLPACK_COUT_STREAM << " \"" << d.name << "\" = IO_GetParam" << GetType<T>(d)
|
||||
<< "(\"" << d.name << "\")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Print output processing for a serializable model.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintOutputProcessing(
|
||||
util::ParamData& d,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::enable_if<data::HasSerialize<T>>::type* = 0)
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* "<param_name>" = <param_name>
|
||||
*
|
||||
*/
|
||||
|
||||
MLPACK_COUT_STREAM << " \"" << d.name << "\" = " << d.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param d Parameter data struct.
|
||||
* @param * (input) Unused parameter.
|
||||
* @param * (output) Unused parameter.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintOutputProcessing(util::ParamData& d,
|
||||
const void* /*input*/,
|
||||
void* /* output */)
|
||||
{
|
||||
PrintOutputProcessing<typename std::remove_pointer<T>::type>(d);
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @file bindings/R/print_serialize_util.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Print the serialize utility in a R binding .R file for a given
|
||||
* parameter.
|
||||
*
|
||||
* 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_PRINT_SERIALIZE_UTIL_HPP
|
||||
#define MLPACK_BINDINGS_R_PRINT_SERIALIZE_UTIL_HPP
|
||||
|
||||
#include <mlpack/bindings/util/strip_type.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* If the type is not serializable, print nothing.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintSerializeUtil(
|
||||
util::ParamData& /* d */,
|
||||
const typename std::enable_if<!arma::is_arma_type<T>::value>::type* = 0,
|
||||
const typename std::enable_if<!data::HasSerialize<T>::value>::type* = 0)
|
||||
{
|
||||
// Do Nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Matrices are serializable but here we also print nothing.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintSerializeUtil(
|
||||
util::ParamData& /* d */,
|
||||
const typename std::enable_if<arma::is_arma_type<T>::value>::type* = 0)
|
||||
{
|
||||
// Do Nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* For non-matrix serializable types we need to print something.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintSerializeUtil(
|
||||
util::ParamData& d,
|
||||
const typename std::enable_if<!arma::is_arma_type<T>::value>::type* = 0,
|
||||
const typename std::enable_if<data::HasSerialize<T>::value>::type* = 0)
|
||||
{
|
||||
/**
|
||||
* This gives us code like:
|
||||
*
|
||||
* <param_name> <- IO_GetParam<ModelType>Ptr("<param_name>")
|
||||
* attr(<param_name>, "type") <- "<ModelType>"
|
||||
*
|
||||
*/
|
||||
MLPACK_COUT_STREAM << " " << d.name << " <- IO_GetParam"
|
||||
<< util::StripType(d.cppType) << "Ptr(\"" << d.name << "\")";
|
||||
MLPACK_COUT_STREAM << std::endl;
|
||||
MLPACK_COUT_STREAM << " attr(" << d.name << ", \"type\") <- \""
|
||||
<< util::StripType(d.cppType) << "\"";
|
||||
MLPACK_COUT_STREAM << std::endl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param d Parameter data struct.
|
||||
* @param * (input) Unused parameter.
|
||||
* @param * (output) Unused parameter.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintSerializeUtil(util::ParamData& d,
|
||||
const void* /*input*/,
|
||||
void* /* output */)
|
||||
{
|
||||
PrintSerializeUtil<typename std::remove_pointer<T>::type>(d);
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @file bindings/R/print_type_doc.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Print documentation for a given type, detailing what the type actually is to
|
||||
* the user.
|
||||
*
|
||||
* 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_PRINT_TYPE_DOC_HPP
|
||||
#define MLPACK_BINDINGS_R_PRINT_TYPE_DOC_HPP
|
||||
|
||||
#include <mlpack/core/util/is_std_vector.hpp>
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* Return a string representing the command-line type of an option.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string PrintTypeDoc(
|
||||
util::ParamData& data,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::disable_if<util::IsStdVector<T>>::type* = 0,
|
||||
const typename boost::disable_if<data::HasSerialize<T>>::type* = 0,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type* = 0);
|
||||
|
||||
/**
|
||||
* Return a string representing the command-line type of a vector.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string PrintTypeDoc(
|
||||
util::ParamData& data,
|
||||
const typename std::enable_if<util::IsStdVector<T>::value>::type* = 0);
|
||||
|
||||
/**
|
||||
* Return a string representing the command-line type of a matrix option.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string PrintTypeDoc(
|
||||
util::ParamData& data,
|
||||
const typename std::enable_if<arma::is_arma_type<T>::value>::type* = 0);
|
||||
|
||||
/**
|
||||
* Return a string representing the command-line type of a matrix tuple option.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string PrintTypeDoc(
|
||||
util::ParamData& data,
|
||||
const typename std::enable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>::value>::type* = 0);
|
||||
|
||||
/**
|
||||
* Return a string representing the command-line type of a model.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string PrintTypeDoc(
|
||||
util::ParamData& data,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type* = 0,
|
||||
const typename boost::enable_if<data::HasSerialize<T>>::type* = 0);
|
||||
|
||||
/**
|
||||
* Print the command-line type of an option into a string.
|
||||
*/
|
||||
template<typename T>
|
||||
void PrintTypeDoc(util::ParamData& data,
|
||||
const void* /* input */,
|
||||
void* output)
|
||||
{
|
||||
*((std::string*) output) =
|
||||
PrintTypeDoc<typename std::remove_pointer<T>::type>(data);
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#include "print_type_doc_impl.hpp"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* @file bindings/R/print_type_doc_impl.hpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* Print documentation for a given type.
|
||||
*
|
||||
* 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_PRINT_TYPE_DOC_IMPL_HPP
|
||||
#define MLPACK_BINDINGS_R_PRINT_TYPE_DOC_IMPL_HPP
|
||||
|
||||
#include "print_type_doc.hpp"
|
||||
|
||||
namespace mlpack {
|
||||
namespace bindings {
|
||||
namespace r {
|
||||
|
||||
/**
|
||||
* Return a string representing the command-line type of an option.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string PrintTypeDoc(
|
||||
util::ParamData& data,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type*,
|
||||
const typename boost::disable_if<util::IsStdVector<T>>::type*,
|
||||
const typename boost::disable_if<data::HasSerialize<T>>::type*,
|
||||
const typename boost::disable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>>::type*)
|
||||
{
|
||||
// A flag type.
|
||||
if (std::is_same<T, bool>::value)
|
||||
{
|
||||
return "A boolean flag option (i.e. `TRUE` or `FALSE`).";
|
||||
}
|
||||
// An integer.
|
||||
else if (std::is_same<T, int>::value)
|
||||
{
|
||||
return "An integer (i.e., `1`).";
|
||||
}
|
||||
// A floating point value.
|
||||
else if (std::is_same<T, double>::value)
|
||||
{
|
||||
return "A floating-point number (i.e., `0.5`).";
|
||||
}
|
||||
// A string.
|
||||
else if (std::is_same<T, std::string>::value)
|
||||
{
|
||||
return "A character string (i.e., `\"hello\"`).";
|
||||
}
|
||||
// Not sure what it is...
|
||||
else
|
||||
{
|
||||
throw std::invalid_argument("Unknown parameter type `" + data.cppType +
|
||||
"`.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representing the command-line type of a vector.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string PrintTypeDoc(
|
||||
util::ParamData& data,
|
||||
const typename std::enable_if<util::IsStdVector<T>::value>::type*)
|
||||
{
|
||||
if (std::is_same<T, std::vector<int>>::value)
|
||||
{
|
||||
return "A vector of integers; i.e., `c(0, 1, 2)`.";
|
||||
}
|
||||
else if (std::is_same<T, std::vector<std::string>>::value)
|
||||
{
|
||||
return "A vector of strings; i.e., `c(\"hello\", \"goodbye\")`.";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::invalid_argument("Unknown vector type `" + data.cppType + "`.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representing the command-line type of a matrix option.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string PrintTypeDoc(
|
||||
util::ParamData& data,
|
||||
const typename std::enable_if<arma::is_arma_type<T>::value>::type*)
|
||||
{
|
||||
if (std::is_same<typename T::elem_type, double>::value)
|
||||
{
|
||||
if (T::is_col || T::is_row)
|
||||
{
|
||||
return "A 1-d matrix-like containing `numeric` data (could be an "
|
||||
"`matrix` or a `data.frame` with one dimension of size 1).";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "A 2-d matrix-like containing `numeric` data (could be an "
|
||||
"`matrix` or a `data.frame` or anything convertible to an "
|
||||
"2-d `matrix`).";
|
||||
}
|
||||
}
|
||||
else if (std::is_same<typename T::elem_type, size_t>::value)
|
||||
{
|
||||
if (T::is_col || T::is_row)
|
||||
{
|
||||
return "A 1-d matrix-like containing `integer` data (could be an "
|
||||
"`matrix` or a `data.frame` with one dimension of size 1).";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "A 2-d matrix-like containing `integer` data (could be an "
|
||||
"`matrix` or a `data.frame` or anything convertible to an "
|
||||
"2-d `matrix`).";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::invalid_argument("Unknown matrix type `" + data.cppType + "`.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representing the command-line type of a matrix tuple option.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string PrintTypeDoc(
|
||||
util::ParamData& /* data */,
|
||||
const typename std::enable_if<std::is_same<T,
|
||||
std::tuple<data::DatasetInfo, arma::mat>>::value>::type*)
|
||||
{
|
||||
return "A 2-d array containing `numeric` data. Like the regular 2-d matrices"
|
||||
", this can be a `matrix`, or a `data.frame`. However, this type can also"
|
||||
" accept a `data.frame` that has columns of type `character`, `logical` "
|
||||
"or `factor`. These values will be converted to `numeric` indices before"
|
||||
" being passed to mlpack, and then inside mlpack they will be properly "
|
||||
"treated as categorical variables, so there is no need to do one-hot "
|
||||
"encoding for this matrix type.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representing the command-line type of a model.
|
||||
*/
|
||||
template<typename T>
|
||||
std::string PrintTypeDoc(
|
||||
util::ParamData& /* data */,
|
||||
const typename boost::disable_if<arma::is_arma_type<T>>::type*,
|
||||
const typename boost::enable_if<data::HasSerialize<T>>::type*)
|
||||
{
|
||||
return "An mlpack model pointer. `<Model>` refers to the type of model that "
|
||||
"is being stored, so, e.g., for `cf()`, the type will be `CFModel`. "
|
||||
"This type holds a pointer to C++ memory containing the mlpack model. "
|
||||
"Note that this means the mlpack model itself cannot be easily inspected "
|
||||
"in R. However, the pointer can be passed to subsequent calls to "
|
||||
"mlpack functions, and can be serialized and deserialized via either the "
|
||||
"`Serialize()` and `Unserialize()` functions.";
|
||||
}
|
||||
|
||||
} // namespace r
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @file src/${PROGRAM_NAME}.cpp
|
||||
*
|
||||
* This is an autogenerated file containing implementations of C++ functions to
|
||||
* be called by the R ${PROGRAM_NAME} binding.
|
||||
*/
|
||||
#include <rcpp_mlpack.h>
|
||||
#define BINDING_TYPE BINDING_TYPE_R
|
||||
#include <${INCLUDE_FILE}>
|
||||
|
||||
#define Realloc(p,n,t) (t *) R_chk_realloc( (void *)(p), (R_SIZE_T)((n) * sizeof(t)) )
|
||||
#define Free(p) (R_chk_free( (void *)(p) ), (p) = NULL)
|
||||
|
||||
// [[Rcpp::export]]
|
||||
void ${PROGRAM_NAME}_mlpackMain()
|
||||
{
|
||||
mlpackMain();
|
||||
}
|
||||
|
||||
// Any implementations of methods for dealing with model pointers will be put
|
||||
// below this comment, if needed.
|
||||
${MODEL_PTR_IMPLS}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Add the R binding test.
|
||||
add_r_binding(test_r_binding)
|
||||
|
||||
add_test(NAME r_binding_test
|
||||
COMMAND ${RSCRIPT_EXECUTABLE} -e "library(pkgload); load_all('.'); library(testthat); test_dir('tests/')"
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src/mlpack/bindings/R/mlpack)
|
||||
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* @file bindings/R/test_r_binding_main.cpp
|
||||
* @author Yashwant Singh Parihar
|
||||
*
|
||||
* A binding test for R.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <mlpack/prereqs.hpp>
|
||||
#include <mlpack/core/util/io.hpp>
|
||||
#include <mlpack/core/util/mlpack_main.hpp>
|
||||
#include <mlpack/core/kernels/gaussian_kernel.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace mlpack;
|
||||
using namespace mlpack::kernel;
|
||||
|
||||
// Program Name.
|
||||
BINDING_NAME("R binding test");
|
||||
|
||||
// Short description.
|
||||
BINDING_SHORT_DESC(
|
||||
"A simple program to test R binding functionality.");
|
||||
|
||||
// Long description.
|
||||
BINDING_LONG_DESC(
|
||||
"A simple program to test R binding functionality. You can build "
|
||||
"mlpack with the BUILD_TESTS option set to off, and this binding will "
|
||||
"no longer be built.");
|
||||
|
||||
PARAM_STRING_IN_REQ("string_in", "Input string, must be 'hello'.", "s");
|
||||
PARAM_INT_IN_REQ("int_in", "Input int, must be 12.", "i");
|
||||
PARAM_DOUBLE_IN_REQ("double_in", "Input double, must be 4.0.", "d");
|
||||
PARAM_FLAG("flag1", "Input flag, must be specified.", "f");
|
||||
PARAM_FLAG("flag2", "Input flag, must not be specified.", "F");
|
||||
PARAM_MATRIX_IN("matrix_in", "Input matrix.", "m");
|
||||
PARAM_UMATRIX_IN("umatrix_in", "Input unsigned matrix.", "u");
|
||||
PARAM_COL_IN("col_in", "Input column.", "c");
|
||||
PARAM_UCOL_IN("ucol_in", "Input unsigned column.", "");
|
||||
PARAM_ROW_IN("row_in", "Input row.", "");
|
||||
PARAM_UROW_IN("urow_in", "Input unsigned row.", "");
|
||||
PARAM_MATRIX_AND_INFO_IN("matrix_and_info_in", "Input matrix and info.", "");
|
||||
PARAM_VECTOR_IN(int, "vector_in", "Input vector of numbers.", "");
|
||||
PARAM_VECTOR_IN(string, "str_vector_in", "Input vector of strings.", "");
|
||||
PARAM_MODEL_IN(GaussianKernel, "model_in", "Input model.", "");
|
||||
PARAM_FLAG("build_model", "If true, a model will be returned.", "");
|
||||
|
||||
PARAM_STRING_OUT("string_out", "Output string, will be 'hello2'.", "S");
|
||||
PARAM_INT_OUT("int_out", "Output int, will be 13.");
|
||||
PARAM_DOUBLE_OUT("double_out", "Output double, will be 5.0.");
|
||||
PARAM_MATRIX_OUT("matrix_out", "Output matrix.", "M");
|
||||
PARAM_UMATRIX_OUT("umatrix_out", "Output unsigned matrix.", "U");
|
||||
PARAM_COL_OUT("col_out", "Output column. 2x input column", "");
|
||||
PARAM_UCOL_OUT("ucol_out", "Output unsigned column. 2x input column.", "");
|
||||
PARAM_ROW_OUT("row_out", "Output row. 2x input row.", "");
|
||||
PARAM_UROW_OUT("urow_out", "Output unsigned row. 2x input row.", "");
|
||||
PARAM_MATRIX_OUT("matrix_and_info_out", "Output matrix and info; all numeric "
|
||||
"elements multiplied by 3.", "");
|
||||
PARAM_VECTOR_OUT(int, "vector_out", "Output vector.", "");
|
||||
PARAM_VECTOR_OUT(string, "str_vector_out", "Output string vector.", "");
|
||||
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()
|
||||
{
|
||||
const string s = IO::GetParam<string>("string_in");
|
||||
const int i = IO::GetParam<int>("int_in");
|
||||
const double d = IO::GetParam<double>("double_in");
|
||||
|
||||
IO::GetParam<string>("string_out") = "wrong";
|
||||
IO::GetParam<int>("int_out") = 11;
|
||||
IO::GetParam<double>("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 (s == "hello")
|
||||
IO::GetParam<string>("string_out") = "hello2";
|
||||
|
||||
if (i == 12)
|
||||
IO::GetParam<int>("int_out") = 13;
|
||||
|
||||
if (d == 4.0)
|
||||
IO::GetParam<double>("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"))
|
||||
{
|
||||
arma::mat out = move(IO::GetParam<arma::mat>("matrix_in"));
|
||||
out.shed_row(4);
|
||||
out.row(2) *= 2.0;
|
||||
|
||||
IO::GetParam<arma::mat>("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"))
|
||||
{
|
||||
arma::Mat<size_t> out =
|
||||
move(IO::GetParam<arma::Mat<size_t>>("umatrix_in"));
|
||||
out.shed_row(4);
|
||||
out.row(2) *= 2;
|
||||
|
||||
IO::GetParam<arma::Mat<size_t>>("umatrix_out") = move(out);
|
||||
}
|
||||
|
||||
// An input column or row should have all elements multiplied by two.
|
||||
if (IO::HasParam("col_in"))
|
||||
{
|
||||
arma::vec out = move(IO::GetParam<arma::vec>("col_in"));
|
||||
out *= 2.0;
|
||||
|
||||
IO::GetParam<arma::vec>("col_out") = move(out);
|
||||
}
|
||||
|
||||
if (IO::HasParam("ucol_in"))
|
||||
{
|
||||
arma::Col<size_t> out =
|
||||
move(IO::GetParam<arma::Col<size_t>>("ucol_in"));
|
||||
out += 1;
|
||||
|
||||
IO::GetParam<arma::Col<size_t>>("ucol_out") = move(out);
|
||||
}
|
||||
|
||||
if (IO::HasParam("row_in"))
|
||||
{
|
||||
arma::rowvec out = move(IO::GetParam<arma::rowvec>("row_in"));
|
||||
out *= 2.0;
|
||||
|
||||
IO::GetParam<arma::rowvec>("row_out") = move(out);
|
||||
}
|
||||
|
||||
if (IO::HasParam("urow_in"))
|
||||
{
|
||||
arma::Row<size_t> out =
|
||||
move(IO::GetParam<arma::Row<size_t>>("urow_in"));
|
||||
out += 1;
|
||||
|
||||
IO::GetParam<arma::Row<size_t>>("urow_out") = move(out);
|
||||
}
|
||||
|
||||
// Vector arguments should have the last element removed.
|
||||
if (IO::HasParam("vector_in"))
|
||||
{
|
||||
vector<int> out = move(IO::GetParam<vector<int>>("vector_in"));
|
||||
out.pop_back();
|
||||
|
||||
IO::GetParam<vector<int>>("vector_out") = move(out);
|
||||
}
|
||||
|
||||
if (IO::HasParam("str_vector_in"))
|
||||
{
|
||||
vector<string> out = move(IO::GetParam<vector<string>>("str_vector_in"));
|
||||
out.pop_back();
|
||||
|
||||
IO::GetParam<vector<string>>("str_vector_out") = move(out);
|
||||
}
|
||||
|
||||
// All numeric elements should be multiplied by 3.
|
||||
if (IO::HasParam("matrix_and_info_in"))
|
||||
{
|
||||
typedef tuple<data::DatasetInfo, arma::mat> TupleType;
|
||||
TupleType tuple = move(IO::GetParam<TupleType>("matrix_and_info_in"));
|
||||
|
||||
const data::DatasetInfo& di = std::get<0>(tuple);
|
||||
arma::mat& m = std::get<1>(tuple);
|
||||
|
||||
for (size_t i = 0; i < m.n_rows; ++i)
|
||||
{
|
||||
if (di.Type(i) == data::Datatype::numeric)
|
||||
m.row(i) *= 2.0;
|
||||
}
|
||||
|
||||
IO::GetParam<arma::mat>("matrix_and_info_out") = move(m);
|
||||
}
|
||||
|
||||
// If we got a request to build a model, then build it.
|
||||
if (IO::HasParam("build_model"))
|
||||
{
|
||||
IO::GetParam<GaussianKernel*>("model_out") = new GaussianKernel(10.0);
|
||||
}
|
||||
|
||||
// If we got an input model, double the bandwidth and output that.
|
||||
if (IO::HasParam("model_in"))
|
||||
{
|
||||
IO::GetParam<double>("model_bw_out") =
|
||||
IO::GetParam<GaussianKernel*>("model_in")->Bandwidth() * 2.0;
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,6 @@ if (BUILD_CLI_EXECUTABLES)
|
||||
target_link_libraries(mlpack_${name}
|
||||
mlpack
|
||||
${ARMADILLO_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${COMPILER_SUPPORT_LIBRARIES}
|
||||
)
|
||||
# Make sure that we set BINDING_TYPE to cli so the command-line program is
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @author Matthew Amidon
|
||||
*
|
||||
* Definition of the Option class, which is used to define parameters which are
|
||||
* used by CLI. The ProgramDoc class also resides here.
|
||||
* used by CLI.
|
||||
*
|
||||
* 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
|
||||
@@ -164,35 +164,6 @@ class CLIOption
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A static object whose constructor registers program documentation with the
|
||||
* CLI class. This should not be used outside of CLI itself, and you should use
|
||||
* the PROGRAM_INFO() macro to declare these objects. Only one ProgramDoc
|
||||
* object should ever exist.
|
||||
*
|
||||
* @see core/util/io.hpp, mlpack::IO
|
||||
*/
|
||||
class ProgramDoc
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct a ProgramDoc object. When constructed, it will register itself
|
||||
* with IO.
|
||||
*
|
||||
* @param programName Short string representing the name of the program.
|
||||
* @param documentation Long string containing documentation on how to use the
|
||||
* program and what it is. No newline characters are necessary; this is
|
||||
* taken care of by IO later.
|
||||
*/
|
||||
ProgramDoc(const std::string& programName,
|
||||
const std::string& documentation);
|
||||
|
||||
//! The name of the program.
|
||||
std::string programName;
|
||||
//! Documentation for what the program does.
|
||||
std::string documentation;
|
||||
};
|
||||
|
||||
} // namespace cli
|
||||
} // namespace bindings
|
||||
} // namespace mlpack
|
||||
|
||||
@@ -47,8 +47,8 @@ void ParseCommandLine(int argc, char** argv)
|
||||
{
|
||||
// Add the parameter to desc.
|
||||
util::ParamData& d = it->second;
|
||||
IO::GetSingleton().functionMap[d.tname]["AddToCLI11"]
|
||||
(d, NULL, (void*) &app);
|
||||
IO::GetSingleton().functionMap[d.tname]["AddToCLI11"](d, NULL, (void*)
|
||||
&app);
|
||||
}
|
||||
|
||||
// Mark that we did parsing.
|
||||
@@ -136,13 +136,15 @@ void ParseCommandLine(int argc, char** argv)
|
||||
util::ParamData d = iter->second;
|
||||
if (d.required)
|
||||
{
|
||||
const std::string cliName;
|
||||
// CLI11 expects the parameter name to have "--" prepended.
|
||||
std::string cliName;
|
||||
IO::GetSingleton().functionMap[d.tname]["MapParameterName"](d, NULL,
|
||||
(void*) &cliName);
|
||||
cliName = "--" + cliName;
|
||||
|
||||
if (!app.count(cliName))
|
||||
{
|
||||
Log::Fatal << "Required option --" << cliName << " is undefined."
|
||||
Log::Fatal << "Required option " << cliName << " is undefined."
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,8 +102,9 @@ inline std::string ProgramCall(const std::string& programName);
|
||||
/**
|
||||
* Print what a user would type to invoke the given option name. Note that the
|
||||
* name *must* exist in the CLI module. (Note that because of the way
|
||||
* ProgramInfo is structured, this doesn't mean that all of the PARAM_*()
|
||||
* declarataions need to come before the PROGRAM_INFO() declaration.)
|
||||
* BINDING_LONG_DESC() and BINDING_EXAMPLE() is structured, this doesn't mean
|
||||
* that all of the PARAM_*() declarataions need to come before
|
||||
* BINDING_LONG_DESC() and BINDING_EXAMPLE() declaration.)
|
||||
*/
|
||||
inline std::string ParamString(const std::string& paramName);
|
||||
|
||||
|
||||
@@ -67,6 +67,26 @@ inline std::string PrintValue(const T& value, bool quotes)
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a vector parameter type, print the corresponding value.
|
||||
*/
|
||||
template<typename T>
|
||||
inline std::string PrintValue(const std::vector<T>& value, bool quotes)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
if (quotes)
|
||||
oss << "'";
|
||||
if (value.size() > 0)
|
||||
{
|
||||
oss << value[0];
|
||||
for (size_t i = 1; i < value.size(); ++i)
|
||||
oss << ", " << value[i];
|
||||
}
|
||||
if (quotes)
|
||||
oss << "'";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a parameter name, print its corresponding default value.
|
||||
*/
|
||||
@@ -138,8 +158,8 @@ std::string ProcessOptions(const std::string& paramName,
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Unknown parameter '" + paramName + "' " +
|
||||
"encountered while assembling documentation! Check PROGRAM_INFO() " +
|
||||
"declaration.");
|
||||
"encountered while assembling documentation! Check BINDING_LONG_DESC()"
|
||||
+ " and BINDING_EXAMPLE() declaration.");
|
||||
}
|
||||
|
||||
std::string rest = ProcessOptions(args...);
|
||||
@@ -229,8 +249,9 @@ inline std::string ProgramCall(const std::string& programName)
|
||||
/**
|
||||
* Print what a user would type to invoke the given option name. Note that the
|
||||
* name *must* exist in the CLI module. (Note that because of the way
|
||||
* ProgramInfo is structured, this doesn't mean that all of the PARAM_*()
|
||||
* declarataions need to come before the PROGRAM_INFO() declaration.)
|
||||
* BINDING_LONG_DESC() and BINDING_EXAMPLE() is structured, this doesn't mean
|
||||
* that all of the PARAM_*() declarataions need to come before
|
||||
* BINDING_LONG_DESC() and BINDING_EXAMPLE() declaration.)
|
||||
*/
|
||||
inline std::string ParamString(const std::string& paramName)
|
||||
{
|
||||
@@ -252,7 +273,7 @@ inline std::string ParamString(const std::string& paramName)
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("Parameter '" + paramName + "' not known! Check "
|
||||
"PROGRAM_INFO() definition.");
|
||||
"BINDING_LONG_DESC() and BINDING_EXAMPLE() definition.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,7 @@ void PrintHelp(const std::string& param)
|
||||
std::string usedParam = param;
|
||||
std::map<std::string, util::ParamData>& parameters = IO::Parameters();
|
||||
const std::map<char, std::string>& aliases = IO::Aliases();
|
||||
util::ProgramDoc& docs = *IO::GetSingleton().doc;
|
||||
|
||||
util::BindingDetails& bindingDetails = IO::GetSingleton().doc;
|
||||
// If we pass a single param, alias it if necessary.
|
||||
if (usedParam.length() == 1 && aliases.count(usedParam[0]))
|
||||
usedParam = aliases.at(usedParam[0]);
|
||||
@@ -64,11 +63,16 @@ void PrintHelp(const std::string& param)
|
||||
}
|
||||
|
||||
// Print out the descriptions.
|
||||
if (docs.programName != "")
|
||||
if (bindingDetails.programName != "")
|
||||
{
|
||||
std::cout << docs.programName << std::endl << std::endl;
|
||||
std::cout << " " << util::HyphenateString(docs.documentation(), 2)
|
||||
<< std::endl << std::endl;
|
||||
std::cout << bindingDetails.programName << std::endl << std::endl;
|
||||
std::cout << " " << util::HyphenateString(bindingDetails.longDescription(),
|
||||
2) << std::endl << std::endl;
|
||||
for (size_t j = 0; j < bindingDetails.example.size(); ++j)
|
||||
{
|
||||
std::cout << " " << util::HyphenateString(bindingDetails.example[j](), 2)
|
||||
<< std::endl << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
std::cout << "[undocumented program]" << std::endl << std::endl;
|
||||
|
||||
+275
-806
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,29 @@ macro (not_found_return message)
|
||||
endif()
|
||||
endmacro ()
|
||||
|
||||
macro (post_go_setup)
|
||||
if (BUILD_GO_BINDINGS)
|
||||
# Once `GO_MODELS` is populated, generate `models.go`.
|
||||
file(APPEND
|
||||
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/models.go"
|
||||
"*/\n"
|
||||
"import \"C\"\n\n"
|
||||
"import (\n"
|
||||
" \"runtime\"\n"
|
||||
" \"unsafe\"\n"
|
||||
")\n\n")
|
||||
|
||||
include("${CMAKE_SOURCE_DIR}/CMake/go/AppendModel.cmake")
|
||||
# Read list content.
|
||||
get_property(MODELS GLOBAL PROPERTY GO_MODELS)
|
||||
foreach (models IN LISTS MODELS)
|
||||
append_model(
|
||||
"${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/models.go"
|
||||
${models})
|
||||
endforeach()
|
||||
endif()
|
||||
endmacro ()
|
||||
|
||||
# If we are not supposed to make Go bindings, define the macro so it does
|
||||
# nothing and leave this file.
|
||||
if (NOT BUILD_GO_BINDINGS)
|
||||
@@ -16,34 +39,33 @@ if (NOT BUILD_GO_BINDINGS)
|
||||
endif ()
|
||||
|
||||
if (BUILD_GO_BINDINGS)
|
||||
|
||||
find_package(Go 1.11.0)
|
||||
if (NOT GO_FOUND)
|
||||
set(GO_NOT_FOUND_MSG "${GO_NOT_FOUND_MSG}\n - Go")
|
||||
endif ()
|
||||
find_package(Gonum)
|
||||
if (NOT GONUM_FOUND)
|
||||
set(GO_NOT_FOUND_MSG "${GO_NOT_FOUND_MSG}\n - Gonum")
|
||||
endif ()
|
||||
|
||||
## We need to check here if Golang 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_GO_BINDINGS)
|
||||
find_package(Go 1.11.0)
|
||||
find_package(Gonum)
|
||||
if (NOT GO_FOUND OR NOT GONUM_FOUND)
|
||||
unset(BUILD_GO_BINDINGS CACHE)
|
||||
set(BUILD_GO_SHLIB OFF)
|
||||
message(FATAL_ERROR "Go or Gonum not found; unable to build Go bindings!")
|
||||
message(FATAL_ERROR "\nCould not Build Go Bindings; the following modules are not available: ${GO_NOT_FOUND_MSG}")
|
||||
endif()
|
||||
else ()
|
||||
find_package(Go 1.11.0)
|
||||
find_package(Gonum)
|
||||
if (NOT GO_FOUND OR NOT GONUM_FOUND)
|
||||
unset(BUILD_GO_BINDINGS CACHE)
|
||||
set(BUILD_GO_SHLIB OFF)
|
||||
not_found_return("Not building Go bindings; the following modules are not available: ${GO_NOT_FOUND_MSG}")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if (NOT GO_FOUND)
|
||||
not_found_return("Go not found; not building Go bindings.")
|
||||
endif ()
|
||||
|
||||
if (NOT GONUM_FOUND)
|
||||
not_found_return("Gonum not found; not building Go bindings.")
|
||||
endif ()
|
||||
|
||||
add_custom_target(go)
|
||||
|
||||
# All the bindings will build under "src/mlpack.org/v1/mlpack"; So if user build
|
||||
@@ -81,7 +103,6 @@ if (BUILD_GO_SHLIB)
|
||||
print_method_config.hpp
|
||||
print_method_init.hpp
|
||||
print_output_processing.hpp
|
||||
camel_case.hpp
|
||||
strip_type.hpp
|
||||
)
|
||||
|
||||
@@ -146,12 +167,12 @@ if (BUILD_GO_SHLIB)
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
add_library(go_util SHARED
|
||||
add_library(mlpack_go_util SHARED
|
||||
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/mlpack/capi/arma_util.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/mlpack/capi/io_util.cpp)
|
||||
target_link_libraries(go_util mlpack ${MLPACK_LIBRARIES})
|
||||
target_compile_definitions(go_util PUBLIC "BINDING_TYPE=BINDING_TYPE_GO")
|
||||
set_target_properties(go_util PROPERTIES
|
||||
target_link_libraries(mlpack_go_util mlpack ${MLPACK_LIBRARIES})
|
||||
target_compile_definitions(mlpack_go_util PUBLIC "BINDING_TYPE=BINDING_TYPE_GO")
|
||||
set_target_properties(mlpack_go_util PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/)
|
||||
|
||||
# Set the include directories correctly.
|
||||
@@ -159,7 +180,7 @@ if (BUILD_GO_SHLIB)
|
||||
PROPERTY INCLUDE_DIRECTORIES)
|
||||
set (GO_INCLDIRS "${GO_INCLUDE_DIRECTORIES}")
|
||||
|
||||
install(TARGETS go_util
|
||||
install(TARGETS mlpack_go_util
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
@@ -178,7 +199,7 @@ set_property(GLOBAL PROPERTY GO_MODELS "")
|
||||
macro (add_go_binding name)
|
||||
if (BUILD_GO_BINDINGS)
|
||||
|
||||
# Include all .h that define model to models.go.
|
||||
# Include all .h that define model to models.go.
|
||||
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp" MAIN_FILE)
|
||||
if (MAIN_FILE MATCHES "PARAM_MODEL")
|
||||
file(APPEND
|
||||
@@ -195,6 +216,7 @@ if (BUILD_GO_BINDINGS)
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DPROGRAM_NAME=${name}
|
||||
-DPROGRAM_MAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp
|
||||
-DSOURCE_DIR=${CMAKE_SOURCE_DIR}
|
||||
-DGO_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/go_method.h.in
|
||||
-DGO_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/capi/${name}.h
|
||||
-P ${CMAKE_SOURCE_DIR}/CMake/go/ConfigureGoHCPP.cmake
|
||||
@@ -208,9 +230,9 @@ if (BUILD_GO_BINDINGS)
|
||||
-DGENERATE_CPP_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/generate_go_${name}.cpp
|
||||
-DPROGRAM_MAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp
|
||||
-DPROGRAM_NAME=${name}
|
||||
-P ${CMAKE_SOURCE_DIR}/CMake/ConfigureGenerate.cmake
|
||||
-P ${CMAKE_SOURCE_DIR}/CMake/ConfigureFile.cmake
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/generate_go.cpp.in
|
||||
${CMAKE_SOURCE_DIR}/CMake/ConfigureGenerate.cmake)
|
||||
${CMAKE_SOURCE_DIR}/CMake/ConfigureFile.cmake)
|
||||
|
||||
add_executable(generate_go_${name}
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/capi/${name}.h
|
||||
@@ -224,7 +246,7 @@ if (BUILD_GO_BINDINGS)
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DGENERATE_BINDING_PROGRAM=${CMAKE_BINARY_DIR}/bin/generate_go_${name}
|
||||
-DBINDING_OUTPUT_FILE=${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/${name}.go
|
||||
-P ${CMAKE_SOURCE_DIR}/CMake/GenerateGoBinding.cmake)
|
||||
-P ${CMAKE_SOURCE_DIR}/CMake/GenerateBinding.cmake)
|
||||
|
||||
add_dependencies(go generate_go_${name})
|
||||
endif ()
|
||||
@@ -236,6 +258,7 @@ if(BUILD_GO_SHLIB)
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DPROGRAM_NAME=${name}
|
||||
-DPROGRAM_MAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp
|
||||
-DSOURCE_DIR=${CMAKE_SOURCE_DIR}
|
||||
-DGO_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/go_method.cpp.in
|
||||
-DGO_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/build/${name}.cpp
|
||||
-P ${CMAKE_SOURCE_DIR}/CMake/go/ConfigureGoHCPP.cmake
|
||||
@@ -245,7 +268,7 @@ if(BUILD_GO_SHLIB)
|
||||
# Build libmlpack_go_${name}.so.
|
||||
add_library(mlpack_go_${name} SHARED
|
||||
${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/build/${name}.cpp)
|
||||
target_link_libraries(mlpack_go_${name} mlpack go_util)
|
||||
target_link_libraries(mlpack_go_${name} mlpack mlpack_go_util)
|
||||
set_target_properties(mlpack_go_${name} PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/")
|
||||
|
||||
@@ -256,7 +279,7 @@ if(BUILD_GO_SHLIB)
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
add_dependencies(mlpack_go_${name} go_copy)
|
||||
add_dependencies(mlpack_go_${name} go_util)
|
||||
add_dependencies(mlpack_go_${name} mlpack_go_util)
|
||||
add_dependencies(go_shlib mlpack_go_${name})
|
||||
|
||||
if (BUILD_GO_BINDINGS)
|
||||
|
||||
@@ -74,7 +74,7 @@ std::string DefaultParamImpl(
|
||||
|
||||
/**
|
||||
* Return the default value of an option. This is the function that will be
|
||||
* placed into the CLI functionMap.
|
||||
* placed into the IO functionMap.
|
||||
*/
|
||||
template<typename T>
|
||||
void DefaultParam(util::ParamData& data,
|
||||
|
||||
@@ -45,5 +45,5 @@ int main(int /* argc */, char** /* argv */)
|
||||
// programName is defined in mlpack_main.hpp.
|
||||
IO::RestoreSettings(programName);
|
||||
|
||||
PrintGo(*IO::GetSingleton().doc, "${PROGRAM_NAME}");
|
||||
PrintGo(IO::GetSingleton().doc, "${PROGRAM_NAME}");
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class GoOption
|
||||
public:
|
||||
/**
|
||||
* Construct a GoOption 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
|
||||
@@ -67,7 +67,7 @@ class GoOption
|
||||
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;
|
||||
@@ -117,7 +117,7 @@ class GoOption
|
||||
IO::GetSingleton().functionMap[data.tname]["GetType"] = &GetType<T>;
|
||||
|
||||
// Add the ParamData object, then store. This is necessary because we may
|
||||
// import more than one .so that uses CLI, so we have to keep the options
|
||||
// import more than one .so 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));
|
||||
if (identifier != "verbose" /*&& identifier != "copy_all_inputs"*/)
|
||||
|
||||
@@ -2,7 +2,7 @@ package mlpack
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -I. -I/capi -g -Wall -Wno-unused-variable
|
||||
#cgo LDFLAGS: -L. -lgo_util
|
||||
#cgo LDFLAGS: -L. -lmlpack_go_util
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <capi/io_util.h>
|
||||
|
||||
@@ -30,7 +30,7 @@ void mlpackToArmaMat(const char* identifier, double* mat,
|
||||
// Advanced constructor.
|
||||
arma::mat m(mat, row, col, false, true);
|
||||
|
||||
// Set input parameter with corresponding matrix in CLI.
|
||||
// Set input parameter with corresponding matrix in IO.
|
||||
SetParam(identifier, m);
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ void mlpackToArmaUmat(const char* identifier, double* mat,
|
||||
|
||||
arma::Mat<size_t> matr = arma::conv_to<arma::Mat<size_t>>::from(m);
|
||||
|
||||
// Set input parameter with corresponding matrix in CLI.
|
||||
// Set input parameter with corresponding matrix in IO.
|
||||
SetParam(identifier, matr);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ void mlpackToArmaRow(const char* identifier, double* rowvec, const size_t elem)
|
||||
// Advanced constructor.
|
||||
arma::rowvec m(rowvec, elem, false, true);
|
||||
|
||||
// Set input parameter with corresponding row in CLI.
|
||||
// Set input parameter with corresponding row in IO.
|
||||
SetParam(identifier, m);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ void mlpackToArmaUrow(const char* identifier, double* rowvec, const size_t elem)
|
||||
|
||||
arma::Row<size_t> matr = arma::conv_to<arma::Row<size_t>>::from(m);
|
||||
|
||||
// Set input parameter with corresponding row in CLI.
|
||||
// Set input parameter with corresponding row in IO.
|
||||
SetParam(identifier, matr);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ void mlpackToArmaCol(const char* identifier, double* colvec, const size_t elem)
|
||||
// Advanced constructor.
|
||||
arma::colvec m(colvec, elem, false, true);
|
||||
|
||||
// Set input parameter with corresponding column in CLI.
|
||||
// Set input parameter with corresponding column in IO.
|
||||
SetParam(identifier, m);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ void mlpackToArmaUcol(const char* identifier, double* colvec, const size_t elem)
|
||||
|
||||
arma::Col<size_t> matr = arma::conv_to<arma::Col<size_t>>::from(m);
|
||||
|
||||
// Set input parameter with corresponding column in CLI.
|
||||
// Set input parameter with corresponding column in IO.
|
||||
SetParam(identifier, matr);
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,11 @@ inline typename T::elem_type* GetMemory(T& m)
|
||||
else
|
||||
{
|
||||
arma::access::rw(m.mem_state) = 1;
|
||||
// With Armadillo 10 and newer, we must set `n_alloc` to 0 so that
|
||||
// Armadillo does not deallocate the memory.
|
||||
#if ARMA_VERSION_MAJOR >= 10
|
||||
arma::access::rw(m.n_alloc) = 0;
|
||||
#endif
|
||||
return m.memptr();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package mlpack
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -I. -I/capi -g -Wall
|
||||
#cgo LDFLAGS: -L${SRCDIR} -Wl,-rpath,${SRCDIR} -lgo_util
|
||||
#cgo LDFLAGS: -L${SRCDIR} -Wl,-rpath,${SRCDIR} -lmlpack_go_util
|
||||
#include <capi/io_util.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user