From c9d5a13be2a30fa56c171dfb83b704624a26d03a Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Wed, 1 Feb 2023 16:31:52 +0530 Subject: [PATCH 01/27] Expose cost from CostIntegrator on the OptimizationSolver. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/builder.py | 1 + src/lava/lib/optimization/solvers/generic/dataclasses.py | 4 ++++ .../optimization/solvers/generic/hierarchical_processes.py | 1 + .../lib/optimization/solvers/generic/sub_process_models.py | 1 + 4 files changed, 7 insertions(+) diff --git a/src/lava/lib/optimization/solvers/generic/builder.py b/src/lava/lib/optimization/solvers/generic/builder.py index 5ed82158..d672c17f 100644 --- a/src/lava/lib/optimization/solvers/generic/builder.py +++ b/src/lava/lib/optimization/solvers/generic/builder.py @@ -179,6 +179,7 @@ def constructor(self, self.optimality = Var(shape=(1,)) self.feasibility = Var(shape=(1,)) self.solution_step = Var(shape=(1,)) + self.cost_monitor = Var(shape=(1,)) self._process_constructor = constructor diff --git a/src/lava/lib/optimization/solvers/generic/dataclasses.py b/src/lava/lib/optimization/solvers/generic/dataclasses.py index 35f5e138..297b6d62 100644 --- a/src/lava/lib/optimization/solvers/generic/dataclasses.py +++ b/src/lava/lib/optimization/solvers/generic/dataclasses.py @@ -93,6 +93,10 @@ class MacroStateReader: def solution_step(self): return self.solution_readout.solution_step + @property + def cost(self): + return self.cost_convergence_check.cost + @property def cost_in(self): return self.cost_convergence_check.cost_components diff --git a/src/lava/lib/optimization/solvers/generic/hierarchical_processes.py b/src/lava/lib/optimization/solvers/generic/hierarchical_processes.py index e03228b5..cfe40451 100644 --- a/src/lava/lib/optimization/solvers/generic/hierarchical_processes.py +++ b/src/lava/lib/optimization/solvers/generic/hierarchical_processes.py @@ -114,6 +114,7 @@ def __init__( super().__init__(shape=shape, name=name, log_config=log_config) self.shape = shape self.min_cost = Var(shape=(1,)) + self.cost = Var(shape=(1,)) self.cost_components = InPort(shape=shape) self.update_buffer = OutPort(shape=(1,)) diff --git a/src/lava/lib/optimization/solvers/generic/sub_process_models.py b/src/lava/lib/optimization/solvers/generic/sub_process_models.py index 30b895e2..9ce03dda 100644 --- a/src/lava/lib/optimization/solvers/generic/sub_process_models.py +++ b/src/lava/lib/optimization/solvers/generic/sub_process_models.py @@ -136,6 +136,7 @@ def __init__(self, proc): self.cost_integrator.out_ports.update_buffer.connect( proc.out_ports.update_buffer) proc.vars.min_cost.alias(self.cost_integrator.vars.min_cost) + proc.vars.cost.alias(self.cost_integrator.vars.cost) @implements(proc=StochasticIntegrateAndFire, protocol=LoihiProtocol) From ec3c06594aa280c1b0690f38bd817e970e10c050 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Wed, 1 Feb 2023 16:32:40 +0530 Subject: [PATCH 02/27] Enable cost tracking on the OptimizationSolver. Signed-off-by: GaboFGuerra --- .../optimization/solvers/generic/solver.py | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index 5d8bb75b..c8fb59b6 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -3,6 +3,7 @@ # See: https://spdx.org/licenses/ import typing as ty from dataclasses import dataclass +from lava.proc.monitor.process import Monitor from lava.utils.profiler import Profiler import numpy.typing as npt @@ -21,12 +22,14 @@ Loihi2NeuroCore, NeuroCore, ) -from lava.magma.core.run_conditions import RunContinuous, RunSteps +from lava.magma.core.run_conditions import RunSteps from lava.magma.core.run_configs import Loihi1SimCfg, Loihi2HwCfg from lava.magma.core.sync.protocol import AbstractSyncProtocol from lava.magma.core.sync.protocols.loihi_protocol import LoihiProtocol from lava.proc.dense.models import PyDenseModelFloat from lava.proc.dense.process import Dense +from lava.utils.loihi2_state_probes import StateProbe + from lava.lib.optimization.solvers.generic.read_gate.models import \ ReadGatePyModel from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate @@ -87,6 +90,7 @@ class SolverConfig: target_cost: int = 0 backend: BACKENDS = CPU hyperparameters: dict = None + probe_cost: bool = False probe_time: bool = False probe_energy: bool = False log_level: int = 40 @@ -113,9 +117,19 @@ class SolverReport: best_cost: int = None best_state: np.ndarray = None best_timestep: int = None + cost_timeseries: np.ndarray = None solver_config: SolverConfig = None profiler: Profiler = None + def plot_cost_timeseries(self, filename: str = None) -> None: + if self.cost_timeseries is None: + return NotImplemented # what to do? + from matplotlib import pyplot as plt + plt.plot(self.cost_timeseries, "ro") + if filename is None: + plt.show() + else: + plt.savefig(filename) def solve(problem: OptimizationProblem, config: SolverConfig = SolverConfig()) -> np.ndarray: @@ -163,6 +177,7 @@ def __init__(self, problem: OptimizationProblem): self.solver_process = None self.solver_model = None self._profiler = None + self._cost_tracker = None def solve(self, config: SolverConfig = SolverConfig()) -> SolverReport: """ @@ -182,20 +197,29 @@ def solve(self, config: SolverConfig = SolverConfig()) -> SolverReport: self.solver_process.run(condition=run_condition, run_cfg=run_cfg) best_state, best_cost, best_timestep = self._get_results() self.solver_process.stop() - + cost_timeseries = self._get_cost_tracking() report = SolverReport( best_cost=best_cost, best_state=best_state, best_timestep=best_timestep, solver_config=config, - profiler=self._profiler + profiler=self._profiler, + cost_timeseries=cost_timeseries ) return report def _prepare_solver(self, config: SolverConfig): + if config.probe_cost: + if config.backend == "Loihi2": + self._cost_tracker = StateProbe(self.solver_process.optimality) + if config.backend == "CPU": + self._cost_tracker = Monitor() + self._cost_tracker.probe(target=self.solver_process.optimality, + num_steps=config.timeout) self._create_solver_process(config=config) - run_cfg = self._get_run_config(backend=config.backend) + run_cfg = self._get_run_config(backend=config.backend, + probes=[self._cost_tracker]) run_condition = RunSteps(num_steps=config.timeout) self._prepare_profiler(config=config, run_cfg=run_cfg) return run_condition, run_cfg @@ -239,7 +263,14 @@ def _get_requirements_and_protocol( """ return [CPU] if backend in CPUS else [Loihi2NeuroCore], LoihiProtocol - def _get_run_config(self, backend: BACKENDS): + def _get_cost_tracking(self): + if type(self._cost_tracker) is Monitor: + return self._cost_tracker.get_data()[self.solver_process.name][ + self.solver_process.optimality.name].T.astype(np.int32) + elif type(self._cost_tracker) is StateProbe: + return self._cost_tracker.time_series + + def _get_run_config(self, backend: BACKENDS, probes=None): if backend in CPUS: pdict = {self.solver_process: self.solver_model, ReadGate: ReadGatePyModel, @@ -257,7 +288,9 @@ def _get_run_config(self, backend: BACKENDS): BoltzmannAbstractModel, } return Loihi2HwCfg(exception_proc_model_map=pdict, - select_sub_proc_model=True) + select_sub_proc_model=True, + callback_fxs=probes + ) else: raise NotImplementedError(str(backend) + BACKEND_MSG) From 8cf27f52ec0ddac03fb2eee9c93f1f9935c582f8 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Wed, 8 Mar 2023 17:06:05 +0100 Subject: [PATCH 03/27] Remove obsolete code. Signed-off-by: GaboFGuerra --- .../lib/optimization/solvers/generic/solver.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index 3134ff44..e06674f4 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -158,15 +158,6 @@ class SolverReport: solver_config: SolverConfig = None profiler: Profiler = None - def plot_cost_timeseries(self, filename: str = None) -> None: - if self.cost_timeseries is None: - return NotImplemented # what to do? - from matplotlib import pyplot as plt - plt.plot(self.cost_timeseries, "ro") - if filename is None: - plt.show() - else: - plt.savefig(filename) def solve( problem: OptimizationProblem, config: SolverConfig = SolverConfig() @@ -246,18 +237,11 @@ def solve(self, config: SolverConfig = SolverConfig()) -> SolverReport: ) def _prepare_solver(self, config: SolverConfig): - if config.probe_cost: - if config.backend == "Loihi2": - self._cost_tracker = StateProbe(self.solver_process.optimality) - if config.backend == "CPU": - self._cost_tracker = Monitor() - self._cost_tracker.probe(target=self.solver_process.optimality, - num_steps=config.timeout) self._create_solver_process(config=config) if config.probe_cost: if config.backend in NEUROCORES: # from lava.utils.loihi2_state_probes import StateProbe - # self._cost_tracker = StateProbe() + # self._cost_tracker = StateProbe(self.solver_process.optimality) raise NotImplementedError if config.backend in CPUS: self._cost_tracker = Monitor() From b4cc0c6c7a792fb117eea2dac834e31b21f67f03 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Mon, 13 Mar 2023 15:38:06 +0100 Subject: [PATCH 04/27] Resolve import issue for ReadGate. Signed-off-by: GaboFGuerra --- .../optimization/solvers/generic/solver.py | 57 ++++++++++--------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index ee6dac39..a5fec35d 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -27,6 +27,7 @@ NEBMAbstractModel, NEBMSimulatedAnnealingAbstractModel, ) + from lava.magma.core.resources import ( AbstractComputeResource, CPU, @@ -315,41 +316,41 @@ def _get_cost_tracking(self): def _get_run_config(self, backend: BACKENDS, probes=None, num_in_ports: int = None): + from lava.lib.optimization.solvers.generic.read_gate.process \ + import ReadGate + from lava.lib.optimization.solvers.generic.read_gate.models import \ + get_read_gate_model_class if backend in CPUS: - from lava.lib.optimization.solvers.generic.read_gate.process \ - import ReadGate - from lava.lib.optimization.solvers.generic.read_gate.models import \ - get_read_gate_model_class ReadGatePyModel = get_read_gate_model_class(num_in_ports) pdict = { - self.solver_process: self.solver_model, - ReadGate: ReadGatePyModel, - Dense: PyDenseModelFloat, - NEBMAbstract: NEBMAbstractModel, - NEBM: NEBMPyModel, - QuboScif: PyModelQuboScifFixed, - } + self.solver_process: self.solver_model, + ReadGate: ReadGatePyModel, + Dense: PyDenseModelFloat, + NEBMAbstract: NEBMAbstractModel, + NEBM: NEBMPyModel, + QuboScif: PyModelQuboScifFixed, + } return Loihi1SimCfg( - exception_proc_model_map=pdict, select_sub_proc_model=True - ) + exception_proc_model_map=pdict, select_sub_proc_model=True + ) elif backend in NEUROCORES: pdict = { - self.solver_process: self.solver_model, - ReadGate: ReadGateCModel, - Dense: NcModelDense, - NEBMAbstract: NEBMAbstractModel, - NEBM: NEBMNcModel, - NEBMSimulatedAnnealingAbstract: - NEBMSimulatedAnnealingAbstractModel, - NEBMSimulatedAnnealing: - NEBMSimulatedAnnealingNcModel, - CostIntegrator: CostIntegratorNcModel - } + self.solver_process: self.solver_model, + ReadGate: ReadGateCModel, + Dense: NcModelDense, + NEBMAbstract: NEBMAbstractModel, + NEBM: NEBMNcModel, + NEBMSimulatedAnnealingAbstract: + NEBMSimulatedAnnealingAbstractModel, + NEBMSimulatedAnnealing: + NEBMSimulatedAnnealingNcModel, + CostIntegrator: CostIntegratorNcModel + } return Loihi2HwCfg( - exception_proc_model_map=pdict, - select_sub_proc_model=True, - callback_fxs=probes, - ) + exception_proc_model_map=pdict, + select_sub_proc_model=True, + callback_fxs=probes, + ) else: raise NotImplementedError(str(backend) + BACKEND_MSG) From 90887dc5d047455a67c762a3ba940a673b0d6be7 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Mon, 13 Mar 2023 15:52:15 +0100 Subject: [PATCH 05/27] solve linting issue Signed-off-by: GaboFGuerra --- .../optimization/solvers/generic/solver.py | 88 ++++++++++--------- 1 file changed, 48 insertions(+), 40 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index a5fec35d..ba59cdde 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -8,7 +8,8 @@ from lava.lib.optimization.problems.problems import OptimizationProblem from lava.lib.optimization.solvers.generic.builder import SolverProcessBuilder from lava.lib.optimization.solvers.generic.hierarchical_processes import ( - NEBMAbstract, NEBMSimulatedAnnealingAbstract + NEBMAbstract, + NEBMSimulatedAnnealingAbstract, ) from lava.lib.optimization.solvers.generic.scif.models import ( @@ -18,10 +19,10 @@ from lava.lib.optimization.solvers.generic.scif.process import QuboScif from lava.lib.optimization.solvers.generic.nebm.process import NEBM from lava.lib.optimization.solvers.generic.cost_integrator.process import ( - CostIntegrator + CostIntegrator, ) from lava.lib.optimization.solvers.generic.nebm.process import ( - NEBMSimulatedAnnealing + NEBMSimulatedAnnealing, ) from lava.lib.optimization.solvers.generic.sub_process_models import ( NEBMAbstractModel, @@ -45,15 +46,18 @@ try: from lava.lib.optimization.solvers.generic.read_gate.ncmodels import ( - ReadGateCModel + ReadGateCModel, ) from lava.proc.dense.ncmodels import NcModelDense from lava.lib.optimization.solvers.generic.nebm.ncmodels import ( - NEBMNcModel, NEBMSimulatedAnnealingNcModel + NEBMNcModel, + NEBMSimulatedAnnealingNcModel, + ) + from lava.lib.optimization.solvers.generic.cost_integrator.ncmodels import ( + CostIntegratorNcModel, ) - from lava.lib.optimization.solvers.generic.cost_integrator.ncmodels \ - import CostIntegratorNcModel except ImportError: + class ReadGateCModel: pass @@ -69,8 +73,10 @@ class NEBMSimulatedAnnealingNcModel: class CostIntegratorNcModel: pass -from lava.lib.optimization.solvers.generic.read_gate.models import \ - ReadGatePyModel + +from lava.lib.optimization.solvers.generic.read_gate.models import ( + ReadGatePyModel, +) BACKENDS = ty.Union[CPU, Loihi2NeuroCore, NeuroCore, str] HP_TYPE = ty.Union[ty.Dict, ty.List[ty.Dict]] @@ -259,7 +265,7 @@ def _prepare_solver(self, config: SolverConfig): run_cfg = self._get_run_config( backend=config.backend, probes=[self._cost_tracker] if self._cost_tracker else None, - num_in_ports=num_in_ports + num_in_ports=num_in_ports, ) run_condition = RunSteps(num_steps=config.timeout) self._prepare_profiler(config=config, run_cfg=run_cfg) @@ -314,43 +320,45 @@ def _get_cost_tracking(self): else: return self._cost_tracker.time_series - def _get_run_config(self, backend: BACKENDS, probes=None, - num_in_ports: int = None): - from lava.lib.optimization.solvers.generic.read_gate.process \ - import ReadGate - from lava.lib.optimization.solvers.generic.read_gate.models import \ - get_read_gate_model_class + def _get_run_config( + self, backend: BACKENDS, probes=None, num_in_ports: int = None + ): + from lava.lib.optimization.solvers.generic.read_gate.process import ( + ReadGate, + ) + from lava.lib.optimization.solvers.generic.read_gate.models import ( + get_read_gate_model_class, + ) + if backend in CPUS: ReadGatePyModel = get_read_gate_model_class(num_in_ports) pdict = { - self.solver_process: self.solver_model, - ReadGate: ReadGatePyModel, - Dense: PyDenseModelFloat, - NEBMAbstract: NEBMAbstractModel, - NEBM: NEBMPyModel, - QuboScif: PyModelQuboScifFixed, - } + self.solver_process: self.solver_model, + ReadGate: ReadGatePyModel, + Dense: PyDenseModelFloat, + NEBMAbstract: NEBMAbstractModel, + NEBM: NEBMPyModel, + QuboScif: PyModelQuboScifFixed, + } return Loihi1SimCfg( - exception_proc_model_map=pdict, select_sub_proc_model=True - ) + exception_proc_model_map=pdict, select_sub_proc_model=True + ) elif backend in NEUROCORES: pdict = { - self.solver_process: self.solver_model, - ReadGate: ReadGateCModel, - Dense: NcModelDense, - NEBMAbstract: NEBMAbstractModel, - NEBM: NEBMNcModel, - NEBMSimulatedAnnealingAbstract: - NEBMSimulatedAnnealingAbstractModel, - NEBMSimulatedAnnealing: - NEBMSimulatedAnnealingNcModel, - CostIntegrator: CostIntegratorNcModel - } + self.solver_process: self.solver_model, + ReadGate: ReadGateCModel, + Dense: NcModelDense, + NEBMAbstract: NEBMAbstractModel, + NEBM: NEBMNcModel, + NEBMSimulatedAnnealingAbstract: NEBMSimulatedAnnealingAbstractModel, + NEBMSimulatedAnnealing: NEBMSimulatedAnnealingNcModel, + CostIntegrator: CostIntegratorNcModel, + } return Loihi2HwCfg( - exception_proc_model_map=pdict, - select_sub_proc_model=True, - callback_fxs=probes, - ) + exception_proc_model_map=pdict, + select_sub_proc_model=True, + callback_fxs=probes, + ) else: raise NotImplementedError(str(backend) + BACKEND_MSG) From 1d8480c944b406058cfb062eee3c9c6ffa093dd2 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Mon, 13 Mar 2023 15:55:51 +0100 Subject: [PATCH 06/27] Solve linting issue. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/solver.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index ba59cdde..e32421e5 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -350,7 +350,8 @@ def _get_run_config( Dense: NcModelDense, NEBMAbstract: NEBMAbstractModel, NEBM: NEBMNcModel, - NEBMSimulatedAnnealingAbstract: NEBMSimulatedAnnealingAbstractModel, + NEBMSimulatedAnnealingAbstract: + NEBMSimulatedAnnealingAbstractModel, NEBMSimulatedAnnealing: NEBMSimulatedAnnealingNcModel, CostIntegrator: CostIntegratorNcModel, } From 5981f6a28d9ffd2753fb58f6f8a8fe8566f29300 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Tue, 14 Mar 2023 17:04:05 +0100 Subject: [PATCH 07/27] Split Py and C read gate models. Signed-off-by: GaboFGuerra --- .../solvers/generic/read_gate/models.py | 281 +++++++++--------- .../optimization/solvers/generic/sconfig.py | 4 + 2 files changed, 151 insertions(+), 134 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/read_gate/models.py b/src/lava/lib/optimization/solvers/generic/read_gate/models.py index 77e709a3..42a6a157 100644 --- a/src/lava/lib/optimization/solvers/generic/read_gate/models.py +++ b/src/lava/lib/optimization/solvers/generic/read_gate/models.py @@ -2,157 +2,170 @@ # SPDX-License-Identifier: BSD-3-Clause # See: https://spdx.org/licenses/ import numpy as np - from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate +from lava.lib.optimization.solvers.generic.types_optim import ( + BACKENDS, CPUS, NEUROCORES, BACKEND_MSG + ) +from lava.magma.core.model.spike_type import SpikeType + from lava.magma.core.decorator import implements, requires +from lava.magma.core.model.c.model import CLoihiProcessModel +from lava.magma.core.model.c.ports import CInPort, COutPort, CRefPort +from lava.magma.core.model.c.type import LavaCDataType, LavaCType from lava.magma.core.model.py.model import PyLoihiProcessModel from lava.magma.core.model.py.ports import PyInPort, PyOutPort, PyRefPort from lava.magma.core.model.py.type import LavaPyType -from lava.magma.core.resources import CPU +from lava.magma.core.resources import CPU, LMT from lava.magma.core.sync.protocols.loihi_protocol import LoihiProtocol def readgate_post_guard(self): - """Decide whether to run post management phase.""" - return True if self.min_cost else False + """Decide whether to run post management phase.""" + return True if self.min_cost else False def readgate_run_spk(self): - """Execute spiking phase, integrate input, update dynamics and - send messages out.""" - in_ports = [ - port for port in self.py_ports if issubclass(type(port), PyInPort) - ] - costs = [] - for port in in_ports: - costs.append(port.recv()[0]) - cost = min(costs) - id = costs.index(cost) - - if self.solution is not None: - timestep = -np.array([self.time_step]) - if self.min_cost <= self.target_cost: - self._req_pause = True - self.cost_out.send(np.array([self.min_cost, self.min_cost_id])) - self.send_pause_request.send(timestep) - self.solution_out.send(self.solution) - self.solution = None - self.min_cost = None - self.min_cost_id = None - else: - self.cost_out.send(np.array([0, 0])) - if cost: - self.min_cost = cost - self.min_cost_id = id + """Execute spiking phase, integrate input, update dynamics and + send messages out.""" + in_ports = [ + port for port in self.py_ports if issubclass(type(port), PyInPort) + ] + costs = [] + for port in in_ports: + costs.append(port.recv()[0]) + cost = min(costs) + id = costs.index(cost) + + if self.solution is not None: + timestep = -np.array([self.time_step]) + if self.min_cost <= self.target_cost: + self._req_pause = True + self.cost_out.send(np.array([self.min_cost, self.min_cost_id])) + self.send_pause_request.send(timestep) + self.solution_out.send(self.solution) + self.solution = None + self.min_cost = None + self.min_cost_id = None + else: + self.cost_out.send(np.array([0, 0])) + if cost: + self.min_cost = cost + self.min_cost_id = id def readgate_run_post_mgmt(self): - """Execute post management phase.""" - self.solution = self.solution_reader.read() - - -def get_readgate_members(num_in_ports): - in_ports = { - f"cost_in_{id}": LavaPyType(PyInPort.VEC_DENSE, np.int32, - precision=32) - for id in range(num_in_ports) - } - readgate_members = { - "target_cost": LavaPyType(int, np.int32, 32), - "best_solution": LavaPyType(int, np.int32, 32), - "cost_out": LavaPyType(PyOutPort.VEC_DENSE, np.int32, - precision=32), - "solution_out": LavaPyType(PyOutPort.VEC_DENSE, np.int32, - precision=32), - "send_pause_request": LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ), - "solution_reader": LavaPyType( - PyRefPort.VEC_DENSE, np.int32, precision=32 - ), - "min_cost": None, - "min_cost_id": None, - "solution": None, - "post_guard": readgate_post_guard, - "run_spk": readgate_run_spk, - "run_post_mgmt": readgate_run_post_mgmt, - } - readgate_members.update(in_ports) - return readgate_members - - -def get_read_gate_model_class(num_in_ports: int): - """Produce CPU model for the ReadGate process. - - The model verifies if better payload (cost) has been notified by the - downstream processes, if so, it reads those processes state and sends - out to - the upstream process the new payload (cost) and the network state. - """ - ReadGatePyModelBase = type( - "ReadGatePyModel", - (PyLoihiProcessModel,), - get_readgate_members(num_in_ports), - ) - ReadGatePyModelImpl = implements(ReadGate, protocol=LoihiProtocol)( - ReadGatePyModelBase - ) - ReadGatePyModel = requires(CPU)(ReadGatePyModelImpl) - return ReadGatePyModel - - -ReadGatePyModel = get_read_gate_model_class(num_in_ports=1) + """Execute post management phase.""" + self.solution = self.solution_reader.read() + + +def get_readgate_members(num_in_ports, backend: BACKENDS): + assert backend in BACKENDS, BACKEND_MSG + + readgate_members = dict(min_cost=None, + min_cost_id=None, + solution=None) + + in_ports_py = { + f"cost_in_{id}": LavaPyType(PyInPort.VEC_DENSE, np.int32, + precision=32) for id in range( + num_in_ports) + } + + class_members_py = dict(target_cost=LavaPyType(int, np.int32, 32), + best_solution=LavaPyType(int, np.int32, 32), + cost_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, + precision=32), + solution_out=LavaPyType(PyOutPort.VEC_DENSE, + np.int32, precision=32), + send_pause_request=LavaPyType(PyOutPort.VEC_DENSE, + np.int32, + precision=32), + solution_reader=LavaPyType(PyRefPort.VEC_DENSE, + np.int32, precision=32)) + + cpu_specific = dict(post_guard=readgate_post_guard, + run_spk=readgate_run_spk, + run_post_mgmt=readgate_run_post_mgmt, ) + + readgate_members.update(in_ports_py) + readgate_members.update(class_members_py) + readgate_members.update(cpu_specific) + return readgate_members + + +def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS): + """Produce CPU model for the ReadGate process. + + The model verifies if better payload (cost) has been notified by the + downstream processes, if so, it reads those processes state and sends + out to + the upstream process the new payload (cost) and the network state. + """ + assert (backend in BACKENDS) + super_class = PyLoihiProcessModel if backend in CPUS else CLoihiProcessModel + resource = CPU if backend in CPUS else LMT + ReadGateModelBase = type( + "ReadGateModel", + (super_class,), + get_readgate_members(num_in_ports, backend), + ) + ReadGateModelImpl = implements(ReadGate, protocol=LoihiProtocol)( + ReadGateModelBase + ) + ReadGateModel = requires(resource)(ReadGateModelImpl) + return ReadGateModel @implements(ReadGate, protocol=LoihiProtocol) @requires(CPU) class ReadGatePyModelD(PyLoihiProcessModel): - """CPU model for the ReadGate process. - - The model verifies if better payload (cost) has been notified by the - downstream processes, if so, it reads those processes state and sends out to - the upstream process the new payload (cost) and the network state. - """ - target_cost: int = LavaPyType(int, np.int32, 32) - best_solution: int = LavaPyType(int, np.int32, 32) - cost_in: PyInPort = LavaPyType(PyInPort.VEC_DENSE, np.int32, - precision=32) - cost_out: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - solution_out: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - send_pause_request: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - solution_reader = LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32) - min_cost: int = None - solution: np.ndarray = None - - def post_guard(self): - """Decide whether to run post management phase.""" - return True if self.min_cost else False - - def run_spk(self): - """Execute spiking phase, integrate input, update dynamics and - send messages out.""" - cost = self.cost_in.recv() - if cost[0]: - self.min_cost = cost[0] - self.cost_out.send(np.array([0])) - elif self.solution is not None: - timestep = - np.array([self.time_step]) - if self.min_cost <= self.target_cost: - self._req_pause = True - self.cost_out.send(np.array([self.min_cost])) - self.send_pause_request.send(timestep) - self.solution_out.send(self.solution) - self.solution = None - self.min_cost = None - else: - self.cost_out.send(np.array([0])) - - def run_post_mgmt(self): - """Execute post management phase.""" - self.solution = self.solution_reader.read() + """CPU model for the ReadGate process. + + The model verifies if better payload (cost) has been notified by the + downstream processes, if so, it reads those processes state and sends + out to + the upstream process the new payload (cost) and the network state. + """ + target_cost: int = LavaPyType(int, np.int32, 32) + best_solution: int = LavaPyType(int, np.int32, 32) + cost_in: PyInPort = LavaPyType(PyInPort.VEC_DENSE, np.int32, + precision=32) + cost_out: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + solution_out: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + send_pause_request: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + solution_reader = LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32) + min_cost: int = None + solution: np.ndarray = None + + def post_guard(self): + """Decide whether to run post management phase.""" + return True if self.min_cost else False + + def run_spk(self): + """Execute spiking phase, integrate input, update dynamics and + send messages out.""" + cost = self.cost_in.recv() + if cost[0]: + self.min_cost = cost[0] + self.cost_out.send(np.array([0])) + elif self.solution is not None: + timestep = - np.array([self.time_step]) + if self.min_cost <= self.target_cost: + self._req_pause = True + self.cost_out.send(np.array([self.min_cost])) + self.send_pause_request.send(timestep) + self.solution_out.send(self.solution) + self.solution = None + self.min_cost = None + else: + self.cost_out.send(np.array([0])) + + def run_post_mgmt(self): + """Execute post management phase.""" + self.solution = self.solution_reader.read() diff --git a/src/lava/lib/optimization/solvers/generic/sconfig.py b/src/lava/lib/optimization/solvers/generic/sconfig.py index b8300e34..ed6b2fe5 100644 --- a/src/lava/lib/optimization/solvers/generic/sconfig.py +++ b/src/lava/lib/optimization/solvers/generic/sconfig.py @@ -1 +1,5 @@ +# Copyright (C) 2023 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# See: https://spdx.org/licenses/ + num_in_ports = 1 From 1613fdfed2c90b38d80fb0d88dfe89905e4fec63 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Tue, 14 Mar 2023 17:05:57 +0100 Subject: [PATCH 08/27] Use different function for generating py and C ReadGate models. Signed-off-by: GaboFGuerra --- .../optimization/solvers/generic/solver.py | 81 +++++++------------ .../solvers/generic/types_optim.py | 22 +++++ 2 files changed, 53 insertions(+), 50 deletions(-) create mode 100644 src/lava/lib/optimization/solvers/generic/types_optim.py diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index e32421e5..ba20ca91 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -1,40 +1,38 @@ # Copyright (C) 2021 Intel Corporation # SPDX-License-Identifier: BSD-3-Clause # See: https://spdx.org/licenses/ -import numpy as np import typing as ty - from dataclasses import dataclass + +import numpy as np from lava.lib.optimization.problems.problems import OptimizationProblem from lava.lib.optimization.solvers.generic.builder import SolverProcessBuilder from lava.lib.optimization.solvers.generic.hierarchical_processes import ( NEBMAbstract, NEBMSimulatedAnnealingAbstract, -) - + ) +from lava.lib.optimization.solvers.generic.nebm.models import NEBMPyModel +from lava.lib.optimization.solvers.generic.nebm.process import ( + NEBM, + NEBMSimulatedAnnealing + ) from lava.lib.optimization.solvers.generic.scif.models import ( PyModelQuboScifFixed, -) -from lava.lib.optimization.solvers.generic.nebm.models import NEBMPyModel + ) from lava.lib.optimization.solvers.generic.scif.process import QuboScif -from lava.lib.optimization.solvers.generic.nebm.process import NEBM -from lava.lib.optimization.solvers.generic.cost_integrator.process import ( - CostIntegrator, -) -from lava.lib.optimization.solvers.generic.nebm.process import ( - NEBMSimulatedAnnealing, -) from lava.lib.optimization.solvers.generic.sub_process_models import ( NEBMAbstractModel, NEBMSimulatedAnnealingAbstractModel, -) - + ) +from lava.lib.optimization.solvers.generic.types_optim import ( + BACKENDS_TYPE, HP_TYPE, + CPUS, NEUROCORES, BACKEND_MSG + ) from lava.magma.core.resources import ( AbstractComputeResource, CPU, Loihi2NeuroCore, - NeuroCore, -) + ) from lava.magma.core.run_conditions import RunSteps from lava.magma.core.run_configs import Loihi1SimCfg, Loihi2HwCfg from lava.magma.core.sync.protocol import AbstractSyncProtocol @@ -74,27 +72,6 @@ class CostIntegratorNcModel: pass -from lava.lib.optimization.solvers.generic.read_gate.models import ( - ReadGatePyModel, -) - -BACKENDS = ty.Union[CPU, Loihi2NeuroCore, NeuroCore, str] -HP_TYPE = ty.Union[ty.Dict, ty.List[ty.Dict]] -CPUS = [CPU, "CPU"] -NEUROCORES = [Loihi2NeuroCore, NeuroCore, "Loihi2"] - -BACKEND_MSG = f""" was requested as backend. However, -the solver currently supports only Loihi 2 and CPU backends. -These can be specified by calling solve with any of the following: -backend = "CPU" -backend = "Loihi2" -backend = CPU -backend = Loihi2NeuroCore -backend = NeuroCoreS -The explicit resource classes can be imported from -lava.magma.core.resources""" - - @dataclass class SolverConfig: """ @@ -134,7 +111,7 @@ class SolverConfig: timeout: int = 1e3 target_cost: int = 0 - backend: BACKENDS = CPU + backend: BACKENDS_TYPE = CPU hyperparameters: HP_TYPE = None probe_cost: bool = False probe_time: bool = False @@ -297,14 +274,14 @@ def _create_solver_process(self, config: SolverConfig) -> None: self.solver_process._log_config.level = config.log_level def _get_requirements_and_protocol( - self, backend: BACKENDS + self, backend: BACKENDS_TYPE ) -> ty.Tuple[AbstractComputeResource, AbstractSyncProtocol]: """ Figure out requirements and protocol for a given backend. Parameters ---------- - backend: BACKENDS + backend: BACKENDS_TYPE Specifies the backend for which requirements and protocol classes will be returned. """ @@ -321,17 +298,17 @@ def _get_cost_tracking(self): return self._cost_tracker.time_series def _get_run_config( - self, backend: BACKENDS, probes=None, num_in_ports: int = None + self, backend: BACKENDS_TYPE, probes=None, num_in_ports: int = None ): from lava.lib.optimization.solvers.generic.read_gate.process import ( ReadGate, ) - from lava.lib.optimization.solvers.generic.read_gate.models import ( - get_read_gate_model_class, - ) - if backend in CPUS: - ReadGatePyModel = get_read_gate_model_class(num_in_ports) + from lava.lib.optimization.solvers.generic.read_gate.models import ( + get_read_gate_py_model_class, + ) + ReadGatePyModel = get_read_gate_py_model_class(num_in_ports, + backend) pdict = { self.solver_process: self.solver_model, ReadGate: ReadGatePyModel, @@ -344,16 +321,20 @@ def _get_run_config( exception_proc_model_map=pdict, select_sub_proc_model=True ) elif backend in NEUROCORES: + from lava.lib.optimization.solvers.generic.read_gate.ncmodels \ + import ( + get_read_gate_c_model_class, + ) + ReadGateCModel = get_read_gate_c_model_class(num_in_ports, backend) pdict = { self.solver_process: self.solver_model, ReadGate: ReadGateCModel, - Dense: NcModelDense, + # Dense: NcModelDense, NEBMAbstract: NEBMAbstractModel, - NEBM: NEBMNcModel, + # NEBM: NEBMNcModel, NEBMSimulatedAnnealingAbstract: NEBMSimulatedAnnealingAbstractModel, NEBMSimulatedAnnealing: NEBMSimulatedAnnealingNcModel, - CostIntegrator: CostIntegratorNcModel, } return Loihi2HwCfg( exception_proc_model_map=pdict, diff --git a/src/lava/lib/optimization/solvers/generic/types_optim.py b/src/lava/lib/optimization/solvers/generic/types_optim.py new file mode 100644 index 00000000..fff9f783 --- /dev/null +++ b/src/lava/lib/optimization/solvers/generic/types_optim.py @@ -0,0 +1,22 @@ +# Copyright (C) 2021 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# See: https://spdx.org/licenses/ +import typing as ty + +from lava.magma.core.resources import CPU, Loihi2NeuroCore, NeuroCore + +BACKENDS = [CPU, Loihi2NeuroCore, NeuroCore, "Loihi2", "CPU"] +BACKENDS_TYPE = ty.Union[CPU, Loihi2NeuroCore, NeuroCore, str] +HP_TYPE = ty.Union[ty.Dict, ty.List[ty.Dict]] +CPUS = [CPU, "CPU"] +NEUROCORES = [Loihi2NeuroCore, NeuroCore, "Loihi2"] +BACKEND_MSG = f""" was requested as backend. However, +the solver currently supports only Loihi 2 and CPU backends. +These can be specified by calling solve with any of the following: +backend = "CPU" +backend = "Loihi2" +backend = CPU +backend = Loihi2NeuroCore +backend = NeuroCoreS +The explicit resource classes can be imported from +lava.magma.core.resources""" From 51c591661f27e56bd949817bc480a7a4f11e9e4a Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Wed, 15 Mar 2023 21:24:19 +0100 Subject: [PATCH 09/27] Change assertion to raise a ValueError instead. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/read_gate/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lava/lib/optimization/solvers/generic/read_gate/models.py b/src/lava/lib/optimization/solvers/generic/read_gate/models.py index 42a6a157..95234215 100644 --- a/src/lava/lib/optimization/solvers/generic/read_gate/models.py +++ b/src/lava/lib/optimization/solvers/generic/read_gate/models.py @@ -101,7 +101,8 @@ def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS): out to the upstream process the new payload (cost) and the network state. """ - assert (backend in BACKENDS) + if backend not in BACKENDS: + raise ValueError(BACKEND_MSG) super_class = PyLoihiProcessModel if backend in CPUS else CLoihiProcessModel resource = CPU if backend in CPUS else LMT ReadGateModelBase = type( From 06a67f86ed73a3b1f506c3a3d1c797b2832c4036 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 14:35:01 -0700 Subject: [PATCH 10/27] Solve linting inssues. Signed-off-by: GaboFGuerra --- .../solvers/generic/read_gate/models.py | 271 +++++++++--------- .../optimization/solvers/generic/solver.py | 39 +-- 2 files changed, 158 insertions(+), 152 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/read_gate/models.py b/src/lava/lib/optimization/solvers/generic/read_gate/models.py index 95234215..99e2c848 100644 --- a/src/lava/lib/optimization/solvers/generic/read_gate/models.py +++ b/src/lava/lib/optimization/solvers/generic/read_gate/models.py @@ -4,8 +4,11 @@ import numpy as np from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate from lava.lib.optimization.solvers.generic.types_optim import ( - BACKENDS, CPUS, NEUROCORES, BACKEND_MSG - ) + BACKENDS, + CPUS, + NEUROCORES, + BACKEND_MSG, +) from lava.magma.core.model.spike_type import SpikeType from lava.magma.core.decorator import implements, requires @@ -20,153 +23,151 @@ def readgate_post_guard(self): - """Decide whether to run post management phase.""" - return True if self.min_cost else False + """Decide whether to run post management phase.""" + return True if self.min_cost else False def readgate_run_spk(self): - """Execute spiking phase, integrate input, update dynamics and - send messages out.""" - in_ports = [ - port for port in self.py_ports if issubclass(type(port), PyInPort) - ] - costs = [] - for port in in_ports: - costs.append(port.recv()[0]) - cost = min(costs) - id = costs.index(cost) - - if self.solution is not None: - timestep = -np.array([self.time_step]) - if self.min_cost <= self.target_cost: - self._req_pause = True - self.cost_out.send(np.array([self.min_cost, self.min_cost_id])) - self.send_pause_request.send(timestep) - self.solution_out.send(self.solution) - self.solution = None - self.min_cost = None - self.min_cost_id = None - else: - self.cost_out.send(np.array([0, 0])) - if cost: - self.min_cost = cost - self.min_cost_id = id + """Execute spiking phase, integrate input, update dynamics and + send messages out.""" + in_ports = [ + port for port in self.py_ports if issubclass(type(port), PyInPort) + ] + costs = [] + for port in in_ports: + costs.append(port.recv()[0]) + cost = min(costs) + id = costs.index(cost) + + if self.solution is not None: + timestep = -np.array([self.time_step]) + if self.min_cost <= self.target_cost: + self._req_pause = True + self.cost_out.send(np.array([self.min_cost, self.min_cost_id])) + self.send_pause_request.send(timestep) + self.solution_out.send(self.solution) + self.solution = None + self.min_cost = None + self.min_cost_id = None + else: + self.cost_out.send(np.array([0, 0])) + if cost: + self.min_cost = cost + self.min_cost_id = id def readgate_run_post_mgmt(self): - """Execute post management phase.""" - self.solution = self.solution_reader.read() + """Execute post management phase.""" + self.solution = self.solution_reader.read() def get_readgate_members(num_in_ports, backend: BACKENDS): - assert backend in BACKENDS, BACKEND_MSG - - readgate_members = dict(min_cost=None, - min_cost_id=None, - solution=None) - - in_ports_py = { - f"cost_in_{id}": LavaPyType(PyInPort.VEC_DENSE, np.int32, - precision=32) for id in range( - num_in_ports) - } - - class_members_py = dict(target_cost=LavaPyType(int, np.int32, 32), - best_solution=LavaPyType(int, np.int32, 32), - cost_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, - precision=32), - solution_out=LavaPyType(PyOutPort.VEC_DENSE, - np.int32, precision=32), - send_pause_request=LavaPyType(PyOutPort.VEC_DENSE, - np.int32, - precision=32), - solution_reader=LavaPyType(PyRefPort.VEC_DENSE, - np.int32, precision=32)) - - cpu_specific = dict(post_guard=readgate_post_guard, - run_spk=readgate_run_spk, - run_post_mgmt=readgate_run_post_mgmt, ) - - readgate_members.update(in_ports_py) - readgate_members.update(class_members_py) - readgate_members.update(cpu_specific) - return readgate_members + assert backend in BACKENDS, BACKEND_MSG + + readgate_members = dict(min_cost=None, min_cost_id=None, solution=None) + + in_ports_py = { + f"cost_in_{id}": LavaPyType(PyInPort.VEC_DENSE, np.int32, precision=32) + for id in range(num_in_ports) + } + + class_members_py = dict( + target_cost=LavaPyType(int, np.int32, 32), + best_solution=LavaPyType(int, np.int32, 32), + cost_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, precision=32), + solution_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, precision=32), + send_pause_request=LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ), + solution_reader=LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32), + ) + + cpu_specific = dict( + post_guard=readgate_post_guard, + run_spk=readgate_run_spk, + run_post_mgmt=readgate_run_post_mgmt, + ) + + readgate_members.update(in_ports_py) + readgate_members.update(class_members_py) + readgate_members.update(cpu_specific) + return readgate_members def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS): - """Produce CPU model for the ReadGate process. - - The model verifies if better payload (cost) has been notified by the - downstream processes, if so, it reads those processes state and sends - out to - the upstream process the new payload (cost) and the network state. - """ - if backend not in BACKENDS: - raise ValueError(BACKEND_MSG) - super_class = PyLoihiProcessModel if backend in CPUS else CLoihiProcessModel - resource = CPU if backend in CPUS else LMT - ReadGateModelBase = type( - "ReadGateModel", - (super_class,), - get_readgate_members(num_in_ports, backend), - ) - ReadGateModelImpl = implements(ReadGate, protocol=LoihiProtocol)( - ReadGateModelBase - ) - ReadGateModel = requires(resource)(ReadGateModelImpl) - return ReadGateModel + """Produce CPU model for the ReadGate process. + + The model verifies if better payload (cost) has been notified by the + downstream processes, if so, it reads those processes state and sends + out to + the upstream process the new payload (cost) and the network state. + """ + if backend not in BACKENDS: + raise ValueError(BACKEND_MSG) + super_class = PyLoihiProcessModel if backend in CPUS else CLoihiProcessModel + resource = CPU if backend in CPUS else LMT + ReadGateModelBase = type( + "ReadGateModel", + (super_class,), + get_readgate_members(num_in_ports, backend), + ) + ReadGateModelImpl = implements(ReadGate, protocol=LoihiProtocol)( + ReadGateModelBase + ) + ReadGateModel = requires(resource)(ReadGateModelImpl) + return ReadGateModel @implements(ReadGate, protocol=LoihiProtocol) @requires(CPU) class ReadGatePyModelD(PyLoihiProcessModel): - """CPU model for the ReadGate process. - - The model verifies if better payload (cost) has been notified by the - downstream processes, if so, it reads those processes state and sends - out to - the upstream process the new payload (cost) and the network state. - """ - target_cost: int = LavaPyType(int, np.int32, 32) - best_solution: int = LavaPyType(int, np.int32, 32) - cost_in: PyInPort = LavaPyType(PyInPort.VEC_DENSE, np.int32, - precision=32) - cost_out: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - solution_out: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - send_pause_request: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - solution_reader = LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32) - min_cost: int = None - solution: np.ndarray = None - - def post_guard(self): - """Decide whether to run post management phase.""" - return True if self.min_cost else False - - def run_spk(self): - """Execute spiking phase, integrate input, update dynamics and - send messages out.""" - cost = self.cost_in.recv() - if cost[0]: - self.min_cost = cost[0] - self.cost_out.send(np.array([0])) - elif self.solution is not None: - timestep = - np.array([self.time_step]) - if self.min_cost <= self.target_cost: - self._req_pause = True - self.cost_out.send(np.array([self.min_cost])) - self.send_pause_request.send(timestep) - self.solution_out.send(self.solution) - self.solution = None - self.min_cost = None - else: - self.cost_out.send(np.array([0])) - - def run_post_mgmt(self): - """Execute post management phase.""" - self.solution = self.solution_reader.read() + """CPU model for the ReadGate process. + + The model verifies if better payload (cost) has been notified by the + downstream processes, if so, it reads those processes state and sends + out to + the upstream process the new payload (cost) and the network state. + """ + + target_cost: int = LavaPyType(int, np.int32, 32) + best_solution: int = LavaPyType(int, np.int32, 32) + cost_in: PyInPort = LavaPyType(PyInPort.VEC_DENSE, np.int32, precision=32) + cost_out: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + solution_out: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + send_pause_request: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + solution_reader = LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32) + min_cost: int = None + solution: np.ndarray = None + + def post_guard(self): + """Decide whether to run post management phase.""" + return True if self.min_cost else False + + def run_spk(self): + """Execute spiking phase, integrate input, update dynamics and + send messages out.""" + cost = self.cost_in.recv() + if cost[0]: + self.min_cost = cost[0] + self.cost_out.send(np.array([0])) + elif self.solution is not None: + timestep = -np.array([self.time_step]) + if self.min_cost <= self.target_cost: + self._req_pause = True + self.cost_out.send(np.array([self.min_cost])) + self.send_pause_request.send(timestep) + self.solution_out.send(self.solution) + self.solution = None + self.min_cost = None + else: + self.cost_out.send(np.array([0])) + + def run_post_mgmt(self): + """Execute post management phase.""" + self.solution = self.solution_reader.read() diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index ba20ca91..099991d5 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -10,29 +10,32 @@ from lava.lib.optimization.solvers.generic.hierarchical_processes import ( NEBMAbstract, NEBMSimulatedAnnealingAbstract, - ) +) from lava.lib.optimization.solvers.generic.nebm.models import NEBMPyModel from lava.lib.optimization.solvers.generic.nebm.process import ( NEBM, - NEBMSimulatedAnnealing - ) + NEBMSimulatedAnnealing, +) from lava.lib.optimization.solvers.generic.scif.models import ( PyModelQuboScifFixed, - ) +) from lava.lib.optimization.solvers.generic.scif.process import QuboScif from lava.lib.optimization.solvers.generic.sub_process_models import ( NEBMAbstractModel, NEBMSimulatedAnnealingAbstractModel, - ) +) from lava.lib.optimization.solvers.generic.types_optim import ( - BACKENDS_TYPE, HP_TYPE, - CPUS, NEUROCORES, BACKEND_MSG - ) + BACKENDS_TYPE, + HP_TYPE, + CPUS, + NEUROCORES, + BACKEND_MSG, +) from lava.magma.core.resources import ( AbstractComputeResource, CPU, Loihi2NeuroCore, - ) +) from lava.magma.core.run_conditions import RunSteps from lava.magma.core.run_configs import Loihi1SimCfg, Loihi2HwCfg from lava.magma.core.sync.protocol import AbstractSyncProtocol @@ -303,12 +306,15 @@ def _get_run_config( from lava.lib.optimization.solvers.generic.read_gate.process import ( ReadGate, ) + if backend in CPUS: from lava.lib.optimization.solvers.generic.read_gate.models import ( get_read_gate_py_model_class, - ) - ReadGatePyModel = get_read_gate_py_model_class(num_in_ports, - backend) + ) + + ReadGatePyModel = get_read_gate_py_model_class( + num_in_ports, backend + ) pdict = { self.solver_process: self.solver_model, ReadGate: ReadGatePyModel, @@ -321,10 +327,10 @@ def _get_run_config( exception_proc_model_map=pdict, select_sub_proc_model=True ) elif backend in NEUROCORES: - from lava.lib.optimization.solvers.generic.read_gate.ncmodels \ - import ( + from lava.lib.optimization.solvers.generic.read_gate.ncmodels import ( get_read_gate_c_model_class, - ) + ) + ReadGateCModel = get_read_gate_c_model_class(num_in_ports, backend) pdict = { self.solver_process: self.solver_model, @@ -332,8 +338,7 @@ def _get_run_config( # Dense: NcModelDense, NEBMAbstract: NEBMAbstractModel, # NEBM: NEBMNcModel, - NEBMSimulatedAnnealingAbstract: - NEBMSimulatedAnnealingAbstractModel, + NEBMSimulatedAnnealingAbstract: NEBMSimulatedAnnealingAbstractModel, NEBMSimulatedAnnealing: NEBMSimulatedAnnealingNcModel, } return Loihi2HwCfg( From 98081e32318e757da653e66af3050375c1011b66 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 14:39:07 -0700 Subject: [PATCH 11/27] Reformat file. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/solver.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index 118e1eba..148fd7bf 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -59,6 +59,7 @@ CostIntegratorNcModel, ) except ImportError: + class NcModelDense: pass From 57c1d7820476dfaf7b436e5320dd087bf3b6c48e Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 22:45:11 +0100 Subject: [PATCH 12/27] Solve linting. Signed-off-by: GaboFGuerra --- .../optimization/solvers/generic/solver.py | 50 +++++++++---------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index 148fd7bf..ba20ca91 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -10,36 +10,29 @@ from lava.lib.optimization.solvers.generic.hierarchical_processes import ( NEBMAbstract, NEBMSimulatedAnnealingAbstract, -) + ) from lava.lib.optimization.solvers.generic.nebm.models import NEBMPyModel from lava.lib.optimization.solvers.generic.nebm.process import ( NEBM, - NEBMSimulatedAnnealing, -) + NEBMSimulatedAnnealing + ) from lava.lib.optimization.solvers.generic.scif.models import ( PyModelQuboScifFixed, -) + ) from lava.lib.optimization.solvers.generic.scif.process import QuboScif from lava.lib.optimization.solvers.generic.sub_process_models import ( NEBMAbstractModel, NEBMSimulatedAnnealingAbstractModel, -) + ) from lava.lib.optimization.solvers.generic.types_optim import ( - BACKENDS_TYPE, - HP_TYPE, - CPUS, - NEUROCORES, - BACKEND_MSG, -) -from lava.lib.optimization.solvers.generic.cost_integrator.process import ( - CostIntegrator, -) - + BACKENDS_TYPE, HP_TYPE, + CPUS, NEUROCORES, BACKEND_MSG + ) from lava.magma.core.resources import ( AbstractComputeResource, CPU, Loihi2NeuroCore, -) + ) from lava.magma.core.run_conditions import RunSteps from lava.magma.core.run_configs import Loihi1SimCfg, Loihi2HwCfg from lava.magma.core.sync.protocol import AbstractSyncProtocol @@ -50,6 +43,9 @@ from lava.utils.profiler import Profiler try: + from lava.lib.optimization.solvers.generic.read_gate.ncmodels import ( + ReadGateCModel, + ) from lava.proc.dense.ncmodels import NcModelDense from lava.lib.optimization.solvers.generic.nebm.ncmodels import ( NEBMNcModel, @@ -60,6 +56,9 @@ ) except ImportError: + class ReadGateCModel: + pass + class NcModelDense: pass @@ -304,15 +303,12 @@ def _get_run_config( from lava.lib.optimization.solvers.generic.read_gate.process import ( ReadGate, ) - if backend in CPUS: from lava.lib.optimization.solvers.generic.read_gate.models import ( get_read_gate_py_model_class, - ) - - ReadGatePyModel = get_read_gate_py_model_class( - num_in_ports, backend - ) + ) + ReadGatePyModel = get_read_gate_py_model_class(num_in_ports, + backend) pdict = { self.solver_process: self.solver_model, ReadGate: ReadGatePyModel, @@ -325,10 +321,10 @@ def _get_run_config( exception_proc_model_map=pdict, select_sub_proc_model=True ) elif backend in NEUROCORES: - from lava.lib.optimization.solvers.generic.read_gate.ncmodels import ( + from lava.lib.optimization.solvers.generic.read_gate.ncmodels \ + import ( get_read_gate_c_model_class, - ) - + ) ReadGateCModel = get_read_gate_c_model_class(num_in_ports, backend) pdict = { self.solver_process: self.solver_model, @@ -336,9 +332,9 @@ def _get_run_config( # Dense: NcModelDense, NEBMAbstract: NEBMAbstractModel, # NEBM: NEBMNcModel, - NEBMSimulatedAnnealingAbstract: NEBMSimulatedAnnealingAbstractModel, + NEBMSimulatedAnnealingAbstract: + NEBMSimulatedAnnealingAbstractModel, NEBMSimulatedAnnealing: NEBMSimulatedAnnealingNcModel, - CostIntegrator: CostIntegratorNcModel, } return Loihi2HwCfg( exception_proc_model_map=pdict, From 221d95197a8203d578e99e5861ffd285b8966ef2 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 14:49:02 -0700 Subject: [PATCH 13/27] Reformat files. Signed-off-by: GaboFGuerra --- .../solvers/generic/read_gate/models.py | 347 +++++++++--------- .../optimization/solvers/generic/solver.py | 69 ++-- 2 files changed, 209 insertions(+), 207 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/read_gate/models.py b/src/lava/lib/optimization/solvers/generic/read_gate/models.py index 99e2c848..a1286086 100644 --- a/src/lava/lib/optimization/solvers/generic/read_gate/models.py +++ b/src/lava/lib/optimization/solvers/generic/read_gate/models.py @@ -1,173 +1,174 @@ -# Copyright (C) 2022 Intel Corporation -# SPDX-License-Identifier: BSD-3-Clause -# See: https://spdx.org/licenses/ -import numpy as np -from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate -from lava.lib.optimization.solvers.generic.types_optim import ( - BACKENDS, - CPUS, - NEUROCORES, - BACKEND_MSG, -) -from lava.magma.core.model.spike_type import SpikeType - -from lava.magma.core.decorator import implements, requires -from lava.magma.core.model.c.model import CLoihiProcessModel -from lava.magma.core.model.c.ports import CInPort, COutPort, CRefPort -from lava.magma.core.model.c.type import LavaCDataType, LavaCType -from lava.magma.core.model.py.model import PyLoihiProcessModel -from lava.magma.core.model.py.ports import PyInPort, PyOutPort, PyRefPort -from lava.magma.core.model.py.type import LavaPyType -from lava.magma.core.resources import CPU, LMT -from lava.magma.core.sync.protocols.loihi_protocol import LoihiProtocol - - -def readgate_post_guard(self): - """Decide whether to run post management phase.""" - return True if self.min_cost else False - - -def readgate_run_spk(self): - """Execute spiking phase, integrate input, update dynamics and - send messages out.""" - in_ports = [ - port for port in self.py_ports if issubclass(type(port), PyInPort) - ] - costs = [] - for port in in_ports: - costs.append(port.recv()[0]) - cost = min(costs) - id = costs.index(cost) - - if self.solution is not None: - timestep = -np.array([self.time_step]) - if self.min_cost <= self.target_cost: - self._req_pause = True - self.cost_out.send(np.array([self.min_cost, self.min_cost_id])) - self.send_pause_request.send(timestep) - self.solution_out.send(self.solution) - self.solution = None - self.min_cost = None - self.min_cost_id = None - else: - self.cost_out.send(np.array([0, 0])) - if cost: - self.min_cost = cost - self.min_cost_id = id - - -def readgate_run_post_mgmt(self): - """Execute post management phase.""" - self.solution = self.solution_reader.read() - - -def get_readgate_members(num_in_ports, backend: BACKENDS): - assert backend in BACKENDS, BACKEND_MSG - - readgate_members = dict(min_cost=None, min_cost_id=None, solution=None) - - in_ports_py = { - f"cost_in_{id}": LavaPyType(PyInPort.VEC_DENSE, np.int32, precision=32) - for id in range(num_in_ports) - } - - class_members_py = dict( - target_cost=LavaPyType(int, np.int32, 32), - best_solution=LavaPyType(int, np.int32, 32), - cost_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, precision=32), - solution_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, precision=32), - send_pause_request=LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ), - solution_reader=LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32), - ) - - cpu_specific = dict( - post_guard=readgate_post_guard, - run_spk=readgate_run_spk, - run_post_mgmt=readgate_run_post_mgmt, - ) - - readgate_members.update(in_ports_py) - readgate_members.update(class_members_py) - readgate_members.update(cpu_specific) - return readgate_members - - -def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS): - """Produce CPU model for the ReadGate process. - - The model verifies if better payload (cost) has been notified by the - downstream processes, if so, it reads those processes state and sends - out to - the upstream process the new payload (cost) and the network state. - """ - if backend not in BACKENDS: - raise ValueError(BACKEND_MSG) - super_class = PyLoihiProcessModel if backend in CPUS else CLoihiProcessModel - resource = CPU if backend in CPUS else LMT - ReadGateModelBase = type( - "ReadGateModel", - (super_class,), - get_readgate_members(num_in_ports, backend), - ) - ReadGateModelImpl = implements(ReadGate, protocol=LoihiProtocol)( - ReadGateModelBase - ) - ReadGateModel = requires(resource)(ReadGateModelImpl) - return ReadGateModel - - -@implements(ReadGate, protocol=LoihiProtocol) -@requires(CPU) -class ReadGatePyModelD(PyLoihiProcessModel): - """CPU model for the ReadGate process. - - The model verifies if better payload (cost) has been notified by the - downstream processes, if so, it reads those processes state and sends - out to - the upstream process the new payload (cost) and the network state. - """ - - target_cost: int = LavaPyType(int, np.int32, 32) - best_solution: int = LavaPyType(int, np.int32, 32) - cost_in: PyInPort = LavaPyType(PyInPort.VEC_DENSE, np.int32, precision=32) - cost_out: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - solution_out: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - send_pause_request: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - solution_reader = LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32) - min_cost: int = None - solution: np.ndarray = None - - def post_guard(self): - """Decide whether to run post management phase.""" - return True if self.min_cost else False - - def run_spk(self): - """Execute spiking phase, integrate input, update dynamics and - send messages out.""" - cost = self.cost_in.recv() - if cost[0]: - self.min_cost = cost[0] - self.cost_out.send(np.array([0])) - elif self.solution is not None: - timestep = -np.array([self.time_step]) - if self.min_cost <= self.target_cost: - self._req_pause = True - self.cost_out.send(np.array([self.min_cost])) - self.send_pause_request.send(timestep) - self.solution_out.send(self.solution) - self.solution = None - self.min_cost = None - else: - self.cost_out.send(np.array([0])) - - def run_post_mgmt(self): - """Execute post management phase.""" - self.solution = self.solution_reader.read() +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# See: https://spdx.org/licenses/ +import numpy as np +from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate +from lava.lib.optimization.solvers.generic.types_optim import ( + BACKENDS, + CPUS, + NEUROCORES, + BACKEND_MSG, +) +from lava.magma.core.model.spike_type import SpikeType + +from lava.magma.core.decorator import implements, requires +from lava.magma.core.model.c.model import CLoihiProcessModel +from lava.magma.core.model.c.ports import CInPort, COutPort, CRefPort +from lava.magma.core.model.c.type import LavaCDataType, LavaCType +from lava.magma.core.model.py.model import PyLoihiProcessModel +from lava.magma.core.model.py.ports import PyInPort, PyOutPort, PyRefPort +from lava.magma.core.model.py.type import LavaPyType +from lava.magma.core.resources import CPU, LMT +from lava.magma.core.sync.protocols.loihi_protocol import LoihiProtocol + + +def readgate_post_guard(self): + """Decide whether to run post management phase.""" + return True if self.min_cost else False + + +def readgate_run_spk(self): + """Execute spiking phase, integrate input, update dynamics and + send messages out.""" + in_ports = [ + port for port in self.py_ports if issubclass(type(port), PyInPort) + ] + costs = [] + for port in in_ports: + costs.append(port.recv()[0]) + cost = min(costs) + id = costs.index(cost) + + if self.solution is not None: + timestep = -np.array([self.time_step]) + if self.min_cost <= self.target_cost: + self._req_pause = True + self.cost_out.send(np.array([self.min_cost, self.min_cost_id])) + self.send_pause_request.send(timestep) + self.solution_out.send(self.solution) + self.solution = None + self.min_cost = None + self.min_cost_id = None + else: + self.cost_out.send(np.array([0, 0])) + if cost: + self.min_cost = cost + self.min_cost_id = id + + +def readgate_run_post_mgmt(self): + """Execute post management phase.""" + self.solution = self.solution_reader.read() + + +def get_readgate_members(num_in_ports, backend: BACKENDS): + if not backend in BACKENDS: + raise ValueError(BACKEND_MSG) + + readgate_members = dict(min_cost=None, min_cost_id=None, solution=None) + + in_ports_py = { + f"cost_in_{id}": LavaPyType(PyInPort.VEC_DENSE, np.int32, precision=32) + for id in range(num_in_ports) + } + + class_members_py = dict( + target_cost=LavaPyType(int, np.int32, 32), + best_solution=LavaPyType(int, np.int32, 32), + cost_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, precision=32), + solution_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, precision=32), + send_pause_request=LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ), + solution_reader=LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32), + ) + + cpu_specific = dict( + post_guard=readgate_post_guard, + run_spk=readgate_run_spk, + run_post_mgmt=readgate_run_post_mgmt, + ) + + readgate_members.update(in_ports_py) + readgate_members.update(class_members_py) + readgate_members.update(cpu_specific) + return readgate_members + + +def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS): + """Produce CPU model for the ReadGate process. + + The model verifies if better payload (cost) has been notified by the + downstream processes, if so, it reads those processes state and sends + out to + the upstream process the new payload (cost) and the network state. + """ + if backend not in BACKENDS: + raise ValueError(BACKEND_MSG) + super_class = PyLoihiProcessModel if backend in CPUS else CLoihiProcessModel + resource = CPU if backend in CPUS else LMT + ReadGateModelBase = type( + "ReadGateModel", + (super_class,), + get_readgate_members(num_in_ports, backend), + ) + ReadGateModelImpl = implements(ReadGate, protocol=LoihiProtocol)( + ReadGateModelBase + ) + ReadGateModel = requires(resource)(ReadGateModelImpl) + return ReadGateModel + + +@implements(ReadGate, protocol=LoihiProtocol) +@requires(CPU) +class ReadGatePyModelD(PyLoihiProcessModel): + """CPU model for the ReadGate process. + + The model verifies if better payload (cost) has been notified by the + downstream processes, if so, it reads those processes state and sends + out to + the upstream process the new payload (cost) and the network state. + """ + + target_cost: int = LavaPyType(int, np.int32, 32) + best_solution: int = LavaPyType(int, np.int32, 32) + cost_in: PyInPort = LavaPyType(PyInPort.VEC_DENSE, np.int32, precision=32) + cost_out: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + solution_out: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + send_pause_request: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + solution_reader = LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32) + min_cost: int = None + solution: np.ndarray = None + + def post_guard(self): + """Decide whether to run post management phase.""" + return True if self.min_cost else False + + def run_spk(self): + """Execute spiking phase, integrate input, update dynamics and + send messages out.""" + cost = self.cost_in.recv() + if cost[0]: + self.min_cost = cost[0] + self.cost_out.send(np.array([0])) + elif self.solution is not None: + timestep = -np.array([self.time_step]) + if self.min_cost <= self.target_cost: + self._req_pause = True + self.cost_out.send(np.array([self.min_cost])) + self.send_pause_request.send(timestep) + self.solution_out.send(self.solution) + self.solution = None + self.min_cost = None + else: + self.cost_out.send(np.array([0])) + + def run_post_mgmt(self): + """Execute post management phase.""" + self.solution = self.solution_reader.read() diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index 148fd7bf..db8c538a 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -81,33 +81,33 @@ class SolverConfig: Parameters ---------- timeout: int - Maximum number of iterations (timesteps) to be run. If set to -1 - then the solver will run continuously in non-blocking mode until a - solution is found. + Maximum number of iterations (timesteps) to be run. If set to -1 + then the solver will run continuously in non-blocking mode until a + solution is found. target_cost: int, optional - A cost value provided by the user as a target for the solution to be - found by the solver, when a solution with such cost is found and - read, execution ends. + A cost value provided by the user as a target for the solution to be + found by the solver, when a solution with such cost is found and + read, execution ends. backend: BACKENDS, optional - Specifies the backend where the main solver network will be - deployed. + Specifies the backend where the main solver network will be + deployed. hyperparameters: - ty.Union[ty.Dict, ty.Dict[str, ty.Union[int, npt.ArrayLike]]], - optional. - A dictionary specifying values for steps_to_fire, noise_amplitude, - step_size and init_value. All but the last are integers, the initial - value is an array-like of initial values for the variables defining - the problem. + ty.Union[ty.Dict, ty.Dict[str, ty.Union[int, npt.ArrayLike]]], + optional. + A dictionary specifying values for steps_to_fire, noise_amplitude, + step_size and init_value. All but the last are integers, the initial + value is an array-like of initial values for the variables defining + the problem. probe_cost: bool - A boolean flag to request cost tracking through time. + A boolean flag to request cost tracking through time. probe_time: bool - A boolean flag to request time profiling, available only on "Loihi2" - backend. + A boolean flag to request time profiling, available only on "Loihi2" + backend. probe_energy: bool - A boolean flag to request time profiling, available only on "Loihi2" - backend. + A boolean flag to request time profiling, available only on "Loihi2" + backend. log_level: int - Select log verbosity (40: default, 20: verbose). + Select log verbosity (40: default, 20: verbose). """ timeout: int = 1e3 @@ -128,15 +128,15 @@ class SolverReport: Parameters ---------- best_cost: int - Best cost found during the execution. + Best cost found during the execution. best_state: np.ndarray - Candidate solution associated to the best cost. + Candidate solution associated to the best cost. best_timestep: int - Execution timestep during which the best solution was found. + Execution timestep during which the best solution was found. solver_config: SolverConfig - Solver configuraiton used. Refers to SolverConfig documentation. + Solver configuraiton used. Refers to SolverConfig documentation. profiler: Profiler - Profiler instance containing time, energy and activity measurements. + Profiler instance containing time, energy and activity measurements. """ best_cost: int = None @@ -157,9 +157,9 @@ def solve( Parameters ---------- problem: OptimizationProblem - Optimization problem to be solved. + Optimization problem to be solved. config: SolverConfig, optional - Solver configuraiton used. Refers to SolverConfig documentation. + Solver configuraiton used. Refers to SolverConfig documentation. """ solver = OptimizationSolver(problem) report = solver.solve(config=config) @@ -187,7 +187,7 @@ def __init__(self, problem: OptimizationProblem): Parameters ---------- problem: OptimizationProblem - Optimization problem to be solved. + Optimization problem to be solved. """ self.problem = problem self._process_builder = SolverProcessBuilder() @@ -203,12 +203,12 @@ def solve(self, config: SolverConfig = SolverConfig()) -> SolverReport: Parameters ---------- config: SolverConfig, optional - Solver configuration used. Refers to SolverConfig documentation. + Solver configuration used. Refers to SolverConfig documentation. Returns ---------- report: SolverReport - An object containing all the data generated by the execution. + An object containing all the data generated by the execution. """ run_condition, run_cfg = self._prepare_solver(config) self.solver_process.run(condition=run_condition, run_cfg=run_cfg) @@ -231,7 +231,8 @@ def _prepare_solver(self, config: SolverConfig): if config.probe_cost: if config.backend in NEUROCORES: # from lava.utils.loihi2_state_probes import StateProbe - # self._cost_tracker = StateProbe(self.solver_process.optimality + # self._cost_tracker = StateProbe( + # self.solver_process.optimality # ) raise NotImplementedError if config.backend in CPUS: @@ -256,7 +257,7 @@ def _create_solver_process(self, config: SolverConfig) -> None: Parameters ---------- config: SolverConfig - Solver configuraiton used. Refers to SolverConfig documentation. + Solver configuraiton used. Refers to SolverConfig documentation. """ requirements, protocol = self._get_requirements_and_protocol( backend=config.backend @@ -283,8 +284,8 @@ def _get_requirements_and_protocol( Parameters ---------- backend: BACKENDS_TYPE - Specifies the backend for which requirements and protocol classes - will be returned. + Specifies the backend for which requirements and protocol classes + will be returned. """ return [CPU] if backend in CPUS else [Loihi2NeuroCore], LoihiProtocol From 551e717c48bab9869fcc2ce626c3c7b413d77829 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 22:52:16 +0100 Subject: [PATCH 14/27] merge remote into local Signed-off-by: GaboFGuerra --- .../solvers/generic/read_gate/models.py | 348 +++++++++--------- 1 file changed, 174 insertions(+), 174 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/read_gate/models.py b/src/lava/lib/optimization/solvers/generic/read_gate/models.py index a1286086..13226746 100644 --- a/src/lava/lib/optimization/solvers/generic/read_gate/models.py +++ b/src/lava/lib/optimization/solvers/generic/read_gate/models.py @@ -1,174 +1,174 @@ -# Copyright (C) 2022 Intel Corporation -# SPDX-License-Identifier: BSD-3-Clause -# See: https://spdx.org/licenses/ -import numpy as np -from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate -from lava.lib.optimization.solvers.generic.types_optim import ( - BACKENDS, - CPUS, - NEUROCORES, - BACKEND_MSG, -) -from lava.magma.core.model.spike_type import SpikeType - -from lava.magma.core.decorator import implements, requires -from lava.magma.core.model.c.model import CLoihiProcessModel -from lava.magma.core.model.c.ports import CInPort, COutPort, CRefPort -from lava.magma.core.model.c.type import LavaCDataType, LavaCType -from lava.magma.core.model.py.model import PyLoihiProcessModel -from lava.magma.core.model.py.ports import PyInPort, PyOutPort, PyRefPort -from lava.magma.core.model.py.type import LavaPyType -from lava.magma.core.resources import CPU, LMT -from lava.magma.core.sync.protocols.loihi_protocol import LoihiProtocol - - -def readgate_post_guard(self): - """Decide whether to run post management phase.""" - return True if self.min_cost else False - - -def readgate_run_spk(self): - """Execute spiking phase, integrate input, update dynamics and - send messages out.""" - in_ports = [ - port for port in self.py_ports if issubclass(type(port), PyInPort) - ] - costs = [] - for port in in_ports: - costs.append(port.recv()[0]) - cost = min(costs) - id = costs.index(cost) - - if self.solution is not None: - timestep = -np.array([self.time_step]) - if self.min_cost <= self.target_cost: - self._req_pause = True - self.cost_out.send(np.array([self.min_cost, self.min_cost_id])) - self.send_pause_request.send(timestep) - self.solution_out.send(self.solution) - self.solution = None - self.min_cost = None - self.min_cost_id = None - else: - self.cost_out.send(np.array([0, 0])) - if cost: - self.min_cost = cost - self.min_cost_id = id - - -def readgate_run_post_mgmt(self): - """Execute post management phase.""" - self.solution = self.solution_reader.read() - - -def get_readgate_members(num_in_ports, backend: BACKENDS): - if not backend in BACKENDS: - raise ValueError(BACKEND_MSG) - - readgate_members = dict(min_cost=None, min_cost_id=None, solution=None) - - in_ports_py = { - f"cost_in_{id}": LavaPyType(PyInPort.VEC_DENSE, np.int32, precision=32) - for id in range(num_in_ports) - } - - class_members_py = dict( - target_cost=LavaPyType(int, np.int32, 32), - best_solution=LavaPyType(int, np.int32, 32), - cost_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, precision=32), - solution_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, precision=32), - send_pause_request=LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ), - solution_reader=LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32), - ) - - cpu_specific = dict( - post_guard=readgate_post_guard, - run_spk=readgate_run_spk, - run_post_mgmt=readgate_run_post_mgmt, - ) - - readgate_members.update(in_ports_py) - readgate_members.update(class_members_py) - readgate_members.update(cpu_specific) - return readgate_members - - -def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS): - """Produce CPU model for the ReadGate process. - - The model verifies if better payload (cost) has been notified by the - downstream processes, if so, it reads those processes state and sends - out to - the upstream process the new payload (cost) and the network state. - """ - if backend not in BACKENDS: - raise ValueError(BACKEND_MSG) - super_class = PyLoihiProcessModel if backend in CPUS else CLoihiProcessModel - resource = CPU if backend in CPUS else LMT - ReadGateModelBase = type( - "ReadGateModel", - (super_class,), - get_readgate_members(num_in_ports, backend), - ) - ReadGateModelImpl = implements(ReadGate, protocol=LoihiProtocol)( - ReadGateModelBase - ) - ReadGateModel = requires(resource)(ReadGateModelImpl) - return ReadGateModel - - -@implements(ReadGate, protocol=LoihiProtocol) -@requires(CPU) -class ReadGatePyModelD(PyLoihiProcessModel): - """CPU model for the ReadGate process. - - The model verifies if better payload (cost) has been notified by the - downstream processes, if so, it reads those processes state and sends - out to - the upstream process the new payload (cost) and the network state. - """ - - target_cost: int = LavaPyType(int, np.int32, 32) - best_solution: int = LavaPyType(int, np.int32, 32) - cost_in: PyInPort = LavaPyType(PyInPort.VEC_DENSE, np.int32, precision=32) - cost_out: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - solution_out: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - send_pause_request: PyOutPort = LavaPyType( - PyOutPort.VEC_DENSE, np.int32, precision=32 - ) - solution_reader = LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32) - min_cost: int = None - solution: np.ndarray = None - - def post_guard(self): - """Decide whether to run post management phase.""" - return True if self.min_cost else False - - def run_spk(self): - """Execute spiking phase, integrate input, update dynamics and - send messages out.""" - cost = self.cost_in.recv() - if cost[0]: - self.min_cost = cost[0] - self.cost_out.send(np.array([0])) - elif self.solution is not None: - timestep = -np.array([self.time_step]) - if self.min_cost <= self.target_cost: - self._req_pause = True - self.cost_out.send(np.array([self.min_cost])) - self.send_pause_request.send(timestep) - self.solution_out.send(self.solution) - self.solution = None - self.min_cost = None - else: - self.cost_out.send(np.array([0])) - - def run_post_mgmt(self): - """Execute post management phase.""" - self.solution = self.solution_reader.read() +# Copyright (C) 2022 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# See: https://spdx.org/licenses/ +import numpy as np +from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate +from lava.lib.optimization.solvers.generic.types_optim import ( + BACKENDS, + CPUS, + NEUROCORES, + BACKEND_MSG, +) +from lava.magma.core.model.spike_type import SpikeType + +from lava.magma.core.decorator import implements, requires +from lava.magma.core.model.c.model import CLoihiProcessModel +from lava.magma.core.model.c.ports import CInPort, COutPort, CRefPort +from lava.magma.core.model.c.type import LavaCDataType, LavaCType +from lava.magma.core.model.py.model import PyLoihiProcessModel +from lava.magma.core.model.py.ports import PyInPort, PyOutPort, PyRefPort +from lava.magma.core.model.py.type import LavaPyType +from lava.magma.core.resources import CPU, LMT +from lava.magma.core.sync.protocols.loihi_protocol import LoihiProtocol + + +def readgate_post_guard(self): + """Decide whether to run post management phase.""" + return True if self.min_cost else False + + +def readgate_run_spk(self): + """Execute spiking phase, integrate input, update dynamics and + send messages out.""" + in_ports = [ + port for port in self.py_ports if issubclass(type(port), PyInPort) + ] + costs = [] + for port in in_ports: + costs.append(port.recv()[0]) + cost = min(costs) + id = costs.index(cost) + + if self.solution is not None: + timestep = -np.array([self.time_step]) + if self.min_cost <= self.target_cost: + self._req_pause = True + self.cost_out.send(np.array([self.min_cost, self.min_cost_id])) + self.send_pause_request.send(timestep) + self.solution_out.send(self.solution) + self.solution = None + self.min_cost = None + self.min_cost_id = None + else: + self.cost_out.send(np.array([0, 0])) + if cost: + self.min_cost = cost + self.min_cost_id = id + + +def readgate_run_post_mgmt(self): + """Execute post management phase.""" + self.solution = self.solution_reader.read() + + +def get_readgate_members(num_in_ports, backend: BACKENDS): + if not backend in BACKENDS: + raise ValueError(BACKEND_MSG) + + readgate_members = dict(min_cost=None, min_cost_id=None, solution=None) + + in_ports_py = { + f"cost_in_{id}": LavaPyType(PyInPort.VEC_DENSE, np.int32, precision=32) + for id in range(num_in_ports) + } + + class_members_py = dict( + target_cost=LavaPyType(int, np.int32, 32), + best_solution=LavaPyType(int, np.int32, 32), + cost_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, precision=32), + solution_out=LavaPyType(PyOutPort.VEC_DENSE, np.int32, precision=32), + send_pause_request=LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ), + solution_reader=LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32), + ) + + cpu_specific = dict( + post_guard=readgate_post_guard, + run_spk=readgate_run_spk, + run_post_mgmt=readgate_run_post_mgmt, + ) + + readgate_members.update(in_ports_py) + readgate_members.update(class_members_py) + readgate_members.update(cpu_specific) + return readgate_members + + +def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS): + """Produce CPU model for the ReadGate process. + + The model verifies if better payload (cost) has been notified by the + downstream processes, if so, it reads those processes state and sends + out to + the upstream process the new payload (cost) and the network state. + """ + if backend not in BACKENDS: + raise ValueError(BACKEND_MSG) + super_class = PyLoihiProcessModel if backend in CPUS else CLoihiProcessModel + resource = CPU if backend in CPUS else LMT + ReadGateModelBase = type( + "ReadGateModel", + (super_class,), + get_readgate_members(num_in_ports, backend), + ) + ReadGateModelImpl = implements(ReadGate, protocol=LoihiProtocol)( + ReadGateModelBase + ) + ReadGateModel = requires(resource)(ReadGateModelImpl) + return ReadGateModel + + +@implements(ReadGate, protocol=LoihiProtocol) +@requires(CPU) +class ReadGatePyModelD(PyLoihiProcessModel): + """CPU model for the ReadGate process. + + The model verifies if better payload (cost) has been notified by the + downstream processes, if so, it reads those processes state and sends + out to + the upstream process the new payload (cost) and the network state. + """ + + target_cost: int = LavaPyType(int, np.int32, 32) + best_solution: int = LavaPyType(int, np.int32, 32) + cost_in: PyInPort = LavaPyType(PyInPort.VEC_DENSE, np.int32, precision=32) + cost_out: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + solution_out: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + send_pause_request: PyOutPort = LavaPyType( + PyOutPort.VEC_DENSE, np.int32, precision=32 + ) + solution_reader = LavaPyType(PyRefPort.VEC_DENSE, np.int32, precision=32) + min_cost: int = None + solution: np.ndarray = None + + def post_guard(self): + """Decide whether to run post management phase.""" + return True if self.min_cost else False + + def run_spk(self): + """Execute spiking phase, integrate input, update dynamics and + send messages out.""" + cost = self.cost_in.recv() + if cost[0]: + self.min_cost = cost[0] + self.cost_out.send(np.array([0])) + elif self.solution is not None: + timestep = -np.array([self.time_step]) + if self.min_cost <= self.target_cost: + self._req_pause = True + self.cost_out.send(np.array([self.min_cost])) + self.send_pause_request.send(timestep) + self.solution_out.send(self.solution) + self.solution = None + self.min_cost = None + else: + self.cost_out.send(np.array([0])) + + def run_post_mgmt(self): + """Execute post management phase.""" + self.solution = self.solution_reader.read() From 804910bca3057c85a2dffdf7694c80cbf7bd0362 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 22:56:13 +0100 Subject: [PATCH 15/27] Correct test for membership. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/read_gate/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lava/lib/optimization/solvers/generic/read_gate/models.py b/src/lava/lib/optimization/solvers/generic/read_gate/models.py index 13226746..6ffebf47 100644 --- a/src/lava/lib/optimization/solvers/generic/read_gate/models.py +++ b/src/lava/lib/optimization/solvers/generic/read_gate/models.py @@ -62,7 +62,7 @@ def readgate_run_post_mgmt(self): def get_readgate_members(num_in_ports, backend: BACKENDS): - if not backend in BACKENDS: + if backend not in BACKENDS: raise ValueError(BACKEND_MSG) readgate_members = dict(min_cost=None, min_cost_id=None, solution=None) From 9c9cf2aa697febc903cd9db545763c36013d75ea Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 23:01:02 +0100 Subject: [PATCH 16/27] Optimize imports. Signed-off-by: GaboFGuerra --- .../optimization/solvers/generic/solver.py | 50 +++++++------------ 1 file changed, 17 insertions(+), 33 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index 8387f847..14935bb0 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -7,32 +7,20 @@ import numpy as np from lava.lib.optimization.problems.problems import OptimizationProblem from lava.lib.optimization.solvers.generic.builder import SolverProcessBuilder -from lava.lib.optimization.solvers.generic.hierarchical_processes import ( - NEBMAbstract, - NEBMSimulatedAnnealingAbstract, - ) +from lava.lib.optimization.solvers.generic.hierarchical_processes import \ + NEBMAbstract, NEBMSimulatedAnnealingAbstract from lava.lib.optimization.solvers.generic.nebm.models import NEBMPyModel -from lava.lib.optimization.solvers.generic.nebm.process import ( - NEBM, +from lava.lib.optimization.solvers.generic.nebm.process import NEBM, \ NEBMSimulatedAnnealing - ) -from lava.lib.optimization.solvers.generic.scif.models import ( - PyModelQuboScifFixed, - ) +from lava.lib.optimization.solvers.generic.scif.models import \ + PyModelQuboScifFixed from lava.lib.optimization.solvers.generic.scif.process import QuboScif -from lava.lib.optimization.solvers.generic.sub_process_models import ( - NEBMAbstractModel, - NEBMSimulatedAnnealingAbstractModel, - ) -from lava.lib.optimization.solvers.generic.types_optim import ( - BACKENDS_TYPE, HP_TYPE, - CPUS, NEUROCORES, BACKEND_MSG - ) -from lava.magma.core.resources import ( - AbstractComputeResource, - CPU, - Loihi2NeuroCore, - ) +from lava.lib.optimization.solvers.generic.sub_process_models import \ + NEBMAbstractModel, NEBMSimulatedAnnealingAbstractModel +from lava.lib.optimization.solvers.generic.types_optim import BACKENDS_TYPE, \ + HP_TYPE, CPUS, NEUROCORES, BACKEND_MSG +from lava.magma.core.resources import AbstractComputeResource, CPU, \ + Loihi2NeuroCore from lava.magma.core.run_conditions import RunSteps from lava.magma.core.run_configs import Loihi1SimCfg, Loihi2HwCfg from lava.magma.core.sync.protocol import AbstractSyncProtocol @@ -43,17 +31,13 @@ from lava.utils.profiler import Profiler try: - from lava.lib.optimization.solvers.generic.read_gate.ncmodels import ( - ReadGateCModel, - ) + from lava.lib.optimization.solvers.generic.read_gate.ncmodels import \ + ReadGateCModel from lava.proc.dense.ncmodels import NcModelDense - from lava.lib.optimization.solvers.generic.nebm.ncmodels import ( - NEBMNcModel, - NEBMSimulatedAnnealingNcModel, - ) - from lava.lib.optimization.solvers.generic.cost_integrator.ncmodels import ( - CostIntegratorNcModel, - ) + from lava.lib.optimization.solvers.generic.nebm.ncmodels import \ + NEBMNcModel, NEBMSimulatedAnnealingNcModel + from lava.lib.optimization.solvers.generic.cost_integrator.ncmodels \ + import CostIntegratorNcModel except ImportError: class ReadGateCModel: From 0ce5ca72e89c5c9dbd578bc63a5998078b071b9d Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 23:03:40 +0100 Subject: [PATCH 17/27] Solve linting. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/solver.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index 14935bb0..8028e49a 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -267,8 +267,8 @@ def _get_requirements_and_protocol( Parameters ---------- backend: BACKENDS_TYPE - Specifies the backend for which requirements and protocol classes - will be returned. + Specifies the backend for which requirements and protocol + classes will be returned. """ return [CPU] if backend in CPUS else [Loihi2NeuroCore], LoihiProtocol @@ -307,9 +307,7 @@ def _get_run_config( ) elif backend in NEUROCORES: from lava.lib.optimization.solvers.generic.read_gate.ncmodels \ - import ( - get_read_gate_c_model_class, - ) + import get_read_gate_c_model_class ReadGateCModel = get_read_gate_c_model_class(num_in_ports, backend) pdict = { self.solver_process: self.solver_model, From 99efed994595681df81cc3a2ea8ccf7cddcedb96 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 23:05:43 +0100 Subject: [PATCH 18/27] Solve linting issue. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/solver.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index 8028e49a..ba9a8dc2 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -289,9 +289,8 @@ def _get_run_config( ReadGate, ) if backend in CPUS: - from lava.lib.optimization.solvers.generic.read_gate.models import ( - get_read_gate_py_model_class, - ) + from lava.lib.optimization.solvers.generic.read_gate.models \ + import get_read_gate_py_model_class ReadGatePyModel = get_read_gate_py_model_class(num_in_ports, backend) pdict = { From 4ce378681a1038f0b48c13964d1f22986d42bf8d Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 23:11:10 +0100 Subject: [PATCH 19/27] Update function name. Signed-off-by: GaboFGuerra --- .../solvers/generic/solution_finder/test_solution_finder.py | 4 ++-- .../solvers/generic/solution_reader/test_solution_reader.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/lava/lib/optimization/solvers/generic/solution_finder/test_solution_finder.py b/tests/lava/lib/optimization/solvers/generic/solution_finder/test_solution_finder.py index 39a64f43..ddd35463 100644 --- a/tests/lava/lib/optimization/solvers/generic/solution_finder/test_solution_finder.py +++ b/tests/lava/lib/optimization/solvers/generic/solution_finder/test_solution_finder.py @@ -6,7 +6,7 @@ import numpy as np from lava.lib.optimization.problems.problems import QUBO from lava.lib.optimization.solvers.generic.read_gate.models import \ - get_read_gate_model_class + get_read_gate_py_model_class from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate from lava.lib.optimization.solvers.generic.solution_finder.process import ( SolutionFinder, @@ -47,7 +47,7 @@ def setUp(self) -> None: ) # Execution configurations. - ReadGatePyModel = get_read_gate_model_class(1) + ReadGatePyModel = get_read_gate_py_model_class(1) pdict = {ReadGate: ReadGatePyModel} self.run_cfg = Loihi2SimCfg(exception_proc_model_map=pdict) self.solution_finder._log_config.level = 20 diff --git a/tests/lava/lib/optimization/solvers/generic/solution_reader/test_solution_reader.py b/tests/lava/lib/optimization/solvers/generic/solution_reader/test_solution_reader.py index eac48d9c..26bd2ff5 100644 --- a/tests/lava/lib/optimization/solvers/generic/solution_reader/test_solution_reader.py +++ b/tests/lava/lib/optimization/solvers/generic/solution_reader/test_solution_reader.py @@ -8,7 +8,7 @@ SolutionReader, ) from lava.lib.optimization.solvers.generic.read_gate.models import \ - get_read_gate_model_class + get_read_gate_py_model_class from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate from lava.magma.core.run_conditions import RunContinuous from lava.magma.core.run_configs import Loihi2SimCfg @@ -31,7 +31,7 @@ def setUp(self) -> None: self.solution_reader.ref_port.connect_var(spiker.payload) # Execution configurations. - ReadGatePyModel = get_read_gate_model_class(1) + ReadGatePyModel = get_read_gate_py_model_class(1) pdict = {ReadGate: ReadGatePyModel, Spiker: SpikerModel} self.run_cfg = Loihi2SimCfg(exception_proc_model_map=pdict) self.solution_reader._log_config.level = 20 From 61015dbc59de294fb92365bf8ac36e9068d7ac08 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 23:14:23 +0100 Subject: [PATCH 20/27] Update function name. Signed-off-by: GaboFGuerra --- .../generic/integration/test_finder_reader_integration.py | 4 ++-- .../solution_readout/test_solution_readout.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/lava/lib/optimization/solvers/generic/integration/test_finder_reader_integration.py b/tests/lava/lib/optimization/solvers/generic/integration/test_finder_reader_integration.py index cafd4fca..c3ba4f7e 100644 --- a/tests/lava/lib/optimization/solvers/generic/integration/test_finder_reader_integration.py +++ b/tests/lava/lib/optimization/solvers/generic/integration/test_finder_reader_integration.py @@ -7,7 +7,7 @@ import numpy as np from lava.lib.optimization.problems.problems import OptimizationProblem, QUBO from lava.lib.optimization.solvers.generic.read_gate.models import \ - get_read_gate_model_class + get_read_gate_py_model_class from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate from lava.lib.optimization.solvers.generic.solution_finder.process import ( SolutionFinder, @@ -24,7 +24,7 @@ from lava.magma.core.sync.protocols.loihi_protocol import LoihiProtocol from numpy import typing as npt -ReadGatePyModel = get_read_gate_model_class(1) +ReadGatePyModel = get_read_gate_py_model_class(1) class Mock: diff --git a/tests/lava/lib/optimization/solvers/generic/monitoring_processes/solution_readout/test_solution_readout.py b/tests/lava/lib/optimization/solvers/generic/monitoring_processes/solution_readout/test_solution_readout.py index 9599d535..5d129edc 100644 --- a/tests/lava/lib/optimization/solvers/generic/monitoring_processes/solution_readout/test_solution_readout.py +++ b/tests/lava/lib/optimization/solvers/generic/monitoring_processes/solution_readout/test_solution_readout.py @@ -10,7 +10,7 @@ .solution_readout.process import \ SolutionReadout from lava.lib.optimization.solvers.generic.read_gate.models import \ - get_read_gate_model_class + get_read_gate_py_model_class from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate from lava.magma.core.run_conditions import RunContinuous from lava.magma.core.run_configs import Loihi2SimCfg @@ -34,7 +34,7 @@ def setUp(self) -> None: readgate.send_pause_request.connect(self.readout.timestep_in) # Execution configurations. - ReadGatePyModel = get_read_gate_model_class(1) + ReadGatePyModel = get_read_gate_py_model_class(1) pdict = {ReadGate: ReadGatePyModel, Spiker: SpikerModel} self.run_cfg = Loihi2SimCfg(exception_proc_model_map=pdict) self.readout._log_config.level = 20 From 058d5222d1b4e84d9d115509d0025d0a0cbb524d Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 23:17:35 +0100 Subject: [PATCH 21/27] Add default backend to function. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/read_gate/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lava/lib/optimization/solvers/generic/read_gate/models.py b/src/lava/lib/optimization/solvers/generic/read_gate/models.py index 6ffebf47..732dc830 100644 --- a/src/lava/lib/optimization/solvers/generic/read_gate/models.py +++ b/src/lava/lib/optimization/solvers/generic/read_gate/models.py @@ -95,7 +95,7 @@ def get_readgate_members(num_in_ports, backend: BACKENDS): return readgate_members -def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS): +def get_read_gate_py_model_class(num_in_ports: int=CPU): """Produce CPU model for the ReadGate process. The model verifies if better payload (cost) has been notified by the From 1c1506e1df34cf1542e5508d27ac230d0550dc7a Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 23:20:19 +0100 Subject: [PATCH 22/27] Add missing white spaces. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/read_gate/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lava/lib/optimization/solvers/generic/read_gate/models.py b/src/lava/lib/optimization/solvers/generic/read_gate/models.py index 732dc830..2df831d5 100644 --- a/src/lava/lib/optimization/solvers/generic/read_gate/models.py +++ b/src/lava/lib/optimization/solvers/generic/read_gate/models.py @@ -95,7 +95,7 @@ def get_readgate_members(num_in_ports, backend: BACKENDS): return readgate_members -def get_read_gate_py_model_class(num_in_ports: int=CPU): +def get_read_gate_py_model_class(num_in_ports: int = CPU): """Produce CPU model for the ReadGate process. The model verifies if better payload (cost) has been notified by the From d606bd691e0d6c9d2a28203117d7ae06e338730c Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 16 Mar 2023 23:21:24 +0100 Subject: [PATCH 23/27] Add default value for argument in funciton. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/read_gate/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lava/lib/optimization/solvers/generic/read_gate/models.py b/src/lava/lib/optimization/solvers/generic/read_gate/models.py index 2df831d5..050537b2 100644 --- a/src/lava/lib/optimization/solvers/generic/read_gate/models.py +++ b/src/lava/lib/optimization/solvers/generic/read_gate/models.py @@ -95,7 +95,7 @@ def get_readgate_members(num_in_ports, backend: BACKENDS): return readgate_members -def get_read_gate_py_model_class(num_in_ports: int = CPU): +def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS=CPU): """Produce CPU model for the ReadGate process. The model verifies if better payload (cost) has been notified by the From d05b9315d11e0d026233d524912c8640714762cc Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Fri, 17 Mar 2023 13:36:03 +0100 Subject: [PATCH 24/27] Add missing white spaces. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/read_gate/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lava/lib/optimization/solvers/generic/read_gate/models.py b/src/lava/lib/optimization/solvers/generic/read_gate/models.py index 050537b2..7ed1e07a 100644 --- a/src/lava/lib/optimization/solvers/generic/read_gate/models.py +++ b/src/lava/lib/optimization/solvers/generic/read_gate/models.py @@ -95,7 +95,7 @@ def get_readgate_members(num_in_ports, backend: BACKENDS): return readgate_members -def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS=CPU): +def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS = CPU): """Produce CPU model for the ReadGate process. The model verifies if better payload (cost) has been notified by the From 0f4a6be50de8c37732f8c87b1f71db07f9ed4d33 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Mon, 20 Mar 2023 12:13:08 +0100 Subject: [PATCH 25/27] Remove backend param as obsolete after separation of backends. Signed-off-by: GaboFGuerra --- .../solvers/generic/read_gate/models.py | 25 ++++--------------- .../optimization/solvers/generic/solver.py | 3 +-- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/src/lava/lib/optimization/solvers/generic/read_gate/models.py b/src/lava/lib/optimization/solvers/generic/read_gate/models.py index 7ed1e07a..676e8592 100644 --- a/src/lava/lib/optimization/solvers/generic/read_gate/models.py +++ b/src/lava/lib/optimization/solvers/generic/read_gate/models.py @@ -3,18 +3,8 @@ # See: https://spdx.org/licenses/ import numpy as np from lava.lib.optimization.solvers.generic.read_gate.process import ReadGate -from lava.lib.optimization.solvers.generic.types_optim import ( - BACKENDS, - CPUS, - NEUROCORES, - BACKEND_MSG, -) -from lava.magma.core.model.spike_type import SpikeType from lava.magma.core.decorator import implements, requires -from lava.magma.core.model.c.model import CLoihiProcessModel -from lava.magma.core.model.c.ports import CInPort, COutPort, CRefPort -from lava.magma.core.model.c.type import LavaCDataType, LavaCType from lava.magma.core.model.py.model import PyLoihiProcessModel from lava.magma.core.model.py.ports import PyInPort, PyOutPort, PyRefPort from lava.magma.core.model.py.type import LavaPyType @@ -61,10 +51,7 @@ def readgate_run_post_mgmt(self): self.solution = self.solution_reader.read() -def get_readgate_members(num_in_ports, backend: BACKENDS): - if backend not in BACKENDS: - raise ValueError(BACKEND_MSG) - +def get_readgate_members(num_in_ports): readgate_members = dict(min_cost=None, min_cost_id=None, solution=None) in_ports_py = { @@ -95,7 +82,7 @@ def get_readgate_members(num_in_ports, backend: BACKENDS): return readgate_members -def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS = CPU): +def get_read_gate_py_model_class(num_in_ports: int): """Produce CPU model for the ReadGate process. The model verifies if better payload (cost) has been notified by the @@ -103,14 +90,12 @@ def get_read_gate_py_model_class(num_in_ports: int, backend: BACKENDS = CPU): out to the upstream process the new payload (cost) and the network state. """ - if backend not in BACKENDS: - raise ValueError(BACKEND_MSG) - super_class = PyLoihiProcessModel if backend in CPUS else CLoihiProcessModel - resource = CPU if backend in CPUS else LMT + super_class = PyLoihiProcessModel + resource = CPU ReadGateModelBase = type( "ReadGateModel", (super_class,), - get_readgate_members(num_in_ports, backend), + get_readgate_members(num_in_ports), ) ReadGateModelImpl = implements(ReadGate, protocol=LoihiProtocol)( ReadGateModelBase diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index ba9a8dc2..cdbd5dfe 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -291,8 +291,7 @@ def _get_run_config( if backend in CPUS: from lava.lib.optimization.solvers.generic.read_gate.models \ import get_read_gate_py_model_class - ReadGatePyModel = get_read_gate_py_model_class(num_in_ports, - backend) + ReadGatePyModel = get_read_gate_py_model_class(num_in_ports) pdict = { self.solver_process: self.solver_model, ReadGate: ReadGatePyModel, From 2f6cc334ba9e5a06eb73e4731d5eb43f0302e2ab Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 23 Mar 2023 10:51:15 +0100 Subject: [PATCH 26/27] Complete conditional for reading state. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/solver.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lava/lib/optimization/solvers/generic/solver.py b/src/lava/lib/optimization/solvers/generic/solver.py index cdbd5dfe..92fb0644 100644 --- a/src/lava/lib/optimization/solvers/generic/solver.py +++ b/src/lava/lib/optimization/solvers/generic/solver.py @@ -343,7 +343,8 @@ def _get_results(self, config: SolverConfig): return best_state, int(best_cost), int(best_timestep) def _get_best_state(self, config: SolverConfig, idx: int): - if isinstance(config.hyperparameters, list): + if isinstance(config.hyperparameters, list) and len( + config.hyperparameters) > 1: raw_solution = np.asarray( self.solver_process.finders[int(idx)].variables_assignment.get() ).astype(np.int32) From a9ae2ec8edc0a48979b31ce80f8a18ef78210f11 Mon Sep 17 00:00:00 2001 From: GaboFGuerra Date: Thu, 23 Mar 2023 11:11:25 +0100 Subject: [PATCH 27/27] Remove sconfig.py as not needed anymore. Signed-off-by: GaboFGuerra --- src/lava/lib/optimization/solvers/generic/sconfig.py | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 src/lava/lib/optimization/solvers/generic/sconfig.py diff --git a/src/lava/lib/optimization/solvers/generic/sconfig.py b/src/lava/lib/optimization/solvers/generic/sconfig.py deleted file mode 100644 index ed6b2fe5..00000000 --- a/src/lava/lib/optimization/solvers/generic/sconfig.py +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (C) 2023 Intel Corporation -# SPDX-License-Identifier: BSD-3-Clause -# See: https://spdx.org/licenses/ - -num_in_ports = 1