-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add example EOS package and modify example config, update eos pkg cre…
…ate, update docs
- Loading branch information
1 parent
2448981
commit efc6960
Showing
18 changed files
with
349 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -170,4 +170,5 @@ cython_debug/ | |
/config.yml | ||
|
||
/user/* | ||
!/user/example/ | ||
!/user/.gitkeep |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import asyncio | ||
from dataclasses import asdict | ||
from datetime import datetime, timezone | ||
from eos.persistence.async_db_interface import AsyncDbInterface | ||
from eos.persistence.service_credentials import ServiceCredentials | ||
from eos.tasks.entities.task import Task, TaskInput, TaskOutput, TaskStatus, TaskDeviceConfig, TaskModel | ||
from eos.experiments.entities.experiment import ( | ||
Experiment, | ||
ExperimentStatus, | ||
ExperimentExecutionParameters, | ||
ExperimentModel, | ||
) | ||
from sqlalchemy.ext.asyncio import AsyncSession | ||
|
||
|
||
async def main(): | ||
# Initialize the database interface | ||
db = AsyncDbInterface( | ||
db_credentials=ServiceCredentials( | ||
host="localhost", | ||
port=5432, | ||
username="eos-user", | ||
password="eos-password", | ||
), | ||
db_name="eos", | ||
) | ||
|
||
# Create tables | ||
await db.create_tables() | ||
|
||
async with db.session_provider.get_session() as session: | ||
# Create a pydantic Experiment | ||
pydantic_experiment = Experiment( | ||
id="exp-001", | ||
type="analysis_experiment", | ||
execution_parameters=ExperimentExecutionParameters(resume=False), | ||
status=ExperimentStatus.CREATED, | ||
labs=["lab-001"], | ||
dynamic_parameters={"param1": {"value": "test"}}, | ||
metadata={"created_by": "user123"}, | ||
created_at=datetime.now(timezone.utc), | ||
) | ||
|
||
print("Pydantic Experiment:") | ||
print(pydantic_experiment.model_dump()) | ||
|
||
# Convert pydantic Experiment to ExperimentModel | ||
experiment_model = ExperimentModel( | ||
id=pydantic_experiment.id, | ||
type=pydantic_experiment.type, | ||
execution_parameters=pydantic_experiment.execution_parameters.model_dump(), | ||
status=pydantic_experiment.status, | ||
labs=pydantic_experiment.labs, | ||
running_tasks=pydantic_experiment.running_tasks, | ||
completed_tasks=pydantic_experiment.completed_tasks, | ||
dynamic_parameters=pydantic_experiment.dynamic_parameters, | ||
experiment_metadata=pydantic_experiment.metadata, | ||
start_time=pydantic_experiment.start_time, | ||
end_time=pydantic_experiment.end_time, | ||
created_at=pydantic_experiment.created_at, | ||
) | ||
|
||
# Add experiment to session and flush | ||
session.add(experiment_model) | ||
await session.flush() | ||
|
||
print(f"Experiment {experiment_model.id} has been created and stored in the database.") | ||
|
||
# Create a pydantic Task associated with the experiment | ||
pydantic_task = Task( | ||
id="task-001", | ||
type="analysis", | ||
experiment_id=pydantic_experiment.id, | ||
devices=[TaskDeviceConfig(id="device-001", lab_id="lab-001")], | ||
input=TaskInput(parameters={"param1": "value1"}), | ||
output=TaskOutput(), | ||
status=TaskStatus.CREATED, | ||
metadata={"created_by": "user123"}, | ||
created_at=datetime.now(timezone.utc), | ||
) | ||
|
||
print("\nPydantic Task:") | ||
print(pydantic_task.model_dump()) | ||
|
||
# Convert pydantic Task to TaskModel | ||
task_model = TaskModel( | ||
id=pydantic_task.id, | ||
type=pydantic_task.type, | ||
experiment_id=pydantic_task.experiment_id, | ||
devices=[asdict(device) for device in pydantic_task.devices], | ||
input=pydantic_task.input.model_dump(), | ||
output=pydantic_task.output.model_dump(), | ||
status=pydantic_task.status.value, | ||
task_metadata=pydantic_task.metadata, | ||
start_time=pydantic_task.start_time, | ||
end_time=pydantic_task.end_time, | ||
created_at=pydantic_task.created_at, | ||
) | ||
|
||
# Add task to session and flush | ||
session.add(task_model) | ||
await session.flush() | ||
|
||
print(f"Task {task_model.id} has been created and stored in the database.") | ||
|
||
# Verify that both experiment and task were stored by querying them | ||
stored_experiment = await session.get(ExperimentModel, experiment_model.id) | ||
print(f"\nRetrieved experiment: {stored_experiment.id}, status: {stored_experiment.status}") | ||
|
||
stored_task = await session.get(TaskModel, task_model.id) | ||
print(f"Retrieved task: {stored_task.id}, status: {stored_task.status}") | ||
|
||
# Commit the transaction | ||
await session.commit() | ||
|
||
# Close the database connection | ||
await db.close() | ||
|
||
|
||
if __name__ == "__main__": | ||
asyncio.run(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Example EOS Package | ||
This is a very simple EOS package that implements an experiment for finding the smallest number that when multiplied by | ||
two factors is as close as possible to 1024. | ||
|
||
## Experiments | ||
The package contains the **optimize_multiplication** experiment which works as explained above. | ||
|
||
## Laboratories | ||
The package defines a very basic laboratory containing a "multiplier" and an "analyzer" device. | ||
|
||
## Devices | ||
1. **Multiplier**: Provides a function for multiplying two numbers. | ||
2. **Analyzer**: Provides a function for producing a score on how close we are to the objective of the experiment. | ||
|
||
## Tasks | ||
1. **Multiply**: Multiplies two numbers using the multiplier device. | ||
2. **Score Multiplication**: Scores the multiplication using the analyzer device. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from typing import Any | ||
|
||
from eos.devices.base_device import BaseDevice | ||
|
||
|
||
class AnalyzerDevice(BaseDevice): | ||
"""Analyzes the multiplication result to produce a loss.""" | ||
|
||
async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: | ||
pass | ||
|
||
async def _cleanup(self) -> None: | ||
pass | ||
|
||
async def _report(self) -> dict[str, Any]: | ||
pass | ||
|
||
def analyze_result(self, number: int, product: int) -> int: | ||
return number + 100 * abs(product - 1024) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
type: analyzer | ||
description: A device for analyzing the result of the multiplication of some numbers and computing a loss. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
from typing import Any | ||
|
||
from eos.devices.base_device import BaseDevice | ||
|
||
|
||
class MultiplierDevice(BaseDevice): | ||
"""Multiplies two numbers.""" | ||
|
||
async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: | ||
pass | ||
|
||
async def _cleanup(self) -> None: | ||
pass | ||
|
||
async def _report(self) -> dict[str, Any]: | ||
pass | ||
|
||
def multiply(self, a: int, b: int) -> int: | ||
return a * b |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
type: multiplier | ||
description: A device for multiplying two numbers |
35 changes: 35 additions & 0 deletions
35
user/example/experiments/optimize_multiplication/experiment.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
type: optimize_multiplication | ||
description: An experiment for finding the smallest number that when multiplied by two factors yields 1024 | ||
|
||
labs: | ||
- multiplication_lab | ||
|
||
tasks: | ||
- id: mult_1 | ||
type: Multiplication | ||
devices: | ||
- lab_id: multiplication_lab | ||
id: multiplier | ||
parameters: | ||
number: eos_dynamic | ||
factor: eos_dynamic | ||
|
||
- id: mult_2 | ||
type: Multiplication | ||
devices: | ||
- lab_id: multiplication_lab | ||
id: multiplier | ||
dependencies: [ mult_1 ] | ||
parameters: | ||
number: mult_1.product | ||
factor: eos_dynamic | ||
|
||
- id: score_multiplication | ||
type: Score Multiplication | ||
devices: | ||
- lab_id: multiplication_lab | ||
id: analyzer | ||
dependencies: [ mult_1, mult_2 ] | ||
parameters: | ||
number: mult_1.number | ||
product: mult_2.product |
27 changes: 27 additions & 0 deletions
27
user/example/experiments/optimize_multiplication/optimizer.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
from bofire.data_models.acquisition_functions.acquisition_function import qLogNEI | ||
from bofire.data_models.enum import SamplingMethodEnum | ||
from bofire.data_models.features.continuous import ContinuousOutput | ||
from bofire.data_models.features.discrete import DiscreteInput | ||
from bofire.data_models.objectives.identity import MinimizeObjective | ||
|
||
from eos.optimization.abstract_sequential_optimizer import AbstractSequentialOptimizer | ||
from eos.optimization.sequential_bayesian_optimizer import BayesianSequentialOptimizer | ||
|
||
|
||
def eos_create_campaign_optimizer() -> tuple[dict, type[AbstractSequentialOptimizer]]: | ||
constructor_args = { | ||
"inputs": [ | ||
DiscreteInput(key="mult_1.number", values=list(range(2, 34))), | ||
DiscreteInput(key="mult_1.factor", values=list(range(2, 18))), | ||
DiscreteInput(key="mult_2.factor", values=list(range(2, 18))), | ||
], | ||
"outputs": [ | ||
ContinuousOutput(key="score_multiplication.loss", objective=MinimizeObjective(w=1.0)), | ||
], | ||
"constraints": [], | ||
"acquisition_function": qLogNEI(), | ||
"num_initial_samples": 5, | ||
"initial_sampling_method": SamplingMethodEnum.SOBOL, | ||
} | ||
|
||
return constructor_args, BayesianSequentialOptimizer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
type: multiplication_lab | ||
description: An example laboratory for testing multiplication | ||
|
||
devices: | ||
multiplier: | ||
type: multiplier | ||
computer: eos_computer | ||
analyzer: | ||
type: analyzer | ||
computer: eos_computer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from eos.tasks.base_task import BaseTask | ||
|
||
|
||
class MultiplicationTask(BaseTask): | ||
async def _execute( | ||
self, | ||
devices: BaseTask.DevicesType, | ||
parameters: BaseTask.ParametersType, | ||
containers: BaseTask.ContainersType, | ||
) -> BaseTask.OutputType: | ||
multiplier = devices.get_all_by_type("multiplier")[0] | ||
product = multiplier.multiply(parameters["number"], parameters["factor"]) | ||
output_parameters = {"product": product} | ||
|
||
return output_parameters, None, None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
type: Multiplication | ||
description: This task takes a number and a factor and multiplies them together using a "multiplier" device. | ||
|
||
device_types: | ||
- multiplier | ||
|
||
input_parameters: | ||
number: | ||
type: integer | ||
unit: none | ||
description: The number to multiply. | ||
factor: | ||
type: integer | ||
unit: none | ||
description: The factor to multiply the number by. | ||
|
||
output_parameters: | ||
product: | ||
type: integer | ||
unit: none | ||
description: The product of the number and the factor. |
Oops, something went wrong.