Hard Sigmoid Approximation
— unknown status| Operation | HardSigmoid (bpd_hardsigmoid) |
|---|---|
| Formula | f(x) = max(0, min(1, (x + 3) / 6)) |
| Category | Piecewise linear |
This is the backend-neutral op_expr fact that specifies the operation. The same term is lowered to LLVM IR, CUDA C, MLIR, and every other backend — one specification, many targets.
op_expr(bpd_hardsigmoid,
sel(le(var, const(-3.0)), const(0.0),
sel(ge(var, const(3.0)), const(1.0),
add(mul(var, const(0.16666667)), const(0.5))))).
| Backend | LLVM NVPTX (llvm_nvptx) |
|---|---|
| Target | nvptx |
| Description | LLVM IR targeting NVIDIA PTX (GPU). Compiled with llc for nvptx64, loaded via CUDA driver API. |
This is the actual LLVM IR (NVPTX) emitted by our Prolog/Logtalk toolchain for this operation. Every instruction was generated from a declarative op_expr specification — no hand-written assembly.
; BPD hardsigmoid: clamp((x+3)/6, 0, 1)
; NOTE: must be (x+3)/6, NOT x/6+0.5 — order matters for float precision
define void @bpd_hardsigmoid(i32 %n, float* %out, float* %in) {
entry:
%cmp = icmp sgt i32 %n, 0
br i1 %cmp, label %loop, label %exit
loop:
%i = phi i32 [ 0, %entry ], [ %next, %loop ]
%idx = sext i32 %i to i64
%inptr = getelementptr float, float* %in, i64 %idx
%x = load float, float* %inptr, align 4
%plus3 = fadd float %x, 3.0
%div6 = fdiv float %plus3, 6.0
%clamped_low = call float @llvm.maxnum.f32(float %div6, float 0.0)
%result = call float @llvm.minnum.f32(float %clamped_low, float 1.0)
%outptr = getelementptr float, float* %out, i64 %idx
store float %result, float* %outptr, align 4
%next = add i32 %i, 1
%done = icmp sge i32 %next, %n
br i1 %done, label %exit, label %loop
exit:
ret void
}
declare float @llvm.maxnum.f32(float, float)
declare float @llvm.minnum.f32(float, float)
| Tier | SILVER — 0 ULP, robustness testing pending |
|---|---|
| ULP Divergence | 0 |
| Source Commit | b03bc23f7 |
| Deployment | deployed |
| Measured | 2026-09-25 |
| Hardware | NVIDIA Tesla P4 (enclave GPU) |
| Gate | Output compared to PyTorch reference on identical input tensor. 0 ULP = every floating-point bit matches. |