MATLAB Production Server C Client
R2021b
component: mds_c_client, module directory: deployment_server/client/c/mps, copyright: MathWorks
|
MATLAB Production Server is a client-server framework created by MathWorks for deploying MATLAB code in scalable and robust manner. The server hosts one or more deployable archives, each exporting one or more MATLAB functions. These MATLAB functions can be invoked from a C/C++ application using the MATLAB Production Server C client API. The client sends request with all the information required to invoke the MATLAB function and receives the result in the response. The server instance may be running on the same machine as the client or on a remote machine.
The following example demonstrates how MATLAB Production Server can be used to create a scalable MATLAB application.
This example deploys a simple MATLAB function to a MATLAB Production Server instance and creates a C application that accesses it:
NOTE
For the sake of simplicity, we will assume that the client and server are running on the same machine. We will also assume that MATLAB and MATLAB Compiler are installed on this machine.
Create a simple MATLAB function, mymagic
, that takes a single double
input and returns a magic square as a 2-D double
array:
function m = mymagic(in) m = magic(in); end
Compile the MATLAB function into a deployable archive as follows:
magic
with Deployable Archive as the target.mymagic
, to this project.magic.ctf
in the magic/for_redistribution_files_only
directory.Note
For this example the MATLAB Production Server is installed in
$MPS_INSTALL
directory and$MPS_INSTALL/script
is on the system path. The directory where we want to create the MATLAB Production Server instance is/tmp/mpsInst1
.
Note
The paths used in the instructions are for Linux.
Before you can start a MATLAB Production Server instance, you must create it:
mps-setup
to configure the MATLAB Compiler Runtime the server instance will use./tmp/mpsInst1
. Note
The directory
/tmp/mpsInst1
must not exist before entering the following command.
Verify the configuration of a MATLAB Production Server instance by editing /tmp/mpsInst1/config/main.config
.
This file has the default configuration parameters when a MATLAB Production Server instance is created for the first time.
Start the server instance:
mps-start
command. 9910
for client requests. This can be verified in the /tmp/mpsInst1/endpoint/http
file: mps-status
command: Once the MATLAB Production Server instance is started, you need to deploy the deployable archive to it. To deploy the deployable archive, magic.ctf
, copy it to the /tmp/mpsInst1/auto_deploy
folder of the server instance.
Now, it is available to the MATLAB Production Server C client API at URL: http://localhost:9910/magic/mymagic
.
The format of the URL is: <host_name>:<port_number>/<archive_file_name_without_extension>/<function_name>
Note
The header files for the MATLAB Production Server C client API are located in the
$MPS_INSTALL/client/c/include/mps
folder where$MPS_INSTALL
is the root folder which MATLAB Production Server is installed.
Before you can call the method representing the MATLAB function, you must:
To call the MATLAB function use the mpsClientRuntime
feval()
function.
Before you can access the data returned from the MATLAB function, you must:
mpsArray
validation API to determine the type of data returned.To compile your client code, the compiler needs access to client.h
. This is stored in $MPSROOT/client/c/include/mps/
.
To link your application, the linker needs access to:
Windows | UNIX/Linux | Mac OSX |
---|---|---|
$C_CLIENT\$arch\lib\mpsclient.lib | $C_CLIENT/$arch/lib/libprotobuf.so | $C_CLIENT/$arch/lib/libprotobuf.dylib |
$C_CLIENT/$arch/lib/libcurl.so | $C_CLIENT/$arch/lib/libcurl.dylib | |
$C_CLIENT/$arch/lib/libmwmpsclient.so | $C_CLIENT/$arch/lib/libmwmpsclient.dylib | |
$C_CLIENT/$arch/lib/libmwcpp11compat.so |
Where $C_CLIENT
is $MPSROOT\client\c\
.
To run your client the following libraries need to be on your system path:
Windows | UNIX/Linux | Mac OSX |
---|---|---|
$C_CLIENT/$arch/lib/libprotobuf.dll | $C_CLIENT/$arch/lib/libprotobuf.so | $C_CLIENT/$arch/lib/libprotobuf.dylib |
$C_CLIENT/$arch/lib/libcurl.dll | $C_CLIENT/$arch/lib/libcurl.so | $C_CLIENT/$arch/lib/libcurl.dylib |
$C_CLIENT/$arch/lib/mpsclient.dll | $C_CLIENT/$arch/lib/libmwmpsclient.so | $C_CLIENT/$arch/lib/libmwmpsclient.dylib |
$C_CLIENT/$arch/lib/libmwcpp11compat.so |
Where $C_CLIENT
is $MPSROOT\client\c\
.
The output should resemble:
You configure the client-server connection using a structure of type mpsClientConfig
. The structure has these fields:
responseTimeOut
- determines the amount of time, in milliseconds, the client waits for a response before timing out.reponseSizeLimit
- determines the maximum size, in bytes, of the response a client accepts.You can use methods provided by the mpsClientConfig
structure, to change the values before you create the client context.
When you create the client configuration using the runtime API createConfig()
function, it is populated with default values:
responseTimeOut
= 120000
reponseSizeLimit
= 64*1024*1024
(64 MB)To change the amount of time the client waits for a response use the setTimeOutSec()
function provided by the mpsClientRuntime
structure.
This code sample creates a client connection with a time out value of 1000 ms:
Tip
Setting the response time out to
0
specifies that the client will wait indefinitely for a response.
To change the amount of data a client will accept in a response use the setResponseSizeLimit()
function provided by the mpsClientRuntime
structure.
This code sample creates a client connection that accepts a maximum of 4 MB in a response:
The MATLAB Runtime works with a single object type: the MATLAB array. All MATLAB variables (including scalars, vectors, matrices, strings, cell arrays, structures, and objects) are stored as MATLAB arrays. In C/C++, the MATLAB array is declared to be of type mpsArray
. The mpsArray
structure contains the following information about the array:
To access the mpsArray
structure, use the mpsArray
API functions. These functions enable you to create, read, and query information about the MATLAB data used by the client. The mpsArray
API mirrors the mxArray
API used by MATLAB Compiler and MATLAB external interfaces.
MATLAB stores data in a column-major (columnwise) numbering scheme. MATLAB internally stores data elements from the first column first, then data elements from the second column second, and so on, through the last column.
For example, given the matrix:
its dimensions are:
and its data is stored as:
If a matrix is N-dimensional, MATLAB represents the data in N-major order. For example, consider a three-dimensional array having dimensions 4-by-2-by-3. Although you can visualize the data as:
MATLAB internally represents the data for this three-dimensional array in the following order:
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
Note
Unlike C indexing, MATLAB indexing starts at 1.
The mpsCalcSingleSubscript()
function creates the offset from the first element of an array to the desired element, using N-dimensional subscripting.
Complex double-precision, non-sparse matrices are of type double
and have dimensions m
-by-n
, where m
is the number of rows and n
is the number of columns. The data is stored as two vectors of double-precision numbers—one contains the real data and one contains the imaginary data. The pointers to this data are referred to as pr
(pointer to real data) and pi
(pointer to imaginary data), respectively. A non-complex matrix is one whose pi
is NULL
.
Numeric matrices are single-precision floating-point integers that can be 8-, 16-, 32-, and 64-bit, both signed and unsigned. The data is stored in two vectors in the same manner as double-precision matrices.
The logical
data type represents a logical true
or false
state using the numbers 1
and 0
, respectively. Certain MATLAB functions and operators return logical 1
or logical 0
to indicate whether a certain condition was found to be true or not. For example, the statement (5 * 10) > 40
returns a logical 1
value.
MATLAB strings are of type char
and are stored in a similar manner to unsigned 16-bit integers, except there is no imaginary data component. Unlike C, MATLAB strings are not null terminated.
Cell arrays are a collection of MATLAB arrays where each mpsArray
is referred to as a cell, enabling MATLAB arrays of different types to be stored together. Cell arrays are stored in a similar fashion to numeric matrices, except the data portion contains a single vector of pointers to mpsArrays
. Members of this vector are called cells. Each cell can be of any supported data type, even another cell array.
A 1-by-1 structure is stored in the same manner as a 1-by-n
cell array where n
is the number of fields in the structure. Members of the data vector are called fields. Each field is associated with a name stored in the mpsArray
.
A multidimensional array is a vector of integers where each element is the size of the corresponding dimension. The storage of the data is the same as matrices. MATLAB arrays of any type can be multidimensional.
An empty mpsArray
is one with at least one dimension equal to zero. For example, a double-precision mpsArray
of type double
, where m
and n
equal 0
and pr
is NULL
, is an empty array. MATLAB arrays of any type can be empty.
Sparse matrices have a different storage convention from that of full matrices in MATLAB. The parameters pr
and pi
are arrays of double-precision numbers, but these arrays contain only nonzero data elements. There are three additional parameters:
nzmax
is an integer that contains the length of ir
, pr
, and, if it exists, pi
. It is the maximum number of nonzero elements in the sparse matrix.ir
points to an integer array of length nzmax
containing the row indices of the corresponding elements in pr
and pi
.jc
points to an integer array of length n+1
, where n
is the number of columns in the sparse matrix. The jc
array contains column index information. If the jth column of the sparse matrix has any nonzero elements, jc[j]
is the index in ir
and pr
(and pi
if it exists) of the first nonzero element in the jth column, and jc[j+1] - 1
is the index of the last nonzero element in that column. For the jth column of the sparse matrix, jc[j]
is the total number of nonzero elements in all preceding columns. The last element of the jc
array, jc[n]
, is equal to nnz
, the number of nonzero elements in the entire sparse matrix. If nnz
is less than nzmax
, more nonzero entries can be inserted into the array without allocating more storage.You can write MATLAB Production Server client applications in C/C++ that accept any class or data type supported by MATLAB (see Data Types).
Caution
The MATLAB Runtime does not check the validity of MATLAB data structures created in C/C++. Using invalid syntax to create a MATLAB data structure can result in unexpected behaviour.
To handle MATLAB arrays, use type mpsArray
. The following statement declares an mpsArray
named myData
:
To define the values of myData
, use one of the mpsCreate*
functions. Some useful array creation routines are mpsCreateNumericArray()
, mpsCreateCellArray()
, and mpsCreateCharArray()
. For example, the following statement allocates an m
-by-1 floating-point mpsArray
initialized to 0:
C/C++ programmers should note that data in a MATLAB array is in column-major order. (For an illustration, see Data Storage.) Use the MATLAB mpsGet*
array access routines to read data from an mpsArray
.
The mpsGet*
array access routines get references to the data in an mpsArray
. Use these routines to modify data in your client application. Each function provides access to specific information in the mpsArray.
Some useful functions are mpsGetData()
, mpsGetPr()
, mpsGetM()
, and mpsGetString()
.
The following statements read the input string prhs[0]
into a C-style string buf
:
To handle errors that occur when processing MATLAB functions:
getLastErrorInfo()
.destroyLastErrorInfo()
.Many of the mpsClientRuntime
functions return a value of type mpsStatus
.
A return value of MPS_OK
indicates that the function processed successfully.
A return value of MPS_FAILURE
indicates that an error occurred.
For example, to check if an error occurred while evaluating a MATLAB function, use an if-then
statement:
Note
Only the
feval()
function returns more details about the error.
If a call to feval()
returns a value of MPS_FAILURE
, you can determine the error by calling the getLastErrorInfo()
function. It returns an mpsErrorInfo
structure that contains these fields:
message
- String containing general information about the errortype
- Character identifying the type of error. The type identifier is used to select the correct data type for the detailed error information.details
- Structure containing details, such as the MATLAB stack, about the error and its underlying causeTo get the error information and print the basic error message:
Before you can process the detailed error information, you need to determine what type of error occurred. This is done by interrogating the type
field of the mpsErrorInfo
structure. It can have one of three values:
MPS_HTTP_ERROR_INFO
- Non-200 HTTP error occurred and the details are stored in an mpsErrorInfoHTTP
structureMPS_MATLAB_ERROR_INFO
- MATLAB error occurred and the details are stored in an mpsErrorInfoMATLAB
structureMPS_GENERIC_ERROR_INFO
- Indeterminate error occurred and the details are stored in an mpsErrorInfoGeneric
structureOnce you determine the type of error, you can process the detailed information.
To determine the error type using a switch
statement:
The details of an HTTP error are stored in an mpsErrorInfoHTTP
structure. This structure has two fields:
responseCode
- HTTP error coderesponseMessage
- String containing the message returned with the errorFor example, if you attempt to access a function using an invalid URL, the client may return an mpsErrorInfoHTTP
structure with the following values:
responseCode
- 404responseMessage
- Not FoundIf the error occurred while the MATLAB Runtime was evaluating the function the client returns an mpsErrorInfoMATLAB
structure. This structure has the following fields:
message
- Error message returned by the MATLAB Runtimeidentifier
- MATLAB error IDmatlabStack
- MATLAB Runtime stackmatlabStackDepth
- Number of entries in the MATLAB Runtime stackThe entries in the MATLAB Runtime stack have the following fields:
file
- Name of the MATLAB file that caused the errorfunction
- Name of the MATLAB function that caused the errorline
- Line number in the MATLAB file that caused the errorTo print the contents of a MATLAB error:
If an error other than a non-200 HTTP response or a MATLAB Runtime exception occurs, the client returns an mpsErrorInfoGeneric
structure containing a genericErrorMessage
field.
The following MATLAB Production Server client artefacts have special clean up functions to release the resources when you are finished with them:
You can clean up the client configuration any time after it is used to create the client context. The context copies the required configuration values when it is created.
To clean up the client configuration, use the mpsClientRuntime
destroyConfig()
function with a pointer to the client configuration data.
The client context encapsulates the connection framework between the client and a server instance. It is required to evaluate MATLAB functions. The context also performs a number of tasks to optimize the connections to server instances.
The client context should not be cleaned up until the client is done evaluating MATLAB functions using MATLAB Production Server.
To clean up the client context use the mpsClientRuntime
destroyContext()
function with a pointer to the client context data.
When you are finished using the MATLAB Production Server client API, you clean up the runtime resources using the mpsTerminate()
function.
Note
mpsTerminate()
does not clean up the client context or the client configuration. They must be cleaned up before callingmpsTerminate()
.
MATLAB arrays stored in mpsArray
variables are opaque. They contain a number of fields used to marshal data between your C client code and the MATLAB Runtime. Variables containing MATLAB arrays can be large.
Clean up variables containing MATLAB arrays using the mpsDestroyArray()
function. mpsDestroyArray()
takes a pointer to the MATLAB array being cleaned-up. It frees all of the memory used by the array.
Note
When cleaning up the arrays used as inputs and outputs of an
feval()
call, you must clean up all of the MATLAB arrays contained in the array before you destroy the MATLAB array pointing to the inputs or outputs.
Clean up the data used in an feval()
call.
The error information created by the MATLAB Production Server client runtime is opaque. Once you have processed the error, clean up the resources used by the error using the mpsClientRuntime
destroyLastErrorInfo()
function. It takes a pointer to the error information returned from getLastErrorInfo()
.