我如何更新mex文件使用大型阵列处理API (- largearraydim)?

112次浏览(过去30天)
MEX API已经改变,以支持超过2^32-1元素的M金宝appATLAB变量。这个特性是在MATLAB版本7.3 (R2006b)中添加的。你必须用- largearraydim标志来编译你的mex文件来选择这个API。
您可能需要更新您的MEX源代码以利用新的API。在不久的将来,MEX构建脚本将默认使用大型数组处理API。

接受的答案

MathWorks支金宝app持团队
编辑:MathWorks支金宝app持团队 2020年2月27日
添加大阵列处理API可能需要您更新MEX文件。代码更改所需的原因是为了启用大型数据,必须更改对MATLAB API的输入和输出类型。我们以减少对现有用户的影响的方式实施了对我们API的更改。我们采用了一个“选项”策略,如果您想利用新的大型数组处理功能,可以使用MEX Flag“-LargeArrayDims”来选择。如果您选择选择选择,您需要进行此解决方案中描述的更新。如果您选择不“选择”,那么您现在不需要做任何事情。尽管如此,在将来,新的大型数组处理API将成为默认值,然后您将需要更新代码或采取其他操作。
此解决方案将逐步引导您完成识别需要进行的更改的过程。该过程建议,在修改代码之前,首先确定并列出需要更改的变量。我们建议您在完成标识步骤之前不要编辑代码。
首先,考虑需要进行的更改的高级技术解释。随着MEX API使用的类型的改变,现有代码有可能将输入和输出的类型传递给MATLAB。具体来说,更改的参数类型是索引和大小。两者都从32位类型变成了64位兼容的类型。
以下过程将帮助您识别需要纠正的类型不匹配。它遵循一个有条理的过程,包括首次测试原始代码,然后识别更改,然后更新代码的副本,构建新代码,最终重新测试。如何处理如何处理公共代码模式,构建故障和警告以及运行时问题。
注意:本文档主要使用C/ c++术语和示例代码。Fortran mex文件共享相同的问题;你可以在8.8节中找到更多的Fortran细节。
详细:
1.测试现有的代码
在调整代码以处理大型数组之前,请先验证它是否适用于传统的32位阵列尺寸。您可能想要构建预期的输入和输出列表,甚至是完整的测试套件。备份您的源代码和一副保管,以便您可以将结果与更新的源代码进行比较。
2.标识包含64位索引或大小值的变量
为了处理非常大的数组,你需要将所有包含数组索引或大小的变量转换为使用mwSize / mwIndex数据类型,而不是32位的“int”。当在64位体系结构上使用大数组维时,这些数据类型是64位整数,并作为预处理宏实现。当使用- largearraydim时,这两种类型与C/ c++中的size_t类型相同。
我们建议查看三类变量:直接被API函数使用的变量、中间变量和同时用作大小/索引和32位整数的变量。
2.1.搜索64位API函数直接使用的变量
要识别这些变量,请查找使用mwSize/mwIndex值作为输入或输出值的mx*和mex*函数。
要获得准确的列表,请查看您的MATLAB版本中的文档。你可以在这里找到这个列表:
< //www.tatmou.com/help/matlab/matlab_external/handling-large-mxarrays.html >
您可以使用编辑器的查找功能或Grep等实用程序找到这些功能。
例如,在Matlab(R2006a及更早版本的旧版本中,这个签名是:
mxarray.*mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag)
mxCreateDoubleMatrix在大数组维度API中的签名是:
mxarray.* mxcreatedoublematrix(mwsize m,mwsize n,mx互补性复杂氟玻璃)
注意,前两个输入参数已经从"int"改为"mwSize"。作为第一个或第二个输入传入的变量必须声明为mwSize。
你可以在每个函数的参考页面上找到新的签名,可以通过帮助浏览器或DOC命令访问:
医生mxCreateDoubleMatrix
因为在使用32位数组维度时,mwSize与“int”相同,所以您的代码仍可能被写入这个较旧的签名。为了利用大型数组处理,您必须更新代码,使用mwSize/mwIndex来允许64位大小和索引值。
搜索您的代码,并注意任何定义为“int”或类似类型的变量。此时不要进行任何编辑,只需注意哪些变量需要更新。
如果您的代码是:
n;
...
YP_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
m和n都应该被声明为mwSize:
mwSizen;
...
YP_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
2.2.找到中间变量
您的代码可能使用中间变量来计算大小和索引。如果是这种情况,您将需要确保这些变量也被声明为适当的类型。考虑一下这个例子:
mwSizen;
numDataPoints
m = 3;
numdatapopoints = m * 2;
n = numdatapopoints + 1;
...
YP_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
第2.1节中的第一个搜索将遗漏mx*函数调用中没有直接使用的中间变量,例如本例中的numdatapopoints。这些变量的大小不足以处理来自mwSize变量的64位索引。在这些32位的中间变量中存储64位的索引将截断索引,从而导致不正确的结果或崩溃。在这个例子中,numdatapopoints应该被更改为mwSize,因为"m"是mwSize:
mwSizen;
mwSizenumDataPoints
检查您的代码,并将所有这样的中间变量添加到要转换的变量列表中。
同样,此时不要进行任何编辑。
2.3。替换提供多种目的的变量
您的代码可能对两个索引(我们将其转换为64位)和STRUCT字段编号或状态码(两者都保持32位)使用相同的变量。
需要识别用于多种目的的变量,并用两个变量替换——一个mwSize / mwIndex和一个32位整数。当使用一个变量同时表示数组大小和STRUCT字段的数量时,这种情况尤其常见。另一种情况是状态码/成功标志也用作索引。
例如,MXCreatedouBlematrix预期MWSize输入,但MxCreateStructMatrix需要一个int:
mxarray.* mxcreatedoublematrix(mwsize m,mwsize n,mx互补性复杂氟玻璃)
mxarray.*mxCreateStructMatrix(mwSize m, mwSize n, int nfields, const char **fieldnames)
现在考虑numdatapopoints变量:
mxarray.* myNumeric* myStruct;
numSensors
mwSizen;
字符* *字段名
numFields
...
myNumeric = mxCreateDoubleMatrix(numSensors, n, mxREAL);
myStruct = mxCreateStructMatrix(m, n, numSensors, fieldnames);
在这个例子中,你需要两个新变量来替换numSensors来正确地处理这两个函数:
mxarray.* myNumeric* myStruct;
mwSizenumsensosize
numSensorFields
mwSizen;
字符* *字段名
...
myNumeric = mxCreateDoubleMatrix(numSensorSize, n, mxREAL);
myStruct = mxCreateStructMatrix(m, n, numSensorFields, fieldnames);
请注意需要以这种方式替换哪些变量。同样,此时不要进行任何编辑。
3.第三方库
您的mex -文件可能涉及您没有编写且无法访问的部分代码。这些可能是完整的mex文件、数值例程或设备驱动程序。有几种方法可以解决这个问题:
3.1.如果您无法访问源代码,请与供应商联系。请参考本文档并讨论处理大型数组维数的选项。
3.2。如果您与其他人共享代码,例如公开可用的源代码,请使用相关作者或用户组检查是否有人已转换代码以使用大型数组维度。如果没有,您可能希望自己转换代码。再次,应用本文档中的建议。
4.创建一个工作副本,进行编辑,并使用32位尺寸进行测试。
现在,您知道需要编辑哪些类型声明了。制作一份源代码的副本,并更改相关声明。像往常一样编译代码:
梅克斯mymexfile.c.
这使用了传统的32位维。这和使用- compatiblearraydim标志是一样的:
梅克斯-compatibleArrayDims myMexFile.c
与原始二进制文件进行比较;两者都应该返回相同的结果。
如果没有,调试并解决任何差异。这将比下一步更容易解析(使用相同的32位大小和索引)。
5.使用- largearraydim构建并解决构建失败和警告。
现在可以使用大型数组处理API编译mex文件了。只需将- largearraydim标志添加到编译中;例如,代替
梅克斯mymexfile.c.
使用
梅克斯-largeArrayDims myMexFile.c
当使用- largearraydim时,编译器可能会将mwSize / mwIndex引用为"size_t", "unsigned " _ _int64”或其他类似的名称。
此时,大多数构建问题都与32位和64位类型之间的类型不匹配有关。你可能会遇到的一些常见问题是:
5.1.赋值类型不匹配
在某些情况下——特别是简单的赋值——C/ c++编译器会警告类型不匹配。例如:
mwSizen;
numDataPoints
...
numdatapopoints = m * 2;
当你使用"mex - largearraydim buggyMexFile.c"编译这个文件时,你可能会收到一个类型不匹配的警告。
从Microsoft Visual Studio上64位Windows: ERROR: C:\Work\buggyMexFile.c(31): warning C4267: '=':从'size_t'转换到'int',可能丢失数据
可以使用第2.2节将此示例进行修复,以将中间变量NumDataPoint转换为MWSize。
5.2。指针类型的类型不匹配
当使用mxCreate*Array函数时,需要将指针从int*转换为mwSize*:
mwSizendim
* mydims.
...
pa1 = mxCreateLogicalArray(ndim, mydim);
从64位Linux中的GCC
在这种情况下,MyDims必须是MWSIZE *,如2.1节所述。
6.执行mex文件、测试和调试
将运行用- largearraydim编译的mex文件的结果与原始二进制文件的结果进行比较。如果存在任何差异或失败,请使用调试器调查原因。
调试器是调查代码中的编程问题的关键工具。有关调试MEX文件的更多说明,请使用下面提供的链接:
有关调试器功能的更多信息,请参考编译器文档。
在解决-largeArrayDims版本的任何问题后,转换后的MEX文件现在使用大型数组处理API同时复制原始代码的功能。
下面列出了在运行mex -文件时可能遇到的一些常见问题。
6.1.内存不足错误
您可能遇到的一个潜在错误模式是“内存不足”错误。这是转换代码以使用大阵列尺寸时最常见的故障模式之一。它通常是由于使用不匹配类型而具有分配内存的功能,例如mxcreatedoublematrix。类型不匹配损坏了所请求的数组大小,导致MATLAB尝试分配比您预期的更多内存。此值远远超过您使用的机器的可用内存(RAM)。
该函数预计8个字节,因此它抓住了4字节变量传递的4个字节。额外的字节在它们中具有随机信息,因此该函数将输入解释为比传递的值的值非常不同。
例如,mxCreateDoubleMatrix期望第一个参数是mwSize,当在64位机器上使用- largearraydim时,它是64位的。假设作为第一个参数传递的变量是一个32位的int型:
n;
m = 10;
...
YP_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
mxCreateDoubleMatrix接收到的值可能包含32位的随机信息。例如,该值可以解释为85899345930(10 + 20*2^32)。这远远超过了大多数机器的内存容量,因此MATLAB报告内存不足错误:
???使用==> buggyMexFile时出错
内存不足。为您的选项输入帮助记忆。
如果你遇到这个问题,将变量的类型更改为mwSize或mwIndex,参考2.1节中的建议:
mwSizen;
m = 10;
...
YP_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
这种情况很难调试,因为“m”和“n”都包含正确的值,但都是错误的存储类。调试器可以帮助识别这一点。例如,Microsoft Visual Studio调试器会显示一个“Type”列,上面的变量会显示“int”和“size_t”,“unsigned” _ 或正确类型的类似名称。
6.2。分割冲突、断言或其他崩溃
使用调试器遍历原始代码和修改代码,寻找两者之间的第一个区别,特别是在您修改的任何变量中。这个根本原因可能早在实际坠机之前就已经发生了。
同样,调试器可以识别每个值的数据类型。
6.3。不同的结果
使用调试器遍历原始代码和修改代码,寻找两者之间的第一个区别,特别是在您修改的任何变量中。这个根本原因可能在将结果返回到MATLAB之前就发生了。
7.使用巨型数组调用mex文件
如果您可以访问具有大量内存的机器,那么现在可以试验具有超过2^32-1元素的数组。使用这些数组需要大量内存——一个包含2^32个元素的双精度浮点数数组(MATLAB中的默认值)需要大约32gb内存。
你可以在MEX-files中找到更多关于64位mxArrays的信息,以及一个演示大型数组使用的arraySize.c MEX-file示例:
8.常见问题(在附件largeArrayDimsFaq.txt中回答):
8.1。如果我只使用32位MATLAB呢?
8.2。如果我已经提出了推荐的更改,以支持64位系统上的稀疏阵列?金宝app
8.3。如果我已经做了推荐的更改以支持64位mxArrays,该怎么办?金宝app
8.4。如果我已经对Fortran源文件进行了建议的更改,该怎么办?
8.5。如果我想退出(不想升级)怎么办?
8.6。如果我什么都不做呢?
8.7。如果我没有源mex文件怎么办?
8.8。如果我在用Fortran呢?
8.9。如果我在我的代码中发现了已弃用的函数,如mexPutFull,该怎么办?

更多的答案(0)

标签

还没有输入标签。

下载188bet金宝搏


释放

R2008a

社区寻宝

在MATLAB中心找到宝藏,并发现社区可以如何帮助您!

开始狩猎!

翻译的