From c70e4b52c3abdacda97db7649e65330319a25488 Mon Sep 17 00:00:00 2001 From: bamsumit Date: Tue, 21 Nov 2023 12:31:37 -0800 Subject: [PATCH 1/9] Conv inp var model created Signed-off-by: bamsumit --- .../compiler/subcompilers/py/pyproc_compiler.py | 7 ++++++- src/lava/magma/compiler/var_model.py | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/lava/magma/compiler/subcompilers/py/pyproc_compiler.py b/src/lava/magma/compiler/subcompilers/py/pyproc_compiler.py index d916a1e52..0cd16ce70 100644 --- a/src/lava/magma/compiler/subcompilers/py/pyproc_compiler.py +++ b/src/lava/magma/compiler/subcompilers/py/pyproc_compiler.py @@ -30,6 +30,7 @@ ImplicitVarPort, VarPort, ) +from lava.magma.core.process.ports.connection_config import ConnectionConfig from lava.magma.core.process.process import AbstractProcess from lava.magma.compiler.subcompilers.constants import SPIKE_BLOCK_CORE @@ -189,7 +190,11 @@ def _create_inport_initializers( pi.embedded_counters = \ np.arange(counter_start_idx, counter_start_idx + num_counters, dtype=np.int32) - pi.connection_config = list(port.connection_configs.values())[0] + if port.connection_configs.values(): + conn_config = list(port.connection_configs.values())[0] + else: + conn_config = ConnectionConfig() + pi.connection_config = conn_config port_initializers.append(pi) self._tmp_channel_map.set_port_initializer(port, pi) else: diff --git a/src/lava/magma/compiler/var_model.py b/src/lava/magma/compiler/var_model.py index e33f3fbd9..0a6044e85 100644 --- a/src/lava/magma/compiler/var_model.py +++ b/src/lava/magma/compiler/var_model.py @@ -272,3 +272,17 @@ class NcSpikeIOVarModel(NcVarModel): decode_config: ty.Optional[DecodeConfig] = None time_compare: ty.Optional[TimeCompare] = None spike_encoder: ty.Optional[SpikeEncoder] = None + + +@dataclass +class NcConvSpikeInVarModel(NcSpikeIOVarModel): + region_map: ty.List[ty.List[ty.Tuple[int, int, int, int]]] = None + # Tuple will be in the order of [atom_paylod, atom_axon, chip, core] + + # for idx in range(port.size): + # rm = region_map[idx] + # activation = data[idx] + # for atom_paylod, atom_axon, chip, core in rm: + # payload = activation << 16 & (atom_paylod & 0xFFFF) + # axon = atom_axon + # nx_send(chip, core, axon, payload, time) From 36f4538aeb32b485045c2271517cef6c2f6ef324 Mon Sep 17 00:00:00 2001 From: bamsumit Date: Tue, 28 Nov 2023 19:44:45 -0800 Subject: [PATCH 2/9] Redesigned NcConvSpikeInVarModel Signed-off-by: bamsumit --- src/lava/magma/compiler/var_model.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lava/magma/compiler/var_model.py b/src/lava/magma/compiler/var_model.py index 0a6044e85..0c7331a2f 100644 --- a/src/lava/magma/compiler/var_model.py +++ b/src/lava/magma/compiler/var_model.py @@ -276,13 +276,15 @@ class NcSpikeIOVarModel(NcVarModel): @dataclass class NcConvSpikeInVarModel(NcSpikeIOVarModel): - region_map: ty.List[ty.List[ty.Tuple[int, int, int, int]]] = None - # Tuple will be in the order of [atom_paylod, atom_axon, chip, core] + region_map: ty.List[ty.List[ty.Tuple[int, int, int]]] = None + # Tuple will be in the order of [atom_paylod, atom_axon, addr_idx] # for idx in range(port.size): # rm = region_map[idx] # activation = data[idx] - # for atom_paylod, atom_axon, chip, core in rm: + # for atom_paylod, atom_axon, addr_idx in rm: + # chip = address[addr_idx].physical_chip_id + # core = address[addr_idx].physical_core_id # payload = activation << 16 & (atom_paylod & 0xFFFF) # axon = atom_axon # nx_send(chip, core, axon, payload, time) From 65b7a2080415a1709d2e5b1d889fdcdfe762ba13 Mon Sep 17 00:00:00 2001 From: bamsumit Date: Wed, 29 Nov 2023 12:10:03 -0800 Subject: [PATCH 3/9] Mapper note added Signed-off-by: bamsumit --- src/lava/magma/compiler/mapper.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lava/magma/compiler/mapper.py b/src/lava/magma/compiler/mapper.py index e05939f89..b3ddb170f 100644 --- a/src/lava/magma/compiler/mapper.py +++ b/src/lava/magma/compiler/mapper.py @@ -162,6 +162,10 @@ def map_cores(self, executable: Executable, address.update(chips) break if len(address) > 1 and hasattr(var_model, "address"): + print('=' * 50) + print('Note to JOYESH from the future:') + print('Add logic to make multichip conv input work for YOLO.') + print('=' * 50) raise ValueError("Lava Compiler doesn't support port" "splitting currently. MultiChip " "Not Supported ") From 8a70ff8bb5d4403bd4a4603b3546c1973a3d8b1f Mon Sep 17 00:00:00 2001 From: Joyesh Mishra Date: Wed, 13 Dec 2023 20:55:55 -0800 Subject: [PATCH 4/9] Make ethernet chip id and idx configuration in Connection Config --- src/lava/magma/compiler/var_model.py | 14 +++----------- .../magma/core/process/ports/connection_config.py | 3 +++ 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/lava/magma/compiler/var_model.py b/src/lava/magma/compiler/var_model.py index 0c7331a2f..94097e71e 100644 --- a/src/lava/magma/compiler/var_model.py +++ b/src/lava/magma/compiler/var_model.py @@ -269,6 +269,8 @@ class NcSpikeIOVarModel(NcVarModel): interface: SpikeIOInterface = SpikeIOInterface.ETHERNET spike_io_port: SpikeIOPort = SpikeIOPort.ETHERNET spike_io_mode: SpikeIOMode = SpikeIOMode.TIME_COMPARE + ethernet_chip_id: ty.Optional[ty.Tuple[int, int, int]] = None + ethernet_chip_idx: ty.Optional[int] = None decode_config: ty.Optional[DecodeConfig] = None time_compare: ty.Optional[TimeCompare] = None spike_encoder: ty.Optional[SpikeEncoder] = None @@ -276,15 +278,5 @@ class NcSpikeIOVarModel(NcVarModel): @dataclass class NcConvSpikeInVarModel(NcSpikeIOVarModel): - region_map: ty.List[ty.List[ty.Tuple[int, int, int]]] = None # Tuple will be in the order of [atom_paylod, atom_axon, addr_idx] - - # for idx in range(port.size): - # rm = region_map[idx] - # activation = data[idx] - # for atom_paylod, atom_axon, addr_idx in rm: - # chip = address[addr_idx].physical_chip_id - # core = address[addr_idx].physical_core_id - # payload = activation << 16 & (atom_paylod & 0xFFFF) - # axon = atom_axon - # nx_send(chip, core, axon, payload, time) + region_map: ty.List[ty.List[ty.Tuple[int, int, int]]] = None diff --git a/src/lava/magma/core/process/ports/connection_config.py b/src/lava/magma/core/process/ports/connection_config.py index 86b0a6d3d..551a7b50f 100644 --- a/src/lava/magma/core/process/ports/connection_config.py +++ b/src/lava/magma/core/process/ports/connection_config.py @@ -14,6 +14,7 @@ # expressly stated in the License. from dataclasses import dataclass from enum import IntEnum, Enum +import typing as ty class SpikeIOInterface(IntEnum): @@ -54,3 +55,5 @@ class ConnectionConfig: spike_io_mode: SpikeIOMode = SpikeIOMode.TIME_COMPARE num_time_buckets: int = 1 << 16 ethernet_mac_address: str = "0x90e2ba01214c" + ethernet_chip_id: ty.Optional[ty.Tuple[int, int, int]] = None + ethernet_chip_idx: ty.Optional[int] = None From c9cb03af15fbfff4bee3437c4fa3ac41dad81c7c Mon Sep 17 00:00:00 2001 From: Joyesh Mishra Date: Thu, 14 Dec 2023 19:09:15 -0800 Subject: [PATCH 5/9] Pass connection config and remove eth interface hard coding in pyncchannel.py --- src/lava/magma/compiler/subcompilers/py/pyproc_compiler.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lava/magma/compiler/subcompilers/py/pyproc_compiler.py b/src/lava/magma/compiler/subcompilers/py/pyproc_compiler.py index 0cd16ce70..9c74c92d8 100644 --- a/src/lava/magma/compiler/subcompilers/py/pyproc_compiler.py +++ b/src/lava/magma/compiler/subcompilers/py/pyproc_compiler.py @@ -214,7 +214,7 @@ def _create_outport_initializers( self, process: AbstractProcess ) -> ty.List[PortInitializer]: port_initializers = [] - for port in list(process.out_ports): + for k, port in enumerate(list(process.out_ports)): pi = PortInitializer( port.name, port.shape, @@ -223,6 +223,11 @@ def _create_outport_initializers( self._compile_config["pypy_channel_size"], port.get_incoming_transform_funcs(), ) + if port.connection_configs.values(): + conn_config = list(port.connection_configs.values())[k] + else: + conn_config = ConnectionConfig() + pi.connection_config = conn_config port_initializers.append(pi) self._tmp_channel_map.set_port_initializer(port, pi) return port_initializers From 4608d34b34fbcd5da83631f3b74c92e59508c409 Mon Sep 17 00:00:00 2001 From: bamsumit Date: Tue, 2 Jan 2024 13:18:21 -0800 Subject: [PATCH 6/9] Async Injector and Extractor models Signed-off-by: bamsumit --- src/lava/proc/io/extractor.py | 26 +++++++++++++++++++++ src/lava/proc/io/injector.py | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/src/lava/proc/io/extractor.py b/src/lava/proc/io/extractor.py index 1f0ca1cf8..436686a27 100644 --- a/src/lava/proc/io/extractor.py +++ b/src/lava/proc/io/extractor.py @@ -10,7 +10,9 @@ from lava.magma.core.resources import CPU from lava.magma.core.decorator import implements, requires from lava.magma.core.model.py.model import PyLoihiProcessModel +from lava.magma.core.model.py.model import PyAsyncProcessModel from lava.magma.core.sync.protocols.loihi_protocol import LoihiProtocol +from lava.magma.core.sync.protocols.async_protocol import AsyncProtocol from lava.magma.core.model.py.type import LavaPyType from lava.magma.core.model.py.ports import PyInPort, PyRefPort from lava.magma.compiler.channels.pypychannel import PyPyChannel @@ -137,6 +139,30 @@ def __del__(self) -> None: self._pm_to_p_src_port.join() +@implements(proc=Extractor, protocol=AsyncProtocol) +@requires(CPU) +class PyLoihiExtractorModelAsync(PyAsyncProcessModel): + in_port: PyInPort = LavaPyType(PyInPort.VEC_DENSE, float) + + def __init__(self, proc_params: dict) -> None: + super().__init__(proc_params=proc_params) + + channel_config = self.proc_params["channel_config"] + self._pm_to_p_src_port = self.proc_params["pm_to_p_src_port"] + self._pm_to_p_src_port.start() + + self._send = channel_config.get_send_full_function() + self.time_step = 1 + + def run_async(self) -> None: + while self.time_step != self.num_steps + 1: + self._send(self._pm_to_p_src_port, self.in_port.recv()) + self.time_step += 1 + + def __del__(self) -> None: + self._pm_to_p_src_port.join() + + class VarWire(AbstractProcess): """VarWire allows non-Lava code, such as a third-party Python library to tap data from a Lava Process Variable (Var) while the Lava Runtime is diff --git a/src/lava/proc/io/injector.py b/src/lava/proc/io/injector.py index e0c4207e5..2e5f19895 100644 --- a/src/lava/proc/io/injector.py +++ b/src/lava/proc/io/injector.py @@ -10,7 +10,9 @@ from lava.magma.core.resources import CPU from lava.magma.core.decorator import implements, requires from lava.magma.core.model.py.model import PyLoihiProcessModel +from lava.magma.core.model.py.model import PyAsyncProcessModel from lava.magma.core.sync.protocols.loihi_protocol import LoihiProtocol +from lava.magma.core.sync.protocols.async_protocol import AsyncProtocol from lava.magma.core.model.py.type import LavaPyType from lava.magma.core.model.py.ports import PyOutPort from lava.magma.runtime.message_infrastructure.multiprocessing import \ @@ -139,3 +141,45 @@ def run_spk(self) -> None: def __del__(self) -> None: self._p_to_pm_dst_port.join() + + +@implements(proc=Injector, protocol=AsyncProtocol) +@requires(CPU) +class PyLoihiInjectorModelAsync(PyAsyncProcessModel): + """PyAsyncProcessModel for the Injector Process.""" + out_port: PyOutPort = LavaPyType(PyOutPort.VEC_DENSE, float) + + def __init__(self, proc_params: dict) -> None: + super().__init__(proc_params=proc_params) + shape = self.proc_params["shape"] + channel_config = self.proc_params["channel_config"] + self._p_to_pm_dst_port = self.proc_params["p_to_pm_dst_port"] + self._p_to_pm_dst_port.start() + + self._zeros = np.zeros(shape) + + self._receive_when_empty = channel_config.get_receive_empty_function() + self._receive_when_not_empty = \ + channel_config.get_receive_not_empty_function() + self.time_step = 1 + + def run_async(self) -> None: + while self.time_step != self.num_steps + 1: + self._zeros.fill(0) + elements_in_buffer = self._p_to_pm_dst_port._queue.qsize() + + if elements_in_buffer == 0: + data = self._receive_when_empty( + self._p_to_pm_dst_port, + self._zeros) + else: + data = self._receive_when_not_empty( + self._p_to_pm_dst_port, + self._zeros, + elements_in_buffer) + self.out_port.send(data) + self.time_step += 1 + self.out_port.send(data) + + def __del__(self) -> None: + self._p_to_pm_dst_port.join() From 7bd51b265ff140d95b75c15a5394590acce40968 Mon Sep 17 00:00:00 2001 From: bamsumit Date: Tue, 2 Jan 2024 14:10:28 -0800 Subject: [PATCH 7/9] Async Injector and Extractor models Signed-off-by: bamsumit --- src/lava/proc/io/injector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lava/proc/io/injector.py b/src/lava/proc/io/injector.py index 2e5f19895..c240d1330 100644 --- a/src/lava/proc/io/injector.py +++ b/src/lava/proc/io/injector.py @@ -151,6 +151,7 @@ class PyLoihiInjectorModelAsync(PyAsyncProcessModel): def __init__(self, proc_params: dict) -> None: super().__init__(proc_params=proc_params) + shape = self.proc_params["shape"] channel_config = self.proc_params["channel_config"] self._p_to_pm_dst_port = self.proc_params["p_to_pm_dst_port"] @@ -179,7 +180,6 @@ def run_async(self) -> None: elements_in_buffer) self.out_port.send(data) self.time_step += 1 - self.out_port.send(data) def __del__(self) -> None: self._p_to_pm_dst_port.join() From 2be6c71204ce6b67ba4d160e9225846e65e49622 Mon Sep 17 00:00:00 2001 From: bamsumit Date: Tue, 2 Jan 2024 15:32:54 -0800 Subject: [PATCH 8/9] Added advance to timestep call for asyncwrapper Signed-off-by: bamsumit --- src/lava/magma/core/model/py/model.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lava/magma/core/model/py/model.py b/src/lava/magma/core/model/py/model.py index 40235d4e1..71dc75f93 100644 --- a/src/lava/magma/core/model/py/model.py +++ b/src/lava/magma/core/model/py/model.py @@ -759,6 +759,7 @@ def run_async(self) -> None: if py_loihi_model.post_guard(self): py_loihi_model.run_post_mgmt(self) self.time_step += 1 + self.advance_to_time_step(self.time_step) py_async_model = type( name, From ac23256a4285a6c1848c6bfcd26ca4d730bce11c Mon Sep 17 00:00:00 2001 From: bamsumit Date: Tue, 2 Jan 2024 16:11:43 -0800 Subject: [PATCH 9/9] Added advance to timestep call for asyncwrapper Signed-off-by: bamsumit --- src/lava/magma/core/model/py/model.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lava/magma/core/model/py/model.py b/src/lava/magma/core/model/py/model.py index 71dc75f93..ec6c252bc 100644 --- a/src/lava/magma/core/model/py/model.py +++ b/src/lava/magma/core/model/py/model.py @@ -759,7 +759,10 @@ def run_async(self) -> None: if py_loihi_model.post_guard(self): py_loihi_model.run_post_mgmt(self) self.time_step += 1 - self.advance_to_time_step(self.time_step) + # self.advance_to_time_step(self.time_step) + for port in self.py_ports: + if isinstance(port, PyOutPort): + port.advance_to_time_step(self.time_step) py_async_model = type( name,