有谁知道matlab mex库生命周期是什么?具体来说,我对以下内容感兴趣:
我在这里和网上进行了广泛的搜索,但我找不到这些问题的答案.我的问题在初始化时有一些性能成本,我想尽可能避免这种情况,而无需编写服务.
我有一个Mex函数,比如说myfunction.mexmaci64
(这是OS X上的正确结尾).
现在,myfunction与库相关联mylibrary.dylib
.mex文件和库都位于同一文件夹中.
现在,每当我改变某些内容时mylibrary
,MATLAB都不会重新加载新的库版本,而是使用旧版本,直到我重新启动MATLAB.在进行开发和调试工作时,这非常有用.有没有办法强制MATLAB重新加载库而无需重新启动应用程序?
注意:将库静态链接到mex函数很容易.但是,当我将相同的库链接到相当多的mex文件时,我宁愿保留我的单个共享库以减少编译时间和数据冗余.
关于讨论的clear mex
帮助:
[~, loaded_mexes] = inmem('-completenames'); % get canonica
Run Code Online (Sandbox Code Playgroud)
返回包含所有已加载的mex文件的列表.此列表不包含链接库,但仅包含mex文件本身.使用clear mex
成功清空此列表但不卸载mylibrary
- 再次运行mex函数仍然会产生与旧共享库相同的输出.
正如标题所说,如何在Matlab中向矩阵添加尾随单例维度?
A=ones(3,3,1);
给出3x3矩阵,同时A=ones(1,3,3);
给出1x3x3矩阵
添加到具体问题:
我有一个应用程序,我有N MxM矩阵,我需要堆叠它们,结果成为一个MxMxN矩阵.但是,N可以是1,如果是,我需要矩阵为MxMx1.
注意:我知道这对Matlab脚本没有多大意义,正如Loren所说,在Matlab中,在非单例之后存在无限的"单例"维度.但是,这是在mex环境中mxGetNumberOfDimensions
使用的地方.
我正在尝试编译一个大的C文件(专门用于MATLAB mexing).C文件大约20 MB(如果你想玩它,可以从GCC bug跟踪器获得).
这是我正在运行的命令和屏幕输出,如下所示.这已经运行了几个小时,如您所见,优化已被禁用(-O0).为什么这么慢?有没有办法让我更快?
(供参考:Ubuntu 12.04(精确穿山甲)64位和GCC 4.7.3)
/usr/bin/gcc -c -DMX_COMPAT_32 -D_GNU_SOURCE -DMATLAB_MEX_FILE -I"/usr/local/MATLAB/R2015a/extern/include" -I"/usr/local/MATLAB/R2015a/simulink/include" -ansi -fexceptions -fPIC -fno-omit-frame-pointer -pthread -O0 -DNDEBUG path/to/test4.c -o /tmp/mex_198714460457975_3922/test4.o -v
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.7.3-2ubuntu1~12.04' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --with-system-zlib --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04)
COLLECT_GCC_OPTIONS='-c' '-D' …
Run Code Online (Sandbox Code Playgroud) 在MATLAB中,clear mex
从内存中卸载所有MEX文件(除非它们已被锁定)。在macOS的早期版本中,仅通过发出clear mex
命令,我就可以重新编译MEX文件并运行修改后的版本,而无需重新启动MATLAB 。在莫哈韦沙漠下,这不再可能。
例如,使用以下简单的MEX文件(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]);
}
Run Code Online (Sandbox Code Playgroud)
我们可以创建MEX文件并将其加载到内存中
mex get_data_pointer.c
get_data_pointer(0)
Run Code Online (Sandbox Code Playgroud)
为了清除它,
clear mex
[~,mexfiles] = inmem
version -modules
Run Code Online (Sandbox Code Playgroud)
inmem
确实返回了一个空单元格数组,指示未在内存中加载MEX文件,但是version -modules
(未记录,根据此答案)仍显示/Users/cris/matlab/get_data_pointer.mexmaci64
在其输出中。更改MEX文件的源代码并重新编译表明,确实从未重新加载MEX文件,旧版本仍在运行,直到有人退出MATLAB。
我在macOS Mojave的MATLAB R2017a上看到了这一点。在High Sierra下使用相同的MATLAB版本从来没有问题。
如何强制MATLAB在不重新启动的情况下卸载MEX文件?
我正在写一个Matlab mex文件.但是,mex文件似乎有一个严重的限制:help mexfilename
不会导致出现帮助文本.
我可以通过编写一个最终调用mex文件的m文件来避免这种情况,但包括帮助,但必须有更好的方法.
另一方面,我可以在m文件中进行所有错误检查,这样做更方便...
在我的电脑上,我有Ubuntu 10.10和gcc 4.4.4.我尝试编译一些使用CUDA的mex文件,我收到以下错误消息:
>> cns_build('hmax')
compiling...
/home/leMe/hmax/cns/source/common_dec.h(54): warning: omission of exception specification is incompatible with previous function "operator new(size_t)"
/usr/include/c++/4.4/new(91): here
/home/leMe/hmax/cns/source/common_dec.h(55): warning: omission of exception specification is incompatible with previous function "operator new[](size_t)"
/usr/include/c++/4.4/new(92): here
/home/leMe/hmax/cns/source/common_dec.h(56): warning: omission of exception specification is incompatible with previous function "operator delete(void *)"
/usr/include/c++/4.4/new(93): here
/home/leMe/hmax/cns/source/common_dec.h(57): warning: omission of exception specification is incompatible with previous function "operator delete[](void *)"
/usr/include/c++/4.4/new(94): here
Segmentation fault
CUDA preprocessing [nvcc] failed
Warning: You are using gcc version …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用此处概述的方法将C++类包装在matlab mex包装器中.基本上,我有一个初始化mex文件,它返回一个C++对象句柄:
handle = myclass_init()
Run Code Online (Sandbox Code Playgroud)
然后我可以将它传递给另一个myclass_amethod
使用句柄调用类方法的mex文件(例如),然后最终myclass_delete
释放C++对象:
retval = myclass_amethod(handle, parameter)
myclass_delete(handle)
Run Code Online (Sandbox Code Playgroud)
为了便于使用,我把它包装在一个MATLAB类中:
classdef myclass < handle
properties(SetAccess=protected)
cpp_handle_
end
methods
% class constructor
function obj = myclass()
obj.cpp_handle_ = myclass_init();
end
% class destructor
function delete(obj)
myclass_delete(obj.cpp_handle_);
end
% class method
function amethod(parameter)
myclass_amethod(obj.cpp_handle_, parameter);
end
end
end
Run Code Online (Sandbox Code Playgroud)
这在非并行代码中工作正常.但是,只要我从一个内部调用它parfor
:
cls = myclass();
parfor i = 1:10
cls.amethod(i)
end
Run Code Online (Sandbox Code Playgroud)
我得到一个段错误,因为类的副本是在parfor
循环中(在每个worker中)制作的,但由于每个worker都是一个单独的进程,因此不会复制C++对象实例,从而导致指针无效.
我最初尝试检测每个类方法何时在parfor循环中运行,并且在这些情况下也重新分配C++对象.但是,由于无法检查是否已为当前工作程序分配了对象,因此会导致多次重新分配,然后只有一次删除(当工作人员退出时)导致内存泄漏(请参阅附录中的附录)问题详情).
matlab.mixin.Copyable
在C++中,处理它的方法是复制构造函数(这样只有在复制包装器MATLAB类时才重新分配C++对象).快速搜索会显示matlab.mixin.Copyable类类型,它似乎提供了所需的功能(即MATLAB句柄类的深层副本).因此,我尝试了以下方法:
classdef myclass …
Run Code Online (Sandbox Code Playgroud) 我编写了一些C代码,在使用MEX编译之后我将其称为MATLAB.在C代码中,我使用以下代码测量计算的一部分时间:
clock_t begin, end;
double time_elapsed;
begin = clock();
/* do stuff... */
end = clock();
time_elapsed = (double) ((double) (end - begin) / (double) CLOCKS_PER_SEC);
Run Code Online (Sandbox Code Playgroud)
经过的时间应该是以秒为单位的执行时间.
然后我将值输出time_elapsed
到MATLAB(它被正确导出;我检查过).然后MATLAB端我调用这个C函数(在我使用MEX编译它之后)并使用tic
和测量它的执行时间toc
.结果是完全荒谬的是我使用tic和toc计算的时间是0.0011s(500次运行时的平均值,st.dev.1.4e-4),而C代码返回的时间是0.037s(平均500次运行,st.dev.00,616).
人们可能会注意到两个非常奇怪的事实:
这些计时器发生了什么事?
我有一个C-code which works fine
使用makefile.现在,我正在尝试提交convert it to mex
文件,以便我可以从Matlab运行它.在这里,我也是using makefile approach
.但是,mex的makefile给了我错误.
这是我想要与我的mex文件一起编译的tsnnls lib.
C项目组织:
tsnnls_test_DKU.c
Include_4_TSNNLS.c
Include_4_TSNNLS.h
Run Code Online (Sandbox Code Playgroud)
" Include_4_TSNNLS.*
"文件具有TestingLibraries()
调用第三部分库的功能; 而我试图保持" tsnnls_test_DKU.c
"非常简单,因为:
原始代码:tsnnls_test_DKU.c
int TestingLibraries() ;
int main( int argc, char* argv[] )
{
int k = TestingLibraries() ;
return(1);
}
Run Code Online (Sandbox Code Playgroud)
现在,代码已更改:
更改的代码:tsnnls_test_DKU.c:
#include "mex.h"
#include <math.h>
int TestingLibraries() ;
void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
int k = TestingLibraries() ;
}
Run Code Online (Sandbox Code Playgroud)
原始make文件(有效
CXX = …
Run Code Online (Sandbox Code Playgroud)