diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2c2142c..c2a109b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,4 +6,4 @@ add_executable(main main.cc STree.cc SVC.cc PyClassifier.cc PyWrap.cc) add_executable(example example.cpp PyWrap.cc) target_link_libraries(main ${Python3_LIBRARIES} "${TORCH_LIBRARIES}" ${LIBTORCH_PYTHON} Boost::boost Boost::python Boost::numpy ArffFiles) -target_link_libraries(example ${Python3_LIBRARIES} "${TORCH_LIBRARIES}" Boost::boost Boost::python Boost::numpy ArffFiles) +target_link_libraries(example ${Python3_LIBRARIES} "${TORCH_LIBRARIES}" ${LIBTORCH_PYTHON} Boost::boost Boost::python Boost::numpy ArffFiles) diff --git a/src/PyClassifier.cc b/src/PyClassifier.cc index 81f7b43..a97033f 100644 --- a/src/PyClassifier.cc +++ b/src/PyClassifier.cc @@ -54,10 +54,10 @@ namespace pywrap { { std::cout << "PyClassifier:fit:Converting X to PyObject" << std::endl; auto [Xn, yn] = tensors2numpy(X, y); - CPyObject Xp = Xn.ptr(); + CPyObject Xp = boost::python::incref(boost::python::object(Xn).ptr()); std::cout << "PyClassifier:fit:Converting y to PyObject" << std::endl; print_array(yn); - CPyObject yp = yn.ptr(); + CPyObject yp = boost::python::incref(boost::python::object(yn).ptr()); std::cout << "PyClassifier:fit:Calling fit" << std::endl; pyWrap->fit(module, this->className, Xp, yp); return *this; @@ -65,18 +65,18 @@ namespace pywrap { torch::Tensor PyClassifier::predict(torch::Tensor& X) { auto Xn = tensor2numpy(X); - print_array(Xn); - CPyObject Xp = Xn.ptr(); + CPyObject Xp = boost::python::incref(boost::python::object(Xn).ptr()); auto PyResult = pyWrap->predict(module, className, Xp); auto result = torch::tensor({ 1,2,3 }); + return result; } double PyClassifier::score(torch::Tensor& X, torch::Tensor& y) { std::cout << "PyClassifier::Score:Converting X to PyObject" << std::endl; auto [Xn, yn] = tensors2numpy(X, y); - CPyObject Xp = Xn.ptr(); - CPyObject yp = yn.ptr(); + CPyObject Xp = boost::python::incref(boost::python::object(Xn).ptr()); + CPyObject yp = boost::python::incref(boost::python::object(yn).ptr()); print_array(yn); auto result = pyWrap->score(module, className, Xp, yp); return result; diff --git a/src/PyClassifier.h b/src/PyClassifier.h index bdc6364..c777624 100644 --- a/src/PyClassifier.h +++ b/src/PyClassifier.h @@ -1,11 +1,12 @@ #ifndef PYCLASSIFER_H #define PYCLASSIFER_H +#include "boost/python/detail/wrap_python.hpp" +#include #include #include #include #include #include -#include #include "PyWrap.h" namespace pywrap { diff --git a/src/PyHelper.hpp b/src/PyHelper.hpp index 2404f6f..ea3f5df 100644 --- a/src/PyHelper.hpp +++ b/src/PyHelper.hpp @@ -3,9 +3,9 @@ #pragma once // Code taken and adapted from // https ://www.codeproject.com/Articles/820116/Embedding-Python-program-in-a-C-Cplusplus-code -#include -#include +#include "boost/python/detail/wrap_python.hpp" #include +#include namespace pywrap { namespace p = boost::python; diff --git a/src/PyWrap.h b/src/PyWrap.h index 0dfe02b..96edd79 100644 --- a/src/PyWrap.h +++ b/src/PyWrap.h @@ -1,6 +1,6 @@ #ifndef PYWRAP_H #define PYWRAP_H -#include +#include "boost/python/detail/wrap_python.hpp" #include #include #include diff --git a/src/example.cpp b/src/example.cpp index c2ae048..e60b8af 100644 --- a/src/example.cpp +++ b/src/example.cpp @@ -1,9 +1,11 @@ +#include "boost/python/detail/wrap_python.hpp" +#include #include +#include #include #include #include "ArffFiles.h" #include "PyHelper.hpp" -#include #include "PyWrap.h" @@ -128,24 +130,59 @@ int main(int argc, char** argv) { cout << "--Fit Phase--" << endl; auto [Xn, yn] = getData(dataset); - CPyObject Xp = Xn.ptr(); - CPyObject yp = yn.ptr(); + auto Xn_shapes = Xn.get_shape(); + auto yn_shapes = yn.get_shape(); + CPyObject Xp = boost::python::incref(boost::python::object(Xn).ptr()); + CPyObject yp = boost::python::incref(boost::python::object(yn).ptr()); + //print_array(yn); // Call fit cout << "Calling fit" << endl; wrapper->fit(moduleName, className, Xp, yp); cout << "--Fit Phase end--" << endl; } - // Call score + // Score { cout << "--Score Phase--" << endl; auto [Xn, yn] = getData(dataset); - CPyObject Xp = Xn.ptr(); - CPyObject yp = yn.ptr(); + auto Xn_shapes = Xn.get_shape(); + auto yn_shapes = yn.get_shape(); + CPyObject Xp = boost::python::incref(boost::python::object(Xn).ptr()); + CPyObject yp = boost::python::incref(boost::python::object(yn).ptr()); + //print_array(yn); + // Call score cout << "Calling score" << endl; - auto score = wrapper->score(moduleName, className, Xp, yp); - cout << "Score: " << score << endl; + auto result = wrapper->score(moduleName, className, Xp, yp); + cout << "Score: " << result << endl; cout << "--Score Phase end--" << endl; } + // Call score + // { + // np::initialize(); + // cout << "--Score Phase--" << endl; + // auto [X, y, featuresx, classNamex, statesx] = loadDataset(dataset, true); + // auto [Xn, yn] = tensors2numpy(X, y); + // auto Xn_shapes = Xn.get_shape(); + // auto yn_shapes = yn.get_shape(); + // cout << "Xn_shapes: " << Xn_shapes[0] << ", " << Xn_shapes[1] << endl; + // cout << "yn_shapes: " << yn_shapes[0] << endl; + // cout << "X shapes: " << X.sizes() << endl; + // cout << "y shapes: " << y.sizes() << endl; + // assert(Xn_shapes[0] == X.sizes()[0]); + // assert(Xn_shapes[1] == X.sizes()[1]); + // assert(yn_shapes[0] == y.sizes()[0]); + // CPyObject Xp = Xn.ptr(); + // CPyObject yp = yn.ptr(); + // print_array(yn); + // cout << "Calling score" << endl; + // auto instance = wrapper->getClass(moduleName, className); + // CPyObject result; + // if (!(result = PyObject_CallMethod(instance, "score", "OO", Xp.getObject(), yp.getObject()))) + // errorAbort("Couldn't call method score"); + // auto score = PyFloat_AsDouble(result); + // //auto score = wrapper->score(moduleName, className, Xp, yp); + // cout << "Score: " << score << endl; + // cout << "--Score Phase end--" << endl; + // } // Clean module { cout << "--Clean Phase--" << endl; diff --git a/src/main.cc b/src/main.cc index 977e963..e2d642a 100644 --- a/src/main.cc +++ b/src/main.cc @@ -40,27 +40,6 @@ tuple, string, map>> loadData return { Xd, torch::tensor(y, torch::kInt32), features, className, states }; } -// int main(int argc, char* argv[]) -// { -// auto [X, y, features, className, states] = loadDataset("iris", true); -// auto stree = pywrap::STree(); -// stree.version(); -// auto svc = pywrap::SVC(); -// svc.version(); -// cout << "Graph: " << stree.graph() << endl; -// stree.version(); -// cout << string(80, '-') << endl; -// cout << "X: " << X.sizes() << endl; -// cout << "y: " << y.sizes() << endl; -// auto result = stree.fit(X, y, features, className, states); -// result = svc.fit(X, y, features, className, states); -// cout << "Now calling score" << endl; -// // auto result1 = stree.score(X, y); -// // auto result2 = svc.score(X, y); -// // cout << "STree score " << result1 << endl; -// // cout << "SVC score " << result2 << endl; -// return 0; -// } int main(int argc, char* argv[]) { cout << "* Begin." << endl; @@ -68,17 +47,16 @@ int main(int argc, char* argv[]) auto [X, y, features, className, states] = loadDataset("iris", true); cout << "X: " << X.sizes() << endl; cout << "y: " << y.sizes() << endl; - cout << "y: " << y << endl; auto clf = pywrap::PyClassifier("stree", "Stree"); cout << "STree Version: " << clf.version() << endl; - // if (true) { - // auto svc = pywrap::PyClassifier("sklearn.svm", "SVC"); - // cout << "SVC Version: " << svc.callMethodString("_repr_html_") << endl; - // cout << "Calling fit" << endl; - // svc.fit(X, y, features, className, states); - // cout << "Calling score" << endl; - // cout << "SVC Score: " << svc.score(X, y) << endl; - // } + if (true) { + auto svc = pywrap::PyClassifier("sklearn.svm", "SVC"); + cout << "SVC Version: " << svc.callMethodString("_repr_html_") << endl; + cout << "Calling fit" << endl; + svc.fit(X, y, features, className, states); + cout << "Calling score" << endl; + cout << "SVC Score: " << svc.score(X, y) << endl; + } cout << "Graph: " << clf.graph() << endl; cout << "Calling fit" << endl; clf.fit(X, y, features, className, states);