All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
-
TwoStageStochasticBlock: the cross-check ofBSPar-BDS-2S.txtalso has theBendersDecompositionSolverwith HiGHS in the master and in the subproblems (BDSCfg-2S-HiGHS.txt,BDSMCfg-MILP-HiGHS.txt,BDSSCfg-HiGHS.txt), i.e., the Benders decomposition where there is no licence of GUROBI, next to the one with GUROBI, whoseComputeConfigis now the fragmentBDSCfg-2S.txtthat both include -
SVMBlock:FWBSCfg.txtalso registersFrankWolfeSolverwith the primal-dual bundle direction (intFWDirectioneDirPrimalDual), on the balls and on the box of the dual alike -
SMS++/AbstractBlock:AbstractBlock_BDS_testalso runs the phase one on four scenarios with the subproblems solved by DAQP, which gives no Farkas certificate (BSPar-BDS-Phase1-DAQP.txt), theComputeConfigof the phase one being the fragmentBDSCfg-Phase1.txt -
HQPBlock, the suite ofHQPBlock,HQPDistBlockandHQPSolver:HQPBlock_testcompares level by level everyHQPSolverofBSPar.txt, a map from the classname of the Block to itsBlockSolverConfig(on theHQPBlock, DAQP, qpOASES, MOSEK and Clarabel as inner Solver, each with the rows of the lower levels relaxed or in the model and with the center of the regularization at the previous solution or at 0, and DAQP and qpOASES solving each level from scratch), and those of each formulation ofHQPDistForms.txt, given with-F, on theHQPDistBlockof the same hierarchies split among 3 owners (with the structurekConsensus, DAQP and qpOASES on the whole tree; withkBenders, DAQP on the whole tree), with an independent null-space implementation;batch-generatedon random and degenerate hierarchies, on a step of Model Predictive Control and on a run of 10 small ones, where DAQP and qpOASES starting from the previous solve of each level must take fewer iterations than from scratch (-I),batch-radialon the instances indata/nc4of the module, each step also reached by Modification of the previous one, with the labelHQPBlock;MILPSolver -
MILPSolver/QuadFunction/LPPar_CL_C-dense.txtalso attachesHPIPMMILPSolver, withQPCfg-C.txt, so thatbatchCL_C_dense,batchMPC_C_denseandbatchMM_C_denserun it next to the other dense QP :MILPSolver -
MILPSolver/QuadFunctionalso has the convex QPs of two test sets of qpbenchmark (Apache License 2.0): the 64 of model predictive control in robotics ofmpc_qpbenchmarkinMPC, and 61 of the dense subset of the Maros-Meszaros test set inMarosMeszaros, written as LP files byqpb2lp.py, with their optimal values inavailable_instances.txt;batchMPC_C,batchMM_C(withLPPar_CL_C.txt) andbatchMPC_C_dense,batchMM_C_dense(withLPPar_CL_C-dense.txt) solve them -
import_modules, built whenSMSpp_BUILD_MODULEisON, imports the C++20 module of each SMS++ module in the build, names their main classes and gets aBlockor aSolverof each one from the factory -
InvestmentBlock/batches-sddp/batchcompares, at a fixed design, the simulation that theInvestmentFunctionruns over anSDDPBlockwith the simulation of the sameSDDPBlockbysddp_solver, and both with the value by hand, on four toy instances written byInvestmentBlock/gen_sddp_initud.pywhose thermal unit is started up at the last instant of the first stage withMinUpTime3 or 1, is off there, or shuts down there withMinDownTime3, the first being a known defect of theInvestmentFunctionthat is printed and does not fail the battery; it runs whereinvestmentblock_solver,sddp_solver, Python andncgenare, with the configurationsInvestmentBlock/*-sddp*.txt -
SingleFlowDCRBlock/batches-multiflow/batchalso runs theLagrangianDualSolverwhose flows are solved by theSingleFlowDCRBendersSolverwithintReuseCuts1 (BSPar-multi-reuse.txt,DCRBSCfg-reuse.txt) and withintWarmLambda1 (BSPar-multi-warm.txt,DCRBSCfg-warm.txt), which no test turned on -
SingleFlowDCRBlock/batches-multiflow/batchruns the instances with 1 flow too, and none is left out any more: with the multi-flow instances of the data version 2026-10-18 of SingleFlowDCRBlock, whose mutual capacity is the sum of the individual ones, the 18 instances of topo that were infeasible are not, and Gurobi solves the 6 it did not -
the first-stage rows of
AbstractBlock_BDS_test: an instance whose first-stageVariablehaveConstraintof their own, a ramp between consecutive ones and a minimum on their sum that the starting point violates, solved in the MILP regime and in the convex one with the primal (BSPar-BDS-Primal.txt,BDSMCfg-Primal.txt) and the dual master problem in theBundleSolveragainst the monolithic model; theComputeConfigof theBundleSolverof the master is now the fragmentBDSMCCfg.txt, whichBDSMCfg.txtincludes andBDSMCfg-Primal.txtoverrides -
batch-instances-bxofSingleFlowDCRBlock: aBranchAndXSolverwhose nodes are solved by theSFDCRBRelaxationSolvernext to theSolverofBSPar.txt(BSPar-BX.txt,BXCfg.txt,InnerBSCfg-BX.txt), on the SOCP formulation with itsBlockConfig, hence with its feasibility tolerance (on the P/C one in CI, asbatch-instances); the build adds it only when it has theBranchAndXSolverand theSingleFlowDCRBlockin it has theSFDCRBRelaxationSolver -
the
LagrangianDualRelaxationSolvernext to thePrimalProximalHeurin the cross-checks ofUCBlock(BSPar.txt,BSPar-DP.txt,BSPar-AC.txt,BSPar-AC-24h.txt,BSPar-PYPSA.txt,BSPar-par.txt,BSPar-par-aggr.txt) and ofTwoStageStochasticBlock(BSPar-2S-LD-IP.txt), with the sameComputeConfig(that ofBSPar-PYPSA.txtnow the fragmentPPHCfg-PYPSA.txt); its upper bound is the other side of the relaxation, so the batteries declare it a relaxation and hold its lower bound to correctness alone (-R ...,r -E ...,inf) -
SVM_FW_testin the suite ofSVMBlockand its batterybatch-fw:FrankWolfeSolveron two problems built out of the data sets of the suite, the least-squares fit in Euclidean balls, a feasible region that is not a polytope whose oracle is the closed-formBallSolverof the tester, and the Wolfe dual of the SVM on a box, whose oracle isBoxSolver, the variants of the direction ofFWBSCfg.txtcross-checked against a:MILPSolverby their bounds -
sweepofbatch_common.sh, which runs a command for every combination of the values of some parameters, the batteries ofBinaryKnapsackBlock_testthat sweep the parameters of a generated instance (batch,batch-mixed,batch-negative) writing only the values, and their run once inbatches/bkb_battery.sh; the runs are those they made before -
UCBlock/batches/batch-acadalso solves the two busUCBlockofconstant/in the data of UCBlock (version 2026-10-13), whose ownObjectivehas the constant term of the network (+1000 and -1000), against their optimum by hand, skipping them when they are not in the data: the value a Solver reports of its solution and its bounds must both count it -
SolveVariants()ofcommon_utils: given copies of aBlock, each configured by one variant of itsBlockConfig, it cross-checks theSolverof each copy asSolveAll()does and then theSolverof all the copies against each other, since whatever the formulation they bound the same optimum;-F <list>is a standard option of the testers, the list aSimpleConfiguration<std::vector<Configuration*>>whose elements are (meta-)BlockConfigor pairs (meta-)BlockConfig+BlockSolverConfig(SimpleConfiguration<std::pair<Configuration*, Configuration*>>), read byget_BlockConfig_variants(), andsolver_config_of()gives theBlockSolverConfigof each copy -
UCBlock_testtakes-F, andUCBlock/batches/batch-pypsaruns each PyPSA instance once with the formulations of theDCNetworkBlocklisted inInnerBVar-DCN.txt(PTDF, CYCLE, KIRCHHOFF) instead of once per formulation, comparing them with each other as well as with PyPSA -
TUDPS_testcompares formulations with each other: given with-Fa list of (meta-)BlockConfig, aSimpleConfiguration<std::vector<Configuration*>>such asUCBlock/TUBVar-PC.txt, it reads the unit once per element, gives each copy its ownBlockConfigand the sameBlockSolverConfig, makes each random change to all the copies, and besides the twoSolverof each copy checks that the copies have the same optimum, which no battery did while each formulation was a run of its own;read_BlockConfig_variants()ofcommon_utilsreads the list for any tester -
UCBlock/batches/batch-acalso runs 6 of the 53 AC instances over 24 hours (ES_acopf_srd_id_*_24h_1: c01, c14, da, g2, d2_c03, d2_c12, both days and the extremes of the total demand), on the SOCP relaxation ofACNetworkBlock[InnerBCfg-SOCP.txt,ACBCfg-SOCP.txt], with a limit on the iterations of theLagrangianDualSolver(withdblMaxTimeit ends withkErrorpast the limit) and on the time of thePrimalProximalHeur[BSPar-AC-24h.txt,LDCfg-AC-24h.txt,PPHCfg-AC-24h.txt]: their verdict says that the bounds are consistent, not that the values agree;BSPar-AC.txtis made of the fragmentsMILPCfg-AC.txt(now withNonConvex 0, so that GUROBI reports the optimum of the convex relaxation as its lower bound and notOBJBOUND),LDCfg-AC.txtandPPHCfg-AC.txt, whose warm start [WSBSCfg-AC.txt] solves the relaxation with the settings ofMILPCfg-AC.txt, on which it no longer stops on numerical trouble (GUROBI status 12) -
UCBlock/batches/batch-conversionruns the instances with aConversionUnitBlock: the multi-energy ones of UCBlock (a combined heat and power plant as aConversionUnitBlockand as aThermalUnitBlockwith hyperarcs, a meshed network with a heat node) against their known optimum, and those that pypsa2smspp makes of the committable links of its test networks (nc4/conversion, data version 2026-10-15: time-varying efficiency, delays, modules, design, also with ramps and on before the horizon) against the optimum of PyPSA, each with the three formulations of the network (InnerBVar-DCN.txt), skipping them when they are not in the data; theConversionUnitBlockinner to theLagrangianDualSolveris solved with its integer commitment [seeCUBSCfg-MIP.txtandInnerBSCfg-DP.txt], and on the units of several modules, whose commitment is integer and not binary, thePrimalProximalHeuronly bounds the optimum and is declared a relaxation -
UCBlock/batches/batch-conversionalso runs the multi-energy cases with the electricity and the heat as two carriers, the plant being aThermalUnitBlockwith two outputs (me_*_carrier) or theConversionUnitBlockwhose generators have each its output on its carrier (me_*_unitcarrier), the PyPSA networks with the electricity, the hydrogen, the gas and the heat as carriers (carriers_*) and the cases of the committable links of pypsa2smspp with the gas, the electric and the heat buses as three carriers (conversion/*_carriers.nc4), against the optimum by hand and of PyPSA, and per instance the tolerances of its Solver (EPS_OF) -
the carrier form of the PyPSA instances, where the buses of each carrier of the network are the nodes of a carrier of the
UCBlockand the links between two carriers are units with outputs (*_carriers.nc, written by the generators of pypsa-eur-instances with--carriers), held to the same reference as the network form: the networks with the hydrogen inUCBlock/batches/batch-pypsaandInvestmentBlock/batches/batch-pypsa, the trees of the PyPSA-Eur network with ten carriers, whose CO2 pipeline is a line with a design in the network of its carrier, inMultiStageStochasticBlock/batches/batch-pypsaand, with the investment outside, inInvestmentBlock/batches/batch-stochastic(frominitial_investment_stochastic_carriers.txt, the point of the other form in the order of the assets of this one), and the flat two-stage equivalent of one tree, in both forms, inTwoStageStochasticBlock/batches/batch-pypsa
-
MILPSolver/QuadFunction:HPIPMMILPSolverhas inLPPar_CL_C-dense.txttheComputeConfigHPIPMCfg-C.txt, that ofQPCfg-C.txtwith a limit of 1000 iterations instead of the 100 of the default mode of HPIPM, with which it stopped with no solution, an interval that the tester accepts, onQCAPRI,QSCAGR7andQSCAGR25ofbatchMM_C_dense; with the 1000 it solves the last two, and returns an error onQCAPRI, whichbatchMM_C_denseleaves out as it does the other models some of its Solver do not solve -
SVMBlock/BSPar.txtadds toGRBMILPSolverandSMOSolverone:MILPSolverfor each other kind of algorithm for a convex quadratic program: the active-setQPOASESMILPSolver, the interior-pointMOSEKMILPSolverand the first-orderOSQPMILPSolver, so that the batteries of the SVM dual and primal also check how they take the changes of the training problem -
the makefiles that include LagrangianDualSolver no longer include BranchAndXSolver, which it no longer needs, save those of the tests whose configurations use it (UCBlock)
-
MILPSolver/QuadFunction/LPPar_CL_C.txtgivesMOSEKMILPSolvertwo threads, withMOSEKCfg-C.txt, since its interior point fails onQGROW7ofbatchMM_Cwith 4 threads or more and onQPCSTAIRwith one, and solves both with two, so that the outcome of the battery does not depend on the cores of the machine -
SolveAll()reports aSolverwhosecompute()throws as an error in the line of the instance, withError! (throw)and the message of the exception on the standard error, and goes on with the otherSolver, rather than ending the tester: the exception of oneSolver(e.g., the active set ofHiGHSMILPSolverthat does not solve a QP) left the others without a value -
the tester of
UCBlockis built without theLagrangianDualSolverMLlibrary, whose loading of Torch cost more than many of the instances, andUCBlock_ML_testis the same tester with it;batch-acad-s, whoseBSPar-DP-BX.txtasks for aSolverof that library, names it as its default executable and is run with it when the build has it -
every test and every battery runs with
OPENBLAS_NUM_THREADS=1, unless the caller sets it, OpenBLAS starting one idle thread per core as soon as it is loaded -
InvestmentBlock/batches-sddp/batchholds theInvestmentFunctionto the value by hand on minup3 too, now that it simulates on a copy of theSDDPBlock;GreedyCfg-sddp.txtgives theSDDPGreedySolverthe BlockSolverConfig of the stages (UCBSCfg-sddp.txt) -
the batteries of
MILPSolver/QuadFunctionsolve each model with every Solver of their BlockSolverConfig and check them against each other and against the known optimal value (SolveAll()), where the tester used the first one alone; the models of the class CL (a convex objective and linear constraints) have configurations of their own,LPPar_CL_C.txtwithMOSEKMILPSolver,ClarabelMILPSolver,PIQPMILPSolver(sparse) andOSQPMILPSolvernext toSCIPMILPSolver, andLPPar_CL_I.txtwithMOSEKMILPSolver, the ComputeConfig of each Solver being a fragment;batchCL_C_denseruns the denseDAQPMILPSolver,QPOASESMILPSolver,ProxQPMILPSolver,QPMADMILPSolverandQuadProgMILPSolver(the last two with their Hessian regularized) ofLPPar_CL_C-dense.txt, which the tester takes from-S, on the models of the class with up to about 2000 variables -
intDoEasyin the configurations follows the new bits of BundleSolver (e.g., 13 is now 7, 45 is now 23), as do the comments that name them -
the batteries
batch,batch-mcfandbatch-cutsofCapacitatedFacilityLocationBlockrun the Yang and TBED instances in CI too, the first instance of each Yang size and the first TBED one with seed 0 only, and all of them locally as before (cfl_yangtakes the numbers of the instances); they were skipped in CI as running for hours, which wasMCFSimplexpivoting for ever on an infeasible round of the MCF R3Block (batch-cuts, which has none, had only copied the skip), and with it fixed the 40 rounds take seconds -
the LMO of the
MCFBlocksuite (MCFBlock/MCFBSCfg.txt) runsMCFSimplexwith the tolerances ofMCFClass, no longer at 1e-9: they had been set becausegoto10_8_1pivoted for ever, which does not happen any more -
what the testers compare with -F is called a formulation everywhere, and no longer a variant: the lists are
*Form*.txt(TUBForm*.txt,NUBForm*.txt,InnerBForm-DCN*.txt,InnerBForm-LD.txt,CFLBForm*.txt,SATBForm.txt,DCRForm.txt,NDForm.txt,MetaForm.txt, formerly*Var*.txt), the long option is--formulations, the functions ofcommon_utilsareread_formulations(),get_formulations(),SolveFormulations()andattach_formulation_Solvers(), and the output saysformulation Fk:andformulations against each other: -
the five options of the rounds of random changes (-e seed, -k what to change, -n rounds, -m changes, -q probability) are written once in
common_utils[seeRoundOptionsandadd_round_options()] and used by the nine testers that change their Block at random: those ofSMS++/BoxSolver,AbstractBlock(box),MCFBlock,CapacitatedFacilityLocationBlockandUCBlock(TUDPS), which had a copy each, and those ofSMS++/PolyhedralFunction,PolyhedralFunctionBlock,LagBFunctionandAbstractBlock(readwrite), which took positional arguments; the NDOBlock configuration ofLagBFunction_testis the standard -S, andMILPSolver/QuadFunctiontakes -t and -r in place of its positional arguments -
IB_testtakes -F, the list of the BlockConfig to compare, like the other testers:InvestmentBlock/batches/batch-pypsaandbatch-stochasticsolve each instance with a network with the three formulations of it (InnerBVar-DCN.txt,InnerBVar-DCN-CI.txtin CI), and the modular ones with the inner Block solved as a linear program and by the recursive Lagrangian dual in one run (InnerBVar-LD.txt), the copies being compared with each other -
BSPar-2S.txtofTwoStageStochasticBlock, the default ofbatch-pypsaandbatch-ec, has the master problem of the bundle of itsLagrangianDualSolversolved by GUROBI's barrier (MPBCfg-barrier.txt, from theComputeConfigof the master now inMILPCfg-MPB.txt, whichMPBCfg.txtincludes, as inUCBlock): with the dual simplex the master of the maxpower instance ofbatch-pypsafailed numerically at every call after a few dozen iterations, and the Lagrangian Dual ended in error, while with the barrier no master fails -
UCBlock/batches/batch-p4rsolves the pHydro instances withBSPar-DPb.txt, whoseLagrangianDualSolver,PrimalProximalHeurandLagrangianDualRelaxationSolverhave the master problem of the bundle solved by GUROBI's barrier (MPBCfg-barrier.txt, from theComputeConfigof the master now inMILPCfg-MPB.txt, whichMPBCfg.txtincludes): with the dual simplex the Lagrangian Dual stopped at the 300 seconds of the battery on four of the five, and onpHydro_18its master failed numerically, while with the barrier it converges on all of them in less than half of that time; aBlockSolverConfiggiven on the command line is still used for every instance -
UCBlock/batches/batch-ecsolves each instance with the three formulations of the network (InnerBVar-DCN.txt,InnerBVar-DCN-CI.txtin CI) and compares them with each other -
UCBlock/batches-tub/batch-nuclearcompares the formulations of theNuclearUnitBlock: the T formulation with Perspective Cuts and its tight forms of the operating rules (NUBVar.txtwithNUBCfg-T-PC-{R,M,RM,RC}.txt,NUBVar-CI.txtin CI), which describe the same set of schedules -
the batteries of
MultiStageStochasticBlockandbatch-ecofTwoStageStochasticBlocksolve each instance with the three formulations of the network of its inner Block (InnerBVar-DCN.txt, PTDF and KIRCHHOFF only in CI), comparing them with each other; the copies are read as with one copy, by the lower bound of their Solver -
batch-pypsaofTwoStageStochasticBlocksolves each instance with the three formulations of the network of its inner Block (InnerBForm-DCN.txt,InnerBForm-DCN-CI.txtin CI), comparing them with each other and with the reference, asbatch-ecdoes; the runs on the Benders form keep the one formulation ofInnerBCfg.txt -
SatellitesBlock_testandMultiKnapsackAssignBlock_testare a call ofload_solve_test()ofcommon_utils, which loads the Block out of the file, once per variant of-F, and cross-checks its Solver withSolveVariants(); their runs are those they made before -
the testers no longer define their own
RED/GREENmacros, which are those ofcommon_utils.h, andUCBlock_testandMMCFBlock_testno longer carry the commented-out template of a loop of changes they never made, nor the random generator and the macros it would have used -
MCFBlock/batches/batchandbatch-densesharebatches/mcf_battery.sh, the sweep of the changes over the instances being the values of its parameters [seesweep], each battery naming only its sizes; the runs are those they made before -
the batteries of
MMCFBlock_testsharebatches/mmcf_battery.sh, the Canad instances with a list ofBlockSolverConfigand the Mnetgen ones, the runs being those they made before (the commented-out instances of 256 nodes are gone) -
the six batteries of
MILPSolver/QuadFunctionsharebatches/qf_battery.sh, each only naming its family of instances and its type, the runs being those they made before -
the batteries of
CapacitatedFacilityLocationBlocksharebatches/cfl_battery.sh, the arguments, the runs of an instance for every seed and the ORLib, Yang and TBED instances: each of them only says its variants, its changes, its seeds and which instances it runs, the runs being those it made before -
the header and END boxes of the configuration files that lacked them or had them with another name or the name glued to the dashes, the author lines and the lines over 77 columns, the comments being rewrapped and nothing else of the files changing
-
TSSB_testandMSSB_testare one main,stochastic_test.{cpp,h}, the twotest.cpponly saying which class they read and what they add (the Benders form of-b, the round trip of theSolution); both take-F, reading the instance once per variant of theBlockConfigand comparing the copies withSolveVariants(), and-R -
MMCFND_testtakes the two formulations ofMMCFNetworkDesignBlockwith-F NDVar.txt(pairsBlockConfig+BlockSolverConfig) instead of-m/-M/-b/-B, its options being parsed bycommon_utils -
SingleFlowDCRBlock/batches/batchruns each instance in both formulations, the SOCP and the P/C one, with-F DCRVar.txt, whose variants carry theirBlockSolverConfigand their-R, and compares them with each other;batch-pcis gone, andbatch-instancesruns the two formulations in one run where it runs both -
a variant of
-Fmay be the vector of itsBlockConfig, itsBlockSolverConfigand aSimpleConfiguration<std::vector<int>>saying which of itsSolversolve a relaxation, i.e., its own-R;attach_variant_Solvers()ofcommon_utilsapplies theBlockSolverConfigof a copy and givesSolveVariants()the-Rof that copy, each copy taking out of it theSolverthis build does not have (before, a run of several copies took them out of-Ronce per copy) -
SATBlock_testandSingleFlowDCRBlock_testtake-F[seeSolveVariants()], given which they read the instance once perBlockConfigof the list;SATBlock/batches/batch-structuregives each instance both structures in one run (SATBVar.txt: the relaxation ofBPar-R.txtand the decomposition ofBPar-D.txt), each round of Modification making the same change to both copies, and compares them with each other;get_BlockConfig_variants()takesoptional, for the testers that may be given noBlockConfigat all -
the tester of
CapacitatedFacilityLocationBlocktakes its configuration from the list of-F, one per battery (CFLBVar*.txt): the pairBlockConfig+BlockSolverConfigof the originalBlock, then one or more R3Block, each the vector of theConfigurationit is made with, itsBlockConfigand itsBlockSolverConfig, with its ownUpdateSolver; the lower bounds of all theirSolverare compared, not only those of the first one, so that the flow relaxation is solved by every:MCFSolveritsBlockSolverConfiglists; its positional arguments are options (-t,-s,-e,-k,-n,-m,-q,-T); the sub-folderscuts,MCF,LD,LDVScutsandBenwith their copies ofBPar1.txt,BPar2.txt,BSPar1.txt,BSPar2.txtandR3BCfg.txtare gone, the configurations being flat files named after what they configure (CFLBCfg-*.txt,CFLBSCfg-*.txt,MCFBCfg.txt,MCFBSCfg*.txt,R3BCfg-copy.txt,R3BCfg-MCF.txt), the identical ones merged -
compare_formulationsis a thin wrapper ofSolveVariants(): it takes-Fand the variants ofMetaVar.txt, each a pairBlockConfig+BlockSolverConfig, instead of-X/-Y; its CMake target linksUCBlockandMILPSolverwhen they are in the build, without which it could not read the instances of its batch -
UCBlock_test --scaleno longer builds theBlockConfigof the formulations of the unit in code: it reads them from the listsUCBlock/TUBVar.txt(the seven formulations, new) andUCBlock/TUBVar-PC.txt(the seven with the Perspective Cuts) withread_BlockConfig_variants(), and it is run in the directory of the suite, which holds them -
b_config_Block()ofcommon_utilsapplies a clone of a plainBlockConfig, as it already did for a meta one:apply()moves theConfigurationit holds into theBlock, so the sameBlockConfigapplied twice gave nothing the second time -
the batteries of
UCBlock/batches-tubthat looped over the formulations of the unit in bash (batch,batch-acad-all,batch-acad-red,batch-mustrun,batch-reserve,batch-reserve-red,batch-shutdown) run each instance once with-Fand the list of its formulations (TUBVar-PC.txt,TUBVar-PC-3bin-T.txton the long horizons,TUBVar-mustrun.txt,TUBVar-shutdown.txt); each run reports theSolverof every formulation as before and, when they agree, the lineformulations ... agree in <n> solvesbefore its verdict -
the comments of
UCBlock/batches/batch-acand of the AC configurations say what is solved: a convex relaxation of the AC model, whose McCormick inequalities are not separated in a continuous solve, by GUROBI (not SCIP); the 24h instances stay skipped, with the measured reason (the:MILPSolveralone solves one in a few minutes, the Lagrangian chain does not converge in 90 minutes and exceeds the sessions of the license) -
compareofml_benchprints a line when each side of an instance starts and one when it ends, with its time and iterations or why it failed, so that a side that does not end is seen while it runs -
the tests that set up the instances of a module are named after the target they build (
extract_<prefix>_<fmt>,run_<tool>), set up the fixture<prefix>_<fmt>_extractedor<tool>_generatedand share the lock<prefix>_data;fetch_bk_data,fetch_sat_dataandfetch_canad_dataare nowextract_bk_txt,extract_sat_cnfwithextract_sat_wcnf, andextract_mmcf_Canad, whose archive MMCFBlock downloads as the modules do
UCBlock/batches-tub/batch-acad-all, which made the runs ofbatches-tub/batchbut those of Frank-Wolfe, so that ctest made them twice
-
the Frank-Wolfe decomposition with the network simplex of LEMON in
batchandbatch-denseof MCFBlock runs the reduced lineup, as the one with the network simplex of MCFClass does, through the newFatherBSPar-fast-lemon.txt:FatherBSPar-lemon.txtgives the whole lineup, whose Away-step and Blended Pairwise variants with an unbounded active set did not end in hours on those instances -
the makefiles of the tests and of the tools build also with g++: they take the option that stops at the first error and the one of the debugging information, which clang++ and g++ spell differently (
-ferror-limit=1and-glldbagainst-fmax-errors=1and-ggdb), fromSMSppSWERRandSMSppSWDBGoflib/makefile-OSof SMS++ -
the makefiles that include the one of LagrangianDualSolver include also the one of BranchAndXSolver, whose branching rules LagrangianDualSolver uses, and so build again
-
BinaryKnapsackBlock/makefilelinks CPLEX only through MILPSolver, which adds it when it is there, and so builds without it -
MMCFBlock/MMCFClasscompiles MMCFCplex only if CPLEX is there (CPLEX_PRESENTofextlib), andMMCFBlock/makefilethen leaves outMMCF_test, whose reference solver is MMCFCplex, as CMake does -
MILPSolver/QuadFunction/MOSEKCfg-I.txtasks MOSEK for the outer approximation of the conic relaxations: with the nonlinear ones and the few threads of a CI runner, MOSEK 11.0 declared optimal -33.7755 on QPLib_10056, whose optimum is -33.8568, andbatchCL_Ifailed -
the SingleFlowDCRBlock tester checks the Solution of a Solver against the problem only if the formulation of its copy does not declare it a relaxation: with -F it read the -R of the command line, which is empty, so the point of the P/C relaxation of
DCRForm.txtwas found to violate the delay, andbatches/batch-instancesstopped at its first instance; each check now also names the formulation of the Solver -
the here-and-now
AbstractPathof the network designVariableof the twos_5instances ofTwoStageStochasticBlock/data-scenredgive the position of each design line, not its line index: past the 11 lines out of design they pointed to the wrongVariable, and the last 11 past the end of the group, on whichTSSB_reduction_testcrashed -
batches-scenred/batchofTwoStageStochasticBlockfails when the tester fails on some instance, rather than always passing -
the Benders form
benders_form.cppbuilds forTSSB_testand the check ofTSSB_reduction_testfor here-and-nowVariableshared by the scenarios take the elements of a here-and-nowAbstractPathselecting an explicit, non-contiguous subset of a group, rather than the ones following the first element -
the
BundleSolverofBSPar-Inv.txtofTwoStageStochasticBlockasks 1e-6 of relative accuracy, the tolerance within whichTSSB_BDS_testcompares the ad hoc Benders form with the extensive optimum, not 1e-4, where it could stop on the bound of the box of the variables above that tolerance -
the
BundleSolverofBSPar.txtofInvestmentBlockasks 1e-5 of relative accuracy, not 1e-4:IB_testreads its value as the optimum and compares it with the reference within 1e-5, and theBundleSolver, which now stops on the bound of the box of the variables, stops where 1e-4 asks, 1.7e-5 above the reference onsmspp_2n_2c_1g_1lext.ncofbatch-pypsa -
the Solver that an option names by its position, i.e., the heuristic that -w of the stochastic testers reads by its upper bound, follows the Solver that the build does not have as -E and -R do [see
name_Solver()]: it moves down past one before it, rather than landing on another Solver, and if it is itself not there the warning says so and the run goes on as without the option; and aBlockSolverConfigthat adds its Solver to those already registered to the Block (as the reference one offw_test) takes out of -E and -R the entries of its Solver after them, not of the first ones.BSPar-2S-IP-missing.txtnames the missing Solver before thePrimalProximalHeur, andbatch-pypsaofTwoStageStochasticBlockruns it also with -w -
with -F and a
BlockSolverConfignaming a Solver that the build does not have, the entry of that Solver in -E was taken out once per copy of the Block rather than once, so that the tolerances of the Solver after it landed on others (a single entry left applied to all of them): each copy now filters -E anew out of what was given [seeattach_formulation_Solvers()]; the Solver of the sub-Block of a metaBlockSolverConfigthat are not in the build no longer take out entries of -E and -R, which are positional on the Solver of the root alone, and the warning names theBlockSolverConfigrather than the formulations.TwoStageStochasticBlock/batches/batch-pypsachecks it on the thermal instance (BSPar-2S-IP-missing.txt, with a Solver that no build has) -
the meta
BlockSolverConfigof theLagBFunctionofUCBlockgive theNuclearUnitBlockits own entry, which fell on*since the match is on the exactclassname():NUBSCfg-DP.txt(NuclearUnitExtDPSolver) inInnerBSCfg-DP.txt, asThermalUnitBlockhas its dynamic programming, andTUBSCfg-CLP.txt/TUBSCfg-QCP.txtinInnerBSCfg.txt/InnerBSCfg-AC.txt, asThermalUnitBlock -
MMCFBlock_testpasses only if every round of the online training of its Solver passes, not only the last one -
SMS++/PolyhedralFunctionBlock/batchexits with 1 on any failure: the number of failures, which it returned, is 0 again from 256 -
the batteries say at their end which runs they skipped, i.e., exited with 77 since the build has none of their Solver [see
report_skippedofbatch_common.sh], as the comment there said they did -
CapacitatedFacilityLocationBlock/CFLBSCfg-ldvscuts.txtgives itsGRBMILPSolverthe parameters of GUROBI (it gave those of CPLEX, which stopped every run ofbatch-ldvscuts), the root node being solved with its cut loop (NodeLimit 1); the battery stays off ctest, the gap between the two bounds being larger than with CPLEX -
compare_formulations/BSCfg1.txtandBSCfg2.txtattach aGRBMILPSolverrather than aHiGHSMILPSolver, which cannot separate the user cuts thatintCutSepPar 7asks for, so that the batch failed on every instance -
UCBlock/batches/batch-p4rholds the solution theLagrangianDualSolverreconstructs onL_H_C_35to the violation its convergence gives (-V 0.5, the largest entry of the residual being 0.157 MW on node injection rows of right-hand side 0, under thedblNZEpstest the bundle stops by), where the default 0.1 made the battery fail on a correct reconstruction
0.7.0 - 2026-10-09
-
the tester of
LagBFunctiontakes as its last argument,detach, whether the Solver of NDOBlock are unregistered and registered again before eachcompute(), which was the compile-time macroDETACH_NDO;batchandbatch-easyhave rows with it, with all the changes between two calls -
the suite
MultiKnapsackAssignBlock, which cross-checks on the instances of the module a:MILPSolveron the whole tree and the Lagrangian decomposition intoBinaryKnapsackBlocksolved by theCoreDPBinaryKnapsackSolver, the latter declared a relaxation -
the tester of
LagBFunctioncan write the transportation components with a size Variable tau, their balances and capacities scaled by it, so that the master problem scales them by its lambda and the easy components can be used with the level and doubly stabilized master problems: the argumentsizeof the tester, the one beforedetach, is 0 for none, in which case the master scales a copy of the inner Block if bit 5 ofintDoEasyasks for it, 1 for a Variable of the inner Block (Block::set_owned_size_variable()), which the master ties to lambda, and 2 for lambda itself, given to the inner Block, aSizedTransportBlock, byBlock::set_size_variable(); bits 4 and 5 ofintDoEasyare taken from the configuration file, so that the file says whether the master uses the size Variable and the copiesbatches/batch-easy, with the path ofbatch_common.shcorrected, is a ctest test, and itssizedrows (in the default profile) run the three ways of scaling with the proximal, level and doubly stabilized masters (NDOPar-Mirror.txt,NDOPar-Lvl.txt,NDOPar-DS.txt, all withintDoEasy33) and with the doubly stabilized one that leaves the easy components unscaled (NDOPar-DS-NoSize.txt,intDoEasy17), also with bit 12 (4096) of the tester, by which the inner Block of an easyLagBFunctionissues an NBModification, which a copy in the master cannot follow and which puts the inner Block back in its place -
the testers of
PolyhedralFunctionandLagBFunctioncheck every Solver the BlockSolverConfig of NDOBlock attaches against the LP, one column each in the per-instance line; theComputeConfigof theirBundleSolveris the fragmentBSCfg.txt.PolyhedralFunction/NDOPar.txtattaches threeBundleSolver, with the proximal stabilization and with the trust region in the dual and in the primal master problem;LagBFunction/NDOPar.txtattaches two, with the proximal stabilization and with the trust region, both taking the easy components in their master problem -
UCBlock/batch-pypsa runs the edge cases of the network of the UCBlock data from 2026-10-03 with the PTDF, CYCLE and KIRCHHOFF formulations against the optimum of PyPSA: parallel DC lines in the same and in opposite directions, a triangle with a parallel side, DC components joined by a link and nodes reached only by links with losses; until then the instances of the battery had no susceptance, so that the three formulations wrote the same transport model
-
MMCFBlock/BSPar-ML-K-train.txt, the configuration of the training ofMMCFBlock_ML_bench:BSPar-ML-K.txtwith the online training of the network on, both taking theirComputeConfigfromLDCfg-ML-K.txt;trainstops with an error when the configuration hasintMLTrainOnlineat 0, since the run would otherwise write weights that learned nothing -
bit 11 (2048) of the
LagBFunctiontester adds at runtime a dual pair to a singleLagBFunctionon an x that it does not have, as one does when dualizing a constraint born during the search, mirroring it on the LP side; the x is a new coordinate of the master when no other component has it, and one the master already has otherwise.batches/batchruns it with the dense and the sparse setup (3583 and 4095), with and without the linear objective and the PolyhedralFunction (nf= -2, -11, 0), and with hard and easy components -
the testers of
PolyhedralFunctionandPolyhedralFunctionBlockremove dynamic Variable as well as adding them (DYNAMIC_VAR_REMOVALSis 1): in the dual representation the coupling rows of the removed coordinates go first, then the columns of the LP side, which the UpdateSolver mirrors on the NDO side, and the Variables of both Blocks; the removal of thePolyhedralFunctiontester uses the positions that follow the static Variable, and its ranged removal from the rows of the LP issues the Modification it skipped -
the
IntegralityBarrierSolverof FrankWolfeSolver in the cross-check ofSATBlock(BSPar.txt), a heuristic on the MILP formulation whose oracle is theBlockSolverConfigIBLPBSCfg.txt, a:MILPSolveron the linear relaxation (LPCfg.txt) applied to the copy of the formulation (strLMOBSCfgofIBCfg.txt), its Frank-Wolfe method looking at the rounding of the iterate every iteration (intEverykIt1 ofFWIBCfg.txt) -
MMCFBlock/MMCFND_testwithbatches/batch-nd: the network design problem ofMMCFNetworkDesignBlock, solved monolithic by the MILP Solver and in Benders form, the two optimal values compared on the p33 instances with 3 and 5 commodities -
the tester of
SATBlockapplies the BlockConfig of-B, e.g., giving theSATBlocka structure out of the groups of its variables, and does not check the solution of the Solver declared with-R;batch-structuregives the instances ofsmspp_satgenboth structures (BPar-R.txt,BPar-D.txt) and cross-checks the Solver ofBSPar-LD.txt, i.e., those ofBSPar.txtand theLagrangianDualSolverof the rows of the father, whose bound has to be below their optimum, also after 3 rounds of Modification that keep the structure -
the suite of
SatellitesBlock: its tester loads an instance of the Satellite Constellation Design Problem into theBlockgiven with-b(ConstellationBlock,DiscreteConstellationBlockorMultiTargetBlock) and cross-checks, withSolveAll(), a:MILPSolveron the whole tree with theLagrangianDualSolver, whose sub-Block get their Solver by classname from a meta-BlockSolverConfig(DiscreteSatelliteSolveror a:MILPSolver);batchruns it on the instances of the module, against their optimum, the Lagrangian dual being declared a relaxation, and stopped after 50 iterations onMultiTargetBlock(BSPar-target.txt) -
the suite of
SATBlock: its tester reads aSATBlockout of a CNF, WCNF or netCDF file and cross-checks, withSolveAll(), the Solver of its physical representation (OLL, with CaDiCaL and with MiniSat) with those of its abstract one, i.e., the:MILPSolveron its MILP formulation, checking also on the clauses the solution each of them writes;batch-mseruns it on the instances of the MaxSAT Evaluation 2024 the module distributes, against their optimum, andbatch-groupson instances made of groups of clauses written bysmspp_satgen -
the tester of
SATBlockchanges the instance with-nrounds of Modification drawn with the seed of-e(the costs of a fifth of the variables moved by a step, as a Lagrangian term does, the weights of a range of clauses, or clauses added), repeating the cross-check after each with the Solver still registered, so that their reoptimization is tested;batch-groupsmakes 5 rounds per instance -
the suite of
SATBlockcross-checks aBranchAndXSolvertoo, which enumerates on theSATSolverwith CaDiCaL, OLL stopping after 20 calls of the SAT solver in each node (BXCfg.txt,BXBSCfg.txt,OLLCfg-node.txt) -
InvestmentBlock/batches/batch-pypsaruns the modular network with one scenario again with the inner UCBlock solved by the recursive Lagrangian dual over its units (InnerBCfg-LD.txt), against the reference of PyPSA -
the nested forms in the batteries:
TwoStageStochasticBlock/batches/batch-pypsaruns the Benders form of the thermal instance with BendersDecompositionSolver whose subproblems are solved by the recursive Lagrangian dual (BSPar-BDS-2S-LD.txt, a relaxation),batch-pypsa-modularthe same BDS with a bundle master (BSPar-BDS-2S-CVX-LD.txt,BDSCfg-CVX-LD.txt), andInvestmentBlock/batches/batch-stochasticruns the modular networks again with the inner Block of the InvestmentFunction solved by the recursive Lagrangian dual (InnerBCfg-LD.txt,IBOCfg-LD.txt,IFCfg-LD.txt,BSCfg-LD.txt) -
TSSB_scenred_testin theTwoStageStochasticBlocksuite, the generic tester of the scenario reduction of aTwoStageStochasticBlockread from a file, which was the instance mode of the test of ScenarioReductionSolver and linked from there the Blocks and the:MILPSolverthat module does not depend on; thebatches-scenredbatteries ofUCBlockandCapacitatedFacilityLocationBlockrun it, and are labelled withScenarioReductionSolver,StochasticBlockandTwoStageStochasticBlockas well -
the tester of
UCBlocktakes-V, how much the point a relaxation reconstructs may violate the rows it has dualised, the default being the 1e-1 that was written in the test -
the same networks of pypsa2smspp in every form a module reads, each in the batch of its module: one scenario of the modular family with the design in the units in
UCBlock/batches/batch-pypsaand under an InvestmentBlock inInvestmentBlock/batches/batch-pypsa, the modular family as an MSSB inMultiStageStochasticBlock/batches/batch-pypsa, next to the TSSB ofbatch-pypsa-modular, and the thermal family, whose scenarios are unit commitments, inTwoStageStochasticBlock/batches/ batch-pypsawithBSPar-2S-LD-IP.txt, i.e., a:MILPSolveron the integer problem, thePrimalProximalHeurand the recursive Lagrangian dual; on the modular family with a continuous designbatch-pypsa-modularalso runs BDS whose subproblems are solved by the recursive dual (BSPar-BDS-2S-LD.txt) and the recursive dual itself (BSPar-2S-LDrec-IP.txt) -
TSSB_test -R, which declares the Solver that solve a relaxation and makes the tester cross-check the intervals of the bounds of all the Solver, as the other testers do, instead of requiring two values to be equal: a Lagrangian dual of a unit commitment is below the optimum by the duality gap -
SingleFlowDCRBlock/batches/batch-instances, the two formulations of the DCR problem on the instances of the module, i.e., on 10 flows of each of 307 real and random networks, which the build ofSingleFlowDCRBlockdownloads and a ctest fixture extracts before the batteries that read them: the P/C one on all of them, the SOCP one on the 2969 that Gurobi solves with each of the numerical focus settings 0, 2 and 3, the other 101 being listed insocp-unstable.txt;batch-instances-cplexsolves the SOCP formulation of those 101 with CPLEX, where CPLEX is available -
MultiFlowDCRBlock_testandSingleFlowDCRBlock/batches-multiflow/batch, which compare on the instances with the first 2 to 5 flows of each network a:MILPSolveron the formulation holding all the flows with theLagrangianDualSolverthat relaxes the mutual capacities, its flows solved by theSingleFlowDCRBendersSolveror by a:MILPSolver: they take the place of the testers of the multi-flow and single-flow DCR problems that lived on the branchesDCRFlowandfeature/dcr-benders -
UCBlock_test --pollutantscales a unit with aLagrangianDualSolverattached, whoseLagBFunctionhold only the dual pairs of the rows their sub-Block is in, and checks that the rows of that unit follow the scale and that the Lagrangian dual is the optimum of the scaled instance, as it is when the unit is scaled before the Solver is attached; the test is run next to the configurations of the batches, whoseLDCfg.txtit reads with a tighter threshold on the residual -
TwoStageStochasticBlock/batches/batch-mmcf: a stochastic multicommodity network design problem, i.e., aTwoStageStochasticBlockwhose scenarios areMMCFBlockwith one knapsack per arc, written bymmcf_tssb_genout of the Canad instances, is solved by the MILP, by the Lagrangian dual over the scenarios, by the nested and by the recursive one (one run each, since duals that do not copy their components cannot share them) and, on its Benders form, byBendersDecompositionSolverwith the scenarios as LPs and with the scenarios solved by the recursive Lagrangian dual (BSPar-MMCF-BDSLD.txt, a run of its own since aBendersDecompositionSolverreformulates its Block), all cross-checked against the MILP; the instances have complete recourse (mmcf_tssb_gen -r), which the Lagrangian subproblems need, and the knapsacks are solved by dynamic programming (BKBSCfg-DP.txt, inInnerBSCfg.txt) -
a configuration that names a
Solverthis build does not have no longer makes a run fail: the testers take those names out of theBlockSolverConfigbefore applying it [seeSolver::has_Solver()] and warn, in the yellow of the other warnings and one line per name, that the run solves without it, so that the log of a run says what it has actually solved with and a configuration can name everySolverthat makes sense on its instances, whatever each machine has; a run left with noSolverat all, and a run whose oneSolverwas the missing one, has nothing to do rather than something to fail, so it exits with the 77 thatctestand the batteries read as "skipped" (SKIP_RETURN_CODE), and a run left with oneSolverout of several warns that there is nothing to cross-check it against.BSPar.txtandBSPar-large.txtof theMCFBlocksuite and the two configurations of the flow relaxation of the capacitated facility location therefore nameMCFSolver<MCFCplex>as well, the network solver of CPLEX, which joins the comparison wherever CPLEX is there and is left out, with a line saying so, wherever it is not -
the tester of
BendersBFunctionchecks the global pool when a dynamic row of the sub-Block is removed: a row that is slack at the optimum, hence with a zero multiplier, leaves the entry of the pool where it is and the linearization it gives is the one it gave before, while a row that is active takes the entry away, what is left of its dual solution no longer satisfying the dual constraints -
the tester of
MCFBlockchecks what a direction of aMCFBlockis: on an instance with a negative cost cycle of infinite capacity theSolutiona:MCFSolvergives has to say that it holds a direction, which theMCFBlocktakes for one and not for a solution, while a:MCFSolverthat gives no such certificate throws and is skipped -
a batch of
LagBFunctionover the easy components, which nothing was exercising -
a batch can set an algorithmic parameter in a
ComputeConfigand time each run, so that a sweep over the values of one parameter is a batch and not a script written for the occasion; the twobatch-aggrtake the values ofintCmpAggrRulethat way -
batch-kof the multicommodity suite, the knapsack formulation asked for as a structure, andMMCFBlock_testlinks the ML variant of the BundleSolver, whichbatchMLattaches -
a driver that runs the batteries backing the validation claim of the dynamic programming Solver of the thermal units, and the batteries require again the fixture that extracts the instances they read
-
the batteries of
UCBlockrun the instances once per value of the rule that forms the groups of the parallel inner loop, and cross-check the academic and plan4res families over the exact Lagrangian chain; in the AC family the Lagrangian dual is declared a relaxation, its point being a convex combination, and the QCP sub-problems give the duals that chain needs -
the SVM suite cross-checks LIBLINEAR on the formulations that LIBSVM cannot express, exercises the exact path and the shrinking, which nothing was running, and compares the Lagrangian dual with a
SMOSolveron each chunk -
batch-ecruns the Benders form of the energy community instances, the form the tester assembles giving the master a cost for every design Variable and keeping integer, in the master, a design that counts modules; the convex regime of the Benders Solver has its own cross-check configuration -
a batch for an
InvestmentBlockwrapping a whole stochastic Block, two- stage or multi-stage, whose instances follow the trees they are built over; the inner Solver is asked for homogeneous dual directions, which the HiGHS variant cannot give, and the configuration says so where it happens -
the batteries of
BinaryKnapsackBlockcover whatBranchAndXSolverdoes: the lazy bounding protocol in every serial exploration strategy, the reoptimization with one Solver per strategy, the negative weights and the regime of a small instance re-solved many times, over the hard instances of Jooken as well, and the benchmarks of the coverage declare the greedy relaxation each of their configurations attaches -
the Frank-Wolfe decomposition is posed on the
BinaryKnapsackBlockof that suite as well, inbatch-pisinger, with the dynamic programme of each knapsack as the Linear Minimization Oracle: since no compact formulation describes the convex hull of a knapsack, what the decomposition computes is a lower bound on the monolithic optimum and not the same number, so the battery declares the variants relaxations (-R) and holds them to nothing (-E), so what is checked is that they agree with one another and that none of them passes the bound. The instances are the netCDF ones thebk2nc4of the module writes out of the curated archive the rest of that battery reads -
UCBlock_test --scale, which checks the scale factor of a unit, i.e., the number of copies of it that aUCBlockholds, on two instances the tester writes itself, one carrying a thermal unit and one a nuclear one, each of them with a cost of every kind its Objective can hold, the two reserves and the reactive power: the model of a unit scaled once the abstract representation is built has to be the one of a unit scaled before it, which is compared coefficient by coefficient over the Objective of every unit and the rows of theUCBlockthat use their Variable, and through the optimum; the data of the unit, being those of one copy, must not move although the Solver attached to it hears of the scaling; and the three dynamic programming Solvers have to answer for all the copies, i.e., to give the value of the Objective, also once a price has been written into it the way a dualizing Solver writes its multipliers. The thermal unit is taken in each of the seven formulations, with and without the perspective cuts. The comparison of the models asks for no Solver at all, so that it runs in a build that has none; the optimum and the dynamic programming Solvers are checked where a:MILPSolveris in the build -
the batch
batch-nuclearof theThermalUnitBlock_Solversuite, which compares theNuclearUnitExtDPSolverwith a:MILPSolveron the operating rules of nuclear units, in eight families of rules, four regimes of the costs (energy only, rewarded reserves, priced reactive power, rounds of changes of the costs) and two formulations of the rules, the default one and the tight one; a further environment variable,TUDPS_FIXMOD, fixes one modulation variable out of the given number, so that the two Solver are compared on a unit whose rules are partly decided; two further BlockSolverConfig serve the study of the solve times,BSCfg-nuc-lim.txt, which holds the MILP solver to a time limit, andBSCfg-nuc-dponly.txt, which attaches the dynamic programming Solver alone, so that the optimal schedule can be looked at without paying for the MILP solve -
the PyPSA instances with the pollutant budget constraints of
UCBlockinpypsa-data/pollutants/, run byUCBlock/batches/batch-pypsa: a PyPSA network with a CO2 limit twice and half the emissions of the unconstrained dispatch, a CO2 and a NOx limit, a CO2 floor, a CO2 equality, an operational limit on a carrier, and CO2 limits where a store and a hydro storage unit contribute through their final level, translated by pypsa2smspp and held to the PyPSA objective -
UCBlock_test --pollutant(the ctestUCBlock_test/pollutant), which checks the pollutant budget constraints ofUCBlockon small instances it writes itself, whose optima are known: several zones per pollutant and a node in none, rates depending on time, lower bounds and equalities, the level of a battery, the scale of a unit, the setters of the budget and of its lower bound, the duals through aUCBlockSolution, the netCDF round trip and the dataUCBlock::deserialize()must refuse -
the
MILPSolversuite (the ctestMILPSolver_test/groups), which solves the same program with every:MILPSolverin the build, itsVariableandConstraintgrouped in every shape aBlockallows -
the
AbstractBlock_mirrorsuite, which checks the copy of the abstract representation of a Block thatAbstractBlock::mirror()builds: that it is the same problem as the original, whichever:MILPSolversolves the two, that solution information moves back to the original, and that the copy follows the original when this changes -
the exact Lagrangian chain for UCBlock: BSPar-DP.txt attaches the three Solver over sub-Block solved to optimality by the dynamic programming Solver (TUBSCfg-DP.txt, InnerBSCfg-DP.txt, LDCfg-DP.txt, PPHCfg-DP.txt) and a :MILPSolver that solves the MIP rather than its continuous relaxation, stopping on a time limit so that what it gives is a valid pair of bounds rather than a claimed optimum (MILPCfg-MIP.txt). With the relaxation in the sub-Block the penalty of the PrimalProximalHeur acts on variables that are not binary there, and its first penalized call does not converge: on T-Ramp 10_0_1_w the heuristic goes from 86 to 13 seconds, its bound becomes the Lagrangian one rather than the value of the continuous relaxation, and every inner call ends on "optimal". No batch uses it yet: the LagrangianDualSolver is a relaxation with a duality gap there, so it has to be declared with -E ,inf
-
the cross-check of common_utils: every Solver enters it as its [get_lb(), get_ub()] interval, valid by the base Solver contract, and is measured against the best bounds the whole set of them provides, since the optimum is not known. Correctness, i.e. not contradicting those bounds, is owed by every Solver; the quality it declares is owed only by the one that returns kOK, i.e. that says it delivered what it was asked, while kLowPrecision promises nothing. No Solver type or name is ever inspected
-
the tolerance each Solver is held to, which is by default the dblRelAcc its ComputeConfig asks of it, and never less than the tolerance the cross-check is called with, below which the comparison would only measure its own numerical noise
-
the -E option, overriding that tolerance per Solver (positionally with respect to the BlockSolverConfig, the empty field leaving the Solver to its dblRelAcc), for the Solver that does not say with kLowPrecision when it did not deliver the accuracy it was asked for, and whose dblRelAcc therefore says nothing about what it returns
-
the tester of
LagBFunctionno longer writesintDoEasyof theBundleSolverit attaches: whether they treat theLagBFunctionas easy components and which of their dual values they keep is in the BlockSolverConfigndopar,NDOPar.txtby default andNDOPar-Hard.txtwith positive #nt, and the rows ofbatchandbatch-easyname the one their changes want, out ofNDOPar-Hard.txt,NDOPar-Dual.txt(all the dual values) andNDOPar-RC.txt(the reduced costs), differential overrides ofBSCfg.txtas the-Dual.txtversion ofNDOPar-Mirror.txt,NDOPar-Lvl.txt,NDOPar-DS.txtandNDOPar-DS-NoSize.txtare -
the inner Solver of the
PrimalProximalHeurand of theLagrangianDualRelaxationSolvertakes its iterations and its accuracy from its own ComputeConfig, given withstr_LDSlv_ISCfg:ISCfg-PPH.txtinUCBlock,TwoStageStochasticBlockandSMS++/AbstractBlock, andISCfg-LDRS.txtinUCBlock, in place ofintInnerMaxIteranddblInnerRelAcc;intMaxThread, which the two Solver now keep for the threads of their primal recovery, is 0 in their configurations, asintRecoveryThreadswas 1, andUCBlock/PPHCfg-DP.txtisPPHCfg.txtwith only what differs -
UCBlock/batches/batch-acad-scross-checks aBranchAndXSolvertoo, whose nodes are solved by theLagrangianDualRelaxationSolverover the same sub-Blocks that the dynamic programming solves exactly, as a fourth Solver ofBSPar-DP-BX.txtstopped on time, branching on the commitment variables only (vstrBranchGroups); in CI it runs on the units of size 10 only, the other ones being solved withBSPar-DP.txt, as each instance takes 2 to 8 minutes and a test is given an hour on the runner of the nightly pipeline.batch-bx-ldandBSPar-BX-LD.txt, which ran it alone on four instances, are gone, and the configurations of the Lagrangian Dual and of the Branch-and-Bound are fragments (LDCfg-DPe.txt,LDRSCfg-DP.txt,BXLDCfg.txt,BXLDCfg-DP.txt) -
UCBlock/batches/batch-acad-scross-checks a secondBranchAndXSolver, whose nodes are solved by theLagrangianDualRelaxationSolverMLwith the branching rule learned online after 2 nodes of strong branching (LDRSCfg-DP-ML.txt,InnerBSCfg-BX-LD-DP-ML.txt,BXLDCfg-DP-ML.txt), in CI too on the units of size 10; a build without Torch leaves it out of the run, andUCBlock_testlinksLagrangianDualSolverMLwhen there is -
in CI
MultiFlowDCRBlockbatches-multiflow/batchruns one instance in 10, andSingleFlowDCRBlockbatch-instancesthe P/C formulation on one instance in 10 and not the SOCP one, on which Gurobi stops on numerical difficulties on the runner of the nightly pipeline, a different instance at each run, while it solves them on the machines of ours -
the meta BlockConfig and BlockSolverConfig of the tests accept the
"*"entry for the classnames they do not name, as those of tools do, and the sub-Block of a Block are looked up after it has been configured -
in CI,
MCFBlock/batches/batchandbatch-denseleave out the Frank-Wolfe decomposition, a single run of which takes the best part of an hour there (batch-smallruns it on the small instances),LagBFunction/batches/batchruns 3 seeds of the 20, andUCBlock/batches-tub/batch-reserveone instance in 10 of each family, so that each fits in the time limit of a test of the nightly pipeline -
the report of
SolveAll()starts on a line of its own, below whatever the test printed before it, and pads the values to the widest of them, the reference included, so that the values and the times of the Solver are in columns whatever the length of their names and of their intervals -
LDCfg-easy.txtandBSPar-DP.txtofUCBlockname the hard components withvstrNoEasyof the innerBundleSolver, which replacesvstr_LDSl_NoEasyofLagrangianDualSolver: which components are easy is a concept ofBundleSolver, and the classes listed are the same -
BDSCfg-LD.txtrecovers a feasible solution at the design of the master (strRecoveryBSC BSCfg1-IP.txt), and the thermal run ofTwoStageStochasticBlock/batches/batch-pypsachecks the interval of BendersDecompositionSolver, its bound below and that solution above, against the reference instead of its bound alone -
BDSMCfg-INV.txtdeclares the residual zero at 1e-6 instead of 1e-8: with the subproblems solved by a Lagrangian dual, whose linearizations are accurate to its owndblRelAcc, the bundle of the master reached the optimum without ever certifying its lower bound, and BendersDecompositionSolver reported-inf -
the testers are named after the component they test:
AbstractBlock_Box_testisLagrangianDualSolver_Box_test, since what it exercises is theLagrangianDualSolver(and thePrimalProximalHeurof the same module) on a box-structuredAbstractBlockwhoseLagBFunctionare solved byBoxSolver, and its battery isLagrangianDualSolver_Box_test/batches/batch-box;BendersBFunction_test2isBendersBFunction_linearization_test, whose source istest_linearization.cpp, since it checks the linearizations theBendersBFunctionproduces on small linear programs whose value is known -
PolyhedralFunctionBlock_prune_testtests onlyPolyhedralFunctionBlock::remove_redundant_rows(), which has to remove both the dominated and the inactive row, while the geometric pruning ofPolyhedralFunction::remove_parallel_rows()is tested byPolyhedralFunction_prune_test, on a convex function with the dominated row after and before the dominating one and on a concave function, and needs nothing but the core library -
GenerateRand(), the random subset ofkdistinct indices out of0 ... m - 1that eight testers copied (and the tester ofMMCFBlockkept commented out), is written once incommon_utilsand takes the generator as argument, the order of the subset being optional as it was in the testers ofMCFBlockand ofCapacitatedFacilityLocationBlock: the draws from the generator are the same as before, so every battery generates the same instances -
the
TwoStageStochasticBlocksuite is configured before those ofCapacitatedFacilityLocationBlockandUCBlock, whose batteries of the scenario reduction run itsTSSB_scenred_test -
BendersBFunction_testruns in the suite, on the 34 small instances of the capacitated warehouse location problem (cap41 to cap134), the large ones being left to a run by hand: it takes the instances as files as well as a directory, prints one line per instance and exits with 1 when an instance is KO, while it used to print KO and exit with 0; its directory has theSMS++label, whichctest -L "SMS\+\+"selects (the label is read as a regex, where the+are operators) -
the
ComputeConfigof the:MILPSolverof theSingleFlowDCRBlocksuite is written once, inMILPCfg.txt, whichBSPar.txt,BSPar-pc.txtand the configurations of the multi-flow problem include, Gurobi throughGRBCfg.txt, which adds a numerical focus of 2: without it the barrier stops short of the optimum of the SOCP formulation on some instances of the module, with a "Numeric error" or with a value a little below it -
the configurations of the Benders tester of
SVMBlockare named as the others are,BSPar-BDS-<variant>.txt(e.g.,BSPar-BDS-SMO.txt,BSPar-BDS-LSVM.txt) andBSPar-LSVM-only.txt; the three variants ofSMOCfg.txtare overrides of it, and theBSPar-SMO*.txthave the header of every other configuration -
the tester of
UCBlockbuilds no configuration in code: it reads-Band-Sand applies them. TheLagrangianDualSolverofBSPar.txtandBSPar-DP.txtcomes fromLDCfg-easy.txt, which lists the hard components by class (vstrNoEasyof the innerBundleSolver), the parallel variants ofbatch-ec-parareBSPar-par.txtandBSPar-par-aggr.txtrather than a config rewritten by the batch, and the network formulations ofbatch-pypsaareInnerBCfg-PTDF.txtandInnerBCfg-CYCLE.txt -
the formulation of the unit of
TUDPS_testis the BlockConfig given with-B, one file per formulation (TUBCfg-<form>.txt,-PCwith the Perspective Cuts), which the batteries ofbatches-tubloop over; the tester reads it back, as the changes it makes depend on it.TUBCfg-DP.txt(DP with the cuts) is nowTUBCfg-DP-PC.txt -
the budget of rounds of the two capped runs of
CFL_BDS_testisint_BDSlv_MaxRoundsinBDSCfg-MILP.txt, of whichBDSCfg-Pareto.txtis the override with the Pareto-optimal cuts;BSPar-BDS-MILP.txtandBSPar-BDS-Pareto.txtinclude them -
what the testers give an
InvestmentBlockand itsInvestmentFunctioncomes from the configuration files, the testers only reading and applying them: inInvestmentBlockand intest_bdsofTwoStageStochasticBlock, theOBlockConfigof theInvestmentBlock(IBOCfg.txt, theInvestmentBlockentry ofInnerBCfg.txt) reformulates the bounds and gives theInvestmentFunctionits ComputeConfig (IFCfg.txt) with the BlockSolverConfig of the inner Block, where the code built the BlockConfig, namedBSCfg1.txtin code and set the file of the candidates; theInvestmentBlockof anSDDPBlock, in a problem file, has its stages configured by-Band its greedy Solvers given the passage of the state.BSCfg1.txtis nowBSCfg.txt, andInvBCfg.txtofTwoStageStochasticBlock, a BlockSolverConfig,InvBSCfg.txt. The threshold of the Lagrangian case ofUCBlock_test --pollutantis inLDCfg-tight.txtrather than set in code -
the instances of
batches/batch-ecwhose components are allECNetworkBlock, and hence all easy, are solved with theBSPar.txtof every other instance of that battery,BundleSolverhandling that case now: the battery no longer picks a configuration by the name of the file, the tester no longer forces one of the components to be hard, andUCBlock/BSPar-EASY.txt, which wasBSPar.txtwithintDoEasyat 0, is gone -
the Lagrangian duals of
TwoStageStochasticBlockdeclare the residual zero at1e-6rather than1e-2(LDCfg.txt, which every one of them includes): with1e-2the bundle stopped with a dual value up to 1.6% below the optimal one and bounds that both lay below it, whence the cut ofBendersDecompositionSolverover such a subproblem was never tight and its loop repeated it -
SMS++/LagBFunction/TPPar.txtasks HiGHS for feasibility tolerances of1e-7, the default, rather than1e-9: the tolerances are absolute, and1e-9goes beyond what double precision holds as soon as the objective grows past1e7, which is how the suite ofInvestmentBlockfailed -
the
ComputeConfigof the flow relaxation of the capacitated facility location, all of them the default one, are the singleDfltCfg.txtthat the two configurations point at instead of seven copies of the same block, which is what takes those two files from 338 and 340 lines to about 100 -
the two batteries of
MCFBlockrun one seed of their three when$CIis set, as the one of the dynamic programming already runs 5 of its 100 ramp profiles: the three seeds are the same sweep with another random stream, while the whole of them takes more than an hour on a machine of ours and does not fit what a test is given on a shared runner -
the inner Solver of the
BendersBFunctionsuite is Gurobi, the one the image of the pipeline carries, so that the suite runs where it is run and not only where a licence of another solver happens to be -
the comparison of the three forms of a two-stage stochastic investment problem lives with the suite of the Block it is posed on, and not with the one of a Solver: the monolithic form, the Lagrangian one and the Benders one are configured side by side there
-
the makefile asks for
-O3 -DNDEBUGand nothing else, the macro of the patch forboost::anyon macOS having no reason to be there since there is noboost::anyleft in the core -
the tester of the copy of an
AbstractBlockand the one of the reference of the multicommodity suite are named after what they are, the core having a target called as the first one was -
a suite is guarded on the modules it is labelled with, and the benchmark of BundleSolverML is skipped when its modules are not in the build, so that a build without a module has no test that cannot run rather than a test that fails
-
the batteries of the Lagrangian dual of the unit commitment fit the three hours a job is given: the academic families are sampled in CI, the plan4res one is run as a smoke test, and the metabatch is not run there, being the batteries it is made of.
batch-acis added, and the variants of the energy community under the proximal heuristic are skipped in CI, where the objective of a thermal unit inside a LagBFunction is the known bug -
the batteries of the scenario reduction read their executables and their directories from the arguments instead of the paths of whoever wrote them, the tester is named after the Solver it drives, and the folder of the facility location is named after the Block it holds
-
the tester of
BendersBFunctionreports and counts its checks instead of aborting at the first one that fails, so that one run says how many of them hold and not only that one does not -
the comparison of the two Benders decompositions of a facility location instance lives with the suite of that Block, its configurations take the names the other suites give them, the inner Solver of the Lagrangian is called
BundleSolver, which is the name the factory has, and theBlockConfigfiles are in the format of now -
a run of the Frank-Wolfe tester attaches the reference and one
FrankWolfeSolverper variant of the decomposition at once, cross-checking the variants against one another as well, the way theBSParof a suite do with theSolverof itsBlock; the variants used to be run one at a time by a battery that rewrote theComputeConfigfile between them, which is gone together with thetrapthat put the file back. Each variant is an override of the shared fragment, and an override block writes the extra-Configurationslot even when it changes nothing of it: one that leaves it out is read on to the end of the stream and swallows theComputeConfigthat follows it, which is what made the Solver of every variant but the first run with its parameters at their default -
the configurations of the Frank-Wolfe tester live in the suite, flat beside those of every other
Solver, rather than in a directory of their own that a battery selected with-c: they are theFather*files, the same set with the same names in each of the three suites the tester is built in -
the reference
BlockSolverConfigof the Polyhedral path of the Frank-Wolfe tester is-F,-Rgoing back to what it is everywhere else, i.e. the declaration of whichSolversolve a relaxation of the problem -
the master problem of the Frank-Wolfe direction taken from a bundle (
MPBCfg-FW.txt, the same in the three suites) is solved by the dual simplex of Gurobi rather than by the barrier Gurobi picks for a QP: with the barrier almost every solve endedSUBOPTIMAL, the primal residual stalling just above the feasibility tolerance, and the number of iterations of a run changed from one run to the next, while with the simplex every solve is optimal and two runs of the same case repeat to the last iteration -
the four sector-coupled instances
batch-pypsawalks are written by the conversion as it stands, where an extendable asset with no upper bound keeps the infinite design cap it has instead of a finite number standing in for it: the ones the archive held carried1e10on nine converters and1e9on nine batteries, which the Lagrangian relaxation sends a design straight to, so that 262 of the 311 linearizations of a solve carried a subgradient entry of exactly1e10against function values of1e9, the rows of the master of the bundle became a difference of terms of1e12giving1e8, and on one of the four the master declared its numerical difficulties unrecoverable a step away from the optimum, upon which the bundle emptied itself one item at a time and the Lagrangian dual ended in error. The objective value of each of the four is the one it was, the caps having never been binding -
every directory of the suites is named after the module its tests are posed on, a suite living here exactly when the module cannot run it by itself: the testers of the objects of the core library are under
SMS++, those of the quadratic programs a:MILPSolveris asked to solve underMILPSolver, the benchmark of the machine-learning driven bundle, which reads the Block of two modules that are not among its dependencies, underBundleSolver/ML, and the suite of the facility location takes the name of its module,CapacitatedFacilityLocationBlock.compare_formulations, which is posed on whichever two Block its configurations name, stays in the root -
the batteries of
UCBlockthat walk the instances carrying one unit alone arebatches-tub, and each of them runs that family with every:Solverthat applies to it: the dynamic programme against the:MILPSolver, and the Frank-Wolfe decomposition of a father ofKcopies of the unit, which used to be a batch of its own -
the suite of
FrankWolfeSolveris dissolved into the suites of the Block it is posed on: the tester assumes nothing on the leaf Block it reads, hence it isfw_test.cppin the root besidecommon_utils, and each suite builds it with its own modules;MCFBlockbuilds it and the tester of what a Modification of the feasible region of a sub-Block does, andUCBlockbuilds it on the thermal unit -
the runs of a Solver that is not the one of the Block are in the battery of the instances they are posed on rather than in a batch of that Solver, its configurations staying together in a directory of their own, which
-cnames; this is whatFWis in the suites ofMCFBlockand ofUCBlock. The scenario reduction, which has no configurations of its own to keep apart, is in the suites instead: the generator of the scenarios of a unit commitment is in that ofUCBlockand what a reduction costs on an investment problem istest_reduction.cppin that ofTwoStageStochasticBlock, the Block it is posed on, each with its battery inbatches -
a battery runs every tester that applies to the family of instances it walks, and is therefore given all of them, the first as before and the others after it:
add_batch_test()names them and hands over the ones that are in the build. InMCFBlockthis is the Solver of the Block, the Frank-Wolfe decomposition and the rounds of Modification of the feasible region on the same instances,batch-smallbeing the fast one that walks every code path of the decomposition; inUCBlockthe dynamic programme and the decomposition on the same units -
the tester of the ways
BendersDecompositionSolverhas of writing a cut is not here: it writes the instance it runs on itself, hence it needs no Block of anyone else and it belongs to the test directory of that module, where it is and where it is being worked on. What stays here is the comparison of the ad hoc Benders decomposition aCapacitatedFacilityLocationBlockcarries with the generic one, which is posed on that Block -
BSCfg-nuc-dponly.txtofUCBlockis gone: it registered the extended dynamic programming Solver of the nuclear unit twice, so that the tester, which compares a first and a second Solver, would run with it alone. A Solver compared with itself checks nothing, and no battery used it; timing the dynamic programme alone is a thing to ask the tester for, not something to obtain by declaring the same Solver twice -
- the report of a cross-check says what each Solver is called, one per line and with the values aligned one under the other, instead of numbering them S0, S1, ...: with several Solver of different families on the same Block, which of them disagrees is what one needs to read at a glance
-
the three testers posed on an
AbstractBlockare one directory,SMS++/AbstractBlock: the box-structured Block whose Lagrangian dual is computed (test_box.cpp), the copy of the abstract representation (test_mirror.cpp) and the round trip of a linear program through a file (test_readwrite.cpp), with a batch each inbatches. The two regimes of the box one, the Lagrangian dual and the primal proximal heuristic, are one script taking which of them to run -
the batches of a suite are registered with
add_batch_test(), written once in the root instead of the same loop copied in every directory -
the scenario reduction is run from the suite of the Block whose scenarios are reduced: the generator of the unit commitment instances and the runs on them are in the suite of
UCBlock, those of the facility location in that ofCapacitatedFacilityLocationBlock, each with the two configurations they read -
a suite is named after the Block its tests are posed on, not after a Solver that runs on it:
AbstractBlock_mirrorisAbstractBlock, andLagrangianDualSolver_BoxisAbstractBlock_Box, the structuredAbstractBlockof box-constrained sub-Block being what it builds and the Lagrangian dual one of the ways it solves it -
the suite of
MILPSolveris the test directory of that module, where its two testers now live astest_farkas.cppandtest_groups.cpp: neither of them needs a Block of another module, hence neither of them needs to be here -
the suite of the dynamic programming solver of
ThermalUnitBlockis part of the suite ofUCBlock, whose instances it reads and whose Block it solves in two ways: the tester istest_tudps.cppand its batches are inbatches-tub, each of them run with that tester rather than with the one of the suite -
SVMBlockruns the comparison of the two dual decompositions of one training problem, the consensus one underLagrangianDualSolverand the Benders one underBendersDecompositionSolver, both cross-checked against the ad hoc solver of the module, andPolyhedralFunctionBlockruns the unit test of the pruning of the rows: both come from the test directory ofBendersDecompositionSolver, which is not where a test that needs another Block to exist belongs -
SMS++/AbstractBlockruns the validation ofBendersDecompositionSolveron a two-stage linear program written as anAbstractBlock, the tester beingtest_bds.cpp(AbstractBlock_BDS_test, labelledSMS++;MILPSolver;BundleSolver;BendersDecompositionSolver) and its configurationsBSPar-BDS*.txt,BDSMCfg.txt,BDSMCfg-MILP.txtandBDSSCfg.txt, the master problem of the bundle using theMPBCfg.txtof the suite: it comes from the test directory of the module, which is not where a test belongs that needs aBundleSolverfor the master and a:MILPSolverfor the subproblems and the reference, neither being a dependency of the module -
batch-resilientofUCBlock,TwoStageStochasticBlock,MultiStageStochasticBlockandInvestmentBlockis nowbatch-pypsa, and the instances it reads are indata/nc4/pypsa-datainstead ofdata/nc4/resilient-data, the folder that holds all the networks translated from PyPSA, one sub-folder per kind of problem:ucblock,pollutants,tssb(whose files are named after the perturbation, instead of lying in a sub-folder each) andmssb; the instances ofEC_Dataare divided in the same way, inucblock,tssbandmssb -
the PyPSA instances of
pypsa-data/ucblockand of thepypsa-dataofInvestmentBlockare written by one generator,test/instance_generator.pyof pypsa2smspp, which builds each test network once and writes it in the two forms the conversion supports, the one where the design variables are those of theUCBlockand the one where anInvestmentBlockwraps it: the two are therefore the same problem and are held to the same reference, the objective value PyPSA computes on that very network. The demand and the hydro inflow of a test network being drawn at random, the generator fixes the seed, so that the instances can be written again; the uncapped extendable assets take the finite caps of the instances with a pollutant budget, an unbounded design making some Lagrangian sub-problem unbounded. The reference values all change, the previous instances coming from an older state of the conversion, and one instance is named after its Excel case,2n_1c_1g_1b_2linstead of2n_1c_1g_1b -
the two-level scenario trees of
pypsa-data/mssb, and the ones theInvestmentBlockruns with the investment stated outside the scenarios, are written bytest/tree_instance_generator.pyof pypsa2smspp from the treesreferences/gen_resilient_tree.pydraws with a fixed seed, each form of a tree being held to the objective value PyPSA computes on the equivalent flat network. The reference values change, the instances in place having been emitted from trees that were drawn again since, and so do the file names, the trees now spanning a day of 24 instants rather than 100: over 100 the MultiStageStochasticBlock of one of them ends in an error after eleven minutes, and the InvestmentBlock over the flat form of another after twenty-four -
the two instances named after the
inv_Excel cases are gone, those cases giving the very networks1n_1c_1gextand2n_1c_1gext_1bext_2lgive, to the byte -
UCBlock/batches/batch-pypsaruns with its own BlockSolverConfig,BSPar-PYPSA.txt, which isBSPar-EASY.txtwithintWZNormat 2 rather than the 10 ofLDCfg.txt: that parameter says which norm of the residual the stopping condition uses and howdblNZEpsis read, and the 8 of that 10 asks for a threshold scaled by the norm of the first full subgradient, which the plan4res instances want. The subgradients of these instances are the productions of the units on the very rows the demand sits on, so that norm is 7.27e+06 against an aggregate of 1.96e+04, and 1e-2 of it stops the Bundle at the first iteration on a value two orders of magnitude below the optimum; read as the absolute value it is on develop, their duals converge in 50 to 600 iterations on the value the MILP computes;InvestmentBlock/batches/batch-pypsafails when it finds no instance at all, which is how a batch that has tested nothing was until now indistinguishable from one where everything went well -
check_relaxation_solutions()holds the point a relaxation reconstructs to the dualised rows only where that relaxation is exact, i.e., where the bound it reports is the optimum: where it is not, that point is a convex combination which violates those rows by the very gap, and holding it to them called a duality gap an error. The reference value is the new argument that says which of the two cases one is in -
InvestmentBlock/batches/batch-pypsafails when it finds no instance at all, which is how a batch that has tested nothing was until now indistinguishable from one where everything went well -
the nested chain of TwoStageStochasticBlock (BSPar-2S-LD.txt, where each scenario sub-problem is solved by an inner LagrangianDualSolver) evaluates every component at each iteration, dblMinNrEvls = -1: a component being an entire inner Lagrangian Dual, an iteration made on one of them alone buys little and pays a master problem anyway; on the NC instances of the energy community the oracle calls go from 865 and 1705 down to 132 and 168, and nothing gets worse on the others
-
LPBSCfg-LD-noeasy.txt, the inner LagrangianDualSolver of that chain with intDoEasy = 0, which the instances with no installable asset need: every unit of theirs is "easy", and a Lagrangian Dual all of whose components are easy is not supported
-
with -v 2 the cross-check prints, before solving, the parameters of every Solver it is about to run, the inner ones included; the level of -v can be written attached or separate, since getopt only hands over the attached form
-
the solve-a-Block-with-Solvers cross-check testers renamed after the Block they exercise: UCBlock (was LagrangianDualSolver_UC, executable UCBlock_test) and MCFBlock (was MCF_MILP, executable MCFBlock_test); LagrangianDualSolver_MMCF was merged into MMCFBlock as a second executable (MMCFBlock_test) alongside the existing MMCF_test, sharing its instance data
-
the one-per-instance cross-check line of SolveAll() (timings, every Solver value, reference, verdict) is now always printed; only the per-round lines of the tests that re-solve in a loop of modifications remain verbose-only
-
PrimalProximalHeur is attached to the AC and resilient batteries too (BSPar-AC.txt and BSPar-EASY.txt now cross-check it as well)
-
the PPHCfg of UCBlock solves the Lagrangian Dual of every proximal iteration to convergence, with the stopping parameters BSPar.txt gives to the LagrangianDualSolver on the same Lagrangian Dual, so that the fractional solution the penalty is built on is the convexified one, and follows the parameters of PrimalProximalHeur being now named after the algorithm they belong to; no -E is needed for the LagrangianDualSolver, which says with its return code that it is a relaxation; the LagBFunctions solve the sub-Block with the same BlockSolverConfig the LagrangianDualSolver gives them, rather than with the plain relaxation of every one of them
-
UCBlock cross-checks every Solver of its BlockSolverConfig at once, rather than selecting one of them from the command line: the meta- batches are gone and each batch is a ctest test of its own
-
the batteries
batch-aggrofMMCFBlockand ofCapacitatedFacilityLocationBlock, which measure the times of the partial aggregation ofBundleSolverfor a paper and check nothing (noctestruns them): they live with the other experiments of that paper; with them gocfg_set_parandrun_timedofbatch_common.sh, which only they used -
the options
-l,-n,-rand-sof the tester ofInvestmentBlock, which had no effect, and the functions only they or nobody called; the configurations ofInvestmentBlockthat the suite never read (BSCfg.txtas it was,BSCfg2.txt,BlockConfig1.txt,BlockConfig2.txt,RBlockConfig1.txt,RBlockConfig2.txt,SimpleConfig1.txt,SimpleConfig2.txt), copies of those ofcompare_formulations -
the option
-fof the tester ofUCBlock, the formulation of theHydroSystemUnitBlockand the rest of the configuration it built, which-Band-Sgive;OUBSCfg.txtandSRSCfg.txt, which no test read -
the option
-fofTUDPS_testand the third argument ofCFL_BDS_test(the budget of rounds), which the configuration files give; the relaxation that the tester ofQuadFunctionset on top ofLPPar_C.txt, which already asks for it
-
the variants of
FrankWolfeSolverin one run offw_teststart from the same point: aFrankWolfeSolverstarts from the vertex its oracle gives at the values it finds in theBlock, which were those the previousSolverhad left, so that the same variant gave a different value according to what ran before it and the comparison depended on the order of theBlockSolverConfig;SolveAll()takes aSolutionto write into theBlockbefore eachSolver, andfw_testpasses the one the father has before any of them computes -
SolveAll()takes the side of the bound of a Solver declared a relaxation from the sense of the objective of the Block, which a Block without an Objective of its own (its objective being the sum of those of its sub-Block, as forMultiKnapsackAssignBlock) also gives, the bound of such a maximization problem having been taken for a lower one -
SMS++/AbstractBlock/test_boxchanges the RHS of the <= linking rows and the LHS of the >= ones, and checks each against the value it set -
the
CapacitatedFacilityLocationBlockbatteries require the fixture that extracts data/txt, which they read, and the conversion to netCDF waits for it -
UCBlock/MPBCfg.txtasks Gurobi forFeasibilityTol1e-8 rather than the 1e-9 of the otherMPBCfg.txt: the units of the Lagrangian relaxation of the UC give no vertical rows, against which the tighter value is there, and with it the master stopped with status 12 (numerical difficulties) after the presolve, 18 times in a row on T-Ramp 10_0_4_w -
the test
run_dmx2nc4ofMCFBlockandMCFClassSolver_run_dmx2nc4share aRESOURCE_LOCK: they build the same target, and underctest -jthey ran at the same time and wrote the same instances, leaving one of them empty, so thatMCFBlock_test/batches/batchfailed on it -
check_relaxation_solutions()does not hold to the dualised rows the reconstruction of a Solver that stopped before converging (anything but kOK, whichSolveAll()now records,last_status()), since its residual is not zero yet: on a slower machine the Lagrangian dual of L_B_N_9 stops at its time limit, and its combination was taken for a wrong one -
TSSB_test/batches/batch-mmcfrequires the fixturecanad_fetched, so that the Canad instances its generator reads are there when it starts rather than whenfetch_canad_datahappens to have run before it -
batch-p4rdeclares the interval of the Lagrangian dual on L_B_N_1, 2.5e-3 wide while the bundle reports kOK, as it does for L_B_C_24 -
the tests of
BinaryKnapsackBlockandtest_tudpsperturb the solution they read back only in the Variable that are not fixed, as writing a different value in a fixedColVariablethrows -
the cross-check of
SolveAll()declares the infeasibility unanimous when all the Solver that are not relaxations say infeasible and those that are have a one-sided bound, which is no claim of feasibility (the Lagrangian dual of an infeasible problem with feasible subproblems grows without ever proving it), rather than taking them for a disagreement, and so for a Solver whose interval is the whole line, such as a heuristic that has found nothing -
a tester picks the
:Solverit solves with throughfirst_Solver_of()ofcommon_utils, which returns the first of the given names that the factory holds and says onstd::cerrwhich ones it has looked for, and what the run gives up, when it holds none of them:Solver::new_Solver()throws on a name that is not there, soUCBlock_test --scale, which asked the factory for one name after the other, died with "CPXMILPSolver not present in Solver factory" on every build without CPLEX, the pipeline comprised -
the two fixtures that bring in the curated knapsack data,
fetch_bk_dataandrun_bk2nc4, hold the sameRESOURCE_LOCK: run at once, asctest -j2did, they drive the build system on the sametxt.tgz, which tar then reads as an archive that ends too soon -
the archive of the Canad instances of MMCFBlock is extracted by
cmake -E tar, which also works with the tar of macOS, where the option--warning=no-unknown-keywordof GNU tar stopped the build -
the tester of
MultiStageStochasticBlockwrites the round trip of theSolutionto a file of its own name, since the batteries of the suite run in parallel in the same directory and read each other's file -
a tester whose instance file is not there says so and stops with 1, where
Block::load( std::string )wrote onstd::cerrand returned, leaving an emptyBlockon which the run went on until something else broke: onCapacitatedFacilityLocationBlockan exception about the number of facilities being too small, which reachedstd::terminate()and dumped core, hiding the missing file behind a message about the instance. The check isload_Block_or_exit()ofcommon_utils, used by the testers ofCapacitatedFacilityLocationBlockandMCFBlock;CFL_BDS_testkeeps skipping the comparison instead, the ORLib instances being downloaded by the build and not always there -
CFLScenarioGenerator/batches-scenred/batchasks for the fixture that writes the netCDF instances it reads, without which it failed in a fresh build tree -
the tester of
CapacitatedFacilityLocationBlockappliedBSPar1.txtandBSPar2.txtby itself, so that theSolverthis build does not have were not left out as the other testers leave them [sees_config_Block()], and a run died onMCFSolver<MCFCplex> not present in Solver factorywherever CPLEX is not there, the pipeline included -
InvestmentBlock/MPBCfg.txtleaves the presolve of the master at its default: with it off the master of a design over several extendable lines ends in "Bundle::FormD: unrecoverable MP failure" -
MCFBlock/BSPar-static.txt, the configuration with every Solver of a MCFBlock whose graph does not change, is in the repository:batch,batch-smalland the README of the suite read it, and without itbatch-smallstopped at its first run -
BinaryKnapsackBlock/batches/batch-jookenandbatch-pisinger-largerun withOPENBLAS_NUM_THREADS=1, andBSPar-milp.txtgives HiGHS a single thread: the memory cap of the two lineups is on the address space, and on a machine with many cores the threads that OpenBLAS starts at load time (one per core up to 64) and the pool of HiGHS (half of the cores) took the parallel depth-firstBranchAndXSolverand the MILP past 8 GB, so both crashed on every instance while using a few tens of MB -
the step that fetches the data archive of the multicommodity suite says what went wrong when it goes wrong: the download is checked, an archive that did not arrive is removed instead of being left on disk for the build to take for the real one, and the message names the URL. A server that answers with an error page used to leave a file of a few bytes there, which made the next build fail while extracting it, with the message of
tarand no mention of the download -
the build no longer waits for the data of the facility location: the tester of the Benders decomposition was hung on the target that extracts the archive, which put the download in the default target, so a registry that answers with an error stopped the build of the libraries as well, and it took a 503 of GitLab to see it. What the tester needs is prepared by a test fixture, as in every other suite
-
the two configurations of the suite of
InvestmentBlockasked HiGHS for a feasibility tolerance of1e-9, which is absolute, on instances whose objective is of the order of1e11, i.e., beyond what double precision holds: HiGHS declared the model optimal and its primal solution infeasible at the same time, which reaches the caller as a solve that went well with no solution in it, and theInvestmentFunctionturned that into an error that stopped the bundle. They ask for1e-7, the default, andbatches/batch-pypsapasses -
LukFi_teststops with an error when theBlockSolverConfigit reads attaches noSolverto theLukFiBlock, e.g. because the file is empty or malformed, rather than crashing on the first element of an empty list -
the suites that try each :MILPSolver in turn skipped the ones the build does not have by constructing them, while
Solver::new_Solver()throws rather than returningnullptron a name the factory does not hold, soMILPSolver_test/groupsandUCBlock_test/pollutantdied withCPXMILPSolver not present in Solver factorywherever CPLEX is not installed; they askSolver::has_Solver()first, andAbstractBlock_mirror_test, which named CPXMILPSolver and nothing else, takes the first :MILPSolver the factory holds unless one is named on the command line -
the tester of
ThermalUnitBlockcompares theSolutionof a Solver with the state it left in the Variable once that is completed from(p, u)as theSolutionis when it is written: with the perspective cuts the epigraph a Solver leaves is only as tight as the separated cuts,1e-7relative, and on an objective that is the difference of much larger terms this showed as aSolutionworth4e-6more than the Variable
0.6.0 - 2025-12-12
-
tests comparing UCBlock solutions with expected values
-
tests for PrimalProximalHeur
-
ComputeConfig for "easy" case in LagBFunction
-
tests for duals in LDS_MMCF
-
[big] tests for Quadratic Problems
-
LEMON to tests/MCF_MILP
-
support for both LP and MPS fles in Write-Read
-
MMCFBlock/gen and the README accordingly to account for the new way of distributing the instances
-
all things that can be changed, and the common definitions, are now in makefile_common to reduce code duplication within makefiles and to make adapting to one's environment quicker
-
adapted to new standard organization of makefiles
- several fixes throughout the testers
0.5.4 - 2024-02-29
-
compare_formulations tester
-
Write-Read tester
-
added -Wno-enum-compare to Makefiles (we regularly do that in SMS++)
-
adapted to new CMake / makefile organisation
-
significant updates to CapacitatedFacilityLocation
- many minor fixes to testers and/or config files
0.5.3 - 2023-05-17
- Early stop in test of ThermalUnitBlock.
- GoogleTest-based test for DPThermalUnitBlock.
- LagrangianDualSolver_UC/test.
0.5.2 - 2022-07-01
-
CapacitatedFacilityLocation tester.
-
Code to test different formulations of some problem.
- Complete rehaul of MCF_MILP tester.
0.5.1 - 2021-12-08
- New tester for ThermalUnitDPSolver.
0.5.0 - 2021-12-08
-
ThermalUnitBlock_Solver tester.
-
BinaryKnapsackBlock tester.
- Completion of dynamic variables handling in test/PolyhedralFunction.
0.4.0 - 2021-02-05
-
Significant improvements in LagBFunction testing.
-
Testers now better use BlockSolverConfigs to be more general.
-
Significant improvements in BendersBFunction testing.
-
Added MMCFBlock tester.
-
Added LagrangianDualSolver_UC tester.
-
Added BoxSolver tester.
-
Added LagrangianDualSolver_Box tester.
-
Added LagrangianDualSolver_MMCF tester.
-
Improved UCBlock tester.
-
Improve README.md with ones for individual testers.
- Too many individual fixes to list.
0.3.2 - 2020-09-24
- Workaround for default MCFSolver setting.
0.3.1 - 2020-09-24
- Compilation issue under Debian/Clang 7.
0.3.0 - 2020-09-16
-
Support for concurrency.
-
Support for new configuration framework.
- Files reorganized.
0.2.0 - 2020-03-06
- Changelog.
- Minor fixes.
0.1.0 - 2020-01-10
- First test release.