Skip to content

Vectorize argmax with TensorPrimitives - #10

Merged
ericstj merged 1 commit into
mainfrom
optimize-tensor-argmax
Jul 24, 2026
Merged

Vectorize argmax with TensorPrimitives#10
ericstj merged 1 commit into
mainfrom
optimize-tensor-argmax

Conversation

@ericstj

@ericstj ericstj commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • use TensorPrimitives.IndexOfMax for independent per-token argmax decoding
  • reference System.Numerics.Tensors directly at the matching .NET servicing version
  • retain the scalar implementation in benchmarks and add finite-score parity coverage

Testing

  • dotnet test PrivacyFilter.Net.sln -c Release --nologo
  • dotnet pack src/PrivacyFilter.Net/PrivacyFilter.Net.csproj -c Release --no-build

Use TensorPrimitives.IndexOfMax for the contiguous per-token class scan, with scalar parity coverage and benchmark results.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a9621082-f9c8-4ec8-ac3c-faaf34eb7d0f
Copilot AI review requested due to automatic review settings July 24, 2026 06:28
@ericstj
ericstj merged commit 14360a2 into main Jul 24, 2026
3 checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR switches the per-token argmax decoding path to use System.Numerics.Tensors.TensorPrimitives.IndexOfMax for potentially faster vectorized max-index selection, while adding parity coverage and preserving the scalar implementation for benchmarking comparison.

Changes:

  • Replace the scalar argmax loop with TensorPrimitives.IndexOfMax in PrivacyFilter.ArgMax.
  • Add System.Numerics.Tensors package reference (centrally versioned) to align with the targeted .NET servicing version.
  • Add a finite-scores parity test and split benchmarks to measure scalar vs tensor-based argmax.
Show a summary per file
File Description
tests/PrivacyFilter.Net.Tests/DecoderTests.cs Adds parity coverage comparing tensor-based argmax to a scalar reference for finite scores (including all-zero tie behavior).
src/PrivacyFilter.Net/PrivacyFilter.Net.csproj Adds a direct System.Numerics.Tensors dependency and exposes internals to tests/benchmarks (already present).
src/PrivacyFilter.Net/PrivacyFilter.cs Replaces scalar per-token argmax with TensorPrimitives.IndexOfMax.
Directory.Packages.props Centrally versions System.Numerics.Tensors to match the repo’s dependency management pattern.
bench/PrivacyFilter.Net.Benchmarks/Program.cs Keeps scalar argmax as a benchmark and adds a separate tensor-based argmax benchmark for comparison.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment on lines 246 to 253
internal static int[] ArgMax(ReadOnlySpan<float> scores, int tokenCount, int classCount)
{
var labels = new int[tokenCount];
for (int token = 0; token < tokenCount; token++)
{
int offset = token * classCount;
int bestLabel = 0;
float bestScore = scores[offset];
for (int label = 1; label < classCount; label++)
{
float score = scores[offset + label];
if (score > bestScore)
{
bestScore = score;
bestLabel = label;
}
}

labels[token] = bestLabel;
labels[token] = TensorPrimitives.IndexOfMax(
scores.Slice(token * classCount, classCount));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants