%% Optimize Generated Code By Developing and Using Code Replacement Libraries - MATLAB®
% Develop and use code replacement libraries to replace function and operators in generated code. Code replacement is a technique to change the code that the code generator produces for functions and operators to meet application code requirements. For example, you can replace generated code to meet requirements such as:
% Optimization for a specific run-time environment, including, but not limited to, specific target hardware
% Integration with existing application code
% Compliance with a standard, such as AUTOSAR
% Modification of code behavior, such as enabling or disabling nonfinite or inline support
% Application- or project-specific code requirements, such as use of BLAS or elimination of math.h, system header files, or calls to memcpy or memset.
% You can configure the code generator to use a code replacement library that MathWorks® provides. If you have an Embedded Coder® license, you can develop your own code replacement library interactively with the Code Replacement Tool or programmatically.
% This example provides MATLAB® code that shows a variety of ways you can define code replacement mappings. With each example MATLAB® function, the example provides MATLAB® files that illustrate how to develop function and operator code replacements programmatically.
% Additional Requirements:
% MATLAB Coder
% Embedded Coder
% Fixed-Point Designer
% For more information, see docid:ecoder_ug.bujlgeg-2 and docid:ecoder_ug.bujlgeh-7.
%% Create a New Folder and Copy Relevant Files
% The following code creates a sub folder in your current working folder (pwd). The new folder contains files that are relevant for this example.

currentDir = pwd;
[~,cgDir] = rtwdemodir();
coderdemo_setup('coderdemo_crl');

%
%% Steps for Developing a Code Replacement Library
% Identify your code replacement requirements with respect to function or operating mappings, build information, and registration information.
% Prepare for code replacement library development (for example, identify or develop models to test your library).
% Define code replacement mappings.
% Specify build information for replacement code.
% Register code replacement mappings.
% Verify code replacements.
% Deploy the library.
% For more information, see docid:ecoder_ug.bujlgeh-7.
%% Math Function Replacement
% This example defines and registers code replacement mappings for math functions. You can define code replacement mappings for a variety of functions. For details, see docid:ecoder_ug.buicawx.
% 1. Open and explore the MATLAB® file for this example.

edit(fullfile(matlabroot,'toolbox','coder','codegendemos','coderdemo_crl','replace_math_fcns.m'))

%
% 2. Configure the code generator to use the code replacement library Function Replacement Examples.

RTW.TargetRegistry.getInstance('reset');
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'Function Replacement Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

%
% 3. Set up the configuration parameters to build and define the function input type.

t = single(2); 

%
% 4. Explore the code replacement table definition file.

edit(fullfile(matlabroot,'toolbox','coder','codegendemos','coderdemo_crl','crl_table_functions.m'))

%
% 5. Compile the MATLAB® program into a C source file by using the configuration parameters that point to the code replacement library and the example input class defined in step 3 as input parameters to the codegen command.

codegen('replace_math_fcns', '-config', cfg, '-args', {t, t});

%
% 6. Open the file replace_math_fcns.c and explore the generated source code.

open(fullfile('codegen','lib','replace_math_fcns','replace_math_fcns.c'))

% 7. Close replace_math_fcns.m.
% For more information on math function replacement, see docid:ecoder_ug.mw_cc21b447-4de6-4118-bd61-17a1e68a2d2c.
%
%% Addition and Subtraction Operator Replacement
% This example shows how to define and register code replacement mappings for addition (+) and subtraction (-) operations. When defining entries for addition and subtraction operations, you can specify which of the following algorithms (EntryInfoAlgorithm) your library functions implement:
% Cast-before-operation (CBO) (RTW_CAST_BEFORE_OP), the default
% Cast-after-operation (CAO) (RTW_CAST_AFTER_OP)
% 1. Open and explore the MATLAB® file for this example.

edit(fullfile(matlabroot,'toolbox','coder','codegendemos','coderdemo_crl','addsub_two_int16.m'))
%
% CBO, the default algorithm, is assumed.

%
% 2. Configure the code generator to use a code replacement library Addition & Subtraction Examples.

RTW.TargetRegistry.getInstance('reset');
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'Addition & Subtraction Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

%
% 3. Set up the configuration parameters to build and define the operation input type.

t = int16(2); 

%
% 4. Explore the code replacement table definition file.

edit(fullfile(matlabroot,'toolbox','coder','codegendemos','coderdemo_crl','crl_table_addsub.m'))

%
% 5. Compile the MATLAB® program into a C source file by using the configuration parameters that point to the desired code replacement library and the example input class defined in step 3 as input parameters to the codegen command.

codegen('addsub_two_int16','-config', cfg, '-args', {t, t});

%
% 6. Open the file addsub_two_int16.c and explore the generated source code.

open(fullfile('codegen','lib','addsub_two_int16','addsub_two_int16.c'))

% 7. Close addsub_two_int16.m.
% For more information on addition and subtraction operator replacement, see docid:ecoder_ug.bujlgeh-84 and docid:ecoder_ug.mw_5328b1d9-4fce-4127-8f0c-96fd92b2d0dc.
%
%% Matrix Operator Replacement
% This example defines and registers code replacement mappings for matrix operations: addition, subtraction, multiplication, transposition, conjugate, and Hermitian.
% Supported types include:
% single, double
% int8, uint8
% int16, uint16
% int32, uint32
% csingle, cdouble
% cint8, cuint8
% cint16, cuint16
% cint32, cuint32
% fixed-point integers
% mixed types (different type on each input)
% 1. Open and explore the MATLAB® file for this example:

edit(fullfile(matlabroot,'toolbox','coder','codegendemos','coderdemo_crl','replace_matrix_ops.m'))

%
% 2. Configure the code generator to use a code replacement library Matrix Op Replacement Examples.

RTW.TargetRegistry.getInstance('reset');
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'Matrix Op Replacement Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

%
% 3. Set up the configuration parameters to build and define the operation input type.

t = [1.0 2.0; 3.0, 4.0]; 

%
% 4. Explore the code replacement table definition file.

edit(fullfile(matlabroot,'toolbox','coder','codegendemos','coderdemo_crl','crl_table_matops.m'))

%
% 5. Compile the MATLAB® program using the configuration parameters that point to the desired code replacement library and the example input class defined in step 3 as input parameters to the codegen command.

codegen('replace_matrix_ops', '-config', cfg, '-args', {t, t});

%
% 6. Open the file replace_matrix_ops.c and explore the generated source code.

open(fullfile('codegen','lib','replace_matrix_ops','replace_matrix_ops.c'))

% 7. Close replace_matrix_ops.m.
% For more information on matrix operator replacement, see docid:ecoder_ug.mw_9d18bfa1-beb4-48eb-b657-ffd9ac16c44c.
%
%% Matrix Multiplication Replacement for BLAS
% This example defines and registers code replacement mappings for Basic Linear Algebra Subroutines (BLAS) subroutines xGEMM and xGEMV. You can map the following operations to a BLAS subroutine:
% Matrix multiplication
% Matrix multiplication with transpose on single or both inputs
% Matrix multiplication with Hermitian operation on single or both inputs
% 1. Open and explore the MATLAB® file for this example.

edit(fullfile(matlabroot,'toolbox','coder','codegendemos','coderdemo_crl','replace_matrix_ops_blas.m'))

%
% 2. Configure the code generator to use a code replacement library BLAS Replacement Examples.

RTW.TargetRegistry.getInstance('reset');
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'BLAS Replacement Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

%
% 3. Set up the configuration parameters to build and define the function input type.

t = [1.0 2.0 3.0; 4.0 5.0 6.0; 7.0 8.0 9.0]; 

%
% 4. Explore the code replacement table definition file.

edit(fullfile(matlabroot,'toolbox','coder','codegendemos','coderdemo_crl','crl_table_blas.m'))

%
% 5. Compile the MATLAB® program using the configuration parameters that point to the desired code replacement library and the example input class defined in step 3 as input parameters to the codegen command.

codegen('replace_matrix_ops_blas', '-config', cfg, '-args', {t, t});

%
% 6. Open the file replace_matrix_ops_blas.c and explore the generated source code.

open(fullfile('codegen','lib','replace_matrix_ops_blas','replace_matrix_ops_blas.c'))

% 7. Close replace_matrix_ops_blas.m.
% For more information on matrix multiplication replacement for BLAS, see docid:ecoder_ug.mw_8a45ace4-0903-46ee-9cf8-c163f477482a.
%
%% MATLAB Function Replacement Using Coder.Replace
% Code replacement libraries support the replacement of MATLAB® functions with scalar and matrix inputs and outputs for built-in, complex, and fixed-point data types.
% 1. Open and explore the MATLAB® file for this example.

edit(fullfile(matlabroot,'toolbox','coder','codegendemos','coderdemo_crl','coder_replace_fcn.m'))

%
% 2. Configure the code generator to use a code replacement library Coder Replace Examples.

RTW.TargetRegistry.getInstance('reset');
cfg = coder.config('lib','ecoder',true);
cfg.CodeReplacementLibrary = 'Coder Replace Examples';
cfg.GenerateReport = false;
cfg.LaunchReport = false;

%
% 3. Set up the configuration parameters to build and define the function input type.

t = [1 2; 3 4];

%
% 4. Explore the code replacement table definition file.

edit(fullfile(matlabroot,'toolbox','coder','codegendemos','coderdemo_crl','crl_table_coder_replace.m'))

%
% 5. Compile the MATLAB® program using the configuration parameters that point to the desired code replacement library and the example input class defined in step 3 as input parameters to the codegen command.

codegen('coder_replace_fcn', '-config', cfg, '-args', {t, t});

%
% 6. Open the file coder_replace_fcn.c and explore the generated source code.

open(fullfile('codegen','lib','coder_replace_fcn','coder_replace_fcn.c'))

% 7. Close coder_replace_fcn.m.
% For more information, see docid:ecoder_ug.mw_ab7cd3a5-076f-40e4-b8a9-d3357993c100.
%
%% Build Information
% For each entry in a code replacement table, you can specify build information such as the following, for replacement functions:
% Header file dependencies
% Source file dependencies
% Additional include paths
% Additional source paths
% Additional link flags
% Additionally, you can specify RTW.copyFileToBuildDir to copy header, source, or object files, which are required to generate replacement code, to the build folder before code generation. You can specify RTW.copyFileToBuildDir by setting it as the value of:
% Property GenCallback in a call to  setTflCFunctionEntryParameters, setTflCOperationEntryParameters, or setTflCSemaphoreEntryParameters.
% Argument genCallback in a call to registerCFunctionEntry,  registerCOperationEntry, or registerCSemaphoreEntry.
% Note: Models in this example are configured for code generation only because the implementations for the replacement functions are not provided.
% For more information on specifying build information for replacement code, see docid:ecoder_ug.bujlgeh-7.
%% Cleanup
% Remove files and return to original folder

RTW.TargetRegistry.getInstance('reset');
rtwdemoclean;
clear coderdemo_crl
cd ../

% Copyright 2010-2015 The MathWorks, Inc.