Skip to content

Commit 387c4e6

Browse files
committed
refactor(NpyIter): Rename Tier A/B/C to Tier 3A/3B/3C
Explicit the hierarchy — Tier A/B/C were always sub-tiers of Layer 3 (the baked-ufunc layer). Numbering them `3A/3B/3C` makes the relationship visible at a glance: Layer 1 — ForEach (delegate) Layer 2 — ExecuteGeneric (struct-generic) Layer 3 — ExecuteBinary / Unary / ... (baked) Tier 3A — ExecuteRawIL (sub-tier: custom IL) Tier 3B — ExecuteElementWise (sub-tier: templated) Tier 3C — ExecuteExpression / Call (sub-tier: DSL) 100 references touched across 6 files: docs/website-src/docs/NDIter.md — prose, TOC, anchor links, worked- example heading anchors (#6, #7, #8) src/NumSharp.Core/Backends/Iterators/NpyExpr.cs — header comment src/NumSharp.Core/Backends/Iterators/NpyIter.Execution.Custom.cs — file header, region comments for each tier entry point src/NumSharp.Core/Backends/Kernels/ILKernelGenerator.InnerLoop.cs — factory method docstrings test/NumSharp.UnitTest/Backends/Iterators/NpyIterCustomOpTests.cs — class docstring, region comments, 10 test method names (TierA_* → Tier3A_*, TierB_* → Tier3B_*, TierC_* → Tier3C_*) test/NumSharp.UnitTest/Backends/Iterators/NpyIterCustomOpEdgeCaseTests.cs — region comments, 2 test method names (Validate_TierA_* → Validate_Tier3A_*) No behavior changes. 264/264 NpyExpr + custom-op tests pass on net8 + net10. Full suite still green (0 regressions).
1 parent 25b058a commit 387c4e6

6 files changed

Lines changed: 101 additions & 101 deletions

File tree

docs/website-src/docs/NDIter.md

Lines changed: 59 additions & 59 deletions
Large diffs are not rendered by default.

src/NumSharp.Core/Backends/Iterators/NpyExpr.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using NumSharp.Backends.Kernels;
55

66
// =============================================================================
7-
// NpyExpr.cs — Expression DSL (Tier C of the custom-op API)
7+
// NpyExpr.cs — Expression DSL (Tier 3C of the custom-op API)
88
// =============================================================================
99
//
1010
// A small algebraic AST over NpyIter operands. Compiles to an
@@ -18,7 +18,7 @@
1818
// mirrors NumPy's casting-by-output behavior for simple ufunc composition
1919
// and keeps the AST trivial to type-check.
2020
//
21-
// For fine-grained type control, use ExecuteElementWise directly (Tier B).
21+
// For fine-grained type control, use ExecuteElementWise directly (Tier 3B).
2222
//
2323
// SIMD
2424
// ----

src/NumSharp.Core/Backends/Iterators/NpyIter.Execution.Custom.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
using NumSharp.Backends.Kernels;
55

66
// =============================================================================
7-
// NpyIter.Execution.Custom.cs — Tier A / B / C entry points for user-defined
7+
// NpyIter.Execution.Custom.cs — Tier 3A / 3B / 3C entry points for user-defined
88
// inner-loop kernels. All three routes funnel into the same
99
// NpyIterRef.ForEach(NpyInnerLoopFunc, aux) driver; only kernel creation
1010
// differs.
1111
//
12-
// Tier A (ExecuteRawIL) — caller emits the entire IL body
13-
// Tier B (ExecuteElementWise) — caller emits per-element scalar + vector
12+
// Tier 3A (ExecuteRawIL) — caller emits the entire IL body
13+
// Tier 3B (ExecuteElementWise) — caller emits per-element scalar + vector
1414
// bodies; the factory wraps them in the
1515
// 4×-unrolled SIMD + scalar-strided shell
16-
// Tier C (ExecuteExpression) — caller composes an NpyExpr tree which is
17-
// compiled to a Tier-B kernel
16+
// Tier 3C (ExecuteExpression) — caller composes an NpyExpr tree which is
17+
// compiled to a Tier-3B kernel
1818
//
1919
// All entry points validate that the iterator's NOp matches the operand type
2020
// array length so common mistakes fail fast.
@@ -25,7 +25,7 @@ namespace NumSharp.Backends.Iteration
2525
internal unsafe ref partial struct NpyIterRef
2626
{
2727
// =====================================================================
28-
// Tier A — Raw IL escape hatch
28+
// Tier 3A — Raw IL escape hatch
2929
// =====================================================================
3030

3131
/// <summary>
@@ -46,7 +46,7 @@ public void ExecuteRawIL(Action<ILGenerator> emitBody, string cacheKey, void* au
4646
}
4747

4848
// =====================================================================
49-
// Tier B — Templated inner loop
49+
// Tier 3B — Templated inner loop
5050
// =====================================================================
5151

5252
/// <summary>
@@ -115,7 +115,7 @@ public void ExecuteElementWiseTernary(
115115
=> ExecuteElementWise(new[] { a, b, c, outType }, scalarBody, vectorBody, cacheKey);
116116

117117
// =====================================================================
118-
// Tier C — Expression DSL
118+
// Tier 3C — Expression DSL
119119
// =====================================================================
120120

121121
/// <summary>

src/NumSharp.Core/Backends/Kernels/ILKernelGenerator.InnerLoop.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@
1717
// THREE ENTRY POINTS
1818
// ------------------
1919
// 1. CompileRawInnerLoop(body, key)
20-
// Caller emits the entire IL body. Full control. Used by Tier A of the
20+
// Caller emits the entire IL body. Full control. Used by Tier 3A of the
2121
// NpyIter custom-op API.
2222
//
2323
// 2. CompileInnerLoop(operandTypes, scalarBody, vectorBody, key)
2424
// Caller supplies per-element scalar/vector bodies; the factory wraps
2525
// them in the standard 4× unrolled SIMD + remainder + scalar-tail shell,
26-
// plus a strided fallback for non-contiguous inner loops. Used by Tier B.
26+
// plus a strided fallback for non-contiguous inner loops. Used by Tier 3B.
2727
//
28-
// 3. Indirectly via NpyExpr.Compile — the expression DSL compiles to Tier B.
28+
// 3. Indirectly via NpyExpr.Compile — the expression DSL compiles to Tier 3B.
2929
//
3030
// STRIDE CONTRACT
3131
// ---------------
@@ -58,7 +58,7 @@ public static partial class ILKernelGenerator
5858
private static readonly ConcurrentDictionary<string, NpyInnerLoopFunc> _innerLoopCache = new();
5959

6060
/// <summary>
61-
/// Number of cached inner-loop kernels (Tier A and Tier B combined).
61+
/// Number of cached inner-loop kernels (Tier 3A and Tier 3B combined).
6262
/// </summary>
6363
internal static int InnerLoopCachedCount => _innerLoopCache.Count;
6464

@@ -69,7 +69,7 @@ public static partial class ILKernelGenerator
6969

7070
#endregion
7171

72-
#region Tier A: Raw IL
72+
#region Tier 3A: Raw IL
7373

7474
/// <summary>
7575
/// Compile a custom inner-loop kernel from user-emitted IL. The body
@@ -102,7 +102,7 @@ internal static NpyInnerLoopFunc CompileRawInnerLoop(Action<ILGenerator> body, s
102102

103103
#endregion
104104

105-
#region Tier B: Templated inner loop (element-wise)
105+
#region Tier 3B: Templated inner loop (element-wise)
106106

107107
/// <summary>
108108
/// Compile an element-wise inner-loop kernel. Operand layout:
@@ -253,7 +253,7 @@ private static void EmitLoadInnerLoopArgs(
253253
/// templated SIMD path — the shell loads every operand through the
254254
/// same Vector{W}&lt;T&gt; instantiation. Mixed-type SIMD (e.g.
255255
/// int32+float32) is too ambiguous for a generic shell; users needing
256-
/// that should either call CompileRawInnerLoop (Tier A) with their
256+
/// that should either call CompileRawInnerLoop (Tier 3A) with their
257257
/// own mixed-type IL, or accept the scalar fallback where the body
258258
/// handles conversion.
259259
/// </summary>

test/NumSharp.UnitTest/Backends/Iterators/NpyIterCustomOpEdgeCaseTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ private static int VectorCountFloat32()
5050
}
5151

5252
// =====================================================================
53-
// Size-boundary: all via Tier C: out = 2*in + 1
53+
// Size-boundary: all via Tier 3C: out = 2*in + 1
5454
// =====================================================================
5555

5656
private static void RunLinear(int count)
@@ -476,7 +476,7 @@ public void NpyExpr_InputNegativeIndex_ThrowsOnConstruction()
476476
}
477477

478478
// =====================================================================
479-
// Auto-derived cache key (Tier C) & cache behavior
479+
// Auto-derived cache key (Tier 3C) & cache behavior
480480
// =====================================================================
481481

482482
[TestMethod]
@@ -613,7 +613,7 @@ public void Validate_NullExpression_Throws()
613613

614614
[TestMethod]
615615
[ExpectedException(typeof(ArgumentNullException))]
616-
public void Validate_TierA_NullBody_Throws()
616+
public void Validate_Tier3A_NullBody_Throws()
617617
{
618618
var a = np.arange(4).astype(np.float32);
619619
var b = np.empty(new Shape(4), np.float32);
@@ -624,7 +624,7 @@ public void Validate_TierA_NullBody_Throws()
624624

625625
[TestMethod]
626626
[ExpectedException(typeof(ArgumentNullException))]
627-
public void Validate_TierA_NullKey_Throws()
627+
public void Validate_Tier3A_NullKey_Throws()
628628
{
629629
var a = np.arange(4).astype(np.float32);
630630
var b = np.empty(new Shape(4), np.float32);
@@ -776,7 +776,7 @@ public void MixedContigAndStrided_ScalarFallback()
776776
}
777777

778778
// =====================================================================
779-
// Integer Tier C
779+
// Integer Tier 3C
780780
// =====================================================================
781781

782782
[TestMethod]

test/NumSharp.UnitTest/Backends/Iterators/NpyIterCustomOpTests.cs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@ namespace NumSharp.UnitTest.Backends.Iterators
99
{
1010
/// <summary>
1111
/// Exercises the three-tier custom-op API on NpyIterRef:
12-
/// Tier A — ExecuteRawIL (user emits entire inner-loop body)
13-
/// Tier B — ExecuteElementWise (user supplies scalar + vector body emitters)
14-
/// Tier C — ExecuteExpression (NpyExpr DSL compiled to inner-loop IL)
12+
/// Tier 3A — ExecuteRawIL (user emits entire inner-loop body)
13+
/// Tier 3B — ExecuteElementWise (user supplies scalar + vector body emitters)
14+
/// Tier 3C — ExecuteExpression (NpyExpr DSL compiled to inner-loop IL)
1515
/// </summary>
1616
[TestClass]
1717
public unsafe class NpyIterCustomOpTests
1818
{
1919
// =====================================================================
20-
// Tier A: Raw IL
20+
// Tier 3A: Raw IL
2121
// =====================================================================
2222

2323
[TestMethod]
24-
public void TierA_RawIL_AddsTwoInt32Arrays()
24+
public void Tier3A_RawIL_AddsTwoInt32Arrays()
2525
{
2626
var a = np.arange(10).astype(np.int32);
2727
var b = np.arange(10, 20).astype(np.int32);
@@ -97,11 +97,11 @@ public void TierA_RawIL_AddsTwoInt32Arrays()
9797
}
9898

9999
// =====================================================================
100-
// Tier B: Templated inner loop
100+
// Tier 3B: Templated inner loop
101101
// =====================================================================
102102

103103
[TestMethod]
104-
public void TierB_ElementWiseBinary_FusedMultiplyAdd_Float32()
104+
public void Tier3B_ElementWiseBinary_FusedMultiplyAdd_Float32()
105105
{
106106
// out = a * b + 1.0f
107107
var a = np.arange(16).astype(np.float32);
@@ -148,7 +148,7 @@ public void TierB_ElementWiseBinary_FusedMultiplyAdd_Float32()
148148
}
149149

150150
[TestMethod]
151-
public void TierB_ElementWiseUnary_Sqrt_Float32_Simd()
151+
public void Tier3B_ElementWiseUnary_Sqrt_Float32_Simd()
152152
{
153153
var input = np.arange(1, 33).astype(np.float32); // 32 floats -> full Vector256 occupancy
154154
var output = np.empty(new Shape(32), np.float32);
@@ -178,7 +178,7 @@ public void TierB_ElementWiseUnary_Sqrt_Float32_Simd()
178178
}
179179

180180
[TestMethod]
181-
public void TierB_Ternary_Float32()
181+
public void Tier3B_Ternary_Float32()
182182
{
183183
// out = a*b + c
184184
var a = np.arange(8).astype(np.float32);
@@ -231,7 +231,7 @@ public void TierB_Ternary_Float32()
231231
}
232232

233233
[TestMethod]
234-
public void TierB_StridedInput_UsesScalarFallback()
234+
public void Tier3B_StridedInput_UsesScalarFallback()
235235
{
236236
// Slice every other element — inner stride = 2*elemSize, not elemSize.
237237
// The iterator keeps EXTERNAL_LOOP so ForEach runs a single inner-loop
@@ -269,7 +269,7 @@ public void TierB_StridedInput_UsesScalarFallback()
269269
}
270270

271271
[TestMethod]
272-
public void TierB_CacheReuse_SameKeyReturnsIdenticalDelegate()
272+
public void Tier3B_CacheReuse_SameKeyReturnsIdenticalDelegate()
273273
{
274274
// Two distinct iters calling ExecuteElementWise with the same
275275
// cacheKey should hit the same compiled delegate.
@@ -311,11 +311,11 @@ public void TierB_CacheReuse_SameKeyReturnsIdenticalDelegate()
311311
}
312312

313313
// =====================================================================
314-
// Tier C: Expression DSL
314+
// Tier 3C: Expression DSL
315315
// =====================================================================
316316

317317
[TestMethod]
318-
public void TierC_Expression_AddConstant()
318+
public void Tier3C_Expression_AddConstant()
319319
{
320320
var a = np.arange(12).astype(np.float32);
321321
var b = np.empty(new Shape(12), np.float32);
@@ -335,7 +335,7 @@ public void TierC_Expression_AddConstant()
335335
}
336336

337337
[TestMethod]
338-
public void TierC_Expression_CompoundFma()
338+
public void Tier3C_Expression_CompoundFma()
339339
{
340340
// out = (a + b) * c + 1
341341
var a = np.arange(8).astype(np.float32);
@@ -369,7 +369,7 @@ public void TierC_Expression_CompoundFma()
369369
}
370370

371371
[TestMethod]
372-
public void TierC_Expression_SqrtOfSumSquares()
372+
public void Tier3C_Expression_SqrtOfSumSquares()
373373
{
374374
// out = sqrt(a^2 + b^2) — hypot, single-kernel
375375
var a = np.array(new float[] { 3, 6, 5, 8 });
@@ -398,7 +398,7 @@ public void TierC_Expression_SqrtOfSumSquares()
398398
}
399399

400400
[TestMethod]
401-
public void TierC_Expression_NegateAndAbs()
401+
public void Tier3C_Expression_NegateAndAbs()
402402
{
403403
var a = np.array(new float[] { 3, -4, 5, -6 });
404404
var b = np.empty(new Shape(4), np.float32);
@@ -420,7 +420,7 @@ public void TierC_Expression_NegateAndAbs()
420420
}
421421

422422
[TestMethod]
423-
public void TierC_Expression_DoubleDtype()
423+
public void Tier3C_Expression_DoubleDtype()
424424
{
425425
var a = np.arange(10).astype(np.float64);
426426
var b = np.empty(new Shape(10), np.float64);
@@ -440,7 +440,7 @@ public void TierC_Expression_DoubleDtype()
440440
}
441441

442442
[TestMethod]
443-
public void TierC_Expression_StridedPath()
443+
public void Tier3C_Expression_StridedPath()
444444
{
445445
// Expression tree must also work on strided views (kernel's
446446
// runtime contig check routes to the scalar-strided fallback).
@@ -471,7 +471,7 @@ public void TierC_Expression_StridedPath()
471471

472472
[TestMethod]
473473
[ExpectedException(typeof(ArgumentException))]
474-
public void TierB_WrongOperandCount_Throws()
474+
public void Tier3B_WrongOperandCount_Throws()
475475
{
476476
var a = np.arange(4).astype(np.float32);
477477
var b = np.empty(new Shape(4), np.float32);
@@ -493,7 +493,7 @@ public void TierB_WrongOperandCount_Throws()
493493

494494
[TestMethod]
495495
[ExpectedException(typeof(ArgumentException))]
496-
public void TierC_WrongInputCount_Throws()
496+
public void Tier3C_WrongInputCount_Throws()
497497
{
498498
var a = np.arange(4).astype(np.float32);
499499
var b = np.empty(new Shape(4), np.float32);

0 commit comments

Comments
 (0)