compute-acceleration
GEMM and sum reduction across serial, OpenMP and CUDA
Loading...
Searching...
No Matches
reduction.h
1// Copyright (c) 2025 yanghuafang
2// SPDX-License-Identifier: MIT
3
4#ifndef ACCEL_CPU_REDUCTION_H_
5#define ACCEL_CPU_REDUCTION_H_
6
7#include "core/span.h"
8
9namespace accel {
10
11// Eight double lanes fill two 256-bit vector registers, the widest shape every
12// target here sustains without spilling.
13inline constexpr int kSumLanes = 8;
14
15// Both return double, matching SumOnDevice so the four implementations of this
16// task compare directly. A float host accumulator would be less accurate than
17// the device kernel it is meant to check.
18//
19// Addition is not associative, so these agree to a relative tolerance, not
20// exactly. An empty span sums to zero rather than being an error.
21
22// Baseline: one accumulator, so one dependency chain of length N. Throughput
23// is bounded by add latency, not by memory or issue width.
24double SumSequential(Span<const float> input) noexcept;
25
26// Same operations and memory traffic, no threads -- only the single dependency
27// chain becomes kSumLanes independent ones, which the pipeline overlaps and the
28// vectoriser widens. Isolates instruction-level parallelism from the
29// thread-level parallelism SumOmp adds. Lane assignment is fixed, so unlike
30// SumOmp this is bit-for-bit reproducible.
31double SumBlocked(Span<const float> input) noexcept;
32
33} // namespace accel
34
35#endif // ACCEL_CPU_REDUCTION_H_