From b072171333096d44ed8cd4462c8863bd2424a1cd Mon Sep 17 00:00:00 2001 From: Alexey Shlyonskikh Date: Mon, 3 Jun 2024 22:17:05 +0300 Subject: [PATCH 1/4] Clean empty log file from ELPP --- src/python_bindings/bindings.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/python_bindings/bindings.cpp b/src/python_bindings/bindings.cpp index c3c0ac798e..3ba72a3c39 100644 --- a/src/python_bindings/bindings.cpp +++ b/src/python_bindings/bindings.cpp @@ -29,9 +29,15 @@ PYBIND11_MODULE(desbordante, module) { if (std::filesystem::exists("logging.conf")) { el::Loggers::configureFromGlobal("logging.conf"); } else { + using std::filesystem::is_empty, std::filesystem::remove; el::Configurations conf; conf.set(el::Level::Global, el::ConfigurationType::Enabled, "false"); el::Loggers::reconfigureAllLoggers(conf); + try { + static constexpr auto kElppDefaultFile = "myeasylog.log"; + if (is_empty(kElppDefaultFile)) remove(kElppDefaultFile); + } catch (std::filesystem::filesystem_error&) { + } } for (auto bind_func : {BindMainClasses, BindDataTypes, BindFd, BindCfd, BindAr, BindUcc, BindAc, From 7ea4b8ef0135e76ac8013847d13063ed36ae76f2 Mon Sep 17 00:00:00 2001 From: Alexey Shlyonskikh Date: Mon, 3 Jun 2024 22:12:06 +0300 Subject: [PATCH 2/4] Rework Python modules AFD and PFD are now separate from FD, same for IND and AIND. More methods for `bind_primitive.h`. --- cli/cli.py | 6 +- src/python_bindings/ar/bind_ar.cpp | 8 +-- src/python_bindings/bindings.cpp | 7 +- src/python_bindings/fd/bind_fd.cpp | 71 ++++++++++--------- .../gfd/bind_gfd_verification.cpp | 2 +- src/python_bindings/ind/bind_ind.cpp | 38 ++++------ src/python_bindings/od/bind_od.cpp | 18 ++--- src/python_bindings/py_util/bind_primitive.h | 46 +++++++----- src/python_bindings/ucc/bind_ucc.cpp | 11 ++- 9 files changed, 102 insertions(+), 105 deletions(-) diff --git a/cli/cli.py b/cli/cli.py index b2ffc8a801..f31ab78b27 100644 --- a/cli/cli.py +++ b/cli/cli.py @@ -474,8 +474,8 @@ class Algorithm(StrEnum): } ALGOS = { - Algorithm.pyro: desbordante.fd.algorithms.Pyro, - Algorithm.tane: desbordante.fd.algorithms.Tane, + Algorithm.pyro: desbordante.afd.algorithms.Pyro, + Algorithm.tane: desbordante.afd.algorithms.Tane, Algorithm.pfdtane: desbordante.pfd.algorithms.PFDTane, Algorithm.hyfd: desbordante.fd.algorithms.HyFD, Algorithm.fd_mine: desbordante.fd.algorithms.FdMine, @@ -487,7 +487,7 @@ class Algorithm(StrEnum): Algorithm.aid: desbordante.fd.algorithms.Aid, Algorithm.fastod: desbordante.od.algorithms.Fastod, Algorithm.order: desbordante.od.algorithms.Order, - Algorithm.spider: desbordante.ind.algorithms.Spider, + Algorithm.spider: desbordante.aind.algorithms.Spider, Algorithm.faida: desbordante.ind.algorithms.Faida, Algorithm.fd_first: desbordante.cfd.algorithms.FDFirst, Algorithm.naive_fd_verifier: desbordante.fd_verification.algorithms.FDVerifier, diff --git a/src/python_bindings/ar/bind_ar.cpp b/src/python_bindings/ar/bind_ar.cpp index ff71b1a758..b87ef805fa 100644 --- a/src/python_bindings/ar/bind_ar.cpp +++ b/src/python_bindings/ar/bind_ar.cpp @@ -34,12 +34,6 @@ void BindAr(py::module_& main_module) { .def("get_itemnames", &ARAlgorithm::GetItemNamesVector) .def("get_ar_ids", &ARAlgorithm::GetArIDsList); - auto algos_module = ar_module.def_submodule("algorithms"); - auto default_algorithm = - detail::RegisterAlgorithm(algos_module, "Apriori"); - algos_module.attr("Default") = default_algorithm; - - // Perhaps in the future there will be a need for: - // default_algorithm.def("get_frequent_list", &Apriori::GetFrequentList); + BindAlgos(ar_module, {"Apriori"}); } } // namespace python_bindings diff --git a/src/python_bindings/bindings.cpp b/src/python_bindings/bindings.cpp index 3ba72a3c39..0e437315ae 100644 --- a/src/python_bindings/bindings.cpp +++ b/src/python_bindings/bindings.cpp @@ -40,9 +40,10 @@ PYBIND11_MODULE(desbordante, module) { } } - for (auto bind_func : {BindMainClasses, BindDataTypes, BindFd, BindCfd, BindAr, BindUcc, BindAc, - BindOd, BindFdVerification, BindMfdVerification, BindUccVerification, - BindStatistics, BindInd, BindGfdVerification, BindSplit}) { + for (auto bind_func : + {BindMainClasses, BindDataTypes, BindFd, BindCfd, BindAr, BindUcc, BindAc, BindOd, + BindFdVerification, BindMfdVerification, BindUccVerification, BindStatistics, BindInd, + BindGfdVerification, BindSplit}) { bind_func(module); } } diff --git a/src/python_bindings/fd/bind_fd.cpp b/src/python_bindings/fd/bind_fd.cpp index 609f7eb8d8..726024c6a3 100644 --- a/src/python_bindings/fd/bind_fd.cpp +++ b/src/python_bindings/fd/bind_fd.cpp @@ -33,44 +33,45 @@ namespace python_bindings { void BindFd(py::module_& main_module) { using namespace algos; + static constexpr auto kFdName = "FD"; + auto fd_module = main_module.def_submodule("fd"); - py::class_(fd_module, "FD") - .def("__str__", &FD::ToLongString) - .def("to_long_string", &FD::ToLongString) - .def("to_short_string", &FD::ToShortString) - .def("to_index_tuple", - [](FD const& fd) { - return py::make_tuple(VectorToTuple(fd.GetLhsIndices()), - std::move(fd.GetRhsIndex())); - }) - .def("to_name_tuple", MakeFdNameTuple) - // TODO: implement proper equality check for FD - .def("__eq__", [](FD const& fd1, - FD const& fd2) { return fd1.ToNameTuple() == fd2.ToNameTuple(); }) - .def("__hash__", [](FD const& fd) { return py::hash(MakeFdNameTuple(fd)); }) - .def_property_readonly("lhs_indices", &FD::GetLhsIndices) - .def_property_readonly("rhs_index", &FD::GetRhsIndex); + auto fd = py::class_(fd_module, kFdName) + .def("__str__", &FD::ToLongString) + .def("to_long_string", &FD::ToLongString) + .def("to_short_string", &FD::ToShortString) + .def("to_index_tuple", + [](FD const& fd) { + return py::make_tuple(VectorToTuple(fd.GetLhsIndices()), + std::move(fd.GetRhsIndex())); + }) + .def("to_name_tuple", MakeFdNameTuple) + // TODO: implement proper equality check for FD + .def("__eq__", + [](FD const& fd1, FD const& fd2) { + return fd1.ToNameTuple() == fd2.ToNameTuple(); + }) + .def("__hash__", [](FD const& fd) { return py::hash(MakeFdNameTuple(fd)); }) + .def_property_readonly("lhs_indices", &FD::GetLhsIndices) + .def_property_readonly("rhs_index", &FD::GetRhsIndex); - static constexpr auto kPyroName = "Pyro"; - static constexpr auto kTaneName = "Tane"; - static constexpr auto kPFDTaneName = "PFDTane"; - auto fd_algos_module = - BindPrimitive(fd_module, py::overload_cast<>(&FDAlgorithm::FdList, py::const_), - "FdAlgorithm", "get_fds", - {"HyFD", "Aid", "Depminer", "DFD", "FastFDs", "FDep", "FdMine", - "FUN", kPyroName, kTaneName, kPFDTaneName}); + BindPrimitive( + fd_module, py::overload_cast<>(&FDAlgorithm::FdList, py::const_), "FdAlgorithm", + "get_fds", {"HyFD", "Aid", "Depminer", "DFD", "FastFDs", "FDep", "FdMine", "FUN"}, + // TODO: make FDs properly copyable. + // NOTE: this breaks FD objects that were not created on the last run of FD search, but + // avoids UB when the last run's FDs are accessed after the FD algorithm is destroyed by + // preventing the algorithm object from being garbage collected. + py::return_value_policy::reference_internal); - auto define_submodule = [&fd_algos_module, &main_module](char const* name, - std::vector algorithms) { - auto algos_module = main_module.def_submodule(name).def_submodule("algorithms"); - for (auto algo_name : algorithms) { - algos_module.attr(algo_name) = fd_algos_module.attr(algo_name); - } - algos_module.attr("Default") = algos_module.attr(algorithms.front()); - }; + auto afd_module = main_module.def_submodule("afd"); + // NOTE: Currently there is no AFD class, using FD instead. + afd_module.attr(kFdName) = fd; + BindAlgos(afd_module, {"Pyro", "Tane"}); - define_submodule("afd", {kPyroName, kTaneName}); - define_submodule("pfd", {kPFDTaneName}); + auto pfd_module = main_module.def_submodule("pfd"); + // NOTE: Currently there is no PFD class, using FD instead. + pfd_module.attr(kFdName) = fd; + BindAlgos(pfd_module, {"PFDTane"}); } } // namespace python_bindings diff --git a/src/python_bindings/gfd/bind_gfd_verification.cpp b/src/python_bindings/gfd/bind_gfd_verification.cpp index 4361523e5a..94d91e7db8 100644 --- a/src/python_bindings/gfd/bind_gfd_verification.cpp +++ b/src/python_bindings/gfd/bind_gfd_verification.cpp @@ -20,6 +20,6 @@ void BindGfdVerification(pybind11::module_& main_module) { BindPrimitive( gfd_module, &GfdHandler::GfdList, "GfdAlgorithm", "get_gfds", - {"GfdValid", "EGfdValid", "NaiveGfdValid"}, py::return_value_policy::copy); + {"GfdValid", "EGfdValid", "NaiveGfdValid"}); } } // namespace python_bindings diff --git a/src/python_bindings/ind/bind_ind.cpp b/src/python_bindings/ind/bind_ind.cpp index e182a3848d..20c32e7e91 100644 --- a/src/python_bindings/ind/bind_ind.cpp +++ b/src/python_bindings/ind/bind_ind.cpp @@ -15,29 +15,21 @@ void BindInd(py::module_& main_module) { using namespace model; using namespace algos; + static constexpr auto kIndName = "IND"; + auto ind_module = main_module.def_submodule("ind"); - py::class_(ind_module, "IND") - .def("__str__", &IND::ToLongString) - .def("to_short_string", &IND::ToShortString) - .def("to_long_string", &IND::ToLongString) - .def("get_lhs", &IND::GetLhs) - .def("get_rhs", &IND::GetRhs); - - static constexpr auto kSpiderName = "Spider"; - static constexpr auto kMindName = "Mind"; - - auto ind_algos_module = - BindPrimitive(ind_module, &INDAlgorithm::INDList, "IndAlgorithm", - "get_inds", {kSpiderName, "Faida", kMindName}); - auto define_submodule = [&ind_algos_module, &main_module](char const* name, - std::vector algorithms) { - auto algos_module = main_module.def_submodule(name).def_submodule("algorithms"); - for (auto algo_name : algorithms) { - algos_module.attr(algo_name) = ind_algos_module.attr(algo_name); - } - algos_module.attr("Default") = algos_module.attr(algorithms.front()); - }; - - define_submodule("aind", {kSpiderName, kMindName}); + auto ind = py::class_(ind_module, kIndName) + .def("__str__", &IND::ToLongString) + .def("to_short_string", &IND::ToShortString) + .def("to_long_string", &IND::ToLongString) + .def("get_lhs", &IND::GetLhs) + .def("get_rhs", &IND::GetRhs); + + BindPrimitive(ind_module, &INDAlgorithm::INDList, "IndAlgorithm", "get_inds", {"Faida"}); + + auto aind_module = main_module.def_submodule("aind"); + // Currently there is no AIND primitive, using IND instead. + aind_module.attr(kIndName) = ind; + BindAlgos(aind_module, {"Spider", "Mind"}); } } // namespace python_bindings diff --git a/src/python_bindings/od/bind_od.cpp b/src/python_bindings/od/bind_od.cpp index 7d168acdd9..e72dae89cb 100644 --- a/src/python_bindings/od/bind_od.cpp +++ b/src/python_bindings/od/bind_od.cpp @@ -54,16 +54,12 @@ void BindOd(py::module_& main_module) { .def_readonly("lhs", &ListOD::lhs) .def_readonly("rhs", &ListOD::rhs); - static constexpr auto kFastodName = "Fastod"; - static constexpr auto kOrderName = "Order"; - - auto fastod_algos_module = - BindPrimitiveNoBase(od_module, "Fastod") - .def("get_asc_ods", &algos::Fastod::GetAscendingDependencies) - .def("get_desc_ods", &algos::Fastod::GetDescendingDependencies) - .def("get_simple_ods", &algos::Fastod::GetSimpleDependencies); - auto order_algos_module = - BindPrimitiveNoBase(od_module, "Order").def("get_list_ods", [](Order& algo) { + auto [fastod, od_algos_module] = BindNoBaseAndSetDefault(od_module, "Fastod"); + fastod.def("get_asc_ods", &algos::Fastod::GetAscendingDependencies) + .def("get_desc_ods", &algos::Fastod::GetDescendingDependencies) + .def("get_simple_ods", &algos::Fastod::GetSimpleDependencies); + detail::RegisterAlgorithm(od_algos_module, "Order") + .def("get_list_ods", [](Order& algo) { OrderDependencies const& map_res = algo.GetValidODs(); std::vector res; for (auto const& [lhs, rhs_list] : map_res) { @@ -73,8 +69,6 @@ void BindOd(py::module_& main_module) { } return res; }); - - main_module.attr("od_module") = od_module; } } // namespace python_bindings diff --git a/src/python_bindings/py_util/bind_primitive.h b/src/python_bindings/py_util/bind_primitive.h index 4389fbe921..fb5a5f38a7 100644 --- a/src/python_bindings/py_util/bind_primitive.h +++ b/src/python_bindings/py_util/bind_primitive.h @@ -48,15 +48,25 @@ template using MemberPointerClass = typename MemberPointerClassHelper::type; } // namespace detail +template +void BindAlgos(pybind11::module_& primitive_module, + std::array algo_names) { + auto algos_module = primitive_module.def_submodule("algorithms"); + auto arr_iter = algo_names.begin(); + auto default_algorithm = detail::RegisterAlgorithm(algos_module, *arr_iter++); + (detail::RegisterAlgorithm(algos_module, *arr_iter++), ...); + algos_module.attr("Default") = default_algorithm; +} + template -auto BindPrimitive(pybind11::module_& module, auto result_method, char const* base_name, - char const* base_result_method_name, - std::array algo_names, - // UB if incorrect. If your algorithm base method is a simple - // util::PrimitiveCollection<...>::AsList() call, the default should work, - // otherwise consult pybind11's docs. - pybind11::return_value_policy result_rv_policy = - pybind11::return_value_policy::reference_internal) { +void BindPrimitive( + pybind11::module_& module, auto result_method, char const* base_name, + char const* base_result_method_name, + std::array algo_names, + // If using the default, make sure your primitive's objects will not become invalid after + // the algorithm's object is destroyed (for example, if they contain a plain pointer to + // schema). If they cannot work without the algorithm's object, rework them. + pybind11::return_value_policy result_rv_policy = pybind11::return_value_policy::copy) { namespace py = pybind11; using algos::Algorithm; @@ -65,24 +75,24 @@ auto BindPrimitive(pybind11::module_& module, auto result_method, char const* ba using Base = detail::MemberPointerClass; py::class_(module, base_name) .def(base_result_method_name, result_method, result_rv_policy); - auto algos_module = module.def_submodule("algorithms"); - auto arr_iter = algo_names.begin(); - auto default_module = detail::RegisterAlgorithm(algos_module, *arr_iter++); - (detail::RegisterAlgorithm(algos_module, *arr_iter++), ...); - algos_module.attr("Default") = default_module; - return algos_module; + BindAlgos(module, std::move(algo_names)); } template -auto BindPrimitiveNoBase(pybind11::module_& module, char const* algo_name) { +auto BindNoBaseAndSetDefault(pybind11::module_& module, char const* algo_name) { namespace py = pybind11; using algos::Algorithm; auto algos_module = module.def_submodule("algorithms"); - auto default_module = + auto default_algorithm = detail::RegisterAlgorithm(algos_module, algo_name); - algos_module.attr("Default") = default_module; - return default_module; + algos_module.attr("Default") = default_algorithm; + return std::pair{default_algorithm, algos_module}; +} + +template +auto BindPrimitiveNoBase(pybind11::module_& module, char const* algo_name) { + return BindNoBaseAndSetDefault(module, algo_name).first; } } // namespace python_bindings diff --git a/src/python_bindings/ucc/bind_ucc.cpp b/src/python_bindings/ucc/bind_ucc.cpp index 517fca8e1f..f565f24b52 100644 --- a/src/python_bindings/ucc/bind_ucc.cpp +++ b/src/python_bindings/ucc/bind_ucc.cpp @@ -22,8 +22,13 @@ void BindUcc(py::module_& main_module) { py::class_(ucc_module, "UCC") .def("__str__", &UCC::ToIndicesString) .def_property_readonly("indices", &UCC::GetColumnIndicesAsVector); - BindPrimitive(ucc_module, - py::overload_cast<>(&UCCAlgorithm::UCCList, py::const_), - "UccAlgorithm", "get_uccs", {"HyUCC", "PyroUCC"}); + BindPrimitive( + ucc_module, py::overload_cast<>(&UCCAlgorithm::UCCList, py::const_), "UccAlgorithm", + "get_uccs", {"HyUCC", "PyroUCC"}, + // TODO: make UCCs independent of the algorithm. + // NOTE: a new run of the algorithm will break the previous run's UCCs with this RV + // policy. On the contrary, the algorithm's object will not be garbage collected (thus + // breaking all UCCs obtained from it) until all UCCs are. + py::return_value_policy::reference_internal); } } // namespace python_bindings From 4c15f0d584da01dcf012e693152fa0d293487086 Mon Sep 17 00:00:00 2001 From: Alexey Shlyonskikh Date: Wed, 5 Jun 2024 01:15:32 +0300 Subject: [PATCH 3/4] Rename data module --- cli/cli.py | 4 ++-- src/python_bindings/bindings.cpp | 4 ++-- .../data/{bind_data_types.cpp => bind_data.cpp} | 17 ++++++----------- .../data/{bind_data_types.h => bind_data.h} | 2 +- 4 files changed, 11 insertions(+), 16 deletions(-) rename src/python_bindings/data/{bind_data_types.cpp => bind_data.cpp} (59%) rename src/python_bindings/data/{bind_data_types.h => bind_data.h} (66%) diff --git a/cli/cli.py b/cli/cli.py index f31ab78b27..040e0231fd 100644 --- a/cli/cli.py +++ b/cli/cli.py @@ -756,13 +756,13 @@ def decorator(func: Callable) -> Callable: in option_type_info.items(): arg = f'--{opt_name}' if opt_main_type == list: - if opt_additional_types[0] == desbordante.data_types.Table: + if opt_additional_types[0] == desbordante.data.Table: click.option(arg, type=(str, str, bool), multiple=True)(func) else: click.option(arg, multiple=True, type=opt_additional_types[0])(func) - elif opt_main_type == desbordante.data_types.Table: + elif opt_main_type == desbordante.data.Table: click.option(arg, type=(str, str, bool))(func) else: click.option(arg, type=opt_main_type)(func) diff --git a/src/python_bindings/bindings.cpp b/src/python_bindings/bindings.cpp index 0e437315ae..f6e5d637b2 100644 --- a/src/python_bindings/bindings.cpp +++ b/src/python_bindings/bindings.cpp @@ -7,7 +7,7 @@ #include "ar/bind_ar.h" #include "bind_main_classes.h" #include "cfd/bind_cfd.h" -#include "data/bind_data_types.h" +#include "data/bind_data.h" #include "dd/bind_split.h" #include "fd/bind_fd.h" #include "fd/bind_fd_verification.h" @@ -41,7 +41,7 @@ PYBIND11_MODULE(desbordante, module) { } for (auto bind_func : - {BindMainClasses, BindDataTypes, BindFd, BindCfd, BindAr, BindUcc, BindAc, BindOd, + {BindMainClasses, BindDataModule, BindFd, BindCfd, BindAr, BindUcc, BindAc, BindOd, BindFdVerification, BindMfdVerification, BindUccVerification, BindStatistics, BindInd, BindGfdVerification, BindSplit}) { bind_func(module); diff --git a/src/python_bindings/data/bind_data_types.cpp b/src/python_bindings/data/bind_data.cpp similarity index 59% rename from src/python_bindings/data/bind_data_types.cpp rename to src/python_bindings/data/bind_data.cpp index 0ee22de4ff..0eeea3de62 100644 --- a/src/python_bindings/data/bind_data_types.cpp +++ b/src/python_bindings/data/bind_data.cpp @@ -1,4 +1,4 @@ -#include "bind_data_types.h" +#include "data/bind_data.h" #include #include @@ -6,19 +6,14 @@ #include "config/tabular_data/input_table_type.h" #include "model/table/column_combination.h" -namespace { namespace py = pybind11; -} // namespace namespace python_bindings { -void BindDataTypes(py::module_& main_module) { - auto data_module = main_module.def_submodule("data_types"); - data_module.doc() = R"doc( - Contains the types of data supported by Desbordante. - - Currently only used as tags for Algorithm.get_option_type - )doc"; - py::class_(data_module, "Table"); +void BindDataModule(py::module_& main_module) { + auto data_module = main_module.def_submodule("data"); + data_module.doc() = "Contains everything related to data itself."; + auto table_tag = py::class_(data_module, "Table"); + table_tag.doc() = "Tag type for tabular data."; using namespace model; py::class_(data_module, "ColumnCombination") diff --git a/src/python_bindings/data/bind_data_types.h b/src/python_bindings/data/bind_data.h similarity index 66% rename from src/python_bindings/data/bind_data_types.h rename to src/python_bindings/data/bind_data.h index d3a6b2d96e..addc2530a3 100644 --- a/src/python_bindings/data/bind_data_types.h +++ b/src/python_bindings/data/bind_data.h @@ -3,5 +3,5 @@ #include namespace python_bindings { -void BindDataTypes(pybind11::module_& main_module); +void BindDataModule(pybind11::module_& main_module); } // namespace python_bindings From 6d79e721949e844a98764ca24e447bd79a228975 Mon Sep 17 00:00:00 2001 From: Alexey Shlyonskikh Date: Mon, 3 Jun 2024 22:17:52 +0300 Subject: [PATCH 4/4] Cleanup in Python bindings and examples --- cli/cli.py | 3 ++- examples/comparison_pfd_vs_afd.py | 4 ++-- src/python_bindings/ac/bind_ac.cpp | 22 +++++++++---------- src/python_bindings/ar/bind_ar.cpp | 4 +--- src/python_bindings/bind_main_classes.cpp | 3 ++- src/python_bindings/dd/bind_split.cpp | 4 +--- src/python_bindings/fd/bind_fd.cpp | 8 +++++-- .../fd/bind_fd_verification.cpp | 6 ++--- .../gfd/bind_gfd_verification.cpp | 2 -- .../mfd/bind_mfd_verification.cpp | 4 +--- src/python_bindings/od/bind_od.cpp | 2 +- src/python_bindings/py_util/bind_primitive.h | 4 ++++ .../py_util/create_dataframe_reader.cpp | 5 ++++- .../py_util/create_dataframe_reader.h | 2 ++ .../py_util/dataframe_reader.cpp | 3 ++- .../py_util/dataframe_reader.h | 5 +++++ src/python_bindings/py_util/get_py_type.cpp | 3 ++- src/python_bindings/py_util/opt_to_py.cpp | 9 ++++++-- src/python_bindings/py_util/py_to_any.cpp | 11 ++++++++-- src/python_bindings/py_util/py_to_any.h | 3 +++ .../statistics/bind_statistics.cpp | 11 +++++++--- src/python_bindings/ucc/bind_ucc.cpp | 4 +--- .../ucc/bind_ucc_verification.cpp | 6 ++--- 23 files changed, 80 insertions(+), 48 deletions(-) diff --git a/cli/cli.py b/cli/cli.py index 040e0231fd..ded7a6adb7 100644 --- a/cli/cli.py +++ b/cli/cli.py @@ -469,7 +469,8 @@ class Algorithm(StrEnum): Algorithm.naive_ucc_verifier), Task.aucc_verification: TaskInfo([Algorithm.naive_aucc_verifier], Algorithm.naive_aucc_verifier), - Task.gfd_verification: TaskInfo([Algorithm.naive_gfd_verifier, Algorithm.gfd_verifier, Algorithm.egfd_verifier], + Task.gfd_verification: TaskInfo([Algorithm.naive_gfd_verifier, Algorithm.gfd_verifier, + Algorithm.egfd_verifier], Algorithm.naive_gfd_verifier), } diff --git a/examples/comparison_pfd_vs_afd.py b/examples/comparison_pfd_vs_afd.py index 07cfb7657d..3fe026ed77 100644 --- a/examples/comparison_pfd_vs_afd.py +++ b/examples/comparison_pfd_vs_afd.py @@ -26,8 +26,8 @@ def get_pfds(): pfds = set(get_pfds()) afds = set(get_afds()) -print("pFDs \ AFDs =", stringify(pfds - afds)) -print("AFDs \ pFDs =", stringify(afds - pfds)) +print("pFDs \\ AFDs =", stringify(pfds - afds)) +print("AFDs \\ pFDs =", stringify(afds - pfds)) print("AFDs ∩ pFDs =", stringify(afds & pfds)) print("1 - PerValue([DeviceId] -> Data) =", 0.1714285714) diff --git a/src/python_bindings/ac/bind_ac.cpp b/src/python_bindings/ac/bind_ac.cpp index 9255b57eb1..a3b276c292 100644 --- a/src/python_bindings/ac/bind_ac.cpp +++ b/src/python_bindings/ac/bind_ac.cpp @@ -1,4 +1,9 @@ -#include "bind_ac.h" +#include "ac/bind_ac.h" + +#include +#include +#include +#include #include #include @@ -7,9 +12,7 @@ #include "algorithms/algebraic_constraints/mining_algorithms.h" #include "py_util/bind_primitive.h" -namespace { namespace py = pybind11; -} // namespace namespace python_bindings { void BindAc(py::module_& main_module) { @@ -27,7 +30,7 @@ void BindAc(py::module_& main_module) { std::vector> res; res.reserve(ranges.ranges.size() / 2); assert(ranges.ranges.size() % 2 == 0); - for (size_t i = 0; i < ranges.ranges.size(); i += 2) { + for (std::size_t i = 0; i < ranges.ranges.size(); i += 2) { // TODO: change this once a proper conversion mechanism from // `model::INumericType` is implemented std::string l_endpoint = @@ -42,12 +45,9 @@ void BindAc(py::module_& main_module) { BindPrimitiveNoBase(ac_module, "AcAlgorithm") .def("get_ac_ranges", &ACAlgorithm::GetRangesCollections, py::return_value_policy::reference_internal) - .def( - "get_ac_exceptions", - [](ACAlgorithm& algo) { - algo.CollectACExceptions(); - return algo.GetACExceptions(); - }, - py::return_value_policy::reference_internal); + .def("get_ac_exceptions", [](ACAlgorithm& algo) { + algo.CollectACExceptions(); + return algo.GetACExceptions(); + }); } } // namespace python_bindings diff --git a/src/python_bindings/ar/bind_ar.cpp b/src/python_bindings/ar/bind_ar.cpp index b87ef805fa..3448fe618e 100644 --- a/src/python_bindings/ar/bind_ar.cpp +++ b/src/python_bindings/ar/bind_ar.cpp @@ -1,4 +1,4 @@ -#include "bind_ar.h" +#include "ar/bind_ar.h" #include #include @@ -7,9 +7,7 @@ #include "algorithms/association_rules/mining_algorithms.h" #include "py_util/bind_primitive.h" -namespace { namespace py = pybind11; -} // namespace namespace python_bindings { void BindAr(py::module_& main_module) { diff --git a/src/python_bindings/bind_main_classes.cpp b/src/python_bindings/bind_main_classes.cpp index 2f3ea88a16..948bc8a3a6 100644 --- a/src/python_bindings/bind_main_classes.cpp +++ b/src/python_bindings/bind_main_classes.cpp @@ -14,8 +14,9 @@ #include "py_util/opt_to_py.h" #include "py_util/py_to_any.h" -namespace { namespace py = pybind11; + +namespace { using algos::Algorithm; auto const kVoidIndex = std::type_index{typeid(void)}; diff --git a/src/python_bindings/dd/bind_split.cpp b/src/python_bindings/dd/bind_split.cpp index e31846e1ce..2fe07a84ea 100644 --- a/src/python_bindings/dd/bind_split.cpp +++ b/src/python_bindings/dd/bind_split.cpp @@ -1,4 +1,4 @@ -#include "bind_split.h" +#include "dd/bind_split.h" #include #include @@ -7,9 +7,7 @@ #include "algorithms/dd/mining_algorithms.h" #include "py_util/bind_primitive.h" -namespace { namespace py = pybind11; -} // namespace namespace python_bindings { void BindSplit(py::module_& main_module) { diff --git a/src/python_bindings/fd/bind_fd.cpp b/src/python_bindings/fd/bind_fd.cpp index 726024c6a3..1f8e4740ca 100644 --- a/src/python_bindings/fd/bind_fd.cpp +++ b/src/python_bindings/fd/bind_fd.cpp @@ -1,4 +1,8 @@ -#include "bind_fd.h" +#include "fd/bind_fd.h" + +#include +#include +#include #include #include @@ -10,9 +14,9 @@ #include "py_util/bind_primitive.h" #include "util/bitset_utils.h" -namespace { namespace py = pybind11; +namespace { template py::tuple VectorToTuple(std::vector vec) { std::size_t const size = vec.size(); diff --git a/src/python_bindings/fd/bind_fd_verification.cpp b/src/python_bindings/fd/bind_fd_verification.cpp index ca65c64236..ad63e62ad2 100644 --- a/src/python_bindings/fd/bind_fd_verification.cpp +++ b/src/python_bindings/fd/bind_fd_verification.cpp @@ -1,4 +1,4 @@ -#include "bind_fd_verification.h" +#include "fd/bind_fd_verification.h" #include #include @@ -8,9 +8,7 @@ #include "algorithms/fd/verification_algorithms.h" #include "py_util/bind_primitive.h" -namespace { namespace py = pybind11; -} // namespace namespace python_bindings { void BindFdVerification(pybind11::module_& main_module) { @@ -30,6 +28,8 @@ void BindFdVerification(pybind11::module_& main_module) { .def("get_num_error_rows", &FDVerifier::GetNumErrorRows) .def("get_highlights", &FDVerifier::GetHighlights); + // Create AFD verification module alias. We currently consider FD verification and AFD + // verification to be the same. main_module.attr("afd_verification") = fd_verification_module; } } // namespace python_bindings diff --git a/src/python_bindings/gfd/bind_gfd_verification.cpp b/src/python_bindings/gfd/bind_gfd_verification.cpp index 94d91e7db8..f9deff7027 100644 --- a/src/python_bindings/gfd/bind_gfd_verification.cpp +++ b/src/python_bindings/gfd/bind_gfd_verification.cpp @@ -6,9 +6,7 @@ #include "algorithms/gfd/verification_algorithms.h" #include "py_util/bind_primitive.h" -namespace { namespace py = pybind11; -} // namespace namespace python_bindings { void BindGfdVerification(pybind11::module_& main_module) { diff --git a/src/python_bindings/mfd/bind_mfd_verification.cpp b/src/python_bindings/mfd/bind_mfd_verification.cpp index 6e7d3bfd71..007b1b7ffa 100644 --- a/src/python_bindings/mfd/bind_mfd_verification.cpp +++ b/src/python_bindings/mfd/bind_mfd_verification.cpp @@ -1,4 +1,4 @@ -#include "bind_mfd_verification.h" +#include "mfd/bind_mfd_verification.h" #include #include @@ -7,9 +7,7 @@ #include "algorithms/metric/verification_algorithms.h" #include "py_util/bind_primitive.h" -namespace { namespace py = pybind11; -} // namespace namespace python_bindings { void BindMfdVerification(py::module_& main_module) { diff --git a/src/python_bindings/od/bind_od.cpp b/src/python_bindings/od/bind_od.cpp index e72dae89cb..167e8e598c 100644 --- a/src/python_bindings/od/bind_od.cpp +++ b/src/python_bindings/od/bind_od.cpp @@ -1,4 +1,4 @@ -#include "bind_od.h" +#include "od/bind_od.h" #include #include diff --git a/src/python_bindings/py_util/bind_primitive.h b/src/python_bindings/py_util/bind_primitive.h index fb5a5f38a7..5d4625b39c 100644 --- a/src/python_bindings/py_util/bind_primitive.h +++ b/src/python_bindings/py_util/bind_primitive.h @@ -2,7 +2,11 @@ #include #include +#include +#include +#include #include +#include #include diff --git a/src/python_bindings/py_util/create_dataframe_reader.cpp b/src/python_bindings/py_util/create_dataframe_reader.cpp index ce9e4c8127..41e5c05595 100644 --- a/src/python_bindings/py_util/create_dataframe_reader.cpp +++ b/src/python_bindings/py_util/create_dataframe_reader.cpp @@ -1,4 +1,7 @@ -#include "create_dataframe_reader.h" +#include "py_util/create_dataframe_reader.h" + +#include +#include #include "config/exceptions.h" #include "py_util/dataframe_reader.h" diff --git a/src/python_bindings/py_util/create_dataframe_reader.h b/src/python_bindings/py_util/create_dataframe_reader.h index 705a57be0c..f9a7e6259a 100644 --- a/src/python_bindings/py_util/create_dataframe_reader.h +++ b/src/python_bindings/py_util/create_dataframe_reader.h @@ -1,5 +1,7 @@ #pragma once +#include + #include #include "config/tabular_data/input_table_type.h" diff --git a/src/python_bindings/py_util/dataframe_reader.cpp b/src/python_bindings/py_util/dataframe_reader.cpp index 3013df0b57..33aa892a11 100644 --- a/src/python_bindings/py_util/dataframe_reader.cpp +++ b/src/python_bindings/py_util/dataframe_reader.cpp @@ -1,5 +1,6 @@ -#include "dataframe_reader.h" +#include "py_util/dataframe_reader.h" +#include #include #include #include diff --git a/src/python_bindings/py_util/dataframe_reader.h b/src/python_bindings/py_util/dataframe_reader.h index 00526305ba..2567959fb4 100644 --- a/src/python_bindings/py_util/dataframe_reader.h +++ b/src/python_bindings/py_util/dataframe_reader.h @@ -1,5 +1,10 @@ #pragma once +#include +#include +#include +#include + #include #include "model/table/idataset_stream.h" diff --git a/src/python_bindings/py_util/get_py_type.cpp b/src/python_bindings/py_util/get_py_type.cpp index 5255d7e59d..1461a81bda 100644 --- a/src/python_bindings/py_util/get_py_type.cpp +++ b/src/python_bindings/py_util/get_py_type.cpp @@ -1,4 +1,4 @@ -#include "get_py_type.h" +#include "py_util/get_py_type.h" #include #include @@ -6,6 +6,7 @@ #include #include +#include #include #include "algorithms/cfd/enums.h" diff --git a/src/python_bindings/py_util/opt_to_py.cpp b/src/python_bindings/py_util/opt_to_py.cpp index 71ba870752..3c9b39593a 100644 --- a/src/python_bindings/py_util/opt_to_py.cpp +++ b/src/python_bindings/py_util/opt_to_py.cpp @@ -1,9 +1,13 @@ -#include "opt_to_py.h" +#include "py_util/opt_to_py.h" #include +#include #include #include +#include +#include +#include #include #include "algorithms/metric/enums.h" @@ -14,8 +18,9 @@ #include "config/max_lhs/type.h" #include "config/thread_number/type.h" -namespace { namespace py = pybind11; + +namespace { using ConvFunction = std::function; template diff --git a/src/python_bindings/py_util/py_to_any.cpp b/src/python_bindings/py_util/py_to_any.cpp index d8eb12e923..88cf249262 100644 --- a/src/python_bindings/py_util/py_to_any.cpp +++ b/src/python_bindings/py_util/py_to_any.cpp @@ -1,5 +1,12 @@ +#include "py_util/py_to_any.h" + #include +#include +#include +#include +#include #include +#include #include #include @@ -19,9 +26,9 @@ #include "py_util/create_dataframe_reader.h" #include "util/enum_to_available_values.h" -namespace { - namespace py = pybind11; + +namespace { using ConvFunc = std::function; template diff --git a/src/python_bindings/py_util/py_to_any.h b/src/python_bindings/py_util/py_to_any.h index 3eece098ec..579cb49a05 100644 --- a/src/python_bindings/py_util/py_to_any.h +++ b/src/python_bindings/py_util/py_to_any.h @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include #include diff --git a/src/python_bindings/statistics/bind_statistics.cpp b/src/python_bindings/statistics/bind_statistics.cpp index 5a23403be0..62846dd6da 100644 --- a/src/python_bindings/statistics/bind_statistics.cpp +++ b/src/python_bindings/statistics/bind_statistics.cpp @@ -1,14 +1,19 @@ -#include "bind_statistics.h" +#include "statistics/bind_statistics.h" +#include +#include + +#include #include #include #include "algorithms/statistics/data_stats.h" +#include "algorithms/statistics/statistic.h" +#include "model/types/builtin.h" +#include "model/types/type.h" #include "py_util/bind_primitive.h" -namespace { namespace py = pybind11; -} // namespace namespace PYBIND11_NAMESPACE { namespace detail { diff --git a/src/python_bindings/ucc/bind_ucc.cpp b/src/python_bindings/ucc/bind_ucc.cpp index f565f24b52..50b2b90379 100644 --- a/src/python_bindings/ucc/bind_ucc.cpp +++ b/src/python_bindings/ucc/bind_ucc.cpp @@ -1,4 +1,4 @@ -#include "bind_ucc.h" +#include "ucc/bind_ucc.h" #include #include @@ -9,10 +9,8 @@ #include "py_util/bind_primitive.h" #include "util/bitset_utils.h" -namespace { namespace py = pybind11; using model::UCC; -} // namespace namespace python_bindings { void BindUcc(py::module_& main_module) { diff --git a/src/python_bindings/ucc/bind_ucc_verification.cpp b/src/python_bindings/ucc/bind_ucc_verification.cpp index e7e8646a7a..95013f2dbc 100644 --- a/src/python_bindings/ucc/bind_ucc_verification.cpp +++ b/src/python_bindings/ucc/bind_ucc_verification.cpp @@ -1,4 +1,4 @@ -#include "bind_ucc_verification.h" +#include "ucc/bind_ucc_verification.h" #include #include @@ -6,9 +6,7 @@ #include "algorithms/ucc/verification_algorithms.h" #include "py_util/bind_primitive.h" -namespace { namespace py = pybind11; -} // namespace namespace python_bindings { void BindUccVerification(pybind11::module_& main_module) { @@ -22,6 +20,8 @@ void BindUccVerification(pybind11::module_& main_module) { .def("get_num_rows_violating_ucc", &UCCVerifier::GetNumRowsViolatingUCC) .def("get_clusters_violating_ucc", &UCCVerifier::GetClustersViolatingUCC) .def("get_error", &UCCVerifier::GetError); + // Create AUCC verification module alias. We currently consider UCC verification and AUCC + // verification to be the same. main_module.attr("aucc_verification") = ucc_verification_module; } } // namespace python_bindings