Skip to content

BranchCore work - #115

Closed
guanqin-123 wants to merge 15 commits into
SVF-tools:mainfrom
guanqin-123:TensorCE
Closed

guanqin-123 wants to merge 15 commits into
SVF-tools:mainfrom
guanqin-123:TensorCE

Conversation

@guanqin-123

@guanqin-123 guanqin-123 commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor
  • CLIMB certificate reuse (opt-in): replays certified dual certificates as ReLU phase cores and propagates them to prune BaB subproblems early.
  • Sound dual bounds for large conv nets (VGG16): forward bounds are symbolic only in the perturbed dimensions and MaxPool has a linear relaxation, with centre–radius numerics and lane chunking. Fixes the lb > ub crash.
  • BaB config and branching fixes: reuse_root_bounds becomes the root_bounds_reuse tri-state and a forward_lin_max_perturbed cap is added. Input splits can no longer pick a zero-width dimension.

@codecov

codecov Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.44576% with 551 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.59%. Comparing base (e9ed992) to head (f7e8eb4).

Files with missing lines Patch % Lines
act/back_end/bab/branching/multi_split.py 51.95% 86 Missing ⚠️
act/back_end/bab/violation.py 59.62% 86 Missing ⚠️
act/back_end/bab/climb.py 88.80% 63 Missing ⚠️
act/back_end/bab/node.py 63.15% 56 Missing ⚠️
.../front_end/torchvision_loader/data_model_loader.py 66.66% 43 Missing ⚠️
act/back_end/dual_tf/tf_forward.py 81.48% 35 Missing ⚠️
act/back_end/solver/solver_dual.py 85.10% 28 Missing ⚠️
act/back_end/bab/bab.py 80.43% 27 Missing ⚠️
act/back_end/bab/branching/branching.py 80.34% 23 Missing ⚠️
act/front_end/vnnlib_loader/data_model_loader.py 76.47% 20 Missing ⚠️
... and 17 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #115      +/-   ##
==========================================
+ Coverage   75.44%   77.59%   +2.14%     
==========================================
  Files          91       94       +3     
  Lines       22575    22985     +410     
==========================================
+ Hits        17032    17835     +803     
+ Misses       5543     5150     -393     
Flag Coverage Δ
bab 50.98% <66.51%> (+7.42%) ⬆️
backend-float32 50.27% <31.64%> (+0.78%) ⬆️
backend-float64 52.01% <31.96%> (+0.74%) ⬆️
frontend 30.83% <18.74%> (-0.72%) ⬇️
pipeline-fuzz 20.31% <11.42%> (-0.06%) ⬇️
pipeline-verify 43.25% <36.06%> (+1.60%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
act/back_end/__init__.py 100.00% <ø> (ø)
act/back_end/bab/__init__.py 100.00% <100.00%> (ø)
act/back_end/hybridz_tf/hybridz_tf.py 95.76% <100.00%> (+0.28%) ⬆️
act/back_end/hybridz_tf/tf_transformer.py 78.60% <100.00%> (+0.32%) ⬆️
act/back_end/layer_util.py 69.74% <100.00%> (+0.89%) ⬆️
act/back_end/net_factory.py 88.33% <100.00%> (+0.50%) ⬆️
act/back_end/serialization/serialization.py 88.09% <100.00%> (+12.09%) ⬆️
act/back_end/transfer_functions.py 90.62% <100.00%> (+0.62%) ⬆️
act/back_end/verifier.py 83.91% <100.00%> (-0.32%) ⬇️
act/pipeline/__init__.py 100.00% <ø> (+57.14%) ⬆️
... and 31 more

... and 5 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e9ed992...f7e8eb4. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@yuleisui

Copy link
Copy Markdown
Collaborator

Please fix the coverage ci

@guanqin-123

Copy link
Copy Markdown
Contributor Author

Please fix the coverage ci

Finished. after this, the upcoming pr to support SST, and YELP (NLP verification instance that contains a transformer architecture)

Comment thread .github/workflows/act-bab.yml Outdated
Comment on lines +401 to +413
--network "$ACT_NETS_DIR/mlp_plain_3x8_64x64_3962224133.json" \
--solver dual --bab --bab-solver-tier dual_alpha_eta \
--bab-branching babsr --bab-bounding depth_bound_blend \
--bab-root-bounds-reuse none --bab-intermediate-refine none \
--bab-per-subproblem-refine none --bab-climb-enabled \
--bab-climb-theta 0.5 --bab-climb-recheck-k 2 \
--bab-multi-split-levels 1 --bab-max-batch-size 16 \
--bab-max-depth 10 --bab-max-subproblems 90 --timeout 80 \
--device cpu --dtype float64 --verbose 2>&1)
echo "$out"
grep -qE "climb_cores_inserted: [1-9]" <<<"$out"
grep -qE "climb_main_bound_calls: [1-9]" <<<"$out"
grep -qE "climb_propagate_time_s: (0\.[0-9]*[1-9]|[1-9])" <<<"$out"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make sure the below:

(1) Options in command line will also have the same mirrored one in yaml?
(2) Try to reduce the number of command line here in the CI file if possible
(3) I am not sure what grep commandline is doing here. Are these grep lines doing validation? I would suggest adding more assertions in your code so that we could catch any issues or implementation bugs and pinpoint them in the source code.

Please do so in the below two CI tests too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

Comment thread act/back_end/bab/bab.py
@@ -8,46 +8,55 @@
#

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current bab.py is too large and should be simplified and obsolete code should be removed.

# All tensor shapes follow the (N, D) batch convention for batch-parallel scoring.
#
# ===---------------------------------------------------------------------====#

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This branching.py is too large close to 2k lines of code after your update. Redundant or obsolete code should be removed for future maintanance purposes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now split.

…to branching/ and node.py; take CLIMB margins and BaB batch size from central config
…it, top-k pool, MCTS visits, witness decisions
…stored tensors instead of re-running the batched wrapper
…); smart_turn CI step asserts the rejection instead of || true
Comment thread .github/workflows/act-bab.yml Outdated
Comment on lines +112 to +113
set -e
test "$status" -eq 3

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to set +e and test? Can we use raise asserts instead?

Comment thread .github/workflows/act-bab.yml Outdated
Comment on lines +201 to +203
--timeout 20 --bab-max-depth 2 --bab-max-subproblems 5 >/dev/null 2>&1
status=$?
set -e

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use raise assert?

Comment thread .github/workflows/act-bab.yml Outdated
Comment on lines +394 to +402
set +e
out=$(coverage run -p -m act.back_end --verify \
--network "$ACT_NETS_DIR/mlp_plain_3x8_64x64_3962224133.json" \
--solver dual --bab --bab-preset climb \
--bab-bounding random --bab-max-depth 1 --bab-max-subproblems 1 2>&1)
status=$?
set -e
echo "$out"
test "$status" -eq 2

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use raise asert instead of outputing them in a text file?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, now fix.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are all asserts added in the backend folder? I didn't find the changes you made?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please point me to where the asserts were added. If not, please try to do another round of searching, fix the "print errors" and make them all as strict assertions.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@guanqin-123 please review and update.

Comment on lines +12 to +16
# Implements the 2^k sign-combination fan-out described in "Mining Verdict
# Boundaries for Neural Network Verification" (Jiawei Ren, Guanqin Zhang,
# Zhenya Zhang, Yulei Sui, FM 2026). Each lane's top-k BaBSR-scored neurons
# are split together into all 2^k sign combinations in a single wave; the
# joint gain is super-additive versus k greedy single splits.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should put ecoop and this FM in the vnnlib-comp references, as both are implemented in ACT

Comment thread act/config/backend.yaml
intermediate_refine: "all"
multi_split_levels: 4

climb:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to explain the options in comments, as quite a number of variables/options in this file need a description.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

guanqin-123 and others added 2 commits September 25, 2026 13:48
…d, util, vnncomp); explicit fallbacks; fix NaN in HybridZ softmax ratio bound
core: raise on errors instead of printing or returning empty
@@ -0,0 +1,84 @@
#===- act/front_end/vnnlib_loader/test_multi_input_rejection.py - Multi-Input --====#

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this file for? Do we need it or could some of these put in the CI?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's for my local testing, deleted.

Comment thread act/config/backend.yaml
# Layout (all under the single top-level `backend:` mapping):
# runtime selectors → verification cascade → torchlp → tf → hybridz
# → bab (branch-and-bound)
# Layout:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all the options (variable names), please try to add a comment for each variable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revised.

…ced in source

Remove the three set +e exit-status steps (smart_turn multi-input, top-k with random/mcts, CLIMB with non-TopK bounding) and the smart_turn download. The rejections are unchanged: BaBConfig.__post_init__ and validate_climb_config raise ConfigError (back-end CLI exit 2), and the VNNLIB pre-scan raises UnsupportedSpecError (pipeline exit 3).
Comments only; values are unchanged (the YAML parses identically and check_parity passes).
Every key now has its own comment giving its unit, valid values and special values, checked against the code. Fixes comments that were wrong: torchlp.stagnation_patience counts iterations; backend.timeout is given in full to the LP tier and to each BaB run; hybridz.timeout null/0 falls back to backend.timeout; sigmoid_segments applies to Sigmoid only; llm_probe_neuron_topk=0 keeps the FSB fallback; bab.verbose is not read yet. Comments only; values unchanged.
Silent failures now raise:
- torch2act/act2torch test harnesses raise when a conversion or test case
  fails or when nothing ran, instead of printing and exiting 0. Drop the
  torch2act placeholder verification block (verify_once was commented out
  and its status hard-coded to SKIPPED). act2torch reports property
  outcomes on random-weight nets as counterexamples, not "Test FAILED".
- VNNLIB/TorchVision spec creation collects per-instance failures and
  raises; unreadable files and invalid specs raise instead of returning
  None/{}/False, and spec creators no longer fall back to hard-coded
  defaults when the YAML config fails to load.
- Back end: narrow broad except clauses in witness branching, attention
  slopes, the interval refresh and the TF self-heal.
@guanqin-123

Copy link
Copy Markdown
Contributor Author

we added assertion to replace try except and return 0 @yuleisui

@yuleisui

Copy link
Copy Markdown
Collaborator

we added assertion to replace try except and return 0 @yuleisui

Could you list the program lines that you changed to asserts? I didn't find them in the recent commit.

@yuleisui

Copy link
Copy Markdown
Collaborator

This is a very large pull request (52 files changed and many of them are restructured). I’d like it to be simplified by removing legacy and unused code, identifying and consolidating code with similar functionality, and reducing duplication as much as possible to make it easier to review and maintain. Please also point out in the reply where you changed or added your asserts.

@yuleisui

Copy link
Copy Markdown
Collaborator

This is a very large pull request (52 files changed and many of them are restructured). I’d like it to be simplified by removing legacy and unused code, identifying and consolidating code with similar functionality, and reducing duplication as much as possible to make it easier to review and maintain. Please also point out in the reply where you changed or added your asserts.

@Kaijie-liu could you also help review this pull request, as it involves quite a lot in the backend and should be compact and extendable for later work.

@guanqin-123

Copy link
Copy Markdown
Contributor Author

we added assertion to replace try except and return 0 @yuleisui

Could you list the program lines that you changed to asserts? I didn't find them in the recent commit.

• bab.py#L200: multi-split counters
• node.py#L207, #L365, #L377: neuron split / child sub-problems
• branching.py#L765: witness residual
• bounding.py#L467, #L477, #L1005: top-k pool, MCTS visits
• multi_split.py#L89: score shape
• utils.py#L86: every layer reads only its predecessors' outputs (caught BatchNorm's SCALE being bypassed)
• frontend_cli.py#L247, #L254, #L288, #L783, #L844: download / inference succeeded
• pipeline_cli.py#L441, #L450, #L457: download succeeded
• torchvision_loader/cli.py#L340, #L604: download / inference succeeded
• torchvision_loader/data_model_loader.py#L277, #L901: all splits downloaded, no pair failed
• vnnlib_loader/cli.py#L272, data_model_loader.py#L255: category / every file downloaded
• vnnlib_parser.py#L679: bounded X_i is a declared input

CLI commands no longer swallow failures:
- front_end (--download/--synthesis/--inference/--info), pipeline
  (--download/--info) and the vnnlib/torchvision loader CLIs re-raise after
  printing their hints, assert that every download/inference result is
  'success', and drop catch-all handlers, so a failed step exits non-zero
  (CI's --synthesis step previously exited 0 on failure).
- Loaders let exceptions propagate instead of converting them into
  {'status': 'error'} dicts; a partially failed dataset or VNNLIB category
  download, an unreadable info.json/instances.csv, and a failed batch load
  now raise where they happen.

Silent fallbacks become assertions or propagated errors:
- VNNLIB: an unparsable property no longer yields empty input bounds, and
  bounds on X_i beyond the declared inputs are asserted.
- ONNX Where/MinMax/Compare no longer guess an output shape when operand
  shapes do not broadcast; constant-subgraph evaluation and ASSERT-layer
  re-encoding errors propagate; the fuzzing report no longer zeroes
  coverage on error; BERT tokenisation falls back to regex only when nltk
  or its data is missing; solver "auto" picks Gurobi only when gurobipy is
  importable instead of hiding Gurobi errors.
- model_inference handles parameter-free models and unlabelled or
  non-classification outputs instead of crashing (previously masked by the
  --synthesis catch-all).

Legacy, unused and duplicated code removed:
- Unreferenced legacy helpers: ACTStats/ACTLog (util/stats.py); the unused
  PerformanceProfiler/ParallelExecutor/ProgressTracker/retry/timeout harness
  in pipeline/verification/utils.py and its act.pipeline re-exports;
  Config.to_yaml (x2); eight unused Net/Layer accessors in back_end/core.py;
  convert_and_save_pytorch; net_factory.append_concat; get_solver_mode.
- branching.py: the serial-evaluation fallback for "legacy solvers" was
  unreachable (FSB always receives a DualSolver, the only solver that
  implements compute_certified_bound); removed with its two catch-all
  except clauses, so a wrong candidate dimension now raises.
- pipeline_cli: the five data-model commands (list/search/info/download/
  list-downloaded) duplicated frontend_cli's unified handlers; dispatch to
  those instead.
@guanqin-123

Copy link
Copy Markdown
Contributor Author

split this large pr in the future following pr. now closde here.

yuleisui pushed a commit that referenced this pull request Oct 13, 2026
Part 1 of 3 of the TensorCE work (#115): the changes that are independent
of the BaB/CLIMB restructuring.

Errors are raised where they occur instead of printed or swallowed:
- back_end core/serialization/layer_util/solver_hz/hybridz_tf and util
  raise instead of printing or returning empty results; fix a NaN in the
  HybridZ softmax ratio bound.
- vnnlib: reject multi-input properties before parsing (pipeline exit 3);
  fuzzing exits 1 on failure and writes counterexample witnesses from the
  stored tensors.
- torch2act/act2torch harnesses raise on failed conversions or test cases
  and when nothing ran; spec creation raises per-instance failures; the
  front_end, pipeline and loader CLIs assert download/inference success and
  re-raise after printing their hints instead of exiting 0.

Torch->ACT conversion:
- Convert nn.ReLU6 and F.adaptive_avg_pool2d (torchvision mobilenet_v2;
  CI's torch2act step hid 4/36 failed conversions behind PASSED).
- Enter chain conversions (BatchNorm -> SCALE + BIAS, c - x,
  DequantizeLinear) at their head: the incoming edge bypassed SCALE, so
  abstract interpretation ran on a different network than the PyTorch
  model (SVHN resnet18: output 0.95 outside the bounds -> 7e-15 after).
  TorchToACT.run asserts that every layer reads only variables produced by
  its predecessors.

Legacy and duplicated code removed: ACTStats/ACTLog; the unused profiler,
parallel-executor and retry/timeout harness in pipeline/verification/utils
and its act.pipeline re-exports; Config.to_yaml (x2); unused Net/Layer
accessors; convert_and_save_pytorch; net_factory.append_concat;
get_solver_mode. pipeline_cli's data-model commands now dispatch to
frontend_cli's unified handlers instead of duplicating them.
yuleisui added a commit that referenced this pull request Oct 13, 2026
Fail loudly on errors; fix Torch->ACT conversion; remove legacy code (part 1/3 of #115)
yuleisui pushed a commit that referenced this pull request Oct 14, 2026
Part 2 of 3 of #115.

- Forward bounds keep explicit linear terms only for the perturbed input
  dimensions (DualConfig.forward_lin_max_perturbed, default 100, mirrored
  in backend.yaml); above the cap the forward pass is interval-only.
- MaxPool gets a linear relaxation; conv bounds use centre-radius numerics
  with lane chunking. Fixes the lb > ub crash on VGG16.
yuleisui added a commit that referenced this pull request Oct 14, 2026
Sound dual bounds for large conv nets (part 2/3 of #115)
guanqin-123 added a commit to guanqin-123/ACT that referenced this pull request Oct 14, 2026
Part 3 of 3 of SVF-tools#115 (parts 1 and 2 merged as SVF-tools#116 and SVF-tools#118).

- CLIMB certificate reuse (opt-in): certified dual certificates are
  replayed as ReLU phase cores and propagated to prune BaB subproblems
  early (bab/climb.py).
- BaB restructuring: split, violation-check and multi-split logic move
  out of bab.py into node.py, violation.py and branching/multi_split.py
  (bab.py 2191 -> 1151 lines, branching.py 1217 -> 1094).
- BaB config: reuse_root_bounds becomes the root_bounds_reuse tri-state;
  CLIMB preset; every backend.yaml option documented; input splits can
  no longer pick a zero-width dimension.
- CI: act-bab.yml grep checks replaced by in-source invariants and
  exit-status checks.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants