Skip to content
Snippets Groups Projects
Commit 29f3f9f6 authored by Angus Lothian's avatar Angus Lothian :dark_sunglasses:
Browse files

Revert "Deleted README.md"

This reverts commit 21124444
parent 726c8e18
No related branches found
No related tags found
No related merge requests found
setup.py 0 → 100644
import os
import sys
import shutil
import subprocess
import setuptools
from setuptools import Extension
from setuptools.command.build_ext import build_ext
CMAKE_EXE = os.environ.get('CMAKE_EXE', shutil.which('cmake'))
class CMakeExtension(Extension):
def __init__(self, name, sourcedir = ""):
super().__init__(name, sources=[])
self.sourcedir = os.path.abspath(sourcedir)
class CMakeBuild(build_ext):
def build_extension(self, ext):
if not isinstance(ext, CMakeExtension):
return super().build_extension(ext)
if not CMAKE_EXE:
raise RuntimeError(f"Cannot build extension {ext.name}: CMake executable not found! Set the CMAKE_EXE environment variable or update your path.")
cmake_build_type = "Debug" if self.debug else "Release"
cmake_output_dir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name)))
cmake_configure_argv = [
CMAKE_EXE, ext.sourcedir,
"-DCMAKE_BUILD_TYPE=" + cmake_build_type,
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=" + cmake_output_dir,
"-DPYTHON_EXECUTABLE=" + sys.executable,
]
cmake_build_argv = [
CMAKE_EXE, "--build", ".",
"--config", cmake_build_type
]
if not os.path.exists(self.build_temp):
os.makedirs(self.build_temp)
env = os.environ.copy()
print(f"=== Configuring {ext.name} ===")
print(f"Temp dir: {self.build_temp}")
print(f"Output dir: {cmake_output_dir}")
subprocess.check_call(cmake_configure_argv, cwd=self.build_temp, env=env)
print(f"=== Building {ext.name} ===")
print(f"Temp dir: {self.build_temp}")
print(f"Output dir: {cmake_output_dir}")
print(f"Build type: {cmake_build_type}")
subprocess.check_call(cmake_build_argv, cwd=self.build_temp, env=env)
print()
setuptools.setup(
name = "b-asic",
version = "0.0.1",
author = "Adam Jakobsson, Angus Lothian, Arvid Westerlund, Felix Goding, Ivar Härnqvist, Jacob Wahlman, Kevin Scott, Rasmus Karlsson",
author_email = "adaja901@student.liu.se, anglo547@student.liu.se, arvwe160@student.liu.se, felgo673@student.liu.se, ivaha717@student.liu.se, jacwa448@student.liu.se, kevsc634@student.liu.se, raska119@student.liu.se",
description = "Better ASIC Toolbox",
long_description = open("README.md", "r").read(),
long_description_content_type = "text/markdown",
url = "https://gitlab.liu.se/PUM_TDDD96/B-ASIC",
license = "MIT",
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires = ">=3.6",
install_requires = [
"pybind11>=2.3.0",
"numpy",
"install_qt_binding"
],
packages = ["b_asic"],
ext_modules = [CMakeExtension("b_asic")],
cmdclass = {"build_ext": CMakeBuild},
zip_safe = False
)
\ No newline at end of file
#include <pybind11/pybind11.h>
namespace py = pybind11;
namespace asic {
int add(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b;
}
} // namespace asic
PYBIND11_MODULE(_b_asic, m) {
m.doc() = "Better ASIC Toolbox Extension Module.";
m.def("add", &asic::add, "A function which adds two numbers.", py::arg("a"), py::arg("b"));
m.def("sub", &asic::sub, "A function which subtracts two numbers.", py::arg("a"), py::arg("b"));
}
\ No newline at end of file
from test.fixtures.signal import signal, signals
from test.fixtures.operation_tree import *
from test.fixtures.port import *
import pytest
from b_asic.core_operations import Addition, Constant
from b_asic.signal import Signal
import pytest
@pytest.fixture
def operation():
return Constant(2)
def create_operation(_type, dest_oper, index, **kwargs):
oper = _type(**kwargs)
oper_signal = Signal()
oper._output_ports[0].add_signal(oper_signal)
dest_oper._input_ports[index].add_signal(oper_signal)
return oper
@pytest.fixture
def operation_tree():
"""Return a addition operation connected with 2 constants.
---C---+
---A
---C---+
"""
add_oper = Addition()
create_operation(Constant, add_oper, 0, value=2)
create_operation(Constant, add_oper, 1, value=3)
return add_oper
@pytest.fixture
def large_operation_tree():
"""Return a constant operation connected with a large operation tree with 3 other constants and 3 additions.
---C---+
---A---+
---C---+ |
+---A
---C---+ |
---A---+
---C---+
"""
add_oper = Addition()
add_oper_2 = Addition()
const_oper = create_operation(Constant, add_oper, 0, value=2)
create_operation(Constant, add_oper, 1, value=3)
create_operation(Constant, add_oper_2, 0, value=4)
create_operation(Constant, add_oper_2, 1, value=5)
add_oper_3 = Addition()
add_oper_signal = Signal(add_oper.output(0), add_oper_3.output(0))
add_oper._output_ports[0].add_signal(add_oper_signal)
add_oper_3._input_ports[0].add_signal(add_oper_signal)
add_oper_2_signal = Signal(add_oper_2.output(0), add_oper_3.output(0))
add_oper_2._output_ports[0].add_signal(add_oper_2_signal)
add_oper_3._input_ports[1].add_signal(add_oper_2_signal)
return const_oper
import pytest
from b_asic.port import InputPort, OutputPort
@pytest.fixture
def input_port():
return InputPort(0, None)
@pytest.fixture
def output_port():
return OutputPort(0, None)
import pytest
from b_asic import Signal
@pytest.fixture
def signal():
"""Return a signal with no connections."""
return Signal()
@pytest.fixture
def signals():
"""Return 3 signals with no connections."""
return [Signal() for _ in range(0,3)]
"""
B-ASIC test suite for the AbstractOperation class.
"""
from b_asic.core_operations import Addition, ConstantAddition, Subtraction, ConstantSubtraction, \
Multiplication, ConstantMultiplication, Division, ConstantDivision
import pytest
def test_addition_overload():
"""Tests addition overloading for both operation and number argument."""
add1 = Addition(None, None, "add1")
add2 = Addition(None, None, "add2")
add3 = add1 + add2
assert isinstance(add3, Addition)
assert add3.input(0).signals == add1.output(0).signals
assert add3.input(1).signals == add2.output(0).signals
add4 = add3 + 5
assert isinstance(add4, ConstantAddition)
assert add4.input(0).signals == add3.output(0).signals
def test_subtraction_overload():
"""Tests subtraction overloading for both operation and number argument."""
add1 = Addition(None, None, "add1")
add2 = Addition(None, None, "add2")
sub1 = add1 - add2
assert isinstance(sub1, Subtraction)
assert sub1.input(0).signals == add1.output(0).signals
assert sub1.input(1).signals == add2.output(0).signals
sub2 = sub1 - 5
assert isinstance(sub2, ConstantSubtraction)
assert sub2.input(0).signals == sub1.output(0).signals
def test_multiplication_overload():
"""Tests multiplication overloading for both operation and number argument."""
add1 = Addition(None, None, "add1")
add2 = Addition(None, None, "add2")
mul1 = add1 * add2
assert isinstance(mul1, Multiplication)
assert mul1.input(0).signals == add1.output(0).signals
assert mul1.input(1).signals == add2.output(0).signals
mul2 = mul1 * 5
assert isinstance(mul2, ConstantMultiplication)
assert mul2.input(0).signals == mul1.output(0).signals
def test_division_overload():
"""Tests division overloading for both operation and number argument."""
add1 = Addition(None, None, "add1")
add2 = Addition(None, None, "add2")
div1 = add1 / add2
assert isinstance(div1, Division)
assert div1.input(0).signals == add1.output(0).signals
assert div1.input(1).signals == add2.output(0).signals
div2 = div1 / 5
assert isinstance(div2, ConstantDivision)
assert div2.input(0).signals == div1.output(0).signals
"""
B-ASIC test suite for the core operations.
"""
from b_asic.core_operations import Constant, Addition, Subtraction, Multiplication, Division, SquareRoot, ComplexConjugate, Max, Min, Absolute, ConstantMultiplication, ConstantAddition, ConstantSubtraction, ConstantDivision
# Constant tests.
def test_constant():
constant_operation = Constant(3)
assert constant_operation.evaluate() == 3
def test_constant_negative():
constant_operation = Constant(-3)
assert constant_operation.evaluate() == -3
def test_constant_complex():
constant_operation = Constant(3+4j)
assert constant_operation.evaluate() == 3+4j
# Addition tests.
def test_addition():
test_operation = Addition()
constant_operation = Constant(3)
constant_operation_2 = Constant(5)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 8
def test_addition_negative():
test_operation = Addition()
constant_operation = Constant(-3)
constant_operation_2 = Constant(-5)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == -8
def test_addition_complex():
test_operation = Addition()
constant_operation = Constant((3+5j))
constant_operation_2 = Constant((4+6j))
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == (7+11j)
# Subtraction tests.
def test_subtraction():
test_operation = Subtraction()
constant_operation = Constant(5)
constant_operation_2 = Constant(3)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 2
def test_subtraction_negative():
test_operation = Subtraction()
constant_operation = Constant(-5)
constant_operation_2 = Constant(-3)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == -2
def test_subtraction_complex():
test_operation = Subtraction()
constant_operation = Constant((3+5j))
constant_operation_2 = Constant((4+6j))
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == (-1-1j)
# Multiplication tests.
def test_multiplication():
test_operation = Multiplication()
constant_operation = Constant(5)
constant_operation_2 = Constant(3)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 15
def test_multiplication_negative():
test_operation = Multiplication()
constant_operation = Constant(-5)
constant_operation_2 = Constant(-3)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 15
def test_multiplication_complex():
test_operation = Multiplication()
constant_operation = Constant((3+5j))
constant_operation_2 = Constant((4+6j))
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == (-18+38j)
# Division tests.
def test_division():
test_operation = Division()
constant_operation = Constant(30)
constant_operation_2 = Constant(5)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 6
def test_division_negative():
test_operation = Division()
constant_operation = Constant(-30)
constant_operation_2 = Constant(-5)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 6
def test_division_complex():
test_operation = Division()
constant_operation = Constant((60+40j))
constant_operation_2 = Constant((10+20j))
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == (2.8-1.6j)
# SquareRoot tests.
def test_squareroot():
test_operation = SquareRoot()
constant_operation = Constant(36)
assert test_operation.evaluate(constant_operation.evaluate()) == 6
def test_squareroot_negative():
test_operation = SquareRoot()
constant_operation = Constant(-36)
assert test_operation.evaluate(constant_operation.evaluate()) == 6j
def test_squareroot_complex():
test_operation = SquareRoot()
constant_operation = Constant((48+64j))
assert test_operation.evaluate(constant_operation.evaluate()) == (8+4j)
# ComplexConjugate tests.
def test_complexconjugate():
test_operation = ComplexConjugate()
constant_operation = Constant(3+4j)
assert test_operation.evaluate(constant_operation.evaluate()) == (3-4j)
def test_test_complexconjugate_negative():
test_operation = ComplexConjugate()
constant_operation = Constant(-3-4j)
assert test_operation.evaluate(constant_operation.evaluate()) == (-3+4j)
# Max tests.
def test_max():
test_operation = Max()
constant_operation = Constant(30)
constant_operation_2 = Constant(5)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 30
def test_max_negative():
test_operation = Max()
constant_operation = Constant(-30)
constant_operation_2 = Constant(-5)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == -5
# Min tests.
def test_min():
test_operation = Min()
constant_operation = Constant(30)
constant_operation_2 = Constant(5)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == 5
def test_min_negative():
test_operation = Min()
constant_operation = Constant(-30)
constant_operation_2 = Constant(-5)
assert test_operation.evaluate(constant_operation.evaluate(), constant_operation_2.evaluate()) == -30
# Absolute tests.
def test_absolute():
test_operation = Absolute()
constant_operation = Constant(30)
assert test_operation.evaluate(constant_operation.evaluate()) == 30
def test_absolute_negative():
test_operation = Absolute()
constant_operation = Constant(-5)
assert test_operation.evaluate(constant_operation.evaluate()) == 5
def test_absolute_complex():
test_operation = Absolute()
constant_operation = Constant((3+4j))
assert test_operation.evaluate(constant_operation.evaluate()) == 5.0
# ConstantMultiplication tests.
def test_constantmultiplication():
test_operation = ConstantMultiplication(5)
constant_operation = Constant(20)
assert test_operation.evaluate(constant_operation.evaluate()) == 100
def test_constantmultiplication_negative():
test_operation = ConstantMultiplication(5)
constant_operation = Constant(-5)
assert test_operation.evaluate(constant_operation.evaluate()) == -25
def test_constantmultiplication_complex():
test_operation = ConstantMultiplication(3+2j)
constant_operation = Constant((3+4j))
assert test_operation.evaluate(constant_operation.evaluate()) == (1+18j)
# ConstantAddition tests.
def test_constantaddition():
test_operation = ConstantAddition(5)
constant_operation = Constant(20)
assert test_operation.evaluate(constant_operation.evaluate()) == 25
def test_constantaddition_negative():
test_operation = ConstantAddition(4)
constant_operation = Constant(-5)
assert test_operation.evaluate(constant_operation.evaluate()) == -1
def test_constantaddition_complex():
test_operation = ConstantAddition(3+2j)
constant_operation = Constant((3+4j))
assert test_operation.evaluate(constant_operation.evaluate()) == (6+6j)
# ConstantSubtraction tests.
def test_constantsubtraction():
test_operation = ConstantSubtraction(5)
constant_operation = Constant(20)
assert test_operation.evaluate(constant_operation.evaluate()) == 15
def test_constantsubtraction_negative():
test_operation = ConstantSubtraction(4)
constant_operation = Constant(-5)
assert test_operation.evaluate(constant_operation.evaluate()) == -9
def test_constantsubtraction_complex():
test_operation = ConstantSubtraction(4+6j)
constant_operation = Constant((3+4j))
assert test_operation.evaluate(constant_operation.evaluate()) == (-1-2j)
# ConstantDivision tests.
def test_constantdivision():
test_operation = ConstantDivision(5)
constant_operation = Constant(20)
assert test_operation.evaluate(constant_operation.evaluate()) == 4
def test_constantdivision_negative():
test_operation = ConstantDivision(4)
constant_operation = Constant(-20)
assert test_operation.evaluate(constant_operation.evaluate()) == -5
def test_constantdivision_complex():
test_operation = ConstantDivision(2+2j)
constant_operation = Constant((10+10j))
assert test_operation.evaluate(constant_operation.evaluate()) == (5+0j)
"""
B-ASIC test suite for graph id generator.
"""
from b_asic.graph_id import GraphIDGenerator, GraphID
import pytest
@pytest.fixture
def graph_id_generator():
return GraphIDGenerator()
class TestGetNextId:
def test_empty_string_generator(self, graph_id_generator):
"""Test the graph id generator for an empty string type."""
assert graph_id_generator.get_next_id("") == "1"
assert graph_id_generator.get_next_id("") == "2"
def test_normal_string_generator(self, graph_id_generator):
""""Test the graph id generator for a normal string type."""
assert graph_id_generator.get_next_id("add") == "add1"
assert graph_id_generator.get_next_id("add") == "add2"
def test_different_strings_generator(self, graph_id_generator):
"""Test the graph id generator for different strings."""
assert graph_id_generator.get_next_id("sub") == "sub1"
assert graph_id_generator.get_next_id("mul") == "mul1"
assert graph_id_generator.get_next_id("sub") == "sub2"
assert graph_id_generator.get_next_id("mul") == "mul2"
"""
B-ASIC test suite for Inputport
"""
import pytest
from b_asic import InputPort, OutputPort
from b_asic import Signal
@pytest.fixture
def inp_port():
return InputPort(0, None)
@pytest.fixture
def out_port():
return OutputPort(0, None)
@pytest.fixture
def out_port2():
return OutputPort(1, None)
@pytest.fixture
def dangling_sig():
return Signal()
@pytest.fixture
def s_w_source():
out_port = OutputPort(0, None)
return Signal(source=out_port)
@pytest.fixture
def sig_with_dest():
inp_port = InputPort(0, None)
return Signal(destination=out_port)
@pytest.fixture
def connected_sig():
out_port = OutputPort(0, None)
inp_port = InputPort(0, None)
return Signal(source=out_port, destination=inp_port)
def test_connect_then_disconnect(inp_port, out_port):
"""Test connect unused port to port."""
s1 = inp_port.connect(out_port)
assert inp_port.connected_ports == [out_port]
assert out_port.connected_ports == [inp_port]
assert inp_port.signals == [s1]
assert out_port.signals == [s1]
assert s1.source is out_port
assert s1.destination is inp_port
inp_port.remove_signal(s1)
assert inp_port.connected_ports == []
assert out_port.connected_ports == []
assert inp_port.signals == []
assert out_port.signals == [s1]
assert s1.source is out_port
assert s1.destination is None
def test_connect_used_port_to_new_port(inp_port, out_port, out_port2):
"""Does connecting multiple ports to an inputport throw error?"""
inp_port.connect(out_port)
with pytest.raises(AssertionError):
inp_port.connect(out_port2)
def test_add_signal_then_disconnect(inp_port, s_w_source):
"""Can signal be connected then disconnected properly?"""
inp_port.add_signal(s_w_source)
assert inp_port.connected_ports == [s_w_source.source]
assert s_w_source.source.connected_ports == [inp_port]
assert inp_port.signals == [s_w_source]
assert s_w_source.source.signals == [s_w_source]
assert s_w_source.destination is inp_port
inp_port.remove_signal(s_w_source)
assert inp_port.connected_ports == []
assert s_w_source.source.connected_ports == []
assert inp_port.signals == []
assert s_w_source.source.signals == [s_w_source]
assert s_w_source.destination is None
def test_connect_then_disconnect(inp_port, out_port):
"""Can port be connected and then disconnected properly?"""
inp_port.connect(out_port)
inp_port.disconnect(out_port)
print("outport signals:", out_port.signals, "count:", out_port.signal_count())
assert inp_port.signal_count() == 1
assert len(inp_port.connected_ports) == 0
assert out_port.signal_count() == 0
from b_asic.core_operations import Constant, Addition
from b_asic.signal import Signal
from b_asic.port import InputPort, OutputPort
import pytest
class TestTraverse:
def test_traverse_single_tree(self, operation):
"""Traverse a tree consisting of one operation."""
constant = Constant(None)
assert list(constant.traverse()) == [constant]
def test_traverse_tree(self, operation_tree):
"""Traverse a basic addition tree with two constants."""
assert len(list(operation_tree.traverse())) == 3
def test_traverse_large_tree(self, large_operation_tree):
"""Traverse a larger tree."""
assert len(list(large_operation_tree.traverse())) == 7
def test_traverse_type(self, large_operation_tree):
traverse = list(large_operation_tree.traverse())
assert len(list(filter(lambda type_: isinstance(type_, Addition), traverse))) == 3
assert len(list(filter(lambda type_: isinstance(type_, Constant), traverse))) == 4
def test_traverse_loop(self, operation_tree):
add_oper_signal = Signal()
operation_tree._output_ports[0].add_signal(add_oper_signal)
operation_tree._input_ports[0].remove_signal(add_oper_signal)
operation_tree._input_ports[0].add_signal(add_oper_signal)
assert len(list(operation_tree.traverse())) == 2
"""
B-ASIC test suite for OutputPort.
"""
from b_asic import OutputPort, InputPort, Signal
import pytest
@pytest.fixture
def output_port():
return OutputPort(0, None)
@pytest.fixture
def input_port():
return InputPort(0, None)
@pytest.fixture
def list_of_input_ports():
return [InputPort(_, None) for _ in range(0,3)]
class TestConnect:
def test_multiple_ports(self, output_port, list_of_input_ports):
"""Can multiple ports connect to an output port?"""
for port in list_of_input_ports:
output_port.connect(port)
assert output_port.signal_count() == len(list_of_input_ports)
def test_same_port(self, output_port, list_of_input_ports):
"""Check error handing."""
output_port.connect(list_of_input_ports[0])
with pytest.raises(AssertionError):
output_port.connect(list_of_input_ports[0])
assert output_port.signal_count() == 2
class TestAddSignal:
def test_dangling(self, output_port):
s = Signal()
output_port.add_signal(s)
assert output_port.signal_count() == 1
def test_with_destination(self, output_port, input_port):
s = Signal(destination=input_port)
output_port.add_signal(s)
assert output_port.connected_ports == [s.destination]
class TestDisconnect:
def test_multiple_ports(self, output_port, list_of_input_ports):
"""Can multiple ports disconnect from OutputPort?"""
for port in list_of_input_ports:
output_port.connect(port)
for port in list_of_input_ports:
output_port.disconnect(port)
assert output_port.signal_count() == 3
assert output_port.connected_ports == []
class TestRemoveSignal:
def test_one_signal(self, output_port, input_port):
s = output_port.connect(input_port)
output_port.remove_signal(s)
assert output_port.signal_count() == 0
assert output_port.signals == []
assert output_port.connected_ports == []
def test_multiple_signals(self, output_port, list_of_input_ports):
"""Can multiple signals disconnect from OutputPort?"""
sigs = []
for port in list_of_input_ports:
sigs.append(output_port.connect(port))
for sig in sigs:
output_port.remove_signal(sig)
assert output_port.signal_count() == 0
assert output_port.signals == []
"""
B-ASIC test suit for the signal module which consists of the Signal class.
"""
from b_asic.port import InputPort, OutputPort
from b_asic.signal import Signal
import pytest
def test_signal_creation_and_disconnction_and_connection_changing():
in_port = InputPort(0, None)
out_port = OutputPort(1, None)
s = Signal(out_port, in_port)
assert in_port.signals == [s]
assert out_port.signals == [s]
assert s.source is out_port
assert s.destination is in_port
in_port1 = InputPort(0, None)
s.set_destination(in_port1)
assert in_port.signals == []
assert in_port1.signals == [s]
assert out_port.signals == [s]
assert s.source is out_port
assert s.destination is in_port1
s.remove_source()
assert out_port.signals == []
assert in_port1.signals == [s]
assert s.source is None
assert s.destination is in_port1
s.remove_destination()
assert out_port.signals == []
assert in_port1.signals == []
assert s.source is None
assert s.destination is None
out_port1 = OutputPort(0, None)
s.set_source(out_port1)
assert out_port1.signals == [s]
assert s.source is out_port1
assert s.destination is None
s.set_source(out_port)
assert out_port.signals == [s]
assert out_port1.signals == []
assert s.source is out_port
assert s.destination is None
s.set_destination(in_port)
assert out_port.signals == [s]
assert in_port.signals == [s]
assert s.source is out_port
assert s.destination is in_port
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment