C/C++ Deployment
This section describes how to deploy generated code in a C/C++ environment.
Include the generated source files and link the dynamic or static library to call the generated code. Note the following when calling the generated code:
- The calling platform and compiler must be consistent with the option.platform setting during code generation
- When the calling platform is Linux/Mac, you need to link the math library (-lm) to use functions such as sin, cos, tan, sqrt
- When the calling platform is Windows, you need to link iphlpapi (-liphlpapi, or add iphlpapi.lib in Visual Studio) to obtain MAC address and other information
Using vehicle as an example, assuming platform is 'linux-x86_64-gcc' and lib_type is 'static', the code directory structure is as follows:
working_dir/
├── vehicle/
│ ├── vehicle_prob.c
│ ├── vehicle_prob.h
│ ├── vehicle_solver.h
│ ├── libvehicle_solver_static.a
├── vehicle_demo.cpp
.
Compilation and Execution
Using CMake
Below is a CMake snippet for compiling a demo (vehicle_demo.cpp) using the static library:
# ${VEHICLE_CODEGEN_DIR} is the dir of the generated code
set(VEHICLE_CODEGEN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vehicle)
# ${LIBS} is the required libs (math or iphlpapi)
set(LIBS m)
add_executable(vehicle_demo vehicle_demo.cpp ${VEHICLE_CODEGEN_DIR}/vehicle_prob.c)
target_include_directories(vehicle_demo PRIVATE ${VEHICLE_CODEGEN_DIR})
target_link_libraries(vehicle_demo ${VEHICLE_CODEGEN_DIR}/libvehicle_solver_static.a ${LIBS})
Command Line
Below is a command line example for compiling with g++:
g++ -o vehicle_demo vehicle_demo.cpp vehicle/vehicle_prob.c -I./vehicle -L./vehicle -lvehicle_solver_static -lm
After compilation is complete, run the generated executable.
./vehicle_demo
Visual Studio
When using Visual Studio, you need to set the platform to windows-x86_64-msvc for code generation.
Below are the steps to deploy the generated code in Visual Studio.
Create a new C++ project in Visual Studio, add the generated source file (vehicle_prob.c) and demo file (vehicle_demo.cpp) to the project, then configure the following settings in the project properties:
- In "C/C++ > General > Additional Include Directories", add the generated code directory (vehicle/)
- In "Linker > General > Additional Library Directories", add the generated code directory (vehicle/)
- In "Linker > Input > Additional Dependencies", add the generated static library filename (libvehicle_solver_static.lib)
- In "Linker > Input > Additional Dependencies", add
iphlpapi.lib
Then you can compile and run the project.
Multi-threaded Deployment
When multiple problems need to be solved simultaneously, multi-threading can be used to accelerate solving.
An independent workspace and output must be allocated for each thread; otherwise, data races will occur.
Below is a code snippet example using OpenMP for parallel solving (NUM_PROBS is the number of problems):
...
#pragma omp parallel for
for (int worker = 0; worker < NUM_PROBS; worker++) {
ws[worker].thread_id = worker;
vehicle_solve(&prob[worker], &option, &ws[worker], &output[worker]);
}
...
Here we use thread_id to identify each thread. This value is passed to the function parameters of prob and can be accessed via _solverinfo->thread_id:
void vehicle_l(const Vehicle_SolverInfo *_solverinfo, ...)
{
...
int thread_id = _solverinfo->thread_id;
...
}
This value is not required, but when using multi-threading, it can be used to distinguish different threads.
For example, when the optimization problem functions are user-defined external functions, this value can be used to distinguish different threads to avoid data races.