Skip to content

feat: add exp2 and log2 operations#1197

Open
jeff-hiner wants to merge 4 commits into
tracel-ai:mainfrom
jeff-hiner:exp2_log2
Open

feat: add exp2 and log2 operations#1197
jeff-hiner wants to merge 4 commits into
tracel-ai:mainfrom
jeff-hiner:exp2_log2

Conversation

@jeff-hiner

Copy link
Copy Markdown

Inside tight loops for inference engines that do stuff like sigmoid functions, it's often more efficient to precalculate a constant to multiply, and then use exp2/log2 instead of exp. This is because the 2 variants generally only require some very simple math on the exponent. (Some Stable Diffusion implementations use this trick, and I want to mirror it.)

Add Exp2 and Log2 as first-class operations in cubecl-ir, mirroring the existing Exp and Log operations. Wire them through all backends:

  • cubecl-core: trait impls for all float types, Float supertrait bound
  • cubecl-ir: Arithmetic enum variants with Display
  • cubecl-opt: visitor and constant propagation support
  • cubecl-spirv: GLSLstd450 Exp2/Log2 extension instructions
  • cubecl-wgpu: exp2()/log2() WGSL builtins

Validate your PR with burn.

This PR is purely additive, and doesn't introduce any issues in burn. (But I did fork it and check.)

Add Exp2 and Log2 as first-class operations in cubecl-ir, mirroring the
existing Exp and Log operations. Wire them through all backends:
- cubecl-core: trait impls for all float types, Float supertrait bound
- cubecl-ir: Arithmetic enum variants with Display
- cubecl-opt: visitor and constant propagation support
- cubecl-spirv: GLSLstd450 Exp2/Log2 extension instructions
- cubecl-wgpu: exp2()/log2() WGSL builtins
impl<const POS: u8> Recip for ElemExpand<POS> {}
impl<const POS: u8> Erf for ElemExpand<POS> {}
impl<const POS: u8> Exp for ElemExpand<POS> {}
impl<const POS: u8> Exp2 for ElemExpand<POS> {}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be updated

+ Exp
+ Exp2
+ Log
+ Log1p

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason Log2 was left out here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason Log2 was left out here

let out = out.fmt_left();
writeln!(f, "{out} = exp({input});")
}
Instruction::Exp2 { input, out } => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should also be implemented for the cpp compiler

@antimora

antimora commented Apr 3, 2026

Copy link
Copy Markdown
Collaborator

Stale?

@jeff-hiner

Copy link
Copy Markdown
Author

Not abandoned, I've just been a bit busy with some personal matters the last couple weeks. Give me a moment.

@jeff-hiner

Copy link
Copy Markdown
Author

I believe everything has been resolved, but I'm not as familiar with the codebase as the owners. Is everything good here, or does it need more work?

@nathanielsimard nathanielsimard left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the only missing piece is the unit tests. I believe they are in cubecl-core/src/runtime_tests

@jeff-hiner

Copy link
Copy Markdown
Author

I wasn't able to find any matching unit tests for exp or log in cubecl-core/src/runtime_tests, but I'm trying to keep this lined up for a potential merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants