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).

Variables

const EINDIR_ABI_FAMILY: &[u8]

Stable ABI family name for the embeddable objective handle.

const EINDIR_ABI_FEATURE_BATCH: u64

Feature bit indicating that batched objective evaluation is supported.

const EINDIR_ABI_FEATURE_GRADIENT: u64

Feature bit indicating that analytic gradients are supported by the handle.

const EINDIR_CALLBACK_LIFETIME_BORROWED_SYNC: u32

Tensor contract value for synchronous borrowed callback inputs/outputs.

const EINDIR_OBJECTIVE_OPERATION_ENERGY: u64

Objective operation bit indicating that the value callback is available.

const EINDIR_OBJECTIVE_OPERATION_FORCES: u64

Objective operation bit indicating that the gradient callback is available.

const EINDIR_TENSOR_DEVICE_CPU: i32

DLPack device code for CPU tensors.

const EINDIR_TENSOR_DTYPE_FLOAT: i32

DLPack dtype code for floating-point tensors.

const EINDIR_TENSOR_LAYOUT_CONTIGUOUS: u32

Tensor contract value for compact row-major storage.

Functions

unsafe extern C fn eindir_core_abi_compatible(stamp: *const eindir_abi_stamp_t) -> i32

Returns nonzero when stamp can be consumed by this eindir ABI.

extern C fn eindir_core_abi_family() -> *const c_char

Returns the stable ABI family name as a NUL-terminated ASCII string.

extern C fn eindir_core_abi_stamp() -> eindir_abi_stamp_t

Returns the native ABI metadata for eindir_objective_t.

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]).

Safety

obj must point to a live objective and out must describe writable, contiguous f64 storage for at least eindir_objective_dim(obj) values.

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]).

Safety

obj must point to a live objective and out must describe writable, contiguous f64 storage for at least eindir_objective_dim(obj) values.

unsafe extern C fn eindir_objective_descriptor(obj: *const eindir_objective_t) -> *const eindir_objective_descriptor_t

Return the semantic descriptor attached to an objective, or NULL.

unsafe extern C fn eindir_objective_descriptor_compatible(actual: *const eindir_objective_descriptor_t, required: *const eindir_objective_descriptor_t) -> i32

Return nonzero when actual satisfies every requirement in required.

A non-empty string or nonzero scalar in required is exact; an empty or zero field acts as a wildcard. Operation bits are checked as a subset so a producer may advertise additional capabilities without breaking consumers.

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

Returns the number of input dimensions.

Safety

obj must be null or point to a live eindir_objective_t.

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.

Safety

obj must point to a live objective, x must be readable by its registered callback, and value_out must point to writable f64 storage.

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.

Safety

obj must be null or a live handle returned by eindir_objective_new, and the handle must not be used or freed again after this call.

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.

Safety

obj must point to a live objective; x and grad_out must satisfy the registered gradient callback’s readable-input and writable-output contracts.

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

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

Safety

obj must be null or point to a live eindir_objective_t.

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.

Safety

Both bounds pointers must reference readable one-dimensional DLPack tensors containing dim contiguous f64 values. The callbacks and user_data must remain valid until the returned handle is freed.

fn set_last_error(msg: &str)

Replace the current thread’s diagnostic returned by eindir_last_error.

Enums

enum eindir_status_t

Status codes returned by all eindir C API functions.

EINDIR_SUCCESS

The operation completed successfully.

EINDIR_INVALID_PARAMETER

A pointer, shape, callback, or scalar argument is invalid.

EINDIR_INTERNAL_ERROR

The operation failed internally or panicked behind the C boundary.

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<'_>
impl DifferentiableObjective<f64> for EindirObjectiveWrapper<'_>
struct eindir_abi_stamp_t

ABI metadata exchanged by native eindir-compatible consumers.

abi_major: u32

Major ABI revision; incompatible layout changes increment this value.

abi_minor: u32

Minor ABI revision; additive compatible changes increment this value.

objective_layout: u32

Revision of the embedded objective layout.

objective_size: usize

Size of eindir_objective_t in bytes.

objective_align: usize

Alignment of eindir_objective_t in bytes.

dlpack_major: u32

Major DLPack version used by callbacks.

dlpack_minor: u32

Minor DLPack version used by callbacks.

features: u64

Bitset describing supported bridge features.

struct eindir_objective_descriptor_t

Machine-readable semantic metadata for an objective handle.

schema_id: *const c_char

Descriptor schema identifier, encoded as a NUL-terminated string.

producer_id: *const c_char

Producer/objective identity, encoded as a NUL-terminated string.

length_unit: *const c_char

Cartesian length unit, encoded as a NUL-terminated string.

energy_unit: *const c_char

Objective energy unit, encoded as a NUL-terminated string.

energy_sign: i32

Sign convention for the returned energy (+1 means minimization energy).

gradient_sign: i32

Sign convention for the returned gradient (+1 means dE/dx).

operations: u64

Bitset of supported objective operations.

tensor_device_type: i32

DLPack device type required by callback tensors.

tensor_dtype_code: i32

DLPack dtype code required by callback tensors.

tensor_dtype_bits: u8

DLPack dtype bit width required by callback tensors.

tensor_dtype_lanes: u8

DLPack dtype lane count required by callback tensors.

tensor_layout: u32

Tensor stride/layout contract.

callback_lifetime: u32

Callback ownership/lifetime contract.

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.

descriptor: *const eindir_objective_descriptor_t

Optional semantic descriptor owned by the embedding producer.

Traits implemented

unsafe impl Send for eindir_objective_t
unsafe impl Sync for eindir_objective_t