-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Factory function that converts PyLoihi process models to PyAsync mode…
…ls on the fly (#595) * update refport unittest to always wait when it writes to port for consistent behavior Signed-off-by: bamsumit <[email protected]> * Removed pyproject changes Signed-off-by: bamsumit <[email protected]> * Fix to convolution tests. Fixed imcompatible mnist_pretrained for old python versions. Signed-off-by: bamsumit <[email protected]> * Missing moudle parent fix Signed-off-by: bamsumit <[email protected]> * Added ConvVarModel * Loihi 2 Async implemented Signed-off-by: bamsumit <[email protected]> * Removed vestigial run_spk in LIF models Signed-off-by: bamsumit <[email protected]> * unittest added Signed-off-by: bamsumit <[email protected]> * Forcing multiprocessing to always fork to avoid pikcling error on Windows Signed-off-by: bamsumit <[email protected]> * Forcing multiprocessing to always fork to avoid pikcling error on Windows Signed-off-by: bamsumit <[email protected]> * ForRemoved forced multiprocessing fork Signed-off-by: bamsumit <[email protected]> * Linting fix Signed-off-by: bamsumit <[email protected]> * Forcing multiprocessing to always fork to avoid pikcling error on Mac Signed-off-by: bamsumit <[email protected]> * Removed support for windows Signed-off-by: bamsumit <[email protected]> --------- Signed-off-by: bamsumit <[email protected]> Co-authored-by: Joyesh Mishra <[email protected]>
- Loading branch information
1 parent
aa84ac2
commit 83df172
Showing
4 changed files
with
289 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
# Copyright (C) 2023 Intel Corporation | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
# See: https://spdx.org/licenses/ | ||
|
||
import unittest | ||
import platform | ||
import numpy as np | ||
|
||
from lava.magma.core.run_conditions import RunSteps | ||
from lava.magma.core.run_configs import Loihi2SimCfg | ||
from lava.magma.core.sync.protocols.async_protocol import AsyncProtocol | ||
from lava.magma.core.model.py.model import ( | ||
PyLoihiProcessModel, PyLoihiModelToPyAsyncModel | ||
) | ||
|
||
from lava.proc import io | ||
from lava.proc.lif.process import LIF | ||
from lava.proc.sdn.process import SigmaDelta | ||
from lava.proc.dense.process import Dense | ||
|
||
from lava.proc.lif.models import PyLifModelFloat, PyLifModelBitAcc | ||
from lava.proc.sdn.models import PySigmaDeltaModelFixed | ||
from lava.proc.dense.models import PyDenseModelFloat | ||
|
||
|
||
py_loihi_models = [PyLifModelFloat, PyLifModelBitAcc, PySigmaDeltaModelFixed, | ||
PyDenseModelFloat] | ||
|
||
|
||
class CustomRunConfig(Loihi2SimCfg): | ||
"""Custom run config that converts PyLoihi models to PyAsync models.""" | ||
|
||
def __init__(self, **kwargs): | ||
super().__init__(**kwargs) | ||
|
||
def select(self, proc, proc_models): | ||
pm = super().select(proc, proc_models) | ||
if issubclass(pm, PyLoihiProcessModel): | ||
return PyLoihiModelToPyAsyncModel(pm) | ||
return pm | ||
|
||
|
||
class TestPyLoihiToPyAsync(unittest.TestCase): | ||
@unittest.skipIf(platform.system() == 'Windows', | ||
'Model conversion is not supported on Windows.') | ||
def test_model_conversion(self): | ||
"""Test model conversion""" | ||
for py_loihi_model in py_loihi_models: | ||
py_async_model = PyLoihiModelToPyAsyncModel(py_loihi_model) | ||
self.assertTrue(py_loihi_model.implements_process | ||
== py_async_model.implements_process) | ||
self.assertTrue( | ||
py_async_model.implements_protocol == AsyncProtocol) | ||
self.assertTrue(hasattr(py_async_model, 'run_async')) | ||
|
||
@unittest.skipIf(platform.system() == 'Windows', | ||
'Model conversion is not supported on Windows.') | ||
def test_lif_dense_lif(self): | ||
"""Test LIF-Dense-LIF equivalency.""" | ||
in_size = 10 | ||
out_size = 8 | ||
weights = np.arange(in_size * out_size).reshape(out_size, in_size) - 25 | ||
weights *= 2 | ||
bias = 20 + np.arange(in_size) | ||
|
||
input_lif_params = {'shape': (in_size,), | ||
'du': 0, | ||
'dv': 0, | ||
'bias_mant': bias, | ||
'bias_exp': 6, | ||
'vth': 20} | ||
output_lif_params = {'shape': (out_size,), | ||
'du': 4096, | ||
'dv': 4096, | ||
'vth': 1024} | ||
dense_params = {'weights': weights} | ||
|
||
input_lif = LIF(**input_lif_params) | ||
output_lif = LIF(**output_lif_params) | ||
dense = Dense(**dense_params) | ||
input_lif.s_out.connect(dense.s_in) | ||
dense.a_out.connect(output_lif.a_in) | ||
|
||
run_cnd = RunSteps(num_steps=2) | ||
# simply run the pyproc model | ||
output_lif.run(condition=run_cnd, | ||
run_cfg=Loihi2SimCfg(select_tag='fixed_pt')) | ||
current_gt = output_lif.u.get() | ||
voltage_gt = output_lif.v.get() | ||
output_lif.stop() | ||
|
||
# Run the same network in async mode. | ||
# Currently we don't allow the same process to run twice | ||
# Copy the model used for pyproc model | ||
input_lif = LIF(**input_lif_params) | ||
output_lif = LIF(**output_lif_params) | ||
dense = Dense(**dense_params) | ||
input_lif.s_out.connect(dense.s_in) | ||
dense.a_out.connect(output_lif.a_in) | ||
output_lif.run(condition=run_cnd, | ||
run_cfg=CustomRunConfig(select_tag='fixed_pt')) | ||
current = output_lif.u.get() | ||
voltage = output_lif.v.get() | ||
output_lif.stop() | ||
|
||
self.assertTrue(np.array_equal(current, current_gt)) | ||
self.assertTrue(np.array_equal(voltage, voltage_gt)) | ||
|
||
@unittest.skipIf(platform.system() == 'Windows', | ||
'Model conversion is not supported on Windows.') | ||
def test_sdn_dense_sdn(self): | ||
"""Test LIF-Dense-LIF equivalency.""" | ||
in_size = 10 | ||
out_size = 8 | ||
weights = np.arange(in_size * out_size).reshape(out_size, in_size) - 25 | ||
weights *= 2 | ||
bias = 20 + np.arange(in_size) | ||
|
||
input_params = {'shape': (in_size,), | ||
'vth': 22, | ||
'bias': bias, | ||
'spike_exp': 6, | ||
'state_exp': 6} | ||
output_params = {'shape': (out_size,), | ||
'vth': 2, | ||
'spike_exp': 6, | ||
'state_exp': 6} | ||
dense_params = {'weights': weights, 'num_message_bits': 16} | ||
|
||
input = SigmaDelta(**input_params) | ||
output = SigmaDelta(**output_params) | ||
dense = Dense(**dense_params) | ||
input.s_out.connect(dense.s_in) | ||
dense.a_out.connect(output.a_in) | ||
|
||
run_cnd = RunSteps(num_steps=2) | ||
# simply run the pyproc model | ||
output.run(condition=run_cnd, | ||
run_cfg=Loihi2SimCfg(select_tag='fixed_pt')) | ||
sigma_gt = output.sigma.get() | ||
output.stop() | ||
|
||
# Run the same network in async mode. | ||
# Currently we don't allow the same process to run twice | ||
# Copy the model used for pyproc model | ||
input = SigmaDelta(**input_params) | ||
output = SigmaDelta(**output_params) | ||
dense = Dense(**dense_params) | ||
input.s_out.connect(dense.s_in) | ||
dense.a_out.connect(output.a_in) | ||
|
||
output.run(condition=run_cnd, | ||
run_cfg=CustomRunConfig(select_tag='fixed_pt')) | ||
sigma = output.sigma.get() | ||
output.stop() | ||
|
||
self.assertTrue(np.array_equal(sigma, sigma_gt)) |