Skip to content

← Reductions and dim step 7 of 7

Easy Primitives

Running totals

Jump to the task

A cumulative sum records the total up to each position rather than only the final total. It preserves the input shape.

import torch

x = torch.tensor([[1.0, 2.0, 3.0, 4.0], [10.0, -2.0, 1.0, 0.0]])
print(x.cumsum(dim=-1).tolist())
# [[1.0, 3.0, 6.0, 10.0], [10.0, 8.0, 9.0, 9.0]]

Each row starts its own running total. Mathematically, the last entry equals the row sum. Floating-point implementations can round differently if they combine values in a different order.

Use the tensor operation

A Python loop can calculate the same running totals, but indexing, extracting Python scalars and writing individual elements add overhead. On a GPU, scalar extraction can also wait for device work.

Prefix sums admit parallel algorithms, so a sequential-looking definition does not require a Python loop. cumsum uses an implementation selected for the device and input. Do not assume every backend uses one particular algorithm or that fewer dispatched operations guarantee a given speedup.

Related operations

diff computes adjacent differences. To reconstruct values from those differences, you also need the initial value. cumprod, cummax and cummin accumulate products, maxima and minima respectively. logcumsumexp computes the logarithm of cumulative sums of exponentials; it is not a replacement for cumulative products.

Cumulative sums are useful for running counts and converting sequence lengths into offsets. A reversed cumulative sum gives undiscounted future reward totals. Discounted returns require discount factors as well.

Your task

def running_total(x: torch.Tensor) -> torch.Tensor

Return the cumulative sum along the last axis of a two-dimensional float32 tensor. Preserve its shape. Use at most two tensor operations as counted by the harness's TorchDispatchMode; the counter measures dispatches inside your function, not execution time or GPU kernel launches.