Parallelism (--cores)
Run verification with multiple parallel worker threads.
Syntax
sector9 --verify --cores <n> file.sr9
The <n> parameter specifies the number of parallel verification threads. This maps to Silicon's --numberOfParallelVerifiers flag with the value n-1.
Normal sector9 --verify runs default to one coordinating verifier thread
unless you pass --cores. The raw VPR helper scripts/verify-vpr.sh defaults
to one Silicon verifier worker explicitly so emitted-VPR timing comparisons are
stable. Override that helper with VERIFY_VPR_PARALLEL_VERIFIERS=N when you are
intentionally measuring raw Silicon worker scaling.
Examples
# Use 4 cores (3 parallel verifiers + 1 main thread)
sector9 --verify --cores 4 file.sr9
# Use 8 cores for larger programs
sector9 --verify --cores 8 file.sr9
# Single-threaded verification (default)
sector9 --verify file.sr9
# Combine with timeout for CI
sector9 --verify --cores 4 --verify-timeout-ms 60000 file.sr9
How It Works
The --cores N flag controls Silicon's internal parallelization:
- Thread allocation: Silicon spawns
N-1additional verifier threads beyond the main thread - Method-level parallelism: Each verifier thread can work on a different method's proof obligations
- Backend scheduling: Silicon schedules independent obligations across those workers and invokes Z3 as needed
For example, --cores 4 results in 3 additional workers plus the main thread, giving 4 total verification threads.
When Parallelism Helps
Parallelism provides the most benefit when:
- Multiple methods: Programs with several independent methods can verify in parallel
- Independent obligations: Methods with separate proof obligations benefit from concurrent solving
- Balanced workloads: Methods with similar verification complexity maximize throughput
Parallelism provides limited benefit when:
- Single method: One large method cannot be parallelized internally
- Quantifier-heavy code: Complex
forall/existspatterns bottleneck on SMT solving - Dependency chains: Methods that depend on each other's specifications
Recommended Values
| Scenario | Cores | Notes |
|---|---|---|
| Development | 2-4 | Fast feedback during iteration |
| Multiple methods | 4-8 | Match available CPU cores |
| CI pipelines | 4 | Balance speed and resource usage |
| Resource-constrained | 1-2 | Minimize memory overhead |
Memory Considerations
Each parallel verifier uses additional memory:
- Stack: 16 MB per thread (
-Xss16mJVM setting) - Heap: Shared 2 GB pool (
-Xmx2048mJVM setting)
With --cores 8, expect approximately 128 MB of stack memory plus shared heap usage. For very high core counts, monitor memory to avoid contention.
Combining with Other Flags
With timeout
Parallelism can reduce wall-clock time, allowing shorter timeouts:
sector9 --verify --cores 4 --verify-timeout-ms 30000 file.sr9
With JSON output
For CI integration with parallel verification:
sector9 --verify --cores 4 --json file.sr9
With counterexamples
Debug verification with parallelism and model extraction:
sector9 --verify --cores 4 --counterexample file.sr9
Environment Variable Override
The SILICON_FLAGS environment variable can pass additional flags directly to Silicon:
SILICON_FLAGS="--numberOfParallelVerifiers=4" sector9 --verify file.sr9
Use this only for advanced Silicon tuning. It is passed through to the backend and can conflict with --cores if you duplicate the same Silicon option.
For raw emitted VPR files:
VERIFY_VPR_PARALLEL_VERIFIERS=2 ./scripts/verify-vpr.sh debug.vpr
Prefer the default one-worker setting for performance baselines, then run file-level jobs in parallel outside Silicon when comparing several generated VPR files.
Troubleshooting
Verification is not faster with more cores
- Check method count: Single-method programs do not benefit from parallelism
- Profile quantifiers: Complex quantifiers are SMT-bound, not parallelizable
- Reduce nesting: Deeply nested quantifiers serialize on the solver
High memory usage
- Reduce cores: Each thread adds memory overhead
- Use bounded quantification: Unbounded quantifiers increase solver state
Inconsistent results
- Use
--deterministic: Ensure reproducible verification artifacts - Reduce parallelism: Lower core counts have less scheduling variance
- Compare with
--cores 1: This isolates backend scheduling from proof changes
Implementation Details
The verification pipeline:
- Sector9 translates Sector9 source to Viper intermediate representation
- Silicon is launched as a Java subprocess with
--numberOfParallelVerifiers - Silicon spawns worker threads that consume proof obligations
- Z3 solves SMT queries from all threads
- Results are collected and mapped back to source locations
Process isolation:
- Silicon runs in its own session group (
setsid) - Timeout termination sends
SIGTERMthenSIGKILLto the entire process tree - This ensures Z3 child processes are properly cleaned up
Summary
--cores Nsets parallel verification threads (mapped toN-1Silicon verifiers)- Default is single-threaded verification
- Best for programs with multiple independent methods
- Memory scales with core count (16 MB stack per thread)
- Combine with
--verify-timeout-msfor faster CI pipelines - Use
SILICON_FLAGSfor advanced Silicon configuration - Prefer
--verify-timeout-msand--deterministicin CI