In MATLAB, clear mex unloads all MEX-files from memory (unless they're locked). Under previous versions of macOS, I was able to re-compile a MEX-file and run the modified version without restarting MATLAB, simply by issuing a clear mex command. This is no longer possible under Mojave.
For example, take this trivial MEX-file (get_data_pointer.c):
#include "mex.h"
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
plhs[0] = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL);
*(uint64_t*)mxGetData(plhs[0]) = (uint64_t)mxGetData(prhs[0]);
}
We can create the MEX-file and load it in memory with
mex get_data_pointer.c
get_data_pointer(0)
To clear it,
clear mex
[~,mexfiles] = inmem
version -modules
inmem indeed returns an empty cell array indicating no MEX-files are loaded in memory, But version -modules (undocumented, from this answer) still shows /Users/cris/matlab/get_data_pointer.mexmaci64 in its output. And changing the MEX-file source code and re-compiling demonstrates that, indeed, the MEX-file is never reloaded, the old version is still being run until one exits MATLAB.
I am seeing this on MATLAB R2017a on macOS Mojave. This was never a problem with the same MATLAB version under High Sierra.
How can I force MATLAB to unload the MEX-file without restarting?
This doesn't technically solve the problem rather than work around it, but I have been using this compilation model because of the problem you mentioned I think. With this workflow I am able to compile Mex files as many times as needed and the version called is always the latest. It works as follows:
mex/ (not on the path). Say the file you want to compile is mex/mex_function.cpp.bin/ folder if it doesn't exist, and "reserve" a temporary filename bin/mex_function_<timestamp>.<mexext> to be used as the compilation output.mex_function.<mexext> to the temporary file reserved in bin/, and update that link every time a new compilation is run.mex() command yourself to actually create the temporary compiled file in bin/.Please don't take this script as-is; take it as guidance and adapt it for your needs. I personally have my own wrapper around mex() to create the compilation command and set all options / compiler flags as needed — you might have something similar on your side.
function outname = matlabBugWorkaround_compile( folder, name )
%
% The input folder is expected to have two subfolders:
% bin/ will contain temporary compiled Mex files
% mex/ contains the source Mex files
%
% The compilation model works as follows:
% 1. reserve filename in bin/ subfolder for temporary Mex file, using datestr suffix
% 2. create a symbolic link in input folder to reserved temporary Mex file
% 3. call mex() to compile the source file in mex/ and save the output in bin/
%
% This function takes care of steps 1 and 2, and returns the name of the temporary Mex
% file in bin/, which does not exist until the Mex file is actually compiled.
%
% .
% ├── bin/mex_function_240824-105633.mexmaci64
% ├── mex/mex_function.cpp
% └── mex_function.mexmaci64 -> bin/mex_function_240824-105633.mexmaci64
%
%
% Practically speaking:
% - put C++ Mex files in mex/ subfolder
% - call this function to create a symlink to a temporary compiled Mex file in bin/,
% which does not exist yet
% - run mex() taking the C++ file in mex/ as an input, using option "-output" with
% the filename returned by this function, and using option "-outdir" with the bin/
% subfolder
%
% binary folder is where the Mex output will be saved
bindir = fullfile(folder,'bin');
if ~isfolder(bindir)
assert( mkdir(bindir)==1, 'Could not create folder: %s', bindir );
end
% use timestamp to create unique name for temporary Mex file
ext = ['.' mexext];
stamp = datestr(now,'yymmdd-HHMMSS');
outname = [name '_' stamp ext];
% remove other binaries with the same prefix
torem = dir(fullfile( bindir, [name '_*'] ));
for i = 1:length(torem)
file = torem(i);
delete(fullfile(file.folder,file.name));
end
% create symlink
mexlink = fullfile( folder, [name ext] );
if isfile(mexlink)
delete(mexlink);
end
unix(['ln -s "' fullfile('bin',outname) '" "' mexlink '"']);
end
I hope this helps, happy to answer questions about it. Again sorry this doesn't actually solve the problem, it's just a workaround.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With