Foundations
Ragged segment sum and mean
EGNNSchNetChempropGeoDiff
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Your task
Group feature rows by their integer segment IDs. Return a sum, mean, and count for every requested segment, including segments with no contributing rows.
Function signature
segment_sum_mean(
values: torch.Tensor,
segment_id: torch.Tensor,
num_segments: int,
) -> dict[str, torch.Tensor]Worked example
Repeated and empty segments
Rows 0 and 1 both belong to segment 1: their sum is [8, 12], count is 2 and mean is [4, 6]. The -1 row is excluded; requested segments 2 and 3 remain zero.
import torch
values = torch.tensor([[2.0, 4.0], [6.0, 8.0], [100.0, -100.0], [-2.0, 0.0]], dtype=torch.float64, requires_grad=True)
segment_id = torch.tensor([1, 1, -1, 0], dtype=torch.int64)
num_segments = 4
result = segment_sum_mean(values=values, segment_id=segment_id, num_segments=num_segments)Expected return
{
'sums': torch.tensor([[-2.0, 0.0], [8.0, 12.0], [0.0, 0.0], [0.0, 0.0]], dtype=torch.float64),
'means': torch.tensor([[-2.0, 0.0], [4.0, 6.0], [0.0, 0.0], [0.0, 0.0]], dtype=torch.float64),
'counts': torch.tensor([1, 2, 0, 0], dtype=torch.int64),
}Parameters
| Parameter | Shape and meaning |
|---|---|
valuestorch.Tensor | [E,f_1,\ldots,f_k]: any trailing feature axes, including none.Feature rows to accumulate; preserve every trailing feature axis. |
segment_idtorch.Tensor | [E]Output-segment assignment for each row. -1 excludes the row; other IDs select a requested segment. |
num_segmentsint | Required nonnegative integer output segment count. IDs -1 are padding; other IDs must refer to a requested segment. |
Return
dict[str, torch.Tensor]
Return exactly the named fields applicable to this operation.
Required behavior
- Group
values[E,\ast F]by integersegment_id[E]along axis zero only, retaining every trailing feature dimension\ast F. The trailing dimensions may be absent (scalar rows), multiple, or empty. Requirednum_segments=Nis a nonnegative integer; every ID is either-1(padding) or in[0,N). - For each
sin[0,N),\mathrm{counts}[s]=\mathrm{number}of rows with\mathrm{segment\_id}[e]=s,\mathrm{sums}[s]=\sum_{e:\mathrm{segment\_id}[e]=s}values[e], and\mathrm{means}[s]=\mathrm{sums}[s]/\operatorname{max}(\mathrm{counts}[s],1). Return all three tensors. - Repeated and unsorted IDs accumulate; padding rows do not affect
sums,means,countsor gradients. Missing intermediate and trailing segments must remain in the output with\mathrm{sums}=\mathrm{means}=0and\mathrm{counts}=0.E=0is legal;N=0is legal only when there are no non-padding rows. sumsandmeanshave shape[N,\ast F]and preservevalues' floating dtype/device;countsisint64[N]on the same device.valuesand IDs share a device, and all floatingvaluesare finite. There is no\epsilon, weighting, sorting requirement, feature-axis reduction, residual addition or input mutation.- Both contiguous and strided input layouts must work.
Why this matters
Segment IDs encode membership without padding each group to equal length; sums and counts reconstruct a mean for each occupied group.
Starter code
You write the body of this function in the BioTorch workspace. Your code runs in an isolated PyTorch sandbox; Run checks the public examples and Submit grades the full test suite, including gradients.
import torch
def segment_sum_mean(
values: torch.Tensor, # (E,f_1,...,f_k): any trailing feature axes, including none.
segment_id: torch.Tensor, # (E,)
num_segments: int,
) -> dict[str, torch.Tensor]:
"""Return dict[str, torch.Tensor]:
sums: (N,f_1,...,f_k): preserve every trailing axis of values.
means: (N,f_1,...,f_k): preserve every trailing axis of values.
counts: (N,)."""
# Implement the operation. Inputs and test setup are supplied by BioTorch.
raise NotImplementedError("Implement segment_sum_mean")
Ready to implement it?
3 progressive hints, a solution walkthrough, and grading that checks values, shapes and gradients are waiting in the workspace.
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Sources and further reading
A primitive exercise, not an end-to-end reproduction of the named models. No affiliation or endorsement is implied.