pub struct CompiledIlpProgram { /* private fields */ }Implementations§
Source§impl CompiledIlpProgram
impl CompiledIlpProgram
Sourcepub fn compile_variant(
&self,
py: Python<'_>,
source: &str,
) -> PyResult<CompiledIlpProgram>
pub fn compile_variant( &self, py: Python<'_>, source: &str, ) -> PyResult<CompiledIlpProgram>
Compile source on this program’s CUDA provider instead of a new one.
The result is a separate program with its own relation store, in the
state IlpProgramFactory.compile(source, ...) would produce — the
frontend runs again, the facts are loaded again and the plan is
executed once. What is skipped is only the per-compile CUDA provider
setup (a fresh context, allocator and memory pool). Intended for ILP
loops that compile many one-rule variants of one program (hold-out
folds, candidate scans).
Because the provider is shared, so are its device-memory budget
(memory_mb given to the base compile covers this program and every
variant alive at the same time), its streams and its host-transfer
counters — variant.fact_exists() bumps the counter
base.d2h_transfer_count() reads. Relation overrides uploaded to the
base with put_relation are NOT carried over: the variant sees only
the facts in source. The variant is compiled with the same
max_active_rules as this program.
Sourcepub fn compile_timing_ms(&self) -> StdHashMap<String, f64>
pub fn compile_timing_ms(&self) -> StdHashMap<String, f64>
Wall-clock breakdown of the compile that produced this program, in
milliseconds per phase (provider, frontend, facts, execute).
A variant has no provider entry. Phase names are diagnostic and may
change; do not build on the exact set.
Sourcepub fn set_candidate_map(
&mut self,
candidates: Vec<(u32, u32, u32)>,
) -> PyResult<()>
pub fn set_candidate_map( &mut self, candidates: Vec<(u32, u32, u32)>, ) -> PyResult<()>
Upload candidate (i,j,k) -> index mapping. Called once per attempt.
Sourcepub fn candidate_map_len(&self) -> usize
pub fn candidate_map_len(&self) -> usize
Length of current candidate map (0 if not set).
pub fn debug_ilp_mask_kind(&self, name: String) -> Option<String>
Sourcepub fn set_coo_chunk_budget(&mut self, bytes: u64)
pub fn set_coo_chunk_budget(&mut self, bytes: u64)
Set the per-chunk temp allocation budget in bytes. The final merged COO buffer is exact-NNZ sized and may exceed this budget. Default: 16 MB.
Sourcepub fn set_coo_memory_cap(&mut self, bytes: u64)
pub fn set_coo_memory_cap(&mut self, bytes: u64)
Deprecated: use set_coo_chunk_budget. Kept for one release cycle.
Sourcepub fn set_strict_zero_dtoh(&mut self, strict: bool)
pub fn set_strict_zero_dtoh(&mut self, strict: bool)
Enable strict zero-D2H mode. When true, raises RuntimeError instead of falling back to the chunked COO path (which uses D2H transfers). Use for zero-D2H benchmarks and CI gates.
Sourcepub fn put_relation(
&mut self,
name: String,
dlpack_columns: &Bound<'_, PyAny>,
) -> PyResult<()>
pub fn put_relation( &mut self, name: String, dlpack_columns: &Bound<'_, PyAny>, ) -> PyResult<()>
Upload a named relation as DLPack tensor columns into the ILP program store.
This enables tensor-native ILP data upload: compile a schema-only source (predicate declarations only, no facts), then upload GPU tensor data via DLPack without host materialization.
Sourcepub fn compute_ilp_loss_grad_gpu<'py>(
&mut self,
py: Python<'py>,
positives: Vec<(String, Vec<i64>)>,
negatives: Vec<(String, Vec<i64>)>,
cand_probs_obj: &Bound<'py, PyAny>,
) -> PyResult<(Py<PyAny>, Py<PyAny>)>
pub fn compute_ilp_loss_grad_gpu<'py>( &mut self, py: Python<'py>, positives: Vec<(String, Vec<i64>)>, negatives: Vec<(String, Vec<i64>)>, cand_probs_obj: &Bound<'py, PyAny>, ) -> PyResult<(Py<PyAny>, Py<PyAny>)>
GPU-resident ILP loss + gradient computation.
Builds a sparse CSR structure from retained per-entry membership masks
and launches forward (credit gather + NLL loss) and backward (gradient
scatter) CUDA kernels. Returns (loss_dlpack, grad_dlpack) where both
are GPU-resident tensors exported via DLPack.
§Arguments
positives— list of(relation, [col_values])positive examplesnegatives— list of(relation, [col_values])negative examplescand_probs_obj— DLPack/PyTorch tensor of candidate probabilities on GPU
Sourcepub fn compute_ilp_loss_grad_gpu_relations<'py>(
&mut self,
py: Python<'py>,
positives_by_relation: &Bound<'py, PyAny>,
negatives_by_relation: &Bound<'py, PyAny>,
cand_probs_obj: &Bound<'py, PyAny>,
) -> PyResult<(Py<PyAny>, Py<PyAny>)>
pub fn compute_ilp_loss_grad_gpu_relations<'py>( &mut self, py: Python<'py>, positives_by_relation: &Bound<'py, PyAny>, negatives_by_relation: &Bound<'py, PyAny>, cand_probs_obj: &Bound<'py, PyAny>, ) -> PyResult<(Py<PyAny>, Py<PyAny>)>
GPU-resident ILP loss + gradient computation from relation-native positive/negative examples stored as DLPack column groups.
positives_by_relation and negatives_by_relation must be Python dicts
mapping relation name -> sequence of DLPack columns with schema-matching
dtypes. No host fact tuple materialization occurs on this path.
pub fn set_rule_mask( &mut self, name: String, mask_hard_flat: &Bound<'_, PyAny>, mask_soft_flat: &Bound<'_, PyAny>, schema_size: usize, ) -> PyResult<()>
Sourcepub fn set_rule_mask_sparse(
&mut self,
name: String,
candidate_ids: Vec<u32>,
soft_probs_dlpack: &Bound<'_, PyAny>,
budget: usize,
allow_recursive: bool,
) -> PyResult<()>
pub fn set_rule_mask_sparse( &mut self, name: String, candidate_ids: Vec<u32>, soft_probs_dlpack: &Bound<'_, PyAny>, budget: usize, allow_recursive: bool, ) -> PyResult<()>
Sparse mask API: candidate IDs + DLPack soft probabilities (GPU tensor).
candidate_ids must be exactly [0..C) where C is the candidate count
for this mask under the provided recursion policy.
soft_probs_dlpack is a DLPack capsule (CUDA f64 tensor) passed from PyTorch.
Rust imports it zero-copy, downloads values (not counted by the D2H counter),
performs deterministic top-k (desc soft value, then lower id), and
stores a sparse IlpMask (no dense N^3 materialization).
Sourcepub fn set_rule_mask_sparse_selected(
&mut self,
name: String,
selected_candidate_ids: Vec<u32>,
selected_soft_probs_dlpack: &Bound<'_, PyAny>,
allow_recursive: bool,
) -> PyResult<()>
pub fn set_rule_mask_sparse_selected( &mut self, name: String, selected_candidate_ids: Vec<u32>, selected_soft_probs_dlpack: &Bound<'_, PyAny>, allow_recursive: bool, ) -> PyResult<()>
Preferred sparse mask API: caller preselects candidate IDs and passes only the selected subset plus aligned soft probabilities.
This path avoids the full-vector soft-probability download in
set_rule_mask_sparse(...). The selected IDs are mapped directly to the
existing candidate triples and stored in sparse-mask order.
Sourcepub fn set_rule_mask_sparse_selected_device(
&mut self,
name: String,
selected_candidate_ids_dlpack: &Bound<'_, PyAny>,
selected_soft_probs_dlpack: &Bound<'_, PyAny>,
allow_recursive: bool,
) -> PyResult<()>
pub fn set_rule_mask_sparse_selected_device( &mut self, name: String, selected_candidate_ids_dlpack: &Bound<'_, PyAny>, selected_soft_probs_dlpack: &Bound<'_, PyAny>, allow_recursive: bool, ) -> PyResult<()>
Strict sparse mask API: selected candidate IDs stay as a device tensor on
the Python side. Rust resolves them against the fixed candidate order
uploaded via set_candidate_map(...).
pub fn evaluate(&mut self, py: Python<'_>) -> PyResult<()>
Sourcepub fn reset_runtime(&mut self, py: Python<'_>) -> PyResult<()>
pub fn reset_runtime(&mut self, py: Python<'_>) -> PyResult<()>
Reset mutable runtime state for ILP attempt reuse.
Clears ILP registry (masks/tagged results), executor store, join index cache, stats, and profiler. Then re-registers schemas with empty buffers, reloads base facts from AST, and re-executes the plan. Preserves all immutable compile artifacts (AST, plan, schemas, rel_index, provider, TMJ metadata, max_active_rules).
After reset, the program is in the same state as a fresh compile() with the same source — ready for set_rule_mask / evaluate cycles.
pub fn get_tagged_results(&self) -> PyResult<Vec<(u32, u32, u32, u32)>>
pub fn fact_exists(&self, relation: &str, values: Vec<i64>) -> PyResult<bool>
Sourcepub fn relation_facts(&self, rel_name: String) -> PyResult<Vec<Vec<i64>>>
pub fn relation_facts(&self, rel_name: String) -> PyResult<Vec<Vec<i64>>>
Return all facts in the named relation as a list of int lists.
Sourcepub fn sample_false_positives(
&self,
head_rel: String,
exclude: Vec<(String, Vec<i64>)>,
max_n: usize,
) -> PyResult<Vec<Vec<i64>>>
pub fn sample_false_positives( &self, head_rel: String, exclude: Vec<(String, Vec<i64>)>, max_n: usize, ) -> PyResult<Vec<Vec<i64>>>
Sample up to max_n derived facts for head_rel that are NOT in exclude.
Returns list[list[int]] — each inner list is a tuple of column values.
Uses the same column-download pattern as relation_facts.
pub fn tagged_entries_containing_fact( &self, relation: &str, values: Vec<i64>, ) -> PyResult<Vec<(u32, u32, u32)>>
pub fn ilp_schema_size(&self) -> usize
pub fn ilp_relation_names(&self) -> Vec<String>
Sourcepub fn relation_type_annotations(&self) -> Vec<(String, Vec<String>)>
pub fn relation_type_annotations(&self) -> Vec<(String, Vec<String>)>
Return declared predicate types from source pred declarations.
Output is a list of (name, types) tuples so callers can
deterministically inspect whether metadata is available for
relations used during promotion.
pub fn commit_induced_rule(&mut self, rule_source: &str) -> PyResult<()>
Sourcepub fn batch_fact_membership_device(
&self,
py: Python<'_>,
relation: &str,
facts: Vec<Vec<i64>>,
) -> PyResult<Py<PyAny>>
pub fn batch_fact_membership_device( &self, py: Python<'_>, relation: &str, facts: Vec<Vec<i64>>, ) -> PyResult<Py<PyAny>>
GPU-side batch fact membership check.
Uploads facts (list of value-lists) to a temporary CudaBuffer,
semi-joins against the named relation, returns per-fact boolean mask.
Zero download_column_* calls — only downloads the u8 mask.
pub fn batch_fact_membership( &self, relation: &str, facts: Vec<Vec<i64>>, ) -> PyResult<Vec<bool>>
Sourcepub fn batch_tagged_credit(
&self,
relation: &str,
facts: Vec<Vec<i64>>,
) -> PyResult<Vec<Vec<(u32, u32, u32)>>>
pub fn batch_tagged_credit( &self, relation: &str, facts: Vec<Vec<i64>>, ) -> PyResult<Vec<Vec<(u32, u32, u32)>>>
GPU-side batch credit assignment.
For each fact in facts, returns the list of (i,j,k) entries whose
join result contains that fact. Uses membership_mask against retained
per-entry buffers — zero download_column_* calls.
Sourcepub fn batch_tagged_credit_device(
&self,
py: Python<'_>,
relation: &str,
facts: Vec<Vec<i64>>,
) -> PyResult<IlpTaggedCreditDeviceResult>
pub fn batch_tagged_credit_device( &self, py: Python<'_>, relation: &str, facts: Vec<Vec<i64>>, ) -> PyResult<IlpTaggedCreditDeviceResult>
GPU-side batch credit assignment.
Returns a CSR-style device representation:
fact_row_offsets: len = num_facts + 1entry_indices: COO candidate indices, sorted by fact rowentry_i/j/k: metadata arrays indexed byentry_indices
Zero DTOH calls on the query path. Uses the non-chunked COO builder to avoid reading device-side nnz metadata back to the host.
pub fn d2h_transfer_count(&self) -> u64
pub fn reset_d2h_transfer_count(&self)
pub fn host_transfer_stats(&self, py: Python<'_>) -> PyResult<Py<PyAny>>
pub fn reset_host_transfer_stats(&self)
Source§impl CompiledIlpProgram
impl CompiledIlpProgram
Sourcepub fn induce_exact_native<'py>(
&mut self,
py: Python<'py>,
head_relation: String,
candidate_relations: Vec<String>,
positive_arg0: &Bound<'py, PyAny>,
positive_arg1: &Bound<'py, PyAny>,
negative_arg0: Option<&Bound<'py, PyAny>>,
negative_arg1: Option<&Bound<'py, PyAny>>,
k_per_topology: u32,
deterministic: bool,
) -> PyResult<Py<PyAny>>
pub fn induce_exact_native<'py>( &mut self, py: Python<'py>, head_relation: String, candidate_relations: Vec<String>, positive_arg0: &Bound<'py, PyAny>, positive_arg1: &Bound<'py, PyAny>, negative_arg0: Option<&Bound<'py, PyAny>>, negative_arg1: Option<&Bound<'py, PyAny>>, k_per_topology: u32, deterministic: bool, ) -> PyResult<Py<PyAny>>
Native backend entrypoint for pyxlog.ilp.induce_exact(backend="native").
Returns a dict (not a dataclass) with the following shape — the
Python wrapper repackages this into the existing ExactInductionResult
/ ScoredCandidate dataclass instances:
{
"candidates": [
{"topology": str, "head_relation": str,
"left_relation": str, "right_relation": str,
"positives_covered": int, "negatives_covered": int,
"local_rank": int,
"next_positives_covered": int, "next_negatives_covered": int,
"tie_class_size": int},
...
],
"total_scored": int,
"candidate_count": int,
"positive_count": int,
"negative_count": int,
}Trait Implementations§
impl DerefToPyAny for CompiledIlpProgram
impl ExtractPyClassWithClone for CompiledIlpProgram
Source§impl<'py> IntoPyObject<'py> for CompiledIlpProgram
impl<'py> IntoPyObject<'py> for CompiledIlpProgram
Source§type Target = CompiledIlpProgram
type Target = CompiledIlpProgram
Source§type Output = Bound<'py, <CompiledIlpProgram as IntoPyObject<'py>>::Target>
type Output = Bound<'py, <CompiledIlpProgram as IntoPyObject<'py>>::Target>
Source§fn into_pyobject(
self,
py: Python<'py>,
) -> Result<<Self as IntoPyObject<'_>>::Output, <Self as IntoPyObject<'_>>::Error>
fn into_pyobject( self, py: Python<'py>, ) -> Result<<Self as IntoPyObject<'_>>::Output, <Self as IntoPyObject<'_>>::Error>
Source§impl PyClass for CompiledIlpProgram
impl PyClass for CompiledIlpProgram
Source§impl PyClassImpl for CompiledIlpProgram
impl PyClassImpl for CompiledIlpProgram
Source§const MODULE: Option<&str> = ::core::option::Option::None
const MODULE: Option<&str> = ::core::option::Option::None
Source§const IS_BASETYPE: bool = false
const IS_BASETYPE: bool = false
Source§const IS_SUBCLASS: bool = false
const IS_SUBCLASS: bool = false
Source§const IS_MAPPING: bool = false
const IS_MAPPING: bool = false
Source§const IS_SEQUENCE: bool = false
const IS_SEQUENCE: bool = false
Source§const IS_IMMUTABLE_TYPE: bool = false
const IS_IMMUTABLE_TYPE: bool = false
Source§const RAW_DOC: &'static CStr = c"\x00"
const RAW_DOC: &'static CStr = c"\x00"
Source§const DOC: &'static CStr
const DOC: &'static CStr
text_signature if a constructor is defined. Read moreSource§type Layout = <<CompiledIlpProgram as PyClassImpl>::BaseNativeType as PyClassBaseType>::Layout<CompiledIlpProgram>
type Layout = <<CompiledIlpProgram as PyClassImpl>::BaseNativeType as PyClassBaseType>::Layout<CompiledIlpProgram>
Source§type ThreadChecker = NoopThreadChecker
type ThreadChecker = NoopThreadChecker
type Inventory = Pyo3MethodsInventoryForCompiledIlpProgram
Source§type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::MutableChild
type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::MutableChild
Source§type BaseNativeType = PyAny
type BaseNativeType = PyAny
PyAny by default, and when you declare
#[pyclass(extends=PyDict)], it’s PyDict.fn items_iter() -> PyClassItemsIter
fn lazy_type_object() -> &'static LazyTypeObject<Self>
§fn dict_offset() -> Option<PyObjectOffset>
fn dict_offset() -> Option<PyObjectOffset>
§fn weaklist_offset() -> Option<PyObjectOffset>
fn weaklist_offset() -> Option<PyObjectOffset>
Source§impl PyTypeInfo for CompiledIlpProgram
impl PyTypeInfo for CompiledIlpProgram
Source§const NAME: &str = <Self as ::pyo3::PyClass>::NAME
const NAME: &str = <Self as ::pyo3::PyClass>::NAME
prefer using ::type_object(py).name() to get the correct runtime value
Source§const MODULE: Option<&str> = <Self as ::pyo3::impl_::pyclass::PyClassImpl>::MODULE
const MODULE: Option<&str> = <Self as ::pyo3::impl_::pyclass::PyClassImpl>::MODULE
prefer using ::type_object(py).module() to get the correct runtime value
Source§fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject
fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject
§fn type_object(py: Python<'_>) -> Bound<'_, PyType>
fn type_object(py: Python<'_>) -> Bound<'_, PyType>
§fn is_type_of(object: &Bound<'_, PyAny>) -> bool
fn is_type_of(object: &Bound<'_, PyAny>) -> bool
object is an instance of this type or a subclass of this type.§fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool
fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool
object is an instance of this type.Auto Trait Implementations§
impl !Freeze for CompiledIlpProgram
impl RefUnwindSafe for CompiledIlpProgram
impl Send for CompiledIlpProgram
impl Sync for CompiledIlpProgram
impl Unpin for CompiledIlpProgram
impl UnsafeUnpin for CompiledIlpProgram
impl UnwindSafe for CompiledIlpProgram
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<'py, T> IntoPyObjectExt<'py> for Twhere
T: IntoPyObject<'py>,
impl<'py, T> IntoPyObjectExt<'py> for Twhere
T: IntoPyObject<'py>,
§fn into_bound_py_any(self, py: Python<'py>) -> Result<Bound<'py, PyAny>, PyErr>
fn into_bound_py_any(self, py: Python<'py>) -> Result<Bound<'py, PyAny>, PyErr>
self into an owned Python object, dropping type information.§fn into_py_any(self, py: Python<'py>) -> Result<Py<PyAny>, PyErr>
fn into_py_any(self, py: Python<'py>) -> Result<Py<PyAny>, PyErr>
self into an owned Python object, dropping type information and unbinding it
from the 'py lifetime.§fn into_pyobject_or_pyerr(self, py: Python<'py>) -> Result<Self::Output, PyErr>
fn into_pyobject_or_pyerr(self, py: Python<'py>) -> Result<Self::Output, PyErr>
self into a Python object. Read more§impl<T> PyErrArguments for T
impl<T> PyErrArguments for T
§impl<T> PyTypeCheck for Twhere
T: PyTypeInfo,
impl<T> PyTypeCheck for Twhere
T: PyTypeInfo,
§fn type_check(object: &Bound<'_, PyAny>) -> bool
fn type_check(object: &Bound<'_, PyAny>) -> bool
§fn classinfo_object(py: Python<'_>) -> Bound<'_, PyAny>
fn classinfo_object(py: Python<'_>) -> Bound<'_, PyAny>
isinstance and issubclass function. Read more