diff --git a/.ci/linux-steps.yaml b/.ci/linux-steps.yaml index 7fd0ab0ab5..0ae2eebee7 100644 --- a/.ci/linux-steps.yaml +++ b/.ci/linux-steps.yaml @@ -29,6 +29,8 @@ steps: 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 + go get -u -t gonum.org/v1/gonum/... + 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 @@ -43,8 +45,6 @@ steps: - 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) .. displayName: 'CMake' diff --git a/.ci/macos-steps.yaml b/.ci/macos-steps.yaml index b74dffc85f..771d6760fd 100644 --- a/.ci/macos-steps.yaml +++ b/.ci/macos-steps.yaml @@ -17,6 +17,8 @@ steps: pip install cython numpy pandas zipp configparser brew install openblas armadillo boost + go get -u -t gonum.org/v1/gonum/... + if [ "a$(julia.version)" != "a" ]; then brew cask install julia fi @@ -28,8 +30,6 @@ 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 .. displayName: 'CMake' diff --git a/CMake/ConfigureGoHCPP.cmake b/CMake/ConfigureGoHCPP.cmake deleted file mode 100644 index 0f241a149f..0000000000 --- a/CMake/ConfigureGoHCPP.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# ConfigureGoHCPP.cmake: generate an mlpack .h file for a Go 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. -# * GENERATE_GO_IN: path of the generate_go.cpp.in file. -# * GENERATE_GO_OUT: name of the output .go file. -# * GENERATE_CPP_IN: path of the generate_cpp.cpp.in file. -# * GENERATE_CPP_OUT: name of the output .cpp file. -# * GENERATE_H_IN: path of the generate_h.cpp.in file. -# * GENERATE_H_OUT: name of the output .h file. -configure_file("${GENERATE_BINDING_IN}" "${GENERATE_BINDING_OUT}") diff --git a/CMake/go/AppendModel.cmake b/CMake/go/AppendModel.cmake index 707a4e754e..bc31fef006 100644 --- a/CMake/go/AppendModel.cmake +++ b/CMake/go/AppendModel.cmake @@ -1,4 +1,4 @@ -# AppendModel.cmake: append model defination and gettter setter methods for +# AppendModel.cmake: append model definition and gettter setter methods for # mlpack model types to the existing file of models.go. # This function depends on the following variables being set: @@ -52,14 +52,14 @@ function(append_model SERIALIZATION_FILE PROGRAM_MAIN_FILE) foreach (INDEX RANGE ${LOOP_MAX}) list(GET MODEL_TYPES ${INDEX} MODEL_TYPE) list(GET MODEL_SAFE_TYPES ${INDEX} MODEL_SAFE_TYPE) - # Convert the model type similar to goStrippedType. + + # Convert the model type similar to goStrippedType(bindings/go/strip_type.hpp). string(LENGTH ${MODEL_SAFE_TYPE} NUM_MODEL_CHAR) if (${NUM_MODEL_CHAR} GREATER 0) math(EXPR LAST_CHAR_INDEX "${NUM_MODEL_CHAR}-1") set(BREAK 0) foreach (INDEX RANGE ${LAST_CHAR_INDEX}) - if ("${MODEL_SAFE_TYPE}" MATCHES "[^A-Z]") - else () + if (NOT "${MODEL_SAFE_TYPE}" MATCHES "[^A-Z]") string(TOLOWER ${MODEL_SAFE_TYPE} GOMODEL_SAFE_TYPE) break() endif() diff --git a/CMake/go/ConfigureGoHCPP.cmake b/CMake/go/ConfigureGoHCPP.cmake new file mode 100644 index 0000000000..cdf4a2df42 --- /dev/null +++ b/CMake/go/ConfigureGoHCPP.cmake @@ -0,0 +1,115 @@ +# ConfigureGoHCPP.cmake: generate an mlpack .h/.cpp file for a Go 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. +# * 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 () + +# Now, generate the definitions of the functions we need. +set(MODEL_PTR_DEFNS "") +set(MODEL_PTR_IMPLS "") +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) + + # Generate the definition. + set(MODEL_PTR_DEFNS "${MODEL_PTR_DEFNS} +// Set the pointer to a ${MODEL_TYPE} parameter. +extern void mlpackSet${MODEL_SAFE_TYPE}Ptr(const char* identifier, void* value); + +// Get the pointer to a ${MODEL_TYPE} parameter. +extern void* mlpackGet${MODEL_SAFE_TYPE}Ptr(const char* identifier); +" +) + + # Generate the implementation. + set(MODEL_PTR_IMPLS "${MODEL_PTR_IMPLS} +// Set the pointer to a ${MODEL_TYPE} parameter. +extern \"C\" void mlpackSet${MODEL_SAFE_TYPE}Ptr( + const char* identifier, + void* value) +{ + mlpack::util::SetParamPtr<${MODEL_TYPE}>(identifier, + static_cast<${MODEL_TYPE}*>(value)); +} + +// Get the pointer to a ${MODEL_TYPE} parameter. +extern \"C\" void *mlpackGet${MODEL_SAFE_TYPE}Ptr(const char* identifier) +{ + ${MODEL_TYPE} *modelptr = CLI::GetParam<${MODEL_TYPE}*>(identifier); + return modelptr; +} +") + endforeach () +endif() + +# Convert ${PROGRAM_NAME} from snake_case to CamelCase. +string(LENGTH ${PROGRAM_NAME} NUM_MODEL_CHAR) +if (${NUM_MODEL_CHAR} GREATER 0) + math(EXPR LAST_CHAR_INDEX "${NUM_MODEL_CHAR}-2") + string(SUBSTRING ${PROGRAM_NAME} "0" "1" MODEL_CHAR) + string(TOUPPER ${MODEL_CHAR} MODEL_CHAR) + string(APPEND GOPROGRAM_NAME ${MODEL_CHAR}) + foreach (INDEX0 RANGE ${LAST_CHAR_INDEX}) + math(EXPR INDEX0 "${INDEX0}+1") + math(EXPR INDEX1 "${INDEX0}+1") + math(EXPR INDEX2 "${INDEX0}-1") + string(SUBSTRING "${PROGRAM_NAME}" "${INDEX0}" "1" MODEL_CHAR1) + string(SUBSTRING "${PROGRAM_NAME}" "${INDEX1}" "1" MODEL_CHAR2) + string(SUBSTRING "${PROGRAM_NAME}" "${INDEX2}" "1" MODEL_CHAR3) + if ("${MODEL_CHAR1}" MATCHES "_") + string(TOUPPER ${MODEL_CHAR2} MODEL_CHAR2) + string(APPEND GOPROGRAM_NAME ${MODEL_CHAR2}) + set(INDEX0 ${INDEX1}) + elseif ("${MODEL_CHAR3}" MATCHES "_") + continue() + else() + string(APPEND GOPROGRAM_NAME ${MODEL_CHAR1}) + endif() + endforeach() +endif() + +# Now configure the files. +configure_file("${GO_IN}" "${GO_OUT}") diff --git a/doc/guide/go_quickstart.hpp b/doc/guide/go_quickstart.hpp index 66d22e30a8..b476d1d85d 100644 --- a/doc/guide/go_quickstart.hpp +++ b/doc/guide/go_quickstart.hpp @@ -41,7 +41,7 @@ You can copy-paste this code directly into main.go to run it. package main import ( - "github.com/mlpack.org/v1/mlpack" + "mlpack.org/v1/mlpack" "fmt" ) func main() { @@ -134,7 +134,7 @@ package main import ( "github.com/frictionlessdata/tableschema-go/csv" - "github.com/mlpack.org/v1/mlpack" + "mlpack.org/v1/mlpack" "gonum.org/v1/gonum/mat" "fmt" ) diff --git a/src/mlpack/bindings/go/CMakeLists.txt b/src/mlpack/bindings/go/CMakeLists.txt index d44a4d177d..c8de8bb76a 100644 --- a/src/mlpack/bindings/go/CMakeLists.txt +++ b/src/mlpack/bindings/go/CMakeLists.txt @@ -44,7 +44,8 @@ if (BUILD_GO_BINDINGS) add_custom_target(go) - # Create model.go with package defination. + # Create model.go with package definition. + # All the bindings will build under "src/mlpack.org/v1/mlpack". file(WRITE "${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/models.go" "package mlpack" @@ -65,8 +66,6 @@ if (BUILD_GO_SHLIB) mlpack/cli_util.h mlpack/cli_util.hpp print_class_defn.hpp - print_cpp.cpp - print_cpp.hpp print_defn_input.hpp print_defn_output.hpp print_doc.hpp @@ -74,8 +73,6 @@ if (BUILD_GO_SHLIB) print_doc_functions_impl.hpp print_go.hpp print_go.cpp - print_h.hpp - print_h.cpp print_input_processing.hpp print_method_config.hpp print_method_init.hpp @@ -188,40 +185,31 @@ if (BUILD_GO_BINDINGS) # Append content to the list. set_property(GLOBAL APPEND PROPERTY GO_MODELS ${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp) - # Create .h file for C API, e.g. pca.h. - add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/generate_h_${name}.cpp - COMMAND ${CMAKE_COMMAND} - -DGENERATE_BINDING_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/generate_h.cpp.in - -DGENERATE_BINDING_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/generate_h_${name}.cpp - -DPROGRAM_MAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp - -DPROGRAM_NAME=${name} - -P ${CMAKE_SOURCE_DIR}/CMake/ConfigureGoHCPP.cmake - DEPENDS ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/generate_h.cpp.in) - - add_executable(generate_h_${name} - ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/generate_h_${name}.cpp - ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/print_h.hpp - ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/print_h.cpp) - target_link_libraries(generate_h_${name} mlpack ${MLPACK_LIBRARIES}) - set_target_properties(generate_h_${name} PROPERTIES COMPILE_FLAGS - -DBINDING_TYPE=BINDING_TYPE_GO) - add_custom_command(TARGET generate_h_${name} POST_BUILD + # Create ${name}.h. + add_custom_command(OUTPUT + ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/capi/${name}.h COMMAND ${CMAKE_COMMAND} - -DGENERATE_BINDING_PROGRAM=${CMAKE_BINARY_DIR}/bin/generate_h_${name} - -DBINDING_OUTPUT_FILE=${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/capi/${name}.h - -P ${CMAKE_SOURCE_DIR}/CMake/GenerateGoBinding.cmake) + -DPROGRAM_NAME="${name}" + -DPROGRAM_MAIN_FILE="${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp" + -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 + DEPENDS ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/go_method.h.in + ${CMAKE_SOURCE_DIR}/CMake/go/ConfigureGoHCPP.cmake) # Create .go file, pca.go. add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/generate_go_${name}.cpp COMMAND ${CMAKE_COMMAND} - -DGENERATE_BINDING_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/generate_go.cpp.in - -DGENERATE_BINDING_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/generate_go_${name}.cpp + -DGENERATE_CPP_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/generate_go.cpp.in + -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/ConfigureGoHCPP.cmake - DEPENDS ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/generate_go.cpp.in) + -P ${CMAKE_SOURCE_DIR}/CMake/ConfigureGenerate.cmake + DEPENDS ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/generate_go.cpp.in + ${CMAKE_SOURCE_DIR}/CMake/ConfigureGenerate.cmake) add_executable(generate_go_${name} + ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/capi/${name}.h ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/generate_go_${name}.cpp ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/print_go.hpp ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/print_go.cpp) @@ -234,57 +222,41 @@ if (BUILD_GO_BINDINGS) -DBINDING_OUTPUT_FILE=${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/${name}.go -P ${CMAKE_SOURCE_DIR}/CMake/GenerateGoBinding.cmake) - add_dependencies(generate_h_${name} generate_go_${name}) - add_dependencies(go generate_h_${name}) + add_dependencies(go generate_go_${name}) endif () if(BUILD_GO_SHLIB) - # Create .cpp file for C API, e.g. pca.cpp. - add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/build/generate_cpp_${name}.cpp - COMMAND ${CMAKE_COMMAND} - -DGENERATE_BINDING_IN=${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/generate_cpp.cpp.in - -DGENERATE_BINDING_OUT=${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/build/generate_cpp_${name}.cpp - -DPROGRAM_MAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp - -DPROGRAM_NAME=${name} - -P ${CMAKE_SOURCE_DIR}/CMake/ConfigureGoHCPP.cmake - DEPENDS ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/generate_cpp.cpp.in) - - add_executable(generate_cpp_${name} - ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/build/generate_cpp_${name}.cpp - ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/print_cpp.hpp - ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/print_cpp.cpp) - target_link_libraries(generate_cpp_${name} mlpack ${MLPACK_LIBRARIES}) - set_target_properties(generate_cpp_${name} PROPERTIES COMPILE_FLAGS - -DBINDING_TYPE=BINDING_TYPE_GO) - add_custom_command(TARGET generate_cpp_${name} POST_BUILD + # Create ${name}.cpp. + add_custom_command(OUTPUT + ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/build/${name}.cpp COMMAND ${CMAKE_COMMAND} - -DGENERATE_BINDING_PROGRAM=${CMAKE_BINARY_DIR}/bin/generate_cpp_${name} - -DBINDING_OUTPUT_FILE=${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/build/${name}.cpp - -P ${CMAKE_SOURCE_DIR}/CMake/GenerateGoBinding.cmake) + -DPROGRAM_NAME="${name}" + -DPROGRAM_MAIN_FILE="${CMAKE_CURRENT_SOURCE_DIR}/${name}_main.cpp" + -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 + DEPENDS ${CMAKE_SOURCE_DIR}/src/mlpack/bindings/go/go_method.cpp.in + ${CMAKE_SOURCE_DIR}/CMake/go/ConfigureGoHCPP.cmake) - add_dependencies(generate_cpp_${name} go_copy) - - # Create, e.g., libmlpack_go_pca.so. + # Build libmlpack_go_${name}.so. add_library(mlpack_go_${name} SHARED ${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/build/${name}.cpp) - set_source_files_properties(${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/build/${name}.cpp - PROPERTIES GENERATED TRUE) - target_link_libraries(mlpack_go_${name} mlpack ${MLPACK_LIBRARIES}) - target_compile_definitions(mlpack_go_${name} PUBLIC "BINDING_TYPE=BINDING_TYPE_GO") + target_link_libraries(mlpack_go_${name} 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/) + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/src/mlpack/bindings/go/src/mlpack.org/v1/mlpack/") + install(TARGETS mlpack_go_${name} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}") - add_dependencies(mlpack_go_${name} generate_cpp_${name}) + add_dependencies(mlpack_go_${name} go_copy) add_dependencies(mlpack_go_${name} go_util) add_dependencies(go_shlib mlpack_go_${name}) if (BUILD_GO_BINDINGS) - add_dependencies(mlpack_go_${name} generate_h_${name}) + add_dependencies(mlpack_go_${name} generate_go_${name}) add_dependencies(go mlpack_go_${name}) endif() endif() diff --git a/src/mlpack/bindings/go/generate_cpp.cpp.in b/src/mlpack/bindings/go/generate_cpp.cpp.in deleted file mode 100644 index 9219d86ea8..0000000000 --- a/src/mlpack/bindings/go/generate_cpp.cpp.in +++ /dev/null @@ -1,49 +0,0 @@ -/* - * @file bindings/go/generate_cpp_${PROGRAM_NAME}.cpp - * @author Yasmine Dumouchel - * - * This is an automatically-generated file that is used to generate the .cpp - * files that are used for the Go bindings. This program will print the - * .cpp file on stdout when run and doesn't need any input parameters. - * - * The CMake variable ${PROGRAM_NAME} must be set for - * this to configure correctly. - * - * 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. - */ -#define BINDING_TYPE BINDING_TYPE_GO -// Disable debug output. -#ifdef DEBUG - #define HAD_DEBUG - #undef DEBUG -#endif -#include -#ifdef HAD_DEBUG - #undef HAD_DEBUG - #define DEBUG -#endif - -#include -#include -#include - -// This will include the ParamData options that are a part of the program. -#include <${PROGRAM_MAIN_FILE}> - -using namespace mlpack; -using namespace mlpack::bindings; -using namespace mlpack::bindings::go; -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. - CLI::RestoreSettings(programName); - - PrintCPP(*CLI::GetSingleton().doc, "${PROGRAM_MAIN_FILE}", "${PROGRAM_NAME}"); -} diff --git a/src/mlpack/bindings/go/generate_h.cpp.in b/src/mlpack/bindings/go/generate_h.cpp.in deleted file mode 100644 index ed616bd593..0000000000 --- a/src/mlpack/bindings/go/generate_h.cpp.in +++ /dev/null @@ -1,49 +0,0 @@ -/* - * @file bindings/go/generate_h_${PROGRAM_NAME}.cpp - * @author Yasmine Dumouchel - * - * This is an automatically-generated file that is used to generate the .h - * files that are used for the Go bindings. This program will print the - * .h file on stdout when run and doesn't need any input parameters. - * - * The CMake variable ${PROGRAM_NAME} must be set for - * this to configure correctly. - * - * 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. - */ -#define BINDING_TYPE BINDING_TYPE_GO -// Disable debug output. -#ifdef DEBUG - #define HAD_DEBUG - #undef DEBUG -#endif -#include -#ifdef HAD_DEBUG - #undef HAD_DEBUG - #define DEBUG -#endif - -#include -#include -#include - -// This will include the ParamData options that are a part of the program. -#include <${PROGRAM_MAIN_FILE}> - -using namespace mlpack; -using namespace mlpack::bindings; -using namespace mlpack::bindings::go; -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. - CLI::RestoreSettings(programName); - - PrintH(*CLI::GetSingleton().doc, "${PROGRAM_NAME}"); -} diff --git a/src/mlpack/bindings/go/go_method.cpp.in b/src/mlpack/bindings/go/go_method.cpp.in new file mode 100644 index 0000000000..6f3a4f463a --- /dev/null +++ b/src/mlpack/bindings/go/go_method.cpp.in @@ -0,0 +1,24 @@ +/** + * @file build/${PROGRAM_NAME}.cpp + * + * This is an autogenerated file containing implementations of C functions to be + * called by the Go ${PROGRAM_NAME} binding. + */ +#define BINDING_TYPE BINDING_TYPE_GO +#include <${PROGRAM_MAIN_FILE}> +#include + +static void ${GOPROGRAM_NAME}MlpackMain() +{ + mlpackMain(); +} + +extern "C" void mlpack${GOPROGRAM_NAME}() +{ + ${GOPROGRAM_NAME}MlpackMain(); +} + +// Any implementations of methods for dealing with model pointers will be put +// below this comment, if needed. +${MODEL_PTR_IMPLS} + diff --git a/src/mlpack/bindings/go/go_method.h.in b/src/mlpack/bindings/go/go_method.h.in new file mode 100644 index 0000000000..da269eff93 --- /dev/null +++ b/src/mlpack/bindings/go/go_method.h.in @@ -0,0 +1,28 @@ +/** + * @file capi/${PROGRAM_NAME}.h + * + * This is an autogenerated header file for functions specified to the %NAME% + * binding to be called by Go. + */ +#ifndef GO_${PROGRAM_NAME}_H +#define GO_${PROGRAM_NAME}_H + +#include + +#if defined(__cplusplus) || defined(c_plusplus) + +extern "C" +{ +#endif + +extern void mlpack${GOPROGRAM_NAME}(); + +// Any definitions of methods for dealing with model pointers will be put below +// this comment, if needed. +${MODEL_PTR_DEFNS} + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif diff --git a/src/mlpack/bindings/go/go_option.hpp b/src/mlpack/bindings/go/go_option.hpp index eeca90d060..fbc14de445 100644 --- a/src/mlpack/bindings/go/go_option.hpp +++ b/src/mlpack/bindings/go/go_option.hpp @@ -23,7 +23,6 @@ #include "print_input_processing.hpp" #include "print_method_config.hpp" #include "print_method_init.hpp" -#include "print_model_util.hpp" #include "print_output_processing.hpp" namespace mlpack { @@ -102,13 +101,6 @@ class GoOption CLI::GetSingleton().functionMap[data.tname]["DefaultParam"] = &DefaultParam; - - CLI::GetSingleton().functionMap[data.tname]["PrintModelUtilCPP"] = - &PrintModelUtilCPP; - CLI::GetSingleton().functionMap[data.tname]["PrintModelUtilH"] = - &PrintModelUtilH; - CLI::GetSingleton().functionMap[data.tname]["PrintModelUtilGo"] = - &PrintModelUtilGo; CLI::GetSingleton().functionMap[data.tname]["PrintDefnInput"] = &PrintDefnInput; CLI::GetSingleton().functionMap[data.tname]["PrintDefnOutput"] = diff --git a/src/mlpack/bindings/go/print_cpp.cpp b/src/mlpack/bindings/go/print_cpp.cpp deleted file mode 100644 index fc69c9ea84..0000000000 --- a/src/mlpack/bindings/go/print_cpp.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @file bindings/go/print_cpp.cpp - * @author Yasmine Dumouchel - * - * Implementation of function to generate a .cpp file given a list of parameters - * for the 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_cpp.hpp" -#include "camel_case.hpp" -#include -#include -#include - -using namespace mlpack::util; -using namespace std; - -namespace mlpack { -namespace bindings { -namespace go { - -/** - * Given a list of parameter definition and program documentation, print a - * generated .cpp file to stdout. - */ -void PrintCPP(const ProgramDoc& programInfo, - const string& mainFilename, - const string& functionName) -{ - // Restore parameters. - CLI::RestoreSettings(programInfo.programName); - - const std::map& parameters = CLI::Parameters(); - typedef std::map::const_iterator ParamIter; - - // First, we must generate the header comment and namespace. - cout << "#include <" << mainFilename << ">" << endl; - cout << "#include " << endl; - cout << endl; - cout << "using namespace mlpack;" << endl; - cout << "using namespace mlpack::util;" << endl; - cout << "using namespace std;" << endl; - cout << endl; - - // Then we must print utility function for model type parameters if needed. - for (ParamIter it = parameters.begin(); it != parameters.end(); ++it) - { - const util::ParamData& d = it->second; - if (d.input) - CLI::GetSingleton().functionMap[d.tname]["PrintModelUtilCPP"](d, - NULL, NULL); - } - - // Finally, we generate the wrapper function for mlpackMain(). - std::string goFunctionName = CamelCase(functionName, false); - cout << "static void " << goFunctionName << "MlpackMain()" << endl; - cout << "{" << endl; - cout << " " << "mlpackMain();" << endl; - cout << "}" << endl; - cout << endl; - cout << "extern \"C\" void mlpack" << goFunctionName << "()" << endl; - cout << "{" << endl; - cout << " " << goFunctionName << "MlpackMain();" << endl; - cout << "}" << endl; - cout << endl; -} - -} // namespace go -} // namespace bindings -} // namespace mlpack diff --git a/src/mlpack/bindings/go/print_cpp.hpp b/src/mlpack/bindings/go/print_cpp.hpp deleted file mode 100644 index bd0cd3bcfb..0000000000 --- a/src/mlpack/bindings/go/print_cpp.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file bindings/go/print_cpp.hpp - * @author Yasmine Dumouchel - * - * Given a list of ParamData structures, emit a .cpp file defining the - * Go 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_GO_PRINT_CPP_HPP -#define MLPACK_BINDINGS_GO_PRINT_CPP_HPP - -#include - -namespace mlpack { -namespace bindings { -namespace go { - -/** - * Given a list of parameter definition and program documentation, print a - * generated .cpp file to stdout. - */ -void PrintCPP(const util::ProgramDoc& programInfo, - const std::string& mainFilename, - const std::string& functionName); - - -} // namespace go -} // namespace bindings -} // namespace mlpack - -#endif diff --git a/src/mlpack/bindings/go/print_go.cpp b/src/mlpack/bindings/go/print_go.cpp index 3cb66f3f49..2b9a3f4732 100644 --- a/src/mlpack/bindings/go/print_go.cpp +++ b/src/mlpack/bindings/go/print_go.cpp @@ -122,15 +122,6 @@ void PrintGo(const util::ProgramDoc& programInfo, cout << "}" << endl; cout << endl; - // Then we must print utility function for model type parameters if needed. - for (ParamIter it = parameters.begin(); it != parameters.end(); ++it) - { - const util::ParamData& d = it->second; - if (d.input) - CLI::GetSingleton().functionMap[d.tname]["PrintModelUtilGo"](d, - NULL, NULL); - } - // Print the comment describing the function and its parameters. cout << "/*" << endl; cout << " " << HyphenateString(programInfo.documentation(), 2) << endl; diff --git a/src/mlpack/bindings/go/print_h.cpp b/src/mlpack/bindings/go/print_h.cpp deleted file mode 100644 index 087af1019d..0000000000 --- a/src/mlpack/bindings/go/print_h.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file bindings/go/print_h.cpp - * @author Yasmine Dumouchel - * - * Implementation of function to generate a .h file given a list of parameters - * for the 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_h.hpp" -#include "camel_case.hpp" -#include -#include -#include - -using namespace mlpack::util; -using namespace std; - -namespace mlpack { -namespace bindings { -namespace go { - -/** - * Given a list of parameter definition and program documentation, print a - * generated .h file to stdout. - * - * @param programInfo Documentation for the program. - * @param functionName Name of the function (i.e. "pca"). - */ -void PrintH(const util::ProgramDoc& programInfo, - const std::string& functionName) -{ - // Restore parameters. - CLI::RestoreSettings(programInfo.programName); - - const std::map& parameters = CLI::Parameters(); - typedef std::map::const_iterator ParamIter; - - // First, we must generate the header comment and namespace. - cout << "#include " << endl; - cout << "#include " << endl; - cout << endl; - cout << "#if defined(__cplusplus) || defined(c_plusplus)" << endl; - cout << "extern \"C\" {" << endl; - cout << "#endif" << endl; - cout << endl; - - // Then we must print utility function for model type parameters if needed. - for (ParamIter it = parameters.begin(); it != parameters.end(); ++it) - { - const util::ParamData& d = it->second; - if (d.input) - CLI::GetSingleton().functionMap[d.tname]["PrintModelUtilH"](d, - NULL, NULL); - } - - std::string goFunctionName = CamelCase(functionName, false); - // We generate the wrapper function for mlpackMain(). - cout << "extern void mlpack" << goFunctionName << "();" << endl; - cout << endl; - - // Finally we close print the closing bracket for extern C. - cout << "#if defined(__cplusplus) || defined(c_plusplus)" << endl; - cout << "}" << endl; - cout << "#endif" << endl; -} - -} // namespace go -} // namespace bindings -} // namespace mlpack diff --git a/src/mlpack/bindings/go/print_h.hpp b/src/mlpack/bindings/go/print_h.hpp deleted file mode 100644 index ea773e3878..0000000000 --- a/src/mlpack/bindings/go/print_h.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @file bindings/go/print_h.hpp - * @author Yasmine Dumouchel - * - * Given a list of ParamData structures, emit a .h file defining the - * Go 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_GO_PRINT_H_HPP -#define MLPACK_BINDINGS_GO_PRINT_H_HPP - -#include - -namespace mlpack { -namespace bindings { -namespace go { - -/** - * Given a list of parameter definition and program documentation, print a - * generated .h file to stdout. - * - * @param programInfo Documentation for the program. - * @param functionName Name of the function (i.e. "pca"). - */ -void PrintH(const util::ProgramDoc& programInfo, - const std::string& functionName); - - -} // namespace go -} // namespace bindings -} // namespace mlpack - -#endif diff --git a/src/mlpack/bindings/go/print_model_util.hpp b/src/mlpack/bindings/go/print_model_util.hpp deleted file mode 100644 index 35cae4e024..0000000000 --- a/src/mlpack/bindings/go/print_model_util.hpp +++ /dev/null @@ -1,292 +0,0 @@ -/** - * @file bindings/go/print_model_util.hpp - * @author Yasmine Dumouchel - * - * Print the functions and structs associated with serializable model. - * for generating the .cpp, .h, and .go 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_GO_PRINT_CLASS_DEFN_HPP -#define MLPACK_BINDINGS_GO_PRINT_CLASS_DEFN_HPP - -#include "strip_type.hpp" - -namespace mlpack { -namespace bindings { -namespace go { - -/** - * Non-serializable models don't require any special definitions, so this prints - * nothing. - */ -template -void PrintModelUtilCPP( - const util::ParamData& /* d */, - const typename boost::disable_if>::type* = 0, - const typename boost::disable_if>::type* = 0, - const typename boost::disable_if>>::type* = 0) -{ - // Do nothing. -} - -/** - * Matrices don't require any special definitions, so this prints nothing. - */ -template -void PrintModelUtilCPP( - const util::ParamData& /* d */, - const typename boost::enable_if>::type* = 0) -{ - // Do nothing. -} - -/** - * Matrices with Info don't require any special definitions, so this prints nothing. - */ -template -void PrintModelUtilCPP( - const util::ParamData& /* d */, - const typename boost::enable_if>>::type* = 0) -{ - // Do nothing. -} - -/** - * Serializable models require a special class definition. - */ -template -void PrintModelUtilCPP( - const util::ParamData& d, - const typename boost::disable_if>::type* = 0, - const typename boost::enable_if>::type* = 0) -{ - // First, we have to parse the type. If we have something like, e.g., - // 'LogisticRegression<>', we must convert this to 'LogisticRegression[].' - std::string goStrippedType, strippedType, printedType, defaultsType; - StripType(d.cppType, goStrippedType, strippedType, printedType, defaultsType); - /** - * This gives us code like: - * - * extern "C" void mlpackSet\Ptr( - * const char* identifier, - * void *value) - * { - * SetParamPtr\(identifier, - * static_cast\*(value)); - * } - * - */ - std::cout << "extern \"C\" void mlpackSet" << strippedType - << "Ptr(" << std::endl; - std::cout << " const char* identifier, " << std::endl; - std::cout << " void* value)" << std::endl; - std::cout << "{" << std::endl; - std::cout << " SetParamPtr<" << printedType - << ">(identifier," << std::endl; - std::cout << " static_cast<" << printedType - << "*>(value));" << std::endl; - std::cout << "}" << std::endl; - std::cout << std::endl; - - /** - * This gives us code like: - * - * extern "C" void *mlpackGet\Ptr(const char* identifier) - * { - * \ *modelptr = GetParamPtr\(identifier); - * return modelptr; - * } - * - */ - std::cout << "extern \"C\" void *mlpackGet" << strippedType - << "Ptr(const char* identifier)" << std::endl; - std::cout << "{" << std::endl; - std::cout << " " << printedType << " *modelptr = GetParamPtr<" - << printedType << ">(identifier);" << std::endl; - std::cout << " return modelptr;" << std::endl; - std::cout << "}" << std::endl; - std::cout << std::endl; -} - -/** - * Print the function to set and get serialization models from Go to mlpack. - * - * @param d Parameter data. - * @param * (input) Unused parameter. - * @param * (output) Unused parameter. - */ -template -void PrintModelUtilCPP(const util::ParamData& d, - const void* /* input */, - void* /* output */) -{ - PrintModelUtilCPP::type>(d); -} - - -/** - * Non-serializable models don't require any special definitions, so this prints - * nothing. - */ -template -void PrintModelUtilH( - const util::ParamData& /* d */, - const typename boost::disable_if>::type* = 0, - const typename boost::disable_if>::type* = 0, - const typename boost::disable_if>>::type* = 0) - -{ - // Do nothing. -} - -/** - * Matrices don't require any special definitions, so this prints nothing. - */ -template -void PrintModelUtilH( - const util::ParamData& /* d */, - const typename boost::enable_if>::type* = 0) -{ - // Do nothing. -} - -/** - * Matrices with Info don't require any special definitions, so this prints nothing. - */ -template -void PrintModelUtilH( - const util::ParamData& /* d */, - const typename boost::enable_if>>::type* = 0) -{ - // Do nothing. -} - -/** - * Serializable models require a special class definition. - */ -template -void PrintModelUtilH( - const util::ParamData& d, - const typename boost::disable_if>::type* = 0, - const typename boost::enable_if>::type* = 0) -{ - // First, we have to parse the type. If we have something like, e.g., - // 'LogisticRegression<>', we must convert this to 'LogisticRegression[].' - std::string goStrippedType, strippedType, printedType, defaultsType; - StripType(d.cppType, goStrippedType, strippedType, printedType, defaultsType); - - /** - * This gives us code like: - * - * extern void *mlpackSet\Ptr(const char* identifier, void* value); - * - */ - std::cout << "extern void mlpackSet" << strippedType - << "Ptr(const char* identifier, void* value);" << std::endl; - std::cout << std::endl; - - /** - * This gives us code like: - * - * extern void *mlpackGet\Ptr(const char* identifier); - * - */ - std::cout << "extern void *mlpackGet" << strippedType - << "Ptr(const char* identifier);" << std::endl; - std::cout << std::endl; -} - -/** - * Print the function to set and get serialization models from Go to mlpack. - * - * @param d Parameter data. - * @param * (input) Unused parameter. - * @param * (output) Unused parameter. - */ -template -void PrintModelUtilH(const util::ParamData& d, - const void* /* input */, - void* /* output */) -{ - PrintModelUtilH::type>(d); -} - -/** - * Non-serializable models don't require any special definitions, so this prints - * nothing. - */ -template -void PrintModelUtilGo( - const util::ParamData& /* d */, - const typename boost::disable_if>::type* = 0, - const typename boost::disable_if>::type* = 0, - const typename boost::disable_if>>::type* = 0) -{ - // Do nothing. -} - -/** - * Matrices don't require any special definitions, so this prints nothing. - */ -template -void PrintModelUtilGo( - const util::ParamData& /* d */, - const typename boost::enable_if>::type* = 0) -{ - // Do nothing. -} - -/** - * Matrices with Info don't require any special definitions, so this prints nothing. - */ -template -void PrintModelUtilGo( - const util::ParamData& /* d */, - const typename boost::enable_if>>::type* = 0) -{ - // Do nothing. -} - -/** - * Serializable models require a special class definition. - */ -template -void PrintModelUtilGo( - const util::ParamData& /* d */, - const typename boost::disable_if>::type* = 0, - const typename boost::enable_if>::type* = 0) -{ - // Do nothing. -} - -/** - * Print the Go struct for Go serialization model and their associated - * set and get methods. - * - * @param d Parameter data. - * @param * (input) Unused parameter. - * @param * (output) Unused parameter. - */ -template -void PrintModelUtilGo(const util::ParamData& d, - const void* /* input */, - void* /* output */) -{ - PrintModelUtilGo::type>(d); -} - -} // namespace go -} // namespace bindings -} // namespace mlpack - -#endif