diff --git a/CMakeLists.txt b/CMakeLists.txt index f3df747ea..4e189e1d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,9 @@ option(HERMES_ENABLE_MPIIO_ADAPTER "Build the Hermes MPI-IO adapter." ON) option(HERMES_ENABLE_PUBSUB_ADAPTER "Build the Hermes pub/sub adapter." OFF) option(HERMES_ENABLE_KVSTORE "Build the Hermes KVStore adapter." OFF) option(HERMES_ENABLE_VFD "Build the Hermes HDF5 Virtual File Driver" OFF) -option(HERMES_ENABLE_PYTHON "Build the Hermes Python wrapper" OFF) +option(HERMES_ENABLE_PYTHON "Build the Hermes Python wrapper" ON) + +message("HERMES_ENABLE_PYTHON: ${HERMES_ENABLE_PYTHON}") #----------------------------------------------------------------------------- # Compiler Optimization diff --git a/wrapper/CMakeLists.txt b/wrapper/CMakeLists.txt index 711dfa18b..082f8c4d6 100644 --- a/wrapper/CMakeLists.txt +++ b/wrapper/CMakeLists.txt @@ -2,5 +2,6 @@ cmake_minimum_required(VERSION 3.10) project(hermes) if (HERMES_ENABLE_PYTHON) + message("Python bindings enabled") add_subdirectory(python) endif() diff --git a/wrapper/python/cpp/CMakeLists.txt b/wrapper/python/cpp/CMakeLists.txt index d45903283..103c27142 100644 --- a/wrapper/python/cpp/CMakeLists.txt +++ b/wrapper/python/cpp/CMakeLists.txt @@ -5,17 +5,17 @@ # message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}") #------------------------------------------------------------------------------ -# Compile Python GL +# Compile Python Hermes #------------------------------------------------------------------------------ pybind11_add_module(py_hermes MODULE py_hermes.cpp) -add_dependencies(py_hermes ${Hermes_CLIENT_DEPS}) +add_dependencies(py_hermes ${Hermes_CLIENT_DEPS} hermes) target_link_libraries(py_hermes PUBLIC - ${Hermes_CLIENT_LIBRARIES} pybind11::module) + ${Hermes_CLIENT_LIBRARIES} hermes pybind11::module) #------------------------------------------------------------------------------ # Install Targets #------------------------------------------------------------------------------ install(TARGETS - hermes + py_hermes LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) \ No newline at end of file diff --git a/wrapper/python/cpp/py_hermes.cpp b/wrapper/python/cpp/py_hermes.cpp index 8889fb859..17e6a89fa 100644 --- a/wrapper/python/cpp/py_hermes.cpp +++ b/wrapper/python/cpp/py_hermes.cpp @@ -4,8 +4,116 @@ #include #include +#include +#include "hermes/hermes.h" +#include "hermes/bucket.h" namespace py = pybind11; +using hermes::BlobId; +using hermes::BucketId; +using hermes::TagId; +using hermes::TargetId; +using hermes::BlobInfo; +using hermes::TargetStats; +using hermes::TagInfo; +using hermes::MetadataTable; +using hermes::Hermes; +using hrun::UniqueId; + +bool TRANSPARENT_HERMES_FUN() { + if (TRANSPARENT_HRUN()) { + HERMES_CONF->ClientInit(); + return true; + } + return false; +} + +template +void BindUniqueId(py::module &m, const std::string &name) { + py::class_(m, name.c_str()) + .def(py::init<>()) + .def(py::init(), py::arg("node_id"), py::arg("unique")) + .def(py::init(), py::arg("node_id"), py::arg("hash"), py::arg("unique")) + .def("IsNull", &UniqueT::IsNull) + .def("GetNull", &UniqueT::GetNull) + .def("SetNull", &UniqueT::SetNull) + .def("GetNodeId", &UniqueT::GetNodeId) + .def("__eq__", &UniqueT::operator==) + .def("__ne__", &UniqueT::operator!=) + .def_readonly("node_id", &UniqueT::node_id_) + .def_readonly("hash", &UniqueT::hash_) + .def_readonly("unique", &UniqueT::unique_); +} + +void BindBlobInfo(py::module &m) { + py::class_(m, "BlobInfo") + .def(py::init<>()) + .def("UpdateWriteStats", &BlobInfo::UpdateWriteStats) + .def("UpdateReadStats", &BlobInfo::UpdateReadStats) + .def_readonly("tag_id", &BlobInfo::tag_id_) + .def_readonly("blob_id", &BlobInfo::blob_id_) + .def_readonly("name", &BlobInfo::name_) + .def_readonly("buffers", &BlobInfo::buffers_) + .def_readonly("tags", &BlobInfo::tags_) + .def_readonly("blob_size", &BlobInfo::blob_size_) + .def_readonly("max_blob_size", &BlobInfo::max_blob_size_) + .def_readonly("score", &BlobInfo::score_) + .def_readonly("access_freq", &BlobInfo::access_freq_) + .def_readonly("last_access", &BlobInfo::last_access_) + .def_readonly("mod_count", &BlobInfo::mod_count_) + .def_readonly("last_flush", &BlobInfo::last_flush_) + .def_static("GetTimeFromStartNs", &BlobInfo::GetTimeFromStartNs); +} + +void BindTargetStats(py::module &m) { + py::class_(m, "TargetStats") + .def(py::init<>()) + .def_readonly("tgt_id", &TargetStats::tgt_id_) + .def_readonly("rem_cap", &TargetStats::rem_cap_) + .def_readonly("max_cap", &TargetStats::max_cap_) + .def_readonly("bandwidth", &TargetStats::bandwidth_) + .def_readonly("latency", &TargetStats::latency_) + .def_readonly("score", &TargetStats::score_); +} + +void BindTagInfo(py::module &m) { + py::class_(m, "TagInfo") + .def(py::init<>()) + .def_readonly("tag_id", &TagInfo::tag_id_) + .def_readonly("name", &TagInfo::name_) + .def_readonly("blobs", &TagInfo::blobs_) + .def_readonly("traits", &TagInfo::traits_) + .def_readonly("internal_size", &TagInfo::internal_size_) + .def_readonly("page_size", &TagInfo::page_size_) + .def_readonly("owner", &TagInfo::owner_); +} + +void BindMetadataTable(py::module &m) { + py::class_(m, "MetadataTable") + .def(py::init<>()) + .def_readonly("blob_info", &MetadataTable::blob_info_) + .def_readonly("target_info", &MetadataTable::target_info_) + .def_readonly("bkt_info", &MetadataTable::bkt_info_); +} + +void BindHermes(py::module &m) { + py::class_(m, "Hermes") + .def(py::init<>()) + .def("ClientInit", &Hermes::ClientInit) + .def("IsInitialized", &Hermes::IsInitialized) + .def("GetTagId", &Hermes::GetTagId) + .def("CollectMetadataSnapshot", &Hermes::CollectMetadataSnapshot); + m.def("TRANSPARENT_HERMES", &TRANSPARENT_HERMES_FUN); +} + PYBIND11_MODULE(py_hermes, m) { + BindUniqueId(m, "BlobId"); + BindUniqueId(m, "BucketId"); + BindUniqueId(m, "TagId"); + BindUniqueId(m, "TargetId"); + BindBlobInfo(m); + BindTargetStats(m); + BindMetadataTable(m); + BindHermes(m); } diff --git a/wrapper/python/test/unit/test_hermes.py b/wrapper/python/test/unit/test_hermes.py index fb803fca4..1a66d462f 100644 --- a/wrapper/python/test/unit/test_hermes.py +++ b/wrapper/python/test/unit/test_hermes.py @@ -1,8 +1,9 @@ from unittest import TestCase -from py_hermes import Hermes, MetadataTable +import py_hermes +# from py_hermes import Hermes, MetadataTable import pathlib import os class TestHermes(TestCase): def test_metadata_query(self): - pass + print("HERE?")