mod ffi

module ffi

C ABI surface, gated behind the capi Cargo feature. C ABI surface for eindir-core.

eindir_objective_t is #[repr(C)] so consumers (e.g. rgpot-core) can embed it as the first member of a derived struct and cast between pointer types at zero cost – the C “is-a” pattern. Keep non-C-ABI fields such as Vec, Box, and OnceLock out of this struct; use raw pointers and manage lifetimes in the corresponding constructors and destructors.

Heap-allocated lifecycle:

  • create an objective with eindir_objective_new;

  • evaluate it with eindir_objective_eval;

  • release it with eindir_objective_free.

Embedded lifecycle:

  • place eindir_objective_t as the first member of the consumer struct;

  • cast the consumer pointer to eindir_objective_t* for evaluation;

  • call the consumer’s own destructor rather than eindir_objective_free.

Types

type EindirEvalFn

Callback for evaluating the objective value.

type EindirFreeFn

Destructor for user_data.

type EindirGradFn

Callback for evaluating the gradient (NULL = no analytic gradient).

Functions

extern C fn eindir_core_version() -> *const c_char

Returns the eindir-core package version as a NUL-terminated ASCII string.

extern C fn eindir_last_error() -> *const c_char

Retrieve the last error message for the current thread.

unsafe extern C fn eindir_objective_bounds_high(obj: *const eindir_objective_t, out: *mut DLManagedTensorVersioned) -> eindir_status_t

Writes the upper-bound vector into out (pre-allocated DLPack tensor, shape [dim]).

unsafe extern C fn eindir_objective_bounds_low(obj: *const eindir_objective_t, out: *mut DLManagedTensorVersioned) -> eindir_status_t

Writes the lower-bound vector into out (pre-allocated DLPack tensor, shape [dim]).

unsafe extern C fn eindir_objective_dim(obj: *const eindir_objective_t) -> usize

Returns the number of input dimensions.

unsafe extern C fn eindir_objective_eval(obj: *const eindir_objective_t, x: *const DLManagedTensorVersioned, value_out: *mut f64) -> eindir_status_t

Evaluate the objective at point x.

unsafe extern C fn eindir_objective_free(obj: *mut eindir_objective_t)

Free an objective handle created by eindir_objective_new.

Calls free_fn(user_data) if a destructor was registered, frees the bounds arrays, then frees the struct. Do NOT call this on embedded objectives; call the owning struct’s free function (e.g. rgpot_potential_free) instead.

unsafe extern C fn eindir_objective_grad(obj: *const eindir_objective_t, x: *const DLManagedTensorVersioned, grad_out: *mut DLManagedTensorVersioned) -> eindir_status_t

Compute the gradient at point x.

Returns EINDIR_INVALID_PARAMETER when no gradient callback was registered.

unsafe extern C fn eindir_objective_has_grad(obj: *const eindir_objective_t) -> i32

Returns non-zero if the objective has a gradient callback.

unsafe extern C fn eindir_objective_new(dim: usize, bounds_low: *const DLManagedTensorVersioned, bounds_high: *const DLManagedTensorVersioned, eval_fn: EindirEvalFn, grad_fn: EindirGradFn, user_data: *mut c_void, free_fn: EindirFreeFn) -> *mut eindir_objective_t

Create a new heap-allocated objective handle from C callbacks.

Bounds data is copied from the DLPack tensors; the caller may free them after this call returns. Returns NULL on failure.

The caller must eventually pass the returned pointer to eindir_objective_free.

fn set_last_error(msg: &str)

Enums

enum eindir_status_t

Status codes returned by all eindir C API functions.

EINDIR_SUCCESS
EINDIR_INVALID_PARAMETER
EINDIR_INTERNAL_ERROR

Structs and Unions

struct EindirObjectiveWrapper<'a>

Rust-side view over a C objective, implementing Objective/Gradient.

Implementations

impl<'a> EindirObjectiveWrapper<'a>

Functions

unsafe fn new(obj: &'a eindir_objective_t) -> Self

Safety obj.low and obj.high must point to obj.dim valid f64 values.

Traits implemented

impl Objective<f64> for EindirObjectiveWrapper<'_>
impl Gradient<f64> for EindirObjectiveWrapper<'_>
struct eindir_objective_t

Embeddable, C-ABI-compatible objective handle.

#[repr(C)] means a consumer can embed this struct as the first member of a derived struct and cast DerivedStruct* to eindir_objective_t* at zero cost. Keep Rust-specific types such as Vec, Box, and OnceLock out of this layout.

Lifecycle:

  • Created by eindir_objective_new: low and high are heap-allocated (len = dim) and freed by eindir_objective_free.

  • Embedded: the consumer fills the fields directly and calls its own free function; never call eindir_objective_free on an embedded base.

dim: usize

Number of input dimensions.

low: *mut f64

Lower bounds: heap-allocated f64[dim], owned by this struct when created via eindir_objective_new.

high: *mut f64

Upper bounds: heap-allocated f64[dim], owned by this struct when created via eindir_objective_new.

eval_fn: EindirEvalFn

Value callback. Must not be NULL.

grad_fn: EindirGradFn

Gradient callback. NULL when no analytic gradient is available.

user_data: *mut c_void

Opaque context forwarded verbatim to every callback invocation.

free_fn: EindirFreeFn

Optional destructor for user_data; called by eindir_objective_free. Set to NULL when embedding; manage cleanup in the derived struct’s own free function.

Traits implemented

unsafe impl Send for eindir_objective_t
unsafe impl Sync for eindir_objective_t