Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

90 lines
3.4 KiB
C++

// Copyright (c) Advanced Micro Devices, Inc., or its affiliates.
// SPDX-License-Identifier: MIT
/*
* helper_rocke.helpers.activations.c -- C99 port of
* rocke.helpers.activations._sigmoid_via_exp2 / _tanh_via_exp2.
*
* Faithful translation of:
*
* def _sigmoid_via_exp2(b: IRBuilder, x: Value) -> Value:
* c_neg_log2e = b.const_f32(-1.4426950408889634)
* one = b.const_f32(1.0)
* return b.rcp(b.fadd(one, b.exp2(b.fmul(c_neg_log2e, x))))
*
* def _tanh_via_exp2(b: IRBuilder, x: Value) -> Value:
* c_2log2e = b.const_f32(2.0 * 1.4426950408889634)
* one = b.const_f32(1.0)
* e2x = b.exp2(b.fmul(c_2log2e, x))
* return b.fmul(b.fsub(e2x, one), b.rcp(b.fadd(e2x, one)))
*
* The builder-call sequence is reproduced in the exact same order as the Python
* so the emitted IR (and SSA value numbering) stays byte-identical. Where a
* Python expression nests several builder calls, C argument-evaluation order is
* unspecified, so the sub-emissions are sequenced explicitly to match Python's
* strict left-to-right evaluation of each call's arguments.
*/
#include "rocke/helper_rocke.helpers.activations.h"
#include "rocke/ir_internal.h" /* rocke_i_live */
rocke_value_t* rocke_sigmoid_via_exp2(rocke_ir_builder_t* b, rocke_value_t* x)
{
rocke_value_t* c_neg_log2e;
rocke_value_t* one;
/* Sticky-error model: a failed builder makes every call a NULL no-op. */
if(!rocke_i_live(b))
{
return NULL;
}
/* c_neg_log2e = b.const_f32(-1.4426950408889634) */
c_neg_log2e = rocke_b_const_f32(b, -1.4426950408889634);
/* one = b.const_f32(1.0) */
one = rocke_b_const_f32(b, 1.0);
/* return b.rcp(b.fadd(one, b.exp2(b.fmul(c_neg_log2e, x))))
*
* Innermost-out: the fmul, exp2 and fadd are each emitted before rcp.
* `one` was emitted above; fadd's first argument (`one`) precedes its
* second (the exp2 chain) in Python's left-to-right argument evaluation,
* but since `one` is an already-bound Value the only new emissions inside
* fadd come from the exp2 subexpression -- sequenced here for clarity. */
{
rocke_value_t* prod = rocke_b_fmul(b, c_neg_log2e, x);
rocke_value_t* ex = rocke_b_exp2(b, prod);
rocke_value_t* sum = rocke_b_fadd(b, one, ex);
return rocke_b_rcp(b, sum);
}
}
rocke_value_t* rocke_tanh_via_exp2(rocke_ir_builder_t* b, rocke_value_t* x)
{
rocke_value_t* c_2log2e;
rocke_value_t* one;
rocke_value_t* e2x;
/* Sticky-error model: a failed builder makes every call a NULL no-op. */
if(!rocke_i_live(b))
{
return NULL;
}
/* c_2log2e = b.const_f32(2.0 * 1.4426950408889634) */
c_2log2e = rocke_b_const_f32(b, 2.0 * 1.4426950408889634);
/* one = b.const_f32(1.0) */
one = rocke_b_const_f32(b, 1.0);
/* e2x = b.exp2(b.fmul(c_2log2e, x)) */
e2x = rocke_b_exp2(b, rocke_b_fmul(b, c_2log2e, x));
/* return b.fmul(b.fsub(e2x, one), b.rcp(b.fadd(e2x, one)))
*
* Python evaluates fmul's arguments left-to-right: the fsub is emitted
* before the rcp(fadd) chain, and each consumes SSA value-counter ticks.
* Sequenced explicitly to keep value numbering byte-identical. */
{
rocke_value_t* num = rocke_b_fsub(b, e2x, one);
rocke_value_t* den = rocke_b_rcp(b, rocke_b_fadd(b, e2x, one));
return rocke_b_fmul(b, num, den);
}
}