Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
fb6028d to
14f0892
Compare
…n Ascend
LMCache core ships an EIC remote connector since LMCache#1930: the
EICConnectorAdapter registers the eic:// URL scheme and EICConnector
implements RemoteConnector. It currently cannot be imported on Ascend
because EICConnector.__init__ eagerly calls ctypes.CDLL("libcudart.so")
for the CUDA GDR path, and CANN images do not ship libcudart.
This change patches the connector through the existing lmcache_ascend
import-time framework: when libcudart is missing, the cudaMemcpy binding
becomes a no-op shim instead of raising at import. NPU deployments use
RDMA transport (eic_trans_type=2) and never enter the GDR path. No
connector is forked and no config keys change.
- add lmcache_ascend/v1/storage_backend/connector/eic_npu.py
- install the patch in __init__ alongside the other storage patches;
no-op when the connector or vendor eic package is absent
- add examples/eic config and docs
- add tests that stub the vendor eic package: import without libcudart,
idempotent patching, graceful skip when eic is unavailable
Verified locally against LMCache v0.4.4 (the version pinned on main).
14f0892 to
06a126e
Compare
|
I found two merge blockers in the current head (
A low-severity documentation issue is also present: from Static validation here: all changed Python compiles, the YAML parses, and |
0101fd3 to
295ef57
Compare
…ate tests Core LMCache#5141 loads libcudart defensively (cuda_lib stays None when the library is absent, RDMA still constructs, only explicit TRANSPORT_GDR is rejected). The Ascend ctypes shim is unnecessary against that core and wrong: intercepting CDLL returned a truthy stand-in, putting core on its load-success branch so the new cuda_lib is None GDR guard never fired. patch_eic_connector now checks the core marker _LMCACHE_EIC_CUDART_OPTIONAL and no-ops when present, installing the shim only on older core that still loads libcudart eagerly. Tests no longer reload the real vendor-bound connector with module scope, which leaked stubbed sys.modules entries and a replaced RemoteConnector base into the rest of the process. They use throwaway dummy modules with function-scoped monkeypatch, overriding both sys.modules and the parent package attribute (the dotted import resolves to a bound parent attribute first), with a real ImportError case for the absent-connector skip.
295ef57 to
4a1a726
Compare
Adds the two-constructor interleaving regression requested on LMCache#296: N concurrent guarded CDLL("libcudart.so") lookups must all receive the no-op shim, and the process-global ctypes.CDLL must remain the real callable throughout, since the module-level proxy never mutates or restores globals.
|
Thanks @matthewygf — all three are addressed on the latest head ( 1. High — 2. Medium — concurrent construction / global One additional layer matters here: the core PR #5141 now loads libcudart defensively itself ( Low — doc link. Fixed to Test notes: the suite is rewritten to function-scoped |
What
The EIC remote KV connector already exists in LMCache core (LMCache/LMCache#1930, shipped since v0.3.10):
EICConnectorAdapterregisters theeic://URL scheme andEICConnectorimplementsRemoteConnectorunderlmcache/v1/storage_backend/connector/. It currently cannot run on Ascend NPU.This PR does not add a new connector. It makes the existing one importable/usable on Ascend through the
lmcache_ascendimport-time patch framework, plus an example config, docs, and tests that need no live EIC cluster.Why it fails on NPU today
EICConnector.__init__eagerly loads CUDA at construction time (LMCache v0.4.4,eic_connector.py:135-145):CANN images do not ship libcudart, so merely selecting/importing the connector raises
OSErrorbefore theeic://adapter can be used.cudaMemcpyis only called on the CUDA GDR receive path; the NPU deployment uses RDMA (eic_trans_type: 2) and never enters that path.Changes
lmcache_ascend/v1/storage_backend/connector/eic_npu.py: an import-time patch with two modes selected by a core capability marker. Core PR fix(storage/eic): portable init, correct batched get/put and multi-group ptr for EIC connector LMCache#5141 already loads libcudart defensively (cuda_libstaysNonewhen the library is absent, RDMA works, only explicitTRANSPORT_GDRis rejected) and marks_LMCACHE_EIC_CUDART_OPTIONAL; against that core this patch is a no-op, because installing a truthy CDLL stand-in would make core take its load-success branch and defeat the newcuda_lib is NoneGDR guard. Against older core (including the v0.4.4 baseline pinned here) that still loads libcudart eagerly, it installs a guarded ctypes proxy: when the library is present behavior is unchanged; when absentCDLL("libcudart.so")yields a shim whosecudaMemcpytakes the existingargtypes/restypebinding and raises "not supported on Ascend NPU" only if the GDR path is ever entered. The proxy is installed on the connector module only, never on process-globalctypes.lmcache_ascend/__init__.pyalongside the other storage-backend patches. It is a no-op when the connector module or the vendoreicpackage is absent, so non-EIC deployments are unaffected.examples/eic/lmcache-eic-config.yaml: RDMA-oriented config with the existingeic_*keys.docs/eic_remote_backend.md: usage and constraints.tests/v1/storage_backend/test_eic_npu.py: exercises the package boundary with throwaway dummy connector modules and function-scopedmonkeypatch(no reload of the real vendor-bound module, no globalsys.modules/base-class/env leakage). Covers the no-op against marker-carrying core, proxy application + idempotency on legacy core, the shim being confined to the cudart lookup, and a genuineImportErrorskip when the connector/vendor package is absent. The dummy is bound on bothsys.modulesand the parent-package attribute, becauseimport a.b.c as xresolves to a bound parent attribute first.No connector is forked and no config keys change; selection still happens from
remote_url: eic://...via core adapter discovery.Validation
main), 4/4 passing on both x86_64 and an aarch64 Linux host without CUDA/CANN libraries.__init__raisesOSError: libcudart.so; patched init succeeds with the shim installed; an accidental GDR call raises the explicit error; other system libraries load normally.Compatibility
eicclient is not on public PyPI and ships in the vendor image, as documented in core; tests skip/stub when it is absent.