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

Add llvmcall #5046

Merged
merged 4 commits into from
Aug 12, 2014
Merged

Add llvmcall #5046

merged 4 commits into from
Aug 12, 2014

Conversation

Keno
Copy link
Member

@Keno Keno commented Dec 7, 2013

This adds llvmcall as described in #4042. This is the simple version of this intrinsic.
I have another version that basically takes functions in place of the IR and the various type declarations, allowing you to integrate any llvm based compiler. I'm a lot less sure about that interface than I am about this one, but I figured I'd mention it in this context anyway, since it's another point of discussion that's fairly similar (in particular, how do we efficiently do inline IR,C,ASM,D,whatever)?

@ViralBShah
Copy link
Member

Having llvmcall is a good start. We can discuss other stuff about inlining code from other languages in a separate issue.

Is this good to merge?

@lindahua
Copy link
Contributor

I am also looking forward to this.

@lindahua
Copy link
Contributor

It is good to add some documentation of llvmcall.

@pygy
Copy link
Contributor

pygy commented Jan 30, 2014

Any chance to see this merged before 0.3?

The examples of #4042 could be used as documentation.

@filmackay
Copy link

I have an issue with llvmcall, am finding that the IR generated does not have quotes around the defined LLVM function name, when the Julia function calls llvmcall:

using Base.llvmcall
function +(x::Int32, y::Int32)
    llvmcall("""%3 = add i32 %1, %0
                ret i32 %3""", Int32, (Int32, Int32), x, y)
end

code_llvm(+, (Int32, Int32))

Output:

ERROR: error compiling +: Failed to parse LLVM Assembly:
julia: <string>:2:19: error: expected '(' in function argument list
define i32 @julia_+961(i32 ,i32 ) {
                  ^

 in _dump_function at reflection.jl:132
 in code_llvm at reflection.jl:139

It's lacking quotes around the LLVM function, like the standard + function:

define i64 @"julia_+85"(i32, i32) {
top:
  %2 = sext i32 %0 to i64, !dbg !281
  %3 = sext i32 %1 to i64, !dbg !281
  %4 = add i64 %3, %2, !dbg !281
  ret i64 %4, !dbg !281
}

@lindahua
Copy link
Contributor

I also want to see this land before 0.3/

@ViralBShah
Copy link
Member

@loladiro @JeffBezanson Is this possible for 0.3?

@pieterverstraete
Copy link

I am trying to add support for PTX intrinsics in Julia using llvmcall. However, when using this in a Julia function, I always encounter the following problem:

declare function:

julia> function ptx_test(a,b,c)
       idx = Base.llvmcall("""%1 = tail call i32 @llvm.nvvm.read.ptx.sreg.tid.x() readnone nounwind
                                   ret i32 %1""", Int32, ())
       c[idx] = a[idx] + b[idx]
       return nothing
       end
ptx_test (generic function with 1 method)

retrieve llvm IR of this function:

julia> code_llvm(ptx_test, (Array{Int32,1},Array{Int32,1},Array{Int32,1}))
PTX function found: ptx_test
ERROR: error compiling ptx_test: Failed to parse LLVM Assembly:
julia: <string>:3:20: error: use of undefined value '@llvm.nvvm.read.ptx.sreg.tid.x'
    %1 = tail call i32 @llvm.nvvm.read.ptx.sreg.tid.x() readnone nounwind
                        ^
in _dump_function at reflection.jl:132
in code_llvm at reflection.jl:139

However, if I execute the same code_llvm command again directly after this, It works (correct IR is returned). How can I avoid this error when compiling for the first time? It seems like the intrinsic should be declared first, but is it possible to achieve this using llvmcall?

@Keno
Copy link
Member Author

Keno commented Mar 6, 2014

You raise a valid point. I believe the way to do this is probably to just go through all unreferenced functions and look them up in the global function table (or if they are intrinsics try to find them). Shouldn't be too hard. I may have a look at it over the weekend.

@pieterverstraete
Copy link

I have another use case where the above mentioned problem occurs. In my project, I need to declare and get a reference to global variables on the fly. However, with llvmcall, all code is added to the module in a function scope and I need to add global variables. Currently I see two possibilities to solve this problem:

  1. I use llvmcall, scan the code (ir string) for the usage of undeclared global variables and declare them.
  2. I modify llvmcall to allow ir code to be added in both global and function scope and add a boolean to the call for the user to denote whether his code should be added globally or not.

What do you think is the best solution? Or is there another way of solving this problem?

@ihnorton ihnorton mentioned this pull request May 2, 2014
@Keno
Copy link
Member Author

Keno commented Jul 18, 2014

Rebased on top of current master and added the ability to just pass a pointer to an llvm::Function*. Together with staged functions that is a very powerful combination.

@Keno
Copy link
Member Author

Keno commented Aug 12, 2014

Travis originally failed due to an unrelated crash. I restarted the travis build and will merge once that passes since it's 0.4 now.

@IainNZ
Copy link
Member

IainNZ commented Aug 12, 2014

@Keno, if you ever get a chance, I'd love to see even a short write up of good uses for this

@Keno
Copy link
Member Author

Keno commented Aug 12, 2014

I'll put it on the todo list ;)

f = m->getFunction(ir_name);
} else {
assert(isPtr);
// Create Function sceleton
Copy link
Member

Choose a reason for hiding this comment

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

small typo: sceleton -> skeleton

@jakebolewski
Copy link
Member

It it would make a great blog post showing off some of the things you can do with this. @IainNZ you can look at Cxx.jl which uses this functionality already. Another example is in the tests, SIMD instructions!.

Keno added a commit that referenced this pull request Aug 12, 2014
@Keno Keno merged commit a636295 into master Aug 12, 2014
@Keno
Copy link
Member Author

Keno commented Aug 12, 2014

Note that you may have to make clean after pulling this.

@IainNZ
Copy link
Member

IainNZ commented Aug 12, 2014

I wonder what will be the first of these new merges to set off all the PackageEvaluator alarms :D

@Keno
Copy link
Member Author

Keno commented Aug 12, 2014

Can't wait ;)

@timholy
Copy link
Sponsor Member

timholy commented Aug 12, 2014

Nice!

@pieterverstraete, your application sounds pretty interesting! Now that this is merged, I'll keep my fingers crossed.

@jakebolewski
Copy link
Member

I don't think this is general enough to do what he wanted. Ptx requires a
whole different target machine, ctx, as well as a runtime to launch the
kernels. This exposes the running llvm mcjit instance Julia is using.
Staged functions are something that would help with alternative backends.

On Tuesday, August 12, 2014, Tim Holy [email protected] wrote:

Nice!

@pieterverstraete https://github.com/pieterverstraete, your application
sounds pretty interesting! Now that this is merged, I'll keep my fingers
crossed.


Reply to this email directly or view it on GitHub
#5046 (comment).

@vtjnash
Copy link
Sponsor Member

vtjnash commented Aug 13, 2014

needs docs

@maleadt
Copy link
Member

maleadt commented Sep 11, 2014

Contents removed; see #8308.

@pao
Copy link
Member

pao commented Sep 11, 2014

I know this has been merged already, but I have a feature request which applies to llvmcall so this seemed like a good place to discuss it.

We're not allergic to new issues, and that would allow your feature request to be tracked more easily. Adding it to a closed issue means that we don't have the ability to tag, milestone, or use the other tools available to us to work with it. It's appropriate to cross-reference this issue in the new one, but please do open a new issue.

@maleadt
Copy link
Member

maleadt commented Sep 11, 2014

Okay, will repost in a new issue.

@pao
Copy link
Member

pao commented Sep 11, 2014

Thanks!

@JeffBezanson JeffBezanson deleted the kf/llvmcall branch October 25, 2014 17:24
@ViralBShah ViralBShah added the domain:gpu Affects running Julia on a GPU label Sep 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:gpu Affects running Julia on a GPU
Projects
None yet
Development

Successfully merging this pull request may close these issues.