Skip to content

Commit

Permalink
Merge branch 'dev' into feature/pyxsi_integration
Browse files Browse the repository at this point in the history
  • Loading branch information
auphelia committed Feb 25, 2025
2 parents faa3d35 + cbf3636 commit 9566fb4
Show file tree
Hide file tree
Showing 19 changed files with 192 additions and 127 deletions.
1 change: 1 addition & 0 deletions docker/Dockerfile.finn
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ RUN pip install pytest-metadata==1.7.0
RUN pip install pytest-html==3.0.0
RUN pip install pytest-html-merger==0.0.8
RUN pip install pytest-cov==4.1.0
RUN pip install pyyaml==6.0.1

# extra dependencies from other FINN deps
# installed in Docker image to make entrypoint script go faster
Expand Down
2 changes: 1 addition & 1 deletion run-docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ SCRIPTPATH=$(dirname "$SCRIPT")
: ${PLATFORM_REPO_PATHS="/opt/xilinx/platforms"}
: ${XRT_DEB_VERSION="xrt_202220.2.14.354_22.04-amd64-xrt"}
: ${FINN_HOST_BUILD_DIR="/tmp/$DOCKER_INST_NAME"}
: ${FINN_DOCKER_TAG="xilinx/finn:$(git describe --always --tags --dirty).$XRT_DEB_VERSION"}
: ${FINN_DOCKER_TAG="xilinx/finn:$(OLD_PWD=$(pwd); cd $SCRIPTPATH; git describe --always --tags --dirty; cd $OLD_PWD).$XRT_DEB_VERSION"}
: ${FINN_DOCKER_PREBUILT="0"}
: ${FINN_DOCKER_RUN_AS_ROOT="0"}
: ${FINN_DOCKER_GPU="$(docker info | grep nvidia | wc -m)"}
Expand Down
39 changes: 13 additions & 26 deletions src/finn/custom_op/fpgadataflow/hls/lookup_hls.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import numpy as np
import os
import warnings
from math import ceil, log2
from qonnx.core.datatype import DataType

Expand Down Expand Up @@ -87,31 +88,6 @@ def defines(self, var):
my_defines.append("#define EmbeddingType %s" % emb_hls_type)
self.code_gen_dict["$DEFINES$"] = my_defines

def read_npy_data(self):
code_gen_dir = self.get_nodeattr("code_gen_dir_cppsim")
dtype = self.get_input_datatype()
if dtype == DataType["BIPOLAR"]:
# use binary for bipolar storage
dtype = DataType["BINARY"]
elem_bits = dtype.bitwidth()
packed_bits = self.get_instream_width()
packed_hls_type = "ap_uint<%d>" % packed_bits
elem_hls_type = dtype.get_hls_datatype_str()
npy_type = "int64_t"
npy_in = "%s/input_0.npy" % code_gen_dir
self.code_gen_dict["$READNPYDATA$"] = []
self.code_gen_dict["$READNPYDATA$"].append(
'npy2apintstream<%s, %s, %d, %s>("%s", in0_%s);'
% (
packed_hls_type,
elem_hls_type,
elem_bits,
npy_type,
npy_in,
self.hls_sname(),
)
)

def dataoutstrm(self):
code_gen_dir = self.get_nodeattr("code_gen_dir_cppsim")
dtype = self.get_output_datatype()
Expand Down Expand Up @@ -273,7 +249,18 @@ def execute_node(self, context, graph):
)

inp = context[node.input[0]]
assert inp.dtype == np.int64, "Inputs must be contained in int64 ndarray"

# Make sure the input has the right container datatype
if inp.dtype is not np.float32:
# Issue a warning to make the user aware of this type-cast
warnings.warn(
f"{node.name}: Changing input container datatype from "
f"{inp.dtype} to {np.float32}"
)
# Convert the input to floating point representation as the
# container datatype
inp = inp.astype(np.float32)

assert inp.shape == exp_ishape, """Input shape doesn't match expected shape."""
export_idt = self.get_input_datatype()
odt = self.get_output_datatype()
Expand Down
16 changes: 12 additions & 4 deletions src/finn/custom_op/fpgadataflow/rtl/streamingfifo_rtl.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,18 @@ def execute_node(self, context, graph):
elif mode == "rtlsim":
code_gen_dir = self.get_nodeattr("code_gen_dir_ipgen")
# create a npy file for the input of the node
assert (
str(inp.dtype) == "float32"
), """Input datatype is
not float32 as expected."""

# Make sure the input has the right container datatype
if inp.dtype is not np.float32:
# Issue a warning to make the user aware of this type-cast
warnings.warn(
f"{node.name}: Changing input container datatype from "
f"{inp.dtype} to {np.float32}"
)
# Convert the input to floating point representation as the
# container datatype
inp = inp.astype(np.float32)

expected_inp_shape = self.get_folded_input_shape()
reshaped_input = inp.reshape(expected_inp_shape)
if DataType[self.get_nodeattr("dataType")] == DataType["BIPOLAR"]:
Expand Down
8 changes: 3 additions & 5 deletions tests/brevitas/test_brevitas_avg_pool_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@

import finn.core.onnx_exec as oxe
from finn.transformation.qonnx.convert_qonnx_to_finn import ConvertQONNXtoFINN

base_export_onnx_path = "test_brevitas_avg_pool_export.onnx"
from finn.util.basic import make_build_dir


@pytest.mark.brevitas_export
Expand All @@ -62,7 +61,8 @@ def test_brevitas_avg_pool_export(
channels,
idim,
):
export_onnx_path = base_export_onnx_path.replace(".onnx", "test_QONNX.onnx")
build_dir = make_build_dir(prefix="test_brevitas_avg_pool_export")
export_onnx_path = os.path.join(build_dir, "test.onnx")
if signed:
quant_node = QuantIdentity(
bit_width=input_bit_width,
Expand Down Expand Up @@ -112,5 +112,3 @@ def test_brevitas_avg_pool_export(
finn_output = odict[model.graph.output[0].name]
# compare outputs
assert np.isclose(ref_output_array, finn_output).all()
# cleanup
os.remove(export_onnx_path)
6 changes: 3 additions & 3 deletions tests/brevitas/test_brevitas_cnv.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,18 @@

import finn.core.onnx_exec as oxe
from finn.transformation.qonnx.convert_qonnx_to_finn import ConvertQONNXtoFINN
from finn.util.basic import make_build_dir
from finn.util.test import get_test_model_trained

export_onnx_path = "test_brevitas_cnv.onnx"


@pytest.mark.brevitas_export
@pytest.mark.parametrize("abits", [1, 2])
@pytest.mark.parametrize("wbits", [1, 2])
def test_brevitas_cnv_export_exec(wbits, abits):
if wbits > abits:
pytest.skip("No wbits > abits cases at the moment")
build_dir = make_build_dir("test_brevitas_cnv_export_exec")
export_onnx_path = os.path.join(build_dir, "test_brevitas_cnv.onnx")
cnv = get_test_model_trained("CNV", wbits, abits)
ishape = (1, 3, 32, 32)
export_qonnx(cnv, torch.randn(ishape), export_onnx_path)
Expand All @@ -78,4 +79,3 @@ def test_brevitas_cnv_export_exec(wbits, abits):
expected = cnv.forward(input_tensor).detach().numpy()
assert np.isclose(produced, expected, atol=1e-3).all()
assert np.argmax(produced) == 3
os.remove(export_onnx_path)
5 changes: 3 additions & 2 deletions tests/brevitas/test_brevitas_debug.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@

import finn.core.onnx_exec as oxe
from finn.transformation.qonnx.convert_qonnx_to_finn import ConvertQONNXtoFINN
from finn.util.basic import make_build_dir
from finn.util.test import get_test_model_trained


@pytest.mark.brevitas_export
@pytest.mark.parametrize("QONNX_FINN_conversion", [False, True])
def test_brevitas_debug(QONNX_FINN_conversion):
finn_onnx = "test_brevitas_debug.onnx"
build_dir = make_build_dir("test_brevitas_debug")
finn_onnx = os.path.join(build_dir, "test_brevitas_debug.onnx")
fc = get_test_model_trained("TFC", 2, 2)
ishape = (1, 1, 28, 28)
dbg_hook = bo.enable_debug(fc, proxy_level=True)
Expand Down Expand Up @@ -94,4 +96,3 @@ def test_brevitas_debug(QONNX_FINN_conversion):
tensor_pytorch = _unpack_quant_tensor(dbg_hook.values[dbg_name]).detach().numpy()
tensor_finn = output_dict[dbg_name]
assert np.isclose(tensor_finn, tensor_pytorch, atol=1e-5).all()
os.remove(finn_onnx)
6 changes: 3 additions & 3 deletions tests/brevitas/test_brevitas_deconv.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@

import finn.core.onnx_exec as oxe
from finn.transformation.qonnx.convert_qonnx_to_finn import ConvertQONNXtoFINN

export_path = "test_brevitas_deconv.onnx"
from finn.util.basic import make_build_dir


@pytest.mark.brevitas_export
Expand All @@ -66,6 +65,8 @@ def test_brevitas_QTransposeConv(ifm_ch, ofm_ch, mh, mw, padding, stride, kw, bi
padding=padding,
bias=bias,
)
build_dir = make_build_dir("test_brevitas_QTransposeConv")
export_path = os.path.join(build_dir, "test_brevitas_deconv.onnx")
# outp = el(inp) # expects NCHW data format
export_qonnx(b_deconv, input_t=inp, export_path=export_path, opset_version=11)
qonnx_cleanup(export_path, out_file=export_path)
Expand All @@ -79,4 +80,3 @@ def test_brevitas_QTransposeConv(ifm_ch, ofm_ch, mh, mw, padding, stride, kw, bi
inp_tensor = torch.from_numpy(inp_tensor).float()
expected = b_deconv.forward(inp_tensor).detach().numpy()
assert np.isclose(produced, expected, atol=1e-3).all()
os.remove(export_path)
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@

import finn.core.onnx_exec as oxe
from finn.transformation.qonnx.convert_qonnx_to_finn import ConvertQONNXtoFINN

export_onnx_path = "test_brevitas_non_scaled_QuantHardTanh_export.onnx"
from finn.util.basic import make_build_dir


@pytest.mark.brevitas_export
Expand Down Expand Up @@ -72,7 +71,8 @@ def get_quant_type(bit_width):
scaling_impl_type=ScalingImplType.CONST,
narrow_range=narrow_range,
)
m_path = export_onnx_path
build_dir = make_build_dir(prefix="test_brevitas_act_export_qhardtanh_nonscaled")
m_path = os.path.join(build_dir, "test_brevitas_non_scaled_QuantHardTanh_export.onnx")
export_qonnx(b_act, torch.randn(ishape), m_path)
qonnx_cleanup(m_path, out_file=m_path)
model = ModelWrapper(m_path)
Expand All @@ -85,4 +85,3 @@ def get_quant_type(bit_width):
inp_tensor = torch.from_numpy(inp_tensor).float()
expected = b_act.forward(inp_tensor).detach().numpy()
assert np.isclose(produced, expected, atol=1e-3).all()
os.remove(export_onnx_path)
7 changes: 3 additions & 4 deletions tests/brevitas/test_brevitas_qconv2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@

import finn.core.onnx_exec as oxe
from finn.transformation.qonnx.convert_qonnx_to_finn import ConvertQONNXtoFINN

export_onnx_path = "test_brevitas_conv.onnx"
from finn.util.basic import make_build_dir


@pytest.mark.brevitas_export
Expand Down Expand Up @@ -92,7 +91,8 @@ def test_brevitas_QConv2d(dw, bias, in_channels):
weight_tensor = gen_finn_dt_tensor(DataType["INT4"], w_shape)
b_conv.weight = torch.nn.Parameter(torch.from_numpy(weight_tensor).float())
b_conv.eval()
m_path = export_onnx_path
build_dir = make_build_dir(prefix="test_brevitas_QConv2d")
m_path = os.path.join(build_dir, "test_brevitas_conv.onnx")
export_qonnx(b_conv, torch.randn(ishape), m_path)
qonnx_cleanup(m_path, out_file=m_path)
model = ModelWrapper(m_path)
Expand All @@ -106,4 +106,3 @@ def test_brevitas_QConv2d(dw, bias, in_channels):
expected = b_conv.forward(inp_tensor).detach().numpy()

assert np.isclose(produced, expected, atol=1e-3).all()
os.remove(export_onnx_path)
7 changes: 3 additions & 4 deletions tests/brevitas/test_brevitas_qlinear.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@

import finn.core.onnx_exec as oxe
from finn.transformation.qonnx.convert_qonnx_to_finn import ConvertQONNXtoFINN

export_onnx_path = "test_brevitas_qlinear.onnx"
from finn.util.basic import make_build_dir


@pytest.mark.brevitas_export
Expand All @@ -67,7 +66,8 @@ def test_brevitas_qlinear(bias, out_features, in_features, w_bits, i_dtype):
weight_tensor_fp = np.random.uniform(low=-1.0, high=1.0, size=w_shape).astype(np.float32)
b_linear.weight.data = torch.from_numpy(weight_tensor_fp)
b_linear.eval()
m_path = export_onnx_path
build_dir = make_build_dir(prefix="test_brevitas_qlinear")
m_path = os.path.join(build_dir, "test_brevitas_qlinear.onnx")
export_qonnx(b_linear, torch.randn(i_shape), m_path)
qonnx_cleanup(m_path, out_file=m_path)
model = ModelWrapper(m_path)
Expand All @@ -81,4 +81,3 @@ def test_brevitas_qlinear(bias, out_features, in_features, w_bits, i_dtype):
expected = b_linear.forward(inp_tensor).detach().numpy()

assert np.isclose(produced, expected, atol=1e-3).all()
os.remove(export_onnx_path)
11 changes: 5 additions & 6 deletions tests/brevitas/test_brevitas_relu_act_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@

import finn.core.onnx_exec as oxe
from finn.transformation.qonnx.convert_qonnx_to_finn import ConvertQONNXtoFINN

export_onnx_path = "test_brevitas_relu_act_export.onnx"
from finn.util.basic import make_build_dir


@pytest.mark.brevitas_export
Expand All @@ -55,7 +54,8 @@ def test_brevitas_act_export_relu(
b_act = QuantReLU(
bit_width=abits,
)
m_path = export_onnx_path
build_dir = make_build_dir(prefix="test_brevitas_act_export_relu")
m_path = os.path.join(build_dir, "test_brevitas_relu_act_export.onnx")
export_qonnx(b_act, torch.randn(ishape), m_path)
qonnx_cleanup(m_path, out_file=m_path)
model = ModelWrapper(m_path)
Expand All @@ -70,7 +70,6 @@ def test_brevitas_act_export_relu(
expected = b_act.forward(inp_tensor).detach().numpy()

assert np.isclose(produced, expected, atol=1e-3).all()
os.remove(export_onnx_path)


@pytest.mark.brevitas_export
Expand All @@ -88,7 +87,8 @@ def test_brevitas_act_export_relu_channel(
scaling_per_output_channel=True,
per_channel_broadcastable_shape=(1, ch, 1, 1),
)
m_path = export_onnx_path
build_dir = make_build_dir(prefix="test_brevitas_act_export_relu_channel")
m_path = os.path.join(build_dir, "test_brevitas_relu_act_export.onnx")
export_qonnx(b_act, torch.randn(ishape), m_path)
qonnx_cleanup(m_path, out_file=m_path)
model = ModelWrapper(m_path)
Expand All @@ -103,4 +103,3 @@ def test_brevitas_act_export_relu_channel(
expected = b_act.forward(inp_tensor).detach().numpy()

assert np.isclose(produced, expected, atol=1e-3).all()
os.remove(export_onnx_path)
7 changes: 3 additions & 4 deletions tests/brevitas/test_brevitas_scaled_qhardtanh_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@

import finn.core.onnx_exec as oxe
from finn.transformation.qonnx.convert_qonnx_to_finn import ConvertQONNXtoFINN

export_onnx_path = "test_brevitas_scaled_QHardTanh_export.onnx"
from finn.util.basic import make_build_dir


@pytest.mark.brevitas_export
Expand Down Expand Up @@ -85,7 +84,8 @@ def get_quant_type(bit_width):
)
}
b_act.load_state_dict(checkpoint)
m_path = export_onnx_path
build_dir = make_build_dir(prefix="test_brevitas_act_export_qhardtanh_scaled")
m_path = os.path.join(build_dir, "test_brevitas_scaled_QHardTanh_export.onnx")
export_qonnx(b_act, torch.randn(ishape), m_path)
qonnx_cleanup(m_path, out_file=m_path)
model = ModelWrapper(m_path)
Expand Down Expand Up @@ -121,4 +121,3 @@ def get_quant_type(bit_width):
print("expec:", ", ".join(["{:8.4f}".format(x) for x in expected[0]]))

assert np.isclose(produced, expected, atol=1e-3).all()
os.remove(export_onnx_path)
5 changes: 3 additions & 2 deletions tests/brevitas/test_brevitas_selu_act_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,16 @@

import finn.core.onnx_exec as oxe
from finn.transformation.qonnx.convert_qonnx_to_finn import ConvertQONNXtoFINN
from finn.util.basic import make_build_dir


@pytest.mark.brevitas_export
@pytest.mark.parametrize("abits", [2, 4, 8])
@pytest.mark.parametrize("ishape", [(1, 15), (1, 32, 1, 1)])
@pytest.mark.parametrize("narrow", [True, False])
def test_brevitas_act_export_selu(abits, ishape, narrow):
export_path = "test_brevitas_selu_act_export_%s.onnx" % str(abits)
build_dir = make_build_dir(prefix="test_brevitas_act_export_selu")
export_path = os.path.join(build_dir, "test_brevitas_selu_act_export_%s.onnx" % str(abits))
b_act = torch.nn.Sequential(torch.nn.SELU(), QuantIdentity(bit_width=abits, narrow=narrow))

export_qonnx(
Expand All @@ -69,4 +71,3 @@ def test_brevitas_act_export_selu(abits, ishape, narrow):
expected = b_act.forward(inp_tensor).detach().numpy()

assert np.isclose(produced, expected, atol=1e-3).all()
os.remove(export_path)
Loading

0 comments on commit 9566fb4

Please sign in to comment.