diff --git a/.gitmodules b/.gitmodules index 4d3f6e99e3d9d4295085c1d11476978ae75f67e7..8c38c8a99db1173117058b2633fc1babc00c0800 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,24 +1,24 @@ [submodule "dep/lapack"] path = dep/lapack - url = https://git.rwth-aachen.de/avt.svt/public/thirdparty/lapack.git + url = https://git.rwth-aachen.de/avt-svt/public/thirdparty/lapack.git [submodule "dep/blas"] path = dep/blas - url = https://git.rwth-aachen.de/avt.svt/public/thirdparty/blas.git + url = https://git.rwth-aachen.de/avt-svt/public/thirdparty/blas.git [submodule "dep/cpplapack"] path = dep/cpplapack - url = https://git.rwth-aachen.de/avt.svt/public/thirdparty/cpplapack.git + url = https://git.rwth-aachen.de/avt-svt/public/thirdparty/cpplapack.git [submodule "dep/filib"] path = dep/filib - url = https://git.rwth-aachen.de/avt.svt/public/thirdparty/filib.git + url = https://git.rwth-aachen.de/avt-svt/public/thirdparty/filib.git [submodule "dep/fadbad"] path = dep/fadbad - url = https://git.rwth-aachen.de/avt.svt/public/thirdparty/fadbad.git + url = https://git.rwth-aachen.de/avt-svt/public/thirdparty/fadbad.git [submodule "dep/json"] path = dep/json - url = https://git.rwth-aachen.de/avt.svt/public/thirdparty/json.git + url = https://git.rwth-aachen.de/avt-svt/public/thirdparty/json.git [submodule "dep/pybind11"] path = dep/pybind11 url = https://github.com/pybind/pybind11 [submodule "dep/mcpp"] path = dep/mcpp - url = https://git.rwth-aachen.de/avt.svt/public/thirdparty/mcpp + url = https://git.rwth-aachen.de/avt-svt/public/thirdparty/mcpp.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 12a09499daeb52684f21abe5a07a49502c52352a..70c91bf2202a512ad26bc057d88f5f19e579b79d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,10 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(melon CXX) -set(MeLOn_build_python_interface FALSE CACHE BOOL "Build a dll and Python module called pymaingo for calling MAiNGO from Python.") +set(MeLOn_build_python_interface FALSE CACHE BOOL "Build the Python extension module 'melonpy' that allows to call MeLOn from Python.") +if(MeLOn_build_python_interface) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() add_library(melon INTERFACE) target_link_libraries(melon INTERFACE gp ffnet svm) @@ -42,6 +45,13 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) # Add python interface if(MeLOn_build_python_interface) + set(PYBIND11_FINDPYTHON FALSE CACHE BOOL "Whether to have pybind11 use FindPython") + if(SKBUILD) + set(Python_EXECUTABLE ${PYTHON_EXECUTABLE}) + set(Python_VERSION ${PYTHON_VERSION_STRING}) + set(Python_INCLUDE_DIRS ${PYTHON_INCLUDE_DIR}) + set(Python_LIBRARIES ${PYTHON_LIBRARY}) + endif() add_dependency_subdir(pybind11) endif() @@ -80,9 +90,13 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) endif() -# Add python interface +# --------------- Python interface --------------------------- if(MeLOn_build_python_interface) - pybind11_add_module(_pymelon common/src/pymelon.cpp) - set_target_properties(_pymelon PROPERTIES CXX_STANDARD 14) - target_link_libraries(_pymelon PRIVATE melon) + + # Create target for melonpy extension module + pybind11_add_module(melonpy common/src/melonpy.cpp) + target_compile_features(melonpy PRIVATE cxx_std_14) + target_link_libraries(melonpy PRIVATE melon) + target_compile_options(melonpy PRIVATE $<$<CXX_COMPILER_ID:AppleClang>: -fvisibility=default>) + endif() diff --git a/common/src/melonpy.cpp b/common/src/melonpy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf778778c038df80eb04988e7c3c26bbe9b74e88 --- /dev/null +++ b/common/src/melonpy.cpp @@ -0,0 +1,167 @@ +/********************************************************************************** + * Copyright (c) 2019 Process Systems Engineering (AVT.SVT), RWTH Aachen University + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + **********************************************************************************/ + +#include "gp.h" +#include "gpData.h" +#include "ffNet.h" +#include "svm.h" +#include "modelParser.h" +#include "ffunc.hpp" + +#include <pybind11/pybind11.h> +#include <pybind11/operators.h> +#include <pybind11/stl.h> + +namespace py = pybind11; + + +// Definition of the actual Python module called melonpy +PYBIND11_MODULE(melonpy, m) { + m.doc() = "MeLOn - Machine-Learning models for Optimization"; + + //---------------------------------------------------------------------------------------- + // MelonModel + //---------------------------------------------------------------------------------------- + + py::class_< melon::MelonModel<mc::FFVar>>(m, "MelonModel") + .def("load_model", py::overload_cast<std::string, std::string, melon::MODEL_FILE_TYPE>(&melon::MelonModel<mc::FFVar>::load_model)) + .def("load_model", py::overload_cast<std::string, melon::MODEL_FILE_TYPE>(&melon::MelonModel<mc::FFVar>::load_model)) + .def("load_model", py::overload_cast<std::shared_ptr<const ModelData>>(&melon::MelonModel<mc::FFVar>::load_model)); + + + // enums + + py::enum_<melon::SCALER_TYPE>(m, "SCALER_TYPE") + .value("IDENTIY", melon::SCALER_TYPE::IDENTITY) + .value("MINMAX", melon::SCALER_TYPE::MINMAX) + .value("STANDARD", melon::SCALER_TYPE::STANDARD) + .export_values(); + + py::enum_<melon::MODEL_FILE_TYPE>(m, "MODEL_FILE_TYPE") + .value("CSV", melon::MODEL_FILE_TYPE::CSV) + .value("XML", melon::MODEL_FILE_TYPE::XML) + .value("JSON", melon::MODEL_FILE_TYPE::JSON) + .export_values(); + + py::enum_<melon::SCALER_PARAMETER>(m, "SCALER_PARAMETER") + .value("LOWER_BOUNDS", melon::SCALER_PARAMETER::LOWER_BOUNDS) + .value("UPPER_BOUNDS", melon::SCALER_PARAMETER::UPPER_BOUNDS) + .value("STD_DEV", melon::SCALER_PARAMETER::STD_DEV) + .value("MEAN", melon::SCALER_PARAMETER::MEAN) + .value("SCALED_LOWER_BOUNDS", melon::SCALER_PARAMETER::SCALED_LOWER_BOUNDS) + .value("SCALED_UPPER_BOUNDS", melon::SCALER_PARAMETER::SCALED_UPPER_BOUNDS) + .export_values(); + + + // data + + py::class_<ModelData, std::shared_ptr<ModelData>>(m, "ModelData"); + + py::class_<melon::kernel::KernelData, std::shared_ptr<melon::kernel::KernelData>>(m, "KernelData") + .def(py::init<>()) + .def_readwrite("sf2", &melon::kernel::KernelData::sf2) + .def_readwrite("ell", &melon::kernel::KernelData::ell); + + py::class_<melon::ScalerData, std::shared_ptr<melon::ScalerData>>(m, "ScalerData") + .def(py::init<>()) + .def_readwrite("type", &melon::ScalerData::type) + .def_readwrite("parameters", &melon::ScalerData::parameters); + + + + //---------------------------------------------------------------------------------------- + // Gaussian process + //---------------------------------------------------------------------------------------- + + // model + + py::class_<melon::GaussianProcess<mc::FFVar>, melon::MelonModel<mc::FFVar> >(m, "GaussianProcess") + .def(py::init<>()) + .def(py::init <std::string >()) + .def(py::init< std::string, std::string >()) + .def("calculate_prediction_reduced_space", &melon::GaussianProcess<mc::FFVar>::calculate_prediction_reduced_space) + .def("calculate_variance_reduced_space", &melon::GaussianProcess<mc::FFVar>::calculate_variance_reduced_space) + .def("calculate_prediction_full_space", &melon::GaussianProcess<mc::FFVar>::calculate_prediction_full_space) + .def("calculate_variance_full_space", &melon::GaussianProcess<mc::FFVar>::calculate_variance_full_space) + .def("calculate_prediction_and_variance_full_space", &melon::GaussianProcess<mc::FFVar>::calculate_prediction_and_variance_full_space) + .def("get_input_dimension", &melon::GaussianProcess<mc::FFVar>::get_input_dimension) + .def("get_number_of_training_data_points", &melon::GaussianProcess<mc::FFVar>::get_number_of_training_data_points) + .def("get_minimum_of_training_data_outputs", &melon::GaussianProcess<mc::FFVar>::get_minimum_of_training_data_outputs) + .def("get_maximum_of_training_data_outputs", &melon::GaussianProcess<mc::FFVar>::get_maximum_of_training_data_outputs) + .def("get_number_of_full_space_variables_prediction", &melon::GaussianProcess<mc::FFVar>::get_number_of_full_space_variables_prediction) + .def("get_full_space_variables_prediction", &melon::GaussianProcess<mc::FFVar>::get_full_space_variables_prediction) + .def("get_number_of_full_space_variables_variance", &melon::GaussianProcess<mc::FFVar>::get_number_of_full_space_variables_variance) + .def("get_full_space_variables_variance", &melon::GaussianProcess<mc::FFVar>::get_full_space_variables_variance) + .def("get_number_of_full_space_variables_prediction_and_variance", &melon::GaussianProcess<mc::FFVar>::get_number_of_full_space_variables_prediction_and_variance) + .def("get_full_space_variables_prediction_and_variance", &melon::GaussianProcess<mc::FFVar>::get_full_space_variables_prediction_and_variance) + .def("get_observations", &melon::GaussianProcess<mc::FFVar>::get_observations) + .def("get_normalized_observations", &melon::GaussianProcess<mc::FFVar>::get_normalized_observations); + + + // data + + py::class_<melon::GPData, ModelData, std::shared_ptr<melon::GPData>>(m, "GPData") + .def(py::init<>()) + .def_readwrite("kernelData", &melon::GPData::kernelData) + .def_readwrite("nX", &melon::GPData::nX) + .def_readwrite("DX", &melon::GPData::DX) + .def_readwrite("DY", &melon::GPData::DY) + .def_readwrite("matern", &melon::GPData::matern) + .def_readwrite("inputScalerData", &melon::GPData::inputScalerData) + .def_readwrite("predictionScalerData", &melon::GPData::predictionScalerData) + .def_readwrite("X", &melon::GPData::X) + .def_readwrite("Y", &melon::GPData::Y) + .def_readwrite("K", &melon::GPData::K) + .def_readwrite("invK", &melon::GPData::invK) + .def_readwrite("stdOfOutput", &melon::GPData::stdOfOutput) + .def_readwrite("meanFunction", &melon::GPData::meanfunction); + + + //---------------------------------------------------------------------------------------- + // Feed forward network + //---------------------------------------------------------------------------------------- + py::class_<melon::FeedForwardNet<mc::FFVar>, melon::MelonModel<mc::FFVar> >(m, "FeedForwardNet") + .def(py::init<>()) + .def(py::init <std::string, melon::MODEL_FILE_TYPE >()) + .def(py::init< std::string, std::string, melon::MODEL_FILE_TYPE >()) + .def("calculate_prediction_reduced_space", &melon::FeedForwardNet<mc::FFVar>::calculate_prediction_reduced_space) + .def("calculate_prediction_full_space", &melon::FeedForwardNet<mc::FFVar>::calculate_prediction_full_space) + .def("set_tanh_formulation", &melon::FeedForwardNet<mc::FFVar>::set_tanh_formulation) + .def("get_number_of_full_space_variables", &melon::FeedForwardNet<mc::FFVar>::get_number_of_full_space_variables) + .def("get_full_space_variables", &melon::FeedForwardNet<mc::FFVar>::get_full_space_variables); + + py::enum_<melon::TANH_REFORMULATION>(m, "TANH_REFORMULATION") + .value("TANH_REF_0", melon::TANH_REFORMULATION::TANH_REF_0) + .value("TANH_REF1", melon::TANH_REFORMULATION::TANH_REF1) + .value("TANH_REF2", melon::TANH_REFORMULATION::TANH_REF2) + .value("TANH_REF3", melon::TANH_REFORMULATION::TANH_REF3) + .value("TANH_REF4", melon::TANH_REFORMULATION::TANH_REF4) + .export_values(); + + //---------------------------------------------------------------------------------------- + // Support vector machines + //---------------------------------------------------------------------------------------- + py::class_<melon::SupportVectorMachine<mc::FFVar>, melon::MelonModel<mc::FFVar> >(m, "SupportVectorMachine") + .def("calculate_prediction_reduced_space", &melon::SupportVectorMachine<mc::FFVar>::calculate_prediction_reduced_space) + .def("calculate_prediction_full_space", &melon::SupportVectorMachine<mc::FFVar>::calculate_prediction_full_space) + .def("get_number_of_full_space_variables", &melon::SupportVectorMachine<mc::FFVar>::get_number_of_full_space_variables) + .def("get_fullspace_variables", &melon::SupportVectorMachine<mc::FFVar>::get_fullspace_variables); + + py::class_<melon::SupportVectorRegression<mc::FFVar>, melon::SupportVectorMachine<mc::FFVar> >(m, "SupportVectorRegression") + .def(py::init<>()) + .def(py::init <std::string >()) + .def(py::init< std::string, std::string >()); + + py::class_<melon::SupportVectorMachineOneClass<mc::FFVar>, melon::SupportVectorMachine<mc::FFVar> >(m, "SupportVectorMachineOneClass") + .def(py::init<>()) + .def(py::init <std::string >()) + .def(py::init< std::string, std::string >()); +} diff --git a/dep/mcpp b/dep/mcpp index da5a2f227ef57f2d88654b30149636a0b1557085..dfbdc830edbd11afe31c4283020ecdb0683c3ee2 160000 --- a/dep/mcpp +++ b/dep/mcpp @@ -1 +1 @@ -Subproject commit da5a2f227ef57f2d88654b30149636a0b1557085 +Subproject commit dfbdc830edbd11afe31c4283020ecdb0683c3ee2