# How does the memory model of pyjulia work?

**URL:** https://discourse.julialang.org/t/how-does-the-memory-model-of-pyjulia-work/62989
**Category:** General Usage
**Created:** [June 16, 2021, 5:25am UTC](https://discourse.julialang.org/t/how-does-the-memory-model-of-pyjulia-work/62989 "2021-06-16T05:25:23Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)
#### Post date: [June 16, 2021, 5:25am UTC](https://discourse.julialang.org/t/how-does-the-memory-model-of-pyjulia-work/62989/1 "2021-06-16T05:25:23Z")

</div>

I am using Julia from Python via pyjulia which has a [how it works](https://pyjulia.readthedocs.io/en/stable/how_it_works.html).

But I want to understand if there are performance implications. E.g. if I have a numpy array in python and use it in Julia; is Julia making a copy or using the array in place?

Vice versa, when I use a vector created in Julia in python, is it using the same block of memory, or is it making a copy?

---

<div class="post-metadata">

### Author: ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)
#### Post date: [June 16, 2021, 8:29am UTC](https://discourse.julialang.org/t/how-does-the-memory-model-of-pyjulia-work/62989/2 "2021-06-16T08:29:36Z")

</div>

I am pretty sure no copy is made. To check it just mutate an array on one side and see if the mutation is present on the other side.

---

<div class="post-metadata">

### Author: ![paulmelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paulmelis/32/35063_2.png) [@paulmelis](https://discourse.julialang.org/u/paulmelis)
#### Post date: [June 16, 2021, 12:18pm UTC](https://discourse.julialang.org/t/how-does-the-memory-model-of-pyjulia-work/62989/3 "2021-06-16T12:18:41Z")

</div>

I remember having issues with unnecessary copies, [Python NumPy array is not modified inside Julia · Issue #385 · JuliaPy/pyjulia · GitHub](https://github.com/JuliaPy/pyjulia/issues/385)

---

<div class="post-metadata">

### Author: ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)
#### Post date: [June 16, 2021, 12:42pm UTC](https://discourse.julialang.org/t/how-does-the-memory-model-of-pyjulia-work/62989/4 "2021-06-16T12:42:24Z")

</div>

From the pycall docs:

> From Julia to Python
> 
> Assuming you have NumPy installed (true by default if you use Conda), then a Julia `a::Array` of NumPy-compatible elements is converted by `PyObject(a)` into a NumPy wrapper for the _same data_ , i.e. without copying the data. Julia arrays are stored in [column-major order](https://en.wikipedia.org/wiki/Row-major_order), and since NumPy supports column-major arrays this is not a problem.
> 
> However, the _default_ ordering of NumPy arrays created in _Python_ is row-major, and some Python packages will throw an error if you try to pass them column-major NumPy arrays. To deal with this, you can use `PyReverseDims(a)` to pass a Julia array as a row-major NumPy array with the dimensions _reversed_ . For example, if `a` is a 3x4x5 Julia array, then `PyReverseDims(a)` passes it as a 5x4x3 NumPy row-major array (without making a copy of the underlying data).
> 
> A `Vector{UInt8}` object in Julia, by default, is converted to a Python `bytearray` object. If you want a `bytes` object instead, you can use the function `pybytes(a)` .
> 
> ##### From Python to Julia
> 
> Multidimensional NumPy arrays ( `ndarray` ) are supported and can be converted to the native Julia `Array` type, which makes a copy of the data.
> 
> 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.)
> 
> Conversely, when passing arrays _to_ Python, Julia `Array` types are converted to `PyObject` types _without_ making a copy via NumPy, e.g. when passed as `pycall` arguments.

There is more information [here](https://github.com/JuliaPy/PyCall.jl#python-object-interfaces) .
