Runtime
neps.runtime
#
Module for the runtime of a single instance of NePS running.
An important advantage of NePS with a running instance per worker and no multiprocessing is that we can reliably use globals to store information such as the currently running configuration, without interfering with other workers which have launched.
This allows us to have a global Trial
object which can be accessed
using import neps.runtime; neps.get_in_progress_trial()
.
This module primarily handles the worker loop where important concepts are: * State: The state of optimization is all of the configurations, their results and the current state of the optimizer. * Shared State: Whenever a worker wishes to read or write any state, they will lock the shared state, declaring themselves as operating on it. At this point, no other worker can access the shared state. * Optimizer Hydration: This is the process through which an optimizer instance is hydrated with the Shared State so it can make a decision, i.e. for sampling. Equally we serialize the optimizer when writing it back to Shared State * Trial Lock: When evaluating a configuration, a worker must lock it to declared itself as evaluating it. This communicates to other workers that this configuration is in progress.
Loop#
We mark lines with +
as the worker having locked the Shared State and ~
as the worker
having locked the Trial. The trial lock ~
is allowed to fail, in which case all steps
with a ~
are skipped and the loop continues.
-
- Check exit conditions
-
- Hydrate the optimizer
-
- Sample a new Trial
- Unlock the Shared State
- ~ Obtain a Trial Lock
- ~ Set the global trial for this work to the current trial
- ~ Evaluate the trial
- ~+ Lock the shared state
- ~+ Write the results of the config to disk
- ~+ Update the optimizer if required (used budget for evaluating trial)
- ~ Unlock the shared state
- Unlock Trial Lock
SharedState
dataclass
#
The shared state of the optimization process that workers communicate through.
ATTRIBUTE | DESCRIPTION |
---|---|
base_dir |
The base directory from which the optimization is running.
TYPE:
|
create_dirs |
Whether to create the directories if they do not exist.
TYPE:
|
lock |
The lock to signify that a worker is operating on the shared state.
TYPE:
|
optimizer_state_file |
The path to the optimizers state.
TYPE:
|
optimizer_info_file |
The path to the file containing information about the optimizer's setup.
TYPE:
|
results_dir |
Directory where results for configurations are stored.
TYPE:
|
check_optimizer_info_on_disk_matches
#
check_optimizer_info_on_disk_matches(
optimizer_info: dict[str, Any],
*,
excluded_keys: Iterable[str] = ("searcher_name")
) -> None
Sanity check that the provided info matches the one on disk (if any).
PARAMETER | DESCRIPTION |
---|---|
optimizer_info |
The optimizer info to check. |
excluded_keys |
Any keys to exclude during the comparison. |
RAISES | DESCRIPTION |
---|---|
ValueError
|
If there is optimizer info on disk and it does not match the |
Source code in neps/runtime.py
trial_refs
#
Get the disk reference of every trial, grouped by their state.
Source code in neps/runtime.py
Trial
dataclass
#
Trial(
id: str,
config: ConfigLike,
pipeline_dir: Path,
prev_config_id: str | None,
metadata: dict[str, Any],
results: dict[str, Any] | ERROR | None = None,
)
A trial is a configuration and it's associated data.
The object is considered mutable and the global trial currently being
evaluated can be access using get_in_progress_trial()
.
ATTRIBUTE | DESCRIPTION |
---|---|
id |
Unique identifier for the configuration
TYPE:
|
config |
The configuration to evaluate
TYPE:
|
pipeline_dir |
Directory where the configuration is evaluated
TYPE:
|
prev_config_id |
The id of the previous configuration evaluated for this trial.
TYPE:
|
metadata |
Additional metadata about the configuration |
results |
The results of the evaluation, if any |
disk |
The disk information of this trial such as paths and locks
TYPE:
|
Disk
dataclass
#
Disk(pipeline_dir: Path)
The disk information of a trial.
ATTRIBUTE | DESCRIPTION |
---|---|
pipeline_dir |
The directory where the trial is stored
TYPE:
|
id |
The unique identifier of the trial
TYPE:
|
config_file |
The path to the configuration file
TYPE:
|
result_file |
The path to the result file
TYPE:
|
metadata_file |
The path to the metadata file
TYPE:
|
optimization_dir |
The directory from which optimization is running
TYPE:
|
previous_config_id_file |
The path to the previous config id file
TYPE:
|
previous_pipeline_dir |
The directory of the previous configuration
TYPE:
|
lock |
The lock for the trial. Obtaining this lock indicates the worker is evaluating this trial.
TYPE:
|
config
#
from_dir
classmethod
#
load
#
load() -> Trial
Load the trial from disk.
Source code in neps/runtime.py
to_result
#
to_result(
config_transform: (
Callable[[ConfigLike], ConfigLike] | None
) = None
) -> ConfigResult
Convert the trial to a ConfigResult
object.
PARAMETER | DESCRIPTION |
---|---|
config_transform |
A function to transform the configuration before
creating the
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
ConfigResult
|
A |
Source code in neps/runtime.py
State
#
The state of a trial.
COMPLETE
class-attribute
instance-attribute
#
The trial has been evaluated and results are available.
CORRUPTED
class-attribute
instance-attribute
#
The trial is not in one of the previous states and should be removed.
IN_PROGRESS
class-attribute
instance-attribute
#
There is currently a worker evaluating this trial.
PENDING
class-attribute
instance-attribute
#
The trial has been sampled but no worker has been assigned to evaluate it.
write_to_disk
#
write_to_disk() -> Disk
Serliaze the trial to disk.
Source code in neps/runtime.py
launch_runtime
#
launch_runtime(
*,
evaluation_fn: Callable[..., float | Mapping[str, Any]],
sampler: BaseOptimizer,
optimizer_info: dict,
optimization_dir: Path | str,
max_evaluations_total: int | None = None,
max_evaluations_per_run: int | None = None,
continue_until_max_evaluation_completed: bool = False,
logger: Logger | None = None,
post_evaluation_hook: (
POST_EVAL_HOOK_SIGNATURE | None
) = None,
overwrite_optimization_dir: bool = False,
pre_load_hooks: (
Iterable[Callable[[BaseOptimizer], BaseOptimizer]]
| None
) = None
) -> None
Launch the runtime of a single instance of NePS.
Please refer to the module docstring for a detailed explanation of the runtime. Runs until some exit condition is met.
PARAMETER | DESCRIPTION |
---|---|
evaluation_fn |
The evaluation function to use. |
sampler |
The optimizer to use for sampling configurations.
TYPE:
|
optimizer_info |
Information about the optimizer.
TYPE:
|
optimization_dir |
The directory where the optimization is running. |
max_evaluations_total |
The maximum number of evaluations to run.
TYPE:
|
max_evaluations_per_run |
The maximum number of evaluations to run in a single run.
TYPE:
|
continue_until_max_evaluation_completed |
Whether to continue until the maximum evaluations are completed.
TYPE:
|
logger |
The logger to use.
TYPE:
|
post_evaluation_hook |
A hook to run after the evaluation.
TYPE:
|
overwrite_optimization_dir |
Whether to overwrite the optimization directory.
TYPE:
|
pre_load_hooks |
Hooks to run before loading the results.
TYPE:
|
Source code in neps/runtime.py
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 |
|