Skip to content

Commit

Permalink
Merge branch 'main' into update_jenkins
Browse files Browse the repository at this point in the history
  • Loading branch information
JanFSchulte authored Oct 2, 2024
2 parents d30773f + d439f26 commit 15abf5b
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 139 deletions.
27 changes: 15 additions & 12 deletions hls4ml/backends/fpga/fpga_backend.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import math
import os
import re
import subprocess
from bisect import bisect_left
from collections.abc import Iterable

Expand Down Expand Up @@ -131,19 +131,22 @@ def compile(self, model):
Returns:
string: Returns the name of the compiled library.
"""
curr_dir = os.getcwd()
os.chdir(model.config.get_output_dir())

lib_name = None
try:
ret_val = os.system('bash build_lib.sh')
if ret_val != 0:
raise Exception(f'Failed to compile project "{model.config.get_project_name()}"')
lib_name = '{}/firmware/{}-{}.so'.format(
model.config.get_output_dir(), model.config.get_project_name(), model.config.get_config_value('Stamp')
)
finally:
os.chdir(curr_dir)
ret_val = subprocess.run(
['./build_lib.sh'],
shell=True,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
cwd=model.config.get_output_dir(),
)
if ret_val.returncode != 0:
print(ret_val.stdout)
raise Exception(f'Failed to compile project "{model.config.get_project_name()}"')
lib_name = '{}/firmware/{}-{}.so'.format(
model.config.get_output_dir(), model.config.get_project_name(), model.config.get_config_value('Stamp')
)

return lib_name

Expand Down
1 change: 1 addition & 0 deletions hls4ml/templates/quartus/build_lib.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash
set -e

CC=g++
if [[ "$OSTYPE" == "linux-gnu" ]]; then
Expand Down
6 changes: 4 additions & 2 deletions hls4ml/templates/vivado/build_lib.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash
set -e

CC=g++
if [[ "$OSTYPE" == "linux-gnu" ]]; then
Expand All @@ -10,8 +11,9 @@ LDFLAGS=
INCFLAGS="-Ifirmware/ap_types/"
PROJECT=myproject
LIB_STAMP=mystamp
WEIGHTS_DIR="\"weights\""

${CC} ${CFLAGS} ${INCFLAGS} -c firmware/${PROJECT}.cpp -o ${PROJECT}.o
${CC} ${CFLAGS} ${INCFLAGS} -c ${PROJECT}_bridge.cpp -o ${PROJECT}_bridge.o
${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR=${WEIGHTS_DIR} -c firmware/${PROJECT}.cpp -o ${PROJECT}.o
${CC} ${CFLAGS} ${INCFLAGS} -D WEIGHTS_DIR=${WEIGHTS_DIR} -c ${PROJECT}_bridge.cpp -o ${PROJECT}_bridge.o
${CC} ${CFLAGS} ${INCFLAGS} -shared ${PROJECT}.o ${PROJECT}_bridge.o -o firmware/${PROJECT}-${LIB_STAMP}.so
rm -f *.o
85 changes: 41 additions & 44 deletions hls4ml/writer/catapult_writer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import glob
import os
import stat
import tarfile
from collections import OrderedDict
from pathlib import Path
from shutil import copyfile, copytree, rmtree

import numpy as np
Expand Down Expand Up @@ -749,55 +751,50 @@ def write_build_script(self, model):
model (ModelGraph): the hls4ml model.
"""

filedir = os.path.dirname(os.path.abspath(__file__))
filedir = Path(__file__).parent

# build_prj.tcl
srcpath = os.path.join(filedir, '../templates/catapult/build_prj.tcl')
dstpath = f'{model.config.get_output_dir()}/build_prj.tcl'
# copyfile(srcpath, dstpath)
f = open(srcpath)
fout = open(dstpath, 'w')
for line in f.readlines():
indent = line[: len(line) - len(line.lstrip())]
line = line.replace('myproject', model.config.get_project_name())
line = line.replace('CATAPULT_DIR', model.config.get_project_dir())
if '#hls-fpga-machine-learning insert techlibs' in line:
if model.config.get_config_value('Technology') is None:
if model.config.get_config_value('Part') is not None:
line = indent + 'setup_xilinx_part {{{}}}\n'.format(model.config.get_config_value('Part'))
elif model.config.get_config_value('ASICLibs') is not None:
line = indent + 'setup_asic_libs {{{}}}\n'.format(model.config.get_config_value('ASICLibs'))
else:
if model.config.get_config_value('Technology') == 'asic':
line = indent + 'setup_asic_libs {{{}}}\n'.format(model.config.get_config_value('ASICLibs'))
srcpath = (filedir / '../templates/catapult/build_prj.tcl').resolve()
dstpath = Path(f'{model.config.get_output_dir()}/build_prj.tcl').resolve()
with open(srcpath) as src, open(dstpath, 'w') as dst:
for line in src.readlines():
indent = line[: len(line) - len(line.lstrip())]
line = line.replace('myproject', model.config.get_project_name())
line = line.replace('CATAPULT_DIR', model.config.get_project_dir())
if '#hls-fpga-machine-learning insert techlibs' in line:
if model.config.get_config_value('Technology') is None:
if model.config.get_config_value('Part') is not None:
line = indent + 'setup_xilinx_part {{{}}}\n'.format(model.config.get_config_value('Part'))
elif model.config.get_config_value('ASICLibs') is not None:
line = indent + 'setup_asic_libs {{{}}}\n'.format(model.config.get_config_value('ASICLibs'))
else:
line = indent + 'setup_xilinx_part {{{}}}\n'.format(model.config.get_config_value('Part'))
elif '#hls-fpga-machine-learning insert invoke_args' in line:
tb_in_file = model.config.get_config_value('InputData')
tb_out_file = model.config.get_config_value('OutputPredictions')
invoke_args = '$sfd/firmware/weights'
if tb_in_file is not None:
invoke_args = invoke_args + f' $sfd/tb_data/{tb_in_file}'
if tb_out_file is not None:
invoke_args = invoke_args + f' $sfd/tb_data/{tb_out_file}'
line = indent + f'flow package option set /SCVerify/INVOKE_ARGS "{invoke_args}"\n'
elif 'set hls_clock_period 5' in line:
line = indent + 'set hls_clock_period {}\n'.format(model.config.get_config_value('ClockPeriod'))
fout.write(line)
f.close()
fout.close()
if model.config.get_config_value('Technology') == 'asic':
line = indent + 'setup_asic_libs {{{}}}\n'.format(model.config.get_config_value('ASICLibs'))
else:
line = indent + 'setup_xilinx_part {{{}}}\n'.format(model.config.get_config_value('Part'))
elif '#hls-fpga-machine-learning insert invoke_args' in line:
tb_in_file = model.config.get_config_value('InputData')
tb_out_file = model.config.get_config_value('OutputPredictions')
invoke_args = '$sfd/firmware/weights'
if tb_in_file is not None:
invoke_args = invoke_args + f' $sfd/tb_data/{tb_in_file}'
if tb_out_file is not None:
invoke_args = invoke_args + f' $sfd/tb_data/{tb_out_file}'
line = indent + f'flow package option set /SCVerify/INVOKE_ARGS "{invoke_args}"\n'
elif 'set hls_clock_period 5' in line:
line = indent + 'set hls_clock_period {}\n'.format(model.config.get_config_value('ClockPeriod'))
dst.write(line)

# build_lib.sh
f = open(os.path.join(filedir, '../templates/catapult/build_lib.sh'))
fout = open(f'{model.config.get_output_dir()}/build_lib.sh', 'w')

for line in f.readlines():
line = line.replace('myproject', model.config.get_project_name())
line = line.replace('mystamp', model.config.get_config_value('Stamp'))

fout.write(line)
f.close()
fout.close()
build_lib_src = (filedir / '../templates/catapult/build_lib.sh').resolve()
build_lib_dst = Path(f'{model.config.get_output_dir()}/build_lib.sh').resolve()
with open(build_lib_src) as src, open(build_lib_dst, 'w') as dst:
for line in src.readlines():
line = line.replace('myproject', model.config.get_project_name())
line = line.replace('mystamp', model.config.get_config_value('Stamp'))

dst.write(line)
build_lib_dst.chmod(build_lib_dst.stat().st_mode | stat.S_IEXEC)

def write_nnet_utils(self, model):
"""Copy the nnet_utils, AP types headers and any custom source to the project output directory
Expand Down
42 changes: 21 additions & 21 deletions hls4ml/writer/quartus_writer.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import glob
import os
import stat
import tarfile
from collections import OrderedDict
from pathlib import Path
from shutil import copyfile, copytree, rmtree

import numpy as np
Expand Down Expand Up @@ -877,32 +879,30 @@ def write_build_script(self, model):
model (ModelGraph): the hls4ml model.
"""

# Makefile
filedir = os.path.dirname(os.path.abspath(__file__))
f = open(os.path.join(filedir, '../templates/quartus/Makefile'))
fout = open(f'{model.config.get_output_dir()}/Makefile', 'w')
filedir = Path(__file__).parent

for line in f.readlines():
line = line.replace('myproject', model.config.get_project_name())
# Makefile
makefile_src = (filedir / '../templates/quartus/Makefile').resolve()
makefile_dst = Path(f'{model.config.get_output_dir()}/Makefile').resolve()
with open(makefile_src) as src, open(makefile_dst, 'w') as dst:
for line in src.readlines():
line = line.replace('myproject', model.config.get_project_name())

if 'DEVICE :=' in line:
line = 'DEVICE := {}\n'.format(model.config.get_config_value('Part'))
if 'DEVICE :=' in line:
line = 'DEVICE := {}\n'.format(model.config.get_config_value('Part'))

fout.write(line)
f.close()
fout.close()
dst.write(line)

# build_lib.sh
f = open(os.path.join(filedir, '../templates/quartus/build_lib.sh'))
fout = open(f'{model.config.get_output_dir()}/build_lib.sh', 'w')

for line in f.readlines():
line = line.replace('myproject', model.config.get_project_name())
line = line.replace('mystamp', model.config.get_config_value('Stamp'))

fout.write(line)
f.close()
fout.close()
build_lib_src = (filedir / '../templates/quartus/build_lib.sh').resolve()
build_lib_dst = Path(f'{model.config.get_output_dir()}/build_lib.sh').resolve()
with open(build_lib_src) as src, open(build_lib_dst, 'w') as dst:
for line in src.readlines():
line = line.replace('myproject', model.config.get_project_name())
line = line.replace('mystamp', model.config.get_config_value('Stamp'))

dst.write(line)
build_lib_dst.chmod(build_lib_dst.stat().st_mode | stat.S_IEXEC)

def write_nnet_utils(self, model):
"""Copy the nnet_utils, AP types headers and any custom source to the project output directory
Expand Down
67 changes: 34 additions & 33 deletions hls4ml/writer/symbolic_writer.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import glob
import os
import stat
from pathlib import Path
from shutil import copyfile, copytree, rmtree

from hls4ml.backends import get_backend
Expand Down Expand Up @@ -56,49 +58,48 @@ def write_build_script(self, model):
model (ModelGraph): the hls4ml model.
"""

filedir = os.path.dirname(os.path.abspath(__file__))

# build_prj.tcl
f = open(f'{model.config.get_output_dir()}/project.tcl', 'w')
f.write('variable project_name\n')
f.write(f'set project_name "{model.config.get_project_name()}"\n')
f.write('variable backend\n')
f.write('set backend "vivado"\n')
f.write('variable part\n')
f.write('set part "{}"\n'.format(model.config.get_config_value('Part')))
f.write('variable clock_period\n')
f.write('set clock_period {}\n'.format(model.config.get_config_value('ClockPeriod')))
f.write('variable clock_uncertainty\n')
f.write('set clock_uncertainty {}\n'.format(model.config.get_config_value('ClockUncertainty', '0%')))
f.write('variable version\n')
f.write('set version "{}"\n'.format(model.config.get_config_value('Version', '1.0.0')))
f.close()
filedir = Path(__file__).parent

# project.tcl
prj_tcl_dst = Path(f'{model.config.get_output_dir()}/project.tcl')
with open(prj_tcl_dst, 'w') as f:
f.write('variable project_name\n')
f.write(f'set project_name "{model.config.get_project_name()}"\n')
f.write('variable backend\n')
f.write('set backend "vivado"\n')
f.write('variable part\n')
f.write('set part "{}"\n'.format(model.config.get_config_value('Part')))
f.write('variable clock_period\n')
f.write('set clock_period {}\n'.format(model.config.get_config_value('ClockPeriod')))
f.write('variable clock_uncertainty\n')
f.write('set clock_uncertainty {}\n'.format(model.config.get_config_value('ClockUncertainty', '0%')))
f.write('variable version\n')
f.write('set version "{}"\n'.format(model.config.get_config_value('Version', '1.0.0')))

# build_prj.tcl
srcpath = os.path.join(filedir, '../templates/vivado/build_prj.tcl')
srcpath = (filedir / '../templates/vivado/build_prj.tcl').resolve()
dstpath = f'{model.config.get_output_dir()}/build_prj.tcl'
copyfile(srcpath, dstpath)

# vivado_synth.tcl
srcpath = os.path.join(filedir, '../templates/vivado/vivado_synth.tcl')
srcpath = (filedir / '../templates/vivado/vivado_synth.tcl').resolve()
dstpath = f'{model.config.get_output_dir()}/vivado_synth.tcl'
copyfile(srcpath, dstpath)

# build_lib.sh
f = open(os.path.join(filedir, '../templates/symbolic/build_lib.sh'))
fout = open(f'{model.config.get_output_dir()}/build_lib.sh', 'w')

for line in f.readlines():
line = line.replace('myproject', model.config.get_project_name())
line = line.replace('mystamp', model.config.get_config_value('Stamp'))
line = line.replace('mylibspath', model.config.get_config_value('HLSLibsPath'))

if 'LDFLAGS=' in line and not os.path.exists(model.config.get_config_value('HLSLibsPath')):
line = 'LDFLAGS=\n'

fout.write(line)
f.close()
fout.close()
build_lib_src = (filedir / '../templates/symbolic/build_lib.sh').resolve()
build_lib_dst = Path(f'{model.config.get_output_dir()}/build_lib.sh').resolve()
with open(build_lib_src) as src, open(build_lib_dst, 'w') as dst:
for line in src.readlines():
line = line.replace('myproject', model.config.get_project_name())
line = line.replace('mystamp', model.config.get_config_value('Stamp'))
line = line.replace('mylibspath', model.config.get_config_value('HLSLibsPath'))

if 'LDFLAGS=' in line and not os.path.exists(model.config.get_config_value('HLSLibsPath')):
line = 'LDFLAGS=\n'

dst.write(line)
build_lib_dst.chmod(build_lib_dst.stat().st_mode | stat.S_IEXEC)

def write_hls(self, model):
print('Writing HLS project')
Expand Down
Loading

0 comments on commit 15abf5b

Please sign in to comment.