docstr: Write the Python-C++ bridge (myproject_bridge.cpp)
  
  Args:
      model (ModelGraph): the hls4ml model.
docstr_tok: ["Write","the","Python-C++","bridge","(","myproject_bridge.cpp",")","Args",":","model","(","ModelGraph",")",":","the","hls4ml","model","."]
code: def write_bridge(self, model):
      """Write the Python-C++ bridge (myproject_bridge.cpp)
  
      Args:
          model (ModelGraph): the hls4ml model.
      """
  
      filedir = os.path.dirname(os.path.abspath(__file__))
      f = open(
          os.path.join(
              filedir, "../templates/quartus/myproject_bridge.cpp"
          )
      )
      fout = open(
          f"{model.config.get_output_dir()}/{model.config.get_project_name()}_bridge.cpp",
          "w",
      )
  
      model_inputs = model.get_input_variables()
      model_outputs = model.get_output_variables()
      model_brams = [
          var
          for var in model.get_weight_variables()
          if var.storage.lower() == "bram"
      ]
  
      io_type = model.config.get_config_value("IOType")
      indent = "    "
  
      for line in f.readlines():
          if "MYPROJECT" in line:
              newline = line.replace(
                  "MYPROJECT",
                  format(model.config.get_project_name().upper()),
              )
  
          elif "myproject" in line:
              newline = line.replace(
                  "myproject", format(model.config.get_project_name())
              )
  
          elif "// hls-fpga-machine-learning insert bram" in line:
              newline = line
              for bram in model_brams:
                  newline += (
                      f'#include "firmware/weights/{bram.name}.h"\n'
                  )
  
          elif "// hls-fpga-machine-learning insert header" in line:
              dtype = line.split("#", 1)[1].strip()
              if io_type == "io_stream":
                  inputs_str = ", ".join(
                      [
                          f"{dtype} {i.name}[{i.size_cpp()}]"
                          for i in model_inputs
                      ]
                  )
                  outputs_str = ", ".join(
                      [
                          f"{dtype} {o.name}[{o.size_cpp()}]"
                          for o in model_outputs
                      ]
                  )
              else:
                  inputs_str = ", ".join(
                      [
                          f"{dtype} {i.member_name}[{i.size_cpp()}]"
                          for i in model_inputs
                      ]
                  )
                  outputs_str = ", ".join(
                      [
                          f"{dtype} {o.member_name}[{o.size_cpp()}]"
                          for o in model_outputs
                      ]
                  )
  
              insize_str = ", ".join(
                  [
                      f"unsigned short &const_size_in_{i}"
                      for i in range(1, len(model_inputs) + 1)
                  ]
              )
              outsize_str = ", ".join(
                  [
                      f"unsigned short &const_size_out_{o}"
                      for o in range(1, len(model_outputs) + 1)
                  ]
              )
  
              newline = ""
              newline += indent + inputs_str + ",\n"
              newline += indent + outputs_str + ",\n"
              newline += indent + insize_str + ",\n"
              newline += indent + outsize_str + "\n"
  
          elif "// hls-fpga-machine-learning insert wrapper" in line:
              bram_params = ""
              if model_brams:
                  bram_params = ", " + ",".join(
                      [b.name for b in model_brams]
                  )
  
              dtype = line.split("#", 1)[1].strip()
              if io_type == "io_stream":
                  newline = ""
                  for i in model_inputs:
                      # Initialise stream object and store input data (C-array) to a 'stream' object
                      newline += (
                          indent
                          + f"stream_in<{i.type.name}> {i.name}_input;\n"
                      )
                      newline += (
                          indent
                          + "nnet::convert_data<{}, {}, {}>({}, {}_input);\n".format(
                              dtype,
                              i.type.name,
                              i.size_cpp(),
                              i.name,
                              i.name,
                          )
                      )
  
                  # Initialise stream output
                  for o in model_outputs:
                      newline += "\n"
                      newline += (
                          indent
                          + f"stream_out<{o.type.name}> {o.name}_output;\n"
                      )
  
                  # Execute top-level function
                  input_params = ", ".join(
                      [f"{i.name}_input" for i in model_inputs]
                  )
                  output_params = ", ".join(
                      [f"{o.name}_output" for o in model_outputs]
                  )
  
                  top_level = (
                      indent
                      + f"{model.config.get_project_name()}({input_params}, {output_params}{bram_params});\n"
                  )
                  newline += top_level
                  newline += "\n"
  
                  # Store data from 'stream' output to C-array, to be then returned and handled in Python
                  for o in model_outputs:
                      newline += (
                          indent
                          + "nnet::convert_data_back<{}, {}, {}>({}_output, {});\n".format(
                              o.type.name,
                              dtype,
                              o.size_cpp(),
                              o.name,
                              o.name,
                          )
                      )
  
              else:
                  # Convert input data from C-array to HLS type
                  newline = ""
                  newline += indent + "input_data inputs_ap;\n"
                  for i in model_inputs:
                      newline += (
                          indent
                          + "nnet::convert_data<{}, {}, {}>({}, inputs_ap.{});\n".format(
                              dtype,
                              i.type.name,
                              i.size_cpp(),
                              i.member_name,
                              i.member_name,
                          )
                      )
                  newline += "\n"
  
                  # Initialise HLS output
                  newline += indent + "output_data outputs_ap;\n"
  
                  # Execute top-level function
                  top_level = (
                      indent
                      + f"outputs_ap = {model.config.get_project_name()}(inputs_ap{bram_params});\n"
                  )
                  newline += top_level
                  newline += "\n"
  
                  # Convert HLS outputs back to C-array
                  for o in model_outputs:
                      newline += (
                          indent
                          + "nnet::convert_data_back<{}, {}, {}>(outputs_ap.{}, {});\n".format(
                              o.type.name,
                              dtype,
                              o.size_cpp(),
                              o.member_name,
                              o.member_name,
                          )
                      )
          elif (
              "// hls-fpga-machine-learning insert trace_outputs"
              in line
          ):
              newline = ""
              for layer in model.get_layers():
                  func = layer.get_attr("function_cpp")
                  if (
                      func
                      and model.config.trace_output
                      and layer.get_attr("trace", False)
                  ):
                      vars = layer.get_variables()
                      for var in vars:
                          newline += (
                              indent
                              + "nnet::trace_outputs->insert(std::pair<std::string, void *>("
                              + f'"{layer.name}", (void *) malloc({var.size_cpp()} * element_size)));\n'
                          )
  
          else:
              newline = line
          fout.write(newline)
  
      f.close()
      fout.close()
  
imports: import glob
  import os
  import tarfile
  from collections import OrderedDict
  from shutil import copyfile, copytree, rmtree
  import numpy
  import yaml
  from hls4ml.backends import get_backend
  from hls4ml.model.layers import Conv1D, Conv2D, Conv2DBatchnorm, Dense
  from hls4ml.utils.fixed_point_utils import FixedPointEmulator, ceil_log2, uint_to_binary
  from hls4ml.writer.writers import Writer
label_desc: Use image node_id 14 for calling the QuartusWriter obj's underlying member method code with example usage: obj.write_bridge(model) without return types