Module_ComputingContext - vorcyc/Vorcyc.Mathematics GitHub Wiki

Location: Home / ComputingContext module

ComputingContext module — ComputingContext

Lightweight CPU execution policy for choosing scalar, SIMD, or parallel implementations per call or code block without global mutable state. Covers FFT, statistics, linear algebra, curve fitting, batch deep learning, MFCC/audio frontends, and training entry points (see “Integrated APIs” below).

No GPU: ComputingContext schedules CPU work only (scalar / SIMD / multithreaded). The main package has dropped built-in CUDA/ILGPU; see GPU policy.

Namespace: Vorcyc.Mathematics


Core types

Type Description
ComputingContext Immutable execution policy (Normal / Simd / Parallel / Auto)
ComputingScope AsyncLocal scope; using (ComputingScope.Enter(ctx)) { ... }
CpuExecutionMode CPU mode enum
ComputingContextExecution Parallel thresholds, worker-count helpers, and indexed ForEach (optional CancellationToken)

Resolution order

explicit context parameter  >  ComputingContext.Current (scope)  >  Default

context: null means “unspecified” and follows the chain above — not forced scalar.

Presets

ComputingContext.Normal    // scalar
ComputingContext.Simd      // SIMD
ComputingContext.Parallel  // parallel (large data)
ComputingContext.Auto      // heuristic by problemSize
ComputingContext.Default   // process default (initially Auto)

Auto thresholds (elements / flop count): ≥1024 → SIMD, ≥16384 → Parallel (see ResolveCpuMode).


Usage

1. Default (no parameter)

signal.TransformToFrequencyDomain();
values.Sum();
var c = a * b;

2. Explicit per call

signal.TransformToFrequencyDomain(ComputingContext.Parallel, WindowType.Hamming);
FastFourierTransform.Forward(input, output, ComputingContext.Simd);
var sum = span.Sum(ComputingContext.Parallel);
var product = MatrixFp32.Multiply(a, b, ComputingContext.Parallel);

3. Scope (multiple calls in a pipeline)

using (ComputingScope.Enter(ComputingContext.Parallel))
{
    var spec1 = s1.TransformToFrequencyDomain();
    var spec2 = s2.TransformToFrequencyDomain(ComputingContext.Simd); // single-call override
    var mean = buffer.Average(); // uses Parallel from scope
}

4. Configure process default

ComputingContext.ConfigureDefault(ComputingContext.Auto);

Integrated APIs

Signal processing

  • ITimeDomainSignal.TransformToFrequencyDomain(ComputingContext?, WindowType?) — uses the SoA FftButterflyFp32 kernel via FastFourierTransform
  • FastFourierTransform.Forward / Inverse(..., ComputingContext?) (span, array, pointer, and in-place; SoA butterfly when WillAccelerate)
  • TimeDomainCharacteristicOps.GetRms / GetAmplitude / GetAveragePower / ...
  • ISingleThreadTimeDomainSignal.GetRms(context) and related extensions (bypass cached properties)
  • Mode decomposition (Vorcyc.Mathematics.SignalProcessing.Transforms.ModeDecomposition) — see Transforms:
    • EmpiricalModeDecomposition / EnsembleEmpiricalModeDecomposition (EEMD) / CompleteEnsembleEmd (CEEMDAN, Torres 2011)
    • VariationalModeDecomposition / MultivariateVariationalModeDecomposition (MVMD)
    • MultivariateEmpiricalModeDecomposition (MEMD)
    • SingularSpectrumAnalysis (SSA) / EmpiricalWaveletTransform (EWT)
    • HilbertHuangTransform (Analyze always runs EMD; AnalyzeModes / ModeDecomposer.Instantaneous for existing modes)
    • All accept CancellationToken + IProgress<ModeDecompositionProgress>; options expose ComputingContext? (honors ComputingScope when null)
    • Parallel / ensemble: EEMD & CEEMDAN ensemble members via ComputingContextExecution.ForEach; VMD / MVMD / EWT FFT paths always take resolved context; SSA forwards context into SVD
    • Still mostly serial: EMD / MEMD spline & extrema loops; CEEMDAN noise EMD precompute is parallelized per realization
    • Facade: ModeDecomposer.Emd / Eemd / Ceemdan / Vmd / Hht / Instantaneous / Memd / Mvmd / Ssa / Ewt
  • Z / Laplace (Vorcyc.Mathematics.SignalProcessing.Transforms):
    • ZTransform.Dtft / Transform / multi-ω EvaluateFrequencyResponse — UseParallelIndexed → ForEach (scalar workers); else explicit/resolved Simd → frequency-lane SIMD; Normal → scalar. Explicit ComputingContext.Simd / Parallel / Normal bypass Auto’s 1K/16K ladders (ResolveCpuMode); the shared parallel work gate (UseParallelIndexed, ≥65 536 total work) still decides whether threads start.
    • LaplaceTransform.FrequencyResponse — same dispatch over ω (SIMD Horner on jω lanes)
    • Single-point Evaluate / IsStable / bilinear maps — O(order); no context (intentional)

Statistics

  • Basic.Sum / Average / Variance / StandardDeviation (Span<float/double> and generic floating-point)
  • Correlation.PearsonCorrelation(x, y, context) (generic, parallel reduction for large data)
  • Standardization.ZScore(values, sample, context) (generic, parallel reduction + parallel write-back)
  • InformationTheory.Entropy / EntropyBits / KullbackLeiblerDivergence(..., context) (generic; parallel reduction preserves the scalar short-circuit semantics)
  • IComparableExtension.CompareMax / CompareMin

Linear algebra

  • MatrixFp32.Multiply(a, b, context), Matrix<T>.Multiply(...)
  • MatrixFp32.Multiply(vector, result, context)
  • VectorSpan.Dot / Sum / Norm / Add / Subtract / Axpy / Scale(..., context)
  • MatrixDecomposition.SingularValueDecomposition(matrix, tolerance, context, cancellationToken) — Householder apply + factor combine honor context; bidiagonal QR iteration remains sequential (cancel polled each sweep)

Scope resolution (Phase 2 fix)

APIs that accept ComputingContext? context call ComputingContext.Resolve(null) when context == null, so ComputingScope applies even when null is passed explicitly (consistent with the resolution order above). Legacy overloads without a context parameter are unchanged.

TensorFp32 statistics

  • TensorStatistics.MeanAlongAxis / StandardDeviationAlongAxis / NormalizeAlongAxis / MeanAlongDepth (optional context)
  • Basic.WeightedAverage(values, weights, context) (generic floating-point)

Deep learning (Phase 3–4)

  • ComputingContextExecution.ForEach — batch-dimension / index parallel scheduling
  • Both forward and backward of batch layers are now parallelized (read ComputingScope / Resolve, since 0.9.2):
    • BatchConv2DMath (direct conv, kernel<5): forward parallel over samples; backward split into two race-free kernels — gradInput over samples, weight/bias gradients over output channels.
    • BatchConv2DIm2Col (im2col conv, kernel≥5): forward GEMM row-parallel; backward likewise two kernels (gradCol over patches, weights/bias over output channels).
    • BatchFullyConnectedLayer: forward over samples; backward two kernels (gradInput over samples, weights/bias over output units).
    • BatchMaxPool2DMath / BatchAvgPool2DLayer / BatchGlobalAveragePool2DLayer: forward + backward over samples.
    • BatchUpsample2DLayer / BatchSoftmaxLayer / BatchConcatenateLayer: forward + backward over samples.
    • BatchTransposedConvolution2DLayer: forward over samples; backward two kernels (same pattern as conv).
    • BatchDepthwiseConvolution2DLayer: forward + backward over channels (each channel owns its filter/bias/gradient plane, so a single kernel is race-free).
    • BatchLayerNormLayer: forward over spatial positions; backward two kernels (gradInput over positions, scale/shift over channels).
    • BatchSqueezeExciteLayer (SE attention): per-channel scaling forward + backward over samples (sub-layers FC/GAP parallel on their own).
  • Trainer.Fit / FitBatched / FitBatchSequential / FitBatchParallelConcat / FitCnnMlp optional computingContext parameter
  • MlpTrainingOptions.ComputingContext
  • Legacy single-sample layers Layers.Conv2D / Dense / LinearLayer / MaxPool2D / ReLU / Sigmoid / BatchNorm / JoinLayer / Fusion — channel-dimension ForEachDepth (respects ComputingScope)

Every backward parallel kernel is partitioned to avoid shared write contention (gradient-input by sample/spatial position, weight gradients by output channel/unit), producing results bit-for-bit identical to the serial path — see ComputingContext_equivalence_test (forward/backward parallel==serial equivalence across layers).

TensorFp32 GEMM (Phase 4)

  • TensorOps.GemmTransposeRight(..., ComputingContext?) — im2col convolution GEMM row parallelism

Feature extraction / MFCC pipeline (Phase 4+)

  • FeatureExtractor.ParallelChunksComputeFrom / ParallelComputeFrom(..., ComputingContext?) — thread count and chunked parallelism
  • MfccExtractor and subclasses via ParallelComputeFrom(samples, context: ComputingContext.Parallel) or outer ComputingScope for unified policy

CNN + audio frontend (Phase 4+)

  • Trainer.FitCnnMlp(..., computingContext) — same scope installation as FitBatched
  • BatchPreEmphasisLayer / BatchStftMagnitudeLayer / BatchMelFilterbankLayer — batch-dimension ForEach (STFT parallelism uses per-thread Stft instances)
  • BatchNormLayer / BatchBatchNormLayer — channel parallelism (for large data)
// Offline MFCC features
using (ComputingScope.Enter(ComputingContext.Parallel))
    var mfcc = extractor.ParallelComputeFrom(samples);

// CNN + Mel frontend training
trainer.FitCnnMlp(model, loss, opt, batches, epochs, computingContext: ComputingContext.Parallel);

Machine learning (Phase 5)

Most estimators in Vorcyc.Mathematics.MachineLearning accept an optional ComputingContext? context constructor argument and/or expose a settable Context property. The instance Context governs PredictBatch for IBatchClassifier / IBatchRegressor models; row/class/tree-level loops dispatch through ComputingContextExecution.

  • Batch prediction over rows: LogisticRegression, SoftmaxRegression, GaussianNaiveBayes, OneVsRestClassifier, NumericDecisionTree, NumericRandomForest, KnnClassifier, KnnRegressor, MultipleLinearRegression, MultivariateRidgeRegression, ClassificationPipeline, RegressionPipeline
  • Parallel training: GradientBoostingClassifier (per class), OneVsRestClassifier (per class), NumericRandomForest (per tree, deterministic seeds)
  • Clustering / reduction / separation: KMeansClusterer, ExpectationMaximization / GMM, DBSCAN, HierarchicalClustering, VectorQuantization, PCA, LinearDiscriminantAnalysis, FactorAnalysis, TSNE, Decomposition.ICA
  • Helpers: ClassificationMetrics.ConfusionMatrix(..., context), ModelBatchExtensions.PredictBatch(..., context) (generic fallback for non-batch classifiers)
  • Curve fitting: all CurveFitter<T> methods — see Curve fitting below
using Vorcyc.Mathematics.MachineLearning;

var forest = new NumericRandomForest<double>(numTrees: 80, seed: 11) { Context = ComputingContext.Parallel };
forest.Fit(xTrain, yTrain);
int[] preds = forest.PredictBatch(xTest);

// Or govern several estimators at once via a scope (leave Context unset)
var knn = new KnnClassifier<double>(k: 3);
knn.Fit(xTrain, yTrain);
using (ComputingScope.Enter(ComputingContext.Parallel))
{
    int[] p = knn.PredictBatch(xTest);
}

Each parallel kernel writes only disjoint indices with thread-local scratch, so results are bit-for-bit identical to the serial path (see TESTS/ML_module_test). AdaBoostClassifier and SupportVectorMachine expose Context for uniformity but currently run serially. Full inventory: Machine learning module.

Curve fitting (Vorcyc.Mathematics.MachineLearning.CurveFitting)

CurveFitter<T> methods accept optional ComputingContext? computingContext = null and follow the same dispatch as Statistics / VectorSpan:

  1. UseParallelIndexed meets the shared threshold → parallel (ComputingContextExecution.ForEach; workers stay scalar)
  2. else Normal (or non-float/double) → scalar
  3. else → SIMD (also when explicit Parallel is below the 65 536 total-work threshold)
Method Notes
Linear / Polynomial / Exponential / Logarithmic / Power Existing Fit_SIMD Vector kernels; no dedicated parallel kernel yet — Parallel falls through to SIMD (same idea as Statistics when Parallel is below threshold)
Sinusoidal LM with analytic Jacobian; parallel residual/Jacobian fill; SIMD reductions when in Simd mode
CubicSpline Tridiagonal solve stays serial; MSE / predict assembly honors context
LocallyWeighted Per-query fits via ForEach; SIMD weighted sums in Simd mode
MovingAverage Per-window smooth via ForEach; SIMD window sums in Simd mode
GaussianProcess Kernel / α / predict / Gauss–Jordan elimination rows via ForEach + SIMD kernels; optional CancellationToken (0.10.9); result exposes PredictStd / PredictVariance (0.10.10)
Nonlinear (1D / multi-column) LM residual/Jacobian via ForEach; SIMD JᵀJ / Jᵀr dots in Simd mode
BayesianLinear Design-matrix assembly via ForEach
using Vorcyc.Mathematics;
using Vorcyc.Mathematics.MachineLearning.CurveFitting;

var fit = CurveFitter<double>.Sinusoidal(x, y, maxIterations: 200, ComputingContext.Simd);

using (ComputingScope.Enter(ComputingContext.Parallel))
{
    var ma = CurveFitter<float>.MovingAverage(xs, ys, windowSize: 9); // null → scope
}

null resolves through ComputingContext.Resolve (explicit → scope → Default). Only float / double take SIMD paths.


Migration: FftVersion

FftVersion, FastFourierTransform.Version, and TransformToFrequencyDomain(WindowType?, FftVersion) were removed in 0.10.12. Use ComputingContext / ComputingScope:

Removed API Replacement
FftVersion.SIMD ComputingContext.Simd
FftVersion.Parallel ComputingContext.Parallel
FftVersion.Normal ComputingContext.Normal
TransformToFrequencyDomain(window, fftVersion) TransformToFrequencyDomain(context, window)
FastFourierTransform.Version = ... ComputingScope.Enter(...) or per-call context

Pointer / in-place overloads without an explicit context argument pass null, which still honors ComputingScope and dispatches through the same SoA FftButterflyFp32 path.


Parallel thresholds (ComputingContextExecution)

Constant Value Use
ParallelReductionThreshold 65536 Sum, variance, dot product, etc.
ParallelMatrixMultiplyThreshold 262144 MatrixFp32 multiply

ForEach(context, from, to, body, workPerItem, …, cancellationToken) honors the same UseParallelIndexed gate. When parallel, CancellationToken is attached to ParallelOptions; when serial, it is polled before each index.


APIs that do not read ComputingContext (intentional)

  • Cached properties such as Signal.Rms / Amplitude — fixed SIMD path; use GetRms(context) etc. for policy-aware behavior
  • MatrixFp32 operator *, parameterless values.Sum() — library default; use Multiply(..., context) / Sum(context) when needed

Not yet integrated (intentional or low ROI)

  • LU / QR decompositions — no parallel hot spots (thin SVD is context-aware; see Linear algebra above)
  • Bidiagonal QR iteration inside SVD — sequential by design (cancel polled)
  • Overlap-add filters — single-threaded implementations
  • GPU / CUDA — not provided in the main package; see GPU policy

Note: Legacy APIs without a context parameter keep their previous behavior; only hot paths listed in this document read ComputingContext / ComputingScope.


Future hardware taxonomy (reserved)

The main package executes on CPU only today. These enums describe a future extension surface; they are not wired into ComputingContext yet.

ComputingBackend

Value Meaning
CPU Host processor (current default)
GPU Graphics / compute GPU
FPGA Field-programmable gate array
ASIC Application-specific integrated circuit
TPU TensorFp32 processing unit
NPU Neural processing unit

ComputingMethodPriority

Maps a backend choice to an execution style: Sequential_Normal, Sequential_SIMD, Parallel.

See GPU policy for why GPU is not shipped in the main NuGet package.


Verification and tests

Numerical equivalence across Normal / Parallel (and SIMD) paths is covered by tests:

Test project Content
TESTS/core_module_test ComputingContext_test: statistics, matrices, VectorSpan, FFT roundtrip, large-array parallelism
TESTS/DL_module_test ComputingContext_equivalence_test: 27 forward/backward/training/MFCC/frontend-layer Normal vs Parallel cases
TESTS/ML_module_test ComputingContext_equivalence_test (estimators / clustering / DR) + CurveFitting_Sinusoidal_test (Sinusoidal correctness and Normal / Simd / Parallel / Auto / ComputingScope equivalence)
TESTS/SP_module_test Mode decomposition suite (EMD / VMD / HHT / CEEMDAN recon / parallel CEEMDAN / SSA+Parallel, …)

Run (Release):

dotnet run --project TESTS/core_module_test/core_module_test.csproj -c Release
dotnet run --project TESTS/DL_module_test/DL_module_test.csproj -c Release
dotnet run --project TESTS/ML_module_test/ML_module_test.csproj -c Release
dotnet run --project TESTS/SP_module_test/SP_module_test.csproj -c Release

Equivalence tolerances: forward/backward 1e-4; post-training inference 5e-3 (floating-point accumulation order differences). Curve-fitting modes should match within a small absolute/relative tolerance (see the ML test harness).

⚠️ **GitHub.com Fallback** ⚠️