← HomOps Reference
HomSumSlots
Sum across the slots inside a ciphertext.
SsSlots
RunsServer
Changes shapeNo
Changes scaleNo
Levels spent0
RotatesYes - stage plan via
stage_sizesKeysRotation key
What it does
HomSumSlots is the slot-axis reduction: it sums packed slots over a span k using rotation and addition, and does not consume levels. Use it instead of HomAxisSum when the reduction is the ciphertext slot axis (n_axis). HomAxisSum only sums tensor axes and cannot reduce n_axis.k is the slot span to reduce. When omitted, it defaults to the full slot count. Optional stage_sizes must multiply to k. You will mostly meet this operator indirectly: HomMatMul runs one internally when it multiplies over the n axis, and bootstrapping uses one for its partial sums.Because it rotates, it takes a stage plan (
stage_sizes), like HomExpand and HomRunningSum. Unlike those two, it is rotations and additions only: no masks, no mod-switch, no levels spent, so there is no stages_per_level knob. If stages, offsets, and rounds are new to you, read Slots, rotations & stages first.Signature
HomSumSlots( k=None, stage_sizes=None, )
No
set_data.Parameters
ParameterTypeDefaultDescription
kint | NoneNoneSlot span to reduce. None means the full slot count (n_slots). A smaller k sums within groups of that width rather than across the whole ciphertext.stage_sizessequenceNoneThe stage plan: one entry per stage, each entry the stage's group size. Unset means (2,) × log₂(k), the smallest-key plan.Rules that depend on the value
SettingRuleIf you break it
stage_sizesThe entries must multiply out to k: prod(stage_sizes) == k. When k is omitted, that product must equal the full slot count.Compilation fails: Product of stage_sizes must be equal to k.stage_sizes unsetThe default plan (2,) × log₂(k) only exists when k is a power of two.For any other k, write the plan yourself.Requirements
- Rotation key entries. Every rotation offset in the stage plan must be present in the evaluation key. The compiler derives the exact set; you don't list them yourself.
These surface as compilation errors; see Compilation errors.
Shape effect - no
The output shape equals the input shape. The values are redistributed: with default
k (full slot count), every slot of a block holds the block's total; with a smaller k, every slot of a group of width k holds that group's total.Scale effect - no
Rotations and additions only; the scale carries through unchanged.
Stages & rotations
The general rules live on Slots, rotations & stages; here is how they apply to
HomSumSlots:QuestionAnswer for HomSumSlots
Where does
k come fromConstructor argument. Omit it to reduce the full slot count; pass an explicit span to sum within groups of width k.Default plan
stage_sizes unset gives (2,) × log₂(k). Requires k to be a power of two.Plan constraint
prod(stage_sizes) == kDistinct rotation offsets
Σ (entry − 1) over the plan. Sets the rotation key size.Rounds
len(stage_sizes). Fewer rounds means a faster query.Levels spent0, always. No mod-switch runs inside, so there is no
stages_per_level here.Since levels are never at stake, the plan is a pure speed-versus-key-size trade:
plans.pyPYTHON
# Default: k = n_slots, log-depth rotation tree HomSumSlots() # full slot-axis reduction # Explicit span: k = 8, two stages HomSumSlots(k=8, stage_sizes=[2, 4]) # prod(stage_sizes) == k
Level budget
Zero. The tree is rotations and additions; no prime is ever dropped, whatever the plan.
Keys
Rotation key. Every offset in the stage plan needs an entry in the rotation key, derived at compile time from the plan and generated for you during key generation. Wider stages mean more offsets and a bigger key. No square key.
Example
Standalone slot sum
Partial sums over column groups: 32 slots as 4 columns of
k = 8:pipeline.pyPYTHON
from lattica_build.operators import HomSumSlots from lattica_build.base_classes.hom_pipeline import HomomorphicPipeline from lattica_build.operators.composite.sequential import SequentialHomOp pipeline = HomomorphicPipeline( hom=SequentialHomOp( HomSumSlots(k=8, stage_sizes=[2, 4]), # 2 * 4 = 8 = k ), input_shape=(32,), )
Inside HomMatMul
You don't write this one; when HomMatMul multiplies over the n axis, it runs a
HomSumSlots with defaults to do its summation. The rotation key entries it needs are derived along with everything else at compile time.See also
- HomAxisSum - sum a tensor axis; cannot reduce the n axis
- HomRotateSum - rotate-and-add primitive behind slot-sum stages
- HomRunningSum - keep the prefixes instead of one total
- HomMatMul - the main consumer of this operator
- Slots, rotations & stages - stage plans, offsets, and the key-size trade
- Bootstrap - refresh when the level budget runs out