Skip to content
Snippets Groups Projects
Commit ebdfdedd authored by auphelia's avatar auphelia
Browse files

[Code gen] Added missing commands to hlslib node files

parent 945e1bd2
No related branches found
No related tags found
No related merge requests found
import os
import subprocess
import numpy as np
import tempfile as tmp
import numpy as np
import finn.core.utils as utils
from finn.backend.fpgadataflow.utils import numpy_to_hls_code
from finn.core.datatype import DataType
......@@ -22,11 +23,22 @@ class StreamingFCLayer_Batch(HLSCustomOp):
pass
def execute_node(self, node, context, graph):
# make temporary directory for generated files
self.tmp_dir = tmp.mkdtemp(prefix=str(node.op_type) + "_")
# create empty list for temporary files to enable the option
# to delete the files after the execution
temp_files = []
# get attributes for correct packing of weights and thresholds
self.get_attributes(node)
# create a npy file fore each input of the node (in_ind is input index)
in_ind = 0
temp_files = []
for inputs in node.input:
# it is assumed that the first input of the node is the data input
# the second input are the weights
# the third input are the thresholds
if in_ind == 0:
np.save(
os.path.join(self.tmp_dir, "input_{}.npy".format(in_ind)),
......@@ -36,12 +48,15 @@ class StreamingFCLayer_Batch(HLSCustomOp):
elif in_ind == 1:
weights = context[inputs]
self.WMEM = weights.shape[2]
# transpose and expand the weights to get the right shape
# for the code generation
weights = np.transpose(weights, (1, 2, 0))
weights = np.expand_dims(weights, 0)
weights = numpy_to_hls_code(
weights, DataType.BINARY, "weights", True, True
)
# write weights into params.h
f_weights = open("{}/params.h".format(self.tmp_dir), "w")
f_weights.write(
"static BinaryWeights<{},{},{}> weights = ".format(
......@@ -55,11 +70,15 @@ class StreamingFCLayer_Batch(HLSCustomOp):
else:
thresholds = context[inputs]
self.TMEM = thresholds.shape[0]
# transpose and expand the thresholds to get the right shape
# for the code generation
thresholds = np.transpose(thresholds, (1, 0, 2))
thresholds = np.expand_dims(thresholds, 0)
thresholds = numpy_to_hls_code(
thresholds, DataType.BINARY, "thresholds", True, True
)
# write weights into thresh.h
f_thresh = open("{}/thresh.h".format(self.tmp_dir), "w")
f_thresh.write(
"""static ThresholdsActivation<{},{},1,ap_uint<16>,
......@@ -73,7 +92,10 @@ class StreamingFCLayer_Batch(HLSCustomOp):
in_ind += 1
# code generation
self.code_generation(node)
# c++ compilation and execution flow
temp_files.append("{}/execute_{}.cpp".format(self.tmp_dir, node.op_type))
bash_compile = """g++ -o {}/execute_{} {}/execute_{}.cpp
/workspace/cnpy/cnpy.cpp -I/workspace/cnpy/
......@@ -88,6 +110,8 @@ class StreamingFCLayer_Batch(HLSCustomOp):
process_execute.communicate()
temp_files.append("{}/execute_{}".format(self.tmp_dir, node.op_type))
temp_files.append("{}/output.npy".format(self.tmp_dir))
# load output npy file
output = np.load("{}/output.npy".format(self.tmp_dir))
context[node.output[0]] = output
# deleting temporary files
......@@ -121,6 +145,8 @@ class StreamingFCLayer_Batch(HLSCustomOp):
]
def read_npy_data(self, node):
# c++ code to read out an npy file
# and put it in hls::stream in the correct order
self.code_gen_dict["$READNPYDATA$"] = []
self.code_gen_dict["$READNPYDATA$"].append(
"""cnpy::NpyArray arr0 = cnpy::npy_load("{}/input_0.npy");\n
......
import os
import numpy as np
import subprocess
import tempfile as tmp
import numpy as np
from finn.core.utils import get_by_name
from finn.custom_op.fpgadataflow import HLSCustomOp
......@@ -16,22 +16,34 @@ class StreamingMaxPool(HLSCustomOp):
pass
def execute_node(self, node, context, graph):
# make temporary directory for generated files
self.tmp_dir = tmp.mkdtemp(prefix=str(node.op_type) + "_")
in_ind = 0
# create empty list for temporary files to enable the option
# to delete the files after the execution
temp_files = []
# create a npy file fore each input of the node (in_ind is input index)
in_ind = 0
for inputs in node.input:
np.save(os.path.join(self.tmp_dir, "input_{}.npy".format(in_ind)),
context[inputs],)
np.save(
os.path.join(self.tmp_dir, "input_{}.npy".format(in_ind)),
context[inputs],
)
temp_files.append("{}/input_{}.npy".format(self.tmp_dir, in_ind))
in_ind += 1
# code generation
self.code_generation(node)
# c++ compilation and execution flow
temp_files.append("{}/execute_{}.cpp".format(self.tmp_dir, node.op_type))
bash_compile = """g++ -o {}/execute_{} {}/execute_{}.cpp
/workspace/cnpy/cnpy.cpp -I/workspace/cnpy/
-I/workspace/finn-hlslib -I/workspace/vivado-hlslib
--std=c++11 -lz""".format(
self.tmp_dir, node.op_type, self.tmp_dir, node.op_type
)
)
process_compile = subprocess.Popen(bash_compile.split(), stdout=subprocess.PIPE)
process_compile.communicate()
bash_execute = "{}/execute_{}".format(self.tmp_dir, node.op_type)
......@@ -39,13 +51,14 @@ class StreamingMaxPool(HLSCustomOp):
process_execute.communicate()
temp_files.append("{}/execute_{}".format(self.tmp_dir, node.op_type))
temp_files.append("{}/output.npy".format(self.tmp_dir))
output = np.load("{}/output.npy".format(self.tmp_dir))
# load output npy file
output = np.load("{}/output.npy".format(self.tmp_dir))
context[node.output[0]] = output
# deleting temporary files
#for temp_file in temp_files:
# for temp_file in temp_files:
# os.remove(temp_file)
def get_attributes(self, node):
self.ImgDim = get_by_name(node.attribute, "ImgDim").i
self.PoolDim = get_by_name(node.attribute, "PoolDim").i
......@@ -62,6 +75,8 @@ class StreamingMaxPool(HLSCustomOp):
]
def read_npy_data(self, node):
# c++ code to read out an npy file
# and put it in hls::stream in the correct order
self.code_gen_dict["$READNPYDATA$"] = []
input_ind = 0
input_file_names = []
......
import os
import numpy as np
import subprocess
import tempfile as tmp
import numpy as np
from finn.core.utils import get_by_name
from finn.custom_op.fpgadataflow import HLSCustomOp
......@@ -14,24 +14,36 @@ class StreamingMaxPool_Batch(HLSCustomOp):
def infer_node_datatype(self, node, model):
pass
def execute_node(self, node, context, graph):
# make temporary directory for generated files
self.tmp_dir = tmp.mkdtemp(prefix=str(node.op_type) + "_")
in_ind = 0
# create empty list for temporary files to enable the option
# to delete the files after the execution
temp_files = []
# create a npy file fore each input of the node (in_ind is input index)
in_ind = 0
for inputs in node.input:
np.save(os.path.join(self.tmp_dir, "input_{}.npy".format(in_ind)),
context[inputs],)
np.save(
os.path.join(self.tmp_dir, "input_{}.npy".format(in_ind)),
context[inputs],
)
temp_files.append("{}/input_{}.npy".format(self.tmp_dir, in_ind))
in_ind += 1
# code generation
self.code_generation(node)
# c++ compilation and execution flow
temp_files.append("{}/execute_{}.cpp".format(self.tmp_dir, node.op_type))
bash_compile = """g++ -o {}/execute_{} {}/execute_{}.cpp
/workspace/cnpy/cnpy.cpp -I/workspace/cnpy/
-I/workspace/finn-hlslib -I/workspace/vivado-hlslib
--std=c++11 -lz""".format(
self.tmp_dir, node.op_type, self.tmp_dir, node.op_type
)
)
process_compile = subprocess.Popen(bash_compile.split(), stdout=subprocess.PIPE)
process_compile.communicate()
bash_execute = "{}/execute_{}".format(self.tmp_dir, node.op_type)
......@@ -39,10 +51,12 @@ class StreamingMaxPool_Batch(HLSCustomOp):
process_execute.communicate()
temp_files.append("{}/execute_{}".format(self.tmp_dir, node.op_type))
temp_files.append("{}/output.npy".format(self.tmp_dir))
output = np.load("{}/output.npy".format(self.tmp_dir))
# load output npy file
output = np.load("{}/output.npy".format(self.tmp_dir))
context[node.output[0]] = output
# deleting temporary files
#for temp_file in temp_files:
# for temp_file in temp_files:
# os.remove(temp_file)
def get_attributes(self, node):
......@@ -63,6 +77,8 @@ class StreamingMaxPool_Batch(HLSCustomOp):
]
def read_npy_data(self, node):
# c++ code to read out an npy file
# and put it in hls::stream in the correct order
self.code_gen_dict["$READNPYDATA$"] = []
input_ind = 0
input_file_names = []
......@@ -153,7 +169,7 @@ class StreamingMaxPool_Batch(HLSCustomOp):
self.code_gen_dict["$SAVEASCNPY$"] = [
"""cnpy::npy_save("{}/output.npy",&output_data_vector[0],
{{{},{},{}}},"w");""".format(
self.tmp_dir,
self.tmp_dir,
numReps,
self.NumChannels,
int(self.ImgDim / self.PoolDim),
......
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