flowlog.c)Flowlog can exploit multicore systems by running parts of Prolog search in parallel using pthreads.
Parallelism is controlled through ISO-compatible Prolog flags
(set_prolog_flag/2).
By default, Flowlog runs with
flowlog_parallel_profile=fast (unordered OR-par commits for
throughput).
Flowlog supports two kinds of parallelism:
The parallel profile determines ordering:
fast (default): unordered OR-par commits
(solutions/effects may be out of order)iso: ordered OR-par commits (tries to preserve classic
enumeration order)off: sequential (no Flowlog parallel features)Classic ordered enumeration (parallel, ordered commits):
?- set_prolog_flag(flowlog_parallel_profile, iso).Maximum throughput (parallel, unordered commits):
?- set_prolog_flag(flowlog_parallel_profile, fast).Disable Flowlog parallel features (sequential):
?- set_prolog_flag(flowlog_parallel_profile, off).Flowlog provides three engines:
wamvm (default): bytecode VM for compiled clause bodies
(falls back to wam when unsupported features are used)wam: WAM-lite VM for pure/static code (falls back to
the interpreter when required)interp / tree: direct interpreter
(“tree-walking”)Parallelism is implemented by running independent solver work concurrently in multiple pthread workers:
interp and wam engines;
wamvm currently does not schedule AND-par inside compiled
bodies.)For more detail on the execution model, see IMPLEMENTATION.md.
flowlog_parallel (on|off): enable OR-par +
AND-par together.flowlog_parallel_profile (off|iso|fast):
iso: enable parallelism while keeping ordering behavior
as close to classic Prolog as possible.fast: enables unordered OR-par commits (solutions may
arrive out of order) and turns on a small amount of OR-par nesting for
better multicore saturation.flowlog_parallel_or (on|off): enable
OR-parallelism.flowlog_parallel_or_order
(ordered|unordered): commit solutions in classic
alternative order or as soon as workers finish.flowlog_parallel_and (on|off): enable
AND-parallelism for safe goal subsets.flowlog_parallel_max_depth (integer): stop spawning
parallel work beyond this call depth.flowlog_parallel_or_nesting (integer): allow nested
OR-par spawning up to this OR-par nesting level (0 =
top-level only; 1 allows OR-par inside OR-par chunks,
etc).Flowlog defaults to using the system’s online CPU count as its worker-thread count.
Override with:
--threads N (CLI), orFLOWLOG_N_CPUPROC=N (environment)OR-parallelism parallelizes alternative exploration: when a goal has many alternatives (e.g. many matching clauses, or a built-in that enumerates candidates), Flowlog can split the alternatives into “chunks” and explore them concurrently.
Implementation note:
select1/3 (and select_/3 /
select/3) as a high-quality nondet generator and can split
its list alternatives into index ranges for OR-par work. In the
wamvm engine, range chunks are executed via an internal
generator goal ($select1_range/5) so each chunk runs as a
single VM invocation.Ordering modes:
flowlog_parallel_or_order=ordered): commits solutions as
if they were produced by classic depth-first search (best for
compatibility, but can reduce throughput).flowlog_parallel_or_order=unordered): commits solutions as
soon as they are found (best for multicore saturation; solutions and
observable effects can be out of order).Cancellation:
throw/1) or a
cut commits a branch, Flowlog propagates cancellation so sibling workers
can stop early.AND-parallelism is conservative: Flowlog only parallelizes conjunction sub-goals when it can preserve ISO-visible semantics.
In practice, this means:
You can introspect parts of Flowlog’s AND-par safety rules via the built-ins:
flowlog_and_safe/2flowlog_and_safe_goal/2Parallel execution is most effective for pure code (no side effects and no reliance on solution order).
If your program depends on any of the following being sequenced “just so”, keep parallelism off or use ordered mode:
write/1, format/2,
nl/0, flush_output/0, …)assert*/1,
retract/1, …)!/0,
once/1) in combination with visible effectsTabling changes the shape of search. While tabling is active, OR-parallelism is currently disabled to keep the table state single-threaded and predictable. Tabled predicates are also treated as AND-par unsafe.
Internal OR-par runs on pthreads and may need tuning on systems with deep recursion or many cores:
FLOWLOG_ORPAR_MAX_WORKERS - cap pthread workers for
OR-par chunksFLOWLOG_ORPAR_STACK_SIZE - override pthread stack size
(bytes)By default, Flowlog auto-scales the OR-par pthread stack size based on detected physical memory and worker count.
For some heavy OR-par workloads, allocating all query-temporary objects from a single global allocator can become a bottleneck.
Flowlog supports a local allocation mode:
FLOWLOG_POOL_LOCAL_ALLOC=onThis causes query-temporary terms/envs to prefer a process-local bump allocator, reducing allocator contention.
OR-par can be debugged via environment variables:
FLOWLOG_DEBUG_ORPAR — 0/off,
1 (big choicepoints), or
2/allFLOWLOG_DEBUG_ORPAR_LOG — file path to append logsThese logs can help answer questions like: