← HomOps Reference
HomAxisSum
Sum an encrypted value along one axis.
AsArithmetic
RunsServer
Changes shapeYes - the summed axis is removed, or kept at size 1
Changes scaleNo
Levels spent0
RotatesNo
KeysNone
What it does
HomAxisSum reduces a ciphertext by summing across one tensor axis, like .sum(dim=...). It is add-only: no multiplication, no rotations, no key, no levels. That makes it the cheap reduction, and the usual follow-up to an element-wise multiply: multiply, then sum the axis away.It does not reduce the ciphertext slot axis (
n_axis). For slot-axis summation use HomSumSlots. HomMul with axis_sum does a multiply and a tensor-axis sum in one step.Signature
HomAxisSum( dim, # required keep_dim=False, )
No
set_data.Parameters
ParameterTypeDefaultDescription
dimintrequiredThe axis to sum, indexed on the ciphertext shape.keep_dimboolFalseIf True, the summed axis stays in the shape with size 1 instead of being removed.Rules that depend on the value
SettingRuleIf you break it
dimMust be a valid axis of the shape.Compilation fails.dim = n axisNot supported. Reducing the packed slot axis is a slot operation: use HomSumSlots.Compilation fails.Requirements
None beyond a valid
dim. No key, no level headroom, no set_data.Shape effect - yes
Rule: the summed axis is removed (
keep_dim=False) or kept at size 1 (keep_dim=True). All other axes are preserved.The n axis is marked in bold:
Input shapedimkeep_dimOutput shape
(16, 32, 128)1True(16, 1, 128)
(16, 32, 128)1False(16, 128)
(num_blocks, n_slots, record_dim)2True(num_blocks, n_slots, 1)
(num_blocks, n_slots)0False(n_slots,)
The packed slot axis cannot be the reduction axis; use HomSumSlots for that.
Scale effect - no
Summation is addition; the scale carries through unchanged.
Level budget
Zero. No mod-switch runs and there is no
with_modswitch option.Keys
None.
Example
The reduction steps of exact search. After the database multiply, one sum collapses the record dimension; after the squarings, another collapses the blocks:
pipeline.pyPYTHON
from lattica_build.client_ops import Repeat from lattica_build.operators import ( HomExpand, HomConstMul, HomAxisSum, HomSquare, ) from lattica_build.base_classes.hom_pipeline import HomomorphicPipeline from lattica_build.operators.composite.sequential import SequentialHomOp pipeline = HomomorphicPipeline( client_pre=[Repeat()], hom=SequentialHomOp( HomExpand(k=64, k_axis=1, stage_sizes=[4, 4, 4], stages_per_level=3), HomConstMul(dims=db.shape, with_modswitch=True), HomAxisSum(dim=2, keep_dim=True), # sum record_dim *(HomSquare(with_modswitch=True) for _ in range(2)), HomAxisSum(dim=0, keep_dim=False), # sum num_blocks ), input_shape=(N_SLOTS,), )
Shape and scale through the reduction tail:
Stagept_shapept_scale
After the multiply
(B, S, R)grown by the multiplyAfter
HomAxisSum(dim=2, keep_dim=True)(B, S, 1)unchangedAfter the squarings
(B, S, 1)grown, rescaledAfter
HomAxisSum(dim=0)(S,)unchangedSee also
- HomMul -
axis_sumfolds this reduction into the multiply - HomSumSlots - sum across slots, the rotation-based reduction
- HomRunningSum - prefix sums instead of a full reduction
- Ciphertext state - shape, blocks, and the n axis