Prefix Matrix Products and Autograd
Reported by candidates from OpenAI's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The OpenAI OA reported in September 2026 looks like a matrix problem, but the part that sinks people is the backward pass. You compute prefix products of N small matrices, then return gradients of a scalar loss for every input. Dependents pile up: matrices[i] feeds every P[j] with j >= i, and a naive version that only credits P[i] fails from Example 2 onward. The hinted pattern is breadth-first-search, though it's really reverse-mode accumulation over a chain. If you blank on the adjoint bookkeeping, StealthCoder is the safety net running invisibly during the live OA.
The problem
You are given a sequence of square integer matrices matrices with shape [N, D, D]. Define the inclusive prefix products P[i] = matrices[0] @ matrices[1] @... @ matrices[i], where @ is ordinary matrix multiplication. Reverse-mode contract You are also given upstream with shape [N, D, D]. Treat upstream[i] as the upstream gradient dL / dP[i] of a scalar loss L. Equivalently, the differential of the loss is dL = sum(i = 0..N-1) <upstream[i], dP[i]>_F, where <A, B>_F = sum(r, c) A[r][c] * B[r][c]. Compute every prefix product P[i] and every input gradient dL / dmatrices[i]. For the sequential backward step, keep the original input matrices available and use only a constant number of D x D scratch matrices beyond the inputs and returned prefixes and gradients. Hillis-Steele follow-up The intended final approach performs the forward pass as an out-of-place Hillis-Steele scan. Start with one snapshot containing the input matrices. For offsets 1, 2, 4,..., build a new snapshot from the previous one: If i < offset, copy matrix i unchanged. Otherwise, set matrix i to previous[i - offset] @ previous[i]. Keep the snapshots needed to reverse these multiplication rounds without mutating an earlier snapshot. Return format Return a long[][] with 2 * N rows and D * D columns. Flatten each matrix in row-major order: Rows 0 through N - 1 contain P[0] through P[N - 1]. Rows N through 2 * N - 1 contain dL / dmatrices[0] through dL / dmatrices[N - 1]. Function prefixProductAutograd(matrices: int[][][], upstream: int[][][]) → long[][] Examples Example 1 matrices = [[[1,2],[3,4]]] upstream = [[[2,0],[1,-1]]] return = [[1,2,3,4],[2,0,1,-1]] There is one prefix, so P[0] = matrices[0]. Because that prefix is the input itself, its gradient is exactly upstream[0]. Example 2 matrices = [[[1,2],[0,1]],[[2,0],[1,3]],[[1,1],[2,0]]] upstream = [[[1,0],[0,1]],[[0,1],[-1,0]],[[2,-1],[1,1]]] return = [[1,2,0,1],[4,6,1,3],[16,4,7,1],[3,16,2,8],[1,5,3,12],[9,-3,15,-3]] The first three rows are the row-major forms of P[0], P[1], and P[2]. The final three rows are the corresponding input gradients after contributions from every dependent prefix have been accumulated. Example 3 matrices = [[[2]],[[-1]],[[3]],[[2]]] upstream = [[[1]],[[2]],[[-1]],[[3]]] return = [[2],[-2],[-6],[-12],[-16],[34],[-10],[-18]] For D = 1, matrix multiplication becomes scalar multiplication. The four prefixes are 2, -2, -6, and -12; the remaining rows are their accumulated reverse-mode gradients. Constraints 1 <= N <= 32 1 <= D <= 4 matrices.length = upstream.length = N. Every matrix in both inputs has exactly D rows and D columns. Every input entry is an integer from -10 through 10. Every individual product, partial sum, prefix-product entry, scan-stage entry, reverse-mode adjoint, and final gradient fits in a signed 64-bit integer. All multiplication and addition are exact; no modulus or floating-point tolerance is used.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is the recurrence. P[i] = P[i-1] @ M[i]. Walk backward with a running adjoint G, where G starts as upstream[N-1]. For each i from N-1 down to 0, the gradient for M[i] is P[i-1]^T @ G (use identity-free handling when i = 0, where the gradient is just G). Then update G = upstream[i-1] + G @ M[i]^T. The pitfall is forgetting that upstream[i-1] adds in at every step, and mixing up transpose sides. You only need a constant number of DxD scratch matrices, so don't store every adjoint. Use long everywhere. Check Example 3 with D = 1 first, since it reduces to scalars and exposes sign mistakes fast. The Hillis-Steele follow-up needs saved snapshots per round, and you reverse each round in the opposite order. If the transpose order slips mid-assessment, StealthCoder is the hedge that reads the problem and hands you the working structure.
If you see this problem in your OA tomorrow, the play is to recognize the pattern in 30 seconds. StealthCoder buys you that recognition.
You can drill Prefix Matrix Products and Autograd cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Built by an Amazon engineer who passed his OA cold and still thinks the filter is broken.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass OpenAI's OA.
OpenAI reuses patterns across OAs. Built by an Amazon engineer who passed his OA cold and still thinks the filter is broken. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Prefix Matrix Products and Autograd FAQ
What's the real trick in the OpenAI prefix matrix products problem?+
Reverse-mode accumulation. Keep a running adjoint G going from i = N-1 down to 0. The gradient for matrices[i] is P[i-1] transposed times G, and G then becomes upstream[i-1] plus G times matrices[i] transposed. Miss the upstream add and Example 2 fails.
Why does a naive solution fail?+
It credits only P[i] to matrices[i]. But matrices[i] feeds every later prefix P[j] with j >= i, so gradients must accumulate across all dependents. Single-matrix and D = 1 examples pass, but the 3-matrix example exposes it right away.
Is this really a BFS problem?+
No. The hinted label is breadth-first-search, but the work is a backward sweep over a chain plus small matrix multiplies. The Hillis-Steele follow-up has round-by-round structure, which is closer to a layered scan than a graph traversal.
What should I watch for with types and sizes?+
Use long for all products and sums, since the input says values fit in signed 64-bit. N is at most 32 and D at most 4, so cubic matrix multiplication per step is fine. Return 2N rows of D*D, flattened row-major.
How do I prepare in 48 hours?+
Hand-derive the gradient for N = 2 with D = 1, then D = 2, and match Examples 1 to 3. Write a small matmul and transpose helper first. Then code the sequential backward pass. Only attempt the Hillis-Steele snapshot reversal after the sequential version passes.