Skip to main content

fused_elementwise_into

Function fused_elementwise_into 

Source
pub fn fused_elementwise_into<T>(
    dests: &mut [StridedViewMut<'_, T>],
    inputs: &[StridedView<'_, T>],
    plan: &FusedPlan,
    exec: Exec<'_>,
) -> Result<(), StridedError>
where T: FusedScalar,
Expand description

Evaluate a runtime-DAG elementwise plan into one or more destinations.

The plan is validated before any destination is written:

  • inputs.len() must equal plan.input_count;
  • dests.len() must equal plan.outputs.len();
  • instruction operands must reference earlier SSA values with the right arity for their FusedOp;
  • every input and destination must have exactly the destination shape;
  • each mutable destination layout must be injective, so two logical output elements never map to the same memory address.

The implementation dispatches known single-output plans to existing static map_into/zip_map*_into kernels, replays a block that is contiguous for every operand through a chunked register machine, and falls back to a per-element interpreter for arbitrary validated DAGs. Overlapping source/destination memory is not supported by the strided kernels generally.

§Numerics

The chunked replay evaluates Exp, Log, Sin, Cos, Tanh and Expm1 with the elem-simd-math slice kernels — the same kernels a per-instruction dispatch through strided_basic::map_into_uninit_with_kernel uses, so the fused and the non-fused route agree with each other. Against std’s scalar functions those six instructions differ by at most one ULP of their own output magnitude; a chain of them multiplies that difference by the output magnitude, so an exponential chain is not bit-stable to std. Log1p and every other instruction (Add, Multiply, Negate, Conj, Divide, Abs, Maximum, Minimum, Clamp, Sqrt, Rsqrt, Pow) keep the scalar FusedScalar methods and are bit-identical to the per-element replay.

Real Maximum, Minimum, and Clamp share the NaN-propagating select and signed-zero contract of strided_basic::nan_propagating_maximum / nan_propagating_minimum (issue #315): a NaN in any operand makes the result NaN, and a tie keeps the left operand, so maximum(-0.0, 0.0) and clamp on equal bounds preserve the signed zero of the left/bound operand. Complex Abs returns the norm in the real component; complex Maximum, Minimum, and Clamp compare by squared norm. Signed integer Add, Multiply, Negate, and Abs use wrapping arithmetic. bool supports only copy-like identity plans and Conj; ambiguous arithmetic and transcendental op/dtype pairs are rejected before any destination is written.