/exp-simd-vectorization
Optimizes hot-path scalar loops in .NET 8+ with cross-platform Vector128/Vector256/Vector512 SIMD intrinsics, or replaces manual math loops with single TensorPrimitives API calls. Covers byte-range validation, character counting, bulk bitwise ops, cross-type conversion, fused
$ npx -y skills add dotnet/skills --skill exp-simd-vectorization --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/exp-simd-vectorization
Context preview
The summary Claude sees to decide when to auto-load this skill.
Optimizes hot-path scalar loops in .NET 8+ with cross-platform Vector128/Vector256/Vector512 SIMD intrinsics, or replaces manual math loops with single TensorPrimitives API calls. Covers byte-range validation, character counting, bulk bitwise ops, cross-type conversion, fused
SKILL.md
exp-simd-vectorization.SKILL.mdname: exp-simd-vectorization
description: "Optimizes hot-path scalar loops in .NET 8+ with cross-platform Vector128/Vector256/Vector512 SIMD intrinsics, or replaces manual math loops with single TensorPrimitives API calls. Covers byte-range validation, character counting, bulk bitwise ops, cross-type conversion, fused multi-array computations, and float/double math operations."
license: MIT
SIMD Vectorization
Decision Gate
1. **Check `Span<T>` and `MemoryExtensions` first.** If the operation can be expressed using built-in `Span<T>` methods (e.g., `Contains`, `IndexOf`, `CopyTo`, `SequenceEqual`) or `MemoryExtensions`, use them — no additional dependency is needed and the runtime already vectorizes many of these internally. 2. **Check for TensorPrimitives next.** If one or more TensorPrimitives methods cover the operation → use them. If the `.csproj` does NOT already reference `System.Numerics.Tensors`, **add the package**, for example: `<PackageReference Include="System.Numerics.Tensors" />` (or use the versioning approach already used by your solution). Then replace the scalar loop with TP calls and stop. See the full API table below. Compose multiple TP calls when needed (e.g., finding both min and max → `TensorPrimitives.Min(span)` + `TensorPrimitives.Max(span)` as two calls). Do NOT write manual Vector128 code for operations TP already handles. 3. **Scalar loop over contiguous array/span** of `byte`, `sbyte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `nint`, `nuint`, `float`, `double` (and `char` via reinterpretation as `ushort`)? → Implement with explicit `Vector128<T>` / `Vector256<T>` / `Vector512<T>` intrinsics using the patterns below. 4. **No contiguous numeric arrays to process** (dictionary lookups, tree traversals, linked lists, state machines, string formatting, small collections, enum comparisons, recursive algorithms, decimal arithmetic)? → Report `[NO SIMD OPPORTUNITY]` and write a **full paragraph** explaining WHY, referencing the specific code characteristics that prevent vectorization (e.g., "State machines require sequential branching on enum values — there are no contiguous numeric arrays to process in parallel, and each transition depends on the previous state"). This explanation is graded.
TensorPrimitives API Reference
TensorPrimitives APIs are generic and work for any primitive type that satisfies the method's generic constraints — not just `float`/`double`. For example, `Sum` requires `IAdditionOperators<T,T,T>` + `IAdditiveIdentity<T,T>` and works for all primitive numeric types, while `CosineSimilarity` requires `IRootFunctions<T>` and only works for `float`/`double`. If the project doesn't already reference `System.Numerics.Tensors`, add it to the `.csproj`. Replace the entire manual loop with **one or more** `TensorPrimitives` calls as needed (prefer a single call when possible):
Reductions (span → scalar)
| Operation | API | |-----------|-----| | Sum | `TensorPrimitives.Sum(span)` | | Sum of squares | `TensorPrimitives.SumOfSquares(span)` | | Sum of magnitudes (L1 norm) | `TensorPrimitives.SumOfMagnitudes(span)` | | L2 norm | `TensorPrimitives.Norm(span)` | | Product of all elements | `TensorPrimitives.Product(span)` | | Min value | `TensorPrimitives.Min(span)` | | Max value | `TensorPrimitives.Max(span)` | | Index of max | `TensorPrimitives.IndexOfMax(span)` | | Index of min | `TensorPrimitives.IndexOfMin(span)` | | Dot product | `TensorPrimitives.Dot(a, b)` | | Cosine similarity | `TensorPrimitives.CosineSimilarity(a, b)` | | Euclidean distance | `TensorPrimitives.Distance(a, b)` |
Element-wise transforms (span → span)
| Operation | API | |-----------|-----| | Negate | `TensorPrimitives.Negate(src, dst)` | | Abs | `TensorPrimitives.Abs(src, dst)` | | Sqrt | `TensorPrimitives.Sqrt(src, dst)` | | Exp | `TensorPrimitives.Exp(src, dst)` | | Log | `TensorPrimitives.Log(src, dst)` | | Log2 | `TensorPrimitives.Log2(src, dst)` | | Tanh | `TensorPrimitives.Tanh(src, dst)` | | Sigmoid | `TensorPrimitives.Sigmoid(src, dst)` | | SoftMax | `TensorPrimitives.SoftMax(src, dst)` | | Sinh | `TensorPrimitives.Sinh(src, dst)` | | Cosh | `TensorPrimitives.Cosh(src, dst)` | | Round | `TensorPrimitives.Round(src, dst)` | | Floor | `TensorPrimitives.Floor(src, dst)` | | Ceiling | `TensorPrimitives.Ceiling(src, dst)` | | CopySign | `TensorPrimitives.CopySign(src, sign, dst)` | | Pow | `TensorPrimitives.Pow(bases, exponents, dst)` |
Two-span operations (a, b → dst)
| Operation | API | |-----------|-----| | Add | `TensorPrimitives.Add(a, b, dst)` | | Subtract | `TensorPrimitives.Subtract(a, b, dst)` | | Multiply | `TensorPrimitives.Multiply(a, b, dst)` | | Divide | `TensorPrimitives.Divide(a, b, dst)` | | Element-wise Min | `TensorPrimitives.Min(a, b, dst)` | | Element-wise Max | `TensorPrimitives.Max(a, b, dst)` |
Three-span fused operations
| Operation | API | |-----------|-----| | (x+y)*z | `TensorPrimitives.AddMultiply(x, y, z, dst)` | | x*y+z | `TensorPrimitives.MultiplyAdd(x, y, z, dst)` | | fma(x,y,z) | `TensorPrimitives.FusedMultiplyAdd(x, y, z, dst)` |
> `AddMultiply` and `MultiplyAdd` are distinct — they optimize differently depending on whether the dependency chain flows from the addend or the multiplier. `FusedMultiplyAdd` is the IEEE 754 fused form of (x*y)+z with a single rounding step.
Manual SIMD with Vector128/Vector256/Vector512
Use this when TensorPrimitives doesn't have a single API for the operation. This is required for byte-level operations, character class counting, range validation, bitwise bulk ops, cross-type conversions, and custom patterns.
Required imports
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
Prefer cross-platform APIs (`System.Runtime.Intrinsics`). Only use platform-specific intrinsics (`System.Runtime.Intrinsics.X86`, `.Arm`) when there is a significant performance advantage that justifies the increased
Read more
name: exp-simd-vectorization description: "Optimizes hot-path scalar loops in .NET 8+ with cross-platform Vector128/Vector256/Vector512 SIMD intrinsics, or replaces manual math loops with single TensorPrimitives API calls. Covers byte-range validation, character counting, bulk bitwise ops, cross-type conversion, fused multi-array computations, and float/double math operations." license: MIT
SIMD Vectorization
Decision Gate
1. **Check `Span<T>` and `MemoryExtensions` first.** If the operation can be expressed using built-in `Span<T>` methods (e.g., `Contains`, `IndexOf`, `CopyTo`, `SequenceEqual`) or `MemoryExtensions`, use them — no additional dependency is needed and the runtime already vectorizes many of these internally. 2. **Check for TensorPrimitives next.** If one or more TensorPrimitives methods cover the operation → use them. If the `.csproj` does NOT already reference `System.Numerics.Tensors`, **add the package**, for example: `<PackageReference Include="System.Numerics.Tensors" />` (or use the versioning approach already used by your solution). Then replace the scalar loop with TP calls and stop. See the full API table below. Compose multiple TP calls when needed (e.g., finding both min and max → `TensorPrimitives.Min(span)` + `TensorPrimitives.Max(span)` as two calls). Do NOT write manual Vector128 code for operations TP already handles. 3. **Scalar loop over contiguous array/span** of `byte`, `sbyte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `nint`, `nuint`, `float`, `double` (and `char` via reinterpretation as `ushort`)? → Implement with explicit `Vector128<T>` / `Vector256<T>` / `Vector512<T>` intrinsics using the patterns below. 4. **No contiguous numeric arrays to process** (dictionary lookups, tree traversals, linked lists, state machines, string formatting, small collections, enum comparisons, recursive algorithms, decimal arithmetic)? → Report `[NO SIMD OPPORTUNITY]` and write a **full paragraph** explaining WHY, referencing the specific code characteristics that prevent vectorization (e.g., "State machines require sequential branching on enum values — there are no contiguous numeric arrays to process in parallel, and each transition depends on the previous state"). This explanation is graded.
TensorPrimitives API Reference
TensorPrimitives APIs are generic and work for any primitive type that satisfies the method's generic constraints — not just `float`/`double`. For example, `Sum` requires `IAdditionOperators<T,T,T>` + `IAdditiveIdentity<T,T>` and works for all primitive numeric types, while `CosineSimilarity` requires `IRootFunctions<T>` and only works for `float`/`double`. If the project doesn't already reference `System.Numerics.Tensors`, add it to the `.csproj`. Replace the entire manual loop with **one or more** `TensorPrimitives` calls as needed (prefer a single call when possible):
Reductions (span → scalar)
| Operation | API | |-----------|-----| | Sum | `TensorPrimitives.Sum(span)` | | Sum of squares | `TensorPrimitives.SumOfSquares(span)` | | Sum of magnitudes (L1 norm) | `TensorPrimitives.SumOfMagnitudes(span)` | | L2 norm | `TensorPrimitives.Norm(span)` | | Product of all elements | `TensorPrimitives.Product(span)` | | Min value | `TensorPrimitives.Min(span)` | | Max value | `TensorPrimitives.Max(span)` | | Index of max | `TensorPrimitives.IndexOfMax(span)` | | Index of min | `TensorPrimitives.IndexOfMin(span)` | | Dot product | `TensorPrimitives.Dot(a, b)` | | Cosine similarity | `TensorPrimitives.CosineSimilarity(a, b)` | | Euclidean distance | `TensorPrimitives.Distance(a, b)` |
Element-wise transforms (span → span)
| Operation | API | |-----------|-----| | Negate | `TensorPrimitives.Negate(src, dst)` | | Abs | `TensorPrimitives.Abs(src, dst)` | | Sqrt | `TensorPrimitives.Sqrt(src, dst)` | | Exp | `TensorPrimitives.Exp(src, dst)` | | Log | `TensorPrimitives.Log(src, dst)` | | Log2 | `TensorPrimitives.Log2(src, dst)` | | Tanh | `TensorPrimitives.Tanh(src, dst)` | | Sigmoid | `TensorPrimitives.Sigmoid(src, dst)` | | SoftMax | `TensorPrimitives.SoftMax(src, dst)` | | Sinh | `TensorPrimitives.Sinh(src, dst)` | | Cosh | `TensorPrimitives.Cosh(src, dst)` | | Round | `TensorPrimitives.Round(src, dst)` | | Floor | `TensorPrimitives.Floor(src, dst)` | | Ceiling | `TensorPrimitives.Ceiling(src, dst)` | | CopySign | `TensorPrimitives.CopySign(src, sign, dst)` | | Pow | `TensorPrimitives.Pow(bases, exponents, dst)` |
Two-span operations (a, b → dst)
| Operation | API | |-----------|-----| | Add | `TensorPrimitives.Add(a, b, dst)` | | Subtract | `TensorPrimitives.Subtract(a, b, dst)` | | Multiply | `TensorPrimitives.Multiply(a, b, dst)` | | Divide | `TensorPrimitives.Divide(a, b, dst)` | | Element-wise Min | `TensorPrimitives.Min(a, b, dst)` | | Element-wise Max | `TensorPrimitives.Max(a, b, dst)` |
Three-span fused operations
| Operation | API | |-----------|-----| | (x+y)*z | `TensorPrimitives.AddMultiply(x, y, z, dst)` | | x*y+z | `TensorPrimitives.MultiplyAdd(x, y, z, dst)` | | fma(x,y,z) | `TensorPrimitives.FusedMultiplyAdd(x, y, z, dst)` |
> `AddMultiply` and `MultiplyAdd` are distinct — they optimize differently depending on whether the dependency chain flows from the addend or the multiplier. `FusedMultiplyAdd` is the IEEE 754 fused form of (x*y)+z with a single rounding step.
Manual SIMD with Vector128/Vector256/Vector512
Use this when TensorPrimitives doesn't have a single API for the operation. This is required for byte-level operations, character class counting, range validation, bitwise bulk ops, cross-type conversions, and custom patterns.
Required imports
using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics;
Prefer cross-platform APIs (`System.Runtime.Intrinsics`). Only use platform-specific intrinsics (`System.Runtime.Intrinsics.X86`, `.Arm`) when there is a significant performance advantage that justifies the increased
This repository contains the .NET team's curated set of core skills and custom agents for coding agents. For information about the Agent Skills standard, see agentskills.io. 📊 Dashboard - Accuracy and efficiency scoring trends for contained plugins (
Repo: dotnet/skills
Other skills on dotnet-skills.
- /csharp-scripts
Run file-based C# apps with the .NET CLI when the user explicitly wants C#/.NET code without creating a project. Use for C# language/API experiments, one-file C# apps, small multi-file C# apps composed with `#:include`/`#:exclude`, or C# file-based apps linked with `#:ref`. Do
Open skill - /dotnet-pinvoke
Correctly call native (C/C++) libraries from .NET using P/Invoke and LibraryImport. Covers function signatures, string marshalling, memory lifetime, SafeHandle, and cross-platform patterns. USE FOR: writing new P/Invoke or LibraryImport declarations, reviewing or debugging
Open skill - /nuget-trusted-publishing
Set up NuGet trusted publishing (OIDC) on a GitHub Actions repo — replaces long-lived API keys with short-lived tokens. USE FOR: trusted publishing, NuGet OIDC, keyless NuGet publish, migrate from NuGet API key, NuGet/login, secure NuGet publishing. DO NOT USE FOR: publishing to
Open skill - /technology-selection
Guides technology selection and implementation of AI and ML features in .NET 8+ applications using ML.NET, Microsoft.Extensions.AI (MEAI), Microsoft Agent Framework (MAF), GitHub Copilot SDK, ONNX Runtime, and OllamaSharp. Covers the full spectrum from classic ML through modern
Open skill - /configuring-opentelemetry-dotnet
Configure OpenTelemetry distributed tracing, metrics, and logging in ASP.NET Core using the .NET OpenTelemetry SDK. Use when adding observability, setting up OTLP exporters, creating custom metrics/spans, or troubleshooting distributed trace correlation.
Open skill - /convert-blazor-server-to-webapp
Guides conversion of a pre-.NET 8 Blazor Server app into a .NET 8+ Blazor Web App. USE FOR: migrating apps that use AddServerSideBlazor and MapBlazorHub to the AddRazorComponents/MapRazorComponents model, converting _Host.cshtml to an App.razor root component, replacing
Open skill

