Skip to content

Commit 0acd2af

Browse files
committed
WIP: working callbacks
1 parent 8ab7929 commit 0acd2af

16 files changed

Lines changed: 345 additions & 17 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,15 @@ jobs:
4747
run: |
4848
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/c/example_expcone
4949
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/c/example_lp
50+
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/c/example_callback
5051
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/c/example_powcone
5152
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/c/example_genpowcone
5253
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/c/example_qp
5354
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/c/example_socp
5455
5556
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/cpp/cpp_example_expcone
5657
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/cpp/cpp_example_lp
58+
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/cpp/cpp_example_callback
5759
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/cpp/cpp_example_powcone
5860
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/cpp/cpp_example_genpowcone
5961
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --error-exitcode=1 ./examples/cpp/cpp_example_qp

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ CMakePresets.json
1919
examples/cpp/*
2020
examples/c/*
2121
!examples/c/*.c
22-
!examples/cpp/*.cpp
22+
!examples/cpp/*.cpp
23+
!examples/c/CMakeLists.txt
24+
!examples/cpp/CMakeLists.txt

examples/c/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ set(C_EXAMPLES
1111
example_sdp
1212
example_json
1313
example_print_stream
14+
example_callback
1415
)
1516

1617
# Compile utils.c as a library

examples/c/example_callback.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include "utils.h"
2+
#include <stdio.h>
3+
#include <Clarabel.h>
4+
5+
6+
int custom_callback(ClarabelDefaultInfo *info)
7+
{
8+
// This function is called at each iteration of the solver.
9+
// You can use it to monitor the progress of the solver or
10+
// to implement custom stopping criteria.
11+
12+
// For example, we can print the current iteration number:
13+
printf("Custom callback at iteration %d: ", info->iterations);
14+
15+
// Return 0 to continue. Anything else to stop.
16+
if (info->iterations < 3) {
17+
printf("tick\n");
18+
return 0; //continue
19+
}
20+
else {
21+
printf("BOOM!\n");
22+
return 1; // stop
23+
}
24+
25+
}
26+
27+
int main(void)
28+
{
29+
// 2 x 2 zero matrix
30+
ClarabelCscMatrix P;
31+
clarabel_CscMatrix_init(
32+
&P,
33+
2, // row
34+
2, // col
35+
(uintptr_t[]){ 0, 0, 0 }, // colptr
36+
NULL, // rowval
37+
NULL // nzval
38+
);
39+
40+
ClarabelFloat q[2] = { 1.0, -1.0 };
41+
42+
// a 2-d box constraint, separated into 4 inequalities.
43+
// A = [I; -I]
44+
ClarabelCscMatrix A;
45+
clarabel_CscMatrix_init(
46+
&A,
47+
4, // row
48+
2, // col
49+
(uintptr_t[]){ 0, 2, 4 }, // colptr
50+
(uintptr_t[]){ 0, 2, 1, 3 }, // rowval
51+
(ClarabelFloat[]){ 1.0, -1.0, 1.0, -1.0 } // nzval
52+
);
53+
54+
ClarabelFloat b[4] = { 1.0, 1.0, 1.0, 1.0 };
55+
56+
ClarabelSupportedConeT cones[1] = { ClarabelNonnegativeConeT(4) };
57+
58+
// Settings
59+
ClarabelDefaultSettings settings = clarabel_DefaultSettings_default();
60+
settings.equilibrate_enable = true;
61+
settings.equilibrate_max_iter = 50;
62+
63+
// Build solver
64+
ClarabelDefaultSolver *solver = clarabel_DefaultSolver_new(
65+
&P, // P
66+
q, // q
67+
&A, // A
68+
b, // b
69+
1, // n_cones
70+
cones, &settings
71+
);
72+
73+
// configure a custom callback function
74+
clarabel_DefaultSolver_set_termination_callback(solver,custom_callback);
75+
76+
// Solve
77+
clarabel_DefaultSolver_solve(solver);
78+
79+
// turn off the callback
80+
clarabel_DefaultSolver_unset_termination_callback(solver);
81+
82+
// Solve again
83+
clarabel_DefaultSolver_solve(solver);
84+
85+
// Get solution
86+
ClarabelDefaultSolution solution = clarabel_DefaultSolver_solution(solver);
87+
print_solution(&solution);
88+
89+
// Free the solver
90+
clarabel_DefaultSolver_free(solver);
91+
92+
return 0;
93+
}
94+

examples/cpp/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ set(CPP_EXAMPLES
1010
example_faer
1111
example_json
1212
example_print_stream
13+
example_callback
1314
)
1415

1516
# Define an executable target for each example

examples/cpp/example_callback.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#include "utils.h"
2+
3+
#include <Clarabel>
4+
#include <Eigen/Eigen>
5+
#include <vector>
6+
7+
using namespace clarabel;
8+
using namespace std;
9+
using namespace Eigen;
10+
11+
int custom_callback(DefaultInfo<double> &info)
12+
{
13+
// This function is called at each iteration of the solver.
14+
// You can use it to monitor the progress of the solver or
15+
// to implement custom stopping criteria.
16+
17+
// For example, we can print the current iteration number:
18+
printf("Custom callback at iteration %d: ", info.iterations);
19+
20+
// Return 0 to continue. Anything else to stop.
21+
if (info.iterations < 3) {
22+
printf("tick\n");
23+
return 0; //continue
24+
}
25+
else {
26+
printf("BOOM!\n");
27+
return 1; // stop
28+
}
29+
}
30+
31+
32+
int main()
33+
{
34+
MatrixXd P_dense = MatrixXd::Zero(2, 2);
35+
SparseMatrix<double> P = P_dense.sparseView();
36+
P.makeCompressed();
37+
38+
Vector<double, 2> q = {1.0, -1.0};
39+
40+
// a 2-d box constraint, separated into 4 inequalities.
41+
// A = [I; -I]
42+
MatrixXd A_dense(4, 2);
43+
A_dense <<
44+
1., 0.,
45+
0., 1.,
46+
-1., 0.,
47+
0., -1.;
48+
49+
SparseMatrix<double> A = A_dense.sparseView();
50+
A.makeCompressed();
51+
52+
Vector<double, 4> b = { 1.0, 1.0, 1.0, 1.0 };
53+
54+
vector<SupportedConeT<double>> cones
55+
{
56+
NonnegativeConeT<double>(4),
57+
// {.tag = SupportedConeT<double>::Tag::NonnegativeConeT, .nonnegative_cone_t = {._0 = 4 }}
58+
};
59+
60+
// Settings
61+
DefaultSettings<double> settings = DefaultSettingsBuilder<double>::default_settings()
62+
.equilibrate_enable(true)
63+
.equilibrate_max_iter(50)
64+
.build();
65+
66+
// Build solver
67+
DefaultSolver<double> solver(P, q, A, b, cones, settings);
68+
69+
// configure a custom callback function
70+
solver.set_termination_callback(custom_callback);
71+
72+
// Solve
73+
solver.solve();
74+
75+
// turn off the callback
76+
solver.unset_termination_callback();
77+
78+
// Solve again
79+
solver.solve();
80+
81+
82+
// Get solution
83+
DefaultSolution<double> solution = solver.solution();
84+
utils::print_solution(solution);
85+
86+
return 0;
87+
}

include/c/DefaultSettings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ typedef ClarabelDefaultSettings_f32 ClarabelDefaultSettings;
130130
typedef ClarabelDefaultSettings_f64 ClarabelDefaultSettings;
131131
#endif
132132

133+
133134
// ClarabelDefaultSettings APIs
134135

135136
// ClarabelDefaultSettings::default

include/c/DefaultSolution.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
typedef enum ClarabelSolverStatus
1111
{
12-
ClarabelUnsolved,
12+
ClarabelUnsolved = 0,
1313
ClarabelSolved,
1414
ClarabelPrimalInfeasible,
1515
ClarabelDualInfeasible,
@@ -20,6 +20,7 @@ typedef enum ClarabelSolverStatus
2020
ClarabelMaxTime,
2121
ClarabelNumericalError,
2222
ClarabelInsufficientProgress,
23+
ClarabelCallbackTerminated,
2324
} ClarabelSolverStatus;
2425

2526
typedef struct ClarabelDefaultSolution_f64

include/c/DefaultSolver.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,40 @@ static inline ClarabelDefaultInfo clarabel_DefaultSolver_info(ClarabelDefaultSol
211211
#endif
212212
}
213213

214+
// DefaultSolver callbacks
215+
typedef int (*ClarabelCallbackFcn_f32)(ClarabelDefaultInfo_f32 *info);
216+
typedef int (*ClarabelCallbackFcn_f64)(ClarabelDefaultInfo_f64 *info);
217+
218+
#ifdef CLARABEL_USE_FLOAT
219+
typedef ClarabelCallbackFcn_f32 ClarabelCallbackFcn;
220+
#else
221+
typedef ClarabelCallbackFcn_f64 ClarabelCallbackFcn;
222+
#endif
223+
224+
void clarabel_DefaultSolver_f64_set_termination_callback(ClarabelDefaultSolver_f64 *solver, ClarabelCallbackFcn_f64 callback);
225+
void clarabel_DefaultSolver_f32_set_termination_callback(ClarabelDefaultSolver_f32 *solver, ClarabelCallbackFcn_f32 callback);
226+
227+
static inline void clarabel_DefaultSolver_set_termination_callback(ClarabelDefaultSolver *solver, ClarabelCallbackFcn callback)
228+
{
229+
#ifdef CLARABEL_USE_FLOAT
230+
clarabel_DefaultSolver_f32_set_termination_callback(solver,callback);
231+
#else
232+
clarabel_DefaultSolver_f64_set_termination_callback(solver,callback);
233+
#endif
234+
}
235+
236+
void clarabel_DefaultSolver_f64_unset_termination_callback(ClarabelDefaultSolver_f64 *solver);
237+
void clarabel_DefaultSolver_f32_unset_termination_callback(ClarabelDefaultSolver_f32 *solver);
238+
239+
static inline void clarabel_DefaultSolver_unset_termination_callback(ClarabelDefaultSolver *solver )
240+
{
241+
#ifdef CLARABEL_USE_FLOAT
242+
clarabel_DefaultSolver_f32_unset_termination_callback(solver);
243+
#else
244+
clarabel_DefaultSolver_f64_unset_termination_callback(solver);
245+
#endif
246+
}
247+
214248

215249
////// P data updating
216250

include/cpp/DefaultSolution.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ enum class SolverStatus
2020
MaxTime,
2121
NumericalError,
2222
InsufficientProgress,
23+
CallbackTerminated,
2324
};
2425

2526
template<typename T = double>

0 commit comments

Comments
 (0)