Skip to main content

CompiledIlpProgram

Struct CompiledIlpProgram 

Source
pub struct CompiledIlpProgram { /* private fields */ }

Implementations§

Source§

impl CompiledIlpProgram

Source

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.

Source

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.

Source

pub fn set_candidate_map( &mut self, candidates: Vec<(u32, u32, u32)>, ) -> PyResult<()>

Upload candidate (i,j,k) -> index mapping. Called once per attempt.

Source

pub fn candidate_map_len(&self) -> usize

Length of current candidate map (0 if not set).

Source

pub fn debug_ilp_mask_kind(&self, name: String) -> Option<String>

Source

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.

Source

pub fn set_coo_memory_cap(&mut self, bytes: u64)

Deprecated: use set_coo_chunk_budget. Kept for one release cycle.

Source

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.

Source

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.

Source

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 examples
  • negatives — list of (relation, [col_values]) negative examples
  • cand_probs_obj — DLPack/PyTorch tensor of candidate probabilities on GPU
Source

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.

Source

pub fn set_rule_mask( &mut self, name: String, mask_hard_flat: &Bound<'_, PyAny>, mask_soft_flat: &Bound<'_, PyAny>, schema_size: usize, ) -> PyResult<()>

Source

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

Source

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.

Source

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

Source

pub fn evaluate(&mut self, py: Python<'_>) -> PyResult<()>

Source

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.

Source

pub fn get_tagged_results(&self) -> PyResult<Vec<(u32, u32, u32, u32)>>

Source

pub fn fact_exists(&self, relation: &str, values: Vec<i64>) -> PyResult<bool>

Source

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.

Source

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.

Source

pub fn tagged_entries_containing_fact( &self, relation: &str, values: Vec<i64>, ) -> PyResult<Vec<(u32, u32, u32)>>

Source

pub fn ilp_schema_size(&self) -> usize

Source

pub fn ilp_relation_names(&self) -> Vec<String>

Source

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.

Source

pub fn commit_induced_rule(&mut self, rule_source: &str) -> PyResult<()>

Source

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.

Source

pub fn batch_fact_membership( &self, relation: &str, facts: Vec<Vec<i64>>, ) -> PyResult<Vec<bool>>

Source

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.

Source

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 + 1
  • entry_indices: COO candidate indices, sorted by fact row
  • entry_i/j/k: metadata arrays indexed by entry_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.

Source

pub fn d2h_transfer_count(&self) -> u64

Source

pub fn reset_d2h_transfer_count(&self)

Source

pub fn host_transfer_stats(&self, py: Python<'_>) -> PyResult<Py<PyAny>>

Source

pub fn reset_host_transfer_stats(&self)

Source§

impl CompiledIlpProgram

Source

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§

Source§

impl DerefToPyAny for CompiledIlpProgram

Source§

impl ExtractPyClassWithClone for CompiledIlpProgram

Source§

impl<'py> IntoPyObject<'py> for CompiledIlpProgram

Source§

type Target = CompiledIlpProgram

The Python output type
Source§

type Output = Bound<'py, <CompiledIlpProgram as IntoPyObject<'py>>::Target>

The smart pointer type to use. Read more
Source§

type Error = PyErr

The type returned in the event of a conversion error.
Source§

fn into_pyobject( self, py: Python<'py>, ) -> Result<<Self as IntoPyObject<'_>>::Output, <Self as IntoPyObject<'_>>::Error>

Performs the conversion.
Source§

impl PyClass for CompiledIlpProgram

Source§

const NAME: &str = "CompiledIlpProgram"

Name of the class. Read more
Source§

type Frozen = False

Whether the pyclass is frozen. Read more
Source§

impl PyClassImpl for CompiledIlpProgram

Source§

const MODULE: Option<&str> = ::core::option::Option::None

Module which the class will be associated with. Read more
Source§

const IS_BASETYPE: bool = false

#[pyclass(subclass)]
Source§

const IS_SUBCLASS: bool = false

#[pyclass(extends=…)]
Source§

const IS_MAPPING: bool = false

#[pyclass(mapping)]
Source§

const IS_SEQUENCE: bool = false

#[pyclass(sequence)]
Source§

const IS_IMMUTABLE_TYPE: bool = false

#[pyclass(immutable_type)]
Source§

const RAW_DOC: &'static CStr = c"\x00"

Docstring for the class provided on the struct or enum. Read more
Source§

const DOC: &'static CStr

Fully rendered class doc, including the text_signature if a constructor is defined. Read more
Source§

type Layout = <<CompiledIlpProgram as PyClassImpl>::BaseNativeType as PyClassBaseType>::Layout<CompiledIlpProgram>

Description of how this class is laid out in memory
Source§

type BaseType = PyAny

Base class
Source§

type ThreadChecker = NoopThreadChecker

This handles following two situations: Read more
Source§

type Inventory = Pyo3MethodsInventoryForCompiledIlpProgram

Source§

type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::MutableChild

Immutable or mutable
Source§

type Dict = PyClassDummySlot

Specify this class has #[pyclass(dict)] or not.
Source§

type WeakRef = PyClassDummySlot

Specify this class has #[pyclass(weakref)] or not.
Source§

type BaseNativeType = PyAny

The closest native ancestor. This is PyAny by default, and when you declare #[pyclass(extends=PyDict)], it’s PyDict.
Source§

fn items_iter() -> PyClassItemsIter

Source§

fn lazy_type_object() -> &'static LazyTypeObject<Self>

§

fn dict_offset() -> Option<PyObjectOffset>

Used to provide the dictoffset slot (equivalent to tp_dictoffset)
§

fn weaklist_offset() -> Option<PyObjectOffset>

Used to provide the weaklistoffset slot (equivalent to tp_weaklistoffset
Source§

impl PyTypeInfo for CompiledIlpProgram

Source§

const NAME: &str = <Self as ::pyo3::PyClass>::NAME

👎Deprecated since 0.28.0:

prefer using ::type_object(py).name() to get the correct runtime value

Class name.
Source§

const MODULE: Option<&str> = <Self as ::pyo3::impl_::pyclass::PyClassImpl>::MODULE

👎Deprecated since 0.28.0:

prefer using ::type_object(py).module() to get the correct runtime value

Module name, if any.
Source§

fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject

Returns the PyTypeObject instance for this type.
§

fn type_object(py: Python<'_>) -> Bound<'_, PyType>

Returns the safe abstraction over the type object.
§

fn is_type_of(object: &Bound<'_, PyAny>) -> bool

Checks if object is an instance of this type or a subclass of this type.
§

fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool

Checks if object is an instance of this type.

Auto Trait Implementations§

Blanket Implementations§

§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<'py, T> IntoPyObjectExt<'py> for T
where T: IntoPyObject<'py>,

§

fn into_bound_py_any(self, py: Python<'py>) -> Result<Bound<'py, PyAny>, PyErr>

Converts self into an owned Python object, dropping type information.
§

fn into_py_any(self, py: Python<'py>) -> Result<Py<PyAny>, PyErr>

Converts 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>

Converts self into a Python object. Read more
§

impl<T> PyErrArguments for T
where T: for<'py> IntoPyObject<'py> + Send + Sync,

§

fn arguments(self, py: Python<'_>) -> Py<PyAny>

Arguments for exception
§

impl<T> PyTypeCheck for T
where T: PyTypeInfo,

§

fn type_check(object: &Bound<'_, PyAny>) -> bool

Checks if object is an instance of Self, which may include a subtype. Read more
§

fn classinfo_object(py: Python<'_>) -> Bound<'_, PyAny>

Returns the expected type as a possible argument for the isinstance and issubclass function. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Ungil for T
where T: Send,

§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V