Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mojo-compiler] CompTime interpreter should be able to fold pop.call_llvm_intrinsic #933

Closed
soraros opened this issue Sep 27, 2023 · 11 comments
Assignees
Labels
bug Something isn't working mojo Issues that are related to mojo mojo-lang Tag for all issues related to language. mojo-repo Tag all issues with this label

Comments

@soraros
Copy link
Contributor

soraros commented Sep 27, 2023

Bug description

math.bit functions doesn't run at compile time.

Steps to reproduce

Consider the following code:

import math.bit as bit

fn main():
  alias n = bit.ctlz(10)

It produces the following error message:

/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:70:1: error: no viable expansions found
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:70:1: note:   call expansion failed - no concrete specializations
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:51:1: note:     no viable expansions found
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:65:57: note:       call expansion failed - no concrete specializations
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:29:1: note:         no viable expansions found
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:42:18: note:           call expansion failed - no concrete specializations
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:62:5: note:             no viable expansions found
/__w/modular/modular/Kernels/mojo/builtin/_startup.mojo:63:22: note:               call expansion failed - no concrete specializations
/workspaces/ubuntu/hello.mojo:3:1: note:                 no viable expansions found
def main():
^
/workspaces/ubuntu/hello.mojo:4:3: note:                   failed to evaluate 'apply'
  alias n = bit.ctlz(10)
  ^
/__w/modular/modular/Kernels/mojo/math/bit.mojo:81:1: note:                     failed to interpret function @$math::$bit::ctlz($builtin::$int::Int)_concrete
/__w/modular/modular/Kernels/mojo/math/bit.mojo:90:44: note:                       failed to fold operation pop.call_llvm_intrinsic(10 : index, #pop<simd false> : !pop.scalar<bool>)
mojo: error: failed to run the pass manager

System information

- OS: Docker on Intel macOS
- mojo -v: mojo 0.3.0 (f64f9601)
- modular -v: modular 0.1.4 (6b54d308)
@soraros soraros added bug Something isn't working mojo Issues that are related to mojo labels Sep 27, 2023
@ematejska ematejska added the mojo-lang Tag for all issues related to language. label Sep 27, 2023
@Mogball
Copy link
Collaborator

Mogball commented Sep 27, 2023

Thanks for filing! We haven't implemented compile-time interpretation of LLVM intrinsics, and it's not clear that's a worthwhile endeavor. That said, there are other ways we can make this work.

@soraros
Copy link
Contributor Author

soraros commented Sep 27, 2023

@Mogball Regardless of how the internal works, I'd still expect this code to run. Because from a users perspective, math.bit just look like any other module. If they definitely can't run at compile time, we should somehow use the type system or some decorators to communicate that fact. It would still be great if you could try "the other way" to make this work though.

I was trying to implement power_of_2 with the math.bit functions in constrained[power_of_2(n)]() for SIMD width checking, which I think is pretty valid use case.

@Mogball
Copy link
Collaborator

Mogball commented Sep 28, 2023

A decorator would be useful from a library design perspective to clearly communicate to users what functions are not intended to run at compile time. However, the language can't rely on library authors always being meticulous with using the decorator, which is why it provides a detailed, if cryptic, error message.

I do agree that the category of functions in math.bit should run at compile time though.

@abduld
Copy link
Contributor

abduld commented Oct 2, 2023

FYI: There is an is_power_of_2 function in the math module which should be compile-time evaluated . You can implement it yourself using

fn is_power_of_2(val: Int) -> Bool:
    return (val & (val - 1) == 0) and (val != 0)

@soraros
Copy link
Contributor Author

soraros commented Oct 2, 2023

@abduld Thanks for the pointer. I'm familiar with this implementation yet didn't know the existence of this function in the stdlib.

@JoeLoser JoeLoser changed the title [BUG]: math.bit functions doesn't run at compile time [mojo-compiler] CompTime interpreter should be able to fold pop.call_llvm_intrinsic Apr 11, 2024
@JoeLoser
Copy link
Collaborator

I've renamed this issue to track the general problem from my observations this past week. From our internal Mojo discussion on this yesterday, we do want to implement support for this (folding llvm_intrinsincs so they work in compile time).

Some notes I'll share from our internal discussion:

  1. We don’t want a split source of truth that causes divergence between comptime and runtime. ⇒ We don’t want a “if running in the comptime interpreter” parameter check.
  2. Not all llvm intrinsics have folders and some have side effects, so not everything can be run at comptime. This is also true of “printf” or c function at comptime today.
  3. That said, some simple things like this do, and can be folded, so we just need to wire that up.
  4. MLIR LLVM dialect may/probably doesn’t have the ability to do this, so we might have to implement these folders upstream.

The big issue is probably plumbing (4) correctly from the list above.

@Mogball
Copy link
Collaborator

Mogball commented Apr 18, 2024

We can inject fold/interpret hooks into the LLVMDialect. We're not bound by upstream in this regard. I suspect there will be resistance to adding intrinsics folders upstream anyways.

@msaelices
Copy link
Contributor

msaelices commented Aug 18, 2024

@JoeLoser, somehow, above's code seems to be working now. I've tested it, and it worked:

from bit import count_leading_zeros

fn main():
  alias n = count_leading_zeros(10)

Note: this is the code adapted from the description based on some bit package changes, as now it's not part of the math package and the ctlz is now called count_leading_zeros

However, I'm not sure if the bug is fixed.

@soraros
Copy link
Contributor Author

soraros commented Aug 19, 2024

@msaelices I think it's because it's being eliminated as dead code. This still fails:

fn main():
  alias n = count_leading_zeros(10)
  print(n)

@gabrieldemarmiesse
Copy link
Contributor

@lattner ping on this issue since you asked :)

@lattner
Copy link
Collaborator

lattner commented Sep 16, 2024

Awesome, I put together a fix, I'll discuss with the team tomorrow and see if they like it.

@lattner lattner self-assigned this Sep 16, 2024
@lattner lattner closed this as completed Sep 16, 2024
@lattner lattner closed this as completed Sep 16, 2024
modularbot pushed a commit that referenced this issue Sep 16, 2024
This teaches the mojo comptime interpreter about LLVM intrinsics,
at least for simple cases involving integer operands and results
(it would be straightforward to extend this to other types now).

This fixes #933 and
Fixes MOCO-138 and Fixes MOCO-504

MODULAR_ORIG_COMMIT_REV_ID: 900128df66da907a0bf61a3b2affb730ef253e17
msaelices pushed a commit to msaelices/mojo that referenced this issue Sep 16, 2024
This teaches the mojo comptime interpreter about LLVM intrinsics,
at least for simple cases involving integer operands and results
(it would be straightforward to extend this to other types now).

This fixes modularml#933 and
Fixes MOCO-138 and Fixes MOCO-504

MODULAR_ORIG_COMMIT_REV_ID: 900128df66da907a0bf61a3b2affb730ef253e17

Signed-off-by: Manuel Saelices <[email protected]>
hayduker pushed a commit to hayduker/mojo that referenced this issue Sep 17, 2024
This teaches the mojo comptime interpreter about LLVM intrinsics,
at least for simple cases involving integer operands and results
(it would be straightforward to extend this to other types now).

This fixes modularml#933 and
Fixes MOCO-138 and Fixes MOCO-504

MODULAR_ORIG_COMMIT_REV_ID: 900128df66da907a0bf61a3b2affb730ef253e17
hayduker pushed a commit to hayduker/mojo that referenced this issue Sep 17, 2024
This teaches the mojo comptime interpreter about LLVM intrinsics,
at least for simple cases involving integer operands and results
(it would be straightforward to extend this to other types now).

This fixes modularml#933 and
Fixes MOCO-138 and Fixes MOCO-504

MODULAR_ORIG_COMMIT_REV_ID: 900128df66da907a0bf61a3b2affb730ef253e17

Signed-off-by: Derek Smith <[email protected]>
hayduker pushed a commit to hayduker/mojo that referenced this issue Sep 17, 2024
This teaches the mojo comptime interpreter about LLVM intrinsics,
at least for simple cases involving integer operands and results
(it would be straightforward to extend this to other types now).

This fixes modularml#933 and
Fixes MOCO-138 and Fixes MOCO-504

MODULAR_ORIG_COMMIT_REV_ID: 900128df66da907a0bf61a3b2affb730ef253e17
hayduker pushed a commit to hayduker/mojo that referenced this issue Sep 17, 2024
This teaches the mojo comptime interpreter about LLVM intrinsics,
at least for simple cases involving integer operands and results
(it would be straightforward to extend this to other types now).

This fixes modularml#933 and
Fixes MOCO-138 and Fixes MOCO-504

MODULAR_ORIG_COMMIT_REV_ID: 900128df66da907a0bf61a3b2affb730ef253e17

Signed-off-by: Derek Smith <[email protected]>
hayduker pushed a commit to hayduker/mojo that referenced this issue Sep 17, 2024
This teaches the mojo comptime interpreter about LLVM intrinsics,
at least for simple cases involving integer operands and results
(it would be straightforward to extend this to other types now).

This fixes modularml#933 and
Fixes MOCO-138 and Fixes MOCO-504

MODULAR_ORIG_COMMIT_REV_ID: 900128df66da907a0bf61a3b2affb730ef253e17

Signed-off-by: Derek Smith <[email protected]>
hayduker pushed a commit to hayduker/mojo that referenced this issue Sep 17, 2024
This teaches the mojo comptime interpreter about LLVM intrinsics,
at least for simple cases involving integer operands and results
(it would be straightforward to extend this to other types now).

This fixes modularml#933 and
Fixes MOCO-138 and Fixes MOCO-504

MODULAR_ORIG_COMMIT_REV_ID: 900128df66da907a0bf61a3b2affb730ef253e17

Signed-off-by: Derek Smith <[email protected]>
hayduker pushed a commit to hayduker/mojo that referenced this issue Sep 17, 2024
This teaches the mojo comptime interpreter about LLVM intrinsics,
at least for simple cases involving integer operands and results
(it would be straightforward to extend this to other types now).

This fixes modularml#933 and
Fixes MOCO-138 and Fixes MOCO-504

MODULAR_ORIG_COMMIT_REV_ID: 900128df66da907a0bf61a3b2affb730ef253e17

Signed-off-by: Derek Smith <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working mojo Issues that are related to mojo mojo-lang Tag for all issues related to language. mojo-repo Tag all issues with this label
Projects
None yet
Development

No branches or pull requests

8 participants