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.
Files changed (399) hide show
  1. lmcache/__init__.py +84 -0
  2. lmcache/_version.py +24 -0
  3. lmcache/cli/__init__.py +1 -0
  4. lmcache/cli/commands/__init__.py +34 -0
  5. lmcache/cli/commands/base.py +157 -0
  6. lmcache/cli/commands/bench/__init__.py +557 -0
  7. lmcache/cli/commands/bench/engine_bench/__init__.py +1 -0
  8. lmcache/cli/commands/bench/engine_bench/config.py +245 -0
  9. lmcache/cli/commands/bench/engine_bench/interactive/__init__.py +274 -0
  10. lmcache/cli/commands/bench/engine_bench/interactive/config.json +10 -0
  11. lmcache/cli/commands/bench/engine_bench/interactive/schema.py +352 -0
  12. lmcache/cli/commands/bench/engine_bench/interactive/state.py +327 -0
  13. lmcache/cli/commands/bench/engine_bench/interactive/terminal.py +291 -0
  14. lmcache/cli/commands/bench/engine_bench/progress.py +145 -0
  15. lmcache/cli/commands/bench/engine_bench/request_sender.py +232 -0
  16. lmcache/cli/commands/bench/engine_bench/stats.py +275 -0
  17. lmcache/cli/commands/bench/engine_bench/workloads/__init__.py +153 -0
  18. lmcache/cli/commands/bench/engine_bench/workloads/base.py +122 -0
  19. lmcache/cli/commands/bench/engine_bench/workloads/long_doc_permutator.py +435 -0
  20. lmcache/cli/commands/bench/engine_bench/workloads/long_doc_qa.py +281 -0
  21. lmcache/cli/commands/bench/engine_bench/workloads/multi_round_chat.py +337 -0
  22. lmcache/cli/commands/bench/engine_bench/workloads/random_prefill.py +178 -0
  23. lmcache/cli/commands/describe.py +310 -0
  24. lmcache/cli/commands/kvcache.py +133 -0
  25. lmcache/cli/commands/mock.py +75 -0
  26. lmcache/cli/commands/ping.py +113 -0
  27. lmcache/cli/commands/query/__init__.py +155 -0
  28. lmcache/cli/commands/query/prompt.py +134 -0
  29. lmcache/cli/commands/query/request.py +357 -0
  30. lmcache/cli/commands/server.py +99 -0
  31. lmcache/cli/commands/tool/__init__.py +63 -0
  32. lmcache/cli/commands/tool/cache_simulator.py +113 -0
  33. lmcache/cli/commands/trace/__init__.py +505 -0
  34. lmcache/cli/commands/trace/dispatch.py +249 -0
  35. lmcache/cli/commands/trace/driver.py +372 -0
  36. lmcache/cli/commands/trace/stats.py +289 -0
  37. lmcache/cli/documents/lmcache.txt +11 -0
  38. lmcache/cli/main.py +42 -0
  39. lmcache/cli/metrics/__init__.py +29 -0
  40. lmcache/cli/metrics/formatter.py +171 -0
  41. lmcache/cli/metrics/handler.py +94 -0
  42. lmcache/cli/metrics/metrics.py +161 -0
  43. lmcache/cli/metrics/section.py +77 -0
  44. lmcache/connections.py +173 -0
  45. lmcache/integration/__init__.py +2 -0
  46. lmcache/integration/base_service_factory.py +165 -0
  47. lmcache/integration/request_telemetry/__init__.py +1 -0
  48. lmcache/integration/request_telemetry/base.py +51 -0
  49. lmcache/integration/request_telemetry/factory.py +113 -0
  50. lmcache/integration/request_telemetry/fastapi.py +109 -0
  51. lmcache/integration/request_telemetry/noop.py +35 -0
  52. lmcache/integration/sglang/__init__.py +2 -0
  53. lmcache/integration/sglang/sglang_adapter.py +326 -0
  54. lmcache/integration/sglang/utils.py +39 -0
  55. lmcache/integration/vllm/__init__.py +1 -0
  56. lmcache/integration/vllm/lmcache_connector_v1.py +213 -0
  57. lmcache/integration/vllm/lmcache_connector_v1_085.py +150 -0
  58. lmcache/integration/vllm/lmcache_mp_connector_0180.py +1072 -0
  59. lmcache/integration/vllm/tests/test_mm_hash_utils.py +112 -0
  60. lmcache/integration/vllm/utils.py +433 -0
  61. lmcache/integration/vllm/vllm_multi_process_adapter.py +1090 -0
  62. lmcache/integration/vllm/vllm_service_factory.py +339 -0
  63. lmcache/integration/vllm/vllm_v1_adapter.py +1713 -0
  64. lmcache/logging.py +107 -0
  65. lmcache/native_storage_ops.pyi +230 -0
  66. lmcache/non_cuda_equivalents.py +1424 -0
  67. lmcache/observability.py +1958 -0
  68. lmcache/storage_backend/serde/__init__.py +1 -0
  69. lmcache/storage_backend/serde/cachegen_basics.py +210 -0
  70. lmcache/storage_backend/serde/cachegen_decoder.py +207 -0
  71. lmcache/storage_backend/serde/cachegen_encoder.py +394 -0
  72. lmcache/storage_backend/serde/serde.py +75 -0
  73. lmcache/tools/__init__.py +1 -0
  74. lmcache/tools/cache_simulator/README.md +392 -0
  75. lmcache/tools/cache_simulator/__init__.py +1 -0
  76. lmcache/tools/cache_simulator/docs/simulate_example.png +0 -0
  77. lmcache/tools/cache_simulator/docs/sweep_example.png +0 -0
  78. lmcache/tools/cache_simulator/gen_bench_dataset.py +360 -0
  79. lmcache/tools/cache_simulator/lru_cache.py +124 -0
  80. lmcache/tools/cache_simulator/plot_hit_rate.py +231 -0
  81. lmcache/tools/cache_simulator/simulator.py +795 -0
  82. lmcache/tools/controller_benchmark/README.md +161 -0
  83. lmcache/tools/controller_benchmark/__init__.py +1 -0
  84. lmcache/tools/controller_benchmark/__main__.py +331 -0
  85. lmcache/tools/controller_benchmark/benchmark.py +660 -0
  86. lmcache/tools/controller_benchmark/config.py +44 -0
  87. lmcache/tools/controller_benchmark/constants.py +10 -0
  88. lmcache/tools/controller_benchmark/handlers/__init__.py +46 -0
  89. lmcache/tools/controller_benchmark/handlers/admit.py +52 -0
  90. lmcache/tools/controller_benchmark/handlers/base.py +47 -0
  91. lmcache/tools/controller_benchmark/handlers/deregister.py +49 -0
  92. lmcache/tools/controller_benchmark/handlers/evict.py +52 -0
  93. lmcache/tools/controller_benchmark/handlers/heartbeat.py +56 -0
  94. lmcache/tools/controller_benchmark/handlers/p2p_lookup.py +47 -0
  95. lmcache/tools/controller_benchmark/handlers/register.py +56 -0
  96. lmcache/tools/mp_status_viewer/__init__.py +1 -0
  97. lmcache/tools/mp_status_viewer/__main__.py +95 -0
  98. lmcache/usage_context.py +417 -0
  99. lmcache/utils.py +665 -0
  100. lmcache/v1/__init__.py +2 -0
  101. lmcache/v1/api_server/__init__.py +2 -0
  102. lmcache/v1/api_server/__main__.py +537 -0
  103. lmcache/v1/basic_check.py +112 -0
  104. lmcache/v1/cache_controller/__init__.py +9 -0
  105. lmcache/v1/cache_controller/commands/__init__.py +15 -0
  106. lmcache/v1/cache_controller/commands/base.py +35 -0
  107. lmcache/v1/cache_controller/commands/full_sync.py +49 -0
  108. lmcache/v1/cache_controller/config.py +176 -0
  109. lmcache/v1/cache_controller/controller_manager.py +535 -0
  110. lmcache/v1/cache_controller/controllers/__init__.py +11 -0
  111. lmcache/v1/cache_controller/controllers/full_sync_tracker.py +473 -0
  112. lmcache/v1/cache_controller/controllers/kv_controller.py +439 -0
  113. lmcache/v1/cache_controller/controllers/registration_controller.py +282 -0
  114. lmcache/v1/cache_controller/executor.py +463 -0
  115. lmcache/v1/cache_controller/frontend/static/css/style.css +201 -0
  116. lmcache/v1/cache_controller/frontend/static/img/logo.png +0 -0
  117. lmcache/v1/cache_controller/frontend/static/index.html +234 -0
  118. lmcache/v1/cache_controller/frontend/static/js/controller_app.js +660 -0
  119. lmcache/v1/cache_controller/full_sync_sender.py +475 -0
  120. lmcache/v1/cache_controller/locks.py +149 -0
  121. lmcache/v1/cache_controller/message.py +828 -0
  122. lmcache/v1/cache_controller/observability.py +208 -0
  123. lmcache/v1/cache_controller/utils.py +679 -0
  124. lmcache/v1/cache_controller/worker.py +665 -0
  125. lmcache/v1/cache_engine.py +2058 -0
  126. lmcache/v1/cache_interface.py +19 -0
  127. lmcache/v1/check/__init__.py +74 -0
  128. lmcache/v1/check/check_mode_gen.py +86 -0
  129. lmcache/v1/check/check_mode_test_l2_adapter.py +284 -0
  130. lmcache/v1/check/check_mode_test_remote.py +155 -0
  131. lmcache/v1/check/check_mode_test_storage_manager.py +142 -0
  132. lmcache/v1/check/utils.py +571 -0
  133. lmcache/v1/compute/__init__.py +2 -0
  134. lmcache/v1/compute/attention/__init__.py +0 -0
  135. lmcache/v1/compute/attention/abstract.py +39 -0
  136. lmcache/v1/compute/attention/flash_attn.py +129 -0
  137. lmcache/v1/compute/attention/flash_infer_sparse.py +284 -0
  138. lmcache/v1/compute/attention/metadata.py +85 -0
  139. lmcache/v1/compute/attention/utils.py +14 -0
  140. lmcache/v1/compute/blend/__init__.py +7 -0
  141. lmcache/v1/compute/blend/blender.py +168 -0
  142. lmcache/v1/compute/blend/metadata.py +34 -0
  143. lmcache/v1/compute/blend/utils.py +63 -0
  144. lmcache/v1/compute/models/__init__.py +0 -0
  145. lmcache/v1/compute/models/base.py +141 -0
  146. lmcache/v1/compute/models/llama.py +9 -0
  147. lmcache/v1/compute/models/qwen3.py +24 -0
  148. lmcache/v1/compute/models/utils.py +68 -0
  149. lmcache/v1/compute/positional_encoding.py +199 -0
  150. lmcache/v1/config.py +848 -0
  151. lmcache/v1/config_base.py +848 -0
  152. lmcache/v1/distributed/api.py +248 -0
  153. lmcache/v1/distributed/config.py +321 -0
  154. lmcache/v1/distributed/error.py +64 -0
  155. lmcache/v1/distributed/eviction.py +192 -0
  156. lmcache/v1/distributed/eviction_policy/__init__.py +21 -0
  157. lmcache/v1/distributed/eviction_policy/factory.py +27 -0
  158. lmcache/v1/distributed/eviction_policy/lru.py +244 -0
  159. lmcache/v1/distributed/eviction_policy/noop.py +50 -0
  160. lmcache/v1/distributed/internal_api.py +170 -0
  161. lmcache/v1/distributed/l1_manager.py +835 -0
  162. lmcache/v1/distributed/l2_adapters/__init__.py +67 -0
  163. lmcache/v1/distributed/l2_adapters/base.py +360 -0
  164. lmcache/v1/distributed/l2_adapters/config.py +385 -0
  165. lmcache/v1/distributed/l2_adapters/factory.py +205 -0
  166. lmcache/v1/distributed/l2_adapters/fs_l2_adapter.py +747 -0
  167. lmcache/v1/distributed/l2_adapters/fs_native_l2_adapter.py +167 -0
  168. lmcache/v1/distributed/l2_adapters/mock_l2_adapter.py +516 -0
  169. lmcache/v1/distributed/l2_adapters/mooncake_store_l2_adapter.py +135 -0
  170. lmcache/v1/distributed/l2_adapters/native_connector_l2_adapter.py +468 -0
  171. lmcache/v1/distributed/l2_adapters/native_plugin_l2_adapter.py +199 -0
  172. lmcache/v1/distributed/l2_adapters/nixl_store_dynamic_l2_adapter.py +831 -0
  173. lmcache/v1/distributed/l2_adapters/nixl_store_l2_adapter.py +983 -0
  174. lmcache/v1/distributed/l2_adapters/plugin_l2_adapter.py +210 -0
  175. lmcache/v1/distributed/l2_adapters/resp_l2_adapter.py +176 -0
  176. lmcache/v1/distributed/memory_manager.py +179 -0
  177. lmcache/v1/distributed/storage_controller.py +39 -0
  178. lmcache/v1/distributed/storage_controllers/__init__.py +43 -0
  179. lmcache/v1/distributed/storage_controllers/eviction_controller.py +242 -0
  180. lmcache/v1/distributed/storage_controllers/prefetch_controller.py +830 -0
  181. lmcache/v1/distributed/storage_controllers/prefetch_policy.py +193 -0
  182. lmcache/v1/distributed/storage_controllers/store_controller.py +452 -0
  183. lmcache/v1/distributed/storage_controllers/store_policy.py +213 -0
  184. lmcache/v1/distributed/storage_manager.py +532 -0
  185. lmcache/v1/event_manager.py +145 -0
  186. lmcache/v1/exceptions/__init__.py +16 -0
  187. lmcache/v1/gpu_connector/__init__.py +126 -0
  188. lmcache/v1/gpu_connector/gpu_connectors.py +1906 -0
  189. lmcache/v1/gpu_connector/gpu_ops.py +85 -0
  190. lmcache/v1/gpu_connector/hpu_connector.py +326 -0
  191. lmcache/v1/gpu_connector/mock_gpu_connector.py +67 -0
  192. lmcache/v1/gpu_connector/utils.py +890 -0
  193. lmcache/v1/gpu_connector/xpu_connectors.py +916 -0
  194. lmcache/v1/health_monitor/__init__.py +1 -0
  195. lmcache/v1/health_monitor/base.py +587 -0
  196. lmcache/v1/health_monitor/checks/__init__.py +1 -0
  197. lmcache/v1/health_monitor/checks/remote_backend_check.py +304 -0
  198. lmcache/v1/health_monitor/constants.py +36 -0
  199. lmcache/v1/internal_api_server/__init__.py +0 -0
  200. lmcache/v1/internal_api_server/api_registry.py +59 -0
  201. lmcache/v1/internal_api_server/api_server.py +120 -0
  202. lmcache/v1/internal_api_server/common/__init__.py +1 -0
  203. lmcache/v1/internal_api_server/common/env_api.py +22 -0
  204. lmcache/v1/internal_api_server/common/loglevel_api.py +57 -0
  205. lmcache/v1/internal_api_server/common/metrics_api.py +29 -0
  206. lmcache/v1/internal_api_server/common/periodic_thread_api.py +138 -0
  207. lmcache/v1/internal_api_server/common/run_script_api.py +73 -0
  208. lmcache/v1/internal_api_server/common/thread_api.py +63 -0
  209. lmcache/v1/internal_api_server/controller/__init__.py +1 -0
  210. lmcache/v1/internal_api_server/controller/key_stats_api.py +81 -0
  211. lmcache/v1/internal_api_server/controller/worker_info_api.py +136 -0
  212. lmcache/v1/internal_api_server/utils.py +43 -0
  213. lmcache/v1/internal_api_server/vllm/__init__.py +1 -0
  214. lmcache/v1/internal_api_server/vllm/backend_api.py +221 -0
  215. lmcache/v1/internal_api_server/vllm/bypass_api.py +204 -0
  216. lmcache/v1/internal_api_server/vllm/cache_api.py +895 -0
  217. lmcache/v1/internal_api_server/vllm/chunk_statistics_api.py +141 -0
  218. lmcache/v1/internal_api_server/vllm/conf_api.py +147 -0
  219. lmcache/v1/internal_api_server/vllm/freeze_api.py +172 -0
  220. lmcache/v1/internal_api_server/vllm/hot_cache_api.py +184 -0
  221. lmcache/v1/internal_api_server/vllm/inference_api.py +65 -0
  222. lmcache/v1/internal_api_server/vllm/load_fs_chunks_api.py +320 -0
  223. lmcache/v1/internal_api_server/vllm/lookup_api.py +145 -0
  224. lmcache/v1/internal_api_server/vllm/version_api.py +25 -0
  225. lmcache/v1/kv_layer_groups.py +267 -0
  226. lmcache/v1/lazy_memory_allocator.py +284 -0
  227. lmcache/v1/lookup_client/__init__.py +25 -0
  228. lmcache/v1/lookup_client/abstract_client.py +77 -0
  229. lmcache/v1/lookup_client/async_lookup_message.py +50 -0
  230. lmcache/v1/lookup_client/chunk_statistics_lookup_client.py +200 -0
  231. lmcache/v1/lookup_client/factory.py +251 -0
  232. lmcache/v1/lookup_client/hit_limit_lookup_client.py +86 -0
  233. lmcache/v1/lookup_client/lmcache_async_lookup_client.py +407 -0
  234. lmcache/v1/lookup_client/lmcache_lookup_client.py +285 -0
  235. lmcache/v1/lookup_client/lmcache_lookup_client_bypass.py +99 -0
  236. lmcache/v1/lookup_client/mooncake_lookup_client.py +87 -0
  237. lmcache/v1/lookup_client/record_strategies/__init__.py +77 -0
  238. lmcache/v1/lookup_client/record_strategies/base.py +327 -0
  239. lmcache/v1/lookup_client/record_strategies/file_hash.py +130 -0
  240. lmcache/v1/lookup_client/record_strategies/memory_bloom_filter.py +81 -0
  241. lmcache/v1/manager.py +539 -0
  242. lmcache/v1/memory_management.py +2619 -0
  243. lmcache/v1/metadata.py +114 -0
  244. lmcache/v1/mp_observability/AGENTS.override.md +21 -0
  245. lmcache/v1/mp_observability/README.md +204 -0
  246. lmcache/v1/mp_observability/config.py +340 -0
  247. lmcache/v1/mp_observability/event.py +100 -0
  248. lmcache/v1/mp_observability/event_bus.py +313 -0
  249. lmcache/v1/mp_observability/otel_init.py +145 -0
  250. lmcache/v1/mp_observability/subscribers/__init__.py +28 -0
  251. lmcache/v1/mp_observability/subscribers/logging/__init__.py +19 -0
  252. lmcache/v1/mp_observability/subscribers/logging/l1.py +56 -0
  253. lmcache/v1/mp_observability/subscribers/logging/l2.py +73 -0
  254. lmcache/v1/mp_observability/subscribers/logging/lookup_hash.py +209 -0
  255. lmcache/v1/mp_observability/subscribers/logging/mp_server.py +90 -0
  256. lmcache/v1/mp_observability/subscribers/logging/sm.py +59 -0
  257. lmcache/v1/mp_observability/subscribers/metrics/__init__.py +20 -0
  258. lmcache/v1/mp_observability/subscribers/metrics/l0_lifecycle.py +290 -0
  259. lmcache/v1/mp_observability/subscribers/metrics/l1.py +55 -0
  260. lmcache/v1/mp_observability/subscribers/metrics/l1_lifecycle.py +166 -0
  261. lmcache/v1/mp_observability/subscribers/metrics/l2.py +121 -0
  262. lmcache/v1/mp_observability/subscribers/metrics/sm.py +69 -0
  263. lmcache/v1/mp_observability/subscribers/tracing/__init__.py +12 -0
  264. lmcache/v1/mp_observability/subscribers/tracing/mp_server.py +333 -0
  265. lmcache/v1/mp_observability/subscribers/tracing/span_registry.py +148 -0
  266. lmcache/v1/mp_observability/trace/__init__.py +50 -0
  267. lmcache/v1/mp_observability/trace/codecs.py +255 -0
  268. lmcache/v1/mp_observability/trace/decorator.py +147 -0
  269. lmcache/v1/mp_observability/trace/format.py +132 -0
  270. lmcache/v1/mp_observability/trace/lifecycle.py +83 -0
  271. lmcache/v1/mp_observability/trace/reader.py +167 -0
  272. lmcache/v1/mp_observability/trace/recorder.py +300 -0
  273. lmcache/v1/multiprocess/__init__.py +0 -0
  274. lmcache/v1/multiprocess/affinity_pool.py +102 -0
  275. lmcache/v1/multiprocess/blend_server_v2.py +891 -0
  276. lmcache/v1/multiprocess/config.py +253 -0
  277. lmcache/v1/multiprocess/custom_types.py +281 -0
  278. lmcache/v1/multiprocess/futures.py +194 -0
  279. lmcache/v1/multiprocess/gpu_context.py +511 -0
  280. lmcache/v1/multiprocess/http_server.py +235 -0
  281. lmcache/v1/multiprocess/mp_runtime_plugin_launcher.py +130 -0
  282. lmcache/v1/multiprocess/mq.py +732 -0
  283. lmcache/v1/multiprocess/protocol.py +86 -0
  284. lmcache/v1/multiprocess/protocols/README.md +213 -0
  285. lmcache/v1/multiprocess/protocols/__init__.py +127 -0
  286. lmcache/v1/multiprocess/protocols/base.py +89 -0
  287. lmcache/v1/multiprocess/protocols/blend.py +109 -0
  288. lmcache/v1/multiprocess/protocols/blend_v2.py +57 -0
  289. lmcache/v1/multiprocess/protocols/controller.py +53 -0
  290. lmcache/v1/multiprocess/protocols/debug.py +34 -0
  291. lmcache/v1/multiprocess/protocols/engine.py +146 -0
  292. lmcache/v1/multiprocess/protocols/observability.py +39 -0
  293. lmcache/v1/multiprocess/server.py +1134 -0
  294. lmcache/v1/multiprocess/session.py +190 -0
  295. lmcache/v1/multiprocess/token_hasher.py +441 -0
  296. lmcache/v1/offload_server/__init__.py +17 -0
  297. lmcache/v1/offload_server/abstract_server.py +37 -0
  298. lmcache/v1/offload_server/message.py +30 -0
  299. lmcache/v1/offload_server/zmq_server.py +122 -0
  300. lmcache/v1/periodic_thread.py +579 -0
  301. lmcache/v1/pin_monitor.py +246 -0
  302. lmcache/v1/plugin/__init__.py +0 -0
  303. lmcache/v1/plugin/runtime_plugin_launcher.py +211 -0
  304. lmcache/v1/protocol.py +317 -0
  305. lmcache/v1/rpc/__init__.py +17 -0
  306. lmcache/v1/rpc/transport.py +105 -0
  307. lmcache/v1/rpc/zmq_transport.py +213 -0
  308. lmcache/v1/rpc_utils.py +165 -0
  309. lmcache/v1/server/__init__.py +2 -0
  310. lmcache/v1/server/__main__.py +170 -0
  311. lmcache/v1/server/storage_backend/__init__.py +21 -0
  312. lmcache/v1/server/storage_backend/abstract_backend.py +80 -0
  313. lmcache/v1/server/storage_backend/local_backend.py +75 -0
  314. lmcache/v1/server/utils.py +21 -0
  315. lmcache/v1/standalone/__init__.py +1 -0
  316. lmcache/v1/standalone/__main__.py +583 -0
  317. lmcache/v1/standalone/manager.py +80 -0
  318. lmcache/v1/standalone/standalone_service_factory.py +86 -0
  319. lmcache/v1/storage_backend/__init__.py +313 -0
  320. lmcache/v1/storage_backend/abstract_backend.py +445 -0
  321. lmcache/v1/storage_backend/audit_backend.py +233 -0
  322. lmcache/v1/storage_backend/batched_message_sender.py +222 -0
  323. lmcache/v1/storage_backend/cache_policy/__init__.py +45 -0
  324. lmcache/v1/storage_backend/cache_policy/base_policy.py +87 -0
  325. lmcache/v1/storage_backend/cache_policy/fifo.py +58 -0
  326. lmcache/v1/storage_backend/cache_policy/lfu.py +105 -0
  327. lmcache/v1/storage_backend/cache_policy/lru.py +81 -0
  328. lmcache/v1/storage_backend/cache_policy/mru.py +61 -0
  329. lmcache/v1/storage_backend/connector/__init__.py +443 -0
  330. lmcache/v1/storage_backend/connector/audit_adapter.py +77 -0
  331. lmcache/v1/storage_backend/connector/audit_connector.py +320 -0
  332. lmcache/v1/storage_backend/connector/base_connector.py +379 -0
  333. lmcache/v1/storage_backend/connector/blackhole_adapter.py +21 -0
  334. lmcache/v1/storage_backend/connector/blackhole_connector.py +37 -0
  335. lmcache/v1/storage_backend/connector/eic_adapter.py +31 -0
  336. lmcache/v1/storage_backend/connector/eic_connector.py +757 -0
  337. lmcache/v1/storage_backend/connector/external_adapter.py +79 -0
  338. lmcache/v1/storage_backend/connector/fs_adapter.py +51 -0
  339. lmcache/v1/storage_backend/connector/fs_connector.py +403 -0
  340. lmcache/v1/storage_backend/connector/infinistore_adapter.py +56 -0
  341. lmcache/v1/storage_backend/connector/infinistore_connector.py +177 -0
  342. lmcache/v1/storage_backend/connector/instrumented_connector.py +219 -0
  343. lmcache/v1/storage_backend/connector/lm_adapter.py +31 -0
  344. lmcache/v1/storage_backend/connector/lm_connector.py +176 -0
  345. lmcache/v1/storage_backend/connector/mock_adapter.py +57 -0
  346. lmcache/v1/storage_backend/connector/mock_connector.py +349 -0
  347. lmcache/v1/storage_backend/connector/mooncakestore_adapter.py +43 -0
  348. lmcache/v1/storage_backend/connector/mooncakestore_connector.py +614 -0
  349. lmcache/v1/storage_backend/connector/redis_adapter.py +181 -0
  350. lmcache/v1/storage_backend/connector/redis_connector.py +828 -0
  351. lmcache/v1/storage_backend/connector/s3_adapter.py +59 -0
  352. lmcache/v1/storage_backend/connector/s3_connector.py +699 -0
  353. lmcache/v1/storage_backend/connector/sagemaker_hyperpod_adapter.py +233 -0
  354. lmcache/v1/storage_backend/connector/sagemaker_hyperpod_connector.py +987 -0
  355. lmcache/v1/storage_backend/connector/valkey_adapter.py +114 -0
  356. lmcache/v1/storage_backend/connector/valkey_connector.py +627 -0
  357. lmcache/v1/storage_backend/gds_backend.py +1199 -0
  358. lmcache/v1/storage_backend/job_executor/__init__.py +0 -0
  359. lmcache/v1/storage_backend/job_executor/base_executor.py +34 -0
  360. lmcache/v1/storage_backend/job_executor/pq_executor.py +235 -0
  361. lmcache/v1/storage_backend/local_cpu_backend.py +810 -0
  362. lmcache/v1/storage_backend/local_disk_backend.py +656 -0
  363. lmcache/v1/storage_backend/maru_backend.py +734 -0
  364. lmcache/v1/storage_backend/naive_serde/__init__.py +50 -0
  365. lmcache/v1/storage_backend/naive_serde/cachegen_basics.py +133 -0
  366. lmcache/v1/storage_backend/naive_serde/cachegen_decoder.py +135 -0
  367. lmcache/v1/storage_backend/naive_serde/cachegen_encoder.py +83 -0
  368. lmcache/v1/storage_backend/naive_serde/kivi_serde.py +22 -0
  369. lmcache/v1/storage_backend/naive_serde/naive_serde.py +18 -0
  370. lmcache/v1/storage_backend/naive_serde/serde.py +37 -0
  371. lmcache/v1/storage_backend/native_clients/connector_client_base.py +165 -0
  372. lmcache/v1/storage_backend/native_clients/resp_client.py +35 -0
  373. lmcache/v1/storage_backend/nixl_storage_backend.py +1400 -0
  374. lmcache/v1/storage_backend/p2p_backend.py +788 -0
  375. lmcache/v1/storage_backend/path_sharder.py +117 -0
  376. lmcache/v1/storage_backend/pd_backend.py +646 -0
  377. lmcache/v1/storage_backend/plugins/dax_backend.py +1443 -0
  378. lmcache/v1/storage_backend/plugins/rust_raw_block_backend.py +1361 -0
  379. lmcache/v1/storage_backend/remote_backend.py +624 -0
  380. lmcache/v1/storage_backend/resp_client.py +227 -0
  381. lmcache/v1/storage_backend/storage_backend_listener.py +19 -0
  382. lmcache/v1/storage_backend/storage_manager.py +1352 -0
  383. lmcache/v1/system_detection.py +110 -0
  384. lmcache/v1/token_database.py +551 -0
  385. lmcache/v1/transfer_channel/__init__.py +83 -0
  386. lmcache/v1/transfer_channel/abstract.py +285 -0
  387. lmcache/v1/transfer_channel/mock_memory_channel.py +156 -0
  388. lmcache/v1/transfer_channel/nixl_channel.py +639 -0
  389. lmcache/v1/transfer_channel/py_socket_channel.py +260 -0
  390. lmcache/v1/transfer_channel/transfer_utils.py +63 -0
  391. lmcache/v1/utils/__init__.py +1 -0
  392. lmcache/v1/utils/bloom_filter.py +109 -0
  393. lmcache/v1/utils/cache_utils.py +125 -0
  394. lmcache_cli-0.4.5.dev0.dist-info/METADATA +185 -0
  395. lmcache_cli-0.4.5.dev0.dist-info/RECORD +399 -0
  396. lmcache_cli-0.4.5.dev0.dist-info/WHEEL +5 -0
  397. lmcache_cli-0.4.5.dev0.dist-info/entry_points.txt +2 -0
  398. lmcache_cli-0.4.5.dev0.dist-info/licenses/LICENSE +201 -0
  399. lmcache_cli-0.4.5.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,210 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """
3
+ Plugin L2 adapter -- dynamically loads an external adapter
4
+ class from a user-supplied Python module.
5
+ """
6
+
7
+ # Future
8
+ from __future__ import annotations
9
+
10
+ # Standard
11
+ from typing import TYPE_CHECKING, Any, Optional
12
+ import importlib
13
+
14
+ if TYPE_CHECKING:
15
+ # First Party
16
+ from lmcache.v1.distributed.internal_api import (
17
+ L1MemoryDesc,
18
+ )
19
+
20
+ # First Party
21
+ from lmcache.v1.distributed.l2_adapters.base import L2AdapterInterface as _L2AI
22
+ from lmcache.v1.distributed.l2_adapters.config import (
23
+ L2AdapterConfigBase,
24
+ register_l2_adapter_type,
25
+ )
26
+ from lmcache.v1.distributed.l2_adapters.factory import (
27
+ register_l2_adapter_factory,
28
+ )
29
+
30
+ # Config class
31
+
32
+
33
+ class PluginL2AdapterConfig(L2AdapterConfigBase):
34
+ """
35
+ Config for a plugin L2 adapter.
36
+
37
+ Dynamically loads an adapter class from a user-supplied
38
+ Python module at creation time.
39
+
40
+ Fields:
41
+ - module_path: Dotted Python import path of the module
42
+ containing the adapter class.
43
+ - class_name: Name of the class inside *module_path*
44
+ that implements ``L2AdapterInterface``.
45
+ - adapter_params: Arbitrary dict forwarded to the
46
+ adapter class constructor.
47
+ - config_class_name: Optional name of a config class
48
+ inside *module_path* that subclasses
49
+ ``L2AdapterConfigBase``. When set, the factory
50
+ builds a config instance via ``from_dict()`` and
51
+ passes it (instead of a raw dict) to the adapter
52
+ constructor -- matching the built-in convention.
53
+ """
54
+
55
+ def __init__(
56
+ self,
57
+ module_path: str,
58
+ class_name: str,
59
+ adapter_params: dict[str, Any] | None = None,
60
+ config_class_name: str | None = None,
61
+ ):
62
+ self.module_path = module_path
63
+ self.class_name = class_name
64
+ self.adapter_params = adapter_params or {}
65
+ self.config_class_name = config_class_name
66
+
67
+ @classmethod
68
+ def from_dict(cls, d: dict) -> "PluginL2AdapterConfig":
69
+ module_path = d.get("module_path")
70
+ if not isinstance(module_path, str) or not module_path:
71
+ raise ValueError("module_path must be a non-empty string")
72
+
73
+ class_name = d.get("class_name")
74
+ if not isinstance(class_name, str) or not class_name:
75
+ raise ValueError("class_name must be a non-empty string")
76
+
77
+ adapter_params = d.get("adapter_params", {})
78
+ if not isinstance(adapter_params, dict):
79
+ raise ValueError("adapter_params must be a dict")
80
+
81
+ config_class_name = d.get("config_class_name")
82
+ if config_class_name is not None and not isinstance(config_class_name, str):
83
+ raise ValueError("config_class_name must be a string")
84
+
85
+ return cls(
86
+ module_path=module_path,
87
+ class_name=class_name,
88
+ adapter_params=adapter_params,
89
+ config_class_name=config_class_name,
90
+ )
91
+
92
+ @classmethod
93
+ def help(cls) -> str:
94
+ return (
95
+ "Plugin L2 adapter config fields:\n"
96
+ "- module_path (str): dotted import path of "
97
+ "the module containing the adapter class "
98
+ "(required)\n"
99
+ "- class_name (str): name of the adapter "
100
+ "class inside the module (required)\n"
101
+ "- adapter_params (dict): forwarded to the "
102
+ "adapter constructor "
103
+ "(optional, default {})\n"
104
+ "- config_class_name (str): explicit config "
105
+ "class name; when omitted the factory "
106
+ "auto-discovers it (see plugin.md)\n"
107
+ "\n"
108
+ "Example JSON (raw dict):\n"
109
+ '{"type": "plugin", '
110
+ '"module_path": "my_plugin.l2", '
111
+ '"class_name": "MyL2Adapter", '
112
+ '"adapter_params": {"host": "localhost"}}\n'
113
+ "\n"
114
+ "Example JSON (with config class):\n"
115
+ '{"type": "plugin", '
116
+ '"module_path": "my_plugin.l2", '
117
+ '"class_name": "MyL2Adapter", '
118
+ '"config_class_name": "MyL2AdapterConfig", '
119
+ '"adapter_params": {"host": "localhost"}}'
120
+ )
121
+
122
+
123
+ # Factory function
124
+
125
+
126
+ def _create_plugin_adapter(
127
+ config: L2AdapterConfigBase,
128
+ l1_memory_desc: "Optional[L1MemoryDesc]" = None,
129
+ ) -> _L2AI:
130
+ """Dynamically load and create a plugin L2 adapter."""
131
+ assert isinstance(config, PluginL2AdapterConfig)
132
+
133
+ try:
134
+ module = importlib.import_module(config.module_path)
135
+ except ImportError as e:
136
+ raise ImportError(
137
+ "Could not import module '%s': %s" % (config.module_path, e)
138
+ ) from e
139
+
140
+ try:
141
+ adapter_cls = getattr(module, config.class_name)
142
+ except AttributeError as e:
143
+ raise AttributeError(
144
+ "Module '%s' has no class '%s': %s"
145
+ % (config.module_path, config.class_name, e)
146
+ ) from e
147
+
148
+ if not (isinstance(adapter_cls, type) and issubclass(adapter_cls, _L2AI)):
149
+ raise TypeError(
150
+ "%s.%s is not a subclass of "
151
+ "L2AdapterInterface" % (config.module_path, config.class_name)
152
+ )
153
+
154
+ cfg_cls = _resolve_config_class(
155
+ module,
156
+ config,
157
+ adapter_cls,
158
+ )
159
+ kwargs: dict[str, object] = {}
160
+ if l1_memory_desc is not None:
161
+ kwargs["l1_memory_desc"] = l1_memory_desc
162
+
163
+ if cfg_cls is not None:
164
+ return adapter_cls( # type: ignore[call-arg]
165
+ cfg_cls.from_dict(config.adapter_params),
166
+ **kwargs,
167
+ )
168
+
169
+ return adapter_cls( # type: ignore[call-arg]
170
+ config.adapter_params,
171
+ **kwargs,
172
+ )
173
+
174
+
175
+ def _resolve_config_class(
176
+ module: object,
177
+ config: PluginL2AdapterConfig,
178
+ adapter_cls: type,
179
+ ) -> type[L2AdapterConfigBase] | None:
180
+ """Resolve the config class for a plugin adapter.
181
+
182
+ Discovery order:
183
+ 1. Explicit ``config.config_class_name`` field.
184
+ 2. Convention: ``config.class_name`` + ``"Config"``.
185
+ 3. ``config_class_name`` attribute on the adapter
186
+ class itself.
187
+ 4. ``None`` -- fall back to raw dict mode.
188
+ """
189
+ candidates: list[str | None] = [
190
+ config.config_class_name,
191
+ config.class_name + "Config",
192
+ getattr(adapter_cls, "config_class_name", None),
193
+ ]
194
+ for name in candidates:
195
+ if not name:
196
+ continue
197
+ cls = getattr(module, name, None)
198
+ if cls is None:
199
+ continue
200
+ if isinstance(cls, type) and issubclass(
201
+ cls,
202
+ L2AdapterConfigBase,
203
+ ):
204
+ return cls
205
+ return None
206
+
207
+
208
+ # Self-register config type and adapter factory
209
+ register_l2_adapter_type("plugin", PluginL2AdapterConfig)
210
+ register_l2_adapter_factory("plugin", _create_plugin_adapter)
@@ -0,0 +1,176 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """
3
+ RESP (Redis/Valkey) L2 adapter config and factory.
4
+
5
+ Backed by the native C++ Redis connector wrapped with
6
+ ``NativeConnectorL2Adapter``.
7
+ """
8
+
9
+ # Future
10
+ from __future__ import annotations
11
+
12
+ # Standard
13
+ from typing import TYPE_CHECKING, Optional
14
+ import os
15
+
16
+ if TYPE_CHECKING:
17
+ from lmcache.v1.distributed.internal_api import (
18
+ L1MemoryDesc,
19
+ )
20
+
21
+ # First Party
22
+ from lmcache.logging import init_logger
23
+ from lmcache.v1.distributed.l2_adapters.base import (
24
+ L2AdapterInterface,
25
+ )
26
+ from lmcache.v1.distributed.l2_adapters.config import (
27
+ L2AdapterConfigBase,
28
+ register_l2_adapter_type,
29
+ )
30
+ from lmcache.v1.distributed.l2_adapters.factory import (
31
+ register_l2_adapter_factory,
32
+ )
33
+
34
+ logger = init_logger(__name__)
35
+
36
+
37
+ class RESPL2AdapterConfig(L2AdapterConfigBase):
38
+ """
39
+ Config for an L2 adapter backed by a native RESP
40
+ connector (Redis/Valkey).
41
+
42
+ Fields:
43
+ - host: server hostname or IP.
44
+ - port: server port.
45
+ - num_workers: C++ worker threads for I/O (default 8).
46
+ - username: optional auth username.
47
+ - password: optional auth password.
48
+ """
49
+
50
+ def __init__(
51
+ self,
52
+ host: str,
53
+ port: int,
54
+ num_workers: int = 8,
55
+ username: str = "",
56
+ password: str = "",
57
+ max_capacity_gb: float = 0,
58
+ ):
59
+ super().__init__()
60
+ self.host = host
61
+ self.port = port
62
+ self.num_workers = num_workers
63
+ self.username = username
64
+ self.password = password
65
+ self.max_capacity_gb = max_capacity_gb
66
+
67
+ @classmethod
68
+ def from_dict(cls, d: dict) -> "RESPL2AdapterConfig":
69
+ host = d.get("host")
70
+ if not isinstance(host, str) or not host:
71
+ raise ValueError("host must be a non-empty string")
72
+
73
+ port = d.get("port")
74
+ if not isinstance(port, int) or port <= 0:
75
+ raise ValueError("port must be a positive integer")
76
+
77
+ num_workers = d.get("num_workers", 8)
78
+ if not isinstance(num_workers, int) or num_workers <= 0:
79
+ raise ValueError("num_workers must be a positive integer")
80
+
81
+ username = d.get("username", "")
82
+ password = d.get("password", "")
83
+
84
+ max_capacity_gb = d.get("max_capacity_gb", 0)
85
+ if not isinstance(max_capacity_gb, (int, float)) or max_capacity_gb < 0:
86
+ raise ValueError("max_capacity_gb must be a non-negative number")
87
+
88
+ return cls(
89
+ host=host,
90
+ port=port,
91
+ num_workers=num_workers,
92
+ username=str(username),
93
+ password=str(password),
94
+ max_capacity_gb=float(max_capacity_gb),
95
+ )
96
+
97
+ @classmethod
98
+ def help(cls) -> str:
99
+ return (
100
+ "RESP L2 adapter config fields:\n"
101
+ "- host (str): Redis/Valkey server hostname "
102
+ "or IP (required)\n"
103
+ "- port (int): server port (required, >0)\n"
104
+ "- num_workers (int): C++ worker threads "
105
+ "for I/O (default 8, >0)\n"
106
+ "- username (str): auth username "
107
+ "(default empty)\n"
108
+ "- password (str): auth password "
109
+ "(default empty)\n"
110
+ "- max_capacity_gb (float): max L2 capacity "
111
+ "in GB for usage tracking / eviction "
112
+ "(default 0 = disabled)\n\n"
113
+ "Environment variable defaults (used when "
114
+ "config value is empty, read at adapter "
115
+ "creation, not stored in config):\n"
116
+ "- LMCACHE_RESP_USERNAME: default username\n"
117
+ "- LMCACHE_RESP_PASSWORD: default password\n"
118
+ "- LMCACHE_RESP_HOST: default host\n"
119
+ "- LMCACHE_RESP_PORT: default port"
120
+ )
121
+
122
+
123
+ def _create_resp_l2_adapter(
124
+ config: L2AdapterConfigBase,
125
+ l1_memory_desc: "Optional[L1MemoryDesc]" = None,
126
+ ) -> L2AdapterInterface:
127
+ """Create a NativeConnectorL2Adapter backed by the
128
+ C++ Redis connector."""
129
+ try:
130
+ # First Party
131
+ from lmcache.lmcache_redis import (
132
+ LMCacheRedisClient,
133
+ )
134
+ except ImportError as e:
135
+ raise RuntimeError(
136
+ "RESP L2 adapter requires the C++ Redis "
137
+ "extension. Build with: pip install -e ."
138
+ ) from e
139
+
140
+ # Lazy import to avoid circular dependency
141
+ # First Party
142
+ from lmcache.v1.distributed.l2_adapters.native_connector_l2_adapter import ( # noqa: E501
143
+ NativeConnectorL2Adapter,
144
+ )
145
+
146
+ assert isinstance(config, RESPL2AdapterConfig)
147
+
148
+ # Config/CLI args take precedence over environment variables,
149
+ # which serve as defaults. This keeps secrets out of logged
150
+ # config while allowing explicit CLI overrides.
151
+ host = config.host or os.environ.get("LMCACHE_RESP_HOST", "")
152
+ port = config.port if config.port else int(os.environ.get("LMCACHE_RESP_PORT", "0"))
153
+ username = config.username or os.environ.get("LMCACHE_RESP_USERNAME", "")
154
+ password = config.password or os.environ.get("LMCACHE_RESP_PASSWORD", "")
155
+
156
+ native_client = LMCacheRedisClient(
157
+ host,
158
+ port,
159
+ config.num_workers,
160
+ username,
161
+ password,
162
+ )
163
+ logger.info(
164
+ "Created RESP L2 adapter: %s:%d (workers=%d)",
165
+ host,
166
+ port,
167
+ config.num_workers,
168
+ )
169
+ return NativeConnectorL2Adapter(
170
+ native_client, max_capacity_gb=config.max_capacity_gb
171
+ )
172
+
173
+
174
+ # Self-register config type and adapter factory
175
+ register_l2_adapter_type("resp", RESPL2AdapterConfig)
176
+ register_l2_adapter_factory("resp", _create_resp_l2_adapter)
@@ -0,0 +1,179 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+
3
+ # First Party
4
+ from lmcache.logging import init_logger
5
+ from lmcache.v1.distributed.api import MemoryLayoutDesc
6
+ from lmcache.v1.distributed.config import L1MemoryManagerConfig
7
+ from lmcache.v1.distributed.error import L1Error
8
+ from lmcache.v1.distributed.internal_api import L1MemoryDesc
9
+ from lmcache.v1.lazy_memory_allocator import LazyMemoryAllocator
10
+ from lmcache.v1.memory_management import (
11
+ MemoryAllocatorInterface,
12
+ MemoryObj,
13
+ MixedMemoryAllocator,
14
+ )
15
+
16
+ logger = init_logger(__name__)
17
+
18
+
19
+ # HELPER FUNCTIONS
20
+ def create_memory_allocator(config: L1MemoryManagerConfig) -> MemoryAllocatorInterface:
21
+ """
22
+ Create a memory allocator based on the provided configuration.
23
+
24
+ Args:
25
+ config (L1MemoryManagerConfig): Configuration for the memory manager.
26
+
27
+ Returns:
28
+ MemoryAllocatorInterface: An instance of a memory allocator.
29
+ """
30
+ if config.use_lazy:
31
+ logger.debug(
32
+ "use lazy memory allocator, init size is %d bytes, "
33
+ "final size is %d bytes, align bytes is %d bytes",
34
+ config.init_size_in_bytes,
35
+ config.size_in_bytes,
36
+ config.align_bytes,
37
+ )
38
+ return LazyMemoryAllocator(
39
+ config.init_size_in_bytes, config.size_in_bytes, config.align_bytes
40
+ )
41
+ else:
42
+ logger.debug(
43
+ "use mixed memory allocator, total size is %d bytes, "
44
+ "align bytes is %d bytes",
45
+ config.size_in_bytes,
46
+ config.align_bytes,
47
+ )
48
+ return MixedMemoryAllocator(
49
+ config.size_in_bytes,
50
+ align_bytes=config.align_bytes,
51
+ )
52
+
53
+
54
+ # MAIN CLASS
55
+ class L1MemoryManager:
56
+ """
57
+ L1MemoryManager manages the allocation and deallocation of L1 memory.
58
+
59
+ Observability metrics to emit:
60
+ 1. Memory usage
61
+ 2. Active allocations
62
+ """
63
+
64
+ def __init__(self, config: L1MemoryManagerConfig):
65
+ self._allocator = create_memory_allocator(config)
66
+ self._size_in_bytes = config.size_in_bytes
67
+ self._align_bytes = config.align_bytes
68
+
69
+ def allocate(
70
+ self, layout_desc: MemoryLayoutDesc, count: int
71
+ ) -> tuple[L1Error, list[MemoryObj]]:
72
+ """
73
+ Allocate memory objects based on the provided layout description and count.
74
+ This function should be thread-safe
75
+
76
+ Args:
77
+ layout_desc (MemoryLayoutDesc): Description of the memory layout.
78
+ count (int): Number of memory objects to allocate.
79
+
80
+ Returns:
81
+ tuple[L1Error, list[MemoryObj]]: Error code and list of
82
+ allocated memory objects.
83
+ Error code will be `L1Error.OUT_OF_MEMORY` if allocation
84
+ fails; otherwise, it will be `L1Error.SUCCESS`.
85
+
86
+ Note:
87
+ If the allocation fails, the memory object list will be empty.
88
+ """
89
+ objects = self._allocator.batched_allocate(
90
+ layout_desc.shapes, layout_desc.dtypes, count
91
+ )
92
+ if objects is None:
93
+ return L1Error.OUT_OF_MEMORY, []
94
+ return L1Error.SUCCESS, objects
95
+
96
+ def free(self, mem_objs: list[MemoryObj]) -> L1Error:
97
+ """
98
+ Free the provided memory objects.
99
+ This function should be thread-safe.
100
+
101
+ Args:
102
+ mem_objs (list[MemoryObj]): List of memory objects to free.
103
+
104
+ Returns:
105
+ L1Error: Error code indicating the result of the operation.
106
+ It will be `L1Error.SUCCESS` if the operation succeeds.
107
+ """
108
+ self._allocator.batched_free(mem_objs)
109
+ return L1Error.SUCCESS
110
+
111
+ def get_memory_usage(self) -> tuple[int, int]:
112
+ """
113
+ Get the current memory usage. This function will mainly be used to support
114
+ eviction decision.
115
+
116
+ Returns:
117
+ tuple[int, int]: A tuple containing used memory in bytes and total memory
118
+ in bytes.
119
+
120
+ Note:
121
+ In the future, we may want to make a "callback" based mechanism to
122
+ trigger eviction when the memory usage reaches a watermark.
123
+ """
124
+
125
+ # HACK: now trying to read this from the address manager in a ad-hoc
126
+ # manner
127
+ def get_address_manager(allocator: MemoryAllocatorInterface):
128
+ if isinstance(allocator, MixedMemoryAllocator) and hasattr(
129
+ allocator.pin_allocator, "address_manager"
130
+ ):
131
+ return allocator.pin_allocator.address_manager
132
+ elif isinstance(allocator, LazyMemoryAllocator):
133
+ return allocator.get_address_manager()
134
+ else:
135
+ raise NotImplementedError(
136
+ "get_memory_usage is not implemented for this allocator type."
137
+ )
138
+
139
+ address_manager = get_address_manager(self._allocator)
140
+ free_size = address_manager.get_free_size()
141
+ total_size = address_manager.get_heap_size()
142
+ used_size = total_size - free_size
143
+ return used_size, total_size
144
+
145
+ def get_l1_memory_desc(self) -> L1MemoryDesc:
146
+ """
147
+ Return an L1MemoryDesc describing the underlying memory buffer.
148
+
149
+ Returns:
150
+ L1MemoryDesc: Pointer, size, and alignment of the L1 buffer.
151
+
152
+ Raises:
153
+ NotImplementedError: If the allocator type does not support this operation.
154
+ """
155
+ if isinstance(self._allocator, MixedMemoryAllocator):
156
+ buffer = self._allocator.buffer
157
+ elif isinstance(self._allocator, LazyMemoryAllocator):
158
+ # TODO(ApostaC): need to test if the RDMA registration works
159
+ # before the lazy expansion is finished
160
+ buffer = self._allocator.get_underlying_buffer()
161
+ else:
162
+ raise NotImplementedError(
163
+ "get_l1_memory_desc is not implemented for this allocator type."
164
+ )
165
+ return L1MemoryDesc(
166
+ ptr=buffer.data_ptr(),
167
+ size=self._size_in_bytes,
168
+ align_bytes=self._align_bytes,
169
+ )
170
+
171
+ def close(self) -> None:
172
+ """
173
+ Close the memory manager and release all resources.
174
+ """
175
+ self._allocator.close()
176
+
177
+ # Debugging APIs
178
+ def memcheck(self):
179
+ return self._allocator.memcheck()
@@ -0,0 +1,39 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """
3
+ Interface for storage controllers
4
+
5
+ Storage controllers are separate modules/threads that sees the L1 Manager
6
+ and can operate on it.
7
+ """
8
+
9
+ # Standard
10
+ from abc import ABC, abstractmethod
11
+
12
+
13
+ class StorageControllerInterface(ABC):
14
+ @abstractmethod
15
+ def start(self):
16
+ """
17
+ Start the storage controller.
18
+ This function should be implemented by subclasses to start
19
+ any necessary threads or processes.
20
+ """
21
+ pass
22
+
23
+ @abstractmethod
24
+ def stop(self):
25
+ """
26
+ Stop the storage controller.
27
+ This function should be implemented by subclasses to stop
28
+ any running threads or processes.
29
+ """
30
+ pass
31
+
32
+ @abstractmethod
33
+ def report_status(self) -> dict:
34
+ """
35
+ Return a status dict for this controller.
36
+
37
+ Must include at least ``is_healthy: bool``.
38
+ """
39
+ pass
@@ -0,0 +1,43 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """
3
+ Storage controllers with automatic module discovery.
4
+
5
+ All modules under this package that call ``register_store_policy`` or
6
+ ``register_prefetch_policy`` at import time are discovered automatically.
7
+ To add a new policy, simply create a new module in this directory -- **no
8
+ changes to any existing file are needed**.
9
+ """
10
+
11
+ # Standard
12
+ import importlib
13
+ import pkgutil
14
+
15
+ # First Party
16
+ from lmcache.v1.distributed.storage_controllers.eviction_controller import (
17
+ EvictionController,
18
+ L1EvictionController,
19
+ L2AdapterEvictionState,
20
+ L2EvictionController,
21
+ )
22
+ from lmcache.v1.distributed.storage_controllers.prefetch_controller import (
23
+ PrefetchController,
24
+ )
25
+ from lmcache.v1.distributed.storage_controllers.store_controller import (
26
+ StoreController,
27
+ )
28
+
29
+ # Auto-discover and import every module in this package so
30
+ # that each policy's self-registration code runs.
31
+ _PACKAGE_PATH = __path__ # type: ignore[name-defined]
32
+ _PACKAGE_NAME = __name__
33
+ for _finder, _mod_name, _is_pkg in pkgutil.iter_modules(_PACKAGE_PATH):
34
+ importlib.import_module(f".{_mod_name}", _PACKAGE_NAME)
35
+
36
+ __all__ = [
37
+ "EvictionController",
38
+ "L1EvictionController",
39
+ "L2EvictionController",
40
+ "L2AdapterEvictionState",
41
+ "PrefetchController",
42
+ "StoreController",
43
+ ]