Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions python/mori/umbp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,36 @@ def _configure_packaged_umbp_master() -> None:
os.environ["UMBP_MASTER_BIN"] = str(master_path)


def _configure_packaged_umbp_standalone_server() -> None:
if os.environ.get("UMBP_STANDALONE_BIN"):
return

server_path = Path(__file__).resolve().parents[1] / "umbp_standalone_server"
if not server_path.is_file():
return

try:
mode = server_path.stat().st_mode
exec_bits = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
if (mode & exec_bits) != exec_bits:
server_path.chmod(mode | exec_bits)
except OSError:
pass

if os.access(server_path, os.X_OK):
os.environ["UMBP_STANDALONE_BIN"] = str(server_path)


_configure_packaged_spdk_proxy()
_configure_packaged_umbp_master()
_configure_packaged_umbp_standalone_server()

from mori.cpp import (
CacheRemoteAdmission,
UMBPClient,
UMBPConfig,
UMBPCopyPipelineConfig,
UMBPDeploymentMode,
UMBPDistributedConfig,
UMBPDramConfig,
UMBPDurabilityMode,
Expand All @@ -84,6 +106,7 @@ def _configure_packaged_umbp_master() -> None:
UMBPIoBackend,
UMBPIoConfig,
UMBPRole,
UMBPStandaloneProcessConfig,
UMBPSsdConfig,
UMBPEvictionConfig,
UMBPDurabilityConfig,
Expand All @@ -97,6 +120,7 @@ def _configure_packaged_umbp_master() -> None:
"UMBPClient",
"UMBPConfig",
"UMBPCopyPipelineConfig",
"UMBPDeploymentMode",
"UMBPDistributedConfig",
"UMBPDramConfig",
"UMBPDurabilityConfig",
Expand All @@ -107,6 +131,7 @@ def _configure_packaged_umbp_master() -> None:
"UMBPIoBackend",
"UMBPIoConfig",
"UMBPRole",
"UMBPStandaloneProcessConfig",
"UMBPSsdConfig",
"UMBPEvictionConfig",
"UMBPTierType",
Expand Down
9 changes: 9 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,14 @@ def build_extension(self, ext: Extension) -> None:
elif umbp_master_dst.exists():
umbp_master_dst.unlink()

umbp_standalone_src = build_dir / "src/umbp/umbp_standalone_server"
umbp_standalone_dst = root_dir / "python/mori/umbp_standalone_server"
if umbp_standalone_src.exists():
shutil.copyfile(umbp_standalone_src, umbp_standalone_dst)
os.chmod(umbp_standalone_dst, 0o700)
elif umbp_standalone_dst.exists():
umbp_standalone_dst.unlink()

# CCO C++ examples: ship the built binaries when BUILD_EXAMPLES=ON. They
# carry an $ORIGIN/../.. rpath (set in examples/CMakeLists.txt) so they
# resolve libmori_*.so from site-packages/mori/ once installed here.
Expand Down Expand Up @@ -723,6 +731,7 @@ def _cco_extension() -> list:
"libmori_metrics.so",
"libmori_collective.so", # optional: only present when BUILD_COLLECTIVE=ON
"umbp_master",
"umbp_standalone_server",
"_jit-sources/include/**/*.hpp",
"_jit-sources/include/**/*.h",
"_jit-sources/include/**/*.cuh",
Expand Down
22 changes: 20 additions & 2 deletions src/pybind/pybind_umbp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ void RegisterMoriUmbp(py::module_& m) {
py::enum_<HostBufferBacking>(m, "UMBPHostBufferBacking")
.value("Anonymous", HostBufferBacking::kAnonymous)
.value("AnonymousHugetlb", HostBufferBacking::kAnonymousHugetlb)
.value("AnonymousShm", HostBufferBacking::kAnonymousShm)
.export_values();

py::class_<HostBufferHandle>(m, "UMBPHostBufferHandle")
Expand Down Expand Up @@ -115,6 +116,12 @@ void RegisterMoriUmbp(py::module_& m) {
.value("SharedSSDFollower", UMBPRole::SharedSSDFollower)
.export_values();

py::enum_<UMBPDeploymentMode>(m, "UMBPDeploymentMode")
.value("Local", UMBPDeploymentMode::Local)
.value("StandaloneProcess", UMBPDeploymentMode::StandaloneProcess)
.value("Distributed", UMBPDeploymentMode::Distributed)
.export_values();

py::enum_<UMBPSsdLayoutMode>(m, "UMBPSsdLayoutMode")
.value("SegmentedLog", UMBPSsdLayoutMode::SegmentedLog)
.export_values();
Expand Down Expand Up @@ -228,6 +235,15 @@ void RegisterMoriUmbp(py::module_& m) {
.def_readwrite("admission_max_block_bytes", &UMBPDistributedConfig::admission_max_block_bytes)
.def_readwrite("dram_page_size", &UMBPDistributedConfig::dram_page_size);

py::class_<UMBPStandaloneProcessConfig>(m, "UMBPStandaloneProcessConfig")
.def(py::init<>())
.def_readwrite("address", &UMBPStandaloneProcessConfig::address)
.def_readwrite("auto_start", &UMBPStandaloneProcessConfig::auto_start)
.def_readwrite("startup_timeout_ms", &UMBPStandaloneProcessConfig::startup_timeout_ms)
.def_readwrite("worker_node_id", &UMBPStandaloneProcessConfig::worker_node_id)
.def_readwrite("worker_node_address", &UMBPStandaloneProcessConfig::worker_node_address)
.def_readwrite("tags", &UMBPStandaloneProcessConfig::tags);

py::class_<UMBPConfig>(m, "UMBPConfig")
.def(py::init<>())
.def_static("from_environment", &UMBPConfig::FromEnvironment)
Expand All @@ -238,7 +254,8 @@ void RegisterMoriUmbp(py::module_& m) {
.def_readwrite("role", &UMBPConfig::role)
.def_readwrite("follower_mode", &UMBPConfig::follower_mode)
.def_readwrite("force_ssd_copy_on_write", &UMBPConfig::force_ssd_copy_on_write)
.def_readwrite("distributed", &UMBPConfig::distributed);
.def_readwrite("distributed", &UMBPConfig::distributed)
.def_readwrite("standalone_process", &UMBPConfig::standalone_process);

py::class_<IUMBPClient, std::unique_ptr<IUMBPClient>>(m, "UMBPClient")
.def(py::init([](const UMBPConfig& cfg) { return CreateUMBPClient(cfg); }),
Expand All @@ -263,7 +280,8 @@ void RegisterMoriUmbp(py::module_& m) {
py::call_guard<py::gil_scoped_release>())
.def("clear", &IUMBPClient::Clear, py::call_guard<py::gil_scoped_release>())
.def("flush", &IUMBPClient::Flush, py::call_guard<py::gil_scoped_release>())
.def("is_distributed", &IUMBPClient::IsDistributed) // pure getter, no I/O
.def("is_distributed", &IUMBPClient::IsDistributed) // pure getter, no I/O
.def("get_deployment_mode", &IUMBPClient::GetDeploymentMode) // pure getter, no I/O
.def("register_memory", &IUMBPClient::RegisterMemory, py::arg("ptr"), py::arg("size"),
py::call_guard<py::gil_scoped_release>())
.def("deregister_memory", &IUMBPClient::DeregisterMemory, py::arg("ptr"),
Expand Down
46 changes: 45 additions & 1 deletion src/umbp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ if(HAVE_SPDK)
# SPDK Proxy daemon (owns SPDK, serves ranks via SHM IPC)
add_executable(spdk_proxy storage/spdk/proxy/spdk_proxy_daemon.cpp)
target_link_libraries(spdk_proxy PRIVATE umbp_core)
set_target_properties(spdk_proxy PROPERTIES BUILD_RPATH "$ORIGIN"
INSTALL_RPATH "$ORIGIN"
BUILD_WITH_INSTALL_RPATH TRUE)
endif()

# Python bindings are registered in src/pybind/pybind_umbp.cpp (compiled into
Expand Down Expand Up @@ -260,6 +263,7 @@ message(
set(UMBP_PROTO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/distributed/proto")
set(UMBP_PROTO_FILE "${UMBP_PROTO_DIR}/umbp.proto")
set(UMBP_PEER_PROTO_FILE "${UMBP_PROTO_DIR}/umbp_peer.proto")
set(UMBP_STANDALONE_PROTO_FILE "${UMBP_PROTO_DIR}/umbp_standalone.proto")
set(UMBP_PROTO_GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/proto_gen")
file(MAKE_DIRECTORY ${UMBP_PROTO_GEN_DIR})

Expand All @@ -273,6 +277,11 @@ set(UMBP_PEER_PROTO_HDRS "${UMBP_PROTO_GEN_DIR}/umbp_peer.pb.h")
set(UMBP_PEER_GRPC_SRCS "${UMBP_PROTO_GEN_DIR}/umbp_peer.grpc.pb.cc")
set(UMBP_PEER_GRPC_HDRS "${UMBP_PROTO_GEN_DIR}/umbp_peer.grpc.pb.h")

set(UMBP_STANDALONE_PROTO_SRCS "${UMBP_PROTO_GEN_DIR}/umbp_standalone.pb.cc")
set(UMBP_STANDALONE_PROTO_HDRS "${UMBP_PROTO_GEN_DIR}/umbp_standalone.pb.h")
set(UMBP_STANDALONE_GRPC_SRCS "${UMBP_PROTO_GEN_DIR}/umbp_standalone.grpc.pb.cc")
set(UMBP_STANDALONE_GRPC_HDRS "${UMBP_PROTO_GEN_DIR}/umbp_standalone.grpc.pb.h")

add_custom_command(
OUTPUT ${UMBP_PROTO_SRCS} ${UMBP_PROTO_HDRS} ${UMBP_GRPC_SRCS}
${UMBP_GRPC_HDRS}
Expand All @@ -299,6 +308,17 @@ add_custom_command(
COMMENT "Generating UMBP Peer protobuf/gRPC C++ sources"
VERBATIM)

add_custom_command(
OUTPUT ${UMBP_STANDALONE_PROTO_SRCS} ${UMBP_STANDALONE_PROTO_HDRS}
${UMBP_STANDALONE_GRPC_SRCS} ${UMBP_STANDALONE_GRPC_HDRS}
COMMAND
${_PROTOBUF_PROTOC} --proto_path=${UMBP_PROTO_DIR}
--cpp_out=${UMBP_PROTO_GEN_DIR} --grpc_out=${UMBP_PROTO_GEN_DIR}
--plugin=protoc-gen-grpc=${_GRPC_CPP_PLUGIN} ${UMBP_STANDALONE_PROTO_FILE}
DEPENDS ${UMBP_STANDALONE_PROTO_FILE} ${UMBP_PROTO_FILE} ${UMBP_PROTO_HDRS}
COMMENT "Generating UMBP Standalone protobuf/gRPC C++ sources"
VERBATIM)

# ---------- Static library: umbp_common ---------------------------------------
# Shared between PoolClient integration and standalone control-plane tools.

Expand All @@ -308,6 +328,8 @@ add_library(
${UMBP_GRPC_SRCS}
${UMBP_PEER_PROTO_SRCS}
${UMBP_PEER_GRPC_SRCS}
${UMBP_STANDALONE_PROTO_SRCS}
${UMBP_STANDALONE_GRPC_SRCS}
distributed/master/global_block_index.cpp
distributed/master/external_kv_block_index.cpp
distributed/master/client_registry.cpp
Expand All @@ -325,7 +347,11 @@ add_library(
distributed/peer/ssd_copy_pipeline.cpp
distributed/peer/peer_service.cpp
distributed/pool_client.cpp
distributed/distributed_client.cpp)
distributed/distributed_client.cpp
standalone/external_kv_identity_client.cpp
standalone/ipc.cpp
standalone/standalone_process_client.cpp
standalone/standalone_server.cpp)

target_include_directories(
umbp_common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${UMBP_PROTO_GEN_DIR}
Expand Down Expand Up @@ -373,6 +399,9 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
endif()
target_link_libraries(umbp_master PRIVATE umbp_common ${_PROTOBUF_LIBS}
${_GRPCPP_LIB})
set_target_properties(umbp_master PROPERTIES BUILD_RPATH "$ORIGIN"
INSTALL_RPATH "$ORIGIN"
BUILD_WITH_INSTALL_RPATH TRUE)

# ---------- Client executable -------------------------------------------------

Expand All @@ -382,6 +411,21 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
endif()
target_link_libraries(umbp_client PRIVATE umbp_common ${_PROTOBUF_LIBS}
${_GRPCPP_LIB})
set_target_properties(umbp_client PROPERTIES BUILD_RPATH "$ORIGIN"
INSTALL_RPATH "$ORIGIN"
BUILD_WITH_INSTALL_RPATH TRUE)

# ---------- Standalone-process executable ------------------------------------

add_executable(umbp_standalone_server standalone/bin/standalone_server_main.cpp)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_link_options(umbp_standalone_server PRIVATE -Wl,--no-as-needed)
endif()
target_link_libraries(umbp_standalone_server PRIVATE umbp_common ${_PROTOBUF_LIBS}
${_GRPCPP_LIB})
set_target_properties(umbp_standalone_server PROPERTIES BUILD_RPATH "$ORIGIN"
INSTALL_RPATH "$ORIGIN"
BUILD_WITH_INSTALL_RPATH TRUE)

if(BUILD_TESTS)
add_subdirectory(tests)
Expand Down
146 changes: 146 additions & 0 deletions src/umbp/distributed/proto/umbp_standalone.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
syntax = "proto3";
package umbp;

import "umbp.proto";

service UMBPStandalone {
rpc Ping(Empty) returns (PingResponse);

rpc Put(PutRequest) returns (BoolResponse);
rpc Get(GetRequest) returns (BoolResponse);
rpc BatchPut(BatchDataRequest) returns (BatchBoolResponse);
rpc BatchPutWithDepth(BatchDataWithDepthRequest) returns (BatchBoolResponse);
rpc BatchGet(BatchDataRequest) returns (BatchBoolResponse);
rpc Exists(KeyRequest) returns (BoolResponse);
rpc BatchExists(BatchKeysRequest) returns (BatchBoolResponse);
rpc BatchExistsConsecutive(BatchKeysRequest) returns (CountResponse);

rpc Clear(Empty) returns (BoolResponse);
rpc Flush(Empty) returns (BoolResponse);
rpc RegisterMemory(RegisterMemoryRequest) returns (BoolResponse);
rpc DeregisterMemory(DeregisterMemoryRequest) returns (Empty);

rpc ReportExternalKvBlocks(StandaloneExternalKvMutationRequest) returns (BoolResponse);
rpc RevokeExternalKvBlocks(StandaloneExternalKvMutationRequest) returns (BoolResponse);
rpc RevokeAllExternalKvBlocksAtTier(StandaloneExternalKvTierRequest) returns (BoolResponse);
rpc MatchExternalKv(StandaloneMatchExternalKvRequest) returns (StandaloneMatchExternalKvResponse);
rpc GetExternalKvHitCounts(StandaloneExternalKvHitCountsRequest)
returns (StandaloneExternalKvHitCountsResponse);
}

message Empty {}

message PingResponse {
bool ready = 1;
StandaloneBackendMode deployment_mode = 2;
}

message BoolResponse {
bool ok = 1;
string error = 2;
}

enum StandaloneBackendMode {
STANDALONE_BACKEND_UNKNOWN = 0;
STANDALONE_BACKEND_LOCAL = 1;
STANDALONE_BACKEND_DISTRIBUTED = 2;
}

message CountResponse {
uint64 count = 1;
}

message KeyRequest {
string key = 1;
}

message BatchKeysRequest {
repeated string keys = 1;
}

message PutRequest {
string key = 1;
string client_id = 2;
uint64 shm_offset = 3;
uint64 size = 4;
}

message GetRequest {
string key = 1;
string client_id = 2;
uint64 shm_offset = 3;
uint64 size = 4;
}

message BatchDataRequest {
repeated string keys = 1;
string client_id = 2;
repeated uint64 shm_offsets = 3;
repeated uint64 sizes = 4;
}

message BatchDataWithDepthRequest {
repeated string keys = 1;
string client_id = 2;
repeated uint64 shm_offsets = 3;
repeated uint64 sizes = 4;
repeated int32 depths = 5;
}

message BatchBoolResponse {
repeated bool ok = 1;
}

message RegisterMemoryRequest {
string client_id = 1;
uint64 worker_base = 2;
uint64 size = 3;
string worker_node_id = 4;
string worker_node_address = 5;
repeated string tags = 6;
}

message DeregisterMemoryRequest {
string client_id = 1;
}

message StandaloneExternalKvMutationRequest {
repeated string hashes = 1;
TierType tier = 2;
string client_id = 3;
}

message StandaloneExternalKvTierRequest {
TierType tier = 1;
string client_id = 2;
}

message StandaloneMatchExternalKvRequest {
repeated string hashes = 1;
bool count_as_hit = 2;
string client_id = 3;
}

message StandaloneExternalKvMatch {
string node_id = 1;
string peer_address = 2;
repeated TierHashes hashes_by_tier = 3;
}

message StandaloneMatchExternalKvResponse {
repeated StandaloneExternalKvMatch matches = 1;
}

message StandaloneExternalKvHitCountsRequest {
repeated string hashes = 1;
string client_id = 2;
}

message StandaloneExternalKvHitCountEntry {
string hash = 1;
uint64 hit_count_total = 2;
}

message StandaloneExternalKvHitCountsResponse {
repeated StandaloneExternalKvHitCountEntry entries = 1;
}
Loading
Loading