Skip to content

Commit 5c87e96

Browse files
Unit fix
1 parent 6b9460a commit 5c87e96

1 file changed

Lines changed: 4 additions & 150 deletions

File tree

hwcomponents_neurosim/main.py

Lines changed: 4 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,10 @@ def get_neurosim_output(
499499
cell size.
500500
"""
501501
)
502+
503+
# pJ->J, um^2->m^2
504+
rval = {k: v / 1e12 for k, v in rval.items()}
505+
502506
return rval
503507

504508
def query_neurosim(self, kind: str, logger: logging.Logger) -> Dict[str, float]:
@@ -1398,156 +1402,6 @@ def build_crossbar(
13981402
return CACHE[key]
13991403

14001404

1401-
def get_neurosim_output(
1402-
kind: str, attributes: dict, logger: logging.Logger
1403-
) -> Dict[str, float]:
1404-
"""Queries Neurosim for the stats for 'kind' component with 'attributes' attributes"""
1405-
assert kind in SUPPORTED_CLASSES, f"Unsupported primitive: {kind}"
1406-
logger.debug("Querying Neurosim for %s with attributes: %s", kind, attributes)
1407-
1408-
# Load defaults
1409-
to_pass = {k: v[1] for k, v in ALL_PARAMS.items()}
1410-
# Get call function ready
1411-
callfunc = SUPPORTED_CLASSES[kind][0]
1412-
params = SUPPORTED_CLASSES[kind][1]
1413-
docs = {k: v[0] for k, v in params.items()}
1414-
1415-
# Get required parameters
1416-
for p in params:
1417-
if "REQUIRED" in params[p][0]:
1418-
assert p in attributes, (
1419-
f"Failed to generate {kind}. Required parameter not found: "
1420-
f"{p}. Usage: \n{dict_to_str(docs)}"
1421-
)
1422-
elif p not in attributes:
1423-
attributes[p] = to_pass[p]
1424-
1425-
passtype = params[p][2] if len(params[p]) > 2 else int
1426-
try:
1427-
if isinstance(attributes[p], str) and passtype != str:
1428-
t = "".join(c for c in attributes[p] if (c.isdigit() or c == "."))
1429-
else:
1430-
t = attributes[p]
1431-
if t != attributes[p]:
1432-
logger.warning(
1433-
f"WARN: Non-numeric {attributes[p]} for parameter {p}. Using {t} instead."
1434-
)
1435-
to_pass[p] = passtype(t)
1436-
except ValueError as e:
1437-
raise ValueError(
1438-
f"Failed to generate {kind}. Parameter {p} must be of type "
1439-
f'{passtype}. Given: "{attributes[p]}" Usage: \n{dict_to_str(docs)}'
1440-
) from e
1441-
1442-
tn = PERMITTED_TECH_NODES
1443-
assert to_pass["rows"] >= 8, f'Rows must be >=8. Got {to_pass["rows"]}'
1444-
assert to_pass["cols"] >= 8, f'Columns must be >=8. Given: {to_pass["columns"]}'
1445-
assert to_pass["cols_active_at_once"] >= 1, (
1446-
f"Columns active at once must be >=1 and divide evenly into cols. "
1447-
f'Given: {to_pass["cols"]} cols, {to_pass["cols_active_at_once"]} cols active at once'
1448-
)
1449-
assert (
1450-
min(tn) <= to_pass["tech_node"] <= max(tn)
1451-
), f'Tech node must be between {max(tn)} and {min(tn)}. Given: {to_pass["tech_node"]}'
1452-
assert (
1453-
to_pass["n_bits"] >= 1
1454-
), f'Adder resolution must be >=1. Given: {to_pass["n_bits"]}'
1455-
assert (
1456-
to_pass["shift_register_n_bits"] >= 1
1457-
), f'Shift register resolution must be >=1. Given: {to_pass["shift_register_n_bits"]}'
1458-
assert (
1459-
to_pass["pool_window"] >= 1
1460-
), f'Max pool window size must be >=1. Given: {to_pass["window_size"]}'
1461-
assert (
1462-
to_pass["n_adder_tree_inputs"] > 0
1463-
), f'Number of adder tree inputs must be >=1. Given: {to_pass["n_adder_tree_inputs"]}'
1464-
assert (
1465-
to_pass["n_mux_inputs"] > 0
1466-
), f'Number of mux inputs must be >=1. Given: {to_pass["n_mux_inputs"]}'
1467-
assert (
1468-
to_pass["voltage_dac_bits"] > 0
1469-
), f'Voltage DAC bits must be >=1. Given: {to_pass["voltage_dac_bits"]}'
1470-
assert (
1471-
to_pass["temporal_dac_bits"] > 0
1472-
), f'Temporal DAC bits must be >=1. Given: {to_pass["temporal_dac_bits"]}'
1473-
1474-
if not os.path.exists(to_pass["cell_config"]):
1475-
cell_config = os.path.join(
1476-
SCRIPT_DIR, "cells", to_pass["cell_config"] + ".cell"
1477-
)
1478-
assert os.path.exists(cell_config), (
1479-
f'Cell config {to_pass["cell_config"]}" not found. '
1480-
f'Try a sample config: "{", ".join(SAMPLE_CELLS)}'
1481-
)
1482-
to_pass["cell_config"] = cell_config
1483-
1484-
# Interpolate the tech_node node. If p is in PERMITTED_TECH_NODES, then all this
1485-
# comes out to just p. If p is not in PERMITTED_TECH_NODES, then we interpolate
1486-
# between the two closest.
1487-
t = to_pass["tech_node"]
1488-
del to_pass["tech_node"]
1489-
1490-
for k in attributes:
1491-
if k not in to_pass:
1492-
to_pass[k] = attributes[k]
1493-
1494-
hi = min(p for p in PERMITTED_TECH_NODES if p >= t)
1495-
lo = max(p for p in PERMITTED_TECH_NODES if p <= t)
1496-
interp_pt = (t - lo) / (hi - lo) if hi - lo else 0
1497-
hi_crossbar = build_crossbar(to_pass, logger, overrides={"tech_node": hi})
1498-
lo_crossbar = build_crossbar(to_pass, logger, overrides={"tech_node": lo})
1499-
hi_est = callfunc(
1500-
hi_crossbar, to_pass["average_input_value"], to_pass["average_cell_value"]
1501-
)
1502-
lo_est = callfunc(
1503-
lo_crossbar, to_pass["average_input_value"], to_pass["average_cell_value"]
1504-
)
1505-
if hi != lo:
1506-
logger.debug(
1507-
"Interpolating between %s and %s. Interpolation " "point: %s",
1508-
lo,
1509-
hi,
1510-
interp_pt,
1511-
)
1512-
1513-
rval = {k: lo_est[k] + (hi_est[k] - lo_est[k]) * interp_pt for k in hi_est}
1514-
logger.debug("NeuroSim returned: %s", rval)
1515-
1516-
assert rval["Area"] >= 0, dedent(
1517-
"""
1518-
NeuroSim returned an area less than zero. This may occur if the array or
1519-
memory cell size is too small for proper layout of peripheral
1520-
components. Try increasing the number of rows/columns or increasing the
1521-
cell size.
1522-
"""
1523-
)
1524-
1525-
return rval
1526-
1527-
1528-
def query_neurosim(
1529-
kind: str, attributes: dict, logger: logging.Logger
1530-
) -> Dict[str, float]:
1531-
for n in ["array_adc", "array_col_drivers"]:
1532-
assert (
1533-
n in SUPPORTED_CLASSES
1534-
), "Please update this method body to support the new NeuroSim names."
1535-
1536-
if kind == "array_col_drivers":
1537-
attributes["adc_resolution"] = 0
1538-
return get_neurosim_output(kind, attributes, logger)
1539-
1540-
if kind in ["array_adc", "array_col_drivers"]:
1541-
logger.info("First running WITH the ADC to get total energy")
1542-
with_adc = get_neurosim_output(kind, attributes, logger)
1543-
attributes["adc_resolution"] = 0
1544-
logger.info("Now running WITHOUT the ADC to get column driver energy")
1545-
without_adc = get_neurosim_output(kind, attributes, logger)
1546-
logger.info("Subtracting column driver energy to get ADC energy")
1547-
return {k: with_adc[k] - without_adc[k] for k in with_adc}
1548-
return get_neurosim_output(kind, attributes, logger)
1549-
1550-
15511405
def dict_to_str(attributes: Dict) -> str:
15521406
"""Converts a dictionary into a multi-line string representation"""
15531407
s = "\n"

0 commit comments

Comments
 (0)