Batch Processing
batch_find_untargeted_attack enables users to run find_adversarial_example for multiple samples from a single dataset, writing 1) a single summary .csv file for the dataset, with a row of summary results per sample, and 2) a file per sample containing the output dictionary from find_adversarial_example.
batch_find_untargeted_attack allows verification of a dataset to be resumed if the process is interrupted by intelligently determining whether to rerun find_adversarial_example on a sample based on the solve_rerun_option specified.
Resuming against a summary written by an older MIPVerify version upgrades its schema in memory; the upgraded file is written back only when the batch appends a new result, so a batch that schedules no work leaves the archived summary untouched. Rows from older summaries keep their historical rerun scheduling: a recorded numeric objective counts as a completed attack for resolve_ambiguous_cases, even though it is not a verified witness. Rerun with always to replace legacy evidence with verified witnesses.
Index
MIPVerify.batch_find_targeted_attackMIPVerify.batch_find_untargeted_attackMIPVerify.extract_results_for_saveMIPVerify.has_available_unverified_witnessMIPVerify.has_legacy_objective_valueMIPVerify.has_verified_witnessMIPVerify.is_infeasibleMIPVerify.persist_summary_migration!MIPVerify.read_summary_fileMIPVerify.run_on_sample_for_targeted_attackMIPVerify.run_on_sample_for_untargeted_attackMIPVerify.save_to_diskMIPVerify.should_refine_insecureMIPVerify.should_resolve_ambiguousMIPVerify.summary_witness_marginMIPVerify.uses_feasibility_objectiveMIPVerify.validate_batch_refinement_objective
Public Interface
MIPVerify.batch_find_untargeted_attack — Method
batch_find_untargeted_attack(
nn,
dataset,
target_indices,
optimizer,
main_solve_options;
save_path,
solve_rerun_option,
pp,
norm_order,
tightening_algorithm,
tightening_options,
solve_if_predicted_in_targeted,
adversarial_example_objective
)
Runs find_adversarial_example for the specified neural network nn and dataset for samples identified by the target_indices, with the target labels for each sample set to the complement of the true label.
It creates a named directory in save_path, with the name summarizing
- the name of the network in
nn, - the perturbation family
pp, - the
norm_order.
Within this directory, a summary of all the results is stored in summary.csv, and results from individual runs are stored in the subfolder run_results.
This function is designed so that it can be interrupted and restarted cleanly; it relies on the summary.csv file to determine what the results of previous runs are (so modifying this file manually can lead to unexpected behavior.)
If the summary file already contains a result for a given target index, the solve_rerun_option determines whether we rerun find_adversarial_example for this particular index.
optimizer specifies the optimizer used to solve the MIP problem once it has been built and main_solve_options specifies the options that will be passed to the optimizer for the main solve.
Named Arguments:
save_path: Directory where results will be saved. Defaults to current directory.pp, norm_order, tightening_algorithm, tightening_options, adversarial_example_objective, solve_if_predicted_in_targetedare passed through tofind_adversarial_exampleand have the same default values; see documentation for that function for more details.solve_rerun_option::MIPVerify.SolveRerunOption: Options arenever,always,resolve_ambiguous_cases, andrefine_insecure_cases. Seerun_on_sample_for_untargeted_attackfor more details.refine_insecure_casesrejects thefeasibilityobjective because refinement computes an exact objective.
Internal
MIPVerify.batch_find_targeted_attack — Method
batch_find_targeted_attack(
nn,
dataset,
target_indices,
optimizer,
main_solve_options;
save_path,
solve_rerun_option,
target_labels,
pp,
norm_order,
tightening_algorithm,
tightening_options,
solve_if_predicted_in_targeted,
adversarial_example_objective
)
Runs find_adversarial_example for the specified neural network nn and dataset for samples identified by the target_indices, with each of the target labels in target_labels individually targeted.
Otherwise same parameters as batch_find_untargeted_attack.
MIPVerify.extract_results_for_save — Method
extract_results_for_save(result)Build the serializable subset of a solver-backed result without mutating result. Numeric witness values are retained whenever a candidate is available, including when independent verification fails. Unavailable objective values and bounds are stored as NaN.
MIPVerify.has_available_unverified_witness — Method
has_available_unverified_witness(row)Return whether row records an available candidate that does not pass every independent witness check. Missing or inconsistent verification fields fail closed through has_verified_witness.
MIPVerify.has_legacy_objective_value — Method
has_legacy_objective_value(row)Return whether an older row has numeric objective evidence but predates independent perturbation verification. This evidence is not a verified witness, but it keeps a legacy row's historical scheduling: it may select the row for an exact rerun and counts as a completed attack for resolve_ambiguous_cases.
MIPVerify.has_verified_witness — Method
has_verified_witness(row)Return true only when all four witness flags exist, are non-missing, and are true. Incomplete or internally inconsistent legacy rows fail closed.
MIPVerify.is_infeasible — Method
is_infeasible(status)Return whether a solve status is exactly INFEASIBLE, given either a MathOptInterface.TerminationStatusCode or its string form. Combined or ambiguous statuses, including INFEASIBLE_OR_UNBOUNDED, do not certify infeasibility. This is the single source of truth for that rule; BenchmarkHelpers.is_infeasible_status delegates to it.
MIPVerify.persist_summary_migration! — Method
persist_summary_migration!(summary_file_path, dt, needs_migration)Rewrite summary_file_path from the in-memory migrated dt and clear needs_migration. Callers invoke this immediately before appending the first new summary row, so the appended row aligns with the migrated header and an append-free batch never modifies the archived file.
MIPVerify.read_summary_file — Method
read_summary_file(summary_file_path)Read a batch summary and upgrade its schema in memory when necessary, returning the migrated DataFrame and whether it differs from the file on disk. The file itself is never modified here; persist_summary_migration! writes the migration immediately before the first new row is appended, so a batch that appends nothing leaves the archive untouched. The migration treats only plain INFEASIBLE as proven infeasible and leaves unavailable legacy objective and witness fields as missing. Non-missing objective names must match a current AdversarialExampleObjective. Summaries from the unreleased boolean-objective schema are rejected instead of migrated. Unrelated extra columns are retained.
MIPVerify.run_on_sample_for_targeted_attack — Method
run_on_sample_for_targeted_attack(
sample_number,
target_label,
summary_dt,
solve_rerun_option
)
Determines whether to run a solve on a sample depending on the solve_rerun_option by looking up information on the most recent completed solve recorded in summary_dt matching sample_number.
summary_dt is expected to be a DataFrame with columns :SampleNumber, :TargetIndexes, :SolveStatus, :ObjectiveValue, :WitnessAvailable, :WitnessTargetVerified, :WitnessPerturbationVerified, and :WitnessVerified. A witness from an older summary that lacks either independent check is unresolved as a verdict, but its numeric objective evidence keeps the row's historical scheduling: it counts as a completed attack for resolve_ambiguous_cases and can still select a non-optimal result for exact refinement.
MIPVerify.run_on_sample_for_untargeted_attack — Method
run_on_sample_for_untargeted_attack(
sample_number,
summary_dt,
solve_rerun_option
)
Determines whether to run a solve on a sample depending on the solve_rerun_option by looking up information on the most recent completed solve recorded in summary_dt matching sample_number.
summary_dt is expected to be a DataFrame with columns :SampleNumber, :SolveStatus, :ObjectiveValue, :WitnessAvailable, :WitnessTargetVerified, :WitnessPerturbationVerified, and :WitnessVerified. A witness from an older summary that lacks either independent check is unresolved as a verdict, but its numeric objective evidence keeps the row's historical scheduling.
Behavior for different choices of solve_rerun_option:
never:trueif and only if there is no previous completed solve.always:truealways.resolve_ambiguous_cases:trueif there is no previous completed solve, or if the most recent completed solve has neither a verified counterexample nor a proof of infeasibility, or if an available witness failed verification despite a contradictory infeasible status. Legacy rows without witness columns keep their historical meaning for scheduling: a recorded numeric objective counts as a completed attack and is not rerun.refine_insecure_cases:trueif there is no previous completed solve, or if the most recent complete solve a) did find a verified counterexample, or recorded legacy objective evidence, but b) did not reach a provably optimal exact objective. A feasibility result still needs refinement even when it terminated withOPTIMAL.
MIPVerify.save_to_disk — Method
save_to_disk(sample_number, main_path, results_dir, summary_file_path, result)Persist one batch result and append its summary row. Solver-backed results write a MAT file and store its relative path; an original-input fast path appends only the CSV row.
MIPVerify.should_refine_insecure — Method
should_refine_insecure(row)Return whether attack evidence needs an exact-objective rerun. A feasibility solve still needs refinement when it terminated OPTIMAL, because that status proves only that a candidate exists.
MIPVerify.should_resolve_ambiguous — Method
should_resolve_ambiguous(row)Return whether a batch row lacks either a strict infeasibility proof or a verified witness. An available but rejected witness remains ambiguous even alongside a contradictory infeasible status. Rerun options schedule work; they do not issue verdicts. Legacy rows that predate witness verification therefore keep their historical scheduling: numeric objective evidence counts as a completed attack even though it is not a verified witness. Rerun with always to replace legacy evidence with verified witnesses.
MIPVerify.summary_witness_margin — Method
summary_witness_margin(result)Return the recorded numeric witness margin when a candidate is available, otherwise NaN for the CSV summary.
MIPVerify.uses_feasibility_objective — Method
uses_feasibility_objective(row)Return whether a row records the feasibility objective. Missing objective metadata is treated as an exact historical result rather than a feasibility result.
MIPVerify.validate_batch_refinement_objective — Method
validate_batch_refinement_objective(solve_rerun_option, objective)Reject a feasibility objective for refine_insecure_cases, which must compute an exact objective.