Skip to content

Commit

Permalink
Merge pull request #34 from Kieranoski702/main
Browse files Browse the repository at this point in the history
Add wrappers for basic chuffed functions and example program using these wrappers
  • Loading branch information
ozgurakgun authored Nov 4, 2023
2 parents 785ca26 + ac3c4c8 commit a74c59e
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 6 deletions.
13 changes: 13 additions & 0 deletions solvers/chuffed/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ fn main() {
println!("cargo:rustc-link-search=all=./solvers/chuffed/vendor/build/");
println!("cargo:rustc-link-lib=static=chuffed");
println!("cargo:rustc-link-lib=static=chuffed_fzn");
println!("cargo:rustc-link-search=all=./solvers/chuffed/");
println!("cargo:rustc-link-lib=static=wrapper");

// also need to (dynamically) link to c++ stdlib
// https://flames-of-code.netlify.app/blog/rust-and-cmake-cplusplus/
Expand Down Expand Up @@ -64,6 +66,17 @@ fn bind() {
// in C++ stdlib that will make it crash.
.allowlist_function("createVars")
.allowlist_function("createVar")
.allowlist_function("all_different")
.allowlist_function("branch")
.allowlist_function("output_vars")
.allowlist_function("var_sym_break")
.allowlist_function("new_dummy_problem")
.allowlist_function("get_idx")
.allowlist_function("make_vec_intvar")
.allowlist_function("destroy_vec_intvar")
.allowlist_function("p_addVars")
.allowlist_function("p_setcallback")
.allowlist_function("branch_IntVar")
.clang_arg("-Ivendor/build") // generated from configure.py
.clang_arg("-Ivendor")
.clang_arg(r"--std=gnu++11")
Expand Down
7 changes: 6 additions & 1 deletion solvers/chuffed/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ SCRIPT_DIR=$(dirname "$0")

git submodule init
git submodule update
cd "$SCRIPT_DIR"
cd "$SCRIPT_DIR" || exit

echo "------ BUILDING ------"
cd vendor || exit
cmake -B build -S .
cmake --build build
cd ..

# Build wrapper.cpp as static library
c++ -c wrapper.cpp -Ivendor --std=c++11
ar rvs libwrapper.a wrapper.o
2 changes: 2 additions & 0 deletions solvers/chuffed/clean.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@

cargo clean
rm -rf vendor/build
rm libwrapper.a
rm wrapper.o
3 changes: 3 additions & 0 deletions solvers/chuffed/compile_flags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-I./vendor
-xc++
--std=c++11
47 changes: 47 additions & 0 deletions solvers/chuffed/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,50 @@ pub mod bindings {
#![allow(non_snake_case)]
include!(concat!(env!("OUT_DIR"), "/chuffed_bindings.rs"));
}

pub mod wrappers {
use crate::bindings::{
all_different, branch_IntVar, createVar, createVars, make_vec_intvar, vec, ConLevel,
IntVar, ValBranch, VarBranch,
};
use core::ptr;

// The signature of createVar is below for reference.
// createVar(x: *mut *mut IntVar, min: ::std::os::raw::c_int, max: ::std::os::raw::c_int, el: bool)
pub fn create_var(min: i32, max: i32, el: bool) -> *mut IntVar {
let mut ptr: *mut IntVar = ptr::null_mut();

unsafe {
createVar(&mut ptr, min, max, el);
ptr
}
}

// createVars void createVars(vec<IntVar*>& x, int n, int min, int max, bool el)
pub fn create_vars(n: i32, min: i32, max: i32, el: bool) -> *mut vec<*mut IntVar> {
let ptr: *mut vec<*mut IntVar> = unsafe { make_vec_intvar() };

unsafe {
createVars(ptr, n, min, max, el);
ptr
}
}

// void all_different(vec<IntVar*>& x, ConLevel cl)
pub unsafe fn all_different_wrapper(x: *mut vec<*mut IntVar>, cl: ConLevel) {
unsafe {
all_different(x, cl);
}
}

// void branch(vec<Branching*> x, VarBranch var_branch, ValBranch val_branch);
pub unsafe fn branch_wrapper(
x: *mut vec<*mut IntVar>,
var_branch: VarBranch,
val_branch: ValBranch,
) {
unsafe {
branch_IntVar(x, var_branch, val_branch);
}
}
}
49 changes: 44 additions & 5 deletions solvers/chuffed/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,47 @@
use chuffed_rs::bindings::createVar;
use chuffed_rs::bindings::IntVar;
pub fn main() {
let mut var = std::mem::MaybeUninit::<IntVar>::uninit();
use chuffed_rs::bindings::{
get_idx, new_dummy_problem, p_addVars, p_setcallback, vec, ConLevel_CL_DEF, IntVar,
VarBranch_VAR_INORDER, VarBranch_VAR_MIN_MIN,
};
use chuffed_rs::wrappers::{all_different_wrapper, branch_wrapper, create_vars};

unsafe fn post_constraints(_n: i32) -> *mut vec<*mut IntVar> {
// Create constant
let n: i32 = _n;
// Create some variables
let x: *mut vec<*mut IntVar> = create_vars(n, 0, n, false);

// Post some constraints
all_different_wrapper(x, ConLevel_CL_DEF);

// Post some branchings
branch_wrapper(x as _, VarBranch_VAR_INORDER, VarBranch_VAR_MIN_MIN);

x
}

// Custom printing function for this problem
#[no_mangle]
pub unsafe extern "C" fn callback(x: *mut vec<*mut IntVar>) {
print!("First output is: {:?}", get_idx(x, 0));
}

fn main() {
let args: Vec<String> = std::env::args().collect();

if args.len() != 2 {
println!("Invalid number of arguments");
return;
}

let n: i32 = args[1].parse().expect("Invalid input");

unsafe {
createVar(&mut var.as_mut_ptr(), 0, 5, false);
let x = post_constraints(n);
// make new dummy problem
let p = new_dummy_problem();
// Call problem.addvars()
p_addVars(p, x);
// Call problem.setcallback()
p_setcallback(p, Some(callback));
}
}
23 changes: 23 additions & 0 deletions solvers/chuffed/wrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "./wrapper.h"

DummyProblem *new_dummy_problem() { return new DummyProblem(); }
void p_addVars(DummyProblem *p, vec<IntVar *> *_searchVars) {
p->addVars(_searchVars);
}
void p_setcallback(DummyProblem *p, void (*_callback)(vec<IntVar *> *)) {
p->setcallback(_callback);
}
IntVar* get_idx(vec<IntVar *> *x, int i) { return *x[i]; }

vec<IntVar*>* make_vec_intvar() {
return new vec<IntVar*>();
}

void destroy_vec_intvar(vec<IntVar*>* v) {
delete v;
}

void branch_IntVar(vec<IntVar *> *x, VarBranch var_branch,
ValBranch val_branch) {
branch(*x, var_branch, val_branch);
}
25 changes: 25 additions & 0 deletions solvers/chuffed/wrapper.h
Original file line number Diff line number Diff line change
@@ -1 +1,26 @@
#include "chuffed/branching/branching.h"
#include "chuffed/core/engine.h"
#include "chuffed/core/propagator.h"
#include "chuffed/vars/modelling.h"

class DummyProblem {
public:
vec<IntVar *> *searchVars;
// callback
void (*callback)(vec<IntVar *> *);

void print() { callback(searchVars); }
void setcallback(void (*_callback)(vec<IntVar *> *)) { callback = _callback; }
void addVars(vec<IntVar *> *_searchVars) { searchVars = _searchVars; }
};

DummyProblem *new_dummy_problem();
void p_addVars(DummyProblem *p, vec<IntVar *> *_searchVars);
void p_setcallback(DummyProblem *p, void (*_callback)(vec<IntVar *> *));
IntVar* get_idx(vec<IntVar *> *x, int i);

vec<IntVar*>* make_vec_intvar();
void destroy_vec_intvar(vec<IntVar*>* v);

void branch_IntVar(vec<IntVar *> *x, VarBranch var_branch,
ValBranch val_branch);

0 comments on commit a74c59e

Please sign in to comment.