fhelium.distributed._typed_collectives
Private aggregation point for FHElium's typed collectives.
Implementations live in responsibility-specific modules. The public fhelium.distributed facade imports through this module to keep its surface unchanged.
all_gather_ciphertexts
function View source
def all_gather_ciphertexts(value: Ciphertext, *, group: torch.distributed.ProcessGroup | None=None) -> list[Ciphertext]: ...All-gather independent ciphertexts with one identical layout.
Equality covers context, depth, scale, components, prime IDs, domain, basis, Montgomery state, degree, shape, and dtype. Rank-local CUDA device indices may differ because descriptors intentionally preserve device type rather than one global device index. This is transport of independent values, not algebraic reduction. The operation is synchronous, accepts no async_op argument, and returns no torch.distributed.Work.
Parameters
value: One independent rank-local ciphertext. All group ranks must provide ciphertexts with identical layout metadata. The input is read but not mutated.group: Participating process group.Noneselects the default process group. No root rank is used.
Returns
A newly allocated list on every rank containing one ciphertext per group rank in process-group-rank order. Entries, including the caller's entry, are new ciphertext objects whose tensors use the same device as the caller's input. For world size one, a one-element copied result is returned.
Raises
TypeError: Ifvalueis not a ciphertext.ValueError: If ciphertext shapes or arithmetic metadata differ across group ranks.RuntimeError: If distributed communication is uninitialized or the caller is not a member ofgroup.
all_gather_compressed_plaintexts
function View source
def all_gather_compressed_plaintexts(value: CompressedPlaintext, *, group: torch.distributed.ProcessGroup | None=None) -> list[CompressedPlaintext]: ...All-gather independent compressed plaintexts sharing one layout.
all_gather_plaintexts
function View source
def all_gather_plaintexts(value: Plaintext, *, group: torch.distributed.ProcessGroup | None=None) -> list[Plaintext]: ...All-gather independent plaintexts with one arithmetic state.
Every rank must provide the same message/encoded representation kind, shape, dtype, context, depth, scale, layout, domain, basis, Montgomery state, and prime IDs. This is representation-preserving transport, not an arithmetic operation. It is synchronous, accepts no async_op argument, and returns no torch.distributed.Work.
Parameters
value: One independent rank-local plaintext. It is read but not mutated.group: Participating process group.Noneselects the default process group. No root rank is used.
Returns
A newly allocated list on every rank containing one plaintext per group rank in process-group-rank order. Entries, including the caller's entry, are new plaintext objects whose tensors use the same device as the caller's input. For world size one, a one-element copied result is returned.
Raises
TypeError: Ifvalueis not a plaintext.ValueError: If plaintext representations, shapes, or arithmetic metadata differ across group ranks.RuntimeError: If distributed communication is uninitialized or the caller is not a member ofgroup.
all_reduce_ciphertext
function View source
def all_reduce_ciphertext(value: Ciphertext, *, engine: Engine, group: torch.distributed.ProcessGroup | None=None) -> None: ...Synchronously sum ciphertext partials and update every rank in place.
The reduction phase uses the arbitrary-world-size binomial tree documented by reduce_ciphertext. The root then uses a representation-preserving tensor broadcast because broadcasting ciphertext payload bits requires no arithmetic specialization. Asynchronous composite Work semantics are intentionally deferred until a measured workload demonstrates useful communication/add overlap. The implicit root is the first global rank in process-group-rank order.
Parameters
value: Rank-local additive ciphertext partial. Every rank's object is overwritten in place with the component-wise CKKS sum modulo the active Q primes. Non-overlapping strided views retain their Tensor storage and are updated through any existing aliases.engine: Rank-local CKKS engine used during tree reduction. Every participating rank must provide an engine compatible with itsvalue.group: Participating process group.Noneselects the default process group. No caller-selected root is used.
Returns
None. Every rank's existing value object contains the global sum after return. For world size one, the value remains unchanged. The function accepts no async_op argument and returns no torch.distributed.Work.
Raises
ValueError: If rank-local values are not ciphertexts with identical shape and arithmetic metadata, or an engine rejects an incompatible value.RuntimeError: If distributed communication is uninitialized or the caller is not a member ofgroup.
broadcast_ciphertext
function View source
def broadcast_ciphertext(value_or_none: Ciphertext | None, *, src: int=0, group: torch.distributed.ProcessGroup | None=None) -> Ciphertext: ...Broadcast one complete ciphertext and allocate non-source receivers.
A small internal object descriptor carries shape and CKKS metadata; the dense payload then uses the ordinary tensor broadcast. No placement or owner policy is inferred. The operation is synchronous: it accepts no async_op argument and returns no torch.distributed.Work.
Parameters
value_or_none: Ciphertext supplied only bysrc. Every non-source rank must passNone.src: Global rank of the source process, which must belong togroup. This is not a process-group-relative rank.group: Participating process group.Noneselects the default process group.
Returns
The source's original ciphertext on src and a newly allocated, metadata-equivalent ciphertext on every other group rank. For a world-size-one group, the source object is returned unchanged and no payload communication or receiver allocation occurs.
Raises
ValueError: Ifsrcis outsidegroupor ranks violate the source/non-source argument rules.RuntimeError: If distributed communication is uninitialized, the caller is not a group member, or a valid transfer descriptor cannot be exchanged.
broadcast_compressed_plaintext
function View source
def broadcast_compressed_plaintext(value_or_none: CompressedPlaintext | None, *, src: int=0, group: torch.distributed.ProcessGroup | None=None) -> CompressedPlaintext: ...Broadcast one compressed plaintext with typed allocation.
The compact tensor, ring dimension, encoded repetition layout, and all arithmetic metadata are preserved. The operation is synchronous.
broadcast_key
function View source
def broadcast_key(key_or_none: _KeyT | None, *, src: int=0, group: torch.distributed.ProcessGroup | None=None) -> _KeyT: ...Broadcast selected key material with typed allocation.
The function performs no key generation, owner inference, or automatic placement. Calling it is the program's visible decision to communicate one selected key. It is synchronous, accepts no async_op argument, and returns no torch.distributed.Work.
Parameters
key_or_none: Supported dense FHElium key supplied only bysrc. Every non-source rank must passNone.src: Global rank of the source process, which must belong togroup. This is not a process-group-relative rank.group: Participating process group.Noneselects the default process group.
Returns
The source's original key object on src and a newly allocated key of the same concrete type and metadata on every other group rank. For a world-size-one group, the source object is returned unchanged and no payload communication or receiver allocation occurs.
Raises
ValueError: Ifsrcis outsidegroup, the source value is not a supported key, or ranks violate the source/non-source argument rules.RuntimeError: If distributed communication is uninitialized, the caller is not a group member, or a valid transfer descriptor cannot be exchanged.
broadcast_plaintext
function View source
def broadcast_plaintext(value_or_none: Plaintext | None, *, src: int=0, group: torch.distributed.ProcessGroup | None=None) -> Plaintext: ...Broadcast one complete plaintext and allocate non-source receivers.
The message or encoded data representation and its arithmetic metadata are preserved. The operation does not mutate the source plaintext, accepts no async_op argument, and returns no torch.distributed.Work.
Parameters
value_or_none: Plaintext supplied only bysrc. Every non-source rank must passNone.src: Global rank of the source process, which must belong togroup. This is not a process-group-relative rank.group: Participating process group.Noneselects the default process group.
Returns
The source's original plaintext on src and a newly allocated, metadata-equivalent plaintext on every other group rank. For a world-size-one group, the source object is returned unchanged without payload communication or receiver allocation.
Raises
ValueError: Ifsrcis outsidegroupor ranks violate the source/non-source argument rules.RuntimeError: If distributed communication is uninitialized, the caller is not a group member, or a valid transfer descriptor cannot be exchanged.
gather_ciphertext_limbs
function View source
def gather_ciphertext_limbs(local_shard: Ciphertext, *, dst: int=0, group: torch.distributed.ProcessGroup | None=None) -> Ciphertext | None: ...Gather and reconstruct one ciphertext from disjoint RNS limb shards.
Group-rank order defines prime-interval order. On dst, compatible, nonempty, contiguous parameter intervals are concatenated along the RNS limb dimension. This is structural reconstruction, not ciphertext addition; use reduce_ciphertext for additive partials. The operation is synchronous, accepts no async_op argument, and returns no torch.distributed.Work.
Parameters
local_shard: Caller-owned rank-local ciphertext shard. It is read but not mutated.dst: Global rank that reconstructs the ciphertext, which must belong togroup. This is not a process-group-relative rank.group: Participating process group.Noneselects the default process group.
Returns
The reconstructed ciphertext on dst and None on every other rank. The destination allocates receive buffers and the concatenated result. For world size one, the validated local_shard object is returned unchanged without concatenation.
Raises
ValueError: Ifdstis outsidegroupor shards differ in logical ciphertext metadata, dtype, device, or contiguous prime layout.RuntimeError: If distributed communication is uninitialized or the caller is not a member ofgroup.
gather_ciphertexts
function View source
def gather_ciphertexts(value: Ciphertext, *, dst: int=0, group: torch.distributed.ProcessGroup | None=None) -> list[Ciphertext] | None: ...Gather independent ciphertexts in process-group rank order.
This is representation-preserving transport, not an algebraic reduction. Use reduce_ciphertext when the inputs are additive partials of one logical encrypted value. The operation is synchronous, accepts no async_op argument, and returns no torch.distributed.Work.
Parameters
value: One independent rank-local ciphertext. It is read but not mutated.dst: Global rank that receives the list, which must belong togroup. This is not a process-group-relative rank.group: Participating process group.Noneselects the default process group.
Returns
On dst, one ciphertext per group rank in process-group-rank order; the destination's list entry is its original object and other entries are newly allocated. Other ranks return None. For world size one, the sole rank returns [value] with the original object.
Raises
ValueError: Ifdstis outsidegroup, a rank does not provide a ciphertext, or rank-local arguments disagree.RuntimeError: If distributed communication is uninitialized or the caller is not a member ofgroup.
reduce_ciphertext
function View source
def reduce_ciphertext(value: Ciphertext, *, dst: int=0, engine: Engine, group: torch.distributed.ProcessGroup | None=None) -> None: ...Synchronously sum ciphertext partials onto dst using add.
A binomial tree combines complete ciphertexts and works for every positive process-group size, not only powers of two. The tree uses P - 1 full ciphertext messages, O(log P) critical-path rounds, and one temporary receive buffer per active rank. Non-destination values are partial or unchanged after return and must not be interpreted as the global sum. This is component-wise CKKS ciphertext addition modulo the active Q primes, not gathering independent values or concatenating RNS limbs. The operation accepts no async_op argument and returns no torch.distributed.Work.
Parameters
value: Rank-local additive ciphertext partial. The object ondstis updated in place; intermediate receivers may also be mutated as the tree accumulates subtrees. Non-overlapping strided views are supported without replacing their Tensor storage.dst: Global rank that receives the complete sum, which must belong togroup. This is not a process-group-relative rank.engine: Rank-local CKKS engine used for in-place modular ciphertext addition. Every participating rank must provide an engine compatible with itsvalue.group: Participating process group.Noneselects the default process group.
Returns
None. Only value on dst is guaranteed to contain the global sum. For world size one, the sole value is already the sum and remains unchanged.
Raises
ValueError: Ifdstis outsidegroup; rank-local values are not ciphertexts with identical shape and arithmetic metadata; or the engine rejects an incompatible value.RuntimeError: If distributed communication is uninitialized or the caller is not a member ofgroup.
scatter_ciphertext_limbs
function View source
def scatter_ciphertext_limbs(value_or_none: Ciphertext | None, *, limb_ranges: Sequence[tuple[int, int]] | None=None, src: int=0, group: torch.distributed.ProcessGroup | None=None) -> Ciphertext: ...Slice and scatter caller-selected RNS intervals of one ciphertext.
The source provides one nonempty half-open interval per group rank. The intervals refer to positions on the source's limb axis, form a consecutive range in group-rank order, and may have unequal lengths. slice_limbs selects both Tensor rows and their declared prime_ids. The caller chooses the partition; the collective performs no arithmetic or balancing. It is synchronous and accepts no async_op argument.
Parameters
value_or_none: Source ciphertext onsrc;Noneon every other rank. The source may itself represent an interval of the full basis.limb_ranges: Onsrc, one(start, stop)pair per process-group rank, indexing the source's stored rows rather than global prime IDs. Other ranks supplyNone. The intervals may select a consecutive portion of the source without covering every row.src: Global rank of the source process, which must belong togroup.group: Participating process group.Noneselects the default group.
Returns
The local ciphertext shard with its selected prime IDs and unchanged arithmetic state. On src, it shares the source Tensor storage; other ranks receive newly allocated storage. World size one returns the requested source view without communication or copying.
Raises
ValueError: If the source rank or source/non-source arguments are invalid; the range count differs from group size; or intervals are empty, out of bounds, or not consecutive in group-rank order.RuntimeError: If distributed communication is uninitialized or the caller is not a member ofgroup.
scatter_ciphertexts
function View source
def scatter_ciphertexts(values_or_none: Sequence[Ciphertext] | None, *, src: int=0, group: torch.distributed.ProcessGroup | None=None) -> Ciphertext: ...Scatter caller-prepared ciphertext values from one source.
The source supplies the values to send, whether independent workload items or views it has already prepared. This interface performs no slicing or reconstruction. This is representation-preserving transport, not an arithmetic operation. Sequence position is process-group-rank order even though src is a global rank. The operation is synchronous, accepts no async_op argument, and returns no torch.distributed.Work.
Parameters
values_or_none: Onsrc, one prepared ciphertext per group rank in process-group-rank order. Every non-source rank must passNone.src: Global rank of the source process, which must belong togroup.group: Participating process group.Noneselects the default process group.
Returns
The ciphertext assigned to the caller's process-group rank. The source receives its existing sequence element; other ranks receive newly allocated ciphertexts. For world size one, values_or_none[0] is returned unchanged without communication or allocation.
Raises
ValueError: Ifsrcis outsidegroup; the source does not provide exactly one ciphertext per group rank; a non-source rank supplies values; or rank-local arguments disagree.RuntimeError: If distributed communication is uninitialized or the caller is not a member ofgroup.