rprechelt / Vectorize.jl

Cross-platform vectorization of Julia code using Accelerate, VML, and Yeppp!
http://vectorizejl.readthedocs.io/en/latest/
Other
19 stars 7 forks source link

Compilation versus Interpretation #3

Closed rprechelt closed 8 years ago

rprechelt commented 8 years ago

@ArchRobison

I was wondering if you had any insight into the conditions that would cause Julia to interpret an expression as opposed to running it through the JIT compiler - I've been struggling with getting Julia to compile the expressions (so I can access LLVM through codegen.cpp) versus running the code through interpreter.cpp. I've been trying to make some sense of toplevel.cpp to figure this out, however the Julia DSL (that I am still getting accustomed to) makes things slow going. I also can't find any info on it anywhere in the devdocs beyond

:c:func:jl_toplevel_eval_flex then uses some simple heuristics to decide whether to JIT compiler the AST or to interpret it directly.

I've been following the general structure of your @simd implementation for what's it is worth.

ArchRobison commented 8 years ago

I have not looked at the logic closely or lately, and I know there's been a concern over compilation time since the switch from LLVM 3.3 to 3.7, so I wouldn't be surprised if the logic has become more biased towards interpretation.

I had the impression, perhaps mistaken, that the callee in a function call is always compiled. For poking around with codegen.cpp, I usually force compilation using code_llvm. E.g., on the weekend I was tracing though codegen.cpp for this example:

typealias m256 NTuple{8,VecElement{Float32}}

function call_dist(a::m256, b::m256)
    ccall((:dist, "libdist"), m256, (m256, m256), a, b)
end

code_llvm(call_dist,(m256,m256))
rprechelt commented 8 years ago

Ok - I've still been playing around with codegen.cpp and have been making progress towards my understanding of the Julia internals. Currently, I've had to implement the following changes to code within Julia. These changes were just meant to be an exercise to help me get a handle on how Julia's codegen works...

https://github.com/JuliaLang/julia/compare/master...rprechelt:rp/vectorize

Yet, I still cannot get Julia to evaluate my expression through codegen.cpp (in the same way that the SIMD pass gets run). For testing, any attempt to codegen :vectorize_sym, should print a message to stdout. See here. I've tried building expressions with :vectorize as head, and placing these :vectorize expressions inside of functions. I either end up with

ERROR: UndefVarError: vectorize not defined

or

ERROR: Vectorize does not support interpreted expressions. 

Clearly, I am missing something very obvious with regards to Julia codegen - any advice or guidance here? @vtjnash

rprechelt commented 8 years ago

In that vein, might it be worth using this GSoC opportunity to provide a C++ method of accessing the :meta tags that have been included since v0.4 instead of adding another specialized symbol to codegen.cpp? We could then use pushmeta to add the :vectorize flag; this is mentioned here.

If we built a method to allow additional annotations to be defined during the Julia build process, so that a user could add their own C++ checks without modifying codegen.cpp directly, we might be one step closer to Arch's "general hook" idea in #2

ArchRobison commented 8 years ago

I'm just guessing, but perhaps the problem is the scope in which :vectorize is being looked up?

rprechelt commented 8 years ago

I've tried experimenting with that; whenever I place an expression at global scope, :vectorize is interpreted by interpreter.c successfully. As soon as I place the expression not at global scope, I get the error. I'm not familiar enough with the Julia code base yet to be able to diagnose where I could investigate this scoping issue.

rprechelt commented 8 years ago

I've tried many variants of the below:

function vectorizetest()
    Expr(:vectorize)
end

under the understanding that when I run @code_llvm vectorizetest(), that Julia should compile the function vectorizetest(). During that, it should run emit_expr on Expr(:vectorize) which should trigger the ex->head == vectorize_sym check in codegen.cpp. Yet after much printing from within emit_expr, I can find no evidence that :vectorize as a symbol is ever making it into emit_expr.

I'm somewhat stuck on this right now - been trying for a few days.. Apologies for all the simple questions - still getting my head around codegen.

vtjnash commented 8 years ago

Expr(:vectorize) isn't an Expr, it's and expression to create an Expr. But you need the actual Expr object to be embedded in the code.

@eval vectorizetest() = $(Expr(:vectorize))

For a similar example, you could take a look at how simdloop deals with this for marking specific loops. If you just need to mark the whole function, putting it in an Expr(:meta) might be easier, since you can follow the example of macro pure or macro inline