如何更新MEX文件以使用大型数组处理API(-LargearyDims)?

93次浏览(过去30天)
MEX API已更改为支持包含2^32-1个以上元素的金宝appMATLAB变量。此功能是在MATLAB 7.3版(R2006b)中添加的。您必须使用-largearydims标志编译MEX文件才能选择加入此API。
您可能需要更新MEX源代码以使用新的API。在不久的将来,MEX构建脚本将默认使用大数组处理API。

公认的答案

MathWorks支金宝app持团队
编辑:MathWorks支金宝app持团队 2020年2月27日
添加大数组处理API可能需要您更新mex文件。需要更改代码的原因是,为了启用大型数据,必须更改MATLAB API的输入和输出类型。我们以减少对现有用户影响的方式实现了对API的更改。我们采用了“选择加入”策略,如果你想利用新的大型数组处理特性,你可以使用MEX标志“- largearraydimms”来选择加入。如果您选择选择加入,则需要进行本解决方案中描述的更新。如果你选择不“opt-in”,你现在不需要做任何事情。但是要注意,在未来,新的大型数组处理API将成为默认值,然后您将需要更新代码或采取其他操作。
此解决方案将引导您逐步确定需要进行的更改。该过程建议您在修改代码之前,首先确定并列出要更改的候选变量。我们建议您在完成识别步骤之前不要编辑代码。
首先,考虑需要进行的更改的高级技术说明。随着MEX API使用的类型的改变,您现有的代码有可能通过错误类型输入和输出到MATLAB。具体地,改变的参数的类型是索引和大小。两者都从32位类型变为64-B。它支持兼容的类型。
以下过程将帮助您识别需要纠正的类型不匹配。它遵循一个系统的过程,包括首先测试原始代码,然后识别更改,然后更新代码的副本,构建新代码,最后重新测试。关于如何处理公共代码模式、构建失败和警告以及运行时问题,一路上都有一些建议。
注意:本文档主要使用C/C++术语和示例代码。Fortran MEX文件共享相同的问题;您可以在第8.8节中找到更多Fortran细节。
更详细地说:
1.测试现有的代码
在调整代码以处理大型数组之前,您应该首先验证它是否可以处理传统的32位数组维。您可能想要构建一个预期输入和输出的列表,甚至是一个完整的测试套件。为了安全起见,备份源代码和二进制文件,以便您可以将结果与更新后的源代码进行比较。
2.标识包含64位索引或大小值的变量
为了处理非常大的数组,您需要将包含数组索引或大小的所有变量转换为使用mwSize/mwIndex数据类型,而不是32位的“int”。在64位体系结构上使用大数组维度时,这些数据类型是64位整数,并作为预处理器宏实现。使用-largearydims时,这两种类型与C/C++中的size\t类型相同。
我们建议查看三类变量:API函数直接使用的变量、中间变量以及用作大小/索引和32位整数的变量。
2.1.搜索64位API函数直接使用的变量
要识别这些变量,请查找将mwSize/mwIndex值作为输入或输出值的mx*和mex*函数。
有关准确列表,请查看MATLAB版本中的文档。您可以在此处找到此列表:
您可以使用编辑器的find函数或GREP之类的实用程序来找到这些函数。
例如,在较早版本的MATLAB (R2006a及更早版本)中,该签名为:
mxArray*mxCreateDoubleMatrix(int m、int n、mxComplexity ComplexFlag);
大数组维度API中mxCreateDoubleMatrix的签名为:
mxArray*mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity ComplexFlag);
请注意,前两个输入参数已从“int”更改为“mwSize”。作为第一个或第二个输入传递的变量必须声明为mwSize。
您可以在每个函数的参考页上找到新签名,可通过帮助浏览器或DOC命令访问:
医生双重矩阵
因为在使用32位数组维度时,mwSize与“int”相同,所以您的代码可能仍然会写入此旧签名。为了利用大数组处理,您必须更新代码以使用mwSize/mwIndex,以允许使用64位大小和索引值。
搜索代码,注意定义为“int”或类似类型的任何变量。此时不要进行任何编辑,只需注意哪些变量需要更新。
如果您的代码是:
intMN
...
YP_OUT=mxCreateDoubleMatrix(m,n,mxREAL);
m和n均应声明为mwSize:
mwSizeMN
...
YP_OUT=mxCreateDoubleMatrix(m,n,mxREAL);
2.2.寻找中间变量
代码可能使用中间变量来计算大小和索引。如果是这种情况,您将需要确保这些变量也被声明为适当的类型。考虑这个例子:
mwSizeMN
intnumDataPoints;
m=3;
numDataPoints=m*2;
n=numDataPoints+1;
...
YP_OUT=mxCreateDoubleMatrix(m,n,mxREAL);
第2.1节中的第一次搜索将丢失mx*函数调用中未直接使用的中间变量,如本例中的numDataPoints。这些变量的大小将不足以处理来自mwSize变量的64位索引。在这些32位中间变量中存储64位索引将截断索引,从而导致不正确的结果或崩溃。在此示例中,numDataPoints应更改为mwSize,因为“m”是mwSize:
mwSizeMN
mwSizenumDataPoints;
检查您的代码,并将所有这些中间变量添加到要转换的变量列表中。
同样,在这一点上不要做任何编辑。
2.3.替换具有多种用途的变量
您的代码可能对索引(我们正在将其转换为64位)和结构字段号或状态代码(两者都保持为32位)使用相同的变量。
用于多种用途的变量需要标识,并替换为两个变量——一个mwSize/MWDINDEX和一个32位整数。当对数组大小和结构字段数使用一个变量时,这种情况尤其常见。另一种情况是状态代码/成功标志也用作索引。
例如,mxCreateDoubleMatrix需要mwSize输入,但mxCreateStructMatrix需要int:
mxArray*mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity ComplexFlag);
mxArray*mxCreateStructMatrix(mwSize m、mwSize n、整数域、常量字符**字段名);
现在考虑NothDaPoInts变量:
mxArray*我的数字,*myStruct;
int数字传感器;
mwSizeMN
烧焦**字段名;
intnumFields;
...
myNumeric=mxCreateDoubleMatrix(numSensors,n,mxREAL);
myStruct=mxCreateStructMatrix(m,n,numSensors,fieldnames);
在本例中,您需要两个新变量来替换NumSensor以正确处理这两个函数:
mxArray*我的数字,*myStruct;
mwSizenumSensorSize;
intnumSensorFields;
mwSizeMN
烧焦**字段名;
...
myNumeric=mxCreateDoubleMatrix(numSensorSize,n,mxREAL);
myStruct=mxCreateStructMatrix(m,n,numSensorFields,FieldName);
注意哪些变量需要以这种方式替换。同样,此时不要进行任何编辑。
3.第三方图书馆
您的MEX文件可能涉及您未编写的部分代码,并且您无权访问这些代码。这些可能是整个MEX文件、数字例程或设备驱动程序。有几种方法可以解决这个问题:
3.1.如果您不能访问源代码,请与供应商联系。请参阅本文档,并讨论使用它们处理大型数组维的选项。
3.2.如果您与他人共享代码,例如公开可用的源代码,请与相关作者或用户组联系,查看是否有人将代码转换为使用大数组维数。如果没有,您可能希望自己转换代码。同样,应用本文中的建议。
4.使用32位尺寸创建工作副本、进行编辑和测试。
此时,您知道需要编辑哪些类型声明。复制源代码并更改相关声明。像往常一样编译代码:
墨西哥人myMexFile.c
这使用传统的32位维度。这与使用-compatibleArrayDims标志相同:
墨西哥人-compatibleArrayDims myMexFile.c
与原始二进制文件进行比较;两者都应该返回相同的结果。
如果没有,调试并解决任何差异。现在(使用相同的32位大小和索引)比下一步更容易解决这些问题。
5.使用-largearydims生成并解决生成故障和警告。
现在可以使用大型数组处理API编译MEX文件了
墨西哥人myMexFile.c
使用
墨西哥人-LargearyDims myMexFile.c
使用-largearydims时,编译器可能会将mwSize/mwsindex称为“size\u t”、“unsigned” _ _int64”或其他类似名称。
此时的大多数生成问题都与32位和64位类型之间的类型不匹配有关。您可能会遇到一些常见问题:
5.1.分配中的类型不匹配
在某些情况下——特别是简单的赋值——C/C++编译器可以警告类型不匹配。例如:
mwSizeMN
intnumDataPoints;
...
numDataPoints=m*2;
使用“mex-largearydims buggyMexFile.c”编译此文件时,可能会收到类型不匹配警告。
来自64位Windows上的Microsoft Visual Studio:错误:C:\Work\buggyMexFile.C(31):警告C4267:“=”:从“大小”转换为“整数”,可能会丢失数据
可以使用2.2节将中间变量numdatapots转换为mwSize来修复这个示例。
5.2.指针类型中的类型不匹配
使用接受维度数组的mxCreate*数组函数时,需要将指针从int*转换为mwSize*:
mwSizendim;
int* myDims;
...
pa1=mxCreateLogicalArray(ndim,myDims);
在64位Linux上gcc: ERROR: buggyMexFile.c: In function 'mexFunction': buggyMexFile.c:35: warning: pass argument 2 of 'mxCreateLogicalArray' From不兼容的指针类型
在这种情况下,mydim必须是mwSize*,如2.1节所述。
6.执行MEX文件、测试和调试
将使用-largearydims编译的MEX文件的运行结果与原始二进制文件的结果进行比较。如果存在任何差异或失败,请使用调试器调查原因。
调试器是研究代码中的编程问题的关键工具。有关调试MEX文件的更多说明,请使用下面提供的链接:
有关调试器功能的更多信息,请参阅编译器文档。
在解决了- largearraydimms版本的任何问题之后,转换后的mex -文件现在可以在使用大型数组处理API的同时复制原始代码的功能。
以下是运行MEX文件时可能遇到的常见问题列表。
6.1. 内存不足错误
您可能遇到的一个潜在错误模式是“内存不足”错误。这是将代码转换为使用大型数组维时最常见的故障模式之一。它通常是由分配内存的函数使用不匹配的类型引起的,例如mxCreateDoubleMatrix。类型不匹配破坏了请求的数组大小,导致MATLAB试图分配比您预期多得多的内存。这个值可能远远超过您正在使用的机器的可用内存(RAM)。
该函数需要8个字节,因此它获取与4字节变量传递进来的相邻的4个字节。额外的字节中包含随机信息,因此,该函数将输入解释为与传入的值非常不同的值。
例如,mxCreateDoubleMatrix期望第一个参数为mwSize,在64位机器上使用-largearyDims时,该参数为64位。假设作为第一个参数传递的变量是一个int,它是32位:
intMN
m=10;
...
YP_OUT=mxCreateDoubleMatrix(m,n,mxREAL);
mxCreateDoubleMatrix接收的值可能包含32位随机信息。例如,该值可能被解释为85899345930(10+20*2^32)。这远远超过大多数机器的内存容量,因此MATLAB报告内存不足错误:
?使用==>buggyMexFile时出错
内存不足。为您的选项键入帮助记忆。
如果遇到此问题,请按照第2.1节的建议,将变量类型更改为mwSize或MWDINDEX:
mwSizeMN
m=10;
...
YP_OUT=mxCreateDoubleMatrix(m,n,mxREAL);
这种情况很难调试,因为“m”和“n”都包含正确的值,但都是错误的存储类。调试器可以帮助识别这一点。例如,Microsoft Visual Studio调试器将显示一个“Type”列,该列将显示上述变量的“int”和“size\t”、“unsigned” _ _int64”,或正确类型的类似名称。
6.2.分段冲突、断言或其他崩溃
使用调试器逐步检查原始代码和修改后的代码,查找两者之间的第一个差异,尤其是在修改的任何变量中。这一根本原因可能发生在实际崩溃之前。
同样,调试器可以识别每个值的数据类型。
6.3.不同的结果
使用调试器对原始代码和修改过的代码进行分步检查,寻找两者之间的第一个区别,特别是在修改过的任何变量中。这个根本原因可能在返回结果到MATLAB之前就已经发生了。
7.用巨大的数组调用您的MEX文件
如果您可以访问具有大量内存的计算机,现在可以使用包含2^32-1个以上元素的数组进行实验。使用这些数组需要大量内存——一个包含2^32个元素的双精度浮点数数组(MATLAB中的默认值)需要约32GB的内存。
您可以在MEX文件中找到有关64位MXArray的更多信息,以及演示大型阵列使用的arraySize.c MEX文件示例,如下所示:
8.常见问题(在随附的largearydimsfaq.txt中回答):
8.1.如果我只使用32位MATLAB怎么办?
8.2.如果我已经在64位系统上进行了建议的更改以支持稀疏数组,那会怎样呢?金宝app
8.3.如果我已经进行了建议的更改以支持64位MX阵列,该怎么办?金宝app
8.4.如果我已经对Fortran源文件进行了建议的更改,该怎么办?
8.5. 如果我想退出(不想升级)怎么办?
8.6. 如果我什么都不做呢?
8.7.如果我没有源MEX文件怎么办?
8.8.如果我使用Fortran怎么办?
8.9. 如果我在代码中发现不推荐使用的函数,如mexPutFull,该怎么办?

更多答案(1)

标签

下载188bet金宝搏


释放

R2008a

社区寻宝

在MATLAB Central中查找宝藏,了解社区如何帮助您!

开始狩猎!