tenferro_ext_tropical_capi/
lib.rs

1//! C-API (FFI) for tropical semiring tensor operations.
2//!
3//! Extends [`tenferro_capi`] with tropical einsum functions for three
4//! semirings: MaxPlus (⊕=max, ⊗=+), MinPlus (⊕=min, ⊗=+), and
5//! MaxMul (⊕=max, ⊗=×).
6//!
7//! # Design
8//!
9//! - **Reuses [`tenferro_capi::TfeTensorF64`]** handles from `tenferro-capi`. Since
10//!   `MaxPlus<f64>` is `#[repr(transparent)]`, it has the same memory
11//!   layout as `f64`. Tropical functions accept f64 tensor handles,
12//!   internally wrap data as `MaxPlus<f64>` (or `MinPlus`/`MaxMul`),
13//!   perform the tropical einsum, and unwrap the result back to f64.
14//! - **No new handle type**: the algebra is selected by the function
15//!   name, not the tensor type.
16//! - **Naming convention**: `tfe_tropical_einsum_<algebra>_f64`.
17//!
18//! # Linking
19//!
20//! This crate produces a separate shared library from `tenferro-capi`.
21//! C/Julia/Python consumers load both:
22//!
23//! ```c
24//! // Core tensor operations
25//! tfe_tensor_f64 *t = tfe_tensor_f64_from_data(...);
26//!
27//! // Tropical einsum (from tenferro-ext-tropical-capi)
28//! const tfe_tensor_f64 *ops[] = {a, b};
29//! tfe_tensor_f64 *c = tfe_tropical_einsum_maxplus_f64("ij,jk->ik", ops, 2, &status);
30//! ```
31//!
32//! # Header generation
33//!
34//! Generate the extension header from a workspace checkout with:
35//!
36//! ```text
37//! cbindgen \
38//!   --config extension/tenferro-ext-tropical-capi/cbindgen.toml \
39//!   --crate tenferro-ext-tropical-capi \
40//!   --output tenferro_ext_tropical.h
41//! ```
42//!
43//! # Example (C pseudocode)
44//!
45//! ```c
46//! #include "tenferro.h"
47//! #include "tenferro_ext_tropical.h"
48//!
49//! tfe_status_t status;
50//! size_t shape[] = {3, 4};
51//! double data_a[12] = { /* ... */ };
52//! double data_b[12] = { /* ... */ };
53//!
54//! tfe_tensor_f64 *a = tfe_tensor_f64_from_data(data_a, 12, shape, 2, &status);
55//! tfe_tensor_f64 *b = tfe_tensor_f64_from_data(data_b, 12, shape, 2, &status);
56//!
57//! // MaxPlus tropical einsum: C[i,k] = max_j (A[i,j] + B[j,k])
58//! const tfe_tensor_f64 *ops[] = {a, b};
59//! tfe_tensor_f64 *c = tfe_tropical_einsum_maxplus_f64("ij,jk->ik", ops, 2, &status);
60//! assert(status == TFE_SUCCESS);
61//!
62//! tfe_tensor_f64_release(c);
63//! tfe_tensor_f64_release(b);
64//! tfe_tensor_f64_release(a);
65//! ```
66
67#![allow(clippy::missing_safety_doc)]
68#![allow(non_camel_case_types)]
69
70mod einsum_api;
71mod ffi_utils;
72mod handle;
73mod status;
74
75pub use einsum_api::{
76    tfe_tropical_einsum_frule_maxmul_f64, tfe_tropical_einsum_frule_maxplus_f64,
77    tfe_tropical_einsum_frule_minplus_f64, tfe_tropical_einsum_maxmul_f64,
78    tfe_tropical_einsum_maxplus_f64, tfe_tropical_einsum_minplus_f64,
79    tfe_tropical_einsum_rrule_maxmul_f64, tfe_tropical_einsum_rrule_maxplus_f64,
80    tfe_tropical_einsum_rrule_minplus_f64,
81};
82#[cfg(test)]
83pub(crate) use handle::{handle_to_ref, tensor_to_handle};
84
85#[cfg(test)]
86mod tests;