Skip to content

Commit

Permalink
[Refactor] Migrate naming to AXE (#38)
Browse files Browse the repository at this point in the history
* [Refactor] Move entry point and toml to AXE
* [Refactor] Move folder `endure` to `axe`
* [Refactor] Remove docker file
* [Refactor] Change README file
  • Loading branch information
ephoris authored Oct 22, 2024
1 parent ffbfaf7 commit 51abdfc
Show file tree
Hide file tree
Showing 69 changed files with 915 additions and 1,192 deletions.
5 changes: 0 additions & 5 deletions .dockerignore

This file was deleted.

27 changes: 0 additions & 27 deletions Dockerfile

This file was deleted.

22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ These are the general steps that can be used to generate data, train each model
```bash
pip install -r requirements.txt
```
8. **Configure the endure.toml file (More details can be found below)** \
The [endure.toml](#Configuration-File) file contains all required options for the experiments and jobs. Please configure all the jobs and their respective parameters required to successfully run the project.
8. **Configure the axe.toml file (More details can be found below)** \
The [axe.toml](#Configuration-File) file contains all required options for the experiments and jobs. Please configure all the jobs and their respective parameters required to successfully run the project.

9. **Run the project** \
The project is structured such that all experiments can be run by just running the endure.py file. Use the following command to run it:
The project is structured such that all experiments can be run by just running the axe.py file. Use the following command to run it:
```bash
python endure.py
python axe.py
```
## Configuration File
All of our configuration is handled by the endure.toml file placed in the root directory of our project.
All of our configuration is handled by the axe.toml file placed in the root directory of our project.
The config file is divided into sections denoted by a heading within the square brackets (for example *[app]*)
1. To run a specific job, change the variable **run** under the *[app]* header. All the available jobs are already present in the variable and provided as commented out code. Uncomment all jobs that have to be run to run multiple jobs or a single job.

Expand All @@ -76,14 +76,14 @@ The config file is divided into sections denoted by a heading within the square
## Project Structure
Our project is separated into repositories to maintain a consistent structure. Below is a short description for each of the repositories to help any user of this project:

1. **jobs** - This repo contains the main entry point defined in endure.py for each job. There are separate files dedicated to each job that can be identified using the filenames.
1. **jobs** - This repo contains the main entry point defined in axe.py for each job. There are separate files dedicated to each job that can be identified using the filenames.

2. **endure** - This repo contains multiple other repositories divided by use case as defined below:
2. **axe** - This repo contains multiple other repositories divided by use case as defined below:

 a. **endure/lcm** - This repo contains the folders and files responsible for the *Learned Cost Model (LCM)* that helps learn the cost surface for the implemented solution. Within this directory, there is a *model* folder that contains the files for each LCM model structure (Classic, KLSM, QHybrid, Doestoevsky (YZLSM)). The *util* folder contains all utilities used by the models within *lcm*. The *data* folder contains code required for generating and using the input (data) files by the models.
 a. **axe/lcm** - This repo contains the folders and files responsible for the *Learned Cost Model (LCM)* that helps learn the cost surface for the implemented solution. Within this directory, there is a *model* folder that contains the files for each LCM model structure (Classic, KLSM, QHybrid, Doestoevsky (YZLSM)). The *util* folder contains all utilities used by the models within *lcm*. The *data* folder contains code required for generating and using the input (data) files by the models.

 b. **endure/lsm** - This repo contains the analytical solver repository called *solver* that is used as the basis of comparison as well as files associated with the structure of the lsm. It has a *types.py* file that is used throughout our project to define each type used. The project also has cost files that use the equations from the cost model (as stated in the paper) to calculate the cost of each operation for all models. There is a also a data_generator file that is used for generation of data from a given sample space uniformly at random.
 b. **axe/lsm** - This repo contains the analytical solver repository called *solver* that is used as the basis of comparison as well as files associated with the structure of the lsm. It has a *types.py* file that is used throughout our project to define each type used. The project also has cost files that use the equations from the cost model (as stated in the paper) to calculate the cost of each operation for all models. There is a also a data_generator file that is used for generation of data from a given sample space uniformly at random.

 c. **endure/ltune** - This repo contains the folders and files responsible for the *Learned Tuner (LTuner)* that helps predict the best configuration for the LSM Tree as per the solution proposed in the paper. Within this directory, there is a *model* folder that contains the files for each Ltuner model structure (Classic, KLSM, QHybrid, Doestoevsky (YZLSM)). The *util* folder contains all utilities used by the models within *ltune*. The *data* folder contains code required for generating and using the input (data) files by the models.
 c. **axe/ltune** - This repo contains the folders and files responsible for the *Learned Tuner (LTuner)* that helps predict the best configuration for the LSM Tree as per the solution proposed in the paper. Within this directory, there is a *model* folder that contains the files for each Ltuner model structure (Classic, KLSM, QHybrid, Doestoevsky (YZLSM)). The *util* folder contains all utilities used by the models within *ltune*. The *data* folder contains code required for generating and using the input (data) files by the models.

 d. **endure/util** - Contains utility files that are used generally by all modules.
 d. **axe/util** - Contains utility files that are used generally by all modules.
6 changes: 3 additions & 3 deletions endure.py → axe.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from jobs.mlos_exp_runs import ExperimentMLOS


class EndureDriver:
class AxeDriver:
def __init__(self, config: dict[str, Any]) -> None:
self.config = config

Expand Down Expand Up @@ -53,10 +53,10 @@ def run(self):
config_path = sys.argv[1]
else:
file_dir = os.path.dirname(__file__)
config_path = os.path.join(file_dir, "endure.toml")
config_path = os.path.join(file_dir, "axe.toml")

with open(config_path) as fid:
config = toml.load(fid)

driver = EndureDriver(config)
driver = AxeDriver(config)
driver.run()
6 changes: 3 additions & 3 deletions endure.toml → axe.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# =============================================================================
# ENDURE Configuration File
# AXE Configuration File
# Following subsections are available
# APP
# LOGGER - output setting
Expand All @@ -18,7 +18,7 @@
# Logic of app including jobs list to run
# =============================================================================
[app]
name = "ENDURE"
name = "AXE"
run = [
# "DataGen",
# "LCMTrain",
Expand All @@ -33,7 +33,7 @@ run = [
# Generic IO settings for experiments, saving data, etc
# =============================================================================
[log]
name = 'endure-logger'
name = 'axe-logger'
format = "[%(levelname)s][%(asctime)-15s][%(filename)s] %(message)s"
datefmt = '%d-%m-%y:%H:%M:%S'
level = "DEBUG"
Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions endure/data/io.py → axe/data/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class Writer(object):
def __init__(self, config):
self._config = config
self.log = logging.getLogger("endure")
self.log = logging.getLogger("axe")

def export_csv_file(self, df, filename):
"""
Expand Down Expand Up @@ -57,7 +57,7 @@ def __init__(self, config):
"""
self._config = config
self.data_dir = self._config["io"]["data_dir"]
self.log = logging.getLogger("endure")
self.log = logging.getLogger("axe")

@classmethod
def read_config(cls, config_path):
Expand Down
File renamed without changes.
8 changes: 4 additions & 4 deletions endure/lcm/data/dataset.py → axe/lcm/data/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
from torch import Tensor
import torch.utils.data

from endure.lcm.data.input_features import kINPUT_FEATS_DICT, kOUTPUT_FEATS
from endure.lsm.types import LSMBounds, Policy
from endure.lcm.util import one_hot_lcm, one_hot_lcm_classic
from axe.lcm.data.input_features import kINPUT_FEATS_DICT, kOUTPUT_FEATS
from axe.lsm.types import LSMBounds, Policy
from axe.lcm.util import one_hot_lcm, one_hot_lcm_classic


class LCMDataSet(torch.utils.data.IterableDataset):
Expand Down Expand Up @@ -102,4 +102,4 @@ def __iter__(self):
label, input = labels[idx], inputs[idx]
if self.test_mode:
input = self._transform_test_data(inputs[idx])
yield label, input
yield label, input
6 changes: 3 additions & 3 deletions endure/lcm/data/generator.py → axe/lcm/data/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

import numpy as np

from endure.lsm.types import LSMDesign, System, Policy, LSMBounds
from endure.lsm.cost import EndureCost
from endure.lcm.data.input_features import (
from axe.lsm.types import LSMDesign, System, Policy, LSMBounds
from axe.lsm.cost import EndureCost
from axe.lcm.data.input_features import (
kWORKLOAD_HEADER,
kSYSTEM_HEADER,
kCOST_HEADER,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from endure.lsm.types import Policy
from axe.lsm.types import Policy

kSYSTEM_HEADER = [
"entry_p_page",
Expand Down
File renamed without changes.
8 changes: 4 additions & 4 deletions endure/lcm/model/builder.py → axe/lcm/model/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
from torch import nn
import torch

from endure.lcm.data.input_features import kINPUT_FEATS_DICT
from endure.lcm.model import KapModel, QModel, ClassicModel, YZModel
from endure.lsm.types import Policy
from axe.lcm.data.input_features import kINPUT_FEATS_DICT
from axe.lcm.model import KapModel, QModel, ClassicModel, YZModel
from axe.lsm.types import Policy


class LearnedCostModelBuilder:
Expand Down Expand Up @@ -78,4 +78,4 @@ def build_model(self, policy: Policy) -> torch.nn.Module:

model = model_class(**args)

return model
return model
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import torch

from .util import eval_lcm_impl
from endure.lcm.data.generator import LCMDataGenerator
from endure.lsm.cost import EndureCost
from endure.lsm.types import LSMDesign, Policy, System
from axe.lcm.data.generator import LCMDataGenerator
from axe.lsm.cost import EndureCost
from axe.lsm.types import LSMDesign, Policy, System

class LCMEvalUtil:
def __init__(
Expand Down Expand Up @@ -67,4 +67,4 @@ def gen_random_sample(self):
row['cost_acm'] = cost_acm

return row, design, system


2 changes: 1 addition & 1 deletion endure/lcm/util/util.py → axe/lcm/util/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import torch
import torch.nn.functional as F

from endure.lsm.types import LSMDesign, Policy, System
from axe.lsm.types import LSMDesign, Policy, System

def one_hot_lcm(
data: Tensor,
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions endure/lsm/cost.py → axe/lsm/cost.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np
import endure.lsm.lsm_cost as Cost
from endure.lsm.types import Policy, System, LSMDesign
import axe.lsm.lsm_cost as Cost
from axe.lsm.types import Policy, System, LSMDesign


class EndureCost:
Expand Down
4 changes: 2 additions & 2 deletions endure/lsm/data_generator.py → axe/lsm/data_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

import numpy as np

from endure.lsm.types import LSMDesign, System, Policy, LSMBounds, Workload
from endure.lsm.cost import EndureCost
from axe.lsm.types import LSMDesign, System, Policy, LSMBounds, Workload
from axe.lsm.cost import EndureCost


class LSMDataGenerator:
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import Type
from endure.lsm.types import Policy
from axe.lsm.types import Policy
from .classic_solver import ClassicSolver
from .qlsm_solver import QLSMSolver
from .klsm_solver import KLSMSolver
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from typing import Any, Optional, Callable, Tuple, List
from typing import Optional, Callable, Tuple, List

import numpy as np
import scipy.optimize as SciOpt

from endure.lsm.cost import EndureCost
from endure.lsm.types import LSMDesign, Policy, System, LSMBounds
from axe.lsm.cost import EndureCost
from axe.lsm.types import LSMDesign, Policy, System, LSMBounds
from .util import kl_div_con
from .util import get_bounds

Expand All @@ -15,11 +15,7 @@


class ClassicSolver:
def __init__(
self,
bounds: LSMBounds,
policies: Optional[List[Policy]] = None
):
def __init__(self, bounds: LSMBounds, policies: Optional[List[Policy]] = None):
self.bounds = bounds
self.cf = EndureCost(bounds.max_considered_levels)
if policies is None:
Expand Down
22 changes: 8 additions & 14 deletions endure/lsm/solver/klsm_solver.py → axe/lsm/solver/klsm_solver.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from typing import Any, Optional, Callable, Tuple
from typing import Optional, Callable, Tuple

import numpy as np
import scipy.optimize as SciOpt

from endure.lsm.cost import EndureCost
from endure.lsm.types import LSMDesign, Policy, System, LSMBounds
from axe.lsm.cost import EndureCost
from axe.lsm.types import LSMDesign, Policy, System, LSMBounds
from .util import kl_div_con, get_bounds
from .util import H_DEFAULT, T_DEFAULT, LAMBDA_DEFAULT, ETA_DEFAULT, K_DEFAULT

Expand All @@ -29,10 +29,8 @@ def robust_objective(
lamb, eta = x[-2:]
design = LSMDesign(h=h, T=t, K=kaps, policy=Policy.KHybrid)
query_cost = 0
query_cost += z0 * \
kl_div_con((self.cf.Z0(design, system) - eta) / lamb)
query_cost += z1 * \
kl_div_con((self.cf.Z1(design, system) - eta) / lamb)
query_cost += z0 * kl_div_con((self.cf.Z0(design, system) - eta) / lamb)
query_cost += z1 * kl_div_con((self.cf.Z1(design, system) - eta) / lamb)
query_cost += q * kl_div_con((self.cf.Q(design, system) - eta) / lamb)
query_cost += w * kl_div_con((self.cf.W(design, system) - eta) / lamb)
cost = eta + (rho * lamb) + (lamb * query_cost)
Expand Down Expand Up @@ -69,7 +67,7 @@ def get_robust_design(
minimizer_kwargs: dict = {},
callback_fn: Optional[Callable] = None,
) -> Tuple[LSMDesign, SciOpt.OptimizeResult]:
raise NotImplemented
raise NotImplementedError

def get_nominal_design(
self,
Expand Down Expand Up @@ -97,8 +95,7 @@ def get_nominal_design(
default_kwargs.update(minimizer_kwargs)
kap_val = init_args[-1]
init_args = np.concatenate(
(init_args[0:2],
np.array([kap_val for _ in range(max_levels)]))
(init_args[0:2], np.array([kap_val for _ in range(max_levels)]))
)

solution = SciOpt.minimize(
Expand All @@ -108,10 +105,7 @@ def get_nominal_design(
**default_kwargs
)
design = LSMDesign(
h=solution.x[0],
T=solution.x[1],
K=solution.x[2:],
policy=Policy.KHybrid
h=solution.x[0], T=solution.x[1], K=solution.x[2:], policy=Policy.KHybrid
)

return design, solution
18 changes: 8 additions & 10 deletions endure/lsm/solver/qlsm_solver.py → axe/lsm/solver/qlsm_solver.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
from typing import Any, Optional, Callable, Tuple
from typing import Optional, Callable, Tuple

import numpy as np
import scipy.optimize as SciOpt

from endure.lsm.cost import EndureCost
from endure.lsm.types import LSMDesign, Policy, System, LSMBounds
from axe.lsm.cost import EndureCost
from axe.lsm.types import LSMDesign, Policy, System, LSMBounds
from .util import kl_div_con, get_bounds
from .util import H_DEFAULT, T_DEFAULT, LAMBDA_DEFAULT, ETA_DEFAULT, Q_DEFAULT


class QLSMSolver:
def __init__(self, bounds:LSMBounds):
def __init__(self, bounds: LSMBounds):
self.bounds = bounds
self.cf = EndureCost(bounds.max_considered_levels)

Expand Down Expand Up @@ -63,7 +64,7 @@ def get_robust_design(
minimizer_kwargs: dict = {},
callback_fn: Optional[Callable] = None,
) -> Tuple[LSMDesign, SciOpt.OptimizeResult]:
raise NotImplemented
raise NotImplementedError

def get_nominal_design(
self,
Expand Down Expand Up @@ -95,10 +96,7 @@ def get_nominal_design(
**default_kwargs
)
design = LSMDesign(
h=solution.x[0],
T=solution.x[1],
Q=solution.x[2],
policy=Policy.QFixed)
h=solution.x[0], T=solution.x[1], Q=solution.x[2], policy=Policy.QFixed
)

return design, solution

Loading

0 comments on commit 51abdfc

Please sign in to comment.