srdatalog.ir.codegen.cuda.build.compiler

C++ compiler wrapper — turns the on-disk .cpp tree from Phase 7 into a loadable .so.

Nim offloads compilation to its C++ backend via {.compile:} pragmas; that backend shells out to the system compiler. Python has no such backend, so we invoke a compiler (clang++/g++/nvcc) directly via subprocess.

Design notes:

  • CompilerConfig carries the full toolchain + flag set. All command assembly flows through _build_compile_cmd / _build_link_cmd — unit tests can verify argv without invoking a real compiler.

  • Per-batch .cpp compilations run in parallel (ThreadPoolExecutor — subprocess bottleneck is I/O, threads are fine).

  • Hash-based build cache: we sha256 the source + the CLI flags and write a .stamp sidecar file alongside each object file. If the stamp matches, compile is a no-op. Independent of the source mtime-guard in cache.py (content didn’t change → no rewrite → no mtime bump) but works even when the source file is touched.

  • SRDATALOG_JIT_COMPILE_JOBS=N overrides parallelism (0 = cpu_count).

  • SRDATALOG_JIT_SKIP_COMPILE=1 skips compile+link entirely — the stamp cache is trusted. Mirrors SRDATALOG_SKIP_JIT_REGEN on the cache side.

Default include paths / link flags for generalized_datalog are supplied by srdatalog.runtime.runtime_include_paths() etc. — this module just consumes a CompilerConfig.

Module Contents

Classes

BuildResult

Full compile_jit_project outcome.

CompileResult

One compile invocation (source → object or link)

CompilerConfig

Compile + link configuration.

Functions

compile_cpp

Compile one .cpp.o. Short-circuits via stamp cache when the source + argv haven’t changed. Never raises on compile error — returns a CompileResult with returncode != 0 so the caller can aggregate.

compile_jit_project

Compile the .cpp tree written by cache.write_jit_project into a shared library. project_result is the dict returned by that function — we pull main and batches out and feed them in.

link_shared

Link objects + extra_sources into a shared library.

API

class srdatalog.ir.codegen.cuda.build.compiler.BuildResult[source]

Full compile_jit_project outcome.

artifact: str

None

compile_results: list[srdatalog.ir.codegen.cuda.build.compiler.CompileResult]

‘field(…)’

elapsed_sec: float

0.0

None

ok() bool[source]
class srdatalog.ir.codegen.cuda.build.compiler.CompileResult[source]

One compile invocation (source → object or link)

cached: bool

False

command: list[str]

None

elapsed_sec: float

0.0

output: str

None

returncode: int

0

stderr: str = <Multiline-String>
stdout: str = <Multiline-String>
class srdatalog.ir.codegen.cuda.build.compiler.CompilerConfig[source]

Compile + link configuration.

Defaults are minimal — cxx_std=c++23 is what the runtime headers require. Callers add include/link/libs via the list fields. extra_sources is for object files / shared libs to feed into the final link (e.g., pre-built runtime artifacts).

cxx: str = <Multiline-String>
cxx_flags: list[str]

‘field(…)’

cxx_std: str

‘c++23’

defines: list[str]

‘field(…)’

extra_sources: list[str]

‘field(…)’

include_paths: list[str]

‘field(…)’

jobs: int

0

libs: list[str]

‘field(…)’

‘field(…)’

output_dir: str = <Multiline-String>
resolved_cxx() str[source]
resolved_jobs() int[source]
shared: bool

True

srdatalog.ir.codegen.cuda.build.compiler.compile_cpp(source: str, output: str, config: srdatalog.ir.codegen.cuda.build.compiler.CompilerConfig) srdatalog.ir.codegen.cuda.build.compiler.CompileResult[source]

Compile one .cpp.o. Short-circuits via stamp cache when the source + argv haven’t changed. Never raises on compile error — returns a CompileResult with returncode != 0 so the caller can aggregate.

srdatalog.ir.codegen.cuda.build.compiler.compile_jit_project(project_result: srdatalog.ir.codegen.cuda.build.cache.JitProjectLayout, config: srdatalog.ir.codegen.cuda.build.compiler.CompilerConfig | None = None, *, use_ninja: bool | None = None) srdatalog.ir.codegen.cuda.build.compiler.BuildResult[source]

Compile the .cpp tree written by cache.write_jit_project into a shared library. project_result is the dict returned by that function — we pull main and batches out and feed them in.

Returns a BuildResult. The caller inspects .ok() and .compile_results/.link_result for errors — this function never raises on a compile/link error.

use_ninja selects the backend:

  • True / None (default): emit a build.ninja + PCH rule and invoke the ninja binary (from the ninja PyPI wheel). Best wall time on multi-TU projects because srdatalog.h is precompiled once and reused across every shard.

  • False: fall through to the ThreadPoolExecutor path below (one subprocess per TU, no PCH). Useful on hosts without ninja or for debugging a single TU’s compile command.

SRDATALOG_JIT_NO_NINJA=1 forces use_ninja=False regardless of the argument.

Link objects + extra_sources into a shared library.