Skip to content

Commit

Permalink
Wrapper updates to rust v0.8.1 (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
goulart-paul authored May 31, 2024
1 parent dc2d78a commit ba7ec3e
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 12 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.13)

# Project properties
set(CLARABEL_PROJECT_VERSION 0.5.1)
set(CLARABEL_PROJECT_VERSION 0.8.0)
project(Clarabel VERSION ${CLARABEL_PROJECT_VERSION})

# Specify the default C++ standard applied to all targets
Expand Down
2 changes: 1 addition & 1 deletion Clarabel.rs
Submodule Clarabel.rs updated 111 files
21 changes: 21 additions & 0 deletions include/c/DefaultSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ typedef enum ClarabelDirectSolveMethods
// CHOLMOD, (not supported in Rust yet)
} ClarabelDirectSolveMethods;

#ifdef FEATURE_SDP
typedef enum ClarabelCliqueMergeMethods
{
CLIQUE_GRAPH,
PARENT_CHILD,
NONE,
} ClarabelCliqueMergeMethods;
#endif

typedef struct ClarabelDefaultSettings_f64
{
uint32_t max_iter;
Expand Down Expand Up @@ -54,6 +63,12 @@ typedef struct ClarabelDefaultSettings_f64
uint32_t iterative_refinement_max_iter;
double iterative_refinement_stop_ratio;
bool presolve_enable;
#ifdef FEATURE_SDP
bool chordal_decomposition_enable;
ClarabelCliqueMergeMethods chordal_decomposition_merge_method;
bool chordal_decomposition_compact;
bool chordal_decomposition_complete_dual;
#endif
} ClarabelDefaultSettings_f64;

typedef struct ClarabelDefaultSettings_f32
Expand Down Expand Up @@ -95,6 +110,12 @@ typedef struct ClarabelDefaultSettings_f32
uint32_t iterative_refinement_max_iter;
float iterative_refinement_stop_ratio;
bool presolve_enable;
#ifdef FEATURE_SDP
bool chordal_decomposition_enable;
enum ClarabelCliqueMergeMethods chordal_decomposition_merge_method;
bool chordal_decomposition_compact;
bool chordal_decomposition_complete_dual;
#endif
} ClarabelDefaultSettings_f32;

#ifdef CLARABEL_USE_FLOAT
Expand Down
43 changes: 43 additions & 0 deletions include/cpp/DefaultSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ enum class ClarabelDirectSolveMethods
// CHOLMOD, (not supported in Rust yet)
};

#ifdef FEATURE_SDP
enum class ClarabelCliqueMergeMethods
{
CLIQUE_GRAPH,
PARENT_CHILD,
NONE,
};
#endif

template<typename T = double>
struct DefaultSettings
{
Expand Down Expand Up @@ -55,6 +64,13 @@ struct DefaultSettings
uint32_t iterative_refinement_max_iter;
T iterative_refinement_stop_ratio;
bool presolve_enable;
#ifdef FEATURE_SDP
bool chordal_decomposition_enable;
ClarabelCliqueMergeMethods chordal_decomposition_merge_method;
bool chordal_decomposition_compact;
bool chordal_decomposition_complete_dual;
#endif


static DefaultSettings<T> default_settings();
};
Expand Down Expand Up @@ -298,6 +314,33 @@ class DefaultSettingsBuilder
settings.presolve_enable = presolve_enable;
return *this;
}

#ifdef FEATURE_SDP
DefaultSettingsBuilder<T> &chordal_decomposition_enable(bool chordal_decomposition_enable)
{
settings.chordal_decomposition_enable = chordal_decomposition_enable;
return *this;
}

DefaultSettingsBuilder<T> &chordal_decomposition_merge_method(ClarabelCliqueMergeMethods chordal_decomposition_merge_method)
{
settings.chordal_decomposition_merge_method = chordal_decomposition_merge_method;
return *this;
}

DefaultSettingsBuilder<T> &chordal_decomposition_compact(bool chordal_decomposition_compact)
{
settings.chordal_decomposition_compact = chordal_decomposition_compact;
return *this;
}

DefaultSettingsBuilder<T> &chordal_decomposition_complete_dual(bool chordal_decomposition_complete_dual)
{
settings.chordal_decomposition_complete_dual = chordal_decomposition_complete_dual;
return *this;
}
#endif

};

extern "C" {
Expand Down
38 changes: 38 additions & 0 deletions rust_wrapper/src/solver/implementations/default/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ pub enum ClarabelDirectSolveMethods {
// CHOLMOD, (not supported yet)
}

#[allow(non_camel_case_types)]
#[cfg(feature = "sdp")]
#[repr(C)]
pub enum ClarabelCliqueMergeMethods {
CLIQUE_GRAPH,
PARENT_CHILD,
NONE,
}

/// DefaultSettings struct used by the C side
#[repr(C)]
pub struct ClarabelDefaultSettings<T: FloatT> {
Expand Down Expand Up @@ -67,6 +76,17 @@ pub struct ClarabelDefaultSettings<T: FloatT> {

// preprocessing
pub presolve_enable: bool,

// chordal decomposition
#[cfg(feature = "sdp")]
pub chordal_decomposition_enable: bool,
#[cfg(feature = "sdp")]
pub chordal_decomposition_merge_method: ClarabelCliqueMergeMethods,
#[cfg(feature = "sdp")]
pub chordal_decomposition_compact: bool,
#[cfg(feature = "sdp")]
pub chordal_decomposition_complete_dual: bool,

}

/// Wrapper function for DefaultSettings::default()
Expand All @@ -75,13 +95,22 @@ pub struct ClarabelDefaultSettings<T: FloatT> {
#[allow(non_snake_case)]
fn _internal_DefaultSettings_default<T: FloatT>() -> ClarabelDefaultSettings<T> {
let default = clarabel::solver::DefaultSettings::<T>::default();

let default_direct_solver_setting = match default.direct_solve_method.as_str() {
"qdldl" => ClarabelDirectSolveMethods::QDLDL,
//"mkl" => ClarabelDirectSolveMethods::MKL,
//"cholmod" => ClarabelDirectSolveMethods::CHOLMOD,
_ => ClarabelDirectSolveMethods::QDLDL, // Default
};

#[cfg(feature = "sdp")]
let default_clique_merge_setting = match default.chordal_decomposition_merge_method.as_str() {
"clique_graph" => ClarabelCliqueMergeMethods::CLIQUE_GRAPH,
"parent_child" => ClarabelCliqueMergeMethods::PARENT_CHILD,
"none" => ClarabelCliqueMergeMethods::NONE,
_ => ClarabelCliqueMergeMethods::CLIQUE_GRAPH, // Default
};

// Assign all fields to the C struct
ClarabelDefaultSettings::<T> {
max_iter: default.max_iter,
Expand Down Expand Up @@ -121,6 +150,15 @@ fn _internal_DefaultSettings_default<T: FloatT>() -> ClarabelDefaultSettings<T>
iterative_refinement_max_iter: default.iterative_refinement_max_iter,
iterative_refinement_stop_ratio: default.iterative_refinement_stop_ratio,
presolve_enable: default.presolve_enable,
#[cfg(feature = "sdp")]
chordal_decomposition_enable: default.chordal_decomposition_enable,
#[cfg(feature = "sdp")]
chordal_decomposition_merge_method: default_clique_merge_setting,
#[cfg(feature = "sdp")]
chordal_decomposition_compact: default.chordal_decomposition_compact,
#[cfg(feature = "sdp")]
chordal_decomposition_complete_dual: default.chordal_decomposition_complete_dual,

}
}

Expand Down
29 changes: 21 additions & 8 deletions rust_wrapper/src/solver/implementations/default/solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,37 @@ unsafe fn _internal_DefaultSolver_new<T: FloatT>(
let P = utils::convert_from_C_CscMatrix(P);
let A = utils::convert_from_C_CscMatrix(A);
// Recover the arrays from C pointers and deduce their lengths from the matrix dimensions
let q = Vec::from_raw_parts(q as *mut T, A.n, A.n);
let b = Vec::from_raw_parts(b as *mut T, A.m, A.m);
let q = match q.is_null() {
true => Vec::new(),
false => Vec::from_raw_parts(q as *mut T, P.n, P.n),
};
let b = match b.is_null() {
true => Vec::new(),
false => Vec::from_raw_parts(b as *mut T, A.m, A.m),
};

// Get a reference to the DefaultSettings struct from the pointer passed from C
let settings_struct = &*(settings as *const ClarabelDefaultSettings<T>);
let settings = utils::get_solver_settings_from_c::<T>(settings_struct);

// Convert the cones from C to Rust
let c_cones = slice::from_raw_parts(cones, n_cones);
// c_cones is a slice created from a raw pointer, so it is not managed by Rust, i.e. C side array is not freed when the slice is dropped.
let cones_vec = utils::convert_from_C_cones(c_cones);
let cones = cones_vec.as_slice();
let cones = match cones.is_null() {
true => Vec::new(),
false => {
let c_cones = slice::from_raw_parts(cones, n_cones);
utils::convert_from_C_cones(c_cones)
}
};

// Create the solver
// This is dropped at the end of the function because it exists on the Rust side only, and cones and settings are created on the Rust side.
let solver = lib::DefaultSolver::<T>::new(&P, &q, &A, &b, cones, settings);
// This is dropped at the end of the function because it exists on the Rust side only,
// and cones and settings are created on the Rust side.
let solver = lib::DefaultSolver::<T>::new(&P, &q, &A, &b, &cones, settings);

// Ensure Rust does not free the memory of arrays managed by C
// Should be fine to forget vectors that were created as zero-length
// vecs when receiving null pointers, since rust vec::new() should
// not allocate memory for zero-length vectors.
forget(P);
forget(A);
forget(q);
Expand Down
12 changes: 10 additions & 2 deletions rust_wrapper/src/utils/csc_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,16 @@ pub unsafe fn convert_from_C_CscMatrix<T: FloatT>(ptr: *const ClarabelCscMatrix<
let colptr = Vec::from_raw_parts(matrix.colptr as *mut usize, n + 1, n + 1);

// Length of rowval and nzval is given by colptr[n]
let rowval = Vec::from_raw_parts(matrix.rowval as *mut usize, colptr[n], colptr[n]);
let nzval_vec = Vec::from_raw_parts(matrix.nzval as *mut T, colptr[n], colptr[n]);
let rowval = match matrix.rowval.is_null() {
true => Vec::new(),
false => Vec::from_raw_parts(matrix.rowval as *mut usize, colptr[n], colptr[n]),
};
let nzval_vec = match matrix.nzval.is_null() {
true => Vec::new(),
false => Vec::from_raw_parts(matrix.nzval as *mut T, colptr[n], colptr[n]),
};

assert!(rowval.len() == colptr[n]);

// Call the CscMatrix constructor defined in Rust
let rust_matrix = lib::CscMatrix::<T> {
Expand Down
12 changes: 12 additions & 0 deletions rust_wrapper/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,17 @@ pub fn get_solver_settings_from_c<T: FloatT>(
iterative_refinement_max_iter: value.iterative_refinement_max_iter,
iterative_refinement_stop_ratio: value.iterative_refinement_stop_ratio,
presolve_enable: value.presolve_enable,
#[cfg(feature = "sdp")]
chordal_decomposition_enable: value.chordal_decomposition_enable,
#[cfg(feature = "sdp")]
chordal_decomposition_merge_method: match value.chordal_decomposition_merge_method {
ClarabelCliqueMergeMethods::CLIQUE_GRAPH => String::from("clique_graph"),
ClarabelCliqueMergeMethods::PARENT_CHILD => String::from("parent_child"),
ClarabelCliqueMergeMethods::NONE => String::from("none"),
},
#[cfg(feature = "sdp")]
chordal_decomposition_compact: value.chordal_decomposition_compact,
#[cfg(feature = "sdp")]
chordal_decomposition_complete_dual: value.chordal_decomposition_complete_dual,
}
}

0 comments on commit ba7ec3e

Please sign in to comment.