Skip to content

Commit f715f45

Browse files
Fix for multiple procs modules at the same time
1 parent cf20f95 commit f715f45

4 files changed

Lines changed: 68 additions & 41 deletions

File tree

hwcomponents/find_models.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import glob
22
import importlib
3+
import importlib.util
34
from importlib.machinery import SourceFileLoader
45
from pathlib import Path
56
from types import ModuleType
@@ -10,9 +11,11 @@
1011
import copy
1112
import sys
1213
import os
14+
import threading
1315
from pkgutil import iter_modules
1416

1517
_ALL_ESTIMATORS = None
18+
_MODULE_LOAD_LOCK = threading.Lock()
1619

1720

1821
def installed_models(
@@ -243,8 +246,17 @@ def get_models(
243246
module_name = f"_hwc_model_{base_name}_{abs(hash(os.path.abspath(path)))}"
244247
if abs_dir not in sys.path:
245248
sys.path.append(abs_dir)
246-
python_module = SourceFileLoader(module_name, path).load_module()
247-
sys.modules[module_name] = python_module
249+
with _MODULE_LOAD_LOCK:
250+
python_module = sys.modules.get(module_name)
251+
if python_module is None:
252+
spec = importlib.util.spec_from_file_location(module_name, path)
253+
python_module = importlib.util.module_from_spec(spec)
254+
sys.modules[module_name] = python_module
255+
try:
256+
spec.loader.exec_module(python_module)
257+
except BaseException:
258+
sys.modules.pop(module_name, None)
259+
raise
248260
new_models += get_models_in_module(
249261
python_module, model_ids, _return_wrappers
250262
)

hwcomponents/scaling/techscaling.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from math import ceil, floor
88
from typing import Union
99

10-
1110
TECH_NODES = [130e-9, 90e-9, 65e-9, 45e-9, 32e-9, 20e-9, 16e-9, 14e-9, 10e-9, 7e-9]
1211
AREA_SCALING = [
1312
[1, 0.44, 0.23, 0.16, 0.072, 0.033, 0.03, 0.027, 0.016, 0.0092],

notebooks/1_finding_and_using_models.ipynb

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"outputs": [],
2020
"source": [
2121
"import logging\n",
22+
"\n",
2223
"logging.getLogger().setLevel(logging.WARNING)\n",
2324
"import hwcomponents as hwc"
2425
]
@@ -46,11 +47,11 @@
4647
"import hwcomponents as hwc\n",
4748
"\n",
4849
"# Find and list all installed component models\n",
49-
"print(f'Listing component models')\n",
50+
"print(f\"Listing component models\")\n",
5051
"all_installed_models = hwc.get_models()\n",
51-
"print(f'Number of available component models: {len(all_installed_models)}')\n",
52+
"print(f\"Number of available component models: {len(all_installed_models)}\")\n",
5253
"for model in all_installed_models[:5]:\n",
53-
" print(f'{model.__name__} supports {model.component_name}')"
54+
" print(f\"{model.__name__} supports {model.component_name}\")"
5455
]
5556
},
5657
{
@@ -74,16 +75,17 @@
7475
"# < DOC_INCLUDE_MARKER > finding_components_2\n",
7576
"\n",
7677
"# Find an SRAM model\n",
77-
"print(f'\\nListing SRAM models')\n",
78-
"sram_models = hwc.get_models(name_must_include='sram')\n",
79-
"print(f'Number of SRAM models: {len(sram_models)}')\n",
78+
"print(f\"\\nListing SRAM models\")\n",
79+
"sram_models = hwc.get_models(name_must_include=\"sram\")\n",
80+
"print(f\"Number of SRAM models: {len(sram_models)}\")\n",
8081
"for model in sram_models[:5]:\n",
81-
" print(f'{model.__name__} supports {model.component_name}')\n",
82+
" print(f\"{model.__name__} supports {model.component_name}\")\n",
8283
"\n",
8384
"# Grab the CACI SRAM model & use the \"help\" function to see its documentation\n",
8485
"models = [s for s in sram_models if \"hwcomponents_cacti\" in s.__module__]\n",
85-
"assert len(models) == 1, \\\n",
86-
" f\"Excected 1 CACTI SRAM model, got {len(models)}. Is hwcomponents_cacti installed?\"\n",
86+
"assert (\n",
87+
" len(models) == 1\n",
88+
"), f\"Excected 1 CACTI SRAM model, got {len(models)}. Is hwcomponents_cacti installed?\"\n",
8789
"sram = models[0]\n",
8890
"help(sram)"
8991
]
@@ -116,10 +118,10 @@
116118
")\n",
117119
"r = sram.read(bits_per_action=8)\n",
118120
"w = sram.write(bits_per_action=8)\n",
119-
"print(f'SRAM read: energy {r.energy:.2e} J, throughput {r.throughput:.2e} actions/s')\n",
120-
"print(f'SRAM write: energy {w.energy:.2e} J, throughput {w.throughput:.2e} actions/s')\n",
121-
"print(f'SRAM area: {sram.area} m^2')\n",
122-
"print(f'SRAM leak power: {sram.leak_power} W')"
121+
"print(f\"SRAM read: energy {r.energy:.2e} J, throughput {r.throughput:.2e} actions/s\")\n",
122+
"print(f\"SRAM write: energy {w.energy:.2e} J, throughput {w.throughput:.2e} actions/s\")\n",
123+
"print(f\"SRAM area: {sram.area} m^2\")\n",
124+
"print(f\"SRAM leak power: {sram.leak_power} W\")"
123125
]
124126
},
125127
{
@@ -147,14 +149,17 @@
147149
"\n",
148150
"# Method 1: Import the model from a module and use it directly.\n",
149151
"from hwcomponents_cacti import SRAM\n",
152+
"\n",
150153
"sram = SRAM(\n",
151154
" tech_node=40e-9, # 40nm\n",
152155
" width=64,\n",
153156
" depth=1024,\n",
154157
" size=64 * 1024,\n",
155158
")\n",
156159
"cost = sram.read()\n",
157-
"print(f\"SRAM read energy {cost.energy:.2e} J, throughput {cost.throughput:.2e} actions/s\")\n",
160+
"print(\n",
161+
" f\"SRAM read energy {cost.energy:.2e} J, throughput {cost.throughput:.2e} actions/s\"\n",
162+
")\n",
158163
"print(f\"SRAM area is {sram.area:.2e}m^2. Leak power is {sram.leak_power:.2e}W\")\n",
159164
"\n",
160165
"\n",

notebooks/2_making_models.ipynb

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
" tech_node_throughput,\n",
5555
")\n",
5656
"\n",
57+
"\n",
5758
"class TernaryMAC(ComponentModel):\n",
5859
" \"\"\"\n",
5960
"\n",
@@ -74,7 +75,7 @@
7475
" The technology node in meters.\n",
7576
" \"\"\"\n",
7677
"\n",
77-
" component_name: str | list[str] = 'TernaryMAC'\n",
78+
" component_name: str | list[str] = \"TernaryMAC\"\n",
7879
" \"\"\" Name of the component. Must be a string or list/tuple of strings. \"\"\"\n",
7980
"\n",
8081
" priority = 0.3\n",
@@ -87,10 +88,7 @@
8788
" def __init__(self, accum_n_bits: int, tech_node: int):\n",
8889
" # Provide an area and leakage power for the component. All units are in\n",
8990
" # standard units without any prefixes (Joules, Watts, meters, etc.).\n",
90-
" super().__init__(\n",
91-
" area=5e-12 * accum_n_bits,\n",
92-
" leak_power=1e-3 * accum_n_bits\n",
93-
" )\n",
91+
" super().__init__(area=5e-12 * accum_n_bits, leak_power=1e-3 * accum_n_bits)\n",
9492
"\n",
9593
" # Scale tech_node to the target from the 40nm reference.\n",
9694
" self.tech_node = self.scale(\n",
@@ -105,8 +103,9 @@
105103
" )\n",
106104
" self.accum_n_bits = accum_n_bits\n",
107105
"\n",
108-
" assert 4 <= accum_n_bits <= 8, \\\n",
109-
" f'Accumulation number of bits {accum_n_bits} outside supported range [4, 8]'\n",
106+
" assert (\n",
107+
" 4 <= accum_n_bits <= 8\n",
108+
" ), f\"Accumulation number of bits {accum_n_bits} outside supported range [4, 8]\"\n",
110109
"\n",
111110
" # The action decorator makes this function visible as an action. Return an\n",
112111
" # ActionCost; throughput defaults to 1/latency if not given.\n",
@@ -125,15 +124,22 @@
125124
" ActionCost\n",
126125
" The cost of this action.\n",
127126
" \"\"\"\n",
128-
" self.logger.info(f'TernaryMAC Model is estimating energy for mac_random.')\n",
127+
" self.logger.info(f\"TernaryMAC Model is estimating energy for mac_random.\")\n",
129128
" if clock_gated:\n",
130129
" return ActionCost(energy=0.0, throughput=float(\"inf\"), latency=0.0)\n",
131-
" return ActionCost(energy=0.002e-12 * (self.accum_n_bits + 0.25), throughput=float(\"inf\"), latency=0.0)\n",
130+
" return ActionCost(\n",
131+
" energy=0.002e-12 * (self.accum_n_bits + 0.25),\n",
132+
" throughput=float(\"inf\"),\n",
133+
" latency=0.0,\n",
134+
" )\n",
135+
"\n",
132136
"\n",
133-
"mac = TernaryMAC(accum_n_bits=8, tech_node=16e-9) # Scale the TernaryMAC to 16nm\n",
137+
"mac = TernaryMAC(accum_n_bits=8, tech_node=16e-9) # Scale the TernaryMAC to 16nm\n",
134138
"cost = mac.mac()\n",
135-
"print(f'TernaryMAC energy is {cost.energy:.2e}J (throughput {cost.throughput:.2e} actions/s). '\n",
136-
" f'Area is {mac.area:.2e}m^2. Leak power is {mac.leak_power:.2e}W')"
139+
"print(\n",
140+
" f\"TernaryMAC energy is {cost.energy:.2e}J (throughput {cost.throughput:.2e} actions/s). \"\n",
141+
" f\"Area is {mac.area:.2e}m^2. Leak power is {mac.leak_power:.2e}W\"\n",
142+
")"
137143
]
138144
},
139145
{
@@ -155,6 +161,7 @@
155161
"source": [
156162
"# < DOC_INCLUDE_MARKER > scaling_by_number_of_bits\n",
157163
"\n",
164+
"\n",
158165
"class LPDDR4(ComponentModel):\n",
159166
" \"\"\"LPDDR4 DRAM energy model.\"\"\"\n",
160167
"\n",
@@ -228,6 +235,7 @@
228235
"from hwcomponents import ComponentModel, action\n",
229236
"import math\n",
230237
"\n",
238+
"\n",
231239
"class SmartBufferSRAM(ComponentModel):\n",
232240
" \"\"\"\n",
233241
" An SRAM with an address generator that sequentially reads addresses in the SRAM.\n",
@@ -240,16 +248,17 @@
240248
" n_rw_ports: The number of read/write ports.\n",
241249
" n_banks: The number of banks.\n",
242250
" \"\"\"\n",
251+
"\n",
243252
" component_name = [\"smart_buffer_sram\", \"smartbuffer_sram\", \"smartbuffersram\"]\n",
244253
" priority = 0.3\n",
245254
"\n",
246255
" def __init__(\n",
247-
" self,\n",
248-
" tech_node: float,\n",
249-
" width: int,\n",
250-
" depth: int,\n",
251-
" n_rw_ports: int=1,\n",
252-
" n_banks: int=1,\n",
256+
" self,\n",
257+
" tech_node: float,\n",
258+
" width: int,\n",
259+
" depth: int,\n",
260+
" n_rw_ports: int = 1,\n",
261+
" n_banks: int = 1,\n",
253262
" ):\n",
254263
" self.sram: SRAM = SRAM(\n",
255264
" tech_node=tech_node,\n",
@@ -268,12 +277,14 @@
268277
"\n",
269278
" # If there are subcomponents, we can omit area and leak_power; their cost\n",
270279
" # accumulates from the subcomponents.\n",
271-
" super().__init__(subcomponents=[\n",
280+
" super().__init__(\n",
281+
" subcomponents=[\n",
272282
" self.sram,\n",
273283
" self.address_reg,\n",
274284
" self.delta_reg,\n",
275285
" self.adder,\n",
276-
" ])\n",
286+
" ]\n",
287+
" )\n",
277288
"\n",
278289
" @action(bits_per_action=\"width\")\n",
279290
" def read(self) -> ActionCost:\n",
@@ -328,10 +339,10 @@
328339
"\n",
329340
"r = smartbuffer_sram.read(bits_per_action=32)\n",
330341
"w = smartbuffer_sram.write(bits_per_action=32)\n",
331-
"print(f'Read energy: {r.energy} J, throughput: {r.throughput} actions/s')\n",
332-
"print(f'Write energy: {w.energy} J, throughput: {w.throughput} actions/s')\n",
333-
"print(f'Area: {smartbuffer_sram.area} m^2')\n",
334-
"print(f'Leak power: {smartbuffer_sram.leak_power} W')"
342+
"print(f\"Read energy: {r.energy} J, throughput: {r.throughput} actions/s\")\n",
343+
"print(f\"Write energy: {w.energy} J, throughput: {w.throughput} actions/s\")\n",
344+
"print(f\"Area: {smartbuffer_sram.area} m^2\")\n",
345+
"print(f\"Leak power: {smartbuffer_sram.leak_power} W\")"
335346
]
336347
}
337348
],

0 commit comments

Comments
 (0)