MATLAB: Code produced wrong fixed sized arrays causing exceptions

arrayfindloopMATLABmatlab coder

we generated c++ code using matlab coder. problem occurs when there is a loop that reads and writes to fix sized arrays but the loop runs on size grater than the size of the arrays.( all determined by the coder).
Example:
in our imerode2.m file:
function bw = imerode2(bw,strel)
%#codegen
s = sum2(strel);
bw = filter2(strel,bw);
bw(bw<s) = 0;
bw(bw==s) = 1;
return;
bw is 1000:1000, strel size is 1:3
in the c++ file
/*
* imerode2.cpp
*
* Code generation for function 'imerode2'
*
* C source code generated on: Thu Jan 26 15:50:32 2012
*
*/
/* Include files */
#include "rt_nonfinite.h"
# #include "imerode2.h"
#include "Blobs2LineApprox.h"
#include "filter2.h"
#include "sum2.h"
/* Type Definitions */
/* Named Constants */
/* Variable Declarations */
/* Variable Definitions */
/* Function Declarations */
/* Function Definitions */
/*
* function bw = imerode2(bw,strel)
*/
void imerode2(const uint8_T bw_data[1000000], const int16_T bw_sizes[2],
real32_T b_bw_data[1000000], int16_T b_bw_sizes[2])
{
real32_T fv1[3];
int16_T i;
real32_T s;
static boolean_T c_bw_data[1000000];
int16_T c_bw_sizes[2];
int32_T loop_ub;
int16_T tmp_sizes;
static int32_T tmp_data[32767];
int16_T b_tmp_data[32767];
int16_T d_bw_sizes[2];
/* 'imerode2:5' s = sum2(strel); */
for (i = 0; i < 3; i++) {
fv1[i] = 1.0F;
}
s = sum2(fv1);
/* 'imerode2:6' bw = filter2(strel,bw); */
b_filter2(bw_data, bw_sizes, b_bw_data, b_bw_sizes);
/* 'imerode2:7' bw(bw<s) = 0; */
c_bw_sizes[0] = b_bw_sizes[0];
c_bw_sizes[1] = b_bw_sizes[1];
loop_ub = (int32_T)b_bw_sizes[0] * (int32_T)b_bw_sizes[1] - 1L;
for (i = 0; (int32_T)i <= loop_ub; i = (int16_T)((int32_T)i + 1L)) {
c_bw_data[i] = (b_bw_data[i] < s);
}
b_eml_li_find(c_bw_data, c_bw_sizes, tmp_data, *(int16_T (*)[1])&tmp_sizes);
loop_ub = (int32_T)tmp_sizes - 1L;
for (i = 0; (int32_T)i <= loop_ub; i++) {
b_tmp_data[i] = (int16_T)tmp_data[i];
}
loop_ub = (int32_T)tmp_sizes - 1L;
for (i = 0; (int32_T)i <= loop_ub; i++) {
b_bw_data[b_tmp_data[i] - 1] = 0.0F;
}
/* 'imerode2:8' bw(bw==s) = 1; */
d_bw_sizes[0] = b_bw_sizes[0];
d_bw_sizes[1] = b_bw_sizes[1];
loop_ub = (int32_T)b_bw_sizes[0] * (int32_T)b_bw_sizes[1] - 1L;
for (i = 0; (int32_T)i <= loop_ub; i = (int16_T)((int32_T)i + 1L)) {
c_bw_data[i] = (b_bw_data[i] == s);
}
b_eml_li_find(c_bw_data, d_bw_sizes, tmp_data, *(int16_T (*)[1])&tmp_sizes);
loop_ub = (int32_T)tmp_sizes - 1L;
for (i = 0; (int32_T)i <= loop_ub; i++) {
b_tmp_data[i] = (int16_T)tmp_data[i];
}
loop_ub = (int32_T)tmp_sizes - 1L;
for (i = 0; (int32_T)i <= loop_ub; i++) {
b_bw_data[b_tmp_data[i] - 1] = 1.0F;
}
}
/* End of code generation (imerode2.cpp) */
you can see that after calling the find function 'b_eml_li_find()' that might return array of max size of 1000000 there is a loop reading and writing to the arrays locally defined with smaller size of 32767.
strange thing is that if we compile only the function in imerode2.m the code generated is correct (local arrays are also of size 1000000) but when we compile our entire project we get the code with local arrays of the smaller size.
does anyone have an idea why it happens?
thnks!

Best Answer

Hi Rami,
I suspect this is happening because your target has 16-bit integers. The size vector is wrapping as one million cannot be represented in 16-bits. On your MATLAB host, integers are 32-bits so you don't have this problem. My speculation is that you are generating code as MEX-functions when you just build these functions, but picking a custom target when generating code for the whole project. Is this right?
Unfortunately, I don't see a workaround other than picking a target with 32-bit integers. The type used for size vectors is hard-coded to the integer type of your target.
Hope this helps.
Regards,
Fred
Related Question