Integrate C function with multiple outputs built with MATLAB Coder - c

I have been coding in MATLAB and I managed to convert my work to a single function, however it has several inputs and outputs. For the sake of simplicity, lets say it receives three inputs: X (vectorial and for reading only), Y (vectorial and for reading and writing) and Z (scalar and for writing only). Thanks to the reply here I was able to understand that I must create variables with special MATLAB types in order to pre-allocate space and then send them as parameters in my function in the C code.
An initial version with a single scalar output (Z) worked as expected, however taking the next step towards having multiple outputs has raised some questions. I'll try to be as concise as possible. Here's the header of my function in MATLAB and C code once I change Z to a vector:
[Y,Z]=foo(X,Y)
void foo(const unsigned int *X, float Y[n_Y], float Z[n_Z])
These are my doubts so far.
1 - I would expect that if Z is only created inside, it should not appear as an input for the C function. What should I do with it in order to obtain it outside the function? My idea would be to provide a fake variable with the same name that would later be overwritten.
2 - If Y is being changed, then the function should receive the pointer to Y. Is it being updated this way, as it should?
3 - Right now the dimensions are set for X as (1x:inf), which causes the pointer to show up. If I change to a smaller and realistic bound, that single input transforms into two, although nothing else changed (the variable creation in C is independent). Now there is const unsigned int X_data[], const int X_size[2] instead of just const unsigned int X. How should I deal with it within the C code?
The call to the function in C is being made as follows:
emxArray_uint32_T *X=emxCreate_uint32_T(1,n_X);
static emxArray_uint32_T *Y=emxCreate_real32_T(1,n_Y), *Z=emxCreate_real32_T(1,n_Z);
foo(X,&Y,&Z);
emxDestroyArray_uint32_T(X);
I should say that I have not tried to compile the lastest steps, since I need a specific environment to do so (laboratory). However, when I have access to it, the code needs to be almost ready to go. Also, without solving these doubts I think I shouldn't anyway. If it works somehow and I don't understand why, then it's the same as not working.

Related

In an assignment A(:) = B, the number of elements in A and B must be the same

When trying to run my code, for example
for ii= 1:10
output(ii)=rand(3);
end
I get the error
In an assignment A(:) = B, the number of elements in A and B must be the same
or
In an assignment A(I) = B, the number of elements in B and I must be the same.
What does this error mean? What is the approach to get rid of it?
This error comes because you are trying to fill a variable chunk with more (or less) values than its size. In other words, you have a statement A(:)=B on where size(A(:)) is different to size(B).
In the example in the question, rand(3) returns a 3x3 matrix, however, output(ii) is just a single value (even if output may be bigger, output(ii) is just a single value of output), thus the value returned by rand(3) does not fit inside output.
In order to solve this problem, you need to change the the size of the output variable, so you have space to fit all the result.
There are 2 ways of doing this. One of them is by creating a Matrix that fits the return, e.g. output=zeros(3,3,10).
Then we can change the code to
for ii= 1:10
output(:,:,ii)=rand(3);
end
Alternatively, you can fill the output as a cell array. This is particularly useful when the return of the function changes sizes each time, e.g. rand(ii);
In that case, the following would work
for ii= 1:10
output{ii}=rand(ii);
end
It is probable that unlike in the example in the question, in the real case you do not know the size of what the output returns, thus you do not know which of the two options to use to fix your code.
On possible way of learning that, is activating debugging help when the code errors, by typing dbstop if error in your command line. This will trigger a debugging stop when MATLAB throws an error, and you can type size(rand(ii)) and size(output(ii)) to see the sizes of both.
Often, reading the documentation of the function being used also helps, to see if different sizes are possible.
That said, the second option, cell arrays, will always ensure everything will fit. However matrices are generally a faster and easier to use in MATLAB, thus you should aim for the matrix based solution if you can.

Using Matlab Coder generated algorithm for Production

I have a fine tuned algorithm in MATLAB that operates on matrices (ofcourse). I've used matlab coder to generate c code for this algorithm and it works as expected.
Here's a function call that I used in Matlab
x = B/A
wherein
B is of size 1*500 (rows * columns)
A is of size 10*500
x, the result is of size 1*10
When this is converted into C source using Matlab Coder. I noticed that the function definition accepts parameters that are same as above sizes.
void myfunction(const double B[500], const double A[5000], double x[10])
For prototype and testing purposes this seems okay. However, in production I prefer to have this function be used for different sizes too. For example 100 instead of 500 in above mentioned variables should also work. How can I remove dependence of matrix dimensions in my algorithm ?
Additionally, there are few lines of code that use hard coded integers. For example, there is code like
if (rankR <= 1.4903363393874656E-8)
// Some internal function calls
else
// Usage of standard sqrt
or
500.0 * fabs(A[0]) * 2.2204460492503131E-16
Could any one explain what are these hard coded integers ? Are these generated from the test data that I've used in MATLAB ?
If the function call you refer to is the entry-point function, you can define the size when setting up Coder. The simplest way to run the Coder is using the GUI from the 'Apps' menu inside MATLAB (or type 'coder' at the console). After specifying the entry-point function, step 2 is to define the type and size for each of the input variables.
For each dimension of your input variable (there can be more than 2 if necessary), you can specify the:
n - dimension is exactly n long
:n - dimension is up to n long
inf - dimension is unbounded
If the function call is not the entry-point function, and is buried inside your code (or if you are running the codegen function from the console), you can explicitly define variables as being of varying size:
coder.varsize('myVariableName');
Bear in mind that some functions can only be used (with Coder) with fixed-sized inputs.
Fuller description here:
http://uk.mathworks.com/help/fixedpoint/ug/defining-variable-size-data-for-code-generation.html#br9t627
Not sure about the random constants unfortunately.

C code works standalone. But when UVM test calls C DPI, c variables gets messed up

I am using Synopsis VCS compiler. My testbench is coded in UVM. I have a set of C routines that perform some standalone functions. I am calling these C routines through DPI imports in the UVM environment.
Here is the code snippet in a simple way,
uint64_t blah, var1, blah_1;
var1 = UVM_class::C_function_1(uint64_t blah);
blah_1 = UVM_class::C_function_2(uint64_t var1);
if(blah_1 != blah) assert(0);
#
uint64_t C_function_1(uint64_t blah)
{
.....
.....
uint64_t x = function1(...);
return x;
}
#
uint64_t function1(...)
{
uint64_t y;
calculate some stuff
return y;
}
Here is the issue: If I run this as a part of regression, about 10000 times it works perfect.
At the 10001th time, this is what happens.
function1 retruns the correct value and I see that when I print y. However, when I print x inside C_function_1, x has something like 0xffffff_fffff_y. That is value of y is present, but there is some garbage attached to it. This messes up subsequent calculations that involve x.
I read a lot regarding stack getting messed up and made sure I malloc'd and free'd all pointers that are arguments to various functions.
I also tried running the C portion as standalone and there is no error and the regression is clean.
The only issue is when I run the UVM test which calls the C regression routine.
I have spent a lot of time debugging this to no avail.
Anybody any suggestions?
I am the poster of the question and I tried three things as far as restructuring my code was concerned and I do not see this behaviour anymore :)
1) Made certain key variables global. Hence, they have no business with the C stack and can be saved from stack issues
2) Had a number of functions calling other functions to do basic one liner stuff. Reduced the number of functions and hence less chances for the stack to get messed up. This worked for me as I mentioned my functions were doing one liner stuff...combined my four functions each with 15 variables into one single functon with 4 lines.
3) Third and I think the most important thing:
I had statement like this in my for loops
int a = func();
So, this means a local variable is being created everytime the loop is traversed...the stack will grow unnecessirily.
changed it to :
int a;
inside the loop:
a =func();
now, the stack grows just once and this could also save the stack from getting messed up.
These are the steps I took and I do not see this behaviour anymore.

Is printing a char* faster than printing a char one at a time?

I have to write a simple program in C that prints to the standard output triangle with two equal edges for given number n. Meaning that for n=3 the output would be:
x
xx
xxx
Now I'm supposed to do two version of this program:
1. Memory conservative.
2. Time conservative.
Now I'm not entirely sure, but I think that the first version would just print x one at a time, and the second would expand the char table one at a time and then print it.
But is printing a char* faster than printing multiple single chars?
You may not be able to observe but building the entire string in memory and then printing it at once is definitely faster in theory. Reason being you will be making less calls to printf function. Each time you call a function there are multiple things that happen in the background like pushing all the current method variables and current location to stack and popping them back after returning.
However as I mentioned you may not be able to observe this difference for smaller inputs because the time needed for each of these operations are small unless you use a computer from 1960s.

R external interface

I would like to implement some R package, written in C code.
The C code must:
take an array (of any type) as input.
produce array as output (of unpredictable size).
What is the best practice of implementing array passing?
At the moment C code is called with .C(). It accesses array directly from R, through pointer. Unfortunately same can't be done for output, as output dimensions need to be known in advance which is not true in my case.
Would it make sense to pass array from C to R through a file? For example, in ramfs, if using linux?
Update 1:
Here the exact same problem was discussed.
There, possible option of returning array with unknown dimensions was mentioned:
Splitting external function into two, at the point before calculating the array but after dimensions are known. First part would return dimensions, then empty array would be prepared, then second part would run and populate the array in R.
In my case full dimensions are known only once whole code is executed, so this method would mean running C code twice. Taking a guess on maximal array size isn't optional either.
Update 2: It seems only way to do this is to use .Call() instead, as power suggested. Here are few good examples: http://www.sfu.ca/~sblay/R-C-interface.ppt.
Thanks.
What is the best practice of implementing array passing?
Is the package already written in ANSI C? .C() would then be quick and easy.
If you are writing from scratch, I suggest .Call() and Rcpp. In this way, you can pass R objects to your C/C++ code.
Would it make sense to pass array through a file?
No
Read "Writing R Extensions".

Resources