Giter VIP home page Giter VIP logo

ben-izd / shared_memory Goto Github PK

View Code? Open in Web Editor NEW
28.0 2.0 3.0 2.9 MB

Share data between Python - Julia - Matlab - Java - Wolfram Language (Mathematica) through memory

License: MIT License

Julia 8.01% Mathematica 5.91% Python 12.75% C 1.04% Rust 19.27% MATLAB 9.32% Java 43.70%
data-sharing julia mathematica matlab python shared-memory wolfram-language java jdk19 rust numpy project-panama sharing-data

shared_memory's Introduction

Shared Memory

Image poster shows multiple languages are connected using shared memory

Easily and efficiently share rectangular array (any dimension, any type) or String between Python, Julia, Matlab - Wolfram Language (Mathematica), Java through memory. Each language somehow implements sharing data either for its sub-kernel or the same processes but now you can share between them at a super fast speed. It's backed by a library written in Rust.

To make your life and mine easier, all the function names are the same (snake_case) except Mathematica which does not support underline and is PascalCase and Java which is a convention to be camelCase. All of them have simple logic action_shared_memory[_property], like get_shared_memory_flatten_length in Julia, Python and Matlab which is GetSharedMemoryFlattenLength in Mathematica and all have the same functionality. (Due to Java's strict type syntax, some intermediate methods was introduced)

Simple Example

Let's suppose you have a matrix in julia and you would like to apply Numpy.sin function on it then use Matlab mpower, then in Mathematica use Minors and share that result with Java, how would you do it? Saving in a file? use socket?

If we ignore the Java, just reading and writing a 1000x1000 double matrix to disk on my system took around 8 seconds while using the shared memory it's under 1 second (0.26). It not only helps you to share data, it can share it super fast, far suprior than disk or socket. Here is the steps for a small matrix with this library:

First, we assume, you've downloaded the repository in your C:\download directory.

  1. Julia
# Setup
include(raw"C:\download\shared_memory\julia\shared_memory.jl")
set_shared_memory_path(raw"C:\download\shared_memory\data")

# Sample Matrix
data = [1 2 3 ; 4 5 6 ; 7 8 9];

# Share
set_shared_memory_data(data) 
  1. Python
import numpy
import sys

# Setup
sys.path.append(r'C:\download\shared_memory\python')
from shared_memory import *
set_shared_memory_path(r'C:\download\shared_memory\data')

# Receive
data = get_shared_memory_data()

# Manipulate
new_data = numpy.sin(data);

# Share
set_shared_memory_data(new_data)
  1. Matlab
% Setup
addpath("C:\\download\\shared_memory");
addpath("C:\\download\\shared_memory\\matlab");
set_shared_memory_path("C:\\download\\shared_memory\\data")

% Receive
data = get_shared_memory_data();

% Manipulate
new_data = mpower(data,2);

% Share
set_shared_memory_data(new_data)
  1. Mathematica (Wolfram Language)
(* Setup *)
SharedMemory`libraryPath = "C:\\download\\shared_memory\\shared_memory.dll";
Get["C:\\download\\shared_memory\\mathematica\\shared_memory.wl"];
SetSharedMemoryPath["C:\\download\\shared_memory\\data"];

(* Receive *)
data = GetSharedMemoryData[];

(* Manipulate *)
newData = Minors[data];

(* Share *)
SetSharedMemoryData[newData];
  1. Java
import com.github.ben_izd.shared_memory.SharedMemory;
import java.nio.file.Path;

public class Sample {
    public static void main(String[] args) {
        
        // Setup
        var libraryPath = Path.of("C:\\download\\shared_memory\\shared_memory.dll");
        try(SharedMemory sharedMemory = new SharedMemory(libraryPath)) {
            sharedMemory.setSharedMemoryPath("C:\\download\\shared_memory\\data");

            // Receive
            var data = sharedMemory.getSharedMemoryDouble2D();
        }
    }
}

Advance Example

Sharing Image

Assume you have an image inside Mathematica and you want to share it with other interfaces.

Mathematica

First we share our image (stored in sampleImage variable):

(* Setup *)
SharedMemory`libraryPath = "C:\\download\\shared_memory\\shared_memory.dll";
Get["C:\\download\\shared_memory\\mathematica\\shared_memory.wl"]
SetSharedMemoryPath["C:\\download\\shared_memory\\sample_image"]

(* Share *)
SetSharedMemoryData @ NumericArray @ ImageData[sampleImage, "Byte"]

Matlab

% Setup
addpath("C:\\download\\shared_memory");
addpath("C:\\download\\shared_memory\\matlab");
set_shared_memory_path("C:\\download\\shared_memory\\sample_image");

% Receive
data = get_shared_memory_data();
image = permute(data,[3 1 2])

Python

# Setup
import sys
sys.path.append(r'C:\download\shared_memory\python')
from shared_memory import *
from PIL import Image

set_shared_memory_path("C:\download\shared_memory\sample_image")

# Receive
data = get_shared_memory_data()
image = Image.fromarray(data, 'RGB')

Julia

# Setup
include(raw"C:\download\shared_memory\julia\shared_memory.jl")
using .shared_memory
import Images: colorview, RGB
set_shared_memory_path(raw"C:\download\shared_memory\sample_image")

# Receive
data = get_shared_memory_data()
image = colorview(RGB, permutedims(data, [2 3 1]) /255)

Java

import com.github.ben_izd.shared_memory.SharedMemory;
import java.nio.file.Path;
import java.awt.image.BufferedImage;

public class Sample {
    public static void main(String[] args) throws Throwable {
        var libraryPath = Path.of("E:\\projects\\Mathematica\\community\\31. shared_memory\\shared_memory.dll");
        try(SharedMemory sharedMemory = new SharedMemory(libraryPath)) {
            
            sharedMemory.setSharedMemoryPath(Path.of("E:\\projects\\Mathematica\\community\\31. shared_memory\\example\\image\\imageData"));
            var data = sharedMemory.getSharedMemoryByte3D();
            var image = readImage(data);
        }
    }

    public static BufferedImage readImage(byte[][][] data) {
        int width = data[0].length;
        int height = data.length;
        BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        int red,green,blue,rgb;
        for (int row = 0; row < height; row++) {
            for (int column = 0; column < width; column++) {

                red = data[row][column][0] & 0xFF;
                green = data[row][column][1] & 0xFF;
                blue = data[row][column][2] & 0xFF;
                rgb = (red << 16) | (green << 8) | blue;
                bufferedImage.setRGB(column,row,rgb);
            }
        }
        return bufferedImage;
    }
}

Initializations

Matlab

matlab folder contains all functions as separate files, just include that folder and the root (in windows folder contains .dll) to path variable with addpath or other methods to be able to use the functions.

Now use set_shared_memory_path function to set your shared memory file, a file used by other programs to access the data you'll share or want to receive.

Advance Tip: If you want to move the shared library (in windows that shared_memory.dll file), also move the head file shared_memory.h with it.

Mathematica

Before loading the package, first you have to set SharedMemory`libraryPath to the library path (in windows is .dll file). Then, use Get or other functions to load the package.

Julia

Just include the shared_memory.jl in your code.

If you moved the shared_memory.jl or shared_memory.dll file, then open shared_memory.jl file and set LIBRARY_PATH to the shared library (in windows is shared_memory.dll file).

Python

You need Numpy installed first. Add the python folder to your path with sys module and import the file like below:

import sys
sys.path.append(r'C:\download\shared_memory\python')

from shared_memory import *

If you moved the shared_memory.py or shared_memory.dll file, then open shared_memory.py file and set LIBRARY_PATH to the shared library (in windows is .dll file).

Java

Add java folder to you class path and give the path of shared library (in windows shared_memory.dll) file to the SharedMemory constructor.

Limitations

  • Only rectangular arrays or single String
  • Data stored in shared memory is column-major like Julia and Matlab but Mathematica and python (by default) are row-major, sending and receiving data from Python, Mathematica and Java will apply the necessary transformations.
  • Java does not have a complex notion. Because of that, you can't share or receive complex values within Java.

Documentation

Check all the functions and names in different interfaces in the Wiki section.

Notes for non-Windows users

The project was built on windows and the dll files is included in the repository, but if you're on other operating systems, you have to build the rust project on your platform which thanks to Rust cargo, is surprisingly easy.

How to build the Rust

  1. Install Rust on your computer
  2. Make sure you have an internet connection and build the Rust project (rust folder) - You can read Building for Release section.
  3. Go inside target/release, and use the built library.

Note

If you don't have Mathematica, you can comment the mathematica module in lib.rs and also comment wolfram-library-link = ... in cargo.toml file

shared_memory's People

Contributors

ben-izd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

shared_memory's Issues

Unable to compile on a Apple silicon macOS

I got 1 warning and 4 errors when trying to compile on macOS:

warning: creating a shared reference to mutable static is discouraged
   --> src/lib.rs:284:24
    |
284 |         match unsafe { &SHARED_MEMORY_FILE_PATH } {
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
    |
    = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
    = note: this will be a hard error in the 2024 edition
    = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
    = note: `#[warn(static_mut_refs)]` on by default
help: use `addr_of!` instead to create a raw pointer
    |
284 |         match unsafe { addr_of!(SHARED_MEMORY_FILE_PATH) } {
    |                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error[E0308]: mismatched types
    --> src/lib.rs:1071:88
     |
1071 |             SharedMemoryType::Unsigned32 => get_shared_memory_flatten_data_unsigned_32(numeric_array_data as *mut u32),
     |                                             ------------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `*mut u64`, found `*mut u32`
     |                                             |
     |                                             arguments to this function are incorrect
     |
     = note: expected raw pointer `*mut u64`
                found raw pointer `*mut u32`
note: function defined here
    --> src/lib.rs:641:23
     |
641  |     pub extern "C" fn get_shared_memory_flatten_data_unsigned_32(array_source: *mut c_ulong) -> c_int {
     |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------------------

error[E0308]: mismatched types
    --> src/lib.rs:1075:84
     |
1075 |             SharedMemoryType::Signed32 => get_shared_memory_flatten_data_signed_32(numeric_array_data as *mut i32),
     |                                           ---------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `*mut i64`, found `*mut i32`
     |                                           |
     |                                           arguments to this function are incorrect
     |
     = note: expected raw pointer `*mut i64`
                found raw pointer `*mut i32`
note: function defined here
    --> src/lib.rs:677:23
     |
677  |     pub extern "C" fn get_shared_memory_flatten_data_signed_32(array_source: *mut c_long) -> c_int {
     |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -------------------------

error[E0308]: mismatched types
    --> src/lib.rs:1255:51
     |
1255 | ...5 => set_shared_memory_data_signed_32(numeric_array_data as *const i32, numeric_array_dimensions, numeric_array_rank),
     |         -------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `*const i64`, found `*const i32`
     |         |
     |         arguments to this function are incorrect
     |
     = note: expected raw pointer `*const i64`
                found raw pointer `*const i32`
note: function defined here
    --> src/lib.rs:805:23
     |
805  |     pub extern "C" fn set_shared_memory_data_signed_32(
     |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
806  |         data: *const c_long,
     |         -------------------

error[E0308]: mismatched types
    --> src/lib.rs:1258:53
     |
1258 | ... => set_shared_memory_data_unsigned_32(numeric_array_data as *const u32, numeric_array_dimensions, numeric_array_rank),
     |        ---------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `*const u64`, found `*const u32`
     |        |
     |        arguments to this function are incorrect
     |
     = note: expected raw pointer `*const u64`
                found raw pointer `*const u32`
note: function defined here
    --> src/lib.rs:753:23
     |
753  |     pub extern "C" fn set_shared_memory_data_unsigned_32(
     |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
754  |         data: *const c_ulong,
     |         --------------------

For more information about this error, try `rustc --explain E0308`.
warning: `shared_memory` (lib) generated 1 warning
error: could not compile `shared_memory` (lib) due to 4 previous errors; 1 warning emitted

Any ideas how I can get it to compile?

Working in Windows, but errors in Ubuntu

I followed the instructions for non-windows platforms built the lib.rs in Ubuntu 16.04LTS and it produced a .d and .so files (along with lots of other files) in the target directory with one warning about an unused datatype. I copied the .d and .so files to the shared_memory folder. In matlab it's resulting in an error.

Error using loadlibrary>lFullPath (line 627)
Could not find file shared_memory.

See full session.

>> pwd

ans =
/home/raad/Documents/sharedmemproject/shared_memory

>> addpath(pwd)

>> pwd
ans =
/home/raad/Documents/sharedmemproject/shared_memory/matlab

>> addpath(pwd)
>> set_shared_memory_path('/home/raad/Documents/sharedmemproject/shared_memory/data');
Error using loadlibrary>lFullPath (line 627)
Could not find file shared_memory.

Error in loadlibrary (line 229)

Error in load_shared_memory_library (line 16)
        loadlibrary(library_path)

Error in set_shared_memory_path (line 8)
        load_shared_memory_library();

Can you please help understand and fix this. Is this a problem with old version of ubuntu or is it because of any issues with Rust compilation?

Thanks.

"Can't create shared memory error" for Python/Matlab on Windows

Hi, this looks like an interesting library and have tried to get it to run on Windows (10 Pro) for Python and Matlab but consistently get the same "Can't create shared memory error".

Python 3.9.5 (default, May 18 2021, 14:42:02) [MSC v.1916 64 bit (AMD64)]
---------------------------------------------------------------------------
SharedMemoryLibraryError                  Traceback (most recent call last)
File shared_memory\test.py:12, in <module>
      9 d = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
     11 # Share
---> 12 set_shared_memory_data(d)
     14 # Receive
     15 data = get_shared_memory_data()

File shared_memory\python\shared_memory.py:458, in set_shared_memory_data(data)
    456     _check_library_error(_c_library_set_shared_memory_data_signed_16(data, temp_dims, temp_rank))
    457 elif data_type == np.int32:
--> 458     _check_library_error(_c_library_set_shared_memory_data_signed_32(data, temp_dims, temp_rank))
    459 elif data_type == np.int64:
    460     _check_library_error(_c_library_set_shared_memory_data_signed_64(data, temp_dims, temp_rank))

File shared_memory\python\shared_memory.py:243, in _check_library_error(value)
    241     return value
    242 else:
--> 243     raise SharedMemoryLibraryError(value)

SharedMemoryLibraryError: Can't create shared memory

I have also successfully recompiled the library and the test suite seems to run fine. Is there a recommended way how to debug this issue?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.