Label
new feature, l2-adapter, multiprocess, pd-backend, pr/2
Is your feature request related to a problem? Please describe.
After PR 1/7 landed the config class, we need the actual PdL2Adapter class skeleton so that downstream PRs (submit/query API, store/load logic) have a compilable, importable, and testable foundation. Without the skeleton, no dependent PR can even import the adapter.
Describe the solution you'd like
Depends on: #217 (PR 1/7 — PdL2AdapterConfig)
-
Location & Naming
- All code in existing file:
lmcache/v1/distributed/l2_adapters/pd_l2_adapter.py (same file as config from PR 1/7; filename ends with _l2_adapter.py for auto-discovery)
- Unit test:
tests/v1/distributed/l2_adapters/test_l2_pd_adapter_skeleton.py
-
Class: PdL2Adapter(L2AdapterInterface)
- Import:
from lmcache.v1.distributed.l2_adapters.base import L2AdapterInterface
- Constructor
__init__(self, config: PdL2AdapterConfig, l1_memory_desc=None):
Constructor must initialize these members:
| Member |
Type |
Description |
self._config |
PdL2AdapterConfig |
Stored config reference |
self._role |
str |
config.role ("sender" or "receiver") |
self._store_efd |
int |
os.eventfd(0, os.EFD_NONBLOCK) for store completion |
self._lookup_efd |
int |
os.eventfd(0, os.EFD_NONBLOCK) for lookup completion |
self._load_efd |
int |
os.eventfd(0, os.EFD_NONBLOCK) for load completion |
self._staging_allocator |
Optional[PagedCpuGpuMemoryAllocator] |
None stub; real init in PR 5/7 |
self._transfer_channel |
Optional[BaseTransferChannel] |
None stub; real init in PR 5/7 |
self._zmq_context |
Optional[zmq.Context] |
None stub; real init in PR 5/7 |
self._stop_flag |
threading.Event |
For graceful shutdown |
- Call
super().__init__(max_capacity_bytes=0) (no aggregate eviction for PD).
-
Abstract method stubs — ALL must be implemented as:
def submit_store_task(self, keys, memory_objs, sizes) -> L2TaskId:
raise NotImplementedError("PdL2Adapter.submit_store_task: impl in PR 4/7")
Full list of methods to stub:
get_store_event_fd(self) -> int — return self._store_efd
get_lookup_and_lock_event_fd(self) -> int — return self._lookup_efd
get_load_event_fd(self) -> int — return self._load_efd
submit_store_task(...) — raise NotImplementedError
query_store_result(...) — raise NotImplementedError
submit_lookup_and_lock_task(...) — raise NotImplementedError
query_lookup_and_lock_result(...) — raise NotImplementedError
submit_load_task(...) — raise NotImplementedError
query_load_result(...) — raise NotImplementedError
close(self) — close 3 eventfds via os.close(), set self._stop_flag
-
Factory wiring
- In
pd_l2_adapter.py, add factory function at module level:
from lmcache.v1.distributed.l2_adapters.factory import register_l2_adapter
register_l2_adapter("pd", lambda config, **kw: PdL2Adapter(config, **kw))
- Verify the factory auto-discovery via
_l2_adapter.py suffix picks this up.
-
Unit Tests Required (test_l2_pd_adapter_skeleton.py):
- test_instantiate_sender — create with role=sender, no crash
- test_instantiate_receiver — create with role=receiver, no crash
- test_eventfd_getters_return_valid_fd — all 3 fds are ints > 0
- test_eventfd_unique — 3 fds are distinct values
- test_close_releases_fds — after close(), fds are invalid (os.write raises)
- test_stub_methods_raise — each submit/query method raises NotImplementedError
- test_stop_flag_set_on_close —
_stop_flag.is_set() after close()
- test_factory_creates_instance — factory("pd", config) returns PdL2Adapter
Describe alternatives you've considered
- Implementing full logic in one PR (too large for review, >1000 lines).
- Separate eventfd management class (over-engineering at this stage).
Additional context
- This PR delivers ZERO functional I/O — only structure, types, and eventfd plumbing.
PagedCpuGpuMemoryAllocator, TransferChannel, ZMQ are all None stubs — real init comes in PR 5/7.
- For agent: check
lmcache/v1/distributed/l2_adapters/base.py for the full list of abstract methods and their exact signatures.
Label
new feature, l2-adapter, multiprocess, pd-backend, pr/2
Is your feature request related to a problem? Please describe.
After PR 1/7 landed the config class, we need the actual
PdL2Adapterclass skeleton so that downstream PRs (submit/query API, store/load logic) have a compilable, importable, and testable foundation. Without the skeleton, no dependent PR can even import the adapter.Describe the solution you'd like
Location & Naming
lmcache/v1/distributed/l2_adapters/pd_l2_adapter.py(same file as config from PR 1/7; filename ends with_l2_adapter.pyfor auto-discovery)tests/v1/distributed/l2_adapters/test_l2_pd_adapter_skeleton.pyClass: PdL2Adapter(L2AdapterInterface)
from lmcache.v1.distributed.l2_adapters.base import L2AdapterInterface__init__(self, config: PdL2AdapterConfig, l1_memory_desc=None):Constructor must initialize these members:
self._configPdL2AdapterConfigself._rolestrconfig.role("sender" or "receiver")self._store_efdintos.eventfd(0, os.EFD_NONBLOCK)for store completionself._lookup_efdintos.eventfd(0, os.EFD_NONBLOCK)for lookup completionself._load_efdintos.eventfd(0, os.EFD_NONBLOCK)for load completionself._staging_allocatorOptional[PagedCpuGpuMemoryAllocator]Nonestub; real init in PR 5/7self._transfer_channelOptional[BaseTransferChannel]Nonestub; real init in PR 5/7self._zmq_contextOptional[zmq.Context]Nonestub; real init in PR 5/7self._stop_flagthreading.Eventsuper().__init__(max_capacity_bytes=0)(no aggregate eviction for PD).Abstract method stubs — ALL must be implemented as:
Full list of methods to stub:
get_store_event_fd(self) -> int— returnself._store_efdget_lookup_and_lock_event_fd(self) -> int— returnself._lookup_efdget_load_event_fd(self) -> int— returnself._load_efdsubmit_store_task(...)— raise NotImplementedErrorquery_store_result(...)— raise NotImplementedErrorsubmit_lookup_and_lock_task(...)— raise NotImplementedErrorquery_lookup_and_lock_result(...)— raise NotImplementedErrorsubmit_load_task(...)— raise NotImplementedErrorquery_load_result(...)— raise NotImplementedErrorclose(self)— close 3 eventfds viaos.close(), setself._stop_flagFactory wiring
pd_l2_adapter.py, add factory function at module level:_l2_adapter.pysuffix picks this up.Unit Tests Required (
test_l2_pd_adapter_skeleton.py):_stop_flag.is_set()after close()Describe alternatives you've considered
Additional context
PagedCpuGpuMemoryAllocator,TransferChannel,ZMQare allNonestubs — real init comes in PR 5/7.lmcache/v1/distributed/l2_adapters/base.pyfor the full list of abstract methods and their exact signatures.