Coder Social home page Coder Social logo

mex.jl's Introduction

Mex.jl

Embedding Julia in the MATLAB process

Mex.jl embeds Julia into the MATLAB process using MATLAB's C++ Mex interface. This allows Julia functions to be called from MATLAB. This also allows (embedded) Julia to call MATLAB functions.

Prerequisites

❗ This package cannot be used with MATLAB 2022a/2022b because these versions are currently incompatible with MATLAB.jl.

Mex.jl requires MATLAB and Julia along with a C++ compiler configured to work with MATLAB's mex command, the last is required for building the mexjulia MEX function. You can check that a compiler is properly configured by executing:

>> mex -setup C++

from the MATLAB command prompt.

Installation

First ensure that the MATLAB.jl Julia package can be properly installed.

Then enter the package manager by typing ] and then run the following:

pkg> add Mex

The build process will:

  1. use julia to determine build options,
  2. build the mexjulia MEX function from source,
  3. add the mexjulia directory to your MATLAB path.

By default, Mex.jl uses the MATLAB installation with the greatest version number. To specify that a specific MATLAB installation should be used, set the environment variable MATLAB_ROOT.

Quick start

Use jl.eval to parse and evaluate MATLAB strings as Julia expressions:

>> jl.eval('2+2')

ans =

  int64

   4

You can evaluate multiple expressions in a single call:

>> [s, c] = jl.eval('sin(pi/3), cos(pi/3)')

s =

    0.8660


c =

    0.5000

Note that Julia's STDOUT and STDERR are not redirected to the MATLAB console. But if MATLAB is launched from the terminal they will appear there.

>> jl.eval('println("Hello, world!")');
>> jl.eval('@warn("Oh, no!")');

One can avoid the parentheses and string quotes using jleval (a simple wrapper around jl.eval) and MATLAB's command syntax:

>> jleval 1 + 1

ans =

  int64

   2

>> jleval println("Hello, world!")
Hello, world!

Use jl.call to call a Julia function specified by its name as a string:

>> jl.call('factorial', int64(10))

ans =

     3628800

Load new Julia code by calling jl.include:

>> jl.include('my_own_julia_code.jl')

Exercise more control over how data is marshaled between MATLAB and Julia by defining a Julia function with a "MEX-like" signature and invoking it with jl.mex:

>> jleval import MATLAB
>> jleval double_it(args::Vector{MATLAB.MxArray}) = [2*MATLAB.jvalue(arg) for arg in args]
>> a = rand(5,5)

a =

    0.6443    0.9390    0.2077    0.1948    0.3111
    0.3786    0.8759    0.3012    0.2259    0.9234
    0.8116    0.5502    0.4709    0.1707    0.4302
    0.5328    0.6225    0.2305    0.2277    0.1848
    0.3507    0.5870    0.8443    0.4357    0.9049

>> jl.mex('double_it', a)

ans =

    1.2886    1.8780    0.4155    0.3895    0.6222
    0.7572    1.7519    0.6025    0.4518    1.8468
    1.6232    1.1003    0.9418    0.3414    0.8604
    1.0657    1.2450    0.4610    0.4553    0.3696
    0.7015    1.1741    1.6886    0.8714    1.8098

The first argument to jl.mex is the name of the function to be invoked. All remaining arguments are treated as function arguments.

jl.mex expects the functions on which it is invoked to accept a single argument of type Vector{MATLAB.MxArray} and to return an iterable collection of values on which MATLAB.mxarray may be successfully invoked (e.g., a value of type Vector{MATLAB.MxArray}).

Additional Examples

Additional usage examples may be found in the examples folder.

Performance

To learn how to reduce the overhead associated with this package, see performance.m in the example folder.

Credits

The starting point for the development of this package was the mexjulia project, which was designed to embed early versions of Julia into the MATLAB process.

mex.jl's People

Contributors

bermanmaxim avatar nboulle avatar omus avatar samuelpowell avatar sg-s avatar standarddeviant avatar taylormcd avatar twadleigh 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  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

mex.jl's Issues

Crashes in tight loops

First thank you very much for this awesome package.

I'm trying to run the stuff in performance.m and unfortunately, the first test fails. Could have to do with the JIT compiler of Matlab:

>> k=1;while(true), [q,r] = jl.call('divrem',7,3); k=k+1; end
Array indices must be positive integers or logical values.

Error in jl.mex (line 23)
            [err, varargout{1:nout}] = mexjulia('jl_mex', fn, varargin{:});

Error in jl.callkw (line 52)
            [varargout{1:nargout}] = jl.mex('Mex.jl_call_kw', fn, int32(npos), varargin{:});

Error in jl.call (line 59)
            [varargout{1:nargout}] = jl.callkw(fn, -1, varargin{:});

Using dbstop if error reveals, that the value of k differs a lot, sometimes it's in the range of 40, sometimes 10000. But it crashes. Is some kind of locking neeeded?

Thanks!

edit 1:
try, k=1;while(true), [q,r] = jl.call('divrem',7,3); pause(0.1), k=k+1; end, catch E, E, k, end always returns k=50 on my machine, regardless of the value in pause().

edit 2:
tic; for i=1:2000; [q,r] = divrem(7,3); end; elpsd = toc; always works. Is there something wrong with jl.call?

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Matlab closes quickly after executing mexjulia

Hi! I just tried this out and encountered the following issues (on Ubuntu 20.04)
*) I had to add the package to the MATLAB path manually
*) jlexec statements execute and return, but a few seconds later matlab just closes without without warning

MEX.jl with Julia 1.10.1

Sadly, Mex.jl doesn't seem to work with Julia 1.10.1.

After some trial (by me) and error (by Matlab) yesterday I installed Julia's long term support version 1.6.7, installed MATLAB.jl and Mex.jl and it worked fine with my installation of Matlab R2021b. However, the actual Julia package I want to use installs an old version on Julia 1.6.7 which hasn't all the functionality that I will need, so it's not an option for me to use that old Julia version to get Mex.jl to work.

In theory I might be able to find some Julia version in between 1.6.7 and 1.10.1 where both packages work but that doesn't sound like a long term solution. Here's the output of a REPL session with a completely new Julia installation:

(@v1.10) pkg> add MATLAB
  Installing known registries into `C:\Users\Ronny\.julia`
    Updating registry at `C:\Users\Ronny\.julia\registries\General.toml`
   Resolving package versions...
   Installed MATLAB ─ v0.8.4
    Updating `C:\Users\Ronny\.julia\environments\v1.10\Project.toml`
  [10e44e05] + MATLAB v0.8.4
    Updating `C:\Users\Ronny\.julia\environments\v1.10\Manifest.toml`
  [10e44e05] + MATLAB v0.8.4
  [56f22d72] + Artifacts
  [8f399da3] + Libdl
  [37e2e46d] + LinearAlgebra
  [9a3f8284] + Random
  [ea8e919c] + SHA v0.7.0
  [9e88b42a] + Serialization
  [2f01184e] + SparseArrays v1.10.0
  [e66e0078] + CompilerSupportLibraries_jll v1.1.0+0
  [4536629a] + OpenBLAS_jll v0.3.23+4
  [bea87d4a] + SuiteSparse_jll v7.2.1+1
  [8e850b90] + libblastrampoline_jll v5.8.0+1
    Building MATLAB → `C:\Users\Ronny\.julia\scratchspaces\44cfe95a-1eb2-52ea-b672-e2afdf69b78f\f640678d27790992e2a697f60e6afb1be3ebb7fc\build.log`
Precompiling project...
  2 dependencies successfully precompiled in 3 seconds. 2 already precompiled.

(@v1.10) pkg> test MATLAB
     Testing MATLAB
      Status `C:\Users\Ronny\AppData\Local\Temp\jl_0zgNbg\Project.toml`
  [2f01184e] SparseArrays v1.10.0
  [8dfed614] Test
      Status `C:\Users\Ronny\AppData\Local\Temp\jl_0zgNbg\Manifest.toml`
  [10e44e05] MATLAB v0.8.4
  [56f22d72] Artifacts
  [b77e0a4c] InteractiveUtils
  [8f399da3] Libdl
  [37e2e46d] LinearAlgebra
  [56ddb016] Logging
  [d6f4376e] Markdown
  [9a3f8284] Random
  [ea8e919c] SHA v0.7.0
  [9e88b42a] Serialization
  [2f01184e] SparseArrays v1.10.0
  [8dfed614] Test
  [e66e0078] CompilerSupportLibraries_jll v1.1.0+0
  [4536629a] OpenBLAS_jll v0.3.23+4
  [bea87d4a] SuiteSparse_jll v7.2.1+1
  [8e850b90] libblastrampoline_jll v5.8.0+1
Precompiling project...
  2 dependencies successfully precompiled in 3 seconds. 3 already precompiled.
     Testing Running tests...
     Testing MATLAB tests passed

(@v1.10) pkg> add Mex
   Resolving package versions...
   Installed Reexport ─ v1.2.2
   Installed Mex ────── v0.1.1
    Updating `C:\Users\Ronny\.julia\environments\v1.10\Project.toml`
  [5e29dd5e] + Mex v0.1.1
    Updating `C:\Users\Ronny\.julia\environments\v1.10\Manifest.toml`
  [5e29dd5e] + Mex v0.1.1
  [189a3867] + Reexport v1.2.2
    Building Mex → `C:\Users\Ronny\.julia\scratchspaces\44cfe95a-1eb2-52ea-b672-e2afdf69b78f\2e99a552c9b0f56718ed54e9427c4789f122f4af\build.log`
Precompiling project...
  2 dependencies successfully precompiled in 2 seconds. 4 already precompiled.

(@v1.10) pkg> test Mex
     Testing Mex
      Status `C:\Users\Ronny\AppData\Local\Temp\jl_nvUX8O\Project.toml`
  [10e44e05] MATLAB v0.8.4
  [5e29dd5e] Mex v0.1.1
  [8dfed614] Test
      Status `C:\Users\Ronny\AppData\Local\Temp\jl_nvUX8O\Manifest.toml`
  [10e44e05] MATLAB v0.8.4
  [5e29dd5e] Mex v0.1.1
  [189a3867] Reexport v1.2.2
  [56f22d72] Artifacts
  [2a0f44e3] Base64
  [b77e0a4c] InteractiveUtils
  [8f399da3] Libdl
  [37e2e46d] LinearAlgebra
  [56ddb016] Logging
  [d6f4376e] Markdown
  [9a3f8284] Random
  [ea8e919c] SHA v0.7.0
  [9e88b42a] Serialization
  [2f01184e] SparseArrays v1.10.0
  [8dfed614] Test
  [e66e0078] CompilerSupportLibraries_jll v1.1.0+0
  [4536629a] OpenBLAS_jll v0.3.23+4
  [bea87d4a] SuiteSparse_jll v7.2.1+1
  [8e850b90] libblastrampoline_jll v5.8.0+1
Precompiling project...
  2 dependencies successfully precompiled in 3 seconds. 5 already precompiled.
     Testing Running tests...
jl.eval: Error During Test at C:\Users\Ronny\.julia\packages\Mex\qcSLo\test\runtests.jl:7
  Got exception outside of a @test
  MATLAB.MEngineError("invalid engine session (err = 1)")
  Stacktrace:
    [1] eval_string(session::MSession, stmt::String)
      @ MATLAB C:\Users\Ronny\.julia\packages\MATLAB\xBhSu\src\engine.jl:135
    [2] eval_string(stmt::String)
      @ MATLAB C:\Users\Ronny\.julia\packages\MATLAB\xBhSu\src\engine.jl:147
    [3] macro expansion
      @ C:\Users\Ronny\.julia\packages\MATLAB\xBhSu\src\matstr.jl:161 [inlined]
    [4] macro expansion
      @ C:\Users\Ronny\.julia\packages\Mex\qcSLo\test\runtests.jl:9 [inlined]
    [5] macro expansion
      @ C:\Users\Ronny\AppData\Local\Programs\Julia-1.10.1\share\julia\stdlib\v1.10\Test\src\Test.jl:1577 [inlined]
    [6] top-level scope
      @ C:\Users\Ronny\.julia\packages\Mex\qcSLo\test\runtests.jl:9
    [7] include(fname::String)
      @ Base.MainInclude .\client.jl:489
    [8] top-level scope
      @ none:6
    [9] eval
      @ .\boot.jl:385 [inlined]
   [10] exec_options(opts::Base.JLOptions)
      @ Base .\client.jl:291
   [11] _start()
      @ Base .\client.jl:552
Test Summary: | Error  Total   Time
jl.eval       |     1      1  16.7s
ERROR: LoadError: Some tests did not pass: 0 passed, 0 failed, 1 errored, 0 broken.
in expression starting at C:\Users\Ronny\.julia\packages\Mex\qcSLo\test\runtests.jl:5
ERROR: Package Mex errored during testing

If I hadn't done the test and instead tried to use Mex.jl from MATLAB, the result would be MATLAB crashing and closing without error whenever I use jl.eval().

I don't know what that "invalid engine session" error is trying to tell me, especially since it works with the same MATLAB installation and just an older Julia one. Did something vital change in MATLAB.jl or in Julia's C API? Maybe it's an easy fix for you?

Issues on Windows 10 [SOLVED]

Hello,

I had some problems with the installation and the working of this package, and since I've already solved them I tought to share my findings in case someone incurred in the same issues.

I'm currently using Windows 10, Matlab R2019a and Julia 1.2.0-2.
MEX on matlab is configured to use 'MinGW64 Compiler (C++)' for C++ language compilation.

Problem 1 (installation): using "]add https://github.com/byuflowlab/Mex.jl" in Julia used to work for everything except for the compilation of mexjulia. However, this doesn't throw an error. Looking in "...\.juliapro\JuliaPro_v1.2.0-2\packages\Mex\ZlRZN\deps" and reading the textfile "build" at the very end it says

"Error using mex
g++: error: ...\AppData\Local\JuliaPro-1.1.1.1\Julia-1.1.1\bin\libjulia.dll.a: No such file or directory"

... and indeed the file "libjulia.dll.a" does not exist, whereas "libjulia.dll" does. To fix it, I naively copied "libjulia.dll" in the same folder and renamed it as "libjulia.dll.a". To my surprise, it worked and the compilation was successful.

Problem 2 (find libraries): I then tried to run jl.eval('1+1') in MATLAB, but it returned an error saying that some libraries could not be found. Long story short, I think there was a problem with the paths, and my fix was to change the jl.m (class definition) at lines 136-146 switching the order of the two operations, that is:
ORIGINAL:

                % tweak path to find shared libs
                if ispc
                    % This is a hack for windows which lets the mex function
                    % find the julia dlls during initialization without requiring that
                    % julia be on the path.
                    old_dir = pwd;
                    cd(jl.julia_home);
                end

                % basic runtime initialization
                jldict = load('jldict', 'julia_home', 'sys_image', 'lib_path');

MODIFIED:

                % basic runtime initialization
                jldict = load('jldict', 'julia_home', 'sys_image', 'lib_path');
                
                % tweak path to find shared libs
                if ispc
                    % This is a hack for windows which lets the mex function
                    % find the julia dlls during initialization without requiring that
                    % julia be on the path.
                    old_dir = pwd;
                    cd(jldict.julia_home);
                end

Possibly I'm the only one experiencing these issues, but I wanted to share : )

Xcode build error when using mex

On macOS 10.15.4 with Julia 1.5:
Although mex -setup C++ goes through just fine, the mexjulia build process throws:

Error using mex
xcodebuild: error: SDK "macosx10.15.4" cannot be located.
xcrun: error: sh -c
'/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -sdk
macosx10.15.4 -find clang++ 2> /dev/null' failed with exit code 16384: (null)
(errno=No such file or directory)
xcrun: error: unable to find utility "clang++", not a developer tool or in PATH

This .m-snippet
This issue is more on the side of Matlabs Xcode integration, I however thought I post the solution here in case someone runs into the same issue as it did cost me half a day.

DLLs load improperly under 2021b in Windows 10/11

I believe the following DLL files in the <install directory>\bin\win64\ directory of MATLAB have issues in locked-down Windows (i.e. without administrator privileges):
libgit2.dll
libssh2.dll

This causes julia to fail with stacktraces similar to the following:

fatal: error thrown and no exception handler available.
InitError(mod=:LibCURL_jll, error=ErrorException("could not load library "libcurl-4.dll"
The specified procedure could not be found. "))
ijl_errorf at /home/user/julia/src\rtutils.c:77
ijl_load_dynamic_library at /home/user/julia/src\dlload.c:388
#dlopen#3 at .\libdl.jl:117
dlopen at .\libdl.jl:116 [inlined]
dlopen at .\libdl.jl:116 [inlined]
__init__ at C:\cygwin64\home\user\julia\usr\share\julia\stdlib\v1.10\LibCURL_jll\src\LibCURL_jll.jl:30
jfptr___init___96794 at C:\Users\User\AppData\Local\Programs\Julia-1.10.4\lib\julia\sys.dll (unknown line)
_jl_invoke at /home/user/julia/src\gf.c:2876 [inlined]
ijl_apply_generic at /home/user/julia/src\gf.c:3077
jl_apply at /home/user/julia/src\julia.h:1982 [inlined]
jl_module_run_initializer at /home/user/julia/src\toplevel.c:76
_finish_julia_init at /home/user/julia/src\init.c:901
ijl_init_with_image at /home/user/julia/src\jlapi.c:70 [inlined]
ijl_init_with_image at /home/user/julia/src\jlapi.c:59
mexFunction at C:\Users\User\.julia\dev\Mex.jl\mexjulia\mexjulia.mexw64 (unknown line)
### Stacktrace truncated

By renaming these files and re-running the build step, Julia is able to use Mex.jl as expected.

Renaming these DLL files requires administrator privileges, so this is not a viable solution for locked-down Windows users (i.e. without administrator privileges).

I believe Julia would need a patch to fix this issue.

Pkg.test() fails

Hello,

I cannot get Mex to run.
In the beginning I had a problem that Mex could not build, but after adding the Mex path to

ENV["MATLABPATH"]="/home/user/.julia/packages/Mex/5WarT/mexjulia"

manually the Pkg.build() ran through.
Unfortunately, Pkg.test() throws the following error

pkg> test Mex
     Testing Mex
      Status `/tmp/jl_zvEiaW/Project.toml`
  [10e44e05] MATLAB v0.8.3
  [5e29dd5e] Mex v0.1.0
  [8dfed614] Test `@stdlib/Test`
      Status `/tmp/jl_zvEiaW/Manifest.toml`
  [10e44e05] MATLAB v0.8.3
  [5e29dd5e] Mex v0.1.0
  [189a3867] Reexport v1.2.2
  [56f22d72] Artifacts `@stdlib/Artifacts`
  [2a0f44e3] Base64 `@stdlib/Base64`
  [b77e0a4c] InteractiveUtils `@stdlib/InteractiveUtils`
  [8f399da3] Libdl `@stdlib/Libdl`
  [37e2e46d] LinearAlgebra `@stdlib/LinearAlgebra`
  [56ddb016] Logging `@stdlib/Logging`
  [d6f4376e] Markdown `@stdlib/Markdown`
  [9a3f8284] Random `@stdlib/Random`
  [ea8e919c] SHA v0.7.0 `@stdlib/SHA`
  [9e88b42a] Serialization `@stdlib/Serialization`
  [2f01184e] SparseArrays `@stdlib/SparseArrays`
  [8dfed614] Test `@stdlib/Test`
  [e66e0078] CompilerSupportLibraries_jll v0.5.2+0 `@stdlib/CompilerSupportLibraries_jll`
  [4536629a] OpenBLAS_jll v0.3.20+0 `@stdlib/OpenBLAS_jll`
  [8e850b90] libblastrampoline_jll v5.1.1+0 `@stdlib/libblastrampoline_jll`
Precompiling project...
  2 dependencies successfully precompiled in 2 seconds. 4 already precompiled.
  2 dependencies precompiled but different versions are currently loaded. Restart julia to access the new versions
     Testing Running tests...
Error using mexjulia
Unhandled Julia exception: ErrorException

Error in jl.init (line 145)
            mexjulia(true, 'using Mex')

Error in jl.check_init (line 112)
                jl.init()

Error in jl.mex (line 21)
            jl.check_init();

Error in jl.eval (line 30)
            [varargout{1:nargout}] = jl.mex('Mex.jl_eval', expr);
 
Error using save
Variable 'matlab_jl_2' not found.
 
jl.eval: Error During Test at /home/htc/bzfhelfm/.julia/packages/Mex/5WarT/test/runtests.jl:7
  Got exception outside of a @test
  MATLAB.MEngineError("failed to get variable matlab_jl_2 from MATLAB session")
  Stacktrace:
    [1] get_mvariable(session::MSession, name::Symbol)
      @ MATLAB ~/.julia/packages/MATLAB/SVjnA/src/engine.jl:164
    [2] get_mvariable
      @ ~/.julia/packages/MATLAB/SVjnA/src/engine.jl:168 [inlined]
    [3] get_variable(name::Symbol)
      @ MATLAB ~/.julia/packages/MATLAB/SVjnA/src/engine.jl:170
    [4] macro expansion
      @ ~/.julia/packages/MATLAB/SVjnA/src/matstr.jl:162 [inlined]
    [5] macro expansion
      @ ~/.julia/packages/Mex/5WarT/test/runtests.jl:9 [inlined]
    [6] macro expansion
      @ /data/numerik/people/bzfsikor/julia/julia-1.8.3/share/julia/stdlib/v1.8/Test/src/Test.jl:1360 [inlined]
    [7] top-level scope
      @ ~/.julia/packages/Mex/5WarT/test/runtests.jl:9
    [8] include(fname::String)
      @ Base.MainInclude ./client.jl:476
    [9] top-level scope
      @ none:6
   [10] eval
      @ ./boot.jl:368 [inlined]
   [11] exec_options(opts::Base.JLOptions)
      @ Base ./client.jl:276
   [12] _start()
      @ Base ./client.jl:522
Test Summary: | Error  Total  Time
jl.eval       |     1      1  7.4s
ERROR: LoadError: Some tests did not pass: 0 passed, 0 failed, 1 errored, 0 broken.
in expression starting at /home/htc/bzfhelfm/.julia/packages/Mex/5WarT/test/runtests.jl:5
ERROR: Package Mex errored during testing

Do you have any ideas on how to proceed?

Thanks,
Luzie

CI with Julia 1.8 fails

This package doesn't seem to load correctly in Julia 1.8. I think I might be able to access a useful stack trace if I were to try loading this package from the Julia REPL, but I don't currently have MATLAB on my system so I can't diagnose it.

unexpected crashes

great that this project is still being updated! I just tried out with the newest release candidate for julia which again exports options, so the build script works.

I tried to use this package in the past to write bindings for matlab against a julia optimization library (I have attached a toy version
testmex.zip
). I want to call a julia function from matlab, and supply it with function handles. Then in turn, the julia function will call those matlab function handles with data.

This works, as you can see. However, if you run it often enough (matlab 2018a, ubuntu linux), I get an unexpected crash. The fact that this is sporadic makes me suspect the julia garbage collector, is there something to be mindful about when using mex?

I've tried debugging this but I'm hopelessly out of my depth, I never succesfully attached gdb to the matlab process.

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.