Skip to content

Commit

Permalink
v0.1.4
Browse files Browse the repository at this point in the history
  • Loading branch information
jondeuce committed Nov 15, 2023
1 parent 63b6104 commit 81eb548
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "MATDaemon"
uuid = "88578114-2e0c-4679-8b18-24dc4fa60bec"
authors = ["Jonathan Doucette <jdoucette@physics.ubc.ca> and contributors"]
version = "0.1.3"
version = "0.1.4"

[deps]
DaemonMode = "d749ddd5-2b29-4920-8305-6ff5a704e36e"
Expand Down
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Call Julia from MATLAB using a Julia daemon launched by [`DaemonMode.jl`](https:

## Quickstart

Use the MATLAB function [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m) to call Julia from MATLAB:
Use the MATLAB function [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m) to call Julia from MATLAB:

```matlab
>> jlcall('sort', {rand(2,5)}, struct('dims', int64(2)))
Expand All @@ -21,13 +21,13 @@ ans =
0.0975 0.5469 0.9058 0.9134 0.9649
```

The positional arguments passed to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m) are:
The positional arguments passed to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m) are:
1. The Julia function to call, given as a MATLAB `char` array. This can be any Julia expression which evaluates to a function. For example, `'a=2; b=3; x -> a*x+b'`. For convenience, the empty string `''` is interpreted as `'(args...; kwargs...) -> nothing'`, returning `nothing` for any inputs. **Note:** expressions are wrapped in a `let` block and evaluated in the global scope
2. Positional arguments, given as a MATLAB `cell` array. For example, `args = {arg1, arg2, ...}`
3. Keyword arguments, given as a MATLAB `struct`. For example, `kwargs = struct('key1', value1, 'key2', value2, ...)`

The first time [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m) is invoked:
1. `MATDaemon.jl` will be installed into a local Julia project, if one does not already exist. By default, a folder `.jlcall` is created in the same folder as [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m)
The first time [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m) is invoked:
1. `MATDaemon.jl` will be installed into a local Julia project, if one does not already exist. By default, a folder `.jlcall` is created in the same folder as [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m)
2. A Julia server will be started in the background using [`DaemonMode.jl`](https://github.com/dmolina/DaemonMode.jl)

All subsequent calls to Julia are run on the Julia server.
Expand Down Expand Up @@ -55,7 +55,7 @@ run [setup scripts](https://github.com/jondeuce/MATDaemon.jl#loading-setup-code)
[import modules](https://github.com/jondeuce/MATDaemon.jl#loading-setup-code) for later use,
or set the [number of threads](https://github.com/jondeuce/MATDaemon.jl#julia-multithreading) for running multithreaded code.

This setup can be conveniently executed at the start of your MATLAB script with a single call to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m) as follows:
This setup can be conveniently executed at the start of your MATLAB script with a single call to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m) as follows:

```matlab
>> jlcall('', ...
Expand Down Expand Up @@ -104,7 +104,7 @@ ans =

### Persistent environments

By default, previously loaded Julia code is available on subsequent calls to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m).
By default, previously loaded Julia code is available on subsequent calls to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m).
For example, following the [above call](https://github.com/jondeuce/MATDaemon.jl#loading-modules) to `LinearAlgebra.norm`, the `LinearAlgebra.det` function can be called without loading `LinearAlgebra` again:

```matlab
Expand Down Expand Up @@ -136,9 +136,9 @@ Stacktrace:

### Unique Julia instances

Instead of running Julia code on a persistent Julia server, unique Julia instances can be launched for each call to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m) by passing the `'server'` flag with value `false`.
Instead of running Julia code on a persistent Julia server, unique Julia instances can be launched for each call to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m) by passing the `'server'` flag with value `false`.

**Note:** this may cause significant overhead when repeatedly calling [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m) due to Julia package precompilation and loading:
**Note:** this may cause significant overhead when repeatedly calling [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m) due to Julia package precompilation and loading:

```matlab
>> tic; jlcall('x -> sum(abs2, x)', {1:5}, 'server', false); toc
Expand Down Expand Up @@ -176,7 +176,7 @@ One possible remedy is to define a wrapper function in a Julia script:
julia_version() = string(Base.VERSION)
```

Then, use the `'setup'` flag to pass the above script to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m):
Then, use the `'setup'` flag to pass the above script to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m):

```matlab
>> jlcall('julia_version', 'setup', '/path/to/setup.jl')
Expand All @@ -189,7 +189,7 @@ ans =
In this case, `jlcall('() -> string(Base.VERSION)')` would work just as well.
In general, however, interfacing with complex Julia libraries using MATLAB types may be nontrivial, and the `'setup'` flag allows for the execution of arbitrary setup code.

**Note:** the setup script is loaded into the global scope using `include`; when using [persistent environments](https://github.com/jondeuce/MATDaemon.jl#persistent-environments), symbols defined in the setup script will be available on subsequent calls to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m).
**Note:** the setup script is loaded into the global scope using `include`; when using [persistent environments](https://github.com/jondeuce/MATDaemon.jl#persistent-environments), symbols defined in the setup script will be available on subsequent calls to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m).

### Handling Julia outputs

Expand Down Expand Up @@ -238,10 +238,10 @@ In case the Julia server gets into a bad state, the following troubleshooting ti
* Try restarting the server: `jlcall('', 'restart', true)`
* Enable debug mode for verbose logging: `jlcall('', 'debug', true)`
* Call Julia directly instead of calling the server: `jlcall('', 'server', false)`
* This will be slower, since each call to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m) will start a new Julia instance, but it may [fix server issues on Windows](https://github.com/jondeuce/MATDaemon.jl/issues/9#issuecomment-1761710048)
* This will be slower, since each call to [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m) will start a new Julia instance, but it may [fix server issues on Windows](https://github.com/jondeuce/MATDaemon.jl/issues/9#issuecomment-1761710048)
* Update the `MATDaemon.jl` Julia project environment (note: this will restart the server): `jlcall('', 'update', true)`
* Reinstall the `MATDaemon.jl` workspace folder (note: this will restart the server): `jlcall('', 'reinstall', true)`
* By default, the workspace folder is named `.jlcall` and is stored in the same directory as [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m)
* By default, the workspace folder is named `.jlcall` and is stored in the same directory as [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m)
* The `'reinstall'` flag deletes the workspace folder, forcing `MATDaemon.jl` to be reinstalled; you can also delete it manually

### Performance
Expand All @@ -252,13 +252,13 @@ Pointing these files to a ram-backed file system is recommended when possible (f
This is now the default; `'infile'` and `'outfile'` are created via the MATLAB `tempname` function (thanks to @mauro3 for this tip).

Nevertheless, this naturally leads to some overhead when calling Julia, particularly when the MATLAB inputs and/or Julia outputs have large memory footprints.
It is therefore not recommended to use [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m) in performance critical loops.
It is therefore not recommended to use [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m) in performance critical loops.

## MATLAB and Julia version compatibility

This package has been tested on a variety of MATLAB versions.
However, for some versions of Julia and MATLAB, supported versions of external libraries may clash.
For example, running [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m) using Julia v1.6.1 and MATLAB R2015b gives the following error:
For example, running [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m) using Julia v1.6.1 and MATLAB R2015b gives the following error:

```matlab
>> jlcall
Expand All @@ -276,4 +276,4 @@ If you encounter this issue, see the [`Julia`](https://github.com/JuliaLang/juli

This repository contains utilities for parsing and running Julia code, passing MATLAB arguments to Julia, and retrieving Julia outputs from MATLAB.

The workhorse behind `MATDaemon.jl` and [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m) is [`DaemonMode.jl`](https://github.com/dmolina/DaemonMode.jl) which is used to start a persistent Julia server in the background.
The workhorse behind `MATDaemon.jl` and [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m) is [`DaemonMode.jl`](https://github.com/dmolina/DaemonMode.jl) which is used to start a persistent Julia server in the background.
2 changes: 1 addition & 1 deletion api/jlcall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# User settings are loaded from the input file `MATDaemon.JL_OPTIONS` located in the jlcall.m workspace folder.
# The workspace folder is passed using the environment variable `MATDAEMON_WORKSPACE`.
#
# This version of jlcall.jl was written for MATDaemon v0.1.3.
# This version of jlcall.jl was written for MATDaemon v0.1.4.
# MATDaemon was written by Jonathan Doucette (jdoucette@physics.ubc.ca).

let
Expand Down
4 changes: 2 additions & 2 deletions api/jlcall.m
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@
%
% The workhorse behind MATDaemon.jl and JLCALL is <a href="matlab: web('https://github.com/dmolina/DaemonMode.jl')">DaemonMode.jl</a> which is used to start a persistent Julia server in the background.
%
% This version of jlcall.m was written for MATDaemon v0.1.3.
% This version of jlcall.m was written for MATDaemon v0.1.4.
% MATDaemon was written by Jonathan Doucette (jdoucette@physics.ubc.ca).

% Parse inputs
Expand Down Expand Up @@ -289,7 +289,7 @@
addParameter(p, 'quiet', false, @(x) validateattributes(x, {'logical'}, {'scalar'}));
addParameter(p, 'update', false, @(x) validateattributes(x, {'logical'}, {'scalar'}));
addParameter(p, 'reinstall', false, @(x) validateattributes(x, {'logical'}, {'scalar'}));
addParameter(p, 'VERSION', '0.1.3', @ischar); % NOTE: for internal use only
addParameter(p, 'VERSION', '0.1.4', @ischar); % NOTE: for internal use only

parse(p, varargin{:});
opts = p.Results;
Expand Down
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

!!! note
Manual installation of `MATDaemon.jl` is generally not necessary.
Simply download the [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.3/api/jlcall.m) MATLAB API function and `MATDaemon.jl` will be automatically installed into a local Julia project on first use.
Simply download the [`jlcall.m`](https://github.com/jondeuce/MATDaemon.jl/blob/v0.1.4/api/jlcall.m) MATLAB API function and `MATDaemon.jl` will be automatically installed into a local Julia project on first use.

## [Docstrings](@id docstrings)

Expand Down
2 changes: 1 addition & 1 deletion src/MATDaemon.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ $(README)
"""
module MATDaemon

const VERSION = v"0.1.3"
const VERSION = v"0.1.4"

import DaemonMode
import MAT
Expand Down
4 changes: 3 additions & 1 deletion test/julia_tests.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
@testset "code quality (Aqua.jl)" begin
Aqua.test_all(MATDaemon)
# TODO: Dependency compat bounds should be tested, but currently[1] there is an issue with how to specify bounds for standard libraries
# [1] https://discourse.julialang.org/t/psa-compat-requirements-in-the-general-registry-are-changing/104958#update-november-9th-2023-2
Aqua.test_all(MATDaemon; deps_compat = false)
end

@testset "version numbers" begin
Expand Down

2 comments on commit 81eb548

@jondeuce
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/95398

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.1.4 -m "<description of version>" 81eb548ebb8230a8d03f439a82e44a8d08b97d74
git push origin v0.1.4

Please sign in to comment.