├── simulation
├── __init__.py
├── gym
│ ├── __init__.py
│ ├── sample_envs.py
│ ├── E.py
│ └── environment.py
├── plugins
│ ├── __init__.py
│ ├── cost_plugin.py
│ ├── interface.py
│ ├── visualization_template.html
│ ├── chart_plugin.py
│ └── wandb_plugin.py
├── dispatching
│ ├── __init__.py
│ ├── dm_lot_for_machine.py
│ ├── dispatcher.py
│ └── dm_machine_for_lot.py
├── randomizer.py
├── dataset_preprocess.py
├── tools.py
├── read.py
├── event_queue.py
├── events.py
├── generator_instance.py
├── stats.py
├── file_instance.py
├── greedy.py
├── classes.py
└── instance.py
├── .gitignore
├── docs
├── favicon.ico
└── assets
│ ├── img
│ ├── logo_xs.png
│ ├── bg
│ │ ├── bg-home.jpg
│ │ ├── bg-action.jpg
│ │ ├── bg-client.jpg
│ │ ├── bg-quote.jpg
│ │ ├── bg-milestone.jpg
│ │ └── bg-corporate.svg
│ ├── logo_small.png
│ ├── user
│ │ ├── user-1.jpg
│ │ ├── user-2.jpg
│ │ └── user-3.jpg
│ ├── carousel
│ │ ├── carousel-1.jpg
│ │ ├── carousel-2.jpg
│ │ └── carousel-3.jpg
│ └── portfolio
│ │ ├── asmc_paper.png
│ │ ├── wsc_paper.png
│ │ ├── es_preprint.png
│ │ ├── asmc_2023_poster.pdf
│ │ ├── asmc_2023_poster.png
│ │ ├── asmc_presentation.pdf
│ │ ├── asmc_presentation.png
│ │ ├── wsc_presentation.pdf
│ │ └── wsc_presentation.png
│ └── css
│ ├── webfonts
│ ├── fa-brands-400.ttf
│ ├── fa-solid-900.ttf
│ ├── fa-brands-400.woff2
│ ├── fa-regular-400.ttf
│ ├── fa-regular-400.woff2
│ ├── fa-solid-900.woff2
│ ├── fa-v4compatibility.ttf
│ └── fa-v4compatibility.woff2
│ └── one-page-parallax
│ ├── fonts
│ ├── bootstrap-icons.woff
│ └── bootstrap-icons.woff2
│ └── images
│ └── bg-content-cover.png
├── datasets
├── SMT2020_HVLM
│ ├── fromto.txt
│ ├── part.txt
│ ├── setupgrp.txt
│ ├── setup.txt
│ ├── order.txt
│ ├── downcal.txt
│ ├── attach.txt
│ └── tool.txt.1l
└── SMT2020_LVHM
│ ├── fromto.txt
│ ├── setupgrp.txt
│ ├── setup.txt
│ ├── part.txt
│ ├── downcal.txt
│ ├── order.txt
│ ├── attach.txt
│ └── tool.txt.1l
├── reproduce_dispatcher_experiments.sh
├── gui.html
├── env_test.py
├── main.py
├── README.md
├── test_rl_agents.py
├── greedy_runner.py
├── requirements.txt
├── exp_set_gen.py
├── rl_train.py
├── rl_test.py
└── eval_results.py
/simulation/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | venv/
--------------------------------------------------------------------------------
/simulation/gym/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/simulation/plugins/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/simulation/dispatching/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/favicon.ico
--------------------------------------------------------------------------------
/datasets/SMT2020_HVLM/fromto.txt:
--------------------------------------------------------------------------------
1 | FROMLOC TOLOC DDIST DTIME DTIME2 DUNITS
2 | Fab Fab uniform 7.5 2.5 min
3 |
--------------------------------------------------------------------------------
/datasets/SMT2020_LVHM/fromto.txt:
--------------------------------------------------------------------------------
1 | FROMLOC TOLOC DDIST DTIME DTIME2 DUNITS
2 | Fab Fab uniform 7.5 2.5 min
3 |
--------------------------------------------------------------------------------
/docs/assets/img/logo_xs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/logo_xs.png
--------------------------------------------------------------------------------
/docs/assets/img/bg/bg-home.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/bg/bg-home.jpg
--------------------------------------------------------------------------------
/docs/assets/img/logo_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/logo_small.png
--------------------------------------------------------------------------------
/docs/assets/img/bg/bg-action.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/bg/bg-action.jpg
--------------------------------------------------------------------------------
/docs/assets/img/bg/bg-client.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/bg/bg-client.jpg
--------------------------------------------------------------------------------
/docs/assets/img/bg/bg-quote.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/bg/bg-quote.jpg
--------------------------------------------------------------------------------
/docs/assets/img/user/user-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/user/user-1.jpg
--------------------------------------------------------------------------------
/docs/assets/img/user/user-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/user/user-2.jpg
--------------------------------------------------------------------------------
/docs/assets/img/user/user-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/user/user-3.jpg
--------------------------------------------------------------------------------
/reproduce_dispatcher_experiments.sh:
--------------------------------------------------------------------------------
1 | mkdir greedy
2 | python3 greedy_runner.py
3 | python3 eval_results.py > greedy/_greedy_sum.txt
--------------------------------------------------------------------------------
/docs/assets/img/bg/bg-milestone.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/bg/bg-milestone.jpg
--------------------------------------------------------------------------------
/docs/assets/img/carousel/carousel-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/carousel/carousel-1.jpg
--------------------------------------------------------------------------------
/docs/assets/img/carousel/carousel-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/carousel/carousel-2.jpg
--------------------------------------------------------------------------------
/docs/assets/img/carousel/carousel-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/carousel/carousel-3.jpg
--------------------------------------------------------------------------------
/docs/assets/img/portfolio/asmc_paper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/portfolio/asmc_paper.png
--------------------------------------------------------------------------------
/docs/assets/img/portfolio/wsc_paper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/portfolio/wsc_paper.png
--------------------------------------------------------------------------------
/docs/assets/css/webfonts/fa-brands-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/css/webfonts/fa-brands-400.ttf
--------------------------------------------------------------------------------
/docs/assets/css/webfonts/fa-solid-900.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/css/webfonts/fa-solid-900.ttf
--------------------------------------------------------------------------------
/docs/assets/img/portfolio/es_preprint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/portfolio/es_preprint.png
--------------------------------------------------------------------------------
/docs/assets/css/webfonts/fa-brands-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/css/webfonts/fa-brands-400.woff2
--------------------------------------------------------------------------------
/docs/assets/css/webfonts/fa-regular-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/css/webfonts/fa-regular-400.ttf
--------------------------------------------------------------------------------
/docs/assets/css/webfonts/fa-regular-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/css/webfonts/fa-regular-400.woff2
--------------------------------------------------------------------------------
/docs/assets/css/webfonts/fa-solid-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/css/webfonts/fa-solid-900.woff2
--------------------------------------------------------------------------------
/datasets/SMT2020_HVLM/part.txt:
--------------------------------------------------------------------------------
1 | PARTGRP PARTFAM PART ROUTEFILE ROUTE
2 | Saleable product_3 part_3 route_3.txt r_3
3 | Saleable product_4 part_4 route_4.txt r_4
4 |
--------------------------------------------------------------------------------
/docs/assets/css/webfonts/fa-v4compatibility.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/css/webfonts/fa-v4compatibility.ttf
--------------------------------------------------------------------------------
/docs/assets/img/portfolio/asmc_2023_poster.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/portfolio/asmc_2023_poster.pdf
--------------------------------------------------------------------------------
/docs/assets/img/portfolio/asmc_2023_poster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/portfolio/asmc_2023_poster.png
--------------------------------------------------------------------------------
/docs/assets/img/portfolio/asmc_presentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/portfolio/asmc_presentation.pdf
--------------------------------------------------------------------------------
/docs/assets/img/portfolio/asmc_presentation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/portfolio/asmc_presentation.png
--------------------------------------------------------------------------------
/docs/assets/img/portfolio/wsc_presentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/portfolio/wsc_presentation.pdf
--------------------------------------------------------------------------------
/docs/assets/img/portfolio/wsc_presentation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/img/portfolio/wsc_presentation.png
--------------------------------------------------------------------------------
/docs/assets/css/webfonts/fa-v4compatibility.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/css/webfonts/fa-v4compatibility.woff2
--------------------------------------------------------------------------------
/docs/assets/css/one-page-parallax/fonts/bootstrap-icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/css/one-page-parallax/fonts/bootstrap-icons.woff
--------------------------------------------------------------------------------
/docs/assets/css/one-page-parallax/fonts/bootstrap-icons.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/css/one-page-parallax/fonts/bootstrap-icons.woff2
--------------------------------------------------------------------------------
/docs/assets/css/one-page-parallax/images/bg-content-cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/prosysscience/PySCFabSim-release/HEAD/docs/assets/css/one-page-parallax/images/bg-content-cover.png
--------------------------------------------------------------------------------
/datasets/SMT2020_HVLM/setupgrp.txt:
--------------------------------------------------------------------------------
1 | SETUPGRP SETUP MINRUN IGNORE
2 | Implant_Gas SU128_1 7 Implant_128
3 | SU128_2 7 Implant_128
4 | SU128_3 7 Implant_128
5 | SU132_1 7 Implant_132
6 | SU132_2 7 Implant_132
7 | SU132_3 7 Implant_132
8 | SU91_1 7 Implant_91
9 | SU91_2 7 Implant_91
10 | SU91_3 7 Implant_91
11 |
--------------------------------------------------------------------------------
/datasets/SMT2020_LVHM/setupgrp.txt:
--------------------------------------------------------------------------------
1 | SETUPGRP SETUP MINRUN IGNORE
2 | Implant_Gas SU128_1 7 Implant_128
3 | SU128_2 7 Implant_128
4 | SU128_3 7 Implant_128
5 | SU132_1 7 Implant_132
6 | SU132_2 7 Implant_132
7 | SU132_3 7 Implant_132
8 | SU91_1 7 Implant_91
9 | SU91_2 7 Implant_91
10 | SU91_3 7 Implant_91
11 |
--------------------------------------------------------------------------------
/gui.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Simulator gui
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/env_test.py:
--------------------------------------------------------------------------------
1 | import gym
2 | import simulation.gym
3 | from simulation.gym.environment import DynamicSCFabSimulationEnvironment
4 |
5 | env = gym.make('DynamicSCFabSimulation-10days-v0')
6 | state, done = env.reset(), False
7 | ret = 0
8 | steps = 0
9 | while not done:
10 | action = env.action_space.sample()
11 | state, reward, done, info = env.step(action)
12 | ret += reward
13 | steps += 1
14 |
15 | print(f"Return {ret} steps {steps}")
16 |
17 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | from simulation.greedy import run_greedy
2 | import sys
3 |
4 | sys.path.insert(0, '.')
5 |
6 |
7 | def main():
8 | profile = False
9 | if profile:
10 | from pyinstrument import Profiler
11 |
12 | p = Profiler()
13 | p.start()
14 |
15 | run_greedy()
16 | print()
17 | print()
18 |
19 | if profile:
20 | p.stop()
21 | p.open_in_browser()
22 |
23 |
24 | if __name__ == '__main__':
25 | main()
26 |
--------------------------------------------------------------------------------
/datasets/SMT2020_HVLM/setup.txt:
--------------------------------------------------------------------------------
1 | CURSETUP NEWSETUP STIME STUNITS IGNORE
2 | DE_BE_13_1 DE_BE_13_2 7 min DE_BE_13
3 | DE_BE_13_2 DE_BE_13_1 12 min DE_BE_13
4 | DE_BE_66_1 DE_BE_66_2 15 min DE_BE_66
5 | DE_BE_66_2 DE_BE_66_1 10 min DE_BE_66
6 | SU128_1 72 min Implant_128
7 | SU128_2 72 min Implant_128
8 | SU128_3 72 min Implant_128
9 | SU132_1 60 min Implant_132
10 | SU132_2 60 min Implant_132
11 | SU132_3 60 min Implant_132
12 | SU91_1 80 min Implant_91
13 | SU91_2 80 min Implant_91
14 | SU91_3 80 min Implant_91
15 |
--------------------------------------------------------------------------------
/datasets/SMT2020_LVHM/setup.txt:
--------------------------------------------------------------------------------
1 | CURSETUP NEWSETUP STIME STUNITS IGNORE
2 | DE_BE_13_1 DE_BE_13_2 7 min DE_BE_13
3 | DE_BE_13_2 DE_BE_13_1 12 min DE_BE_13
4 | DE_BE_66_1 DE_BE_66_2 15 min DE_BE_66
5 | DE_BE_66_2 DE_BE_66_1 10 min DE_BE_66
6 | SU128_1 72 min Implant_128
7 | SU128_2 72 min Implant_128
8 | SU128_3 72 min Implant_128
9 | SU132_1 60 min Implant_132
10 | SU132_2 60 min Implant_132
11 | SU132_3 60 min Implant_132
12 | SU91_1 80 min Implant_91
13 | SU91_2 80 min Implant_91
14 | SU91_3 80 min Implant_91
15 |
--------------------------------------------------------------------------------
/datasets/SMT2020_LVHM/part.txt:
--------------------------------------------------------------------------------
1 | PARTGRP PARTFAM PART ROUTEFILE ROUTE
2 | Saleable product_1 part_1 route_1.txt r_1
3 | Saleable product_2 part_2 route_2.txt r_2
4 | Saleable product_3 part_3 route_3.txt r_3
5 | Saleable product_4 part_4 route_4.txt r_4
6 | Saleable product_5 part_5 route_5.txt r_5
7 | Saleable product_6 part_6 route_6.txt r_6
8 | Saleable product_7 part_7 route_7.txt r_7
9 | Saleable product_8 part_8 route_8.txt r_8
10 | Saleable product_9 part_9 route_9.txt r_9
11 | Saleable product_10 part_10 route_10.txt r_10
12 |
--------------------------------------------------------------------------------
/simulation/randomizer.py:
--------------------------------------------------------------------------------
1 | import os
2 | from random import Random
3 |
4 |
5 | class Singleton(type):
6 | _instances = {}
7 |
8 | def __call__(cls, *args, **kwargs):
9 | if cls not in cls._instances:
10 | cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
11 | return cls._instances[cls]
12 |
13 |
14 | class Randomizer(metaclass=Singleton):
15 | def __init__(self):
16 | random_seed = int(os.environ['SEED']) if 'SEED' in os.environ else None
17 | self.random = Random(random_seed)
18 |
--------------------------------------------------------------------------------
/datasets/SMT2020_HVLM/order.txt:
--------------------------------------------------------------------------------
1 | LOT PART PRIOR PIECES START RDIST REPEAT RUNITS RPT# LOTSPERRPT DUE ORDER HOTLOT
2 | Lot_3 part_3 10 25 01/01/18 00:00:00 constant 51.69 min 200000 1 02/23/18 20:07:47 O_Lot_3 no
3 | Lot_4 part_4 10 25 01/01/18 00:00:00 constant 51.69 min 200000 1 01/31/18 07:29:20 O_Lot_4 no
4 | HotLot_3 part_3 20 25 01/01/18 00:00:00 constant 2016 min 20000 1 02/03/18 07:59:15 O_HotLot_3 no
5 | HotLot_4 part_4 20 25 01/01/18 00:00:00 constant 2016 min 20000 1 01/20/18 13:17:36 O_HotLot_4 no
6 | SuperHotLot_3 part_3 30 25 01/01/18 00:00:00 constant 27397.61 min 2000 1 02/03/18 05:13:01 O_SuperHotLot_3 no
7 |
--------------------------------------------------------------------------------
/simulation/gym/sample_envs.py:
--------------------------------------------------------------------------------
1 | from simulation.gym.E import E
2 |
3 | DEMO_ENV_1 = {
4 | 'action': E.A.CHOOSE_LOT_FOR_FREE_MACHINE,
5 | 'state_components': (
6 | E.A.L4M.S.MACHINE.SETUP_PROCESSING_RATIO,
7 | E.A.L4M.S.MACHINE.IDLE_RATIO,
8 | E.A.L4M.S.MACHINE.MAINTENANCE.NEXT,
9 | E.A.L4M.S.OPERATION_TYPE.NO_LOTS_PER_BATCH,
10 | E.A.L4M.S.OPERATION_TYPE.CR.MAX,
11 | E.A.L4M.S.OPERATION_TYPE.FREE_SINCE.MAX,
12 | E.A.L4M.S.OPERATION_TYPE.SETUP.MIN_RUNS_OK,
13 | E.A.L4M.S.OPERATION_TYPE.SETUP.NEEDED,
14 | E.A.L4M.S.OPERATION_TYPE.SETUP.LAST_SETUP_TIME,
15 | )
16 | }
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Reproduction of experiments
2 |
3 | ## Install requirements (suggested to run in a new virtual environment)
4 |
5 | ```shell
6 | pip install -r requirements.txt
7 | ```
8 |
9 |
10 | ## Test FIFO and CR dispatching startegies
11 |
12 | ```shell
13 | ./reproduce_dispatcher_experiments.sh
14 | ```
15 |
16 | ## Dataset
17 |
18 | Our simulator uses the SMT2020 dataset. It is available on https://p2schedgen.fernuni-hagen.de/index.php/downloads/simulation
19 |
20 | Kopp, Denny & Hassoun, Michael & Kalir, Adar & Mönch, Lars. (2020). SMT2020—A Semiconductor Manufacturing Testbed. IEEE Transactions on Semiconductor Manufacturing. PP. 1-1. 10.1109/TSM.2020.3001933.
--------------------------------------------------------------------------------
/simulation/plugins/cost_plugin.py:
--------------------------------------------------------------------------------
1 | from simulation.plugins.interface import IPlugin
2 |
3 |
4 | class CostPlugin(IPlugin):
5 |
6 | def on_sim_done(self, instance):
7 | super().on_sim_done(instance)
8 | self.cost = 0
9 | for lot in instance.done_lots:
10 | self.cost += 25 if lot.deadline_at < lot.done_at else 0
11 | self.cost += max(0, lot.done_at - lot.deadline_at) / 3600 / 24
12 | self.cost += len(instance.active_lots) * 200
13 | self.done_lots = len(instance.done_lots)
14 |
15 | def get_output_name(self):
16 | super().get_output_name()
17 | return 'cost'
18 |
19 | def get_output_value(self):
20 | return self.cost
21 |
--------------------------------------------------------------------------------
/test_rl_agents.py:
--------------------------------------------------------------------------------
1 | import io
2 | import os
3 | import subprocess
4 | import time
5 | from os import listdir, path, mkdir
6 |
7 | root = 'experiments'
8 |
9 | dirs = listdir(root)
10 | while True:
11 | for d in sorted(dirs):
12 | for checkpoint in [50000, 100000, 150000, 200000, 300000, 400000, 500000, 600000, 800000, 1000000, 1200000, 1400000, 1600000, 1800000, 2000000]:
13 | report_loc = path.join(root, d, f'report_{checkpoint}.txt')
14 | weights_loc = f'checkpoint__{checkpoint}_steps.zip'
15 | if path.exists(path.join(root, d, weights_loc)) and not path.exists(report_loc):
16 | print(d)
17 | with io.open(report_loc, 'w') as f:
18 | subprocess.call(['python3', 'rl_test.py', path.join(root, d), weights_loc],
19 | stdout=f)
20 |
21 |
22 | print('No more experiments to run.')
23 | time.sleep(10)
24 |
25 |
--------------------------------------------------------------------------------
/datasets/SMT2020_HVLM/downcal.txt:
--------------------------------------------------------------------------------
1 | DOWNCALNAME DOWNCALTYPE MTTFDIST MTTF MTTFUNITS MTTRDIST MTTR MTTRUNITS IGNORE
2 | BREAK_Def_Met mttf_by_cal exponential 10080 min exponential 35.28 min Def_Met
3 | BREAK_Dielectric mttf_by_cal exponential 10080 min exponential 604.8 min Dielectric
4 | BREAK_Diffusion mttf_by_cal exponential 10080 min exponential 151.2 min Diffusion
5 | BREAK_Dry_Etch mttf_by_cal exponential 10080 min exponential 231.84 min Dry_Etch
6 | BREAK_Implant mttf_by_cal exponential 10080 min exponential 604.8 min Implant
7 | BREAK_Litho mttf_by_cal exponential 10080 min exponential 705.59 min Litho
8 | BREAK_Litho_Met mttf_by_cal exponential 10080 min exponential 35.28 min Litho_Met
9 | BREAK_Planar mttf_by_cal exponential 10080 min exponential 201.6 min Planar
10 | BREAK_TF mttf_by_cal exponential 10080 min exponential 453.6 min TF
11 | BREAK_TF_Met mttf_by_cal exponential 10080 min exponential 35.28 min TF_Met
12 | BREAK_Wet_Etch mttf_by_cal exponential 10080 min exponential 221.76 min Wet_Etch
13 |
--------------------------------------------------------------------------------
/datasets/SMT2020_LVHM/downcal.txt:
--------------------------------------------------------------------------------
1 | DOWNCALNAME DOWNCALTYPE MTTFDIST MTTF MTTFUNITS MTTRDIST MTTR MTTRUNITS IGNORE
2 | BREAK_Def_Met mttf_by_cal exponential 10080 min exponential 35.28 min Def_Met
3 | BREAK_Dielectric mttf_by_cal exponential 10080 min exponential 604.8 min Dielectric
4 | BREAK_Diffusion mttf_by_cal exponential 10080 min exponential 151.2 min Diffusion
5 | BREAK_Dry_Etch mttf_by_cal exponential 10080 min exponential 231.84 min Dry_Etch
6 | BREAK_Implant mttf_by_cal exponential 10080 min exponential 604.8 min Implant
7 | BREAK_Litho mttf_by_cal exponential 10080 min exponential 705.59 min Litho
8 | BREAK_Litho_Met mttf_by_cal exponential 10080 min exponential 35.28 min Litho_Met
9 | BREAK_Planar mttf_by_cal exponential 10080 min exponential 201.6 min Planar
10 | BREAK_TF mttf_by_cal exponential 10080 min exponential 453.6 min TF
11 | BREAK_TF_Met mttf_by_cal exponential 10080 min exponential 35.28 min TF_Met
12 | BREAK_Wet_Etch mttf_by_cal exponential 10080 min exponential 221.76 min Wet_Etch
13 |
--------------------------------------------------------------------------------
/greedy_runner.py:
--------------------------------------------------------------------------------
1 | import io
2 | import os
3 | import subprocess
4 | import threading
5 | import time
6 |
7 | threads = []
8 |
9 | if not os.path.exists('greedy'):
10 | os.mkdir('greedy')
11 |
12 | for seed in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]:
13 | for day in [365*2]:
14 | for dataset, dispatcher in [('HVLM', 'fifo'), ('LVHM', 'cr')]:
15 | def s(day_, dataset_, dispatcher_):
16 | name_ = f'greedy/greedy_seed{seed}_{day}days_{dataset}_{dispatcher}.txt'
17 | with io.open(name_, 'w') as f:
18 | print(name_)
19 | subprocess.call(['pypy3', 'main.py', '--days', str(day_),
20 | '--dataset', dataset_, '--dispatcher', dispatcher_, '--seed', str(seed),
21 | '--alg', 'l4m'], stdout=f)
22 |
23 |
24 | t = threading.Thread(target=s, args=(day, dataset, dispatcher))
25 | t.start()
26 | time.sleep(2)
27 | threads.append(t)
28 |
29 | for t in threads:
30 | t.join()
31 |
32 | print('Done')
33 |
--------------------------------------------------------------------------------
/simulation/plugins/interface.py:
--------------------------------------------------------------------------------
1 | from abc import abstractmethod, ABCMeta
2 |
3 |
4 | class IPlugin(metaclass=ABCMeta):
5 | def on_sim_init(self, instance):
6 | pass
7 |
8 | def on_sim_done(self, instance):
9 | pass
10 |
11 | def on_lots_release(self, instance, lots):
12 | pass
13 |
14 | def on_lot_done(self, instance, lot):
15 | pass
16 |
17 | def on_step_done(self, instance, lot, step):
18 | pass
19 |
20 | def on_dispatch(self, instance, machine, lots, machine_end_time, lot_end_time):
21 | pass
22 |
23 | def on_machine_free(self, instance, machine):
24 | pass
25 |
26 | def on_lot_free(self, instance, lot):
27 | pass
28 |
29 | def on_breakdown(self, machine, breakdown_event):
30 | pass
31 |
32 | def on_preventive_maintenance(self, machine, preventive_maintenance_event):
33 | pass
34 |
35 | def get_output_name(self):
36 | return None
37 |
38 | def get_output_value(self):
39 | raise NotImplementedError()
40 |
41 | def on_cqt_violated(self, instance, machine, lot):
42 | pass
43 |
--------------------------------------------------------------------------------
/simulation/dataset_preprocess.py:
--------------------------------------------------------------------------------
1 | class RemoveBreakdowns:
2 |
3 | def preprocess(self, files):
4 | files['attach.txt'] = [r for r in files['attach.txt'] if r['CALTYPE'] != 'down']
5 | files['downcal.txt'] = []
6 | return files
7 |
8 |
9 | class RemovePreventiveMaintenance:
10 |
11 | def preprocess(self, files):
12 | files['attach.txt'] = [r for r in files['attach.txt'] if r['CALTYPE'] != 'pm']
13 | files['pmcal.txt'] = []
14 | return files
15 |
16 |
17 | class RemoveWIP:
18 |
19 | def preprocess(self, files):
20 | files['WIP.txt'] = []
21 | return files
22 |
23 |
24 | class RemoveRework:
25 |
26 | def preprocess(self, files):
27 | for name, val in files.items():
28 | if 'route' in name:
29 | for v in val:
30 | v['REWORK'] = None
31 | return files
32 |
33 |
34 | class RemoveSampling:
35 |
36 | def preprocess(self, files):
37 | for name, val in files.items():
38 | if 'route' in name:
39 | for v in val:
40 | v['StepPercent'] = None
41 | return files
42 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | absl-py==1.0.0
2 | atari-py==0.2.9
3 | cachetools==4.2.4
4 | certifi==2021.10.8
5 | charset-normalizer==2.0.9
6 | click==8.0.3
7 | cloudpickle==1.6.0
8 | configparser==5.2.0
9 | cycler==0.11.0
10 | docker-pycreds==0.4.0
11 | fonttools==4.28.4
12 | gitdb==4.0.9
13 | GitPython==3.1.24
14 | google-auth==2.3.3
15 | google-auth-oauthlib==0.4.6
16 | grpcio==1.43.0
17 | gym==0.19.0
18 | idna==3.3
19 | importlib-metadata==4.9.0
20 | kiwisolver==1.3.2
21 | Markdown==3.3.6
22 | matplotlib==3.5.1
23 | numpy==1.21.4
24 | oauthlib==3.1.1
25 | opencv-python==4.5.4.60
26 | packaging==21.3
27 | pandas==1.3.5
28 | pathtools==0.1.2
29 | Pillow==8.4.0
30 | promise==2.3
31 | protobuf==3.19.1
32 | psutil==5.8.0
33 | pyasn1==0.4.8
34 | pyasn1-modules==0.2.8
35 | pyparsing==3.0.6
36 | python-dateutil==2.8.2
37 | pytz==2021.3
38 | PyYAML==6.0
39 | requests==2.26.0
40 | requests-oauthlib==1.3.0
41 | rsa==4.8
42 | sentry-sdk==1.5.1
43 | shortuuid==1.0.8
44 | six==1.16.0
45 | smmap==5.0.0
46 | stable-baselines3==1.3.0
47 | subprocess32==3.5.4
48 | tensorboard==2.7.0
49 | tensorboard-data-server==0.6.1
50 | tensorboard-plugin-wit==1.8.0
51 | termcolor==1.1.0
52 | torch==1.10.1
53 | typing-extensions==4.0.1
54 | urllib3==1.26.7
55 | wandb==0.12.9
56 | Werkzeug==2.0.2
57 | yaspin==2.1.0
58 | zipp==3.6.0
59 |
60 | pyinstrument~=4.1.1
--------------------------------------------------------------------------------
/simulation/plugins/visualization_template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Chart
4 |
5 |
6 |
7 |
8 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/exp_set_gen.py:
--------------------------------------------------------------------------------
1 | import io
2 | import json
3 | import os.path
4 | from os import mkdir, path
5 |
6 | root = 'experiments'
7 | if not os.path.exists(root):
8 | mkdir(root)
9 |
10 | stngrps = [
11 | '',
12 | ]
13 |
14 | for seed in [0]:
15 | for dataset, dispatcher in [('HVLM', 'fifo')]:
16 | for action_count in [9]:
17 | for training_period in [365 * 2]:
18 | for reward in [2]:
19 | for stngrp in stngrps:
20 | case_name = f'{seed}_ds_{dataset}_a{action_count}_tp{training_period}_reward{reward}_di_{dispatcher}_{str(stngrp)[:2]}'
21 | d = path.join(root, case_name)
22 | mkdir(d)
23 | with io.open(path.join(d, 'config.json'), 'w') as f:
24 | case = {
25 | 'name': case_name,
26 | 'params': {
27 | 'seed': seed,
28 | 'dataset': dataset,
29 | 'action_count': action_count,
30 | 'training_period': training_period,
31 | 'dispatcher': dispatcher,
32 | 'reward': reward,
33 | 'station_group': stngrp,
34 | }
35 | }
36 | json.dump(case, f, indent=2)
37 |
--------------------------------------------------------------------------------
/simulation/tools.py:
--------------------------------------------------------------------------------
1 | import datetime
2 |
3 | from simulation.randomizer import Randomizer
4 |
5 | r = Randomizer()
6 |
7 |
8 | def get_interval(num, unit):
9 | units = {'sec': 1, 's': 1, 'min': 60, 'hr': 3600, 'day': 86400, 'pieces': 1, '': 1}
10 | if num is None:
11 | return None
12 | if unit in units:
13 | return num * units[unit]
14 | else:
15 | raise ValueError(f'Unit {unit} not known.')
16 |
17 |
18 | class UniformDistribution:
19 |
20 | def __init__(self, m, l):
21 | self.m, self.l = m, l
22 |
23 | def sample(self):
24 | return r.random.uniform(self.m - self.l / 2, self.m + self.l / 2)
25 |
26 | def avg(self):
27 | return self.m
28 |
29 |
30 | class ConstantDistribution:
31 |
32 | def __init__(self, c):
33 | self.c = c
34 |
35 | def sample(self):
36 | return self.c
37 |
38 | def avg(self):
39 | return self.c
40 |
41 |
42 | class ExponentialDistribution:
43 |
44 | def __init__(self, p):
45 | self.p = p
46 |
47 | def sample(self):
48 | return r.random.expovariate(1 / self.p)
49 |
50 |
51 | def get_distribution(typ, unit, *args, multiplier=1):
52 | arr = [multiplier * get_interval(a, unit) for a in args if a is not None]
53 | if typ == 'uniform':
54 | return UniformDistribution(*arr)
55 | if typ == 'constant':
56 | return ConstantDistribution(*arr)
57 | if typ == 'exponential':
58 | return ExponentialDistribution(*arr)
59 |
60 |
61 | def date_time_parse(st):
62 | return datetime.datetime.strptime(st, '%m/%d/%y %H:%M:%S')
63 |
--------------------------------------------------------------------------------
/simulation/dispatching/dm_lot_for_machine.py:
--------------------------------------------------------------------------------
1 |
2 | class LotForMachineDispatchManager:
3 |
4 | @staticmethod
5 | def init(self):
6 | self.free_machines = [False for _ in self.machines]
7 | self.usable_machines = set()
8 |
9 | @staticmethod
10 | def free_up_lots(self, lot):
11 | for machine in self.family_machines[lot.actual_step.family]:
12 | di = lot.actual_step.order
13 | if di not in lot.dedications or machine.idx == lot.dedications[di]:
14 | machine.waiting_lots.append(lot)
15 | lot.waiting_machines.append(machine)
16 | if self.free_machines[machine.idx]:
17 | self.usable_machines.add(machine)
18 |
19 | @staticmethod
20 | def free_up_machine(self, machine):
21 | assert not self.free_machines[machine.idx]
22 | self.free_machines[machine.idx] = True
23 | if len(machine.waiting_lots) > 0:
24 | self.usable_machines.add(machine)
25 |
26 | @staticmethod
27 | def reserve(self, lots, machine):
28 | self.free_machines[machine.idx] = False
29 | self.usable_machines.remove(machine)
30 | for lot in lots:
31 | for mx in lot.waiting_machines:
32 | mx.waiting_lots.remove(lot)
33 | if len(mx.waiting_lots) == 0 and mx in self.usable_machines:
34 | self.usable_machines.remove(mx)
35 | lot.waiting_machines.clear()
36 |
37 | @staticmethod
38 | def next_decision_point(self):
39 | while len(self.usable_machines) == 0 and not self.done:
40 | self.next_step()
41 | return self.done
42 |
43 |
--------------------------------------------------------------------------------
/simulation/read.py:
--------------------------------------------------------------------------------
1 | import io
2 | import os
3 | from collections import defaultdict
4 | from os import environ
5 |
6 | from simulation.dataset_preprocess import RemoveBreakdowns, RemoveWIP, RemoveRework, RemoveSampling, \
7 | RemovePreventiveMaintenance
8 |
9 |
10 | def try_to_num(inp: str):
11 | try:
12 | return int(inp)
13 | except Exception:
14 | try:
15 | return float(inp)
16 | except Exception:
17 | return inp
18 |
19 |
20 | def read_txt(path):
21 | with io.open(path, 'r') as f:
22 | lines = f.read().split('\n')
23 | headers, lines = lines[0].split('\t'), lines[1:]
24 | dicts = []
25 | for line in lines:
26 | cols = line.split('\t')
27 | d = defaultdict(lambda: None)
28 | all_none = True
29 | for header, col in zip(headers, cols):
30 | if header.upper() != 'IGNORE':
31 | col = try_to_num(col)
32 | d[header] = col
33 | if col is not None:
34 | all_none = False
35 | if len(line) > 0 and len(d) > 0 and not all_none:
36 | dicts.append(d)
37 | return dicts
38 |
39 |
40 | def read_all(d, preprocessors=None):
41 | files = defaultdict(lambda: [])
42 | for file in os.listdir(d):
43 | if '.txt' in file:
44 | files[file] = read_txt(os.path.join(d, file))
45 | if preprocessors is None:
46 | preprocessors = []
47 | if 'NOWIP' in environ:
48 | preprocessors.append(RemoveWIP())
49 | if 'NOBREAKDOWN' in environ:
50 | preprocessors.append(RemoveBreakdowns())
51 | if 'NOPM' in environ:
52 | preprocessors.append(RemovePreventiveMaintenance())
53 | if 'NOREWORK' in environ:
54 | preprocessors.append(RemoveRework())
55 | if 'NOSAMPLING' in environ:
56 | preprocessors.append(RemoveSampling())
57 | if preprocessors is not None:
58 | for p in preprocessors:
59 | files = p.preprocess(files)
60 | return files
61 |
--------------------------------------------------------------------------------
/simulation/gym/E.py:
--------------------------------------------------------------------------------
1 | class E:
2 | class A:
3 | CHOOSE_LOT_FOR_FREE_MACHINE = 100001
4 | CHOOSE_MACHINE_FOR_FREE_LOT = 100002
5 | CHOOSE_LOT_TO_DISPATCH = 100003
6 |
7 | class L4M:
8 | class S:
9 | class GLOBAL:
10 | pass
11 |
12 | class MACHINE:
13 | class MAINTENANCE:
14 | NEXT = 4010101
15 |
16 | SETUP_PROCESSING_RATIO = 4010010
17 | IDLE_RATIO = 4010020
18 | MACHINE_CLASS = 4010030
19 |
20 | class OPERATION_TYPE:
21 | NO_LOTS = 4030010
22 | NO_LOTS_PER_BATCH = 4030020
23 |
24 | class STEPS_LEFT:
25 | MIN = 4030101
26 | MEAN = 4030102
27 | MEDIAN = 4030103
28 | MAX = 4030104
29 |
30 | class FREE_SINCE:
31 | MIN = 4030201
32 | MEAN = 4030202
33 | MEDIAN = 4030203
34 | MAX = 4030204
35 |
36 | class PRIORITY:
37 | MIN = 4030401
38 | MEAN = 4030402
39 | MEDIAN = 4030403
40 | MAX = 4030404
41 |
42 | class PROCESSING_TIME:
43 | AVERAGE = 4030501
44 |
45 | class BATCH:
46 | MIN = 4030601
47 | MAX = 4030602
48 | FULLNESS = 4030603
49 |
50 | class CR:
51 | MIN = 4030701
52 | MEAN = 4030703
53 | MEDIAN = 4030703
54 | MAX = 4030704
55 |
56 | class SETUP:
57 | NEEDED = 4030801
58 | MIN_RUNS_LEFT = 4030802
59 | MIN_RUNS_OK = 4030803
60 | LAST_SETUP_TIME = 4030804
61 |
--------------------------------------------------------------------------------
/rl_train.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import json
3 | import os
4 | import sys
5 | import time
6 |
7 | import wandb
8 |
9 | from stable_baselines3 import PPO
10 |
11 | from wandb.integration.sb3 import WandbCallback
12 |
13 | from simulation.gym.environment import DynamicSCFabSimulationEnvironment
14 | from stable_baselines3.common.callbacks import CheckpointCallback
15 |
16 | from sys import argv
17 |
18 | from simulation.gym.sample_envs import DEMO_ENV_1
19 |
20 |
21 | def main():
22 | to_train = 1000000
23 | t = time.time()
24 |
25 | class MyCallBack(CheckpointCallback):
26 |
27 | def on_step(self) -> bool:
28 | if self.num_timesteps % 100 == 0:
29 | ratio = self.num_timesteps / to_train
30 | perc = round(ratio * 100)
31 | remaining = (time.time() - t) / ratio * (1 - ratio) if ratio > 0 else 9999999999999
32 | remaining /= 3600
33 |
34 | sys.stderr.write(f'\r{self.num_timesteps} / {to_train} {perc}% {round(remaining, 2)} hours left {env.instance.current_time_days} ')
35 | return super().on_step()
36 |
37 | fn = argv[1]
38 | with open(fn, 'r') as config:
39 | p = json.load(config)['params']
40 | args = dict(num_actions=p['action_count'], active_station_group=p['station_group'],
41 | days=p['training_period'], dataset='SMT2020_' + p['dataset'],
42 | dispatcher=p['dispatcher'])
43 | env = DynamicSCFabSimulationEnvironment(**DEMO_ENV_1, **args, seed=p['seed'], max_steps=1000000, reward_type=p['reward'])
44 | eval_env = DynamicSCFabSimulationEnvironment(**DEMO_ENV_1, **args, seed=777, max_steps=10000, reward_type=p['reward'])
45 | model = PPO("MlpPolicy", env, verbose=1)
46 |
47 | p = os.path.dirname(os.path.realpath(fn))
48 | checkpoint_callback = MyCallBack(save_freq=100000, save_path=p, name_prefix='checkpoint_')
49 | model.learn(
50 | total_timesteps=to_train, eval_freq=4000000, eval_env=eval_env, n_eval_episodes=1,
51 | callback=checkpoint_callback
52 | )
53 | model.save(os.path.join(p, 'trained.weights'))
54 |
55 |
56 | if __name__ == '__main__':
57 | main()
58 |
--------------------------------------------------------------------------------
/datasets/SMT2020_LVHM/order.txt:
--------------------------------------------------------------------------------
1 | LOT PART PRIOR PIECES START RDIST REPEAT RUNITS RPT# LOTSPERRPT DUE ORDER HOTLOT
2 | Lot_1 part_1 10 25 01/01/18 00:00:00 constant 258.46 min 200000 1 02/19/18 18:41:46 O_Lot_1 no
3 | Lot_2 part_2 10 25 01/01/18 00:00:00 constant 258.46 min 200000 1 02/22/18 11:05:59 O_Lot_2 no
4 | Lot_3 part_3 10 25 01/01/18 00:00:00 constant 258.46 min 200000 1 02/26/18 08:27:35 O_Lot_3 no
5 | Lot_4 part_4 10 25 01/01/18 00:00:00 constant 258.46 min 200000 1 02/02/18 04:30:02 O_Lot_4 no
6 | Lot_5 part_5 10 25 01/01/18 00:00:00 constant 258.46 min 200000 1 01/24/18 18:49:41 O_Lot_5 no
7 | Lot_6 part_6 10 25 01/01/18 00:00:00 constant 258.46 min 200000 1 01/30/18 23:03:00 O_Lot_6 no
8 | Lot_7 part_7 10 25 01/01/18 00:00:00 constant 258.46 min 200000 1 02/05/18 00:53:39 O_Lot_7 no
9 | Lot_8 part_8 10 25 01/01/18 00:00:00 constant 258.46 min 200000 1 02/07/18 22:42:05 O_Lot_8 no
10 | Lot_9 part_9 10 25 01/01/18 00:00:00 constant 258.46 min 200000 1 02/09/18 00:24:20 O_Lot_9 no
11 | Lot_10 part_10 10 25 01/01/18 00:00:00 constant 258.46 min 200000 1 02/10/18 02:18:05 O_Lot_10 no
12 | HotLot_1 part_1 20 25 01/01/18 00:00:00 constant 10080 min 20000 1 02/03/18 22:41:51 O_HotLot_1 no
13 | HotLot_2 part_2 20 25 01/01/18 00:00:00 constant 10080 min 20000 1 02/06/18 05:43:47 O_HotLot_2 no
14 | HotLot_3 part_3 20 25 01/01/18 00:00:00 constant 10080 min 20000 1 02/08/18 07:05:01 O_HotLot_3 no
15 | HotLot_4 part_4 20 25 01/01/18 00:00:00 constant 10080 min 20000 1 01/24/18 01:49:09 O_HotLot_4 no
16 | HotLot_5 part_5 20 25 01/01/18 00:00:00 constant 10080 min 20000 1 01/17/18 20:54:20 O_HotLot_5 no
17 | HotLot_6 part_6 20 25 01/01/18 00:00:00 constant 10080 min 20000 1 01/21/18 22:30:42 O_HotLot_6 no
18 | HotLot_7 part_7 20 25 01/01/18 00:00:00 constant 10080 min 20000 1 01/25/18 00:45:18 O_HotLot_7 no
19 | HotLot_8 part_8 20 25 01/01/18 00:00:00 constant 10080 min 20000 1 01/26/18 09:57:25 O_HotLot_8 no
20 | HotLot_9 part_9 20 25 01/01/18 00:00:00 constant 10080 min 20000 1 01/27/18 18:09:27 O_HotLot_9 no
21 | HotLot_10 part_10 20 25 01/01/18 00:00:00 constant 10080 min 20000 1 01/28/18 18:30:14 O_HotLot_10 no
22 | SuperHotLot_3 part_3 30 25 01/01/18 00:00:00 constant 28258.37 min 2000 1 02/08/18 07:05:01 O_SuperHotLot_3 no
23 |
--------------------------------------------------------------------------------
/simulation/event_queue.py:
--------------------------------------------------------------------------------
1 | class EventQueue:
2 | def __init__(self):
3 | self.arr = []
4 |
5 | @property
6 | def first(self):
7 | return self.arr[0]
8 |
9 | @property
10 | def empty(self):
11 | return len(self.arr) == 0
12 |
13 | def pop_first(self):
14 | return self.arr.pop(0)
15 |
16 | def push(self, item):
17 | self.arr.append(item)
18 |
19 | def ordered_insert(self, item):
20 | if len(self.arr) == 0 or item.timestamp < self.arr[0].timestamp:
21 | self.arr.insert(0, item)
22 | elif item.timestamp > self.arr[-1].timestamp:
23 | self.arr.append(item)
24 | else:
25 | lo = 0
26 | hi = len(self.arr)
27 | while lo < hi:
28 | mid = (lo + hi) // 2
29 | if item.timestamp < self.arr[mid].timestamp:
30 | hi = mid
31 | else:
32 | lo = mid + 1
33 | self.arr.insert(lo, item)
34 |
35 | def remove(self, remove):
36 | self.arr.remove(remove)
37 |
38 |
39 | class LNode:
40 | def __init__(self, value, nx):
41 | self.value = value
42 | self.next: LNode = nx
43 |
44 |
45 | class LinkedList:
46 | def __init__(self):
47 | self.f = None
48 |
49 | @property
50 | def first(self):
51 | return self.f.value
52 |
53 | @property
54 | def empty(self):
55 | return self.f is None
56 |
57 | def pop_first(self):
58 | val = self.f.value
59 | self.f = self.f.next
60 | return val
61 |
62 | def ordered_insert(self, item):
63 | for i, ev in enumerate(self.arr):
64 | if item.timestamp < ev.timestamp:
65 | ins = True
66 | break
67 | if ins:
68 | self.arr.insert(i, item)
69 | else:
70 | self.push(item)
71 | pass
72 |
73 | def remove(self, item):
74 | if item == self.f.value:
75 | return self.pop_first()
76 | else:
77 | pointer = self.f
78 | while pointer is not None:
79 | if pointer.next.value == item.value:
80 | item = pointer.next.item
81 | pointer.next = pointer.next.next
82 | return item
83 | raise ValueError('not found')
84 |
--------------------------------------------------------------------------------
/simulation/dispatching/dispatcher.py:
--------------------------------------------------------------------------------
1 | from simulation.classes import Lot, Machine
2 | from simulation.randomizer import Randomizer
3 |
4 | r = Randomizer()
5 |
6 |
7 | class Dispatchers:
8 |
9 | @staticmethod
10 | def get_setup(new_setup, machine, actual_step_setup_time, setups):
11 | if new_setup != '' and machine.current_setup != new_setup:
12 | if actual_step_setup_time is not None:
13 | return actual_step_setup_time
14 | elif (machine.current_setup, new_setup) in setups:
15 | return setups[(machine.current_setup, new_setup)]
16 | elif ('', new_setup) in setups:
17 | return setups[('', new_setup)]
18 | return 0
19 |
20 | @staticmethod
21 | def fifo_ptuple_for_lot(lot: Lot, time, machine: Machine = None, setups=None):
22 | if machine is not None:
23 | lot.ptuple = (
24 | 0 if machine.min_runs_left is None or machine.min_runs_setup == lot.actual_step.setup_needed else 1,
25 | 0 if lot.cqt_waiting is not None else 1,
26 | Dispatchers.get_setup(lot.actual_step.setup_needed, machine, lot.actual_step.setup_time, setups),
27 | -lot.priority, lot.free_since, lot.deadline_at,
28 | )
29 | return lot.ptuple
30 | else:
31 | return -lot.priority, lot.free_since, lot.deadline_at,
32 |
33 | @staticmethod
34 | def cr_ptuple_for_lot(lot: Lot, time, machine: Machine = None, setups=None):
35 | if machine is not None:
36 | lot.ptuple = (
37 | 0 if machine.min_runs_left is None or machine.min_runs_setup == lot.actual_step.setup_needed else 1,
38 | 0 if lot.cqt_waiting is not None else 1,
39 | Dispatchers.get_setup(lot.actual_step.setup_needed, machine, lot.actual_step.setup_time, setups),
40 | -lot.priority, lot.cr(time),
41 | )
42 | return lot.ptuple
43 | else:
44 | return -lot.priority, lot.cr(time),
45 |
46 | @staticmethod
47 | def random_ptuple_for_lot(lot: Lot, time, machine: Machine = None, setups=None):
48 | if machine is not None:
49 | return (
50 | 0 if machine.min_runs_left is None or machine.min_runs_setup == lot.actual_step.setup_needed else 1,
51 | 0 if lot.cqt_waiting is not None else 1,
52 | r.random.uniform(0, 99999),
53 | )
54 | else:
55 | return r.random.uniform(0, 99999),
56 |
57 |
58 | dispatcher_map = {
59 | 'fifo': Dispatchers.fifo_ptuple_for_lot,
60 | 'cr': Dispatchers.cr_ptuple_for_lot,
61 | 'random': Dispatchers.random_ptuple_for_lot,
62 | }
63 |
--------------------------------------------------------------------------------
/simulation/events.py:
--------------------------------------------------------------------------------
1 | class MachineDoneEvent:
2 |
3 | def __init__(self, timestamp, machines):
4 | self.timestamp = timestamp
5 | self.machines = machines
6 | self.lots = []
7 |
8 | def handle(self, instance):
9 | instance.free_up_machines(self.machines)
10 |
11 |
12 | class LotDoneEvent:
13 |
14 | def __init__(self, timestamp, machines, lots):
15 | self.timestamp = timestamp
16 | self.machines = machines
17 | self.lots = lots
18 |
19 | def handle(self, instance):
20 | instance.free_up_lots(self.lots)
21 |
22 |
23 | class ReleaseEvent:
24 |
25 | @staticmethod
26 | def handle(instance, to_time):
27 | if to_time is None or (
28 | len(instance.dispatchable_lots) > 0 and instance.dispatchable_lots[0].release_at <= to_time):
29 | instance.current_time = max(0, instance.dispatchable_lots[0].release_at, instance.current_time)
30 | lots_released = []
31 | while len(instance.dispatchable_lots) > 0 and max(0, instance.dispatchable_lots[
32 | 0].release_at) <= instance.current_time:
33 | lots_released.append(instance.dispatchable_lots[0])
34 | instance.dispatchable_lots = instance.dispatchable_lots[1:]
35 | instance.active_lots += lots_released
36 | instance.free_up_lots(lots_released)
37 | for plugin in instance.plugins:
38 | plugin.on_lots_release(instance, lots_released)
39 | return True
40 | else:
41 | return False
42 |
43 |
44 | class BreakdownEvent:
45 |
46 | def __init__(self, timestamp, length, repeat_interval, machine, is_breakdown):
47 | self.timestamp = timestamp
48 | self.machine = machine
49 | self.machines = []
50 | self.lots = []
51 | self.is_breakdown = is_breakdown
52 | self.repeat_interval = repeat_interval
53 | self.length = length
54 | if not is_breakdown:
55 | machine.next_preventive_maintenance = timestamp
56 |
57 | def handle(self, instance):
58 | length = self.length.sample()
59 | if self.is_breakdown:
60 | self.machine.bred_time += length
61 | else:
62 | self.machine.pmed_time += length
63 | instance.handle_breakdown(self.machine, length)
64 | for plugin in instance.plugins:
65 | if self.is_breakdown:
66 | plugin.on_breakdown(instance, self)
67 | else:
68 | plugin.on_preventive_maintenance(instance, self)
69 | instance.add_event(BreakdownEvent(
70 | self.timestamp + length + self.repeat_interval.sample(),
71 | self.length,
72 | self.repeat_interval,
73 | self.machine,
74 | self.is_breakdown,
75 | ))
76 |
--------------------------------------------------------------------------------
/simulation/dispatching/dm_machine_for_lot.py:
--------------------------------------------------------------------------------
1 | from collections import defaultdict
2 |
3 |
4 | class MachineForLotDispatchManager:
5 |
6 | @staticmethod
7 | def init(self):
8 | self.lots_waiting_for_family = defaultdict(lambda: set())
9 | self.usable_lots = list()
10 | self.lot_in_usable = defaultdict(lambda: False)
11 | self.free_machines = [False for _ in self.machines]
12 |
13 | @staticmethod
14 | def free_up_lots(self, lot):
15 | self.lots_waiting_for_family[lot.actual_step.family].add(lot)
16 | for machine in self.family_machines[lot.actual_step.family]:
17 | if self.free_machines[machine.idx]:
18 | MachineForLotDispatchManager.assign_lot_if_dedication_ok(self, lot, machine)
19 |
20 | @staticmethod
21 | def assign_lot_if_dedication_ok(self, lot, machine):
22 | di = lot.actual_step.order
23 | if di not in lot.dedications or machine.idx == lot.dedications[di]:
24 | if machine not in lot.waiting_machines:
25 | lot.waiting_machines.append(machine)
26 | if lot not in machine.waiting_lots:
27 | machine.waiting_lots.append(lot)
28 | if not self.lot_in_usable[lot.idx]:
29 | self.lot_in_usable[lot.idx] = True
30 | assert lot not in self.usable_lots
31 | assert len(lot.waiting_machines) > 0
32 | self.usable_lots.append(lot)
33 |
34 | @staticmethod
35 | def free_up_machine(self, machine):
36 | self.free_machines[machine.idx] = True
37 | for lot in self.lots_waiting_for_family[machine.family]:
38 | MachineForLotDispatchManager.assign_lot_if_dedication_ok(self, lot, machine)
39 |
40 | @staticmethod
41 | def reserve(self, lots, machine):
42 | self.free_machines[machine.idx] = False
43 | for lot in machine.waiting_lots:
44 | lot.waiting_machines.remove(machine)
45 | if len(lot.waiting_machines) == 0 and self.lot_in_usable[lot.idx]:
46 | self.lot_in_usable[lot.idx] = False
47 | self.usable_lots.remove(lot)
48 | machine.waiting_lots.clear()
49 | for lot in lots:
50 | self.lots_waiting_for_family[lot.actual_step.family].remove(lot)
51 | for m in lot.waiting_machines:
52 | m.waiting_lots.remove(lot)
53 | lot.waiting_machines.clear()
54 | for lot in lots:
55 | if self.lot_in_usable[lot.idx]:
56 | self.lot_in_usable[lot.idx] = False
57 | self.usable_lots.remove(lot)
58 | assert lot not in self.usable_lots
59 |
60 | @staticmethod
61 | def next_decision_point(self):
62 | while len(self.usable_lots) == 0 and not self.done:
63 | self.next_step()
64 | return self.done
65 |
--------------------------------------------------------------------------------
/rl_test.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import io
3 | import json
4 | import os
5 | from sys import argv, stdout
6 |
7 | from stable_baselines3 import PPO
8 |
9 | from simulation.gym.environment import DynamicSCFabSimulationEnvironment
10 | from simulation.gym.sample_envs import DEMO_ENV_1
11 | from simulation.stats import print_statistics
12 |
13 |
14 | def main():
15 | t = datetime.datetime.now()
16 | ranag = 'random' in argv[2]
17 | if not ranag:
18 | model = PPO.load(os.path.join(argv[1], argv[2]))
19 | with io.open(os.path.join(argv[1], "config.json"), "r") as f:
20 | config = json.load(f)['params']
21 |
22 | args = dict(seed=0, num_actions=config['action_count'], active_station_group=config['station_group'], days=365 * 2,
23 | dataset='SMT2020_' + config['dataset'], dispatcher=config['dispatcher'], reward_type=config['reward'])
24 | env = DynamicSCFabSimulationEnvironment(**DEMO_ENV_1, **args, max_steps=1000000000)
25 | obs = env.reset()
26 | reward = 0
27 |
28 | checkpoints = [180, 365]
29 | current_checkpoint = 0
30 |
31 | steps = 0
32 | shown_days = 0
33 | deterministic = True
34 | while True:
35 | if not ranag:
36 | action, _states = model.predict(obs, deterministic=deterministic)
37 | if ranag:
38 | if argv[2] == 'random':
39 | action = env.action_space.sample()
40 | else:
41 | state = obs[4:]
42 | actions = config['action_count']
43 | one_length = len(state) // actions
44 | descending = True
45 | index = 0
46 | sortable = []
47 | for i in range(actions):
48 | sortable.append((state[one_length * i + index], i))
49 | sortable.sort(reverse=descending)
50 | action = sortable[0][1]
51 | obs, r, done, info = env.step(action)
52 | if r < 0:
53 | deterministic = False
54 | else:
55 | deterministic = True
56 | reward += r
57 | steps += 1
58 | di = int(env.instance.current_time_days)
59 |
60 | if di % 10 == 0 and di > shown_days:
61 | print(f'Step {steps} day {shown_days}')
62 | shown_days = di
63 | stdout.flush()
64 |
65 | chp = checkpoints[current_checkpoint]
66 | if env.instance.current_time_days > chp:
67 | print(f'{checkpoints[current_checkpoint]} days')
68 | print_statistics(env.instance, chp, config['dataset'], config['dispatcher'], method=f'rl{chp}', dir=argv[1])
69 | print('=================')
70 | stdout.flush()
71 | current_checkpoint += 1
72 | if len(checkpoints) == current_checkpoint:
73 | break
74 |
75 | if done:
76 | print('Exiting with DONE')
77 | break
78 |
79 | print(f'Reward is {reward}')
80 | dt = datetime.datetime.now() - t
81 | print('Elapsed', str(dt))
82 | env.close()
83 |
84 |
85 | if __name__ == '__main__':
86 | main()
87 |
--------------------------------------------------------------------------------
/simulation/plugins/chart_plugin.py:
--------------------------------------------------------------------------------
1 | import io
2 | import os
3 | from collections import defaultdict
4 | import random
5 |
6 | from simulation.plugins.interface import IPlugin
7 |
8 | CHART_INTERVAL = 10
9 |
10 |
11 | def random_color():
12 | r = lambda: random.randint(0, 255)
13 | return '#%02X%02X%02X' % (r(), r(), r())
14 |
15 |
16 | class ChartPlugin(IPlugin):
17 | def on_sim_init(self, instance):
18 | self.debug_step_count = 0
19 | self.visualization_data_jobs = defaultdict(lambda: [])
20 | self.visualization_data_jobs_colors = defaultdict(lambda: [])
21 | self.visualization_data_tools = defaultdict(lambda: [])
22 | self.visualization_data_tools_colors = defaultdict(lambda: [])
23 | self.visualization_task_colors = defaultdict(random_color)
24 | self.visualization_tool_colors = defaultdict(random_color)
25 |
26 | def on_dispatch(self, instance, machine, lots, machine_end_time, lot_end_time):
27 | machine_name = f"{machine.idx}_{machine.family}"
28 | self.add_chart_tools(machine_name, ','.join([lot.name + ' ' + str(lot.idx) for lot in lots]),
29 | ','.join([lot.actual_step.step_name for lot in lots]), instance.current_time,
30 | machine_end_time)
31 | for lot in lots:
32 | self.add_chart_jobs(lot.name + ' ' + str(lot.idx), machine_name, lot.actual_step.order,
33 | instance.current_time, lot_end_time)
34 |
35 | if self.debug_step_count % CHART_INTERVAL == 0:
36 | self.print_html()
37 |
38 | @property
39 | def act_dir(self):
40 | return os.path.dirname(os.path.realpath(__file__))
41 |
42 | def print_html(self):
43 | d = os.path.join(self.act_dir, 'visualization_template.html')
44 | with io.open(d, 'r') as f:
45 | template = f.read()
46 | for name, li, colors in [('tools', self.visualization_data_tools, self.visualization_data_tools_colors),
47 | ('jobs', self.visualization_data_jobs, self.visualization_data_jobs_colors)]:
48 | vis_data = []
49 | color_data = []
50 | keyss = sorted(li.keys())
51 | for k in keyss:
52 | vis_data += li[k]
53 | color_data += colors[k]
54 | data = template.replace('["DATA"]', ',\n'.join(vis_data))
55 | with io.open(f'chart_{name}.html', 'w') as f:
56 | f.write(data)
57 |
58 | def add_chart_tools(self, tool_name, job_name, task_name, t_from: int, t_to: int):
59 | self.visualization_data_tools[tool_name].append(
60 | f"['{tool_name}', '{task_name}', 'fill-color: {self.visualization_task_colors[job_name]}', " +
61 | f"new Date({t_from * 1000}), new Date({t_to * 1000})]")
62 | self.visualization_data_tools_colors[tool_name].append(f"'{self.visualization_task_colors[job_name]}'")
63 |
64 | def add_chart_jobs(self, job_name, tool_name, step, t_from, t_to):
65 | self.visualization_data_jobs[tool_name].append(
66 | f"['{job_name}', '{tool_name} s{step}', 'fill-color: {self.visualization_tool_colors[tool_name]}', " +
67 | f"new Date({t_from * 1000}), new Date({t_to * 1000})]")
68 | self.visualization_data_jobs_colors[tool_name].append(f"'{self.visualization_tool_colors[tool_name]}'")
69 |
--------------------------------------------------------------------------------
/simulation/generator_instance.py:
--------------------------------------------------------------------------------
1 | import os
2 | from typing import Dict, List
3 |
4 | from simulation.classes import Machine, FileRoute, Lot, Step, Route
5 | from simulation.events import BreakdownEvent
6 | from simulation.instance import Instance
7 | from simulation.randomizer import Randomizer
8 | from simulation.tools import get_interval, get_distribution, UniformDistribution, date_time_parse
9 |
10 | r = Randomizer()
11 |
12 |
13 | class GeneratorRoute(Route):
14 | def __init__(self, idx, steps: int):
15 | fams = [r.random.choice(['S1', 'S2', 'S3', 'S4', 'B1', 'B2', 'B3',
16 | 'C1', 'C2']) for i in range(steps)]
17 | steps = [Step(i, {
18 | 'STEP': i + 1,
19 | 'DESC': f'Step {i} for route {idx}',
20 | 'STNFAM': fam,
21 | 'SETUP': r.random.choice(['', '', '', '', 'Setup1', 'Setup2']),
22 | 'STIME': 20,
23 | 'STUNITS': 'min',
24 | 'RWKSTEP': '',
25 | 'PTPER': 'per_batch',
26 | 'PDIST': 'uniform',
27 | 'PTUNITS': 'min',
28 | 'PTIME': r.random.choice([25, 45, 120, 10]),
29 | 'PTIME2': 5,
30 | 'BATCHMN': 75 if fam.startswith('B') else '',
31 | 'BATCHMX': 125 if fam.startswith('B') else '',
32 | 'StepPercent': '',
33 | 'REWORK': '',
34 | 'PartInterval': '',
35 | 'BatchInterval': '',
36 | }) for i, fam in enumerate(fams)]
37 | super().__init__(idx, steps)
38 |
39 |
40 | class GeneratorInstance(Instance):
41 |
42 | def __init__(self, run_to):
43 | print('New instance generated')
44 | machines = []
45 | machine_id = 0
46 | r = Randomizer()
47 | family_locations = {}
48 | for group, family, quantity, cascading in [
49 | ('Simple', 'S1', 4, 1),
50 | ('Simple', 'S2', 2, 1),
51 | ('Simple', 'S3', 3, 1),
52 | ('Simple', 'S4', 2, 1),
53 | ('Batching', 'B1', 5, 1),
54 | ('Batching', 'B2', 3, 1),
55 | ('Batching', 'B3', 2, 1),
56 | ('Cascading', 'C1', 3, 2),
57 | ('Cascading', 'C2', 1, 2),
58 | ]:
59 | for i in range(quantity):
60 | speed = r.random.uniform(0.7, 1.3)
61 | m = Machine(idx=machine_id, d={
62 | 'LTIME': 1,
63 | 'LTUNITS': 'min',
64 | 'ULTIME': 1,
65 | 'ULTUNITS': 'min',
66 | 'STNGRP': group,
67 | 'STNFAMLOC': 'Fab',
68 | 'STNFAM': family,
69 | 'STNCAP': cascading,
70 | }, speed=speed)
71 | family_locations[m.family] = m.loc
72 | machines.append(m)
73 | machine_id += 1
74 |
75 | from_to = {('Fab', 'Fav'): get_distribution('uniform', 'min', 5, 1)}
76 |
77 | routes = {}
78 | for rk in range(5):
79 | route = GeneratorRoute(rk, 10)
80 | last_loc = None
81 | for s in route.steps:
82 | s.family_location = family_locations[s.family]
83 | key = (last_loc, s.family_location)
84 | if last_loc is not None and key in from_to:
85 | s.transport_time = from_to[key]
86 | last_loc = s.family_location
87 | routes[str(rk)] = route
88 |
89 | parts = {str(p): str(p) for p in range(5)}
90 |
91 | lots = []
92 | idx = 0
93 | lot_pre = {}
94 | for order in range(5):
95 | first_release = 0
96 | release_interval = 36000
97 |
98 | for i in range(10000):
99 | rel_time = first_release + i * release_interval
100 |
101 | route = routes[str(order)]
102 |
103 | relative_deadline = sum([s.processing_time.avg() for s in route.steps]) * 2
104 |
105 | lot = Lot(idx, route, 10, rel_time, relative_deadline, {'LOT': f'Lot {order}'})
106 | lots.append(lot)
107 | lot_pre[lot.name] = relative_deadline
108 | idx += 1
109 | if rel_time > run_to * 1.5:
110 | break
111 |
112 | setups = {('Setup1', 'Setup2'): 1200, ('Setup1', 'Setup2'): 2400}
113 |
114 | super().__init__(machines, routes, lots, setups, [])
115 |
--------------------------------------------------------------------------------
/simulation/stats.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import io
3 | import json
4 | import statistics
5 | from collections import defaultdict
6 |
7 | from simulation.classes import Lot, Step
8 |
9 |
10 | def print_statistics(instance, days, dataset, disp, method='greedy', dir='greedy'):
11 | from simulation.instance import Instance
12 | instance: Instance
13 | lot: Lot
14 | lots = defaultdict(lambda: {'ACT': [], 'throughput': 0, 'on_time': 0, 'tardiness': 0, 'waiting_time': 0,
15 | 'processing_time': 0, 'transport_time': 0, 'waiting_time_batching': 0})
16 | apt = {}
17 | dl = {}
18 | for lot in instance.done_lots:
19 | lots[lot.name]['ACT'].append(lot.done_at - lot.release_at)
20 | lots[lot.name]['throughput'] += 1
21 | lots[lot.name]['tardiness'] += max(0, lot.done_at - lot.deadline_at)
22 | lots[lot.name]['waiting_time'] += lot.waiting_time
23 | lots[lot.name]['waiting_time_batching'] += lot.waiting_time_batching
24 | lots[lot.name]['processing_time'] += lot.processing_time
25 | lots[lot.name]['transport_time'] += lot.transport_time
26 | if lot.done_at <= lot.deadline_at:
27 | lots[lot.name]['on_time'] += 1
28 | if lot.name not in apt:
29 | apt[lot.name] = sum([s.processing_time.avg() for s in lot.processed_steps])
30 | dl[lot.name] = lot.deadline_at - lot.release_at
31 | print('Lot', 'APT', 'DL', 'ACT', 'TH', 'ONTIME', 'tardiness', 'wa', 'pr', 'tr')
32 | acts = []
33 | ths = []
34 | ontimes = []
35 | for lot_name in sorted(list(lots.keys())):
36 | l = lots[lot_name]
37 | avg = statistics.mean(l['ACT']) / 3600 / 24
38 | lots[lot_name]['ACT'] = avg
39 | acts += [avg]
40 | th = lots[lot_name]['throughput']
41 | ths += [th]
42 | ontime = round(l['on_time'] / l['throughput'] * 100)
43 | ontimes += [ontime]
44 | wa = lots[lot_name]['waiting_time'] / l['throughput'] / 3600 / 24
45 | wab = lots[lot_name]['waiting_time_batching'] / l['throughput'] / 3600 / 24
46 | pr = lots[lot_name]['processing_time'] / l['throughput'] / 3600 / 24
47 | tr = lots[lot_name]['transport_time'] / l['throughput'] / 3600 / 24
48 | print(lot_name, round(apt[lot_name] / 3600 / 24, 1), round(dl[lot_name] / 3600 / 24, 1), round(avg, 1), th,
49 | ontime, l['tardiness'], wa, wab, pr, tr)
50 | print('---------------')
51 | print(round(statistics.mean(acts), 2), statistics.mean(ths), statistics.mean(ontimes))
52 | print(round(sum(acts), 2), sum(ths), sum(ontimes))
53 |
54 | utilized_times = defaultdict(lambda: [])
55 | setup_times = defaultdict(lambda: [])
56 | pm_times = defaultdict(lambda: [])
57 | br_times = defaultdict(lambda: [])
58 | for machine in instance.machines:
59 | utilized_times[machine.family].append(machine.utilized_time)
60 | setup_times[machine.family].append(machine.setuped_time)
61 | pm_times[machine.family].append(machine.pmed_time)
62 | br_times[machine.family].append(machine.bred_time)
63 |
64 | print('Machine', 'Cnt', 'avail' 'util', 'br', 'pm', 'setup')
65 | machines = defaultdict(lambda: {})
66 | for machine_name in sorted(list(utilized_times.keys())):
67 | av = (instance.current_time - statistics.mean(pm_times[machine_name]) - statistics.mean(br_times[machine_name]))
68 | machines[machine_name]['avail'] = av / instance.current_time
69 | machines[machine_name]['util'] = statistics.mean(utilized_times[machine_name]) / av
70 | machines[machine_name]['pm'] = statistics.mean(pm_times[machine_name]) / instance.current_time
71 | machines[machine_name]['br'] = statistics.mean(br_times[machine_name]) / instance.current_time
72 | machines[machine_name]['setup'] = statistics.mean(setup_times[machine_name]) / instance.current_time
73 | r = instance.lot_waiting_at_machine[machine_name]
74 | machines[machine_name]['waiting_time'] = r[1] / r[0] / 3600 / 24
75 | print(machine_name, len(utilized_times[machine_name]),
76 | round(machines[machine_name]['avail'] * 100, 2),
77 | round(machines[machine_name]['util'] * 100, 2),
78 | round(machines[machine_name]['br'] * 100, 2),
79 | round(machines[machine_name]['pm'] * 100, 2),
80 | round(machines[machine_name]['setup'] * 100, 2))
81 |
82 | plugins = {}
83 |
84 | for plugin in instance.plugins:
85 | if plugin.get_output_name() is not None:
86 | plugins[plugin.get_output_name()] = plugin.get_output_value()
87 |
88 | with io.open(f'{dir}/{method}_{days}days_{dataset}_{disp}.json', 'w') as f:
89 | json.dump({
90 | 'lots': lots,
91 | 'machines': machines,
92 | 'plugins': plugins,
93 | }, f)
94 |
--------------------------------------------------------------------------------
/simulation/file_instance.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, List
2 |
3 | from simulation.classes import Machine, FileRoute, Lot
4 | from simulation.events import BreakdownEvent
5 | from simulation.instance import Instance
6 | from simulation.randomizer import Randomizer
7 | from simulation.tools import get_interval, get_distribution, UniformDistribution, date_time_parse
8 |
9 |
10 | class FileInstance(Instance):
11 |
12 | def __init__(self, files: Dict[str, List[Dict]], run_to, lot_for_machine, plugins):
13 | machines = []
14 | machine_id = 0
15 | r = Randomizer()
16 | family_locations = {}
17 | for d_m in files['tool.txt.1l']:
18 | for i in range(int(d_m['STNQTY'])):
19 | speed = 1 # r.random.uniform(0.7, 1.3)
20 | m = Machine(idx=machine_id, d=d_m, speed=speed)
21 | family_locations[m.family] = m.loc
22 | machines.append(m)
23 | machine_id += 1
24 |
25 | from_to = {(a['FROMLOC'], a['TOLOC']): get_distribution(a['DDIST'], a['DUNITS'], a['DTIME'], a['DTIME2']) for a
26 | in files['fromto.txt']}
27 |
28 | pieces = max([a['PIECES'] for a in files['order.txt'] + files['WIP.txt']])
29 | routes = {}
30 | route_keys = [key for key in files.keys() if 'route' in key]
31 | for rk in route_keys:
32 | route = FileRoute(rk, pieces, files[rk])
33 | last_loc = None
34 | for s in route.steps:
35 | s.family_location = family_locations[s.family]
36 | key = (last_loc, s.family_location)
37 | if last_loc is not None and key in from_to:
38 | s.transport_time = from_to[key]
39 | last_loc = s.family_location
40 | routes[rk] = route
41 |
42 | parts = {p['PART']: p['ROUTEFILE'] for p in files['part.txt']}
43 |
44 | lots = []
45 | idx = 0
46 | lot_pre = {}
47 | for order in files['order.txt']:
48 | assert pieces == order['PIECES']
49 | first_release = 0
50 | release_interval = get_interval(order['REPEAT'], order['RUNITS'])
51 | relative_deadline = (date_time_parse(order['DUE']) - date_time_parse(order['START'])).total_seconds()
52 |
53 | for i in range(order['RPT#']):
54 | rel_time = first_release + i * release_interval
55 | lot = Lot(idx, routes[parts[order['PART']]], order['PRIOR'], rel_time, relative_deadline, order)
56 | lots.append(lot)
57 | lot_pre[lot.name] = relative_deadline
58 | idx += 1
59 | if rel_time > run_to:
60 | break
61 |
62 | for wip in files['WIP.txt']:
63 | assert pieces == wip['PIECES']
64 | first_release = 0
65 | relative_deadline = (date_time_parse(wip['DUE']) - date_time_parse(wip['START'])).total_seconds()
66 | if wip['CURSTEP'] < len(routes[parts[wip['PART']]].steps) - 1:
67 | lot = Lot(idx, routes[parts[wip['PART']]], wip['PRIOR'], first_release, relative_deadline, wip)
68 | lots.append(lot)
69 | lot.release_at = lot.deadline_at - lot_pre[lot.name]
70 | idx += 1
71 |
72 | setups = {(s['CURSETUP'], s['NEWSETUP']): get_interval(s['STIME'], s['STUNITS']) for s in files['setup.txt']}
73 | setup_min_run = {s['SETUP']: s['MINRUN'] for s in files['setupgrp.txt']}
74 |
75 | downcals = {}
76 | for dc in files['downcal.txt']:
77 | downcals[dc['DOWNCALNAME']] = (get_distribution(dc['MTTFDIST'], dc['MTTFUNITS'], dc['MTTF']),
78 | get_distribution(dc['MTTRDIST'], dc['MTTRUNITS'], dc['MTTR']))
79 | pmcals = {}
80 | for dc in files['pmcal.txt']:
81 | pmcals[dc['PMCALNAME']] = (get_distribution('constant', dc['MTBPMUNITS'], dc['MTBPM']),
82 | get_distribution(dc['MTTRDIST'], dc['MTTRUNITS'], dc['MTTR'], dc['MTTR2']))
83 |
84 | breakdowns = []
85 | for a in files['attach.txt']:
86 | if a['RESTYPE'] == 'stngrp':
87 | m_break = [m for m in machines if m.group == a['RESNAME']]
88 | else:
89 | m_break = [m for m in machines if m.family == a['RESNAME']]
90 | distribution = get_distribution(a['FOADIST'], a['FOAUNITS'], a['FOA'])
91 | if a['CALTYPE'] == 'down':
92 | is_breakdown = True
93 | ne, le = downcals[a['CALNAME']]
94 | else:
95 | is_breakdown = False
96 | ne, le = pmcals[a['CALNAME']]
97 | if distribution is None:
98 | distribution = ne
99 | if a['FOAUNITS'] == '':
100 | for m in m_break:
101 | m.piece_per_maintenance.append(ne.c)
102 | m.pieces_until_maintenance.append(a['FOA'])
103 | m.maintenance_time.append(le)
104 | else:
105 | for m in m_break:
106 | br = BreakdownEvent(distribution.sample(), le, ne, m, is_breakdown)
107 | if not is_breakdown:
108 | m.pms.append(br)
109 | breakdowns.append(br)
110 |
111 | super().__init__(machines, routes, lots, setups, setup_min_run, breakdowns, lot_for_machine, plugins)
112 |
--------------------------------------------------------------------------------
/eval_results.py:
--------------------------------------------------------------------------------
1 | import io
2 | import json
3 | import statistics
4 | from collections import defaultdict
5 | from os import listdir, path
6 |
7 |
8 | def read_references():
9 | out = {}
10 | for t in ['lots', 'machines']:
11 | out[t] = {}
12 | for ds in ['HVLM', 'LVHM']:
13 | out[t][ds] = defaultdict(lambda: 0)
14 | file_name = f'datasets/{t}_SMT2020_{ds}.txt'
15 | with io.open(file_name, 'r') as f:
16 | lines = f.read().split('\n')
17 | headers = lines[0].split(' ')
18 | rows = [a.split(' ') for a in lines[1:]]
19 | for row in rows:
20 | for h, c in zip(headers[1:], row[1:]):
21 | out[t][ds][(h, row[0])] = c
22 | return out
23 |
24 |
25 | def handle_obj(datas):
26 | o = {}
27 | for k, v in datas[0].items():
28 | its = [d[k] for d in datas]
29 | if type(v) is dict:
30 | o[k] = handle_obj(its)
31 | elif type(v) in [int, float]:
32 | o[k] = (statistics.mean(its), statistics.stdev(its))
33 | else:
34 | assert False
35 | return o
36 |
37 |
38 | def loadfile(f):
39 | with io.open(f, 'r') as q:
40 | return q.read()
41 |
42 |
43 | def main():
44 | dirs = ['greedy']
45 |
46 | results = {}
47 | names = set()
48 |
49 | runs = 10
50 |
51 | lots = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
52 | machines = defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
53 |
54 | for d in dirs:
55 | subs = listdir(d)
56 | for s in subs:
57 | if path.isfile(d + '/' + s) and 'seed0' in s and s.endswith('.json'):
58 | file_locs = [d + '/' + s.replace('seed0_', f'seed{r}_') for r in range(runs)]
59 | name = f'{len(file_locs)}x {s.replace("seed0_", "")}'
60 | results[name] = {'files': file_locs}
61 | elif path.isdir(d + '/' + s) and s.startswith('0_'):
62 | s = s[2:]
63 | ds = 'HVLM' if 'HVLM' in s else 'LVHM'
64 | dispatcher = 'fifo' if 'fifo' in s else 'cr'
65 | y2n = f'rl2y_730days_{ds}_{dispatcher}.json'
66 | d180n = f'rl180_180days_{ds}_{dispatcher}.json'
67 | file_locs_2y = [path.join(d, str(r) + '_' + s, y2n) for r in range(runs)]
68 | file_locs_180d = [path.join(d, str(r) + '_' + s, d180n) for r in range(runs)]
69 | name180 = f'{len(file_locs_2y)}x {d}_180days_{s}'
70 | name730 = f'{len(file_locs_2y)}x {d}_730days_{s}'
71 | results[name180] = {'files': file_locs_180d}
72 | results[name730] = {'files': file_locs_2y}
73 |
74 | for name in results.keys():
75 | names.add(name)
76 | d = results[name]
77 | files = d['files']
78 | datas = [json.loads(loadfile(f)) for f in files]
79 | r = d['avgs'] = handle_obj(datas)
80 | for k, v in sorted(r['lots'].items(), key=lambda k: k[0]):
81 | lots[k][name] = dict(
82 | act=round(v["ACT"][0], 2),
83 | th=round(v["throughput"][0], 2),
84 | on_time=round(v["on_time"][0] / v["throughput"][0] * 100),
85 | tardiness=round(v["tardiness"][0] / v["throughput"][0] / 24),
86 | )
87 |
88 | for k, v in sorted(r['machines'].items(), key=lambda k: k[0]):
89 | machines[k][name] = dict(
90 | avail=round(v["avail"][0] * 100, 2),
91 | util=round(v["util"][0] * 100, 2),
92 | pm=round(v["pm"][0] * 100, 2),
93 | br=round(v["br"][0] * 100, 2),
94 | setup=round(v["setup"][0] * 100, 2),
95 | waiting_time=round(v["waiting_time"][0], 2),
96 | )
97 |
98 | print('\t', end='')
99 | names = sorted(list(names))
100 | for name in names:
101 | print(name.replace(':', '').replace('\t', ''), '\t\t', end='')
102 | print()
103 |
104 | print('', end='\t')
105 | for name in names:
106 | print('act\tth\ton_time\ttardiness', end='\t')
107 | print()
108 |
109 | ref = read_references()
110 |
111 | for lot in sorted(lots.keys()):
112 | t = lots[lot]
113 | print(lot, end='\t')
114 | for name in names:
115 | i = ref['lots']['HVLM' if 'HVLM' in name else 'LVHM']
116 | for x in ['act', 'th', 'on_time']:
117 | i[(x, lot)] = float(i[(x, lot)])
118 | print(f"{i[(x, lot)]}->{t[name][x]} ({round(t[name][x] - i[(x, lot)], 2)})", end='\t')
119 | print(t[name]['tardiness'], end='\t')
120 | print()
121 |
122 | print('', end='\t')
123 | for name in names:
124 | print('avail\t\t\tutil\t\t\tpm\t\t\tbr\t\t\tsetup\t\t\twaiting_time_before', end='\t')
125 | print()
126 | print('', end='\t')
127 | for name in names:
128 | print('old\tnew\tdelta\told\tnew\tdelta\told\tnew\tdelta\told\tnew\tdelta\told\tnew\tdelta\tnew', end='\t')
129 | print()
130 | for machine in sorted(machines.keys()):
131 | t = machines[machine]
132 | print(machine, end='\t')
133 | for name in names:
134 | i = ref['machines']['HVLM' if 'HVLM' in name else 'LVHM']
135 | for x in ['avail', 'util', 'pm', 'br', 'setup']:
136 | i[(x, machine)] = float(i[(x, machine)])
137 | print(f"{i[(x, machine)]}\t{t[name][x]}\t{round(t[name][x] - i[(x, machine)], 2)}", end='\t')
138 | # print(f"{round(t[name][x] - i[(x, machine)], 2)}", end='\t')
139 | print(t[name]['waiting_time'], end='\t')
140 | print()
141 |
142 |
143 | if __name__ == '__main__':
144 | main()
145 |
--------------------------------------------------------------------------------
/simulation/plugins/wandb_plugin.py:
--------------------------------------------------------------------------------
1 | import statistics
2 | import time
3 | from collections import defaultdict
4 | from typing import List
5 |
6 | from simulation.classes import Machine, Lot
7 | from simulation.plugins.interface import IPlugin
8 |
9 | import wandb
10 |
11 | WANDB_LOG_INTERVAL = 5000
12 |
13 |
14 | def meanor0(li):
15 | if len(li) > 0:
16 | return statistics.mean(li)
17 | else:
18 | return 0
19 |
20 |
21 | class WandBPlugin(IPlugin):
22 | def on_sim_init(self, instance):
23 | wandb.init()
24 | self.wandb_start = time.time()
25 | self.wandb_machine_free_count = []
26 | self.wandb_machine_usable_count = []
27 | self.wandb_steps_performed = 0
28 | self.wandb_lots_already_done = 0
29 | self.wandb_time_done = 0
30 | self.wandb_initial_waiting_lots = len(instance.dispatchable_lots)
31 | self.wandb_batch_util = []
32 | self.wandb_step_count = 0
33 |
34 | self.wandb_last_setup = defaultdict(lambda: None)
35 | self.wandb_same_setup_count = defaultdict(lambda: 0)
36 | self.wandb_avg_steps_after_setup = [0]
37 | self.wandb_avg_steps_after_setup_1 = [0]
38 | self.wandb_avg_steps_after_setup_2 = [0]
39 | self.wandb_resetups = 0
40 | self.wandb_setup_machines = set()
41 | self.wandb_cqt_violations = 0
42 |
43 | def on_sim_done(self, instance):
44 | self.step(instance, force=True)
45 | columns = ['lot name', 'in progress', 'completed', 'completed on time', 'on time percent', 'average cycle time',
46 | 'theoretical processing time']
47 |
48 | groups = defaultdict(lambda: defaultdict(lambda: 0))
49 | for lot in instance.active_lots:
50 | groups[lot.name]['in progress'] += 1
51 | for lot in instance.done_lots:
52 | groups[lot.name]['completed'] += 1
53 | if lot.done_at <= lot.deadline_at:
54 | groups[lot.name]['completed on time'] += 1
55 | groups[lot.name]['on time percent'] = round(
56 | groups[lot.name]['completed on time'] / groups[lot.name]['completed'] * 100, 2)
57 | groups[lot.name]['act_sum'] += lot.done_at - lot.release_at
58 | groups[lot.name]['average cycle time'] = round(
59 | groups[lot.name]['act_sum'] / groups[lot.name]['completed'] / 3600 / 24, 2)
60 | groups[lot.name]['theoretical processing time'] = round(lot.full_time / 3600 / 24, 2)
61 |
62 | rows = []
63 | for k, v in groups.items():
64 | r = [k]
65 | for c in columns[1:]:
66 | r.append(v[c])
67 | rows.append(r)
68 | rows.sort(key=lambda k: k[0])
69 |
70 | html = '' + \
71 | ''.join([f'| {c} | ' for c in columns]) + \
72 | '
' + \
73 | ''.join(['' + ''.join([f'| {c} | ' for c in row]) + '
' for row in rows]) + \
74 | '
'
75 | wandb.log({
76 | 'lot_stats': wandb.Html(html)
77 | })
78 | wandb.finish()
79 |
80 | def on_dispatch(self, instance, machine, lots, machine_end_time, lot_end_time):
81 | machine: Machine
82 | lots: List[Lot]
83 | s = lots[0].actual_step.setup_needed
84 | if s not in [None, '']:
85 | if machine.last_setup != machine.current_setup:
86 | self.wandb_setup_machines.add(machine.idx)
87 | self.wandb_resetups += 1
88 | if self.wandb_same_setup_count[machine.idx] != 0:
89 | self.wandb_avg_steps_after_setup.append(self.wandb_same_setup_count[machine.idx])
90 | if machine.has_min_runs:
91 | self.wandb_avg_steps_after_setup_2.append(self.wandb_same_setup_count[machine.idx])
92 | else:
93 | self.wandb_avg_steps_after_setup_1.append(self.wandb_same_setup_count[machine.idx])
94 | self.wandb_same_setup_count[machine.idx] = 1
95 | else:
96 | self.wandb_same_setup_count[machine.idx] += 1
97 | self.wandb_last_setup[machine.idx] = s
98 | self.wandb_step_count += 1
99 | self.wandb_machine_free_count.append(sum(instance.free_machines))
100 | self.wandb_machine_usable_count.append(len(instance.usable_machines))
101 | self.wandb_steps_performed += len(lots)
102 | if lots[0].actual_step.batch_max > 1:
103 | self.wandb_batch_util.append(len(lots) / lots[0].actual_step.batch_max)
104 | self.step(instance)
105 |
106 | def step(self, instance, force=False):
107 | if self.wandb_step_count % WANDB_LOG_INTERVAL == 0 or force:
108 | now_done = len(instance.done_lots) - self.wandb_lots_already_done
109 | elapsed_time = instance.current_time_days - self.wandb_time_done
110 | wandb.log({
111 | 'lots/wip': len(instance.active_lots),
112 | 'lots/done': len(instance.done_lots),
113 | 'machines/free': meanor0(self.wandb_machine_free_count),
114 | 'machines/free_with_lots_waiting': meanor0(self.wandb_machine_usable_count),
115 | 'lots/steps_performed': self.wandb_steps_performed,
116 | 'lots/now_done': now_done,
117 | 'sim/simulated_time_seconds': instance.current_time,
118 | 'sim/simulated_time_days': instance.current_time_days,
119 | 'sim/running_time_minutes': (time.time() - self.wandb_start) / 60,
120 | 'sim/running_time_hours': (time.time() - self.wandb_start) / 3600,
121 | 'sim/speed': instance.current_time / (time.time() - self.wandb_start),
122 | 'lots/throughput_per_day': now_done / elapsed_time,
123 | 'lots/released': self.wandb_initial_waiting_lots - len(instance.dispatchable_lots),
124 | 'machines/batch_util': meanor0(self.wandb_batch_util),
125 | 'machines/setups_executed': self.wandb_resetups / max(1, len(self.wandb_setup_machines)),
126 | 'machines/avg_run_per_setup': statistics.mean(self.wandb_avg_steps_after_setup),
127 | 'machines/avg_run_per_setup_for_enforced': statistics.mean(self.wandb_avg_steps_after_setup_2),
128 | 'machines/avg_run_per_setup_NOT_enforced': statistics.mean(self.wandb_avg_steps_after_setup_1),
129 | 'lots/done_in_time': len([l for l in instance.done_lots if l.done_at <= l.deadline_at]),
130 | 'lots/done_late': len([l for l in instance.done_lots if l.done_at > l.deadline_at]),
131 | 'lots/cqt_violations': self.wandb_cqt_violations,
132 | })
133 | self.wandb_lots_already_done = len(instance.done_lots)
134 | self.wandb_machine_free_count.clear()
135 | self.wandb_machine_usable_count.clear()
136 | self.wandb_batch_util.clear()
137 | self.wandb_steps_performed = 0
138 | self.wandb_time_done = instance.current_time_days
139 |
140 | def on_cqt_violated(self, instance, machine, lot):
141 | super().on_cqt_violated(instance, machine, lot)
142 | self.wandb_cqt_violations += 1
143 |
144 |
--------------------------------------------------------------------------------
/simulation/greedy.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | from collections import defaultdict
4 | from datetime import datetime
5 | from typing import List
6 |
7 | from simulation.classes import Lot, Machine
8 | from simulation.dispatching.dispatcher import dispatcher_map
9 | from simulation.file_instance import FileInstance
10 | from simulation.plugins.cost_plugin import CostPlugin
11 | from simulation.randomizer import Randomizer
12 | from simulation.read import read_all
13 | from simulation.stats import print_statistics
14 |
15 | import argparse
16 |
17 | last_sort_time = -1
18 |
19 |
20 | def dispatching_combined_permachine(ptuple_fcn, machine, time, setups):
21 | for lot in machine.waiting_lots:
22 | lot.ptuple = ptuple_fcn(lot, time, machine, setups)
23 |
24 |
25 | def get_lots_to_dispatch_by_machine(instance, ptuple_fcn, machine=None):
26 | time = instance.current_time
27 | if machine is None:
28 | for machine in instance.usable_machines:
29 | break
30 | dispatching_combined_permachine(ptuple_fcn, machine, time, instance.setups)
31 | wl = sorted(machine.waiting_lots, key=lambda k: k.ptuple)
32 | # select lots to dispatch
33 | lot = wl[0]
34 | if lot.actual_step.batch_max > 1:
35 | # construct batch
36 | lot_m = defaultdict(lambda: [])
37 | for w in wl:
38 | lot_m[w.actual_step.step_name].append(w) # + '_' + w.part_name
39 | lot_l = sorted(list(lot_m.values()),
40 | key=lambda l: (
41 | l[0].ptuple[0], # cqt
42 | l[0].ptuple[1], # min run setup is the most important
43 | -min(1, len(l) / l[0].actual_step.batch_max), # then maximize the batch size
44 | 0 if len(l) >= l[0].actual_step.batch_min else 1, # then take min batch size into account
45 | *(l[0].ptuple[2:]), # finally, order based on prescribed priority rule
46 | ))
47 | lots: List[Lot] = lot_l[0]
48 | if len(lots) > lots[0].actual_step.batch_max:
49 | lots = lots[:lots[0].actual_step.batch_max]
50 | if len(lots) < lots[0].actual_step.batch_max:
51 | lots = None
52 | else:
53 | # dispatch single lot
54 | lots = [lot]
55 | if lots is not None and machine.current_setup != lots[0].actual_step.setup_needed:
56 | m: Machine
57 | for m in instance.family_machines[machine.family]:
58 | if m in instance.usable_machines and m.current_setup == lots[0].actual_step.setup_needed: # TODO: check instance.free_machines[m.idx] bug
59 | machine = m
60 | break
61 | if machine.dispatch_failed < 5 and machine.min_runs_left is not None and machine.min_runs_setup != lots[0].actual_step.setup_needed:
62 | machine.dispatch_failed += 1
63 | lots = None
64 | if lots is not None:
65 | machine.dispatch_failed = 0
66 | return machine, lots
67 |
68 |
69 | def build_batch(lot, nexts):
70 | batch = [lot]
71 | if lot.actual_step.batch_max > 1:
72 | for bo_lot in nexts:
73 | if lot.actual_step.step_name == bo_lot.actual_step.step_name:
74 | batch.append(bo_lot)
75 | if len(batch) == lot.actual_step.batch_max:
76 | break
77 | return batch
78 |
79 |
80 | def get_lots_to_dispatch_by_lot(instance, current_time, dispatcher):
81 | global last_sort_time
82 | if last_sort_time != current_time:
83 | for lot in instance.usable_lots:
84 | lot.ptuple = dispatcher(lot, current_time, None)
85 | last_sort_time = current_time
86 | instance.usable_lots.sort(key=lambda k: k.ptuple)
87 | lots = instance.usable_lots
88 | setup_machine, setup_batch = None, None
89 | min_run_break_machine, min_run_break_batch = None, None
90 | family_lock = None
91 | for i in range(len(lots)):
92 | lot: Lot = lots[i]
93 | if family_lock is None or family_lock == lot.actual_step.family:
94 | family_lock = lot.actual_step.family
95 | assert len(lot.waiting_machines) > 0
96 | for machine in lot.waiting_machines:
97 | if lot.actual_step.setup_needed == '' or lot.actual_step.setup_needed == machine.current_setup:
98 | return machine, build_batch(lot, lots[i + 1:])
99 | else:
100 | if setup_machine is None and machine.min_runs_left is None:
101 | setup_machine = machine
102 | setup_batch = i
103 | if min_run_break_machine is None:
104 | min_run_break_machine = machine
105 | min_run_break_batch = i
106 | if setup_machine is not None:
107 | return setup_machine, build_batch(lots[setup_batch], lots[setup_batch + 1:])
108 | return min_run_break_machine, build_batch(lots[min_run_break_batch], lots[min_run_break_batch + 1:])
109 |
110 |
111 | def run_greedy():
112 | p = argparse.ArgumentParser()
113 | p.add_argument('--dataset', type=str)
114 | p.add_argument('--days', type=int)
115 | p.add_argument('--dispatcher', type=str)
116 | p.add_argument('--seed', type=int)
117 | p.add_argument('--wandb', action='store_true', default=False)
118 | p.add_argument('--chart', action='store_true', default=False)
119 | p.add_argument('--alg', type=str, default='l4m', choices=['l4m', 'm4l'])
120 | a = p.parse_args()
121 |
122 | sys.stderr.write('Loading ' + a.dataset + ' for ' + str(a.days) + ' days, using ' + a.dispatcher + '\n')
123 | sys.stderr.flush()
124 |
125 | start_time = datetime.now()
126 |
127 | files = read_all('datasets/' + a.dataset)
128 |
129 | run_to = 3600 * 24 * a.days
130 | Randomizer().random.seed(a.seed)
131 | l4m = a.alg == 'l4m'
132 | plugins = []
133 | if a.wandb:
134 | from simulation.plugins.wandb_plugin import WandBPlugin
135 | plugins.append(WandBPlugin())
136 | if a.chart:
137 | from simulation.plugins.chart_plugin import ChartPlugin
138 | plugins.append(ChartPlugin())
139 | plugins.append(CostPlugin())
140 | instance = FileInstance(files, run_to, l4m, plugins)
141 |
142 | dispatcher = dispatcher_map[a.dispatcher]
143 |
144 | sys.stderr.write('Starting simulation with dispatching rule\n\n')
145 | sys.stderr.flush()
146 |
147 | while not instance.done:
148 | done = instance.next_decision_point()
149 | instance.print_progress_in_days()
150 | if done or instance.current_time > run_to:
151 | break
152 |
153 | if l4m:
154 | machine, lots = get_lots_to_dispatch_by_machine(instance, dispatcher)
155 | if lots is None:
156 | instance.usable_machines.remove(machine)
157 | else:
158 | instance.dispatch(machine, lots)
159 | else:
160 | machine, lots = get_lots_to_dispatch_by_lot(instance, instance.current_time, dispatcher)
161 | if lots is None:
162 | instance.usable_lots.clear()
163 | instance.lot_in_usable.clear()
164 | instance.next_step()
165 | else:
166 | instance.dispatch(machine, lots)
167 |
168 | instance.finalize()
169 | interval = datetime.now() - start_time
170 | print(instance.current_time_days, ' days simulated in ', interval)
171 | print_statistics(instance, a.days, a.dataset, a.dispatcher, method='greedy_seed' + str(a.seed))
172 |
--------------------------------------------------------------------------------
/simulation/classes.py:
--------------------------------------------------------------------------------
1 | from typing import List, Dict
2 |
3 | from simulation.events import BreakdownEvent
4 | from simulation.randomizer import Randomizer
5 | from simulation.tools import get_interval, get_distribution, date_time_parse, ConstantDistribution
6 |
7 | r = Randomizer()
8 |
9 | machine_classes = {}
10 |
11 |
12 | def alt(d, a1, a2):
13 | return d[a1] if a1 in d else (d[a2] if a2 is not None else None)
14 |
15 |
16 | def default(d, a1, de):
17 | return d[a1] if a1 in d else de
18 |
19 |
20 | def none_is_0(v):
21 | return 0 if v is None else v
22 |
23 |
24 | class Machine:
25 |
26 | def __init__(self, idx, d, speed):
27 | self.idx = idx
28 | self.load_time = none_is_0(get_interval(d['LTIME'], d['LTUNITS']))
29 | self.unload_time = none_is_0(get_interval(d['ULTIME'], d['ULTUNITS']))
30 | self.group = d['STNGRP']
31 | if self.group not in machine_classes:
32 | machine_classes[self.group] = len(machine_classes)
33 | self.machine_class = machine_classes[self.group]
34 | self.loc = d['STNFAMLOC']
35 | self.family = d['STNFAM']
36 | self.cascading = True if type(d['STNCAP']) in [int, float] and int(d['STNCAP']) == 2 else False
37 | self.speed = speed
38 | self.minimize_setup_time = d['WAKERESRANK'] == 'wake_LeastSetupTime'
39 |
40 | self.available_from = None
41 | self.available_to = None
42 |
43 | self.piece_per_maintenance = []
44 | self.pieces_until_maintenance = []
45 | self.maintenance_time = []
46 |
47 | self.waiting_lots: List[Lot] = []
48 |
49 | self.utilized_time = 0
50 | self.setuped_time = 0
51 | self.pmed_time = 0
52 | self.bred_time = 0
53 |
54 | self.current_setup = ''
55 |
56 | self.events = []
57 | self.min_runs_left = None
58 | self.min_runs_setup = None
59 |
60 | # RL state space features
61 | self.pms: List[BreakdownEvent] = []
62 | self.last_actions = 4 * [999]
63 |
64 | self.last_setup_time = 0
65 | self.dispatch_failed = 0
66 |
67 | self.has_min_runs = False
68 |
69 | self.next_preventive_maintenance = None
70 |
71 | def __hash__(self):
72 | return self.idx
73 |
74 | def __repr__(self):
75 | return f'Machine {self.idx}'
76 |
77 |
78 | class Product:
79 | def __init__(self, route, priority):
80 | self.route = route
81 | self.priority = priority
82 |
83 |
84 | class Step:
85 |
86 | def __init__(self, idx, pieces_per_lot, d):
87 | self.idx = idx
88 | self.order = d['STEP']
89 | self.step_name = d['DESC']
90 | self.family = d['STNFAM']
91 | self.setup_needed = d['SETUP']
92 | self.setup_time = get_interval(d['STIME'], d['STUNITS']) if type(d['STIME']) is int else None
93 | self.rework_step = d['RWKSTEP']
94 | assert len(self.family) > 0
95 | self.cascading = False
96 | if type(d['PartInterval']) in [float, int]:
97 | assert d['PTPER'] == 'per_piece'
98 | per_piece = get_interval(d['PartInterval'], d['PartIntUnits'])
99 | self.processing_time = get_distribution(d['PDIST'], d['PTUNITS'], d['PTIME'], d['PTIME2'])
100 | self.processing_time.m += per_piece * (pieces_per_lot - 1)
101 | self.cascading_time = ConstantDistribution(per_piece * pieces_per_lot)
102 | self.cascading = True
103 | else:
104 | if d['PTPER'] == 'per_piece':
105 | m = pieces_per_lot
106 | else:
107 | m = 1
108 | self.processing_time = get_distribution(default(d, 'PDIST', 'constant'), d['PTUNITS'], d['PTIME'],
109 | d['PTIME2'], multiplier=m)
110 | if type(d['BatchInterval']) in [float, int]:
111 | self.cascading_time = get_distribution('constant', d['BatchIntUnits'], d['BatchInterval'])
112 | self.cascading = True
113 | else:
114 | self.cascading_time = self.processing_time
115 | self.batching = d['PTPER'] == 'per_batch'
116 | self.batch_min = 1 if d['BATCHMN'] == '' else int(d['BATCHMN'] / pieces_per_lot)
117 | self.batch_max = 1 if d['BATCHMX'] == '' else int(d['BATCHMX'] / pieces_per_lot)
118 | self.sampling_percent = 100 if d['StepPercent'] in ['', None] else float(d['StepPercent'])
119 | self.rework_percent = 0 if d['REWORK'] in ['', None] else float(d['REWORK'])
120 |
121 | self.cqt_for_step = d['STEP_CQT'] if 'STEP_CQT' in d else None
122 | self.cqt_time = get_interval(d['CQT'], d['CQTUNITS']) if self.cqt_for_step is not None else None
123 |
124 | self.lot_to_lens_dedication = d['FORSTEP'] if d['SVESTN'] == 'yes' else None
125 |
126 | self.family_location = ''
127 | self.transport_time = ConstantDistribution(0)
128 |
129 | self.reworked = {}
130 |
131 | def has_to_perform(self):
132 | if self.sampling_percent == 100:
133 | return True
134 | return r.random.uniform(0, 100) <= self.sampling_percent
135 |
136 | def has_to_rework(self, lot_id):
137 | if self.rework_percent == 0 or lot_id in self.reworked:
138 | return False
139 | self.reworked[lot_id] = True
140 | return r.random.uniform(0, 100) <= self.rework_percent
141 |
142 |
143 | class Lot:
144 | def __init__(self, idx, route, priority, release, relative_deadline, d):
145 | self.idx = idx
146 | self.remaining_steps = [step for step in route.steps]
147 | self.actual_step: Step = None
148 | self.processed_steps = []
149 | self.priority = priority
150 | self.release_at = release
151 | self.deadline_at = self.release_at + relative_deadline
152 | self.name: str = d['LOT']
153 | self.part_name: str = d['PART']
154 | if 'Init_' in self.name:
155 | self.name = self.name[self.name.index('_') + 1:self.name.rindex('_')]
156 |
157 | if 'CURSTEP' in d:
158 | cs = d['CURSTEP']
159 | self.processed_steps, self.remaining_steps = self.remaining_steps[:cs - 1], self.remaining_steps[cs - 1:]
160 |
161 | self.pieces = d['PIECES']
162 |
163 | self.waiting_machines = []
164 |
165 | self.done_at = None
166 | self.free_since = None
167 |
168 | self.remaining_steps_last = -1
169 | self.remaining_time_last = 0
170 |
171 | self.dedications = {}
172 |
173 | self.waiting_time = 0
174 | self.waiting_time_batching = 0
175 | self.processing_time = 0
176 | self.transport_time = 0
177 |
178 | self.cqt_waiting = None
179 | self.cqt_deadline = None
180 |
181 | self.ft = None
182 |
183 | def __hash__(self):
184 | return self.idx
185 |
186 | def __repr__(self):
187 | return f'Lot {self.idx}'
188 |
189 | def cr(self, time):
190 | rt = self.remaining_time
191 | return (self.deadline_at - time) / rt if rt > 0 else 1
192 |
193 | @property
194 | def full_time(self):
195 | if self.ft is None:
196 | self.ft = sum(
197 | [s.processing_time.avg() for s in self.processed_steps +
198 | ([self.actual_step] if self.actual_step is not None else []) + self.remaining_steps])
199 | return self.ft
200 |
201 | @property
202 | def remaining_time(self):
203 | if self.remaining_steps_last != len(self.remaining_steps):
204 | if self.remaining_steps_last - 1 == len(self.remaining_steps):
205 | self.remaining_time_last -= self.processed_steps[-1].processing_time.avg()
206 | else:
207 | self.remaining_time_last = sum(
208 | [s.processing_time.avg() for s in self.remaining_steps]) + self.actual_step.processing_time.avg()
209 | self.remaining_steps_last = len(self.remaining_steps)
210 | return self.remaining_time_last
211 |
212 |
213 | class Route:
214 |
215 | def __init__(self, idx, steps: List[Step]):
216 | self.idx = idx
217 | self.steps = steps
218 |
219 |
220 | class FileRoute(Route):
221 |
222 | def __init__(self, idx, pieces_per_lot, steps: List[Dict]):
223 | steps = [Step(i, pieces_per_lot, d) for i, d in enumerate(steps)]
224 | super().__init__(idx, steps)
225 |
--------------------------------------------------------------------------------
/simulation/gym/environment.py:
--------------------------------------------------------------------------------
1 | import statistics
2 | from collections import defaultdict
3 | from typing import List
4 |
5 | import gym
6 | from gym import Env
7 |
8 | from simulation.classes import Machine, Lot
9 | from simulation.file_instance import FileInstance
10 | from simulation.greedy import get_lots_to_dispatch_by_machine
11 | from simulation.dispatching.dispatcher import Dispatchers, dispatcher_map
12 | from simulation.gym.E import E
13 | from simulation.randomizer import Randomizer
14 | from simulation.read import read_all
15 |
16 | r = Randomizer()
17 |
18 | STATE_COMPONENTS_DEMO = (
19 | E.A.L4M.S.OPERATION_TYPE.NO_LOTS_PER_BATCH,
20 | E.A.L4M.S.OPERATION_TYPE.CR.MAX,
21 | E.A.L4M.S.OPERATION_TYPE.FREE_SINCE.MAX,
22 | E.A.L4M.S.OPERATION_TYPE.SETUP.MIN_RUNS_OK,
23 | E.A.L4M.S.OPERATION_TYPE.SETUP.NEEDED,
24 | E.A.L4M.S.OPERATION_TYPE.SETUP.LAST_SETUP_TIME,
25 | )
26 |
27 |
28 | class DynamicSCFabSimulationEnvironment(Env):
29 |
30 | def __init__(self, num_actions, active_station_group, days, dataset, dispatcher, seed, max_steps,
31 | reward_type, action, state_components):
32 | self.did_reset = False
33 | self.files = read_all('datasets/' + dataset)
34 | self.instance = None
35 | self.num_actions = num_actions
36 | self.days = days
37 | self.action_space = gym.spaces.Discrete(num_actions)
38 | self.action = action
39 | self.observation_space = gym.spaces.Box(low=-100, high=1000000,
40 | shape=(4 + num_actions * len(state_components),))
41 | self._state = None
42 | self.station_group = active_station_group
43 | self.lots_done = 0
44 | self.seed_val = seed
45 | self.dispatcher = dispatcher_map[dispatcher]
46 | self.max_steps = max_steps
47 | self.reward_type = reward_type
48 | self.mavg = 0
49 | self.state_components = state_components
50 | self.reset()
51 |
52 | def seed(self, seed=None):
53 | if seed is None:
54 | seed = 0
55 | self.seed_val = seed
56 | self.reset()
57 |
58 | def step(self, action):
59 | self.did_reset = False
60 | self.actual_step += 1
61 | # apply_priority_rule(self._machine)
62 | waiting_lots = self._machine.actions
63 | lot_index = action
64 | if lot_index < len(waiting_lots) and waiting_lots[lot_index] is not None:
65 | lot_group = waiting_lots[lot_index]
66 | lot = lot_group[0]
67 | lots = lot_group[:min(len(lot_group), lot.actual_step.batch_max)]
68 | violated_minruns = self._machine.min_runs_left is not None and self._machine.min_runs_setup == lot.actual_step.setup_needed
69 | self.instance.dispatch(self._machine, lots)
70 | done = self.next_step() or self.max_steps < self.actual_step
71 | reward = 0
72 | if self.reward_type in [1, 2]:
73 | for i in range(self.lots_done, len(self.instance.done_lots)):
74 | lot = self.instance.done_lots[i]
75 | reward += 1000
76 | if self.reward_type == 2:
77 | reward += 1000 if lot.deadline_at >= lot.done_at else 0
78 | else:
79 | reward += 1000 if lot.deadline_at >= lot.done_at else -min(500, (
80 | lot.done_at - lot.deadline_at) / 3600)
81 | elif self.reward_type == 3:
82 | reward += statistics.mean(
83 | [min(1, j.cr(self.instance.current_time) - 1) for j in self.instance.active_lots])
84 | elif self.reward_type == 7:
85 | reward += statistics.mean(
86 | [l.notlateness(self.instance.current_time) for l in self.instance.active_lots])
87 | else:
88 | pass
89 | if violated_minruns:
90 | reward += -10
91 | self.lots_done = len(self.instance.done_lots)
92 | return self.state, reward, done, {}
93 | else:
94 | return self.state, -100, self.max_steps < self.actual_step, {}
95 |
96 | def reset(self):
97 | if not self.did_reset:
98 | self.did_reset = True
99 | self.actual_step = 0
100 | self.lots_done = 0
101 | run_to = 3600 * 24 * self.days
102 | self.instance = FileInstance(self.files, run_to, True, [])
103 | Randomizer().random.seed(self.seed_val)
104 | self.seed_val += 1
105 | self.next_step()
106 | return self.state
107 |
108 | def next_step(self):
109 | found = False
110 | while not found:
111 | done = self.instance.next_decision_point()
112 | if done or self.instance.current_time > 3600 * 24 * self.days:
113 | return True
114 | for machine in self.instance.usable_machines:
115 | break
116 | if self.station_group is None or \
117 | f'[{machine.group}]' in self.station_group or \
118 | f'<{machine.family}>' in self.station_group:
119 | found = True
120 | else:
121 | machine, lots = get_lots_to_dispatch_by_machine(self.instance, machine=machine,
122 | ptuple_fcn=self.dispatcher)
123 | if lots is None:
124 | self.instance.usable_machines.remove(machine)
125 | else:
126 | self.instance.dispatch(machine, lots)
127 |
128 | self._machine = machine
129 | actions = defaultdict(lambda: [])
130 | for lot in machine.waiting_lots:
131 | actions[lot.actual_step.step_name].append(lot)
132 | self.mavg = self.mavg * 0.99 + len(actions) * 0.01
133 | if len(actions) > self.num_actions:
134 | self._machine.actions = r.random.sample(list(actions.values()), self.num_actions)
135 | else:
136 | self._machine.actions = list(actions.values())
137 | while len(self._machine.actions) < self.num_actions:
138 | self._machine.actions.append(None)
139 | r.random.shuffle(self._machine.actions)
140 | self._state = None
141 | return False
142 |
143 | @property
144 | def state(self):
145 | if self._state is None:
146 | m: Machine = self._machine
147 | t = self.instance.current_time
148 | self._state = [
149 | m.pms[0].timestamp - t if len(m.pms) > 0 else 999999, # next maintenance
150 | m.utilized_time / m.setuped_time if m.setuped_time > 0 else 0, # ratio of setup time / processing time
151 | (m.setuped_time + m.utilized_time) / t if t > 0 else 0, # ratio of non idle time
152 | m.machine_class, # type of machine
153 | ]
154 | from statistics import mean, median
155 | for action in self._machine.actions:
156 | if action is None:
157 | self._state += [-1000] * len(self.state_components)
158 | else:
159 | action: List[Lot]
160 | free_since = [self.instance.current_time - l.free_since for l in action]
161 | work_rem = [len(l.remaining_steps) for l in action]
162 | cr = [l.cr(self.instance.current_time) for l in action]
163 | priority = [l.priority for l in action]
164 | l0 = action[0]
165 |
166 | self._machine: Machine
167 | action_type_state_lambdas = {
168 | E.A.L4M.S.OPERATION_TYPE.NO_LOTS: lambda: len(action),
169 | E.A.L4M.S.OPERATION_TYPE.NO_LOTS_PER_BATCH: lambda: len(action) / l0.actual_step.batch_max,
170 | E.A.L4M.S.OPERATION_TYPE.STEPS_LEFT.MEAN: lambda: mean(work_rem),
171 | E.A.L4M.S.OPERATION_TYPE.STEPS_LEFT.MEDIAN: lambda: median(work_rem),
172 | E.A.L4M.S.OPERATION_TYPE.STEPS_LEFT.MAX: lambda: max(work_rem),
173 | E.A.L4M.S.OPERATION_TYPE.STEPS_LEFT.MIN: lambda: min(work_rem),
174 | E.A.L4M.S.OPERATION_TYPE.FREE_SINCE.MEAN: lambda: mean(free_since),
175 | E.A.L4M.S.OPERATION_TYPE.FREE_SINCE.MEDIAN: lambda: median(free_since),
176 | E.A.L4M.S.OPERATION_TYPE.FREE_SINCE.MAX: lambda: max(free_since),
177 | E.A.L4M.S.OPERATION_TYPE.FREE_SINCE.MIN: lambda: min(free_since),
178 | E.A.L4M.S.OPERATION_TYPE.PROCESSING_TIME.AVERAGE: lambda: l0.actual_step.processing_time.avg(),
179 | E.A.L4M.S.OPERATION_TYPE.BATCH.MIN: lambda: l0.actual_step.batch_min,
180 | E.A.L4M.S.OPERATION_TYPE.BATCH.MAX: lambda: l0.actual_step.batch_max,
181 | E.A.L4M.S.OPERATION_TYPE.BATCH.FULLNESS: lambda: min(1, len(action) / l0.actual_step.batch_max),
182 | E.A.L4M.S.OPERATION_TYPE.PRIORITY.MEAN: lambda: mean(priority),
183 | E.A.L4M.S.OPERATION_TYPE.PRIORITY.MEDIAN: lambda: median(priority),
184 | E.A.L4M.S.OPERATION_TYPE.PRIORITY.MAX: lambda: max(priority),
185 | E.A.L4M.S.OPERATION_TYPE.PRIORITY.MIN: lambda: min(priority),
186 | E.A.L4M.S.OPERATION_TYPE.CR.MEAN: lambda: mean(cr),
187 | E.A.L4M.S.OPERATION_TYPE.CR.MEDIAN: lambda: median(cr),
188 | E.A.L4M.S.OPERATION_TYPE.CR.MAX: lambda: max(cr),
189 | E.A.L4M.S.OPERATION_TYPE.CR.MIN: lambda: min(cr),
190 | E.A.L4M.S.OPERATION_TYPE.SETUP.NEEDED: lambda: 0 if l0.actual_step.setup_needed == '' or l0.actual_step.setup_needed == m.current_setup else 1,
191 | E.A.L4M.S.OPERATION_TYPE.SETUP.MIN_RUNS_LEFT: lambda: 0 if self._machine.min_runs_left is None else self._machine.min_runs_left,
192 | E.A.L4M.S.OPERATION_TYPE.SETUP.MIN_RUNS_OK: lambda: 1 if l0.actual_step.setup_needed == '' or l0.actual_step.setup_needed == self._machine.min_runs_setup else 0,
193 | E.A.L4M.S.OPERATION_TYPE.SETUP.LAST_SETUP_TIME: lambda: self._machine.last_setup_time,
194 | E.A.L4M.S.MACHINE.MAINTENANCE.NEXT: lambda: 0,
195 | E.A.L4M.S.MACHINE.IDLE_RATIO: lambda: 1 - (
196 | self._machine.utilized_time / self.instance.current_time) if self._machine.utilized_time > 0 else 1,
197 | E.A.L4M.S.MACHINE.SETUP_PROCESSING_RATIO: lambda: (
198 | self._machine.setuped_time / self._machine.utilized_time) if self._machine.utilized_time > 0 else 1,
199 | E.A.L4M.S.MACHINE.MACHINE_CLASS: lambda: 0,
200 | }
201 | self._state += [
202 | action_type_state_lambdas[s]()
203 | for s in self.state_components
204 | ]
205 | return self._state
206 |
207 | def render(self, mode="human"):
208 | pass
209 |
--------------------------------------------------------------------------------
/simulation/instance.py:
--------------------------------------------------------------------------------
1 | from collections import defaultdict
2 | from typing import Dict, List, Set, Tuple
3 |
4 | from simulation.classes import Machine, Route, Lot
5 | from simulation.dispatching.dm_lot_for_machine import LotForMachineDispatchManager
6 | from simulation.dispatching.dm_machine_for_lot import MachineForLotDispatchManager
7 | from simulation.event_queue import EventQueue
8 | from simulation.events import MachineDoneEvent, LotDoneEvent, BreakdownEvent, ReleaseEvent
9 | from simulation.plugins.interface import IPlugin
10 |
11 |
12 | class Instance:
13 |
14 | def __init__(self, machines: List[Machine], routes: Dict[str, Route], lots: List[Lot],
15 | setups: Dict[Tuple, int], setup_min_run: Dict[str, int], breakdowns: List[BreakdownEvent],
16 | lot_for_machine, plugins):
17 | self.plugins: List[IPlugin] = plugins
18 | self.lot_waiting_at_machine = defaultdict(lambda: (0, 0))
19 |
20 | self.free_machines: List[bool] = []
21 | self.usable_machines: Set[Machine] = set()
22 | self.usable_lots: List[Lot] = list()
23 |
24 | self.machines: List[Machine] = [m for m in machines]
25 | self.family_machines = defaultdict(lambda: [])
26 | for m in self.machines:
27 | self.family_machines[m.family].append(m)
28 | self.routes: Dict[str, Route] = routes
29 | self.setups: Dict[Tuple, int] = setups
30 | self.setup_min_run: Dict[str, int] = setup_min_run
31 |
32 | self.dm = LotForMachineDispatchManager() if lot_for_machine else MachineForLotDispatchManager()
33 | self.dm.init(self)
34 |
35 | self.dispatchable_lots: List[Lot] = lots
36 | self.dispatchable_lots.sort(key=lambda k: k.release_at)
37 | self.active_lots: List[Lot] = []
38 | self.done_lots: List[Lot] = []
39 |
40 | self.events = EventQueue()
41 |
42 | self.current_time = 0
43 |
44 | for plugin in self.plugins:
45 | plugin.on_sim_init(self)
46 |
47 | self.next_step()
48 |
49 | self.free_up_machines(self.machines)
50 |
51 | for br in breakdowns:
52 | self.add_event(br)
53 |
54 | self.printed_days = -1
55 |
56 | @property
57 | def current_time_days(self):
58 | return self.current_time / 3600 / 24
59 |
60 | def next_step(self):
61 | process_until = []
62 | if len(self.events.arr) > 0:
63 | process_until.append(max(0, self.events.first.timestamp))
64 | process_until.append(max(0, self.dispatchable_lots[0].release_at))
65 | process_until = min(process_until)
66 | while len(self.events.arr) > 0 and self.events.first.timestamp <= process_until:
67 | ev = self.events.pop_first()
68 | self.current_time = max(0, ev.timestamp, self.current_time)
69 | # print(f'Time stamp {self.current_time}')
70 | ev.handle(self)
71 | ReleaseEvent.handle(self, process_until)
72 |
73 | def free_up_machines(self, machines):
74 | # add machine to list of available machines
75 | for machine in machines:
76 | machine.events.clear()
77 | self.dm.free_up_machine(self, machine)
78 |
79 | for plugin in self.plugins:
80 | plugin.on_machine_free(self, machine)
81 |
82 | def free_up_lots(self, lots: List[Lot]):
83 | # add lot to lists, make it available
84 | for lot in lots:
85 | lot.free_since = self.current_time
86 | step_found = False
87 | while len(lot.remaining_steps) > 0:
88 | old_step = None
89 | if lot.actual_step is not None:
90 | lot.processed_steps.append(lot.actual_step)
91 | old_step = lot.actual_step
92 | if lot.actual_step is not None and lot.actual_step.has_to_rework(lot.idx):
93 | rw_step = lot.actual_step.rework_step
94 | removed = lot.processed_steps[rw_step - 1:]
95 | lot.processed_steps = lot.processed_steps[:rw_step - 1]
96 | lot.remaining_steps = removed + lot.remaining_steps
97 | lot.actual_step, lot.remaining_steps = lot.remaining_steps[0], lot.remaining_steps[1:]
98 | if lot.actual_step.has_to_perform():
99 | # print(f'Lot {lot.idx} step {len(lot.processed_steps)} / {len(lot.remaining_steps)}')
100 | self.dm.free_up_lots(self, lot)
101 | step_found = True
102 | for plugin in self.plugins:
103 | plugin.on_step_done(self, lot, old_step)
104 | break
105 | if not step_found:
106 | assert len(lot.remaining_steps) == 0
107 | lot.actual_step = None
108 | lot.done_at = self.current_time
109 | # print(f'Lot {lot.idx} is done {len(self.active_lots)} {len(self.done_lots)} {self.current_time_days}')
110 | self.active_lots.remove(lot)
111 | self.done_lots.append(lot)
112 | for plugin in self.plugins:
113 | plugin.on_lot_done(self, lot)
114 |
115 | for plugin in self.plugins:
116 | plugin.on_lot_free(self, lot)
117 |
118 | def dispatch(self, machine: Machine, lots: List[Lot]):
119 | # remove machine and lot from active sets
120 | self.reserve_machine_lot(lots, machine)
121 | lwam = self.lot_waiting_at_machine[machine.family]
122 | self.lot_waiting_at_machine[machine.family] = (lwam[0] + len(lots),
123 | lwam[1] + sum([self.current_time - l.free_since for l in lots]))
124 | for lot in lots:
125 | lot.waiting_time += self.current_time - lot.free_since
126 | if lot.actual_step.batch_max > 1:
127 | lot.waiting_time_batching += self.current_time - lot.free_since
128 | if lot.actual_step.cqt_for_step is not None:
129 | lot.cqt_waiting = lot.actual_step.cqt_for_step
130 | lot.cqt_deadline = lot.actual_step.cqt_time
131 | if lot.actual_step.order == lot.cqt_waiting:
132 | if lot.cqt_deadline < self.current_time:
133 | for plugin in self.plugins:
134 | plugin.on_cqt_violated(self, machine, lot)
135 | lot.cqt_waiting = None
136 | lot.cqt_deadline = None
137 | # compute times for lot and machine
138 | lot_time, machine_time, setup_time = self.get_times(self.setups, lots, machine)
139 | # compute per-piece preventive maintenance requirement
140 | for i in range(len(machine.pieces_until_maintenance)):
141 | machine.pieces_until_maintenance[i] -= sum([l.pieces for l in lots])
142 | if machine.pieces_until_maintenance[i] <= 0:
143 | s = machine.maintenance_time[i].sample()
144 | machine_time += s
145 | machine.pieces_until_maintenance[i] = machine.piece_per_maintenance[i]
146 | machine.pmed_time += s
147 | # if there is ltl dedication, dedicate lot for selected step
148 | for lot in lots:
149 | if lot.actual_step.lot_to_lens_dedication is not None:
150 | lot.dedications[lot.actual_step.lot_to_lens_dedication] = machine.idx
151 | # decrease / eliminate min runs required before next setup
152 | if machine.min_runs_left is not None:
153 | machine.min_runs_left -= len(lots)
154 | if machine.min_runs_left <= 0:
155 | machine.min_runs_left = None
156 | machine.min_runs_setup = None
157 | # add events
158 | machine_done = self.current_time + machine_time + setup_time
159 | lot_done = self.current_time + lot_time + setup_time
160 | ev1 = MachineDoneEvent(machine_done, [machine])
161 | ev2 = LotDoneEvent(lot_done, [machine], lots)
162 | self.add_event(ev1)
163 | self.add_event(ev2)
164 | machine.events += [ev1, ev2]
165 |
166 | for plugin in self.plugins:
167 | plugin.on_dispatch(self, machine, lots, machine_done, lot_done)
168 | return machine_done, lot_done
169 |
170 | def get_times(self, setups, lots, machine):
171 | proc_t_samp = lots[0].actual_step.processing_time.sample()
172 | lot_time = proc_t_samp + machine.load_time + machine.unload_time
173 | for lot in lots:
174 | lot.processing_time += lot_time
175 | if len(lots[0].remaining_steps) > 0:
176 | tt = lots[0].remaining_steps[0].transport_time.sample()
177 | lot_time += tt
178 | for lot in lots:
179 | lot.transport_time += tt
180 | if lots[0].actual_step.processing_time == lots[0].actual_step.cascading_time:
181 | cascade_t_samp = proc_t_samp
182 | else:
183 | cascade_t_samp = lots[0].actual_step.cascading_time.sample()
184 | machine_time = cascade_t_samp + (machine.load_time + machine.unload_time if not machine.cascading else 0)
185 | new_setup = lots[0].actual_step.setup_needed
186 | if new_setup != '' and machine.current_setup != new_setup:
187 | if lots[0].actual_step.setup_time is not None:
188 | setup_time = lots[0].actual_step.setup_time
189 | elif (machine.current_setup, new_setup) in setups:
190 | setup_time = setups[(machine.current_setup, new_setup)]
191 | elif ('', new_setup) in setups:
192 | setup_time = setups[('', new_setup)]
193 | else:
194 | setup_time = 0
195 | else:
196 | setup_time = 0
197 | if new_setup in self.setup_min_run:
198 | machine.min_runs_left = self.setup_min_run[new_setup]
199 | machine.min_runs_setup = new_setup
200 | machine.has_min_runs = True
201 | if setup_time > 0:
202 | machine.last_setup_time = setup_time
203 | machine.utilized_time += machine_time
204 | machine.setuped_time += setup_time
205 | machine.last_setup = machine.current_setup
206 | machine.current_setup = new_setup
207 | return lot_time, machine_time, setup_time
208 |
209 | def reserve_machine_lot(self, lots, machine):
210 | self.dm.reserve(self, lots, machine)
211 |
212 | def add_event(self, to_insert):
213 | # insert event to the correct place in the array
214 | self.events.ordered_insert(to_insert)
215 |
216 | def next_decision_point(self):
217 | return self.dm.next_decision_point(self)
218 |
219 | def handle_breakdown(self, machine, delay):
220 | ta = []
221 | for ev in machine.events:
222 | if ev in self.events.arr:
223 | ta.append(ev)
224 | self.events.remove(ev)
225 | for ev in ta:
226 | ev.timestamp += delay
227 | self.add_event(ev)
228 |
229 | @property
230 | def done(self):
231 | return len(self.dispatchable_lots) == 0 and len(self.active_lots) == 0
232 |
233 | def finalize(self):
234 | for plugin in self.plugins:
235 | plugin.on_sim_done(self)
236 |
237 | def print_progress_in_days(self):
238 | import sys
239 | if int(self.current_time_days) > self.printed_days:
240 | self.printed_days = int(self.current_time_days)
241 | if self.printed_days > 0:
242 | sys.stderr.write(
243 | f'\rDay {self.printed_days}===Throughput: {round(len(self.done_lots) / self.printed_days)}/day=')
244 | sys.stderr.flush()
245 |
--------------------------------------------------------------------------------
/datasets/SMT2020_LVHM/attach.txt:
--------------------------------------------------------------------------------
1 | CALNAME CALTYPE RESTYPE RESNAME FOADIST FOA FOAUNITS
2 | BREAK_Def_Met down stngrp Def_Met exponential 10080 min
3 | BREAK_Dielectric down stngrp Dielectric exponential 10080 min
4 | BREAK_Diffusion down stngrp Diffusion exponential 10080 min
5 | BREAK_Dry_Etch down stngrp Dry_Etch exponential 10080 min
6 | BREAK_Implant down stngrp Implant exponential 10080 min
7 | BREAK_Litho down stngrp Litho exponential 10080 min
8 | BREAK_Litho_Met down stngrp Litho_Met exponential 10080 min
9 | BREAK_Planar down stngrp Planar exponential 10080 min
10 | BREAK_TF down stngrp TF exponential 10080 min
11 | BREAK_TF_Met down stngrp TF_Met exponential 10080 min
12 | BREAK_Wet_Etch down stngrp Wet_Etch exponential 10080 min
13 | DefMet_BE_33_MN pm stnfam DefMet_BE_33 constant 29.1 day
14 | DefMet_BE_33_QT pm stnfam DefMet_BE_33 constant 88.3 day
15 | DefMet_BE_42_MN pm stnfam DefMet_BE_42 constant 25.8 day
16 | DefMet_BE_42_QT pm stnfam DefMet_BE_42 constant 78.3 day
17 | DefMet_FE_10_MN pm stnfam DefMet_FE_10 constant 27 day
18 | DefMet_FE_10_QT pm stnfam DefMet_FE_10 constant 81.9 day
19 | DefMet_FE_106_MN pm stnfam DefMet_FE_106 constant 25.5 day
20 | DefMet_FE_106_QT pm stnfam DefMet_FE_106 constant 77.4 day
21 | DefMEt_FE_118_MN pm stnfam DefMEt_FE_118 constant 28.2 day
22 | DefMEt_FE_118_QT pm stnfam DefMEt_FE_118 constant 85.5 day
23 | DefMet_FE_34_MN pm stnfam DefMet_FE_34 constant 33 day
24 | DefMet_FE_34_QT pm stnfam DefMet_FE_34 constant 100.1 day
25 | DefMet_FE_43_MN pm stnfam DefMet_FE_43 constant 28.8 day
26 | DefMet_FE_43_QT pm stnfam DefMet_FE_43 constant 87.4 day
27 | Diffusion_BE_123_MN pm stnfam Diffusion_BE_123 constant 28.5 day
28 | Diffusion_BE_123_QT pm stnfam Diffusion_BE_123 constant 86.5 day
29 | Diffusion_FE_100_MN pm stnfam Diffusion_FE_100 constant 29.7 day
30 | Diffusion_FE_100_QT pm stnfam Diffusion_FE_100 constant 90.1 day
31 | Diffusion_FE_101_MN pm stnfam Diffusion_FE_101 constant 31.5 day
32 | Diffusion_FE_101_QT pm stnfam Diffusion_FE_101 constant 95.6 day
33 | Diffusion_FE_120_MN pm stnfam Diffusion_FE_120 constant 27.9 day
34 | Diffusion_FE_120_QT pm stnfam Diffusion_FE_120 constant 84.6 day
35 | Diffusion_FE_122_MN pm stnfam Diffusion_FE_122 constant 27.9 day
36 | Diffusion_FE_122_QT pm stnfam Diffusion_FE_122 constant 84.6 day
37 | Diffusion_FE_125_MN pm stnfam Diffusion_FE_125 constant 28.5 day
38 | Diffusion_FE_125_QT pm stnfam Diffusion_FE_125 constant 86.5 day
39 | Diffusion_FE_126_MN pm stnfam Diffusion_FE_126 constant 30.6 day
40 | Diffusion_FE_126_QT pm stnfam Diffusion_FE_126 constant 92.8 day
41 | Diffusion_FE_127_MN pm stnfam Diffusion_FE_127 constant 31.8 day
42 | Diffusion_FE_127_QT pm stnfam Diffusion_FE_127 constant 96.5 day
43 | Diffusion_FE_44_MN pm stnfam Diffusion_FE_44 constant 30.3 day
44 | Diffusion_FE_44_QT pm stnfam Diffusion_FE_44 constant 91.9 day
45 | Diffusion_FE_94_MN pm stnfam Diffusion_FE_94 constant 30 day
46 | Diffusion_FE_94_QT pm stnfam Diffusion_FE_94 constant 91 day
47 | Litho_BE_110_WK pm stnfam Litho_BE_110 constant 7 day
48 | Litho_BE_110_MN pm stnfam Litho_BE_110 constant 30 day
49 | Litho_BE_110_QT pm stnfam Litho_BE_110 constant 91 day
50 | Litho_BE_93_WK pm stnfam Litho_BE_93 constant 7.1 day
51 | Litho_BE_93_MN pm stnfam Litho_BE_93 constant 30.3 day
52 | Litho_BE_93_QT pm stnfam Litho_BE_93 constant 91.9 day
53 | Litho_BE_99_WK pm stnfam Litho_BE_99 constant 6.6 day
54 | Litho_BE_99_MN pm stnfam Litho_BE_99 constant 28.2 day
55 | Litho_BE_99_QT pm stnfam Litho_BE_99 constant 85.5 day
56 | Litho_FE_111_WK pm stnfam Litho_FE_111 constant 6.7 day
57 | Litho_FE_111_MN pm stnfam Litho_FE_111 constant 28.8 day
58 | Litho_FE_111_QT pm stnfam Litho_FE_111 constant 87.4 day
59 | Litho_FE_35_WK pm stnfam Litho_FE_35 constant 6.4 day
60 | Litho_FE_35_MN pm stnfam Litho_FE_35 constant 27.3 day
61 | Litho_FE_35_QT pm stnfam Litho_FE_35 constant 82.8 day
62 | Litho_FE_92_WK pm stnfam Litho_FE_92 constant 7.2 day
63 | Litho_FE_92_MN pm stnfam Litho_FE_92 constant 30.9 day
64 | Litho_FE_92_QT pm stnfam Litho_FE_92 constant 93.7 day
65 | Litho_FE_98_WK pm stnfam Litho_FE_98 constant 7.7 day
66 | Litho_FE_98_MN pm stnfam Litho_FE_98 constant 33 day
67 | Litho_FE_98_QT pm stnfam Litho_FE_98 constant 100.1 day
68 | Litho_REG_BE_63_MN pm stnfam Litho_REG_BE_63 constant 29.1 day
69 | Litho_REG_BE_63_QT pm stnfam Litho_REG_BE_63 constant 88.3 day
70 | Litho_REG_FE_64_MN pm stnfam Litho_REG_FE_64 constant 29.7 day
71 | Litho_REG_FE_64_QT pm stnfam Litho_REG_FE_64 constant 90.1 day
72 | LithoMet_BE_18_MN pm stnfam LithoMet_BE_18 constant 31.8 day
73 | LithoMet_BE_18_QT pm stnfam LithoMet_BE_18 constant 96.5 day
74 | LithoMet_FE_19_MN pm stnfam LithoMet_FE_19 constant 31.2 day
75 | LithoMet_FE_19_QT pm stnfam LithoMet_FE_19 constant 94.6 day
76 | LithoTrack_BE_117_WK pm stnfam LithoTrack_BE_117 constant 7.5 day
77 | LithoTrack_BE_117_MN pm stnfam LithoTrack_BE_117 constant 32.1 day
78 | LithoTrack_BE_117_QT pm stnfam LithoTrack_BE_117 constant 97.4 day
79 | LithoTrack_FE_115_WK pm stnfam LithoTrack_FE_115 constant 7 day
80 | LithoTrack_FE_115_MN pm stnfam LithoTrack_FE_115 constant 30 day
81 | LithoTrack_FE_115_QT pm stnfam LithoTrack_FE_115 constant 91 day
82 | LithoTrack_FE_95_WK pm stnfam LithoTrack_FE_95 constant 6.9 day
83 | LithoTrack_FE_95_MN pm stnfam LithoTrack_FE_95 constant 29.7 day
84 | LithoTrack_FE_95_QT pm stnfam LithoTrack_FE_95 constant 90.1 day
85 | LithoTrack_FE_96_WK pm stnfam LithoTrack_FE_96 constant 6.4 day
86 | LithoTrack_FE_96_MN pm stnfam LithoTrack_FE_96 constant 27.6 day
87 | LithoTrack_FE_96_QT pm stnfam LithoTrack_FE_96 constant 83.7 day
88 | TF_Met_FE_45_MN pm stnfam TF_Met_FE_45 constant 32.7 day
89 | TF_Met_FE_45_QT pm stnfam TF_Met_FE_45 constant 99.2 day
90 | TF_Met_FE_61_MN pm stnfam TF_Met_FE_61 constant 30.9 day
91 | TF_Met_FE_61_QT pm stnfam TF_Met_FE_61 constant 93.7 day
92 | DE_BE_11_WK pm stnfam DE_BE_11 constant 2244
93 | DE_BE_11_MN pm stnfam DE_BE_11 constant 9764
94 | DE_BE_11_QT pm stnfam DE_BE_11 constant 29290
95 | DE_BE_12_WK pm stnfam DE_BE_12 constant 1200
96 | DE_BE_12_MN pm stnfam DE_BE_12 constant 5250
97 | DE_BE_12_QT pm stnfam DE_BE_12 constant 15750
98 | DE_BE_13_WK pm stnfam DE_BE_13 constant 1942
99 | DE_BE_13_MN pm stnfam DE_BE_13 constant 8391
100 | DE_BE_13_QT pm stnfam DE_BE_13 constant 25172
101 | DE_BE_48_WK pm stnfam DE_BE_48 constant 1542
102 | DE_BE_48_MN pm stnfam DE_BE_48 constant 6649
103 | DE_BE_48_QT pm stnfam DE_BE_48 constant 19947
104 | DE_BE_50_WK pm stnfam DE_BE_50 constant 1800
105 | DE_BE_50_MN pm stnfam DE_BE_50 constant 7800
106 | DE_BE_50_QT pm stnfam DE_BE_50 constant 23400
107 | DE_BE_65_WK pm stnfam DE_BE_65 constant 1710
108 | DE_BE_65_MN pm stnfam DE_BE_65 constant 7380
109 | DE_BE_65_QT pm stnfam DE_BE_65 constant 22140
110 | DE_BE_66_WK pm stnfam DE_BE_66 constant 1486
111 | DE_BE_66_MN pm stnfam DE_BE_66 constant 6417
112 | DE_BE_66_QT pm stnfam DE_BE_66 constant 19250
113 | DE_BE_67_WK pm stnfam DE_BE_67 constant 1782
114 | DE_BE_67_MN pm stnfam DE_BE_67 constant 7751
115 | DE_BE_67_QT pm stnfam DE_BE_67 constant 23252
116 | DE_BE_69_WK pm stnfam DE_BE_69 constant 2180
117 | DE_BE_69_MN pm stnfam DE_BE_69 constant 9447
118 | DE_BE_69_QT pm stnfam DE_BE_69 constant 28340
119 | DE_FE_1_WK pm stnfam DE_FE_1 constant 1302
120 | DE_FE_1_MN pm stnfam DE_FE_1 constant 5580
121 | DE_FE_1_QT pm stnfam DE_FE_1 constant 16740
122 | DE_FE_51_WK pm stnfam DE_FE_51 constant 1504
123 | DE_FE_51_MN pm stnfam DE_FE_51 constant 6499
124 | DE_FE_51_QT pm stnfam DE_FE_51 constant 19497
125 | DE_FE_53_WK pm stnfam DE_FE_53 constant 900
126 | DE_FE_53_MN pm stnfam DE_FE_53 constant 3960
127 | DE_FE_53_QT pm stnfam DE_FE_53 constant 11880
128 | DE_FE_54_WK pm stnfam DE_FE_54 constant 1650
129 | DE_FE_54_MN pm stnfam DE_FE_54 constant 7260
130 | DE_FE_54_QT pm stnfam DE_FE_54 constant 21780
131 | DE_FE_56_WK pm stnfam DE_FE_56 constant 2825
132 | DE_FE_56_MN pm stnfam DE_FE_56 constant 12430
133 | DE_FE_56_QT pm stnfam DE_FE_56 constant 37290
134 | DE_FE_58_WK pm stnfam DE_FE_58 constant 2240
135 | DE_FE_58_MN pm stnfam DE_FE_58 constant 9520
136 | DE_FE_58_QT pm stnfam DE_FE_58 constant 28560
137 | DE_FE_59_WK pm stnfam DE_FE_59 constant 1750
138 | DE_FE_59_MN pm stnfam DE_FE_59 constant 7625
139 | DE_FE_59_QT pm stnfam DE_FE_59 constant 22875
140 | DE_FE_62_WK pm stnfam DE_FE_62 constant 1427
141 | DE_FE_62_MN pm stnfam DE_FE_62 constant 6162
142 | DE_FE_62_QT pm stnfam DE_FE_62 constant 18487
143 | DE_FE_70_WK pm stnfam DE_FE_70 constant 2028
144 | DE_FE_70_MN pm stnfam DE_FE_70 constant 8818
145 | DE_FE_70_QT pm stnfam DE_FE_70 constant 26455
146 | DE_FE_71_WK pm stnfam DE_FE_71 constant 1485
147 | DE_FE_71_MN pm stnfam DE_FE_71 constant 6435
148 | DE_FE_71_QT pm stnfam DE_FE_71 constant 19305
149 | DE_FE_72_WK pm stnfam DE_FE_72 constant 1814
150 | DE_FE_72_MN pm stnfam DE_FE_72 constant 7859
151 | DE_FE_72_QT pm stnfam DE_FE_72 constant 23577
152 | DE_FE_86_WK pm stnfam DE_FE_86 constant 1556
153 | DE_FE_86_MN pm stnfam DE_FE_86 constant 6744
154 | DE_FE_86_QT pm stnfam DE_FE_86 constant 20231
155 | Dielectric_BE_20_WK pm stnfam Dielectric_BE_20 constant 3604
156 | Dielectric_BE_20_MN pm stnfam Dielectric_BE_20 constant 15688
157 | Dielectric_BE_20_QT pm stnfam Dielectric_BE_20 constant 47064
158 | Dielectric_BE_21_WK pm stnfam Dielectric_BE_21 constant 4680
159 | Dielectric_BE_21_MN pm stnfam Dielectric_BE_21 constant 20340
160 | Dielectric_BE_21_QT pm stnfam Dielectric_BE_21 constant 61020
161 | Dielectric_BE_27_WK pm stnfam Dielectric_BE_27 constant 3986
162 | Dielectric_BE_27_MN pm stnfam Dielectric_BE_27 constant 17246
163 | Dielectric_BE_27_QT pm stnfam Dielectric_BE_27 constant 51740
164 | Dielectric_BE_28_WK pm stnfam Dielectric_BE_28 constant 4420
165 | Dielectric_BE_28_MN pm stnfam Dielectric_BE_28 constant 19040
166 | Dielectric_BE_28_QT pm stnfam Dielectric_BE_28 constant 57120
167 | Dielectric_BE_60_WK pm stnfam Dielectric_BE_60 constant 4000
168 | Dielectric_BE_60_MN pm stnfam Dielectric_BE_60 constant 17280
169 | Dielectric_BE_60_QT pm stnfam Dielectric_BE_60 constant 51840
170 | Dielectric_FE_112_WK pm stnfam Dielectric_FE_112 constant 3547
171 | Dielectric_FE_112_MN pm stnfam Dielectric_FE_112 constant 15336
172 | Dielectric_FE_112_QT pm stnfam Dielectric_FE_112 constant 46007
173 | Dielectric_FE_130_WK pm stnfam Dielectric_FE_130 constant 3500
174 | Dielectric_FE_130_MN pm stnfam Dielectric_FE_130 constant 15250
175 | Dielectric_FE_130_QT pm stnfam Dielectric_FE_130 constant 45750
176 | Dielectric_FE_29_WK pm stnfam Dielectric_FE_29 constant 2730
177 | Dielectric_FE_29_MN pm stnfam Dielectric_FE_29 constant 11830
178 | Dielectric_FE_29_QT pm stnfam Dielectric_FE_29 constant 35490
179 | Dielectric_FE_30_WK pm stnfam Dielectric_FE_30 constant 3150
180 | Dielectric_FE_30_MN pm stnfam Dielectric_FE_30 constant 13500
181 | Dielectric_FE_30_QT pm stnfam Dielectric_FE_30 constant 40500
182 | Dielectric_FE_31_WK pm stnfam Dielectric_FE_31 constant 4360
183 | Dielectric_FE_31_MN pm stnfam Dielectric_FE_31 constant 18803
184 | Dielectric_FE_31_QT pm stnfam Dielectric_FE_31 constant 56408
185 | EPI_36_WK pm stnfam EPI_36 constant 2675
186 | EPI_36_MN pm stnfam EPI_36 constant 11770
187 | EPI_36_QT pm stnfam EPI_36 constant 35310
188 | EPI_38_WK pm stnfam EPI_38 constant 3480
189 | EPI_38_MN pm stnfam EPI_38 constant 14790
190 | EPI_38_QT pm stnfam EPI_38 constant 44370
191 | Implant_119_WK pm stnfam Implant_119 constant 4895
192 | Implant_119_MN pm stnfam Implant_119 constant 21360
193 | Implant_119_QT pm stnfam Implant_119 constant 64080
194 | Implant_128_WK pm stnfam Implant_128 constant 7438
195 | Implant_128_MN pm stnfam Implant_128 constant 32228
196 | Implant_128_QT pm stnfam Implant_128 constant 96684
197 | Implant_132_WK pm stnfam Implant_132 constant 6143
198 | Implant_132_MN pm stnfam Implant_132 constant 26571
199 | Implant_132_QT pm stnfam Implant_132 constant 79714
200 | Implant_74_WK pm stnfam Implant_74 constant 3465
201 | Implant_74_MN pm stnfam Implant_74 constant 14850
202 | Implant_74_QT pm stnfam Implant_74 constant 44550
203 | Implant_88_WK pm stnfam Implant_88 constant 3570
204 | Implant_88_MN pm stnfam Implant_88 constant 15300
205 | Implant_88_QT pm stnfam Implant_88 constant 45900
206 | Implant_90_WK pm stnfam Implant_90 constant 5610
207 | Implant_90_MN pm stnfam Implant_90 constant 24480
208 | Implant_90_QT pm stnfam Implant_90 constant 73440
209 | Implant_91_WK pm stnfam Implant_91 constant 6879
210 | Implant_91_MN pm stnfam Implant_91 constant 29807
211 | Implant_91_QT pm stnfam Implant_91 constant 89421
212 | Planar_BE_75_WK pm stnfam Planar_BE_75 constant 3189
213 | Planar_BE_75_MN pm stnfam Planar_BE_75 constant 13842
214 | Planar_BE_75_QT pm stnfam Planar_BE_75 constant 41528
215 | Planar_FE_76_WK pm stnfam Planar_FE_76 constant 3815
216 | Planar_FE_76_MN pm stnfam Planar_FE_76 constant 16350
217 | Planar_FE_76_QT pm stnfam Planar_FE_76 constant 49050
218 | Planar_FE_77_WK pm stnfam Planar_FE_77 constant 3955
219 | Planar_FE_77_MN pm stnfam Planar_FE_77 constant 16950
220 | Planar_FE_77_QT pm stnfam Planar_FE_77 constant 50850
221 | Planar_FE_78_WK pm stnfam Planar_FE_78 constant 2275
222 | Planar_FE_78_MN pm stnfam Planar_FE_78 constant 10010
223 | Planar_FE_78_QT pm stnfam Planar_FE_78 constant 30030
224 | Planar_FE_79_WK pm stnfam Planar_FE_79 constant 3300
225 | Planar_FE_79_MN pm stnfam Planar_FE_79 constant 14300
226 | Planar_FE_79_QT pm stnfam Planar_FE_79 constant 42900
227 | Planar_FE_80_WK pm stnfam Planar_FE_80 constant 3395
228 | Planar_FE_80_MN pm stnfam Planar_FE_80 constant 14550
229 | Planar_FE_80_QT pm stnfam Planar_FE_80 constant 43650
230 | TF_BE_2_WK pm stnfam TF_BE_2 constant 2325
231 | TF_BE_2_MN pm stnfam TF_BE_2 constant 9998
232 | TF_BE_2_QT pm stnfam TF_BE_2 constant 29993
233 | TF_BE_23_WK pm stnfam TF_BE_23 constant 2786
234 | TF_BE_23_MN pm stnfam TF_BE_23 constant 12071
235 | TF_BE_23_QT pm stnfam TF_BE_23 constant 36214
236 | TF_BE_24_WK pm stnfam TF_BE_24 constant 2160
237 | TF_BE_24_MN pm stnfam TF_BE_24 constant 9450
238 | TF_BE_24_QT pm stnfam TF_BE_24 constant 28350
239 | TF_BE_26_WK pm stnfam TF_BE_26 constant 2777
240 | TF_BE_26_MN pm stnfam TF_BE_26 constant 12057
241 | TF_BE_26_QT pm stnfam TF_BE_26 constant 36173
242 | TF_BE_40_WK pm stnfam TF_BE_40 constant 2682
243 | TF_BE_40_MN pm stnfam TF_BE_40 constant 11640
244 | TF_BE_40_QT pm stnfam TF_BE_40 constant 34920
245 | TF_FE_103_WK pm stnfam TF_FE_103 constant 2240
246 | TF_FE_103_MN pm stnfam TF_FE_103 constant 9660
247 | TF_FE_103_QT pm stnfam TF_FE_103 constant 28980
248 | TF_FE_104_WK pm stnfam TF_FE_104 constant 2968
249 | TF_FE_104_MN pm stnfam TF_FE_104 constant 12932
250 | TF_FE_104_QT pm stnfam TF_FE_104 constant 38796
251 | TF_FE_113_WK pm stnfam TF_FE_113 constant 2100
252 | TF_FE_113_MN pm stnfam TF_FE_113 constant 9000
253 | TF_FE_113_QT pm stnfam TF_FE_113 constant 27000
254 | TF_FE_131_WK pm stnfam TF_FE_131 constant 2356
255 | TF_FE_131_MN pm stnfam TF_FE_131 constant 10269
256 | TF_FE_131_QT pm stnfam TF_FE_131 constant 30805
257 | TF_FE_3_WK pm stnfam TF_FE_3 constant 2403
258 | TF_FE_3_MN pm stnfam TF_FE_3 constant 10300
259 | TF_FE_3_QT pm stnfam TF_FE_3 constant 30900
260 | TF_FE_5_WK pm stnfam TF_FE_5 constant 2100
261 | TF_FE_5_MN pm stnfam TF_FE_5 constant 9000
262 | TF_FE_5_QT pm stnfam TF_FE_5 constant 27000
263 | WE_BE_14_WK pm stnfam WE_BE_14 constant 9828
264 | WE_BE_14_MN pm stnfam WE_BE_14 constant 42588
265 | WE_BE_14_QT pm stnfam WE_BE_14 constant 127764
266 | WE_BE_16_WK pm stnfam WE_BE_16 constant 10010
267 | WE_BE_16_MN pm stnfam WE_BE_16 constant 43420
268 | WE_BE_16_QT pm stnfam WE_BE_16 constant 130260
269 | WE_BE_17_WK pm stnfam WE_BE_17 constant 10200
270 | WE_BE_17_MN pm stnfam WE_BE_17 constant 44370
271 | WE_BE_17_QT pm stnfam WE_BE_17 constant 133110
272 | WE_BE_7_WK pm stnfam WE_BE_7 constant 6840
273 | WE_BE_7_MN pm stnfam WE_BE_7 constant 29640
274 | WE_BE_7_QT pm stnfam WE_BE_7 constant 88920
275 | WE_BE_81_WK pm stnfam WE_BE_81 constant 9630
276 | WE_BE_81_MN pm stnfam WE_BE_81 constant 41730
277 | WE_BE_81_QT pm stnfam WE_BE_81 constant 125190
278 | WE_BE_82_WK pm stnfam WE_BE_82 constant 11550
279 | WE_BE_82_MN pm stnfam WE_BE_82 constant 50050
280 | WE_BE_82_QT pm stnfam WE_BE_82 constant 150150
281 | WE_BE_9_WK pm stnfam WE_BE_9 constant 9100
282 | WE_BE_9_MN pm stnfam WE_BE_9 constant 39494
283 | WE_BE_9_QT pm stnfam WE_BE_9 constant 118482
284 | WE_FE_108_WK pm stnfam WE_FE_108 constant 11163
285 | WE_FE_108_MN pm stnfam WE_FE_108 constant 48373
286 | WE_FE_108_QT pm stnfam WE_FE_108 constant 145120
287 | WE_FE_41_WK pm stnfam WE_FE_41 constant 11880
288 | WE_FE_41_MN pm stnfam WE_FE_41 constant 51480
289 | WE_FE_41_QT pm stnfam WE_FE_41 constant 154440
290 | WE_FE_47_WK pm stnfam WE_FE_47 constant 10400
291 | WE_FE_47_MN pm stnfam WE_FE_47 constant 45000
292 | WE_FE_47_QT pm stnfam WE_FE_47 constant 135000
293 | WE_FE_8_WK pm stnfam WE_FE_8 constant 5280
294 | WE_FE_8_MN pm stnfam WE_FE_8 constant 22880
295 | WE_FE_8_QT pm stnfam WE_FE_8 constant 68640
296 | WE_FE_83_WK pm stnfam WE_FE_83 constant 11158
297 | WE_FE_83_MN pm stnfam WE_FE_83 constant 48410
298 | WE_FE_83_QT pm stnfam WE_FE_83 constant 145230
299 | WE_FE_84_WK pm stnfam WE_FE_84 constant 10608
300 | WE_FE_84_MN pm stnfam WE_FE_84 constant 45944
301 | WE_FE_84_QT pm stnfam WE_FE_84 constant 137834
302 | WE_FE_85_WK pm stnfam WE_FE_85 constant 7560
303 | WE_FE_85_MN pm stnfam WE_FE_85 constant 32940
304 | WE_FE_85_QT pm stnfam WE_FE_85 constant 98820
305 |
--------------------------------------------------------------------------------
/datasets/SMT2020_HVLM/attach.txt:
--------------------------------------------------------------------------------
1 | CALNAME CALTYPE RESTYPE RESNAME FOADIST FOA FOAUNITS
2 | BREAK_Def_Met down stngrp Def_Met exponential 10080 min
3 | BREAK_Dielectric down stngrp Dielectric exponential 10080 min
4 | BREAK_Diffusion down stngrp Diffusion exponential 10080 min
5 | BREAK_Dry_Etch down stngrp Dry_Etch exponential 10080 min
6 | BREAK_Implant down stngrp Implant exponential 10080 min
7 | BREAK_Litho down stngrp Litho exponential 10080 min
8 | BREAK_Litho_Met down stngrp Litho_Met exponential 10080 min
9 | BREAK_Planar down stngrp Planar exponential 10080 min
10 | BREAK_TF down stngrp TF exponential 10080 min
11 | BREAK_TF_Met down stngrp TF_Met exponential 10080 min
12 | BREAK_Wet_Etch down stngrp Wet_Etch exponential 10080 min
13 | DefMet_BE_33_MN pm stnfam DefMet_BE_33 constant 27.3 day
14 | DefMet_BE_33_QT pm stnfam DefMet_BE_33 constant 82.8 day
15 | DefMet_BE_42_MN pm stnfam DefMet_BE_42 constant 27 day
16 | DefMet_BE_42_QT pm stnfam DefMet_BE_42 constant 81.9 day
17 | DefMet_FE_10_MN pm stnfam DefMet_FE_10 constant 33.3 day
18 | DefMet_FE_10_QT pm stnfam DefMet_FE_10 constant 101 day
19 | DefMet_FE_106_MN pm stnfam DefMet_FE_106 constant 27.3 day
20 | DefMet_FE_106_QT pm stnfam DefMet_FE_106 constant 82.8 day
21 | DefMEt_FE_118_MN pm stnfam DefMEt_FE_118 constant 27.3 day
22 | DefMEt_FE_118_QT pm stnfam DefMEt_FE_118 constant 82.8 day
23 | DefMet_FE_34_MN pm stnfam DefMet_FE_34 constant 30.6 day
24 | DefMet_FE_34_QT pm stnfam DefMet_FE_34 constant 92.8 day
25 | DefMet_FE_43_MN pm stnfam DefMet_FE_43 constant 29.4 day
26 | DefMet_FE_43_QT pm stnfam DefMet_FE_43 constant 89.2 day
27 | Diffusion_BE_123_MN pm stnfam Diffusion_BE_123 constant 28.5 day
28 | Diffusion_BE_123_QT pm stnfam Diffusion_BE_123 constant 86.5 day
29 | Diffusion_FE_100_MN pm stnfam Diffusion_FE_100 constant 26.1 day
30 | Diffusion_FE_100_QT pm stnfam Diffusion_FE_100 constant 79.2 day
31 | Diffusion_FE_101_MN pm stnfam Diffusion_FE_101 constant 31.5 day
32 | Diffusion_FE_101_QT pm stnfam Diffusion_FE_101 constant 95.6 day
33 | Diffusion_FE_120_MN pm stnfam Diffusion_FE_120 constant 28.2 day
34 | Diffusion_FE_120_QT pm stnfam Diffusion_FE_120 constant 85.5 day
35 | Diffusion_FE_122_MN pm stnfam Diffusion_FE_122 constant 29.1 day
36 | Diffusion_FE_122_QT pm stnfam Diffusion_FE_122 constant 88.3 day
37 | Diffusion_FE_125_MN pm stnfam Diffusion_FE_125 constant 30.9 day
38 | Diffusion_FE_125_QT pm stnfam Diffusion_FE_125 constant 93.7 day
39 | Diffusion_FE_126_MN pm stnfam Diffusion_FE_126 constant 26.4 day
40 | Diffusion_FE_126_QT pm stnfam Diffusion_FE_126 constant 80.1 day
41 | Diffusion_FE_127_MN pm stnfam Diffusion_FE_127 constant 29.4 day
42 | Diffusion_FE_127_QT pm stnfam Diffusion_FE_127 constant 89.2 day
43 | Diffusion_FE_44_MN pm stnfam Diffusion_FE_44 constant 29.4 day
44 | Diffusion_FE_44_QT pm stnfam Diffusion_FE_44 constant 89.2 day
45 | Diffusion_FE_94_MN pm stnfam Diffusion_FE_94 constant 30.9 day
46 | Diffusion_FE_94_QT pm stnfam Diffusion_FE_94 constant 93.7 day
47 | Litho_BE_110_WK pm stnfam Litho_BE_110 constant 6.9 day
48 | Litho_BE_110_MN pm stnfam Litho_BE_110 constant 29.4 day
49 | Litho_BE_110_QT pm stnfam Litho_BE_110 constant 89.2 day
50 | Litho_BE_93_WK pm stnfam Litho_BE_93 constant 7.6 day
51 | Litho_BE_93_MN pm stnfam Litho_BE_93 constant 32.4 day
52 | Litho_BE_93_QT pm stnfam Litho_BE_93 constant 98.3 day
53 | Litho_BE_99_WK pm stnfam Litho_BE_99 constant 6.8 day
54 | Litho_BE_99_MN pm stnfam Litho_BE_99 constant 29.1 day
55 | Litho_BE_99_QT pm stnfam Litho_BE_99 constant 88.3 day
56 | Litho_FE_111_WK pm stnfam Litho_FE_111 constant 6.8 day
57 | Litho_FE_111_MN pm stnfam Litho_FE_111 constant 29.1 day
58 | Litho_FE_111_QT pm stnfam Litho_FE_111 constant 88.3 day
59 | Litho_FE_35_WK pm stnfam Litho_FE_35 constant 7.6 day
60 | Litho_FE_35_MN pm stnfam Litho_FE_35 constant 32.4 day
61 | Litho_FE_35_QT pm stnfam Litho_FE_35 constant 98.3 day
62 | Litho_FE_92_WK pm stnfam Litho_FE_92 constant 6.9 day
63 | Litho_FE_92_MN pm stnfam Litho_FE_92 constant 29.4 day
64 | Litho_FE_92_QT pm stnfam Litho_FE_92 constant 89.2 day
65 | Litho_FE_98_WK pm stnfam Litho_FE_98 constant 7.5 day
66 | Litho_FE_98_MN pm stnfam Litho_FE_98 constant 32.1 day
67 | Litho_FE_98_QT pm stnfam Litho_FE_98 constant 97.4 day
68 | Litho_REG_BE_63_MN pm stnfam Litho_REG_BE_63 constant 29.7 day
69 | Litho_REG_BE_63_QT pm stnfam Litho_REG_BE_63 constant 90.1 day
70 | Litho_REG_FE_64_MN pm stnfam Litho_REG_FE_64 constant 30.3 day
71 | Litho_REG_FE_64_QT pm stnfam Litho_REG_FE_64 constant 91.9 day
72 | LithoMet_BE_18_MN pm stnfam LithoMet_BE_18 constant 30.6 day
73 | LithoMet_BE_18_QT pm stnfam LithoMet_BE_18 constant 92.8 day
74 | LithoMet_FE_19_MN pm stnfam LithoMet_FE_19 constant 29.7 day
75 | LithoMet_FE_19_QT pm stnfam LithoMet_FE_19 constant 90.1 day
76 | LithoTrack_BE_117_WK pm stnfam LithoTrack_BE_117 constant 7.1 day
77 | LithoTrack_BE_117_MN pm stnfam LithoTrack_BE_117 constant 30.6 day
78 | LithoTrack_BE_117_QT pm stnfam LithoTrack_BE_117 constant 92.8 day
79 | LithoTrack_FE_115_WK pm stnfam LithoTrack_FE_115 constant 7.1 day
80 | LithoTrack_FE_115_MN pm stnfam LithoTrack_FE_115 constant 30.3 day
81 | LithoTrack_FE_115_QT pm stnfam LithoTrack_FE_115 constant 91.9 day
82 | LithoTrack_FE_95_WK pm stnfam LithoTrack_FE_95 constant 7.1 day
83 | LithoTrack_FE_95_MN pm stnfam LithoTrack_FE_95 constant 30.3 day
84 | LithoTrack_FE_95_QT pm stnfam LithoTrack_FE_95 constant 91.9 day
85 | LithoTrack_FE_96_WK pm stnfam LithoTrack_FE_96 constant 6.5 day
86 | LithoTrack_FE_96_MN pm stnfam LithoTrack_FE_96 constant 27.9 day
87 | LithoTrack_FE_96_QT pm stnfam LithoTrack_FE_96 constant 84.6 day
88 | TF_Met_FE_45_MN pm stnfam TF_Met_FE_45 constant 26.1 day
89 | TF_Met_FE_45_QT pm stnfam TF_Met_FE_45 constant 79.2 day
90 | TF_Met_FE_61_MN pm stnfam TF_Met_FE_61 constant 33.9 day
91 | TF_Met_FE_61_QT pm stnfam TF_Met_FE_61 constant 102.8 day
92 | DE_BE_11_WK pm stnfam DE_BE_11 constant 1880
93 | DE_BE_11_MN pm stnfam DE_BE_11 constant 8178
94 | DE_BE_11_QT pm stnfam DE_BE_11 constant 24534
95 | DE_BE_12_WK pm stnfam DE_BE_12 constant 1100
96 | DE_BE_12_MN pm stnfam DE_BE_12 constant 4730
97 | DE_BE_12_QT pm stnfam DE_BE_12 constant 14190
98 | DE_BE_13_WK pm stnfam DE_BE_13 constant 1905
99 | DE_BE_13_MN pm stnfam DE_BE_13 constant 8238
100 | DE_BE_13_QT pm stnfam DE_BE_13 constant 24714
101 | DE_BE_48_WK pm stnfam DE_BE_48 constant 1560
102 | DE_BE_48_MN pm stnfam DE_BE_48 constant 6760
103 | DE_BE_48_QT pm stnfam DE_BE_48 constant 20280
104 | DE_BE_50_WK pm stnfam DE_BE_50 constant 1667
105 | DE_BE_50_MN pm stnfam DE_BE_50 constant 7222
106 | DE_BE_50_QT pm stnfam DE_BE_50 constant 21667
107 | DE_BE_65_WK pm stnfam DE_BE_65 constant 1765
108 | DE_BE_65_MN pm stnfam DE_BE_65 constant 7647
109 | DE_BE_65_QT pm stnfam DE_BE_65 constant 22941
110 | DE_BE_66_WK pm stnfam DE_BE_66 constant 1579
111 | DE_BE_66_MN pm stnfam DE_BE_66 constant 6842
112 | DE_BE_66_QT pm stnfam DE_BE_66 constant 20526
113 | DE_BE_67_WK pm stnfam DE_BE_67 constant 1980
114 | DE_BE_67_MN pm stnfam DE_BE_67 constant 8613
115 | DE_BE_67_QT pm stnfam DE_BE_67 constant 25839
116 | DE_BE_69_WK pm stnfam DE_BE_69 constant 2700
117 | DE_BE_69_MN pm stnfam DE_BE_69 constant 11880
118 | DE_BE_69_QT pm stnfam DE_BE_69 constant 35640
119 | DE_FE_1_WK pm stnfam DE_FE_1 constant 1529
120 | DE_FE_1_MN pm stnfam DE_FE_1 constant 6573
121 | DE_FE_1_QT pm stnfam DE_FE_1 constant 19719
122 | DE_FE_51_WK pm stnfam DE_FE_51 constant 1579
123 | DE_FE_51_MN pm stnfam DE_FE_51 constant 6842
124 | DE_FE_51_QT pm stnfam DE_FE_51 constant 20526
125 | DE_FE_53_WK pm stnfam DE_FE_53 constant 970
126 | DE_FE_53_MN pm stnfam DE_FE_53 constant 4268
127 | DE_FE_53_QT pm stnfam DE_FE_53 constant 12804
128 | DE_FE_54_WK pm stnfam DE_FE_54 constant 1980
129 | DE_FE_54_MN pm stnfam DE_FE_54 constant 8514
130 | DE_FE_54_QT pm stnfam DE_FE_54 constant 25542
131 | DE_FE_56_WK pm stnfam DE_FE_56 constant 2550
132 | DE_FE_56_MN pm stnfam DE_FE_56 constant 11220
133 | DE_FE_56_QT pm stnfam DE_FE_56 constant 33660
134 | DE_FE_58_WK pm stnfam DE_FE_58 constant 1534
135 | DE_FE_58_MN pm stnfam DE_FE_58 constant 6746
136 | DE_FE_58_QT pm stnfam DE_FE_58 constant 20240
137 | DE_FE_59_WK pm stnfam DE_FE_59 constant 1584
138 | DE_FE_59_MN pm stnfam DE_FE_59 constant 6840
139 | DE_FE_59_QT pm stnfam DE_FE_59 constant 20520
140 | DE_FE_62_WK pm stnfam DE_FE_62 constant 1415
141 | DE_FE_62_MN pm stnfam DE_FE_62 constant 6152
142 | DE_FE_62_QT pm stnfam DE_FE_62 constant 18457
143 | DE_FE_70_WK pm stnfam DE_FE_70 constant 2019
144 | DE_FE_70_MN pm stnfam DE_FE_70 constant 8723
145 | DE_FE_70_QT pm stnfam DE_FE_70 constant 26169
146 | DE_FE_71_WK pm stnfam DE_FE_71 constant 1415
147 | DE_FE_71_MN pm stnfam DE_FE_71 constant 6117
148 | DE_FE_71_QT pm stnfam DE_FE_71 constant 18351
149 | DE_FE_72_WK pm stnfam DE_FE_72 constant 2222
150 | DE_FE_72_MN pm stnfam DE_FE_72 constant 9667
151 | DE_FE_72_QT pm stnfam DE_FE_72 constant 29000
152 | DE_FE_86_WK pm stnfam DE_FE_86 constant 1519
153 | DE_FE_86_MN pm stnfam DE_FE_86 constant 6578
154 | DE_FE_86_QT pm stnfam DE_FE_86 constant 19733
155 | Dielectric_BE_20_WK pm stnfam Dielectric_BE_20 constant 4200
156 | Dielectric_BE_20_MN pm stnfam Dielectric_BE_20 constant 18270
157 | Dielectric_BE_20_QT pm stnfam Dielectric_BE_20 constant 54810
158 | Dielectric_BE_21_WK pm stnfam Dielectric_BE_21 constant 4594
159 | Dielectric_BE_21_MN pm stnfam Dielectric_BE_21 constant 19950
160 | Dielectric_BE_21_QT pm stnfam Dielectric_BE_21 constant 59850
161 | Dielectric_BE_27_WK pm stnfam Dielectric_BE_27 constant 4000
162 | Dielectric_BE_27_MN pm stnfam Dielectric_BE_27 constant 17333
163 | Dielectric_BE_27_QT pm stnfam Dielectric_BE_27 constant 52000
164 | Dielectric_BE_28_WK pm stnfam Dielectric_BE_28 constant 4163
165 | Dielectric_BE_28_MN pm stnfam Dielectric_BE_28 constant 18038
166 | Dielectric_BE_28_QT pm stnfam Dielectric_BE_28 constant 54113
167 | Dielectric_BE_60_WK pm stnfam Dielectric_BE_60 constant 3900
168 | Dielectric_BE_60_MN pm stnfam Dielectric_BE_60 constant 16900
169 | Dielectric_BE_60_QT pm stnfam Dielectric_BE_60 constant 50700
170 | Dielectric_FE_112_WK pm stnfam Dielectric_FE_112 constant 3920
171 | Dielectric_FE_112_MN pm stnfam Dielectric_FE_112 constant 16954
172 | Dielectric_FE_112_QT pm stnfam Dielectric_FE_112 constant 50862
173 | Dielectric_FE_130_WK pm stnfam Dielectric_FE_130 constant 3563
174 | Dielectric_FE_130_MN pm stnfam Dielectric_FE_130 constant 15438
175 | Dielectric_FE_130_QT pm stnfam Dielectric_FE_130 constant 46313
176 | Dielectric_FE_29_WK pm stnfam Dielectric_FE_29 constant 2933
177 | Dielectric_FE_29_MN pm stnfam Dielectric_FE_29 constant 12613
178 | Dielectric_FE_29_QT pm stnfam Dielectric_FE_29 constant 37840
179 | Dielectric_FE_30_WK pm stnfam Dielectric_FE_30 constant 5600
180 | Dielectric_FE_30_MN pm stnfam Dielectric_FE_30 constant 24080
181 | Dielectric_FE_30_QT pm stnfam Dielectric_FE_30 constant 72240
182 | Dielectric_FE_31_WK pm stnfam Dielectric_FE_31 constant 3713
183 | Dielectric_FE_31_MN pm stnfam Dielectric_FE_31 constant 16088
184 | Dielectric_FE_31_QT pm stnfam Dielectric_FE_31 constant 48263
185 | EPI_36_WK pm stnfam EPI_36 constant 2700
186 | EPI_36_MN pm stnfam EPI_36 constant 11880
187 | EPI_36_QT pm stnfam EPI_36 constant 35640
188 | EPI_38_WK pm stnfam EPI_38 constant 4250
189 | EPI_38_MN pm stnfam EPI_38 constant 18700
190 | EPI_38_QT pm stnfam EPI_38 constant 56100
191 | Implant_119_WK pm stnfam Implant_119 constant 4450
192 | Implant_119_MN pm stnfam Implant_119 constant 19135
193 | Implant_119_QT pm stnfam Implant_119 constant 57405
194 | Implant_128_WK pm stnfam Implant_128 constant 8000
195 | Implant_128_MN pm stnfam Implant_128 constant 34700
196 | Implant_128_QT pm stnfam Implant_128 constant 104100
197 | Implant_132_WK pm stnfam Implant_132 constant 6806
198 | Implant_132_MN pm stnfam Implant_132 constant 29453
199 | Implant_132_QT pm stnfam Implant_132 constant 88358
200 | Implant_74_WK pm stnfam Implant_74 constant 2250
201 | Implant_74_MN pm stnfam Implant_74 constant 9900
202 | Implant_74_QT pm stnfam Implant_74 constant 29700
203 | Implant_88_WK pm stnfam Implant_88 constant 4600
204 | Implant_88_MN pm stnfam Implant_88 constant 19780
205 | Implant_88_QT pm stnfam Implant_88 constant 59340
206 | Implant_90_WK pm stnfam Implant_90 constant 4650
207 | Implant_90_MN pm stnfam Implant_90 constant 19995
208 | Implant_90_QT pm stnfam Implant_90 constant 59985
209 | Implant_91_WK pm stnfam Implant_91 constant 6134
210 | Implant_91_MN pm stnfam Implant_91 constant 26526
211 | Implant_91_QT pm stnfam Implant_91 constant 79580
212 | Planar_BE_75_WK pm stnfam Planar_BE_75 constant 3185
213 | Planar_BE_75_MN pm stnfam Planar_BE_75 constant 13818
214 | Planar_BE_75_QT pm stnfam Planar_BE_75 constant 41454
215 | Planar_FE_76_WK pm stnfam Planar_FE_76 constant 3733
216 | Planar_FE_76_MN pm stnfam Planar_FE_76 constant 16053
217 | Planar_FE_76_QT pm stnfam Planar_FE_76 constant 48160
218 | Planar_FE_77_WK pm stnfam Planar_FE_77 constant 4700
219 | Planar_FE_77_MN pm stnfam Planar_FE_77 constant 20210
220 | Planar_FE_77_QT pm stnfam Planar_FE_77 constant 60630
221 | Planar_FE_78_WK pm stnfam Planar_FE_78 constant 2600
222 | Planar_FE_78_MN pm stnfam Planar_FE_78 constant 11440
223 | Planar_FE_78_QT pm stnfam Planar_FE_78 constant 34320
224 | Planar_FE_79_WK pm stnfam Planar_FE_79 constant 3090
225 | Planar_FE_79_MN pm stnfam Planar_FE_79 constant 13390
226 | Planar_FE_79_QT pm stnfam Planar_FE_79 constant 40170
227 | Planar_FE_80_WK pm stnfam Planar_FE_80 constant 2375
228 | Planar_FE_80_MN pm stnfam Planar_FE_80 constant 10450
229 | Planar_FE_80_QT pm stnfam Planar_FE_80 constant 31350
230 | TF_BE_2_WK pm stnfam TF_BE_2 constant 2750
231 | TF_BE_2_MN pm stnfam TF_BE_2 constant 11825
232 | TF_BE_2_QT pm stnfam TF_BE_2 constant 35475
233 | TF_BE_23_WK pm stnfam TF_BE_23 constant 2808
234 | TF_BE_23_MN pm stnfam TF_BE_23 constant 12150
235 | TF_BE_23_QT pm stnfam TF_BE_23 constant 36452
236 | TF_BE_24_WK pm stnfam TF_BE_24 constant 1840
237 | TF_BE_24_MN pm stnfam TF_BE_24 constant 7912
238 | TF_BE_24_QT pm stnfam TF_BE_24 constant 23736
239 | TF_BE_26_WK pm stnfam TF_BE_26 constant 2910
240 | TF_BE_26_MN pm stnfam TF_BE_26 constant 12610
241 | TF_BE_26_QT pm stnfam TF_BE_26 constant 37830
242 | TF_BE_40_WK pm stnfam TF_BE_40 constant 2681
243 | TF_BE_40_MN pm stnfam TF_BE_40 constant 11633
244 | TF_BE_40_QT pm stnfam TF_BE_40 constant 34898
245 | TF_FE_103_WK pm stnfam TF_FE_103 constant 2425
246 | TF_FE_103_MN pm stnfam TF_FE_103 constant 10428
247 | TF_FE_103_QT pm stnfam TF_FE_103 constant 31283
248 | TF_FE_104_WK pm stnfam TF_FE_104 constant 2880
249 | TF_FE_104_MN pm stnfam TF_FE_104 constant 12480
250 | TF_FE_104_QT pm stnfam TF_FE_104 constant 37440
251 | TF_FE_113_WK pm stnfam TF_FE_113 constant 2825
252 | TF_FE_113_MN pm stnfam TF_FE_113 constant 12430
253 | TF_FE_113_QT pm stnfam TF_FE_113 constant 37290
254 | TF_FE_131_WK pm stnfam TF_FE_131 constant 2550
255 | TF_FE_131_MN pm stnfam TF_FE_131 constant 11050
256 | TF_FE_131_QT pm stnfam TF_FE_131 constant 33150
257 | TF_FE_3_WK pm stnfam TF_FE_3 constant 2175
258 | TF_FE_3_MN pm stnfam TF_FE_3 constant 9570
259 | TF_FE_3_QT pm stnfam TF_FE_3 constant 28710
260 | TF_FE_5_WK pm stnfam TF_FE_5 constant 2425
261 | TF_FE_5_MN pm stnfam TF_FE_5 constant 10428
262 | TF_FE_5_QT pm stnfam TF_FE_5 constant 31283
263 | WE_BE_14_WK pm stnfam WE_BE_14 constant 9800
264 | WE_BE_14_MN pm stnfam WE_BE_14 constant 42532
265 | WE_BE_14_QT pm stnfam WE_BE_14 constant 127596
266 | WE_BE_16_WK pm stnfam WE_BE_16 constant 10028
267 | WE_BE_16_MN pm stnfam WE_BE_16 constant 43489
268 | WE_BE_16_QT pm stnfam WE_BE_16 constant 130466
269 | WE_BE_17_WK pm stnfam WE_BE_17 constant 11100
270 | WE_BE_17_MN pm stnfam WE_BE_17 constant 48285
271 | WE_BE_17_QT pm stnfam WE_BE_17 constant 144855
272 | WE_BE_7_WK pm stnfam WE_BE_7 constant 4350
273 | WE_BE_7_MN pm stnfam WE_BE_7 constant 19140
274 | WE_BE_7_QT pm stnfam WE_BE_7 constant 57420
275 | WE_BE_81_WK pm stnfam WE_BE_81 constant 8166
276 | WE_BE_81_MN pm stnfam WE_BE_81 constant 35280
277 | WE_BE_81_QT pm stnfam WE_BE_81 constant 105840
278 | WE_BE_82_WK pm stnfam WE_BE_82 constant 11400
279 | WE_BE_82_MN pm stnfam WE_BE_82 constant 49400
280 | WE_BE_82_QT pm stnfam WE_BE_82 constant 148200
281 | WE_BE_9_WK pm stnfam WE_BE_9 constant 9300
282 | WE_BE_9_MN pm stnfam WE_BE_9 constant 40256
283 | WE_BE_9_QT pm stnfam WE_BE_9 constant 120767
284 | WE_FE_108_WK pm stnfam WE_FE_108 constant 11143
285 | WE_FE_108_MN pm stnfam WE_FE_108 constant 48286
286 | WE_FE_108_QT pm stnfam WE_FE_108 constant 144857
287 | WE_FE_41_WK pm stnfam WE_FE_41 constant 12480
288 | WE_FE_41_MN pm stnfam WE_FE_41 constant 54080
289 | WE_FE_41_QT pm stnfam WE_FE_41 constant 162240
290 | WE_FE_47_WK pm stnfam WE_FE_47 constant 9625
291 | WE_FE_47_MN pm stnfam WE_FE_47 constant 41650
292 | WE_FE_47_QT pm stnfam WE_FE_47 constant 124950
293 | WE_FE_8_WK pm stnfam WE_FE_8 constant 11000
294 | WE_FE_8_MN pm stnfam WE_FE_8 constant 47850
295 | WE_FE_8_QT pm stnfam WE_FE_8 constant 143550
296 | WE_FE_83_WK pm stnfam WE_FE_83 constant 10515
297 | WE_FE_83_MN pm stnfam WE_FE_83 constant 45605
298 | WE_FE_83_QT pm stnfam WE_FE_83 constant 136817
299 | WE_FE_84_WK pm stnfam WE_FE_84 constant 11050
300 | WE_FE_84_MN pm stnfam WE_FE_84 constant 47883
301 | WE_FE_84_QT pm stnfam WE_FE_84 constant 143650
302 | WE_FE_85_WK pm stnfam WE_FE_85 constant 6675
303 | WE_FE_85_MN pm stnfam WE_FE_85 constant 28925
304 | WE_FE_85_QT pm stnfam WE_FE_85 constant 86775
305 |
--------------------------------------------------------------------------------
/docs/assets/img/bg/bg-corporate.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/datasets/SMT2020_LVHM/tool.txt.1l:
--------------------------------------------------------------------------------
1 | STNFAM STN RULE FWLRANK WAKERESRANK BATCHCRITF BATCHPER LTIME LTUNITS ULTIME ULTUNITS STNCAP STNQTY STNGRP STNFAMSTEP_ACTLIST STNFAMLOC PRERULERWL SETUPGRP
2 | DE_BE_11 DE_BE_11 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 9.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
3 | DE_BE_12 DE_BE_12 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 7.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
4 | DE_BE_13 DE_BE_13 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR wake_LeastSetupTime 1.0 min 1.0 min 13.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
5 | DE_BE_48 DE_BE_48 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 11.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
6 | DE_BE_50 DE_BE_50 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 10.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
7 | DE_BE_65 DE_BE_65 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 11.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
8 | DE_BE_66 DE_BE_66 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR wake_LeastSetupTime 1.0 min 1.0 min 17.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
9 | DE_BE_67 DE_BE_67 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 11.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
10 | DE_BE_69 DE_BE_69 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 3.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
11 | DE_FE_1 DE_FE_1 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 5.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
12 | DE_FE_51 DE_FE_51 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 20.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
13 | DE_FE_53 DE_FE_53 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 5.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
14 | DE_FE_54 DE_FE_54 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 3.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
15 | DE_FE_56 DE_FE_56 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
16 | DE_FE_58 DE_FE_58 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
17 | DE_FE_59 DE_FE_59 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 8.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
18 | DE_FE_62 DE_FE_62 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 17.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
19 | DE_FE_70 DE_FE_70 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 11.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
20 | DE_FE_71 DE_FE_71 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 18.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
21 | DE_FE_72 DE_FE_72 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 11.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
22 | DE_FE_86 DE_FE_86 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 118.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
23 | DefMet_BE_33 DefMet_BE_33 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
24 | DefMet_BE_42 DefMet_BE_42 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 1.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
25 | DefMet_FE_10 DefMet_FE_10 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
26 | DefMet_FE_106 DefMet_FE_106 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 1.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
27 | DefMEt_FE_118 DefMEt_FE_118 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
28 | DefMet_FE_34 DefMet_FE_34 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
29 | DefMet_FE_43 DefMet_FE_43 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 5.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
30 | Delay_32 Delay1 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 0.0 min 0.0 min 400.0 Delay_32 Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Delay no
31 | Dielectric_BE_20 Dielectric_BE_20 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 5.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
32 | Dielectric_BE_21 Dielectric_BE_21 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 6.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
33 | Dielectric_BE_27 Dielectric_BE_27 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 12.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
34 | Dielectric_BE_28 Dielectric_BE_28 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 3.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
35 | Dielectric_BE_60 Dielectric_BE_60 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 6.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
36 | Dielectric_FE_112 Dielectric_FE_112 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 9.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
37 | Dielectric_FE_130 Dielectric_FE_130 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 4.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
38 | Dielectric_FE_29 Dielectric_FE_29 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 3.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
39 | Dielectric_FE_30 Dielectric_FE_30 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 2.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
40 | Dielectric_FE_31 Dielectric_FE_31 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 4.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
41 | Diffusion_BE_123 Diffusion_BE_123 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR crit_sameroutestep piece 1.0 min 1.0 min 9.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
42 | Diffusion_FE_100 Diffusion_FE_100 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR crit_sameroutestep piece 1.0 min 1.0 min 3.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
43 | Diffusion_FE_101 Diffusion_FE_101 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR crit_sameroutestep piece 1.0 min 1.0 min 10.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
44 | Diffusion_FE_120 Diffusion_FE_120 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR crit_sameroutestep piece 1.0 min 1.0 min 8.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
45 | Diffusion_FE_122 Diffusion_FE_122 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR crit_sameroutestep piece 1.0 min 1.0 min 6.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
46 | Diffusion_FE_125 Diffusion_FE_125 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR crit_sameroutestep piece 1.0 min 1.0 min 5.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
47 | Diffusion_FE_126 Diffusion_FE_126 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR crit_sameroutestep piece 1.0 min 1.0 min 4.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
48 | Diffusion_FE_127 Diffusion_FE_127 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR crit_sameroutestep piece 1.0 min 1.0 min 8.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
49 | Diffusion_FE_44 Diffusion_FE_44 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR crit_sameroutestep piece 1.0 min 1.0 min 7.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
50 | Diffusion_FE_94 Diffusion_FE_94 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR crit_sameroutestep piece 1.0 min 1.0 min 13.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
51 | EPI_36 EPI_36 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 2.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
52 | EPI_38 EPI_38 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 1.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
53 | Implant_119 Implant_119 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR wake_LeastSetupTime 1.0 min 1.0 min 2.0 2.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
54 | Implant_128 Implant_128 rule_LSSU rank_HP;rank_RSETUP;rank_CR wake_LeastSetupTime 1.0 min 1.0 min 2.0 11.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no Implant_Gas
55 | Implant_132 Implant_132 rule_LSSU rank_HP;rank_RSETUP;rank_CR wake_LeastSetupTime 1.0 min 1.0 min 2.0 7.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no Implant_Gas
56 | Implant_74 Implant_74 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 2.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
57 | Implant_88 Implant_88 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 2.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
58 | Implant_90 Implant_90 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR wake_LeastSetupTime 1.0 min 1.0 min 2.0 2.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
59 | Implant_91 Implant_91 rule_LSSU rank_HP;rank_RSETUP;rank_CR wake_LeastSetupTime 1.0 min 1.0 min 2.0 7.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no Implant_Gas
60 | Litho_BE_110 Litho_BE_110 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 23.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
61 | Litho_BE_93 Litho_BE_93 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 4.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
62 | Litho_BE_99 Litho_BE_99 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 3.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
63 | Litho_FE_111 Litho_FE_111 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 20.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
64 | Litho_FE_35 Litho_FE_35 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
65 | Litho_FE_92 Litho_FE_92 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 26.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
66 | Litho_FE_98 Litho_FE_98 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 4.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
67 | Litho_REG_BE_63 Litho_REG_BE_63 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 8.0 Litho_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
68 | Litho_REG_FE_64 Litho_REG_FE_64 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 12.0 Litho_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
69 | LithoMet_BE_18 LithoMet_BE_18 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 11.0 Litho_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
70 | LithoMet_FE_19 LithoMet_FE_19 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 14.0 Litho_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
71 | LithoTrack_BE_117 LithoTrack_BE_117 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 5.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
72 | LithoTrack_FE_115 LithoTrack_FE_115 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR wake_LeastSetupTime 1.0 min 1.0 min 41.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
73 | LithoTrack_FE_95 LithoTrack_FE_95 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR wake_LeastSetupTime 1.0 min 1.0 min 40.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
74 | LithoTrack_FE_96 LithoTrack_FE_96 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
75 | Planar_BE_75 Planar_BE_75 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 14.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
76 | Planar_FE_76 Planar_FE_76 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 2.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
77 | Planar_FE_77 Planar_FE_77 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 2.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
78 | Planar_FE_78 Planar_FE_78 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 2.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
79 | Planar_FE_79 Planar_FE_79 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 4.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
80 | Planar_FE_80 Planar_FE_80 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 2.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
81 | TF_BE_2 TF_BE_2 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 4.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
82 | TF_BE_23 TF_BE_23 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 14.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
83 | TF_BE_24 TF_BE_24 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 4.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
84 | TF_BE_26 TF_BE_26 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 13.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
85 | TF_BE_40 TF_BE_40 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 17.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
86 | TF_FE_103 TF_FE_103 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 7.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
87 | TF_FE_104 TF_FE_104 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 5.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
88 | TF_FE_113 TF_FE_113 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 3.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
89 | TF_FE_131 TF_FE_131 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 6.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
90 | TF_FE_3 TF_FE_3 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 3.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
91 | TF_FE_5 TF_FE_5 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 3.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
92 | TF_Met_FE_45 TF_Met_FE_45 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 TF_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
93 | TF_Met_FE_61 TF_Met_FE_61 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 TF_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
94 | WE_BE_14 WE_BE_14 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 5.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
95 | WE_BE_16 WE_BE_16 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 8.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
96 | WE_BE_17 WE_BE_17 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 2.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
97 | WE_BE_7 WE_BE_7 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 1.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
98 | WE_BE_81 WE_BE_81 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 3.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
99 | WE_BE_82 WE_BE_82 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 9.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
100 | WE_BE_9 WE_BE_9 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 5.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
101 | WE_FE_108 WE_FE_108 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 29.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
102 | WE_FE_41 WE_FE_41 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 5.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
103 | WE_FE_47 WE_FE_47 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 5.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
104 | WE_FE_8 WE_FE_8 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 2.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
105 | WE_FE_83 WE_FE_83 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 6.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
106 | WE_FE_84 WE_FE_84 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 17.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
107 | WE_FE_85 WE_FE_85 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_CR 1.0 min 1.0 min 2.0 2.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
108 |
--------------------------------------------------------------------------------
/datasets/SMT2020_HVLM/tool.txt.1l:
--------------------------------------------------------------------------------
1 | STNFAM STN RULE FWLRANK WAKERESRANK BATCHCRITF BATCHPER LTIME LTUNITS ULTIME ULTUNITS STNCAP STNQTY STNGRP STNFAMSTEP_ACTLIST STNFAMLOC PRERULERWL SETUPGRP
2 | DE_BE_11 DE_BE_11 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 10.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
3 | DE_BE_12 DE_BE_12 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 9.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
4 | DE_BE_13 DE_BE_13 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO wake_LeastSetupTime 1.0 min 1.0 min 21.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
5 | DE_BE_48 DE_BE_48 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 10.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
6 | DE_BE_50 DE_BE_50 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 9.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
7 | DE_BE_65 DE_BE_65 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 17.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
8 | DE_BE_66 DE_BE_66 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO wake_LeastSetupTime 1.0 min 1.0 min 19.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
9 | DE_BE_67 DE_BE_67 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 10.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
10 | DE_BE_69 DE_BE_69 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
11 | DE_FE_1 DE_FE_1 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 7.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
12 | DE_FE_51 DE_FE_51 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 19.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
13 | DE_FE_53 DE_FE_53 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 5.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
14 | DE_FE_54 DE_FE_54 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 5.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
15 | DE_FE_56 DE_FE_56 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
16 | DE_FE_58 DE_FE_58 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 3.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
17 | DE_FE_59 DE_FE_59 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 15.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
18 | DE_FE_62 DE_FE_62 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 14.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
19 | DE_FE_70 DE_FE_70 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 13.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
20 | DE_FE_71 DE_FE_71 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 28.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
21 | DE_FE_72 DE_FE_72 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 9.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
22 | DE_FE_86 DE_FE_86 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 135.0 Dry_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
23 | DefMet_BE_33 DefMet_BE_33 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
24 | DefMet_BE_42 DefMet_BE_42 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 1.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
25 | DefMet_FE_10 DefMet_FE_10 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
26 | DefMet_FE_106 DefMet_FE_106 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 1.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
27 | DefMEt_FE_118 DefMEt_FE_118 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
28 | DefMet_FE_34 DefMet_FE_34 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
29 | DefMet_FE_43 DefMet_FE_43 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 6.0 Def_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
30 | Delay_32 Delay1 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 0.0 min 0.0 min 400.0 Delay_32 Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Delay no
31 | Dielectric_BE_20 Dielectric_BE_20 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 5.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
32 | Dielectric_BE_21 Dielectric_BE_21 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 8.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
33 | Dielectric_BE_27 Dielectric_BE_27 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 15.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
34 | Dielectric_BE_28 Dielectric_BE_28 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 4.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
35 | Dielectric_BE_60 Dielectric_BE_60 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 4.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
36 | Dielectric_FE_112 Dielectric_FE_112 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 10.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
37 | Dielectric_FE_130 Dielectric_FE_130 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 4.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
38 | Dielectric_FE_29 Dielectric_FE_29 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 3.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
39 | Dielectric_FE_30 Dielectric_FE_30 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
40 | Dielectric_FE_31 Dielectric_FE_31 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 4.0 Dielectric Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
41 | Diffusion_BE_123 Diffusion_BE_123 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO crit_sameroutestep piece 1.0 min 1.0 min 12.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
42 | Diffusion_FE_100 Diffusion_FE_100 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO crit_sameroutestep piece 1.0 min 1.0 min 2.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
43 | Diffusion_FE_101 Diffusion_FE_101 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO crit_sameroutestep piece 1.0 min 1.0 min 7.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
44 | Diffusion_FE_120 Diffusion_FE_120 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO crit_sameroutestep piece 1.0 min 1.0 min 11.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
45 | Diffusion_FE_122 Diffusion_FE_122 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO crit_sameroutestep piece 1.0 min 1.0 min 5.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
46 | Diffusion_FE_125 Diffusion_FE_125 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO crit_sameroutestep piece 1.0 min 1.0 min 4.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
47 | Diffusion_FE_126 Diffusion_FE_126 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO crit_sameroutestep piece 1.0 min 1.0 min 3.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
48 | Diffusion_FE_127 Diffusion_FE_127 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO crit_sameroutestep piece 1.0 min 1.0 min 9.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
49 | Diffusion_FE_44 Diffusion_FE_44 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO crit_sameroutestep piece 1.0 min 1.0 min 11.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
50 | Diffusion_FE_94 Diffusion_FE_94 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO crit_sameroutestep piece 1.0 min 1.0 min 11.0 Diffusion Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
51 | EPI_36 EPI_36 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
52 | EPI_38 EPI_38 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 1.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
53 | Implant_119 Implant_119 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO wake_LeastSetupTime 1.0 min 1.0 min 2.0 2.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
54 | Implant_128 Implant_128 rule_LSSU rank_HP;rank_RSETUP;rank_FIFO wake_LeastSetupTime 1.0 min 1.0 min 2.0 10.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no Implant_Gas
55 | Implant_132 Implant_132 rule_LSSU rank_HP;rank_RSETUP;rank_FIFO wake_LeastSetupTime 1.0 min 1.0 min 2.0 8.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no Implant_Gas
56 | Implant_74 Implant_74 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
57 | Implant_88 Implant_88 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
58 | Implant_90 Implant_90 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO wake_LeastSetupTime 1.0 min 1.0 min 2.0 2.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
59 | Implant_91 Implant_91 rule_LSSU rank_HP;rank_RSETUP;rank_FIFO wake_LeastSetupTime 1.0 min 1.0 min 2.0 6.0 Implant Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no Implant_Gas
60 | Litho_BE_110 Litho_BE_110 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 28.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
61 | Litho_BE_93 Litho_BE_93 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 3.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
62 | Litho_BE_99 Litho_BE_99 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 3.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
63 | Litho_FE_111 Litho_FE_111 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 22.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
64 | Litho_FE_35 Litho_FE_35 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
65 | Litho_FE_92 Litho_FE_92 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 33.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
66 | Litho_FE_98 Litho_FE_98 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 5.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
67 | Litho_REG_BE_63 Litho_REG_BE_63 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 8.0 Litho_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
68 | Litho_REG_FE_64 Litho_REG_FE_64 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 14.0 Litho_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
69 | LithoMet_BE_18 LithoMet_BE_18 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 13.0 Litho_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
70 | LithoMet_FE_19 LithoMet_FE_19 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 18.0 Litho_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
71 | LithoTrack_BE_117 LithoTrack_BE_117 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 5.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
72 | LithoTrack_FE_115 LithoTrack_FE_115 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO wake_LeastSetupTime 1.0 min 1.0 min 51.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
73 | LithoTrack_FE_95 LithoTrack_FE_95 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO wake_LeastSetupTime 1.0 min 1.0 min 49.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
74 | LithoTrack_FE_96 LithoTrack_FE_96 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 Litho Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
75 | Planar_BE_75 Planar_BE_75 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 20.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
76 | Planar_FE_76 Planar_FE_76 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 3.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
77 | Planar_FE_77 Planar_FE_77 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
78 | Planar_FE_78 Planar_FE_78 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
79 | Planar_FE_79 Planar_FE_79 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 5.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
80 | Planar_FE_80 Planar_FE_80 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 Planar Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
81 | TF_BE_2 TF_BE_2 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 4.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
82 | TF_BE_23 TF_BE_23 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 19.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
83 | TF_BE_24 TF_BE_24 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 5.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
84 | TF_BE_26 TF_BE_26 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 15.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
85 | TF_BE_40 TF_BE_40 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 24.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
86 | TF_FE_103 TF_FE_103 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 4.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
87 | TF_FE_104 TF_FE_104 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 5.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
88 | TF_FE_113 TF_FE_113 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
89 | TF_FE_131 TF_FE_131 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 6.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
90 | TF_FE_3 TF_FE_3 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
91 | TF_FE_5 TF_FE_5 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 4.0 TF Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
92 | TF_Met_FE_45 TF_Met_FE_45 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 TF_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
93 | TF_Met_FE_61 TF_Met_FE_61 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 TF_Met Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
94 | WE_BE_14 WE_BE_14 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 5.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
95 | WE_BE_16 WE_BE_16 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 9.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
96 | WE_BE_17 WE_BE_17 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
97 | WE_BE_7 WE_BE_7 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 1.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
98 | WE_BE_81 WE_BE_81 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 3.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
99 | WE_BE_82 WE_BE_82 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 10.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
100 | WE_BE_9 WE_BE_9 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 7.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
101 | WE_FE_108 WE_FE_108 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 35.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
102 | WE_FE_41 WE_FE_41 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 5.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
103 | WE_FE_47 WE_FE_47 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 6.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
104 | WE_FE_8 WE_FE_8 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
105 | WE_FE_83 WE_FE_83 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 7.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
106 | WE_FE_84 WE_FE_84 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 18.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
107 | WE_FE_85 WE_FE_85 rule_HotLotFIRST rank_HP;rank_RSETUP;rank_FIFO 1.0 min 1.0 min 2.0 2.0 Wet_Etch Custom_actlist_ASISemiOpersDuringSetupAndAdditionalLoadUnload Fab no
108 |
--------------------------------------------------------------------------------