mex
команда использует -largeArrayDims
опция по умолчанию. В этом разделе описывается, как обновить файлы MEX для использования 64-разрядного API.
Вы можете продолжить использовать 32-битный API, позвонив mex
команда со -compatibleArrayDims
опция. Однако для получения дополнительной информации об использовании этой опции см. раздел «Что делать, если я не обновляю?».
Чтобы просмотреть и обновить исходный код файла MEX, используйте следующий контрольный список.
Подготовьте код перед редактированием - см. «Резервное копирование файлов» и «Создание тестов».
Итерационное изменение и тестовый код.
Прежде чем создавать файлы MEX с 64-разрядным API, рефаксируйте существующий код с помощью Переменные и, для Фортран, Upgrade Файлы MEX на языке ФОРТРАН, чтобы использовать 64-разрядный API.
После каждого изменения создайте и протестируйте свой код:
Создайте с 32-разрядным API. Например, чтобы создать myMexFile.c
, тип:
mex -compatibleArrayDims myMexFile.c
Тестируйте после каждого рефакторинга - см. «Тестирование, отладка и разрешение различий после каждой итерации рефакторинга».
Скомпилируйте с помощью 64-битного API. Как создать myMexFile.c
, тип:
mex myMexFile.c
Устранение отказов и предупреждений - см. Раздел «Устранение отказов сборки и предупреждения» -largeArrayDims.
Сравнение результатов - см. Выполнение 64-Bit файла MEX и Сравнение результатов с 32-Bit версией.
Проверяйте память - см. «Эксперимент с большими массивами».
В следующих процедурах используется терминология C/C + + и пример кода. Файлы MEX на языке ФОРТРАН имеют общие проблемы с дополнительными задачами, описанными в Upgrade Fortran MEX Files, чтобы использовать 64-разрядный API.
Прежде чем изменять код, проверьте, что файл MEX работает с 32-битным API. Как минимум, составьте список ожидаемых входов и выходов или создайте полный тестовый набор. Используйте эти тесты для сравнения результатов с обновленным исходным кодом. Результаты должны быть идентичными.
Резервное копирование всех исходных, двоичных и тестовых файлов.
Чтобы обработать большие массивы, преобразуйте переменные, содержащие индексы или размеры массивов, в использование mwSize
и mwIndex
типы вместо 32-битных int
тип. Проверьте свой код, чтобы увидеть, содержит ли он следующие типы переменных:
Переменные, используемые непосредственно функциями Matrix API - см. «Аргументы обновления, используемые для вызова функций» в 64-Bit API.
Промежуточные переменные - см. «Переменные обновления, используемые для индексов и размеров массивов».
Переменные, используемые как в значениях size/index, так и в 32-битных целых числах - см. «Анализ других переменных».
Идентифицируйте 64-битные функции API в вашем коде, которые используют mwSize
/ mwIndex
типы. Список функций см. в разделе Использование 64-Bit API. Поиск переменных, которые вы используете для вызова функций. Проверьте сигнатуру функции, показанную под заголовком «Синтаксис» в справочной документации функции. Сигнатура определяет переменные, которые берут mwSize
/ mwIndex
значения как входные или выходные значения. Измените свои переменные, чтобы использовать правильный тип.
Например, предположим, что ваш код использует mxCreateDoubleMatrix
функция, как показано на следующих операторах:
int nrows,ncolumns; ... y_out = mxCreateDoubleMatrix(nrows, ncolumns, mxREAL);
Чтобы увидеть сигнатуру функции, введите:
doc mxCreateDoubleMatrix
Подпись:
mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity ComplexFlag)
Тип для входных параметров m
и n
является mwSize
. Измените код как показано в таблице.
Замените: | С: |
---|---|
int nrows,ncolumns; |
mwSize nrows,ncolumns; |
Если ваш код использует промежуточные переменные для вычисления размера и значений индекса, используйте mwSize
/ mwIndex
для этих переменных. Например, следующий код объявляет входы mxCreateDoubleMatrix
как тип mwSize
:
mwSize nrows,ncolumns; /* inputs to mxCreateDoubleMatrix */ int numDataPoints; nrows = 3; numDataPoints = nrows * 2; ncolumns = numDataPoints + 1; ... y_out = mxCreateDoubleMatrix(nrows, ncolumns, mxREAL);
Этот пример использует промежуточную переменную, numDataPoints (типа int
), для вычисления значения ncolumns. Если вы копируете 64-битное значение из nrows в 32-битную переменную, numDataPoints, полученное значение обрезается. Ваш файл MEX может аварийно завершиться или привести к неправильным результатам. Используйте тип mwSize
для numDataPoints, как показано в следующей таблице.
Замените: | С: |
---|---|
int numDataPoints; |
mwSize numDataPoints; |
Вам не нужно менять каждую целочисленную переменную в коде. Например, номера полей в структурах и коды состояния имеют тип int
. Однако вам нужно идентифицировать переменные, используемые в нескольких целях, и, при необходимости, заменить их несколькими переменными.
Следующий пример создает матрицу, myNumeric и структуру, myStruct, на основе количества датчиков. Код использует одну переменную, numSensors, как для размера массива, так и для количества полей в структуре.
mxArray *myNumeric, *myStruct; int numSensors; mwSize m, n; char **fieldnames; ... myNumeric = mxCreateDoubleMatrix(numSensors, n, mxREAL); myStruct = mxCreateStructMatrix(m, n, numSensors, fieldnames);
Сигнатуры функции для mxCreateDoubleMatrix
и mxCreateStructMatrix
являются:
mxArray *mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity ComplexFlag) mxArray *mxCreateStructMatrix(mwSize m, mwSize n, int nfields, const char **fieldnames);
Для mxCreateDoubleMatrix
функция, ваш код использует numSensors для переменной m. Тип m mwSize
. Для mxCreateStructMatrix
функция, ваш код использует numSensors для переменной nfields. Тип nfields int
. Чтобы обработать обе функции, замените numSensors на две новые переменные, как показано в следующей таблице.
Замените: | С: |
---|---|
int numSensors; |
/* create 2 variables */ /* of different types */ mwSize numSensorSize; int numSensorFields; |
myNumeric = mxCreateDoubleMatrix( numSensors, n, mxREAL); |
/* use mwSize variable */ /* numSensorSize */ myNumeric = mxCreateDoubleMatrix( numSensorSize, n, mxREAL); |
myStruct = mxCreateStructMatrix( m, n, numSensors, fieldnames); |
/* use int variable */ /* numSensorFields */ myStruct = mxCreateStructMatrix( m, n, numSensorFields, fieldnames); |
Как создать myMexFile.c
с помощью 32-битного API введите:
mex -compatibleArrayDims myMexFile.c
Используйте тесты, созданные в начале этого процесса, чтобы сравнить результаты обновленного файла MEX с исходным двоичным файлом. Оба файла MEX должны получить одинаковые результаты. Если нет, отлаживайте и устраняйте любые различия. Сейчас устранить различия проще, чем при сборке с использованием 64-разрядного API.
-largeArrayDims
Отказы сборки и предупрежденияПосле просмотра и обновления кода скомпилируйте файл MEX с помощью API обработки больших массивов. Как создать myMexFile.c
с помощью 64-битного API введите:
mex myMexFile.c
Начиная с mwSize
/ mwIndex
типы являются MATLAB® типы, ваш компилятор иногда ссылается на них как size_t
, unsigned_int64
, или по другим подобным именам.
Большинство проблем со сборкой связаны с несоответствием типов между 32-разрядными и 64-разрядными типами. См. шаг 5 в разделе Как обновить файлы MEX, чтобы использовать API обработки больших массивов (-largeArrayDims)? идентифицировать общие проблемы сборки для конкретных компиляторов и возможные решения.
Сравните результаты выполнения файла MEX, скомпилированного с 64-разрядным API, с результатами из вашего исходного двоичного файла. Если есть какие-либо различия или отказы, используйте отладчик, чтобы выяснить причину. Для получения информации о возможностях отладчика см. документацию компилятора.
Чтобы идентифицировать проблемы - и возможные решения - вы можете столкнуться с ними при запуске файлов MEX, смотрите Шаг 6 в Как обновить MEX-файлы, чтобы использовать API обработки больших массивов (-largeArrayDims)?.
После решения проблем и обновления файла MEX он наследует функциональность оригинального кода при использовании API обработки больших массивов.
Если у вас есть доступ к машине с большим объемом памяти, можно экспериментировать с большими массивами. Массив с двойной точностью чисел с плавающей запятой (по умолчанию в MATLAB) с 232 элементы занимают приблизительно 32 ГБ памяти.
Для примера, который демонстрирует использование больших массивов, смотрите arraySize.c
MEX-файл в обработке больших mxArrays в файлах MEX на C.