Quantcast
Channel: First steps - JuliaLang
Viewing all articles
Browse latest Browse all 2795

PyJulia, passing numpy array from Python side

$
0
0

I’m looking into extending Python with Julia code through PyJulia, particularly allocating numpy arrays in Python, passing them to Julia (without copying) to do some processing and then use the result in Python again. This seems to be the reverse of what many other users are doing (i.e. using PyCall from Julia to call into Python), so maybe what I want is not supported.

But looking at the docs for PyCall, specifically https://github.com/JuliaPy/PyCall.jl#arrays-and-pyarray, seems to suggest it is possible to pass a NumPy array from Python to Julia without copying:

Alternatively, the PyCall module also provides a new type PyArray (a subclass of AbstractArray ) which implements a no-copy wrapper around a NumPy array (currently of numeric types or objects only). Just use PyArray as the return type of a pycall returning an ndarray , or call PyArray(o::PyObject) on an ndarray object o . (Technically, a PyArray works for any Python object that uses the NumPy array interface to provide a data pointer and shape information.)

However, the referenced PyArray type lives on the Julia side so I can’t call it on the Python side. Using a Julia function with signature fn(x::PyArray) also doesn’t seem to do automatic conversion, as I get a no method matching fn(::Array{Float32,2}) error when called from Python with:

melis@juggle 15:33:~$ cat fn.jl 
function fn(x::PyArray)
    println("array size: $(size(x))");
    println("max element: $(maximum(x))")
    println("min element: $(minimum(x))")
    x[1,1] = 123
    return 2x
end

melis@juggle 15:33:~$ cat callit.py 
from julia.api import Julia
from julia import Main

jl = Julia(compiled_modules=False)
jl.eval('include("fn.jl")')

import numpy as np

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

res = Main.fn(x)

melis@juggle 15:34:~$ python callit.py 
Traceback (most recent call last):
  File "callit.py", line 11, in <module>
    res = Main.fn(x)
RuntimeError: Julia exception: MethodError: no method matching fn(::Array{Float64,2})
Closest candidates are:
  fn(!Matched::PyArray) at /home/melis/concepts/blender-julia/fn.jl:1
Stacktrace:
 [1] #invokelatest#1 at ./essentials.jl:710 [inlined]
 [2] invokelatest(::Any, ::Any) at ./essentials.jl:709
 [3] _pyjlwrap_call(::Function, ::Ptr{PyCall.PyObject_struct}, ::Ptr{PyCall.PyObject_struct}) at /home/melis/.julia/packages/PyCall/zqDXB/src/callback.jl:28
 [4] pyjlwrap_call(::Ptr{PyCall.PyObject_struct}, ::Ptr{PyCall.PyObject_struct}, ::Ptr{PyCall.PyObject_struct}) at /home/melis/.julia/packages/PyCall/zqDXB/src/callback.jl:49

Any other ways to make this work?

Edit: word

5 posts - 3 participants

Read full topic


Viewing all articles
Browse latest Browse all 2795

Latest Images

Trending Articles



Latest Images