From 81eb548ebb8230a8d03f439a82e44a8d08b97d74 Mon Sep 17 00:00:00 2001 From: Jonathan Doucette Date: Wed, 15 Nov 2023 12:10:06 -0800 Subject: [PATCH] v0.1.4 --- Project.toml | 2 +- README.md | 30 +++++++++++++++--------------- api/jlcall.jl | 2 +- api/jlcall.m | 4 ++-- docs/src/index.md | 2 +- src/MATDaemon.jl | 2 +- test/julia_tests.jl | 4 +++- 7 files changed, 24 insertions(+), 22 deletions(-) diff --git a/Project.toml b/Project.toml index 2514a2f..ca2a69f 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "MATDaemon" uuid = "88578114-2e0c-4679-8b18-24dc4fa60bec" authors = ["Jonathan Doucette and contributors"] -version = "0.1.3" +version = "0.1.4" [deps] DaemonMode = "d749ddd5-2b29-4920-8305-6ff5a704e36e" diff --git a/README.md b/README.md index 1d4201e..87129de 100644 --- a/README.md +++ b/README.md @@ -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))) @@ -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. @@ -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('', ... @@ -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 @@ -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 @@ -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') @@ -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 @@ -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 @@ -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 @@ -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. diff --git a/api/jlcall.jl b/api/jlcall.jl index 89dc163..26cefd2 100644 --- a/api/jlcall.jl +++ b/api/jlcall.jl @@ -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 diff --git a/api/jlcall.m b/api/jlcall.m index 7e14f62..626ed59 100644 --- a/api/jlcall.m +++ b/api/jlcall.m @@ -239,7 +239,7 @@ % % The workhorse behind MATDaemon.jl and JLCALL is DaemonMode.jl 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 @@ -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; diff --git a/docs/src/index.md b/docs/src/index.md index fb0ab71..47fd913 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -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) diff --git a/src/MATDaemon.jl b/src/MATDaemon.jl index 7b12ead..27e6d44 100644 --- a/src/MATDaemon.jl +++ b/src/MATDaemon.jl @@ -3,7 +3,7 @@ $(README) """ module MATDaemon -const VERSION = v"0.1.3" +const VERSION = v"0.1.4" import DaemonMode import MAT diff --git a/test/julia_tests.jl b/test/julia_tests.jl index cfea87a..24f3b73 100644 --- a/test/julia_tests.jl +++ b/test/julia_tests.jl @@ -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