-
Notifications
You must be signed in to change notification settings - Fork 0
JNI and Java API
The Java classes and the ABI of
libmtpnddjni.soare identical on both branches: the same Java code runs unchanged against either thefeature/c.so (C + Sylvan + Lace) or thefeature/go.so (pure Go, goroutine-based). Drop in whicheverlibmtpnddjni.soyou want benchmarked.
The Java API lives under jni/. It consists of:
- A JNI shim compiled into
libmtpnddjni.so-
feature/c:jni/src/main/native/mtpndd_jni.c→ Sylvan/Lace C core -
feature/go:jni/main.go→ pure-Go core, viacgo -buildmode=c-shared
-
- Pure-Java classes in
jni/src/main/java/org/ants/mtpndd/:-
MTPNDDEngine— lifecycle + operation entry points -
MTPNDD— thin handle over a native node pointer -
MTPNDDConfig— builder-pattern configuration
-
The top-level CMake build produces build/jni/libmtpnddjni.so when MTPNDD_BUILD_JNI=ON (default).
cmake -B build
cmake --build build -j # builds native C + JNI .soThen build the Java JAR:
cd jni
mvn -DskipTests package # produces target/mtpndd-java-0.1.0-SNAPSHOT.jar
mvn test # runs the JUnit 5 suiteThe Java side resolves the native library in this order:
-
org.ants.mtpndd.library.pathsystem property (explicit path tolibmtpnddjni.so) - Auto-discovery under the project's
build/jni/(new layout) orjni/build/(legacy standalone build) -
java.library.pathviaSystem.loadLibrary("mtpnddjni")
Explicit override:
java -Dorg.ants.mtpndd.library.path="$PWD/build/jni/libmtpnddjni.so" \
-cp jni/target/mtpndd-java-0.1.0-SNAPSHOT.jar:jni/target/test-classes \
org.ants.mtpndd.NQueensMTPNDD 8 onehotimport org.ants.mtpndd.*;
MTPNDDEngine.init(new MTPNDDConfig.Builder()
.workers(6)
.mtpnddNodeTableSize(1L << 20)
.operationCacheSize(1L << 20)
.build());
int fieldA = MTPNDDEngine.declareField(8); // 8-bit field
int fieldB = MTPNDDEngine.declareField(4);
MTPNDDEngine.generateFields();
MTPNDD x = MTPNDD.getVar(fieldA, 0); // literal: fieldA bit 0 = 1
MTPNDD y = MTPNDD.getNotVar(fieldA, 1); // literal: fieldA bit 1 = 0
MTPNDD f = MTPNDDEngine.and(x, y);
MTPNDDEngine.ref(f);
double sat = MTPNDDEngine.satCount(f);
System.out.println("sat count = " + sat);
MTPNDDEngine.deref(f);
MTPNDDEngine.shutdown();| Method | Notes |
|---|---|
init(MTPNDDConfig) |
Initialize Lace + Sylvan + MTPNDD with the given config |
shutdown() |
Shut down in the correct order (Sylvan before Lace) |
isInitialized() |
true between init and shutdown
|
| Method | Notes |
|---|---|
int declareField(int bitWidth) |
Register a field, returns its id. Must precede generateFields()
|
generateFields() |
Finalize; afterwards declareField is no longer permitted |
MTPNDDFieldInfo getFieldInfo(int fieldId) |
Field metadata (bit width, var offset, …) |
and, or, not, diff, exist(value, fieldId). Batched forms: andBatch(lefts[], rights[]), orReduce(values[]), andReduce(values[]).
satCount, minZeros, leafCount, abstractPlus(node, fieldId), abstractPlusValidate(node).
ref(node), deref(node). Every node returned by an op is already referenced; call deref when you're done with it.
makeFraction(numer, denom), makeDouble(value), plus, minus, times, divide, leafGc().
stats() returns native counters (node table occupancy, op cache hits, GC events). resetTiming() / printTimingReport() control Java-side timing around JNI calls.
Thin wrapper around a native pointer with ergonomic instance methods:
- Boolean:
and(other),or(other),diff(other),not(),exist(fieldId) - Counting:
satCount(),minZeros() - Predicates:
isTrue(),isFalse(),isTerminal() - Introspection:
getFieldId(),getEdges()(returnsMTPNDDEdges) - Lifecycle:
ref(),deref() - Static builders:
MTPNDD.getVar(field, idx),getNotVar(field, idx),getTrue(),getFalse()
Fluent builder mirroring every field in the C mtpndd_pal_config_t. See Configuration Reference for defaults and semantics.
MTPNDDConfig cfg = new MTPNDDConfig.Builder()
.workers(6) // 0 = auto-detect
.laceDequeSize(1L << 20)
.bddNodeTableSize(1L << 22)
.mtpnddNodeTableSize(1L << 20)
.operationCacheSize(1L << 20)
.quickGrowthThreshold(0.75) // -1 to disable
.edgeBucketCount(8) // power of 2, ≤ 64
.nodetableBucketCount(65537)
.nodeSlabCapacity(1024)
.edgeEntrySlabCapacity(4096)
.nodetableEntrySlabCapacity(2048)
.edgeMapSlabCapacity(2048)
.build();The JUnit 5 suite lives at jni/src/test/java/org/ants/mtpndd/. @BeforeAll helpers discover the .so from build/jni/ (current layout) or jni/build/ (legacy). Running mvn test exercises both the boolean path (nqueens-style) and the MT/fraction path.
The Go-side bridge at jni/main.go + jni/exports.go presents the
same JNI surface but auto-tunes the Go engine for long-running JNI
hosts. Callers never set these — they're hardcoded in mapInitArgs
when the init path detects the JNI entry:
| Setting | Go-native default | JNI override | Why |
|---|---|---|---|
SpawnPairThreshold |
4 | 1024 | Disable in-Go goroutine spawning. SRE's N Java worker threads already saturate cores making independent JNI calls; in-Go spawn became 25 %+ of CPU in runtime.futex / runtime.schedule. Cut fattree08 MF=3 from 28.9 s → 15.8 s (v1.9) |
NDD.CacheClearInterval |
2²¹ (~2 M puts) | 2⁶² (effectively off) | Go's strong-ref design means periodic clears drop otherwise-live hits; cachePutCount atomic contention also showed up in profiles (v1.10 / v1.14) |
BDD.CacheClearInterval |
2²¹ | 2⁶² | Same |
SlabChunkSize |
2¹⁸ = 256 K nodes | same (ignores nodeSlabCapacity) |
sre-ndd passes 2048 as a C batch-size constant; applying it as a Go chunk size shrinks chunks 128× and overflowed the chunk directory on ft12+. Fixed in 2cf68e8 by ignoring that field |
MTPNDD_BDD_SPAWN_CUTOFF env var is not honoured by the Go
backend (it's a Sylvan concept). Optional -tags pprof build
exposes an HTTP pprof endpoint — useful for profiling under the sre-ndd
harness.
Handle representation: the Go bridge casts *mtpndd.Node to
uintptr and hands that to Java as jlong. The same cast goes in the
reverse direction on method entry. No handle table, no weak wrapper —
relies on feature/go's strong-ref lifetime model keeping nodes alive
until MTPNDDEngine.shutdown() (which triggers mtpndd.Reset()).
Headline (feature/go v1.18 vs feature/c, w=4): ft08 MF=3 2.31× · ft12 MF=3 2.92× · nqueens N=13 22 % faster — see Performance.
feature/go @ b8e651c · feature/c @ head · Apache-2.0
Maintained by Augists (<augists@duck.com>). Issues & PRs: github.com/Augists/mtpndd.