Calling julia functions from python

pycall

#1

I’m interested in using Julia to speed up parts of a python program I’m writing.

It seems pyjulia https://github.com/JuliaPy/pyjulia is the standard package to do this with? As it uses pycall I guess it should be fine to call the function with some arguments being ndarrays (from numpy)?
Looking at pyjulia, calling stdlib functions and evaluating julia expressions seems pretty straightforward. But I don’t understand how one is supposed to, let’s say, import a julia function from a .jl file and then call it with some (python) arguments?


#2

I think pyjulia needs a little love. I distinctly remember figuring this out a long time ago, but am unable to do so in an easy fashion right now.

The best I could come up with is to take advantage of the fact that, when you include a file in julia, the last “value” in the file is returned. If the last thing in the file, is a function, then you get back an anonymous version of that function:

# test.jl

function myArrayFn{T<:Number}(x::Array{T})
    println("array size: $(size(x))");
    println("max element: $(maximum(x))")
    println("min element: $(minimum(x))")
    return 2x
end
In [1]: import julia

In [2]: j = julia.Julia()

In [3]: fn = j.include('test.jl')

In [4]: fn
Out[4]: <PyCall.jlwrap myArrayFn>

In [5]: import numpy as np

In [6]: x = np.array([[1,2,3], [4,5,6]], dtype=np.float64)

In [7]: fn(x)
array size: (2,3)
max element: 6.0
min element: 1.0
Out[7]:
array([[  2.,   4.,   6.],
       [  8.,  10.,  12.]])

This only works for the last function in the file.

I tried a number of other things (using include, include_string, etc.), and nothing seemed to modify the Julia environment available in the python Julia object. It might be that the internals have changed, and that pyjulia hasn’t kept up. Or maybe I’m just doing something wrong. I haven’t tried digging into the code to see why.

Anyway, hope this helps, and maybe someone else will respond with better info.

Cheers,
Kevin


#3

Figured it out. With foo being an exported function in test.jl:

import julia
j = julia.Julia()
j.include("test.jl")
j.eval("importall julia_util")  # I used importall, sure other stuff also works.

Now you can define your function with foo = jl.eval("foo").

Or you do j.add_module_functions("julia_util") and then use j.foo.