我如何更新墨西哥文件使用大数组处理API (-largeArrayDims)?

115次观看(过去30天)
MEX API已更改为支持超过2^32-1个元素的MA金宝appTLAB变量。该特性是在MATLAB Version 7.3 (R2006b)中添加的。你必须用-largeArrayDims标记来编译你的mexo文件来选择加入这个API。
您可能需要更新您的MEX源代码以利用新的API。在不久的将来,MEX构建脚本将默认使用大数组处理API。

接受的答案

MathWorks支金宝app援小组
编辑:MathWorks支金宝app援小组 2020年2月27日
大数组处理API的添加可能需要您更新您的mexs文件。需要更改代码的原因是,为了支持大型数据,必须更改MATLAB API的输入和输出类型。我们已经以一种减少对现有用户影响的方式实现了API的更改。我们采用了“选择加入”策略,如果您想利用新的大数组处理特性,您可以使用MEX标志“-largeArrayDims”选择加入。如果选择加入,则需要进行本解决方案中描述的更新。如果你选择不“加入”,你现在不需要做任何事情。但是要注意,将来新的大数组处理API将成为默认值,届时您将需要更新代码或采取其他操作。
此解决方案将引导您逐步确定需要进行的更改。这个过程建议您在修改代码之前首先确定并列出需要更改的变量。我们建议您在完成标识步骤之前不要编辑代码。
首先,考虑对需要进行的更改进行高层次的技术解释。随着MEX API使用的类型的变化,现有代码可能会以错误的类型向MATLAB传递输入和输出。具体来说,更改的参数类型是索引和大小。两者都从32位类型更改为64位兼容类型。
以下步骤将帮助您识别需要更正的类型不匹配。它遵循一个有系统的过程,包括首先测试原始代码,然后确定更改,然后更新代码的副本,构建新代码,最后重新测试。本文还提供了一些关于如何处理常见代码模式、构建失败和警告以及运行时问题的建议。
注意:本文档主要使用C/ c++术语和示例代码。Fortran的墨西哥文件也有同样的问题;你可以在8.8节找到更多的Fortran细节。
详情如下:
1.测试现有代码
在调整代码以处理大型数组之前,应该首先验证它是否适用于传统的32位数组尺寸。您可能想要构建一个预期输入和输出的列表,甚至是一个完整的测试套件。备份源代码和二进制文件以确保安全,这样就可以将结果与更新后的源代码进行比较。
2.识别包含64位索引或大小值的变量
为了处理非常大的数组,你需要将所有包含数组索引或大小的变量转换为使用mwSize / mwIndex数据类型,而不是32位的“int”。当在64位体系结构上使用大数组维时,这些数据类型是64位整数,并作为预处理器宏实现。当使用-largeArrayDims时,这两种类型都与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 >
您可以使用编辑器的find函数或GREP之类的实用程序来查找这些函数。
例如,在旧版本的MATLAB (R2006a和更早的版本)中,这个签名是:
mxArray*mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag)
mxCreateDoubleMatrix在大数组维API中的签名是:
mxArray*mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity ComplexFlag)
请注意,前两个输入参数已从“int”更改为“mwSize”。作为第一个或第二个输入传递的变量必须声明为mwSize。
您可以在每个函数的参考页上找到新签名,通过帮助浏览器或DOC命令访问:
医生mxCreateDoubleMatrix
因为mwSize与使用32位数组维数时的"int"相同,所以您的代码仍可能被写入这个旧签名。为了利用大数组处理,您必须更新您的代码以使用mwSize/mwIndex来允许64位大小和索引值。
搜索您的代码,并注意所有定义为“int”或类似类型的变量。此时不要进行任何编辑,只需注意哪些变量需要更新。
如果你的代码是:
intn;
...
YP_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
m和n都应该声明为mwSize:
mwSizen;
...
YP_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
2.2.找到中间变量
您的代码可能使用中间变量来计算大小和索引。如果是这种情况,您将需要确保这些变量也声明为适当的类型。想想这个例子:
mwSizen;
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:
mwSizen;
mwSizenumDataPoints
检查您的代码,并将所有这些中间变量添加到要转换的变量列表中。
同样,此时不要进行任何编辑。
2.3.替换具有多种用途的变量
您的代码可能对两个索引(我们将其转换为64位)和STRUCT字段号或状态码(两者都保持32位)使用相同的变量。
用于多种目的的变量需要被标识,并替换为两个变量——一个mwSize / mwIndex和一个32位整数。当数组大小和STRUCT字段数量同时使用一个变量时,这种情况尤其常见。另一种情况是状态码/成功标志也用作索引。
例如,mxCreateDoubleMatrix需要mwSize输入,但mxCreateStructMatrix需要int:
mxArray*mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity ComplexFlag)
mxArray*mxCreateStructMatrix(mwSize m, mwSize n, int nfields, const char **fieldnames)
现在考虑numDataPoints变量:
mxArray* myNumeric* myStruct;
intnumSensors
mwSizen;
字符* *字段名
intnumFields
...
myNumeric = mxCreateDoubleMatrix(numSensors, n, mxREAL);
myStruct = mxCreateStructMatrix(m, n, numSensors, fieldnames);
在这个例子中,你需要两个新变量来替换numSensors来正确地处理这两个函数:
mxArray* myNumeric* myStruct;
mwSizenumSensorSize
intnumSensorFields
mwSizen;
字符* *字段名
...
myNumeric = mxCreateDoubleMatrix(numSensorSize, n, mxREAL);
myStruct = mxCreateStructMatrix(m, n, numSensorFields, fieldnames);
注意哪些变量需要以这种方式替换。同样,此时不要进行任何编辑。
3.第三方库
您的mexo文件可能涉及不是您编写的部分代码,并且您无权访问这些代码。这些可能是完整的墨西哥文件、数字例程或设备驱动程序。有几种方法可以解决这个问题:
3.1.如果您无法访问源代码,请与供应商联系。请将它们参考本文档,并讨论使用它们处理大型数组维度的选项。
3.2.如果与他人共享代码,例如公开可用的源代码,请与相关作者或用户组检查是否有人已将代码转换为使用大数组维度。如果不是,您可能希望自己转换代码。同样,应用本文档中的建议。
4.创建工作副本,进行编辑,并使用32位维度进行测试。
现在,您知道需要编辑哪些类型声明了。复制源代码并更改相关声明。像往常一样编译代码:
墨西哥人myMexFile.c
这使用了传统的32位维度。这和使用- compatibllearraydims标志是一样的:
墨西哥人-compatibleArrayDims myMexFile.c
与原始二进制文件进行比较;两者应该返回相同的结果。
如果不是,调试并解决任何差异。现在(使用相同的32位大小和索引)将比下一步更容易解决这些问题。
5.使用-largeArrayDims构建并解决构建失败和警告。
现在可以使用大数组处理API编译墨西哥文件了。简单地添加-largeArrayDims标志到你的编译;例如,而不是
墨西哥人myMexFile.c
使用
墨西哥人-largeArrayDims myMexFile.c
当使用-largeArrayDims时,你的编译器可能会将mwSize / mwIndex引用为"size_t", "unsigned . _ _int64”,或其他类似的名称。
此时,大多数构建问题都与32位和64位类型之间的类型不匹配有关。你可能遇到的一些常见问题是:
5.1.赋值类型不匹配
在某些情况下——尤其是简单的赋值——你的C/ c++编译器会对类型不匹配发出警告。例如:
mwSizen;
intnumDataPoints
...
numDataPoints = m * 2;
当你使用"mex -largeArrayDims buggyMexFile.c"编译这个文件时,你可能会收到一个类型不匹配的警告。
来自Microsoft Visual Studio在64位Windows上:ERROR: C:\Work\buggyMexFile.c(31):警告C4267: '=':从'size_t'转换为'int',可能丢失数据
可以使用第2.2节将中间变量numDataPoints转换为mwSize来修复此示例。
5.2.指针类型不匹配
当使用mxCreate*Array函数接受维度数组时,你需要将指针从int*转换为mwSize*:
mwSizendim
int* myDims
...
pa1 = mxCreateLogicalArray(ndim, myDims);
从64位Linux上的gcc: ERROR: buggyMexFile.c:在函数'mexFunction': buggyMexFile.c:35:警告:从不兼容的指针类型传递'mxCreateLogicalArray'的参数2
在这种情况下,myDims必须是mwSize*,如2.1节所述。
6.执行mex文件、测试和调试
比较使用-largeArrayDims编译的mex文件的结果与原始二进制文件的结果。如果存在任何差异或失败,请使用调试器来调查原因。
调试器是调查代码中编程问题的关键工具。有关调试MEX文件的更多说明,请使用下面提供的链接:
有关调试器功能的更多信息,请参阅编译器文档。
在解决了-largeArrayDims版本的任何问题后,您转换后的墨西哥文件现在可以在使用大数组处理API时复制原始代码的功能。
下面是运行mexs文件时可能遇到的一些常见问题。
6.1.内存不足错误
您可能遇到的一种潜在错误模式是“Out of Memory”错误。这是转换代码以使用大数组维时最常见的故障模式之一。这通常是由于使用不匹配的类型来分配内存,比如mxCreateDoubleMatrix。类型不匹配破坏了请求的数组大小,导致MATLAB试图分配比您期望的更多的内存。这个值可能远远超过您正在使用的机器的可用内存(RAM)。
该函数需要8个字节,因此它获取4字节变量传入的相邻的4个字节。额外的字节中包含随机信息,因此,函数将输入解释为与传入的值非常不同的值。
例如,mxCreateDoubleMatrix期望第一个参数是mwSize,当在64位机器上使用-largeArrayDims时,它是64位的。假设作为第一个参数传递的变量是一个32位的int:
intn;
M = 10;
...
YP_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
mxCreateDoubleMatrix接收到的值可能包含32位随机信息。例如,该值可以解释为85899345930(10 + 20*2^32)。这远远超过了大多数机器的内存容量,因此MATLAB报告内存不足错误:
???使用==> buggyMexFile时出错
内存不足。键入HELP MEMORY作为选项。
如果遇到这个问题,将变量的类型改为mwSize或mwIndex,如2.1节所述:
mwSizen;
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中的默认值)需要大约32 GB的内存。
你可以在墨西哥文件中找到更多关于64位mxArrays的信息,以及一个示例arraySize.c墨西哥文件,它演示了大数组的使用,这里:
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.如果我没有源墨西哥文件怎么办?
8.8.如果我用的是Fortran呢?
8.9.如果我在我的代码中发现废弃的函数,如mexPutFull,该怎么办?

更多答案(1)

shishuai杨
shishuai杨 2021年5月22日
是的

标签

下载188bet金宝搏


释放

R2008a

社区寻宝

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

开始狩猎!