Main Content

Generate Reusable Code from For Each Subsystems

In the model-based design, to convert inefficient repetitive algorithms into compact forms, use For Each subsystems. For Each subsystems repeat execution during a simulation time step on each element or subarray of an input signal or mask parameter array. In addition, to reduce model complexity, you can also generate reusable code for identical For Each subsystems by configuring them as reusable functions. You must configure mask and block parameters of the identical subsystems the same way. The code generator performs a checksum to determine whether subsystems are identical and the code is reusable. If the code is reusable, the code generator produces a single instance of reusable code which is shared by the identical subsystems.

This example shows how you can generate reusable code for For Each subsystems that perform the same processing on their respective inputs.

Example Model

This example generates code from the ForEachReuse model designed in in Improved Code Reuse Using For-Each Subsystems.

model = 'ForEachReuse';
open_system(model)

The model contains three For Each subsystems Vector SS1, Vector SS2, and Vector SS3 that apply the same processing to each scalar element of the vector signal at their respective inputs. For example, the Vector SS3 subsystem contains these blocks.

open_system('ForEachReuse/Vector SS3');

To generate a single shared function for the three subsystems, the input signal dimension of the subsystems must be the same. For Vector SS1 and Vector SS3, set the partition dimension and width to 1. For Vector SS2 to also set the input signal dimension 1, insert a Math Function block to transpose the 1-by-8 row vector into an 8-by-1 column vector. To convert the output of the subsystem back to a 1-by-8 row vector, use a second Math Function block.

The remaining For Each subsystem Matrix SS1 and Matrix SS2 process matrix signals using the same algorithm and have the same input signal dimension setting.

Generate and Inspect Code

  1. To configure the subsystems as reusable functions, open the Block Parameters dialog box. On the Code Generation tab, set Function packaging to Reusable function.

  2. Generate code.

slbuild(model);
### Starting build procedure for: ForEachReuse
### Successful completion of build procedure for: ForEachReuse

Build Summary

Top model targets:

Model         Build Reason                                         Status                        Build Duration
===============================================================================================================
ForEachReuse  Information cache folder or artifacts were missing.  Code generated and compiled.  0h 0m 12.233s 

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 13.04s

The code generator generates a single output function VectorProcessing in VectorProcessing.c.

file = fullfile('ForEachReuse_grt_rtw','VectorProcessing.c');
coder.example.extractLines(file,'* Output and update for iterator system:','/* Outputs for Iterator SubSystem:',1,1);
 * Output and update for iterator system:
 *    '<Root>/Vector SS1'
 *    '<Root>/Vector SS2'
 *    '<Root>/Vector SS3'
 */
void VectorProcessing(int32_T NumIters, const real_T rtu_In1[10], real_T
                      rty_Out1[10], DW_VectorProcessing_T localDW[10])
{
  /* local scratch DWork variables */
  int32_T ForEach_itr;
  real_T rtb_Out1_CoreSubsysCanOut;

The function has an input parameter NumIters that indicates the number of independent scalars that each For Each Subsystem block processes. This function is called three times in the ForEachReuse.c with the parameter NumIters set to 10, 8, and 7 respectively.

The code generator also generates a single output function for Matrix SS1 and Matrix SS2 subsystem in MatrixProcessing.c which is called twice in the ForEachReuse.c.

file = fullfile('ForEachReuse_grt_rtw','MatrixProcessing.c');
coder.example.extractLines(file,'* Output and update for iterator system:','/* Outputs for Iterator SubSystem:',1,1);
bdclose(model)
bdclose('ForEachReuse/Vector SS3')
 * Output and update for iterator system:
 *    '<Root>/Matrix SS1'
 *    '<Root>/Matrix SS2'
 */
void MatrixProcessing(int32_T NumIters, const real_T rtu_In1[32], real_T
                      rty_Out1[32], DW_MatrixProcessing_T localDW[2])
{
  /* local scratch DWork variables */
  int32_T ForEach_itr;
  real_T rtb_MathFunction_h_0;
  int32_T i;
  int32_T rtb_MathFunction_h_tmp;
  int32_T tmp;

See Also

Related Topics