nvalchemi.distributed.MethodAdapter#
- class nvalchemi.distributed.MethodAdapter(target=None, method_or_class=None, replacement_or_method=None, replacement=None, *, module_path=None, class_name=None, method_name=None, mode='wrap', install_site='')[source]#
Wrap a class method: intercept the call, transform an argument, then invoke the original — as opposed to
PythonAdapter/JitAdapter, which replace a module-level function outright.Some third-party models need a method-internal arg wrap that can’t be expressed by replacing a module-level helper. Canonical case: AIMNet2’s
aimnet.modules.aev.ConvSV.forward— itsconv_qpath (d2features=False) indexes a charges-derived arg that has lost ShardTensor metadata through the MLP, so it must be re-wrapped as a sharded ShardTensor before the stocka.index_select(0, nbmat.flatten()), or it reads globalnbmatindices off a rank-local tensor.replacementis a wrapping function(original, *args, **kwargs):install()captures the original (unbound) method and binds it as the first argument, so the replacement can transform args and call through. Reading per-step routing off the method’s own arguments (e.g. ConvSV’sdatadict, whichAIMNet2Wrapper.adapt_input()populates) keeps it free of ambient context — the same discipline the PythonAdapter replacements follow. Declared on a spec’sthird_party_helpersso the framework’sAdapterRegistryinstalls + restores it; no wrapperdistributed_setuphook needed.Normally name the real imported class, not a string path:
MethodAdapter(ConvSV, "forward", _rewrap_conv_q) # real class + method
The string form
MethodAdapter("module", "Class", "method", ...)is also accepted (disambiguated by the first argument’s type), so serialized dicts round-trip unchanged.- Parameters:
target (type | str | None)
method_or_class (str | None)
replacement_or_method (Any)
replacement (Callable[[...], Any] | None)
module_path (str)
class_name (str)
method_name (str)
mode (Literal['wrap', 'marshal'])
install_site (str)
- describe(state='pending', error=None)[source]#
Return an
AdapterStatussnapshot of this adapter.- Parameters:
state (Literal['pending', 'installed', 'restored', 'failed'])
error (str | None)
- Return type:
- classmethod from_dict(d)[source]#
Reconstruct a
MethodAdapterfromto_dict()output.- Parameters:
d (dict[str, Any])
- Return type:
- install()[source]#
Wrap
class.methodso calls route throughreplacement.replacement=Noneis the declaration-only form (registry no-ops); present for parity with the other adapters.mode="marshal": wrap the whole method (e.g. e3nnSphericalHarmonics.forward) withmake_marshaller()— the smallest region that resolves BOTH (A) a scripted call inside the method AND (B) a subsequent in-place mutation of a ShardTensor (e.g.sh.mul_(cat)): the marshaller unwraps the ShardTensor input to its local ONCE, so the scripted op and the in-place op both run on a plain local tensor (eager,torch.compiler.disablegraph-break), then the output is re-wrapped. Subsumes a separateJitAdapteron the inner scripted function. (B is a PyTorch AOT limitation — in-place mutation of a subclass that is a graph input across a graph break — reproduced on stockTwoTensor; keeping the region eager sidesteps it.)- Return type:
dict[str, Any]