当MATLAB桌面打开时,MathWorks当前不允许您使用mex文件中的cout,因为它们已重定向stdout.他们目前的解决方法是提供一个函数mexPrintf,它们要求您使用它.在谷歌搜索了一下之后,我认为可以扩展std :: stringbuf类来完成我需要的工作.这是我到目前为止所拥有的.这是否足够强大,还是有其他方法需要重载或更好的方法来做到这一点?(寻找一般UNIX环境中的可移植性以及如果此代码未与mex可执行文件链接,则能够正常使用std :: cout)
class mstream : public stringbuf {
public:
virtual streamsize xsputn(const char *s, std::streamsize n)
{
mexPrintf("*s",s,n);
return basic_streambuf<char, std::char_traits<char>>::xsputn(s,n);
}
};
mstream mout;
outbuf = cout.rdbuf(mout.rdbuf());
Run Code Online (Sandbox Code Playgroud) 我是OpenMP的新手.我有以下代码,使用配置了MSVS2010的Matlab mex进行编译.计算机有8个处理器可用(我也使用matlabpool检查过).
#include "mex.h"
#include <omp.h>
typedef unsigned char uchar;
typedef unsigned int uint;
//Takes a uint8 input array and uint32 index array and preallocated uint8 array the same
//size as the first one and copies the data over using the indexed mapping
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
{
uint N = mxGetN(prhs[0]);
mexPrintf("n=%i\n", N); mexEvalString("drawnow");
uchar *input = (uchar*)mxGetData(prhs[0]);
uint *index = (uint*)mxGetData(prhs[1]);
uchar *output = (uchar*)mxGetData(prhs[2]);
uint nThreads, tid;
#pragma omp parallel …
Run Code Online (Sandbox Code Playgroud) 我有一些需要加速的Matlab代码.通过分析,我已经确定了一个特定的函数作为减慢执行速度的罪魁祸首.这个函数在循环中被调用了数十万次.
我的第一个想法是将函数转换为mex(使用Matlab Coder)来加速它.然而,常见的编程意义告诉我Matlab和mex代码之间的接口会导致一些开销,这意味着调用这个mex函数数千次可能不是一个好主意.它是否正确?或者Matlab在重复调用相同的mex以消除开销时会做些什么?
如果是显著的开销,我想重新编写代码,以增加循环函数本身和再创造的一个MEX.在此之前,我想验证我的假设,以证明花在此上的时间.
更新:
我尝试了@ angainor的建议,并使用以下代码创建了donothing.m:
function nothing = donothing(dummy) %#codegen
nothing = dummy;
end
Run Code Online (Sandbox Code Playgroud)
然后,我创建了一个mex函数作为donothing_mex,并尝试了以下代码:
tic;
for i=1:1000000
donothing_mex(5);
end
toc;
Run Code Online (Sandbox Code Playgroud)
结果是,对该功能的一百万次调用大约需要9秒.这对我们来说并不是一个重要的开销,所以现在我想我会将被调用的函数单独转换为mex.但是,从一个执行大约一百万次的循环调用一个函数回想起来似乎是一个非常愚蠢的想法,考虑到这是性能关键代码,所以将循环移动到mex函数仍然在书中,但优先级要低得多.
我使用专有的Matlab MEX文件在Matlab中导入一些模拟结果(当然没有可用的源代码!).与Matlab的接口实际上非常简单,因为只有一个函数,返回一个Matlab结构.我想知道是否有任何方法直接从Python调用MEX文件中的这个函数,而不必使用Matlab?
我想到的是例如使用类似SWIG的东西通过在它周围提供一个自定义的Matlab包装器将C函数导入Python ...顺便说一下,我知道用scipy.io.loadmat它已经可以读取了Matlab二进制*.mat数据文件,但我不知道mat文件中的数据表示是否与Matlab中的内部表示相同(在这种情况下,它可能对MEX包装器有用).
这个想法当然是能够使用MEX中提供的功能而系统上没有Matlab安装.
谢谢.
我正在编写一个mex文件(使用C++),它接受一个内存地址作为输入,并对该内存地址的数据进行操作.因为我被迫使用MATLAB作为我的环境,我的程序只能接受MATLAB数据类型作为输入(char,bool,float,double和int).如何将输入值分配给指针?
伪代码:
// Outside of program
// double input_arg = hex2dec('00C2E4E8')
double *pointer;
pointer = (double *)input_arg;
// pointer == hex2dec('00C2E4E8')
Run Code Online (Sandbox Code Playgroud)
基本上,这可以看作是我硬编码指针的值类似于:
double *pointer = (double *)hex2dec('00C2E4E8');
Run Code Online (Sandbox Code Playgroud)
我收到错误:
错误C2440:'=':无法从'double'转换为'double*'
我也尝试过使用static/const/reinterpret/dynamic_cast,但我真的不明白它们是如何工作的(我无法让它们工作).是否可以手动为指针分配内存地址值?
我有一个简单的mex函数,它从库中调用另一个C++函数.我用它编译源代码
mex -cxx mymexfunction.cpp -I/some/include -L/some/lib -lmylib
Run Code Online (Sandbox Code Playgroud)
mylib库是动态的(.so),并且与其他一些库(boost,OpenCV等等)相关联.
我遇到的问题是,一旦我调用函数mymexfunction一次,当我重新编译源代码时它将不会更新.我试过了
clear
clear all
clear mex
clear functions
clear fun('mymexfunction')
munlock('mymexfunction')
unloadlibrary('mymexfunction')
Run Code Online (Sandbox Code Playgroud)
......但没有任何帮助!我必须重新启动Matlab才能看到更新的mexfunction.即使我删除已编译的mex文件并重新编译,我仍然得到旧版本的mex函数(不在磁盘上,但在内存中).
如果我没有链接到mylib,一切都很好,但我不知道阻止更新的罪魁祸首是什么.遗憾的是,图书馆太大而且太交织,无法逐个删除单个模块.
是否存在一些可能导致此类问题的已知条件?
澄清:
我只更新mex函数的内容,而不是库.
更新:
它在Ubuntu 11.04下使用Matlab R2011a工作!我试图在我的OpenSUSE机器上重现相同的环境(R2011a,Boost 1.42,动态链接的OpenCV 2.2 ......)但仍然没有运气.所以我得出结论,我的库没有任何问题(否则它在Ubuntu下不起作用),但它必须是依赖项和Matlab内部库的一些冲突.我正式放弃了.Praetorian和Amro,谢谢你的帮助!
我开始用C++实现一些m文件,以减少运行时间.m文件产生n维点并在这些点评估函数值.这些函数是用户定义的,它们作为函数句柄传递给m文件和mex文件.mex文件使用mexCallMATLAB和feval来查找函数值.
我构造了下面的例子,其中在Matlab命令行中构造的函数句柄fn被传递给matlabcallingmatlab.m和mexcallingmatlab.cpp例程.使用新开放的Matlab,mexcallingmatlab在241.5秒内评估此功能200000,而matlabcallingmatlab在0.81522秒内评估它,因此使用mex实现减慢296倍.这些时间是第二次运行的结果,因为第一次运行似乎更大可能是由于第一次加载程序等相关的一些开销.
我花了很多天在网上搜索这个问题并尝试了一些建议.我尝试了不同的mex编译标志来优化mex,但性能几乎没有差异.Stackoverflow上的一篇文章指出,升级Matlab是解决方案,但我在Mac OS X版本:10.8.4上使用的最新版本MATLAB版本:8.1.0.604(R2013a).我使用和不使用-largeArrayDims标志编译了mex文件,但这也没有任何区别.有人建议函数句柄的内容可以直接在cpp文件中编码,但这是不可能的,因为我想将此代码提供给具有矢量输入和实数输出的任何类型函数的任何用户.
据我所知,mex文件需要通过feval函数来使用函数句柄,而m文件可以直接调用函数句柄,前提是Matlab版本比某些版本更新.
任何帮助将不胜感激.
在Matlab命令行中创建的简单函数句柄:
fn = @(x) x'*x
Run Code Online (Sandbox Code Playgroud)
matlabcallingmatlab.m:
function matlabcallingmatlab( fn )
x = zeros(2,1);
for i = 0 : 199999
x(2) = i;
f = fn( x );
end
Run Code Online (Sandbox Code Playgroud)
mexcallingmatlab.cpp:
#include "mex.h"
#include <cstring>
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
mxArray *lhs[1], *rhs[2]; //parameters to be passed to feval
double f, *xptr, x[] = {0.0, 0.0}; // x: input to f and f=f(x)
int …
Run Code Online (Sandbox Code Playgroud) 我试图通过MATLAB编译C++ Ubuntu项目在这里.当我尝试使用make命令编译后使用它时,我收到以下错误:
Invalid MEX-file
'////fashionista_v0.2/lib/+bsr/buildW.mexglx':
//local/MATLAB/R2011a/bin/glnx86/../../sys/os/glnx86/libstdc++.so.6: version
`GLIBCXX_3.4.11' not found (required by
////fashionista_v0.2/lib/+bsr/buildW.mexglx)
Run Code Online (Sandbox Code Playgroud)
我不熟悉的过程,所以我不能明白像一些提出的解决方案是.什么是libstdc ++和GLIBCXX,我该如何解决这个问题?
我试图使用nkjt 建议的链接解决问题:
export LD_LIBRARY_PATH=${prefix}/lib:$LD_LIBRARY_PATH
Run Code Online (Sandbox Code Playgroud)
但是,由于缺乏unix shell知识,我不明白在命令中放什么.我找到了libstdc ++ .a和.so文件,它位于gcc文件夹中/usr/lib/gcc/i686-linux-gnu/4.6
,我正在尝试以下方法:
export LD_LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/4.6:$LD_LIBRARY_PATH
Run Code Online (Sandbox Code Playgroud)
但是,我的matlab错误仍然存在.我正在使用Ubuntu 12.04版本与gcc 4.6和matlab r2011a.
编辑:我已经更新了matlab版本到r2012a问题仍然相同.我也尝试过以下方法:
sudo ln -s /usr/lib/cc/i686-linux-gnu/4.6/libstdc++.so libstdc++.so.6
Run Code Online (Sandbox Code Playgroud)
我无法创建文件已存在的文件.
usr/lib/libstdc ++.so.6 |的输出 grep GLIBC:
GLIBCXX_3.4
GLIBCXX_3.4.1
...
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBC_2.0
GLIBC_2.3
GLIBC_2.4
GLIBC_2.3.4
GLIBC_2.1
GLIBC_2.1.3
GLIBC_2.3.2
GLIBC_2.2
GLIBCXX_DEBUG_MESSAGE_LENGTH
Run Code Online (Sandbox Code Playgroud)
我怎样才能确保定义了正确版本的libstdc ++?
我std::nth_element
用来得到一个(大致正确的)值的向量百分位数,如下所示:
double percentile(std::vector<double> &vectorIn, double percent)
{
std::nth_element(vectorIn.begin(), vectorIn.begin() + (percent*vectorIn.size())/100, vectorIn.end());
return vectorIn[(percent*vectorIn.size())/100];
}
Run Code Online (Sandbox Code Playgroud)
我注意到,对于vectorIn长度最多为32个元素,向量将完全排序.从33个元素开始,它永远不会被排序(如预期的那样).
不确定这是否重要,但功能是在"(Matlab-)mex c ++代码"中,通过Matlab使用"Microsoft Windows SDK 7.1(C++)"编译.
编辑:
还参见传递给函数的1e5向量中最长排序块的长度的以下直方图(包含1e4个随机元素和随机百分位数的向量).注意非常小的峰值.
当通过 MEX 将一段 Fortran 2003(或更高版本)代码与 MATLAB 连接时,我惊讶地发现MEX 更改了默认逻辑. 这是致命的,因为一段完美编译的 Fortran 代码可能会因为类型不匹配而无法被 mexified,这种情况在我的项目中确实发生过。
\n这是一个最小的工作示例。
\n将以下代码命名为“test_kind.F”,在MATLAB中编译mex test_kind.F
,然后test_kind
在MATLAB中运行。这将生成一个名为 fort.99 的纯文本文件,其中包含两个数字“4”和“8”作为 WRITE 指令的结果。
! test_kind.F\n! Tested by MATLAB 9.8.0.1323502 (R2020a) with GNU Fortran (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0\n\n#include "fintrf.h"\n\n subroutine mexFunction(nlhs, plhs, nrhs, prhs)\n\n use ieee_arithmetic, only : ieee_is_nan\n implicit none\n mwPointer plhs(*), prhs(*)\n integer nlhs, nrhs\n\n write(99, *) kind(ieee_is_nan(1.0)) ! This prints a number in fort.99\n write(99, *) kind(.false.) ! A benchmark, …
Run Code Online (Sandbox Code Playgroud)