lmcache-cli 0.4.5.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lmcache/__init__.py +84 -0
- lmcache/_version.py +24 -0
- lmcache/cli/__init__.py +1 -0
- lmcache/cli/commands/__init__.py +34 -0
- lmcache/cli/commands/base.py +157 -0
- lmcache/cli/commands/bench/__init__.py +557 -0
- lmcache/cli/commands/bench/engine_bench/__init__.py +1 -0
- lmcache/cli/commands/bench/engine_bench/config.py +245 -0
- lmcache/cli/commands/bench/engine_bench/interactive/__init__.py +274 -0
- lmcache/cli/commands/bench/engine_bench/interactive/config.json +10 -0
- lmcache/cli/commands/bench/engine_bench/interactive/schema.py +352 -0
- lmcache/cli/commands/bench/engine_bench/interactive/state.py +327 -0
- lmcache/cli/commands/bench/engine_bench/interactive/terminal.py +291 -0
- lmcache/cli/commands/bench/engine_bench/progress.py +145 -0
- lmcache/cli/commands/bench/engine_bench/request_sender.py +232 -0
- lmcache/cli/commands/bench/engine_bench/stats.py +275 -0
- lmcache/cli/commands/bench/engine_bench/workloads/__init__.py +153 -0
- lmcache/cli/commands/bench/engine_bench/workloads/base.py +122 -0
- lmcache/cli/commands/bench/engine_bench/workloads/long_doc_permutator.py +435 -0
- lmcache/cli/commands/bench/engine_bench/workloads/long_doc_qa.py +281 -0
- lmcache/cli/commands/bench/engine_bench/workloads/multi_round_chat.py +337 -0
- lmcache/cli/commands/bench/engine_bench/workloads/random_prefill.py +178 -0
- lmcache/cli/commands/describe.py +310 -0
- lmcache/cli/commands/kvcache.py +133 -0
- lmcache/cli/commands/mock.py +75 -0
- lmcache/cli/commands/ping.py +113 -0
- lmcache/cli/commands/query/__init__.py +155 -0
- lmcache/cli/commands/query/prompt.py +134 -0
- lmcache/cli/commands/query/request.py +357 -0
- lmcache/cli/commands/server.py +99 -0
- lmcache/cli/commands/tool/__init__.py +63 -0
- lmcache/cli/commands/tool/cache_simulator.py +113 -0
- lmcache/cli/commands/trace/__init__.py +505 -0
- lmcache/cli/commands/trace/dispatch.py +249 -0
- lmcache/cli/commands/trace/driver.py +372 -0
- lmcache/cli/commands/trace/stats.py +289 -0
- lmcache/cli/documents/lmcache.txt +11 -0
- lmcache/cli/main.py +42 -0
- lmcache/cli/metrics/__init__.py +29 -0
- lmcache/cli/metrics/formatter.py +171 -0
- lmcache/cli/metrics/handler.py +94 -0
- lmcache/cli/metrics/metrics.py +161 -0
- lmcache/cli/metrics/section.py +77 -0
- lmcache/connections.py +173 -0
- lmcache/integration/__init__.py +2 -0
- lmcache/integration/base_service_factory.py +165 -0
- lmcache/integration/request_telemetry/__init__.py +1 -0
- lmcache/integration/request_telemetry/base.py +51 -0
- lmcache/integration/request_telemetry/factory.py +113 -0
- lmcache/integration/request_telemetry/fastapi.py +109 -0
- lmcache/integration/request_telemetry/noop.py +35 -0
- lmcache/integration/sglang/__init__.py +2 -0
- lmcache/integration/sglang/sglang_adapter.py +326 -0
- lmcache/integration/sglang/utils.py +39 -0
- lmcache/integration/vllm/__init__.py +1 -0
- lmcache/integration/vllm/lmcache_connector_v1.py +213 -0
- lmcache/integration/vllm/lmcache_connector_v1_085.py +150 -0
- lmcache/integration/vllm/lmcache_mp_connector_0180.py +1072 -0
- lmcache/integration/vllm/tests/test_mm_hash_utils.py +112 -0
- lmcache/integration/vllm/utils.py +433 -0
- lmcache/integration/vllm/vllm_multi_process_adapter.py +1090 -0
- lmcache/integration/vllm/vllm_service_factory.py +339 -0
- lmcache/integration/vllm/vllm_v1_adapter.py +1713 -0
- lmcache/logging.py +107 -0
- lmcache/native_storage_ops.pyi +230 -0
- lmcache/non_cuda_equivalents.py +1424 -0
- lmcache/observability.py +1958 -0
- lmcache/storage_backend/serde/__init__.py +1 -0
- lmcache/storage_backend/serde/cachegen_basics.py +210 -0
- lmcache/storage_backend/serde/cachegen_decoder.py +207 -0
- lmcache/storage_backend/serde/cachegen_encoder.py +394 -0
- lmcache/storage_backend/serde/serde.py +75 -0
- lmcache/tools/__init__.py +1 -0
- lmcache/tools/cache_simulator/README.md +392 -0
- lmcache/tools/cache_simulator/__init__.py +1 -0
- lmcache/tools/cache_simulator/docs/simulate_example.png +0 -0
- lmcache/tools/cache_simulator/docs/sweep_example.png +0 -0
- lmcache/tools/cache_simulator/gen_bench_dataset.py +360 -0
- lmcache/tools/cache_simulator/lru_cache.py +124 -0
- lmcache/tools/cache_simulator/plot_hit_rate.py +231 -0
- lmcache/tools/cache_simulator/simulator.py +795 -0
- lmcache/tools/controller_benchmark/README.md +161 -0
- lmcache/tools/controller_benchmark/__init__.py +1 -0
- lmcache/tools/controller_benchmark/__main__.py +331 -0
- lmcache/tools/controller_benchmark/benchmark.py +660 -0
- lmcache/tools/controller_benchmark/config.py +44 -0
- lmcache/tools/controller_benchmark/constants.py +10 -0
- lmcache/tools/controller_benchmark/handlers/__init__.py +46 -0
- lmcache/tools/controller_benchmark/handlers/admit.py +52 -0
- lmcache/tools/controller_benchmark/handlers/base.py +47 -0
- lmcache/tools/controller_benchmark/handlers/deregister.py +49 -0
- lmcache/tools/controller_benchmark/handlers/evict.py +52 -0
- lmcache/tools/controller_benchmark/handlers/heartbeat.py +56 -0
- lmcache/tools/controller_benchmark/handlers/p2p_lookup.py +47 -0
- lmcache/tools/controller_benchmark/handlers/register.py +56 -0
- lmcache/tools/mp_status_viewer/__init__.py +1 -0
- lmcache/tools/mp_status_viewer/__main__.py +95 -0
- lmcache/usage_context.py +417 -0
- lmcache/utils.py +665 -0
- lmcache/v1/__init__.py +2 -0
- lmcache/v1/api_server/__init__.py +2 -0
- lmcache/v1/api_server/__main__.py +537 -0
- lmcache/v1/basic_check.py +112 -0
- lmcache/v1/cache_controller/__init__.py +9 -0
- lmcache/v1/cache_controller/commands/__init__.py +15 -0
- lmcache/v1/cache_controller/commands/base.py +35 -0
- lmcache/v1/cache_controller/commands/full_sync.py +49 -0
- lmcache/v1/cache_controller/config.py +176 -0
- lmcache/v1/cache_controller/controller_manager.py +535 -0
- lmcache/v1/cache_controller/controllers/__init__.py +11 -0
- lmcache/v1/cache_controller/controllers/full_sync_tracker.py +473 -0
- lmcache/v1/cache_controller/controllers/kv_controller.py +439 -0
- lmcache/v1/cache_controller/controllers/registration_controller.py +282 -0
- lmcache/v1/cache_controller/executor.py +463 -0
- lmcache/v1/cache_controller/frontend/static/css/style.css +201 -0
- lmcache/v1/cache_controller/frontend/static/img/logo.png +0 -0
- lmcache/v1/cache_controller/frontend/static/index.html +234 -0
- lmcache/v1/cache_controller/frontend/static/js/controller_app.js +660 -0
- lmcache/v1/cache_controller/full_sync_sender.py +475 -0
- lmcache/v1/cache_controller/locks.py +149 -0
- lmcache/v1/cache_controller/message.py +828 -0
- lmcache/v1/cache_controller/observability.py +208 -0
- lmcache/v1/cache_controller/utils.py +679 -0
- lmcache/v1/cache_controller/worker.py +665 -0
- lmcache/v1/cache_engine.py +2058 -0
- lmcache/v1/cache_interface.py +19 -0
- lmcache/v1/check/__init__.py +74 -0
- lmcache/v1/check/check_mode_gen.py +86 -0
- lmcache/v1/check/check_mode_test_l2_adapter.py +284 -0
- lmcache/v1/check/check_mode_test_remote.py +155 -0
- lmcache/v1/check/check_mode_test_storage_manager.py +142 -0
- lmcache/v1/check/utils.py +571 -0
- lmcache/v1/compute/__init__.py +2 -0
- lmcache/v1/compute/attention/__init__.py +0 -0
- lmcache/v1/compute/attention/abstract.py +39 -0
- lmcache/v1/compute/attention/flash_attn.py +129 -0
- lmcache/v1/compute/attention/flash_infer_sparse.py +284 -0
- lmcache/v1/compute/attention/metadata.py +85 -0
- lmcache/v1/compute/attention/utils.py +14 -0
- lmcache/v1/compute/blend/__init__.py +7 -0
- lmcache/v1/compute/blend/blender.py +168 -0
- lmcache/v1/compute/blend/metadata.py +34 -0
- lmcache/v1/compute/blend/utils.py +63 -0
- lmcache/v1/compute/models/__init__.py +0 -0
- lmcache/v1/compute/models/base.py +141 -0
- lmcache/v1/compute/models/llama.py +9 -0
- lmcache/v1/compute/models/qwen3.py +24 -0
- lmcache/v1/compute/models/utils.py +68 -0
- lmcache/v1/compute/positional_encoding.py +199 -0
- lmcache/v1/config.py +848 -0
- lmcache/v1/config_base.py +848 -0
- lmcache/v1/distributed/api.py +248 -0
- lmcache/v1/distributed/config.py +321 -0
- lmcache/v1/distributed/error.py +64 -0
- lmcache/v1/distributed/eviction.py +192 -0
- lmcache/v1/distributed/eviction_policy/__init__.py +21 -0
- lmcache/v1/distributed/eviction_policy/factory.py +27 -0
- lmcache/v1/distributed/eviction_policy/lru.py +244 -0
- lmcache/v1/distributed/eviction_policy/noop.py +50 -0
- lmcache/v1/distributed/internal_api.py +170 -0
- lmcache/v1/distributed/l1_manager.py +835 -0
- lmcache/v1/distributed/l2_adapters/__init__.py +67 -0
- lmcache/v1/distributed/l2_adapters/base.py +360 -0
- lmcache/v1/distributed/l2_adapters/config.py +385 -0
- lmcache/v1/distributed/l2_adapters/factory.py +205 -0
- lmcache/v1/distributed/l2_adapters/fs_l2_adapter.py +747 -0
- lmcache/v1/distributed/l2_adapters/fs_native_l2_adapter.py +167 -0
- lmcache/v1/distributed/l2_adapters/mock_l2_adapter.py +516 -0
- lmcache/v1/distributed/l2_adapters/mooncake_store_l2_adapter.py +135 -0
- lmcache/v1/distributed/l2_adapters/native_connector_l2_adapter.py +468 -0
- lmcache/v1/distributed/l2_adapters/native_plugin_l2_adapter.py +199 -0
- lmcache/v1/distributed/l2_adapters/nixl_store_dynamic_l2_adapter.py +831 -0
- lmcache/v1/distributed/l2_adapters/nixl_store_l2_adapter.py +983 -0
- lmcache/v1/distributed/l2_adapters/plugin_l2_adapter.py +210 -0
- lmcache/v1/distributed/l2_adapters/resp_l2_adapter.py +176 -0
- lmcache/v1/distributed/memory_manager.py +179 -0
- lmcache/v1/distributed/storage_controller.py +39 -0
- lmcache/v1/distributed/storage_controllers/__init__.py +43 -0
- lmcache/v1/distributed/storage_controllers/eviction_controller.py +242 -0
- lmcache/v1/distributed/storage_controllers/prefetch_controller.py +830 -0
- lmcache/v1/distributed/storage_controllers/prefetch_policy.py +193 -0
- lmcache/v1/distributed/storage_controllers/store_controller.py +452 -0
- lmcache/v1/distributed/storage_controllers/store_policy.py +213 -0
- lmcache/v1/distributed/storage_manager.py +532 -0
- lmcache/v1/event_manager.py +145 -0
- lmcache/v1/exceptions/__init__.py +16 -0
- lmcache/v1/gpu_connector/__init__.py +126 -0
- lmcache/v1/gpu_connector/gpu_connectors.py +1906 -0
- lmcache/v1/gpu_connector/gpu_ops.py +85 -0
- lmcache/v1/gpu_connector/hpu_connector.py +326 -0
- lmcache/v1/gpu_connector/mock_gpu_connector.py +67 -0
- lmcache/v1/gpu_connector/utils.py +890 -0
- lmcache/v1/gpu_connector/xpu_connectors.py +916 -0
- lmcache/v1/health_monitor/__init__.py +1 -0
- lmcache/v1/health_monitor/base.py +587 -0
- lmcache/v1/health_monitor/checks/__init__.py +1 -0
- lmcache/v1/health_monitor/checks/remote_backend_check.py +304 -0
- lmcache/v1/health_monitor/constants.py +36 -0
- lmcache/v1/internal_api_server/__init__.py +0 -0
- lmcache/v1/internal_api_server/api_registry.py +59 -0
- lmcache/v1/internal_api_server/api_server.py +120 -0
- lmcache/v1/internal_api_server/common/__init__.py +1 -0
- lmcache/v1/internal_api_server/common/env_api.py +22 -0
- lmcache/v1/internal_api_server/common/loglevel_api.py +57 -0
- lmcache/v1/internal_api_server/common/metrics_api.py +29 -0
- lmcache/v1/internal_api_server/common/periodic_thread_api.py +138 -0
- lmcache/v1/internal_api_server/common/run_script_api.py +73 -0
- lmcache/v1/internal_api_server/common/thread_api.py +63 -0
- lmcache/v1/internal_api_server/controller/__init__.py +1 -0
- lmcache/v1/internal_api_server/controller/key_stats_api.py +81 -0
- lmcache/v1/internal_api_server/controller/worker_info_api.py +136 -0
- lmcache/v1/internal_api_server/utils.py +43 -0
- lmcache/v1/internal_api_server/vllm/__init__.py +1 -0
- lmcache/v1/internal_api_server/vllm/backend_api.py +221 -0
- lmcache/v1/internal_api_server/vllm/bypass_api.py +204 -0
- lmcache/v1/internal_api_server/vllm/cache_api.py +895 -0
- lmcache/v1/internal_api_server/vllm/chunk_statistics_api.py +141 -0
- lmcache/v1/internal_api_server/vllm/conf_api.py +147 -0
- lmcache/v1/internal_api_server/vllm/freeze_api.py +172 -0
- lmcache/v1/internal_api_server/vllm/hot_cache_api.py +184 -0
- lmcache/v1/internal_api_server/vllm/inference_api.py +65 -0
- lmcache/v1/internal_api_server/vllm/load_fs_chunks_api.py +320 -0
- lmcache/v1/internal_api_server/vllm/lookup_api.py +145 -0
- lmcache/v1/internal_api_server/vllm/version_api.py +25 -0
- lmcache/v1/kv_layer_groups.py +267 -0
- lmcache/v1/lazy_memory_allocator.py +284 -0
- lmcache/v1/lookup_client/__init__.py +25 -0
- lmcache/v1/lookup_client/abstract_client.py +77 -0
- lmcache/v1/lookup_client/async_lookup_message.py +50 -0
- lmcache/v1/lookup_client/chunk_statistics_lookup_client.py +200 -0
- lmcache/v1/lookup_client/factory.py +251 -0
- lmcache/v1/lookup_client/hit_limit_lookup_client.py +86 -0
- lmcache/v1/lookup_client/lmcache_async_lookup_client.py +407 -0
- lmcache/v1/lookup_client/lmcache_lookup_client.py +285 -0
- lmcache/v1/lookup_client/lmcache_lookup_client_bypass.py +99 -0
- lmcache/v1/lookup_client/mooncake_lookup_client.py +87 -0
- lmcache/v1/lookup_client/record_strategies/__init__.py +77 -0
- lmcache/v1/lookup_client/record_strategies/base.py +327 -0
- lmcache/v1/lookup_client/record_strategies/file_hash.py +130 -0
- lmcache/v1/lookup_client/record_strategies/memory_bloom_filter.py +81 -0
- lmcache/v1/manager.py +539 -0
- lmcache/v1/memory_management.py +2619 -0
- lmcache/v1/metadata.py +114 -0
- lmcache/v1/mp_observability/AGENTS.override.md +21 -0
- lmcache/v1/mp_observability/README.md +204 -0
- lmcache/v1/mp_observability/config.py +340 -0
- lmcache/v1/mp_observability/event.py +100 -0
- lmcache/v1/mp_observability/event_bus.py +313 -0
- lmcache/v1/mp_observability/otel_init.py +145 -0
- lmcache/v1/mp_observability/subscribers/__init__.py +28 -0
- lmcache/v1/mp_observability/subscribers/logging/__init__.py +19 -0
- lmcache/v1/mp_observability/subscribers/logging/l1.py +56 -0
- lmcache/v1/mp_observability/subscribers/logging/l2.py +73 -0
- lmcache/v1/mp_observability/subscribers/logging/lookup_hash.py +209 -0
- lmcache/v1/mp_observability/subscribers/logging/mp_server.py +90 -0
- lmcache/v1/mp_observability/subscribers/logging/sm.py +59 -0
- lmcache/v1/mp_observability/subscribers/metrics/__init__.py +20 -0
- lmcache/v1/mp_observability/subscribers/metrics/l0_lifecycle.py +290 -0
- lmcache/v1/mp_observability/subscribers/metrics/l1.py +55 -0
- lmcache/v1/mp_observability/subscribers/metrics/l1_lifecycle.py +166 -0
- lmcache/v1/mp_observability/subscribers/metrics/l2.py +121 -0
- lmcache/v1/mp_observability/subscribers/metrics/sm.py +69 -0
- lmcache/v1/mp_observability/subscribers/tracing/__init__.py +12 -0
- lmcache/v1/mp_observability/subscribers/tracing/mp_server.py +333 -0
- lmcache/v1/mp_observability/subscribers/tracing/span_registry.py +148 -0
- lmcache/v1/mp_observability/trace/__init__.py +50 -0
- lmcache/v1/mp_observability/trace/codecs.py +255 -0
- lmcache/v1/mp_observability/trace/decorator.py +147 -0
- lmcache/v1/mp_observability/trace/format.py +132 -0
- lmcache/v1/mp_observability/trace/lifecycle.py +83 -0
- lmcache/v1/mp_observability/trace/reader.py +167 -0
- lmcache/v1/mp_observability/trace/recorder.py +300 -0
- lmcache/v1/multiprocess/__init__.py +0 -0
- lmcache/v1/multiprocess/affinity_pool.py +102 -0
- lmcache/v1/multiprocess/blend_server_v2.py +891 -0
- lmcache/v1/multiprocess/config.py +253 -0
- lmcache/v1/multiprocess/custom_types.py +281 -0
- lmcache/v1/multiprocess/futures.py +194 -0
- lmcache/v1/multiprocess/gpu_context.py +511 -0
- lmcache/v1/multiprocess/http_server.py +235 -0
- lmcache/v1/multiprocess/mp_runtime_plugin_launcher.py +130 -0
- lmcache/v1/multiprocess/mq.py +732 -0
- lmcache/v1/multiprocess/protocol.py +86 -0
- lmcache/v1/multiprocess/protocols/README.md +213 -0
- lmcache/v1/multiprocess/protocols/__init__.py +127 -0
- lmcache/v1/multiprocess/protocols/base.py +89 -0
- lmcache/v1/multiprocess/protocols/blend.py +109 -0
- lmcache/v1/multiprocess/protocols/blend_v2.py +57 -0
- lmcache/v1/multiprocess/protocols/controller.py +53 -0
- lmcache/v1/multiprocess/protocols/debug.py +34 -0
- lmcache/v1/multiprocess/protocols/engine.py +146 -0
- lmcache/v1/multiprocess/protocols/observability.py +39 -0
- lmcache/v1/multiprocess/server.py +1134 -0
- lmcache/v1/multiprocess/session.py +190 -0
- lmcache/v1/multiprocess/token_hasher.py +441 -0
- lmcache/v1/offload_server/__init__.py +17 -0
- lmcache/v1/offload_server/abstract_server.py +37 -0
- lmcache/v1/offload_server/message.py +30 -0
- lmcache/v1/offload_server/zmq_server.py +122 -0
- lmcache/v1/periodic_thread.py +579 -0
- lmcache/v1/pin_monitor.py +246 -0
- lmcache/v1/plugin/__init__.py +0 -0
- lmcache/v1/plugin/runtime_plugin_launcher.py +211 -0
- lmcache/v1/protocol.py +317 -0
- lmcache/v1/rpc/__init__.py +17 -0
- lmcache/v1/rpc/transport.py +105 -0
- lmcache/v1/rpc/zmq_transport.py +213 -0
- lmcache/v1/rpc_utils.py +165 -0
- lmcache/v1/server/__init__.py +2 -0
- lmcache/v1/server/__main__.py +170 -0
- lmcache/v1/server/storage_backend/__init__.py +21 -0
- lmcache/v1/server/storage_backend/abstract_backend.py +80 -0
- lmcache/v1/server/storage_backend/local_backend.py +75 -0
- lmcache/v1/server/utils.py +21 -0
- lmcache/v1/standalone/__init__.py +1 -0
- lmcache/v1/standalone/__main__.py +583 -0
- lmcache/v1/standalone/manager.py +80 -0
- lmcache/v1/standalone/standalone_service_factory.py +86 -0
- lmcache/v1/storage_backend/__init__.py +313 -0
- lmcache/v1/storage_backend/abstract_backend.py +445 -0
- lmcache/v1/storage_backend/audit_backend.py +233 -0
- lmcache/v1/storage_backend/batched_message_sender.py +222 -0
- lmcache/v1/storage_backend/cache_policy/__init__.py +45 -0
- lmcache/v1/storage_backend/cache_policy/base_policy.py +87 -0
- lmcache/v1/storage_backend/cache_policy/fifo.py +58 -0
- lmcache/v1/storage_backend/cache_policy/lfu.py +105 -0
- lmcache/v1/storage_backend/cache_policy/lru.py +81 -0
- lmcache/v1/storage_backend/cache_policy/mru.py +61 -0
- lmcache/v1/storage_backend/connector/__init__.py +443 -0
- lmcache/v1/storage_backend/connector/audit_adapter.py +77 -0
- lmcache/v1/storage_backend/connector/audit_connector.py +320 -0
- lmcache/v1/storage_backend/connector/base_connector.py +379 -0
- lmcache/v1/storage_backend/connector/blackhole_adapter.py +21 -0
- lmcache/v1/storage_backend/connector/blackhole_connector.py +37 -0
- lmcache/v1/storage_backend/connector/eic_adapter.py +31 -0
- lmcache/v1/storage_backend/connector/eic_connector.py +757 -0
- lmcache/v1/storage_backend/connector/external_adapter.py +79 -0
- lmcache/v1/storage_backend/connector/fs_adapter.py +51 -0
- lmcache/v1/storage_backend/connector/fs_connector.py +403 -0
- lmcache/v1/storage_backend/connector/infinistore_adapter.py +56 -0
- lmcache/v1/storage_backend/connector/infinistore_connector.py +177 -0
- lmcache/v1/storage_backend/connector/instrumented_connector.py +219 -0
- lmcache/v1/storage_backend/connector/lm_adapter.py +31 -0
- lmcache/v1/storage_backend/connector/lm_connector.py +176 -0
- lmcache/v1/storage_backend/connector/mock_adapter.py +57 -0
- lmcache/v1/storage_backend/connector/mock_connector.py +349 -0
- lmcache/v1/storage_backend/connector/mooncakestore_adapter.py +43 -0
- lmcache/v1/storage_backend/connector/mooncakestore_connector.py +614 -0
- lmcache/v1/storage_backend/connector/redis_adapter.py +181 -0
- lmcache/v1/storage_backend/connector/redis_connector.py +828 -0
- lmcache/v1/storage_backend/connector/s3_adapter.py +59 -0
- lmcache/v1/storage_backend/connector/s3_connector.py +699 -0
- lmcache/v1/storage_backend/connector/sagemaker_hyperpod_adapter.py +233 -0
- lmcache/v1/storage_backend/connector/sagemaker_hyperpod_connector.py +987 -0
- lmcache/v1/storage_backend/connector/valkey_adapter.py +114 -0
- lmcache/v1/storage_backend/connector/valkey_connector.py +627 -0
- lmcache/v1/storage_backend/gds_backend.py +1199 -0
- lmcache/v1/storage_backend/job_executor/__init__.py +0 -0
- lmcache/v1/storage_backend/job_executor/base_executor.py +34 -0
- lmcache/v1/storage_backend/job_executor/pq_executor.py +235 -0
- lmcache/v1/storage_backend/local_cpu_backend.py +810 -0
- lmcache/v1/storage_backend/local_disk_backend.py +656 -0
- lmcache/v1/storage_backend/maru_backend.py +734 -0
- lmcache/v1/storage_backend/naive_serde/__init__.py +50 -0
- lmcache/v1/storage_backend/naive_serde/cachegen_basics.py +133 -0
- lmcache/v1/storage_backend/naive_serde/cachegen_decoder.py +135 -0
- lmcache/v1/storage_backend/naive_serde/cachegen_encoder.py +83 -0
- lmcache/v1/storage_backend/naive_serde/kivi_serde.py +22 -0
- lmcache/v1/storage_backend/naive_serde/naive_serde.py +18 -0
- lmcache/v1/storage_backend/naive_serde/serde.py +37 -0
- lmcache/v1/storage_backend/native_clients/connector_client_base.py +165 -0
- lmcache/v1/storage_backend/native_clients/resp_client.py +35 -0
- lmcache/v1/storage_backend/nixl_storage_backend.py +1400 -0
- lmcache/v1/storage_backend/p2p_backend.py +788 -0
- lmcache/v1/storage_backend/path_sharder.py +117 -0
- lmcache/v1/storage_backend/pd_backend.py +646 -0
- lmcache/v1/storage_backend/plugins/dax_backend.py +1443 -0
- lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py +1361 -0
- lmcache/v1/storage_backend/remote_backend.py +624 -0
- lmcache/v1/storage_backend/resp_client.py +227 -0
- lmcache/v1/storage_backend/storage_backend_listener.py +19 -0
- lmcache/v1/storage_backend/storage_manager.py +1352 -0
- lmcache/v1/system_detection.py +110 -0
- lmcache/v1/token_database.py +551 -0
- lmcache/v1/transfer_channel/__init__.py +83 -0
- lmcache/v1/transfer_channel/abstract.py +285 -0
- lmcache/v1/transfer_channel/mock_memory_channel.py +156 -0
- lmcache/v1/transfer_channel/nixl_channel.py +639 -0
- lmcache/v1/transfer_channel/py_socket_channel.py +260 -0
- lmcache/v1/transfer_channel/transfer_utils.py +63 -0
- lmcache/v1/utils/__init__.py +1 -0
- lmcache/v1/utils/bloom_filter.py +109 -0
- lmcache/v1/utils/cache_utils.py +125 -0
- lmcache_cli-0.4.5.dev0.dist-info/METADATA +185 -0
- lmcache_cli-0.4.5.dev0.dist-info/RECORD +399 -0
- lmcache_cli-0.4.5.dev0.dist-info/WHEEL +5 -0
- lmcache_cli-0.4.5.dev0.dist-info/entry_points.txt +2 -0
- lmcache_cli-0.4.5.dev0.dist-info/licenses/LICENSE +201 -0
- lmcache_cli-0.4.5.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# LMCache Controller ZMQ Benchmark Tool
|
|
2
|
+
|
|
3
|
+
This tool performs load testing on LMCache Controller using ZMQ interface to measure message throughput, latency, and system performance.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The benchmark tool simulates multiple instances and workers sending various types of messages to the LMCache Controller:
|
|
8
|
+
|
|
9
|
+
- **BatchedKVOperationMsg**: admit/evict messages via pull socket
|
|
10
|
+
- **BatchedP2PLookupMsg**: p2p_lookup messages via reply socket
|
|
11
|
+
- **RegisterMsg/DeRegisterMsg/HeartbeatMsg**: worker lifecycle messages
|
|
12
|
+
|
|
13
|
+
### Key Components
|
|
14
|
+
|
|
15
|
+
- **constants.py**: Defines ZMQ socket timeouts and other constants
|
|
16
|
+
- **config.py**: `ZMQBenchmarkConfig` dataclass for benchmark configuration
|
|
17
|
+
- **handlers/**: Operation handlers using Strategy Pattern with dynamic discovery
|
|
18
|
+
- Each operation has its own file (e.g., `admit.py`, `evict.py`)
|
|
19
|
+
- Automatically discovers and registers all handlers at import time
|
|
20
|
+
- Add new operations by creating a new handler file - no need to modify existing code
|
|
21
|
+
- **benchmark.py**: `ZMQControllerBenchmark` class with core logic
|
|
22
|
+
- **__main__.py**: Argument parsing and main entry point
|
|
23
|
+
|
|
24
|
+
## Prerequisites
|
|
25
|
+
|
|
26
|
+
- A running LMCache Controller instance
|
|
27
|
+
- Python 3.10+
|
|
28
|
+
- Required dependencies: `zmq`, `msgspec`, `psutil`
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### Basic Usage
|
|
33
|
+
- Start the controller
|
|
34
|
+
```bash
|
|
35
|
+
python3 -m lmcache.v1.api_server --host 0.0.0.0 --port 9009 \
|
|
36
|
+
--monitor-ports "{\"pull\":7555,\"reply\":7556}" \
|
|
37
|
+
--lmcache-worker-timeout 100 --health-check-interval 10
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- Start the benchmark
|
|
41
|
+
```bash
|
|
42
|
+
python3 -m lmcache.tools.controller_benchmark \
|
|
43
|
+
--monitor-ports "{\"pull\":7555,\"reply\":7556}" \
|
|
44
|
+
--num-instances 50 --num-workers 1 --num-keys 1000000 --batch-size 100 \
|
|
45
|
+
--operations "admit:35,evict:29,heartbeat:1,p2p_lookup:35"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
## Command Line Options
|
|
50
|
+
|
|
51
|
+
| Option | Default | Description |
|
|
52
|
+
|--------|---------|-------------|
|
|
53
|
+
| `--controller-host` | `localhost` | Controller host address |
|
|
54
|
+
| `--monitor-ports` | `{"pull":8100,"reply":8101}` | Monitor ports in JSON format |
|
|
55
|
+
| `--duration` | `60` | Benchmark duration in seconds |
|
|
56
|
+
| `--batch-size` | `50` | Number of KV operations per batch message |
|
|
57
|
+
| `--operations` | `admit:70,evict:25,heartbeat:5` | Operation distribution (name:percentage) |
|
|
58
|
+
| `--num-instances` | `10` | Number of instances to simulate |
|
|
59
|
+
| `--num-workers` | `1` | Number of workers per instance |
|
|
60
|
+
| `--num-locations` | `1` | Number of storage locations |
|
|
61
|
+
| `--num-keys` | `10000` | Number of unique keys |
|
|
62
|
+
| `--num-hashes` | `100` | Number of hashes for P2P lookup operations |
|
|
63
|
+
| `--no-register-first` | `false` | Skip pre-registering workers before benchmark |
|
|
64
|
+
|
|
65
|
+
## Operation Types
|
|
66
|
+
|
|
67
|
+
The benchmark supports the following operation types:
|
|
68
|
+
|
|
69
|
+
| Operation | Description |
|
|
70
|
+
|-----------|-------------------------------------------|
|
|
71
|
+
| `admit` | Simulates KV cache admission (adds entries) |
|
|
72
|
+
| `evict` | Simulates KV cache eviction (removes entries) |
|
|
73
|
+
| `p2p_lookup` | Simulates p2p batch lookup messages |
|
|
74
|
+
| `register` | Simulates worker registration |
|
|
75
|
+
| `deregister` | Simulates worker deregistration |
|
|
76
|
+
|
|
77
|
+
### Adding New Operations
|
|
78
|
+
|
|
79
|
+
To add a new operation, simply create a new handler file in `handlers/` directory:
|
|
80
|
+
|
|
81
|
+
1. Create `handlers/your_operation.py` implementing `OperationHandler` base class
|
|
82
|
+
2. Define `operation_name` property and implement required methods
|
|
83
|
+
3. The handler will be automatically discovered and registered
|
|
84
|
+
|
|
85
|
+
No need to modify existing code - the system uses dynamic discovery!
|
|
86
|
+
|
|
87
|
+
## Output Metrics
|
|
88
|
+
|
|
89
|
+
The benchmark reports:
|
|
90
|
+
|
|
91
|
+
- **Overall QPS**: Total messages per second
|
|
92
|
+
- **Per-operation QPS**: Messages per second for each operation type
|
|
93
|
+
- **Latency statistics**: avg, min, max, p95 (in milliseconds)
|
|
94
|
+
- **Error counts**: Number of failed operations
|
|
95
|
+
- **Memory usage**: System memory usage during the test
|
|
96
|
+
|
|
97
|
+
### Sample Output
|
|
98
|
+
|
|
99
|
+
The following is a sample output from the benchmark ran in my macbook m4 pro.
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
================================================================================
|
|
103
|
+
LMCache Controller ZMQ Benchmark Results
|
|
104
|
+
================================================================================
|
|
105
|
+
|
|
106
|
+
Configuration:
|
|
107
|
+
Controller URL: 127.0.0.1:7555
|
|
108
|
+
Duration: 60 seconds
|
|
109
|
+
Batch Size: 100
|
|
110
|
+
Operations: {'admit': 35.0, 'evict': 29.0, 'heartbeat': 1.0, 'p2p_lookup': 35.0}
|
|
111
|
+
Instances: 50, Workers: 1, Locations: 1, Keys: 1000000
|
|
112
|
+
|
|
113
|
+
Overall Performance:
|
|
114
|
+
Total Requests: 270035
|
|
115
|
+
Total Messages: 26736200
|
|
116
|
+
Total Time: 60.00s
|
|
117
|
+
Overall RPS (Requests/sec): 4500.58
|
|
118
|
+
Overall QPS (Messages/sec): 445602.80
|
|
119
|
+
|
|
120
|
+
Per-Operation Performance:
|
|
121
|
+
admit:
|
|
122
|
+
RPS (Requests/sec): 1575.23
|
|
123
|
+
QPS (Messages/sec): 157523.14
|
|
124
|
+
Latency - Avg: 0.016ms, Min: 0.007ms, Max: 0.249ms, P95: 0.031ms
|
|
125
|
+
Errors: 0
|
|
126
|
+
evict:
|
|
127
|
+
RPS (Requests/sec): 1305.13
|
|
128
|
+
QPS (Messages/sec): 130513.18
|
|
129
|
+
Latency - Avg: 0.016ms, Min: 0.007ms, Max: 1.201ms, P95: 0.031ms
|
|
130
|
+
Errors: 0
|
|
131
|
+
heartbeat:
|
|
132
|
+
RPS (Requests/sec): 45.00
|
|
133
|
+
QPS (Messages/sec): 45.00
|
|
134
|
+
Latency - Avg: 0.010ms, Min: 0.003ms, Max: 0.138ms, P95: 0.024ms
|
|
135
|
+
Errors: 0
|
|
136
|
+
p2p_lookup:
|
|
137
|
+
RPS (Requests/sec): 1575.21
|
|
138
|
+
QPS (Messages/sec): 157521.48
|
|
139
|
+
Latency - Avg: 0.440ms, Min: 0.150ms, Max: 6.291ms, P95: 0.843ms
|
|
140
|
+
Errors: 0
|
|
141
|
+
|
|
142
|
+
System Metrics:
|
|
143
|
+
Memory Usage - Avg: 62.3%, Max: 63.5%
|
|
144
|
+
================================================================================
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Troubleshooting
|
|
148
|
+
|
|
149
|
+
### Send Timeout Error
|
|
150
|
+
|
|
151
|
+
If you see "Send timeout - Controller may not be running", ensure:
|
|
152
|
+
1. The LMCache Controller is running
|
|
153
|
+
2. The `--controller-host` and `--monitor-ports` are correct
|
|
154
|
+
3. No firewall is blocking the connection
|
|
155
|
+
|
|
156
|
+
### High Error Rate
|
|
157
|
+
|
|
158
|
+
If you observe high error rates:
|
|
159
|
+
1. Reduce `--batch-size` to decrease message size
|
|
160
|
+
2. Increase controller resources
|
|
161
|
+
3. Check network connectivity
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
LMCache Controller ZMQ Benchmark Tool - CLI Entry Point
|
|
4
|
+
|
|
5
|
+
This tool performs load testing on LMCache Controller using ZMQ interface
|
|
6
|
+
to measure message throughput, latency, and system performance.
|
|
7
|
+
|
|
8
|
+
Test operations:
|
|
9
|
+
- BatchedKVOperationMsg: admit/evict messages via PUSH socket
|
|
10
|
+
- RegisterMsg/DeRegisterMsg/HeartbeatMsg: worker lifecycle messages
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
14
|
+
|
|
15
|
+
# Standard
|
|
16
|
+
from typing import Dict, List
|
|
17
|
+
import argparse
|
|
18
|
+
import asyncio
|
|
19
|
+
import json
|
|
20
|
+
import multiprocessing
|
|
21
|
+
import statistics
|
|
22
|
+
|
|
23
|
+
# First Party
|
|
24
|
+
from lmcache.logging import init_logger
|
|
25
|
+
from lmcache.tools.controller_benchmark.benchmark import (
|
|
26
|
+
BenchmarkResults,
|
|
27
|
+
OperationStats,
|
|
28
|
+
ZMQControllerBenchmark,
|
|
29
|
+
)
|
|
30
|
+
from lmcache.tools.controller_benchmark.config import ZMQBenchmarkConfig
|
|
31
|
+
|
|
32
|
+
logger = init_logger(__name__)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def run_single_process(config: ZMQBenchmarkConfig) -> BenchmarkResults:
|
|
36
|
+
"""Run benchmark in a single process and return results"""
|
|
37
|
+
benchmark = ZMQControllerBenchmark(config)
|
|
38
|
+
asyncio.run(benchmark.run_benchmark())
|
|
39
|
+
benchmark.print_results()
|
|
40
|
+
return benchmark.get_results()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def aggregate_results(
|
|
44
|
+
results_list: List[BenchmarkResults], operations: Dict[str, float]
|
|
45
|
+
) -> BenchmarkResults:
|
|
46
|
+
"""Aggregate results from multiple processes"""
|
|
47
|
+
aggregated = BenchmarkResults()
|
|
48
|
+
|
|
49
|
+
if not results_list:
|
|
50
|
+
return aggregated
|
|
51
|
+
|
|
52
|
+
# Sum up totals
|
|
53
|
+
aggregated.total_requests = sum(r.total_requests for r in results_list)
|
|
54
|
+
aggregated.total_messages = sum(r.total_messages for r in results_list)
|
|
55
|
+
aggregated.total_time = max(r.total_time for r in results_list)
|
|
56
|
+
aggregated.overall_rps = sum(r.overall_rps for r in results_list)
|
|
57
|
+
aggregated.overall_qps = sum(r.overall_qps for r in results_list)
|
|
58
|
+
|
|
59
|
+
# Aggregate memory usage
|
|
60
|
+
for r in results_list:
|
|
61
|
+
aggregated.memory_usage.extend(r.memory_usage)
|
|
62
|
+
|
|
63
|
+
# Aggregate per-operation stats
|
|
64
|
+
for op_name in operations.keys():
|
|
65
|
+
op_stats_list = [
|
|
66
|
+
r.operations[op_name] for r in results_list if op_name in r.operations
|
|
67
|
+
]
|
|
68
|
+
if op_stats_list:
|
|
69
|
+
# Sum QPS and RPS
|
|
70
|
+
total_qps = sum(s.qps for s in op_stats_list)
|
|
71
|
+
total_rps = sum(s.rps for s in op_stats_list)
|
|
72
|
+
|
|
73
|
+
# Average latencies (weighted by RPS would be more accurate,
|
|
74
|
+
# but simple average is acceptable)
|
|
75
|
+
min_latencies = [s.min_latency for s in op_stats_list if s.min_latency > 0]
|
|
76
|
+
max_latencies = [s.max_latency for s in op_stats_list if s.max_latency > 0]
|
|
77
|
+
p95_latencies = [s.p95_latency for s in op_stats_list if s.p95_latency > 0]
|
|
78
|
+
|
|
79
|
+
aggregated.operations[op_name] = OperationStats(
|
|
80
|
+
qps=total_qps,
|
|
81
|
+
rps=total_rps,
|
|
82
|
+
avg_latency=(
|
|
83
|
+
sum(s.avg_latency * s.rps for s in op_stats_list) / total_rps
|
|
84
|
+
if total_rps > 0
|
|
85
|
+
else 0.0
|
|
86
|
+
),
|
|
87
|
+
min_latency=min(min_latencies) if min_latencies else 0.0,
|
|
88
|
+
max_latency=max(max_latencies) if max_latencies else 0.0,
|
|
89
|
+
p95_latency=(
|
|
90
|
+
sum(s.p95_latency * s.rps for s in op_stats_list) / total_rps
|
|
91
|
+
if total_rps > 0 and p95_latencies
|
|
92
|
+
else 0.0
|
|
93
|
+
),
|
|
94
|
+
errors=sum(s.errors for s in op_stats_list),
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
return aggregated
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def print_aggregated_results(
|
|
101
|
+
results: BenchmarkResults,
|
|
102
|
+
config: ZMQBenchmarkConfig,
|
|
103
|
+
num_processes: int,
|
|
104
|
+
):
|
|
105
|
+
"""Print aggregated benchmark results from all processes"""
|
|
106
|
+
print("\n" + "=" * 80)
|
|
107
|
+
print(
|
|
108
|
+
"LMCache Controller ZMQ Benchmark - AGGREGATED RESULTS (%d processes)"
|
|
109
|
+
% num_processes
|
|
110
|
+
)
|
|
111
|
+
print("=" * 80)
|
|
112
|
+
|
|
113
|
+
print("\nConfiguration:")
|
|
114
|
+
print(" Controller URL: %s" % config.controller_pull_url)
|
|
115
|
+
print(" Duration: %d seconds" % config.duration)
|
|
116
|
+
print(" Batch Size: %d" % config.batch_size)
|
|
117
|
+
print(" Operations: %s" % config.operations)
|
|
118
|
+
print(
|
|
119
|
+
" Instances per process: %d, Workers: %d, Locations: %d, Keys: %d"
|
|
120
|
+
% (
|
|
121
|
+
config.num_instances,
|
|
122
|
+
config.num_workers,
|
|
123
|
+
config.num_locations,
|
|
124
|
+
config.num_keys,
|
|
125
|
+
)
|
|
126
|
+
)
|
|
127
|
+
print(" Total Instances: %d" % (config.num_instances * num_processes))
|
|
128
|
+
|
|
129
|
+
print("\nAggregated Performance:")
|
|
130
|
+
print(" Total Requests: %d" % results.total_requests)
|
|
131
|
+
print(" Total Messages: %d" % results.total_messages)
|
|
132
|
+
print(" Total Time: %.2fs" % results.total_time)
|
|
133
|
+
print(" Overall RPS (Requests/sec): %.2f" % results.overall_rps)
|
|
134
|
+
print(" Overall QPS (Messages/sec): %.2f" % results.overall_qps)
|
|
135
|
+
|
|
136
|
+
print("\nPer-Operation Performance (Aggregated):")
|
|
137
|
+
for op_name in config.operations.keys():
|
|
138
|
+
if op_name in results.operations:
|
|
139
|
+
stats = results.operations[op_name]
|
|
140
|
+
print(" %s:" % op_name)
|
|
141
|
+
print(" RPS (Requests/sec): %.2f" % stats.rps)
|
|
142
|
+
print(" QPS (Messages/sec): %.2f" % stats.qps)
|
|
143
|
+
print(
|
|
144
|
+
" Latency - Avg: %.3fms, Min: %.3fms, Max: %.3fms, P95: %.3fms"
|
|
145
|
+
% (
|
|
146
|
+
stats.avg_latency * 1000,
|
|
147
|
+
stats.min_latency * 1000,
|
|
148
|
+
stats.max_latency * 1000,
|
|
149
|
+
stats.p95_latency * 1000,
|
|
150
|
+
)
|
|
151
|
+
)
|
|
152
|
+
print(" Errors: %d" % stats.errors)
|
|
153
|
+
|
|
154
|
+
print("\nSystem Metrics (All Processes):")
|
|
155
|
+
if results.memory_usage:
|
|
156
|
+
avg_memory = statistics.mean(results.memory_usage)
|
|
157
|
+
max_memory = max(results.memory_usage)
|
|
158
|
+
print(" Memory Usage - Avg: %.1f%%, Max: %.1f%%" % (avg_memory, max_memory))
|
|
159
|
+
|
|
160
|
+
print("=" * 80)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def main():
|
|
164
|
+
"""Main function with argument parsing"""
|
|
165
|
+
parser = argparse.ArgumentParser(
|
|
166
|
+
description="LMCache Controller ZMQ Benchmark Tool",
|
|
167
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
parser.add_argument(
|
|
171
|
+
"--controller-host",
|
|
172
|
+
type=str,
|
|
173
|
+
default="127.0.0.1",
|
|
174
|
+
help="Controller host address",
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
parser.add_argument(
|
|
178
|
+
"--monitor-ports",
|
|
179
|
+
type=str,
|
|
180
|
+
default='{"pull":8100,"reply":8101}',
|
|
181
|
+
help='Monitor ports in JSON format, e.g. {"pull":8100,"reply":8101}',
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
parser.add_argument(
|
|
185
|
+
"--duration",
|
|
186
|
+
type=int,
|
|
187
|
+
default=60,
|
|
188
|
+
help="Benchmark duration in seconds",
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
parser.add_argument(
|
|
192
|
+
"--batch-size",
|
|
193
|
+
type=int,
|
|
194
|
+
default=50,
|
|
195
|
+
help="Number of KV operations per batch message",
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
parser.add_argument(
|
|
199
|
+
"--operations",
|
|
200
|
+
type=str,
|
|
201
|
+
default="admit:70,evict:25,heartbeat:5",
|
|
202
|
+
help="Operation distribution (name:percentage comma-separated)",
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
parser.add_argument(
|
|
206
|
+
"--num-instances",
|
|
207
|
+
type=int,
|
|
208
|
+
default=10,
|
|
209
|
+
help="Number of instances to simulate per process",
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
parser.add_argument(
|
|
213
|
+
"--num-workers",
|
|
214
|
+
type=int,
|
|
215
|
+
default=1,
|
|
216
|
+
help="Number of workers per instance",
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
parser.add_argument(
|
|
220
|
+
"--num-locations",
|
|
221
|
+
type=int,
|
|
222
|
+
default=1,
|
|
223
|
+
help="Number of storage locations",
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
parser.add_argument(
|
|
227
|
+
"--num-keys",
|
|
228
|
+
type=int,
|
|
229
|
+
default=10000,
|
|
230
|
+
help="Number of unique keys",
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
parser.add_argument(
|
|
234
|
+
"--num-hashes",
|
|
235
|
+
type=int,
|
|
236
|
+
default=100,
|
|
237
|
+
help="Number of hashes for P2P lookup operations",
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
parser.add_argument(
|
|
241
|
+
"--num-processes",
|
|
242
|
+
type=int,
|
|
243
|
+
default=1,
|
|
244
|
+
help="Number of concurrent benchmark processes",
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
parser.add_argument(
|
|
248
|
+
"--no-register-first",
|
|
249
|
+
action="store_true",
|
|
250
|
+
help="Skip pre-registering workers before benchmark",
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
args = parser.parse_args()
|
|
254
|
+
|
|
255
|
+
# Parse monitor ports from JSON
|
|
256
|
+
try:
|
|
257
|
+
monitor_ports = json.loads(args.monitor_ports)
|
|
258
|
+
pull_port = monitor_ports.get("pull", 8100)
|
|
259
|
+
reply_port = monitor_ports.get("reply")
|
|
260
|
+
heartbeat_port = monitor_ports.get("heartbeat")
|
|
261
|
+
except json.JSONDecodeError as e:
|
|
262
|
+
logger.error("Failed to parse monitor-ports JSON: %s", e)
|
|
263
|
+
raise ValueError("Invalid monitor-ports format") from e
|
|
264
|
+
|
|
265
|
+
# Convert 0.0.0.0 to 127.0.0.1 for client connections
|
|
266
|
+
client_host = (
|
|
267
|
+
"127.0.0.1" if args.controller_host == "0.0.0.0" else args.controller_host
|
|
268
|
+
)
|
|
269
|
+
controller_pull_url = f"{client_host}:{pull_port}"
|
|
270
|
+
controller_reply_url = f"{client_host}:{reply_port}" if reply_port else None
|
|
271
|
+
controller_heartbeat_url = (
|
|
272
|
+
f"{client_host}:{heartbeat_port}" if heartbeat_port else None
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
# Parse operations
|
|
276
|
+
operations = {}
|
|
277
|
+
for op_str in args.operations.split(","):
|
|
278
|
+
if ":" in op_str:
|
|
279
|
+
name, percentage = op_str.split(":", 1)
|
|
280
|
+
operations[name.strip()] = float(percentage.strip())
|
|
281
|
+
|
|
282
|
+
num_processes = args.num_processes
|
|
283
|
+
|
|
284
|
+
# Create a base config dict
|
|
285
|
+
base_config_kwargs = {
|
|
286
|
+
"controller_pull_url": controller_pull_url,
|
|
287
|
+
"controller_reply_url": controller_reply_url,
|
|
288
|
+
"controller_heartbeat_url": controller_heartbeat_url,
|
|
289
|
+
"duration": args.duration,
|
|
290
|
+
"batch_size": args.batch_size,
|
|
291
|
+
"operations": operations,
|
|
292
|
+
"num_instances": args.num_instances,
|
|
293
|
+
"num_workers": args.num_workers,
|
|
294
|
+
"num_locations": args.num_locations,
|
|
295
|
+
"num_keys": args.num_keys,
|
|
296
|
+
"num_hashes": args.num_hashes,
|
|
297
|
+
"register_first": not args.no_register_first,
|
|
298
|
+
"num_processes": num_processes,
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
try:
|
|
302
|
+
if num_processes == 1:
|
|
303
|
+
# Single process mode
|
|
304
|
+
config = ZMQBenchmarkConfig(**base_config_kwargs, process_id=0)
|
|
305
|
+
run_single_process(config)
|
|
306
|
+
else:
|
|
307
|
+
# Multi-process mode
|
|
308
|
+
logger.info(
|
|
309
|
+
"Starting multi-process benchmark with %d processes", num_processes
|
|
310
|
+
)
|
|
311
|
+
configs = [
|
|
312
|
+
ZMQBenchmarkConfig(**base_config_kwargs, process_id=i)
|
|
313
|
+
for i in range(num_processes)
|
|
314
|
+
]
|
|
315
|
+
# Use multiprocessing pool to run benchmarks in parallel
|
|
316
|
+
with multiprocessing.Pool(processes=num_processes) as pool:
|
|
317
|
+
results_list = pool.map(run_single_process, configs)
|
|
318
|
+
|
|
319
|
+
# Aggregate and print combined results
|
|
320
|
+
aggregated = aggregate_results(results_list, operations)
|
|
321
|
+
print_aggregated_results(aggregated, configs[0], num_processes)
|
|
322
|
+
|
|
323
|
+
except KeyboardInterrupt:
|
|
324
|
+
print("\nBenchmark interrupted by user")
|
|
325
|
+
except Exception as e:
|
|
326
|
+
logger.error("Benchmark failed: %s", e)
|
|
327
|
+
raise e
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
if __name__ == "__main__":
|
|
331
|
+
main()
|