Changelog¶
0.4.0¶
The first release since 0.3.22. Parts of the Python and C++ APIs changed: the upgrade guide says what code written for 0.3 has to change. The ids, names and values of the built-in problems are unchanged, apart from the fixes below.
Installation¶
Python 3.10 or later (3.9 is no longer supported); 3.12 or later is recommended.
Wheels for CPython 3.10–3.15 on Linux x86_64 and (new) aarch64, Windows x64 and (new) ARM64 (from 3.11), and macOS Intel (10.15 or later) and arm64 (11.0 or later). CPython 3.12 and later share one wheel per platform (
cp312-abi3), which also installs on later versions.New free-threaded wheels for CPython 3.14t and 3.15t: the GIL stays disabled.
The Linux wheels need glibc 2.27 or later on x86_64 (0.3.22: 2.17) and 2.26 or later on aarch64. There are no more wheels for 32-bit Linux and Windows. There, and on x86_64 Linux with an older glibc, pip builds the package from source, which needs a C++17 compiler;
pip install "ioh<0.4"installs the 0.3.22 wheels instead.The wheels no longer install top-level
testsanddocpackages.
Faster¶
The bindings moved from pybind11 to nanobind. Problems take numpy arrays at once instead of element by element: a 100-dimensional problem evaluates about 8 times faster from a numpy array, and about 2 times (Python 3.10 and 3.11) or 1.2 times (3.12 and later) faster from a list. Attribute access, state, meta data and suite iteration are faster too.
ManyAffine (MA-BBOB) problems skip the components with weight 0, whose
sub_problemsare no longer evaluated.CEC2022 problems are created about 5 times faster: their data are read once.
Changed¶
Numeric vectors are returned as numpy arrays instead of lists:
LogInfo.x,violationsandpenalties, the batch callproblem(X), the ManyAffineweights,instances,scale_factorsandfunction_values, the DynamicBinValweights,DynamicBinValRanking.rank,rank_indicesandget_comparison_ordering,EAH.atand the matrices inEAH.data, and the graph weights (read-only views). Overrides ofevaluate,transform_variablesandAbstractWModel.wmodel_evaluatereceivexas a numpy array instead of a list, like the functions given towrap_problem.Solution.x, the bounds and the results oftransform_variablesandcalculate_objectivetake numpy arrays at once.The enums (
OptimizationType,ConstraintEnforcement,StarDiscrepancySampler) areenum.Enumclasses;.name,.value,int(...)and construction from an int work as before.Paths are returned as
pathlib.Path(ioh.logger.Pathispathlib.Path), and path arguments take str andos.PathLike. On Windows, paths with characters outside the ANSI code page work.Arguments are converted more strictly: a bool argument takes only
TrueandFalse(notnp.bool_, 0/1 or None), an int argument only objects with__index__. Integer problems, solutions and bounds take numpy arrays of any integer or bool type.A problem’s id belongs to its family (BBOB, PBO, …). Registering a problem whose id is taken in its family raises
ValueError, and so does registering under the name of a built-in problem (wrap_problem(f, "Sphere")replaced Sphere forget_problem(1)). Problem classes defined in Python by subclassing report the id they are registered under instead of 0, also in logged data.The
createmethod of the problem classes (e.g.problem.RealSingleObjective.create) raisesIndexErrorfor an unknown id or name (in 0.3.22 this was undefined behaviour;get_problemraisesValueError, as before).load_instances(path)adds the graphs of a definitions file after the existing problems (from id 2309 on, unless other graphs were added before), never replaces built-in graphs, and returns the new ids and names;load_instances()without a path is deprecated and does nothing.Data files: the package uses the data files installed with it, from any working directory, and no longer sets
IOH_RESOURCES(which still names another data directory).ioh.set_data_root(path)andioh.data_root()set and show the directory. Missing or stale data raiseioh.DataError(aRuntimeError) when a problem that needs them is created, instead of abortingimport ioh.download_static_folder()andload_graph_problems()are deprecated and do nothing.The overrides of Python subclasses of
Store,FlatFileandAnalyzer(e.g. ofcallorattach_problem) are now called by the problems and suites they log.LogInfo.objectiveand the elements ofCEC2013.optimaare copies: writing to them no longer changes the problem.Threads: different problems, loggers and suites can be used from different threads at the same time, also on a free-threaded Python; one object is used by one thread at a time. Loggers that run at the same time need their own
OnDeltaImprovementandOnViolationtriggers instead of the sharedON_DELTA_IMPROVEMENTandON_VIOLATION.New:
MetaData.fixed_dimensionandfixed_instance, whether a problem has one dimension and one instance whatever was requested (CEC2013 and graph problems);MetaData(...)takes them too.Signatures and docstrings follow nanobind’s notation; the type stubs include
logger.oldandproblem.sbox.The objective-function server (
ioh-server) moved to its own repository, IOHprofiler/ioh-objective-server.The documentation is built from the sources by CI and published at https://iohprofiler.github.io/IOHexperimenter.
Fixed¶
On Windows, the graph problems’ ids and names were one too high (
get_problem(2308)was namedPackWhileTravel2309), also in logged data.After a call of the Sobol sampler with a dimension outside 1–1111 raised an error, later points in the previous dimension were about 0 (
SobolStarDiscrepancy*problems,StarDiscrepancySampler.SOBOL, C++sampler::Sobol).Sobol star discrepancy problems get the same grid whatever problems were created before them.
Analyzers made with the default triggers shared one best value, so an Analyzer could skip lines because of another’s run. Analyzers created at the same time, also in different processes, get different folders.
EAH.sizeandreprof anEAHwithout data crashed.Experiment.add_custom_problemfailed when the problem ids were a numpy array (e.g. a suite’sproblem_ids).logger.property.Property(container, attribute)raisedSystemErrorfor an attribute that is not a number; it raisesTypeError.
C++¶
The library is no longer header-only. Every program links the
ioh::iohtarget (with CMake) or compilessrc/: it holds the registries of the built-in problems and suites, which are filled when a factory is first used instead of at program start, and the BBOB/SBOX problem classes. The default build type is Release; the Debug library isiohd.Registration: a problem class declares
registry_idandregistry_name, or lists its problems in a staticregistry_entries(), and is registered withregister_problem<T, Parent>(), once for each factory; suites declareregistry_idandregistry_nametoo and are registered withregister_suite<T>(). Removed: the registration at program start (RegisteredProblem,AutomaticProblemRegistration,AutomaticSuiteRegistration,AutomaticTypeRegistration,RegistrationInvoker,InvokeApplyOnConstruction),InstanceBasedProblemand itsload_instances, the base classesBBOProblem,PBOProblem,CEC2013Problem,CEC2022Problem,DynamicBinValProblem,RealSuiteandIntegerSuite,RegisterWithFactory::include,IdGetter,FactoryID,type_nameandclass_name. Suite ids are fixed (Real 1, BBOB 2, SBOX 3, RealStarDiscrepancy 4; Integer 1, PBO 2, Submodular 3, IntegerStarDiscrepancy 4).Factory::createwith an unknown id or name throwsstd::out_of_range; registering a problem whose id is taken in its family’s factory throwsstd::invalid_argument.Factory::include_with_id(name, first, make)chooses an id and registers under one lock.Data:
ioh::data(set_root,root,file,data_error) replacesget_static_rootandfind_static_file. The library finds its data in the directory given toioh::data::set_root, inIOH_RESOURCES, in the source tree it was built from or inshare/iohof the installation (installed bycmake --install); it no longer searches the working directory’s parents. The test reference files moved fromstatic/totests/data/.CMake 3.16 or later (also CMake 4). The tests and the example are built by default only when IOHexperimenter is the top-level project; the tests are one executable,
test_ioh, andctestruns from the top of the build directory.The server, the CMake option
BUILD_SERVER, the json and cxxopts submodules andioh::common::file::merge_output_to_single_folderare gone.ioh::common::random::GENERATORis one generator per thread. An Analyzer giventrigger::on_delta_improvement(the default) has its ownOnDeltaImprovement.
Building from source¶
The package builds with scikit-build-core instead of
setup.py(pip install .). A rebuild (pip install --no-build-isolation -e .) compiles only what changed, and a clean build takes about a quarter of the time it took for 0.3.22: the problem library is compiled once instead of in every source file of the bindings, and the sources are compiled in batches.ARCHFLAGSis respected on macOS.MAKE_STUBSandMAKE_DOCSare replaced bypython tools/gen_stubs.pyandpython doc/generate_docs.py.The sdist holds only what building the package needs, with the license of the bundled fmt. The package metadata give the license as
BSD-3-Clause.
0.3.22 and earlier¶
See the GitHub releases.