Array signal processing

Direction of arrival, on hardware that has no room for a BLAS.

MUSIC and ESPRIT are eigendecomposition in a latency budget. The array covariance matrix has to be decomposed, the signal and noise subspaces split, and the spectrum scanned — inside a frame, on a board that has to fit and draw the power it is allowed, producing a result that will later have to be qualified. This is the one workload that needs all four VVE advantages at the same time.

Wilkinson, N=16,383

89.6×


vs single-threaded reference netlib LAPACK dsyev (the default dense path) — wilkinson, N = 16,383

Wilkinson, N = 45,056

5.16×


vs LAPACK's own expert O(N²) routine, single-threaded dstemr (MRRR)

libvve.so

1.4MB


libvve.so, zero external dependencies

x86Intel · AMDArmArmsame answer, bit for bit
The same bits on the Intel/AMD workstation and on the Arm board it ships to.

In plain terms

Why a radar cares about an eigensolver.

The pipeline below has one expensive stage. Here is what the problem is, why that stage is the one that hurts, and why the answer has to be the same on every board.

Direction of arrivalWhat is the problem?
angleantenna arraysignal
Each element hears the same signal a moment apart. The angle is the answer the system exists to produce.

An array of antennas or microphones hears the same signal at slightly different moments at each element. From those differences, software works out where the signal came from. The standard methods, MUSIC and ESPRIT, start by building a matrix of how every element's signal relates to every other, and then take that matrix apart with an eigensolver to separate the signals from the noise.

Latency budgetWhy is the eigensolver the hard part?

Every other stage in the chain is cheap and predictable. The eigendecomposition is the stage that sets how long a frame takes, how much memory the board needs, and how much of the system has to be re-examined when anything changes. It has to finish inside the frame, on a board with no room for a large tuned math library.

QualifiedWhy does determinism matter here?
x86Intel · AMDArmArmsame answer, bit for bit
The same answer on the workstation it was developed on and on the board it ships to.

A sensing product is tested and signed off, then shipped on many boards for years. If the answer shifts with the chip, every new board reopens that work. VVE EigenCore returns the same bits on x86 and Arm from the same source, so the evidence gathered on one does not have to be re-argued on the next.

Where the eigensolver sits.

Signal-processing pipelineThe signal chain from array snapshots to a direction estimate. Every stage but one is cheap and predictable. The symmetric eigendecomposition of the covariance matrix is the stage that sets the latency, the memory footprint and the qualification cost of the whole chain.Array snapshotsCovariance REigendecomposition of RSignal / noise subspace splitMUSIC / ESPRIT spectrum
The signal chain from array snapshots to a direction estimate. Every stage but one is cheap and predictable.

Snapshot averaging, spatial smoothing and the spectral scan are all well-behaved. The eigendecomposition is the block that grows with the array, pulls in a numerical library, and produces the number that has to be identical next year on next year's board.

Four requirements. Four advantages.

Array signal-processing requirements and the corresponding VVE advantage.
The workload requiresVVE answers with
A frame-rate latency budget.VVE SmartRoute, structure-aware O(N²) routing — 89.6× vs single-threaded reference netlib dsyev at N = 16,383, and up to 5.16× vs single-threaded LAPACK dstemr on clustered spectra; both comparisons are single-threaded on both sides.
A board with no room for a tuned BLAS.1.4 MB, zero external dependencies. Runtime dependencies are libc, libm and libpthread. Intel/AMD and Arm from the same source.
Evidence that survives qualification.The same bits across machine, chip family, compiler and chip generation — 96 fingerprint records across 12 groups, zero mismatches, 541 / 541 across chip generations.
Correlated sources.Clustered spectra are where VVE's margin is largest and where it holds at every size measured — the wilkinson and schrödinger families in the campaign.

Why correlated sources favour this solver.

Subspace methods need a clean split between the signal eigenvalues and the noise floor. Correlated and coherent arrivals collapse that separation — the signal eigenvalues bunch, and the classical response is to spend more work resolving them. MRRR resolves a cluster by refining its representation tree, and that refinement is exactly where its cost goes up. VVE's routing does not pay that penalty, which is why the two clustered families in the campaign are the two where it wins at every size measured.

Well separated and clustered eigenvalue laddersTwo eigenvalue ladders on the same axis. The left is evenly spaced. The right has several near-coincident values, the pattern correlated arrivals produce.well separatedclustered — correlated sources
Two eigenvalue ladders on the same axis. The left is evenly spaced. The right has several near-coincident values, the pattern correlated arrivals produce.

Scoped to this workload.

Wilkinson, N=16,383

89.6×


vs single-threaded reference netlib LAPACK dsyev (the default dense path) — wilkinson, N = 16,383, full decomposition

Full decomposition, N=45,056, Wilkinson spectrum

5.16×


vs LAPACK's own expert O(N²) routine, single-threaded dstemr (MRRR) — wilkinson, N = 45,056, accuracy gated on both sides

Wilkinson, N=45,056, wall clock

171.1s


dstemr vs VVE, wilkinson, N = 45,056, both single-threaded

96 / 96


SHA-256 records identical across Intel/AMD and Arm chips, GCC and Clang

The full measured record →

Two ways in.

Drop in

Zero code changes. Preload the library and the covered routines are served by VVE EigenCore: dsyev · dsyevd · dsyevr · dgesdd · dgesvd · dstev. Python through vvepy. This is the speed path.

LD_PRELOAD=libvve.so ./your_doa_pipeline

Bands-native

One small code change, and the dense buffer never exists. You pass the diagonal and the off-diagonal directly. This is the memory path, and it is what makes large arrays fit in a board's memory budget rather than a server's.

/* pass D and E — no dense N×N is ever allocated */
vve_eigen_values_tridiag(D, E, N, W);

Send us your array geometry.

Array size, snapshot count, source correlation, target board and instruction set. We will run your case on the harness and send the numbers back with the build, so the first result you see comes from your problem rather than ours.