← HomOps Reference
HomRunningSum
Turn values into running totals: each position becomes the sum of itself and everything before it.
RsSlots
RunsServer
Changes shapeNo
Changes scaleYes - managed per mod-switch group
Levels spent
len(stage_sizes) / stages_per_levelRotatesYes - stage plan via
stage_sizesKeysRotation key
What it does
HomRunningSum computes a prefix sum over encrypted data: after it runs, each position holds the cumulative total of all positions up to and including itself. The slot-tree path takes k (slot span; default full n_slots) plus stage_sizes / stages_per_level. The axis-based path uses cumsum_axis and blocks_axis_external.Where HomAxisSum collapses an axis to a single total,
HomRunningSum keeps every intermediate total. That is what selection logic needs: in the cosine-similarity pipeline, it runs on the 0/1 selector produced by the threshold polynomial, turning match flags into match positions.The accumulation across slots is built from rotations, so
HomRunningSum takes a stage plan, the same stage_sizes / stages_per_level pair as HomExpand. If stages, offsets, and rounds are new to you, read Slots, rotations & stages first; this page only states how the rules land on this operator.Signature
HomRunningSum( cumsum_axis=None, blocks_axis_external=None, k=None, stage_sizes=None, stages_per_level=None, rows_budget=None, )
HomRunningSum takes no weights, so there is no set_data call. The slot-tree path uses k=None (full slot count) by default; axis-based cumsum is selected with cumsum_axis.Parameters
ParameterTypeDefaultDescription
cumsum_axisint | NoneNoneAxis to cumulatively sum. When set, enables the axis-based cumsum path.blocks_axis_externalint | NoneNoneAxis that describes block structure for the axis-based cumsum path.kint | NoneNoneSlot span to accumulate. None means the full slot count (n_slots). When set, prod(stage_sizes) must equal k.stage_sizessequenceNoneThe stage plan: one entry per stage, each entry the stage's group size. Unset means (2,) × log₂(k), the smallest-key plan.stages_per_levelintNoneHow many stages share one mod-switch. Unset means 1: a mod-switch after every stage.rows_budgetSequence[int] | NoneNoneAbsolute rows allowed for the internal mod-switches.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.stages_per_levelMust divide the number of stages exactly: len(stage_sizes) % stages_per_level == 0. And when you set it, set stage_sizes explicitly too; the default plan is not filled in early enough to divide against.Compilation fails: stages_per_level must divide len(stage_sizes).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.
- Level headroom. The chain must have
len(stage_sizes) / stages_per_levellevels left when the operator runs. See Level budget.
These surface as compilation errors; see Compilation errors.
Shape effect - no
The output shape equals the input shape. The values are redistributed into running totals; the layout stays as it was.
Scale effect - yes
Rule: scale is managed per mod-switch group, exactly as on HomExpand. A group is
stages_per_level consecutive stages: the mask multiplies inside a group grow the scale by one prime's worth in total, and the mod-switch at the group boundary brings it back down. The net effect is one mod-switch worth of scale movement per group.How scale moves through a pipeline is on Ciphertext state - Scale.
Stages & rotations
The general rules live on Slots, rotations & stages; here is how they apply to
HomRunningSum:QuestionAnswer for HomRunningSum
Where does
k come fromConstructor argument. Omit it to accumulate over the full slot count; pass an explicit span to run the prefix 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 spent
len(stage_sizes) / stages_per_level, controlled by stages_per_level.plans.pyPYTHON
# Two stages, one mod-switch: k = 64, plan 8 × 8 HomRunningSum(k=64, stage_sizes=[8, 8], stages_per_level=2) # 14 offsets, 2 rounds, 1 level # One group over the whole plan: spend a single level regardless of depth HomRunningSum(k=k, stage_sizes=plan, stages_per_level=len(plan))
Level budget
ConfigurationLevels spent
stage_sizes and stages_per_level unsetlog₂(k) - one per stageExplicit plan
len(stage_sizes) / stages_per_levelThe rotations and mask multiplies spend nothing; only the mod-switch at the end of each group does. How primes are organized in the chain is explained on Level budget - The chain.
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: the only multiplies are by plaintext masks.
Example
Standalone running sum
pipeline.pyPYTHON
from lattica_build.operators import HomRunningSum from lattica_build.base_classes.hom_pipeline import HomomorphicPipeline from lattica_build.operators.composite.sequential import SequentialHomOp K = 64 STAGE_SIZES = [8, 8] # 8 * 8 = 64 = k STAGES_PER_LEVEL = 2 # one mod-switch for both stages pipeline = HomomorphicPipeline( hom=SequentialHomOp( HomRunningSum(k=K, stage_sizes=STAGE_SIZES, stages_per_level=STAGES_PER_LEVEL), ), input_shape=(5120,), )
The plan
[8, 8] costs 7 + 7 = 14 rotation offsets over two rounds, and with stages_per_level=2 spends one level.See also
- HomExpand - the other stage-plan operator, same knobs, opposite job (replicate instead of accumulate)
- HomAxisSum - a full reduction when you only need the total
- HomSumSlots - sum across slots without keeping prefixes
- Slots, rotations & stages - stage plans, offsets, and the key-size trade