Most neural-symbolic systems run neural computation on the GPU and symbolic reasoning on the CPU. Every training iteration then pays a PCIe round-trip to move data across that boundary, and at scale those transfers dominate wall-clock time. XLOG removes the boundary: symbolic evaluation runs on the device, and reasoning state stays there.
XLOG GPU residency model: the host executor and compiler launch kernels into a GPU-resident device plane holding relations, deltas, circuit values, and solver state within a memory budget, exposed zero-copy to PyTorch, JAX, and cuDF via DLPack and Arrow.

The host launches kernels and reads only bounded metadata; relations, deltas, circuit values, and solver state stay in the device memory budget, and results reach PyTorch, JAX, and cuDF zero-copy through DLPack and Arrow.

The contract

During execution, XLOG’s runtime semantic state — relations, deltas, probabilistic circuit values, and solver state — is GPU-resident. The host compiles the program, launches kernels, and reads back bounded metadata (such as row counts to decide when a fixpoint has converged), but the production data plane performs no tracked host-to-device or device-to-host transfers of semantic data.
“Bounded metadata” — a handful of counts read to drive control flow — is exempt from the zero-transfer contract. The guarantee is about semantic data (tuples, weights, circuit values), which never leaves the device in a production run.
This is what makes XLOG a runtime you put inside a training loop. Query results and gradient tensors are exposed as GPU-resident DLPack capsules and Arrow arrays, so a PyTorch or JAX computation consumes them without a copy. You can confirm residency held on a run: the tensor XLOG hands back reports a CUDA device (tensor.device), which means the data was never copied to the host.

Enforce it, don’t just observe it

Checking tensor.device tells you where one result ended up. If you want the runtime to enforce the contract instead, a Python session can turn on a strict gate:
While the gate is on, any attempt to read relation data back to the host fails instead of copying — including the small, ordinarily-permitted deterministic reads, such as the one-byte-per-fact membership mask used to validate evidence. Bounded metadata reads stay exempt: the scalar counts that drive control flow never trip the gate, because the guarantee is about semantic data. Two calls let you inspect the gate: session.strict_deterministic_d2h_enabled() reports whether it is on, and session.deterministic_d2h_violation_count() reports how many reads it has rejected — session.reset_deterministic_d2h_violations() clears that count. A rejection is atomic: the operation leaves the relation and its evidence unchanged. See the Python reference for the full API and diagnostics for a worked zero-transfer audit.

Strict residency, and what happens when it fails

By default XLOG runs in strict GPU-resident mode: the entire plan must execute within the device memory budget. The budget defaults to a fixed limit you can raise per program (memory_mb in the API, --memory-mb on the CLI). If a plan cannot fit, XLOG does not silently spill or fall back to the host. It fails closed with a ResourceExhausted error. Its fixed-order context reports the rejecting layer, current reservation, requested bytes, exact required bytes, configured budget, and the manager’s prior peak. Required bytes are calculated without saturation; if the exact value exceeds u64, estimated_bytes is u64::MAX and the context carries an explicit overflow marker. This makes an out-of-memory condition definite and diagnosable rather than a slow degradation. Concurrent requests are reserved against the local budget before allocator admission, so in-flight requests still prevent oversubscription. The manager publishes current and peak bytes only after admission succeeds: a request refused by CUDA or the device-runtime budget is removed from the local guard and never appears in the admitted current value or the reservation-lifetime high-water mark.
Fail-closed behavior is a running theme in XLOG. Where a computation cannot be done on the device within its declared bounds, the engine rejects it with a typed error instead of quietly switching to a slower or less exact path. You always know which path produced a result.

Compile once, keep the structure resident

Because the compiled plan is stable across evaluations, XLOG keeps compiled artifacts resident and reuses them. For probabilistic inference this includes the compiled arithmetic circuit: training iterations update leaf weights and evidence in place without recompiling the circuit structure. For deterministic queries, build-side hash indexes for hot relations are cached and reused across evaluations in a session.

See it in the pipeline

The compilation pipeline shows exactly where the host/device boundary sits: the executor orchestrates on the host, while kernels and the relation store are resident on the GPU.