Beispiel #1
0
def print_code(stencil, header_file):
  logger.info('generate host header code as %s' % header_file.name)
  printer = util.Printer(header_file)
  println = printer.println
  do_indent = printer.do_indent
  un_indent = printer.un_indent
  println('#ifndef HALIDE_%s_H_' % stencil.app_name.upper())
  println('#define HALIDE_%s_H_' % stencil.app_name.upper())
  println()

  println('#ifndef HALIDE_ATTRIBUTE_ALIGN')
  do_indent()
  println('#ifdef _MSC_VER')
  do_indent()
  println('#define HALIDE_ATTRIBUTE_ALIGN(x) __declspec(align(x))')
  un_indent()
  println('#else')
  do_indent()
  println('#define HALIDE_ATTRIBUTE_ALIGN(x) __attribute__((aligned(x)))')
  un_indent()
  println('#endif')
  un_indent()
  println('#endif//HALIDE_ATTRIBUTE_ALIGN')
  println()

  println('#ifndef BUFFER_T_DEFINED')
  println('#define BUFFER_T_DEFINED')
  println('#include<stdbool.h>')
  println('#include<stdint.h>')
  println('typedef struct buffer_t {')
  do_indent()
  println('uint64_t dev;')
  println('uint8_t* host;')
  println('int32_t extent[4];')
  println('int32_t stride[4];')
  println('int32_t min[4];')
  println('int32_t elem_size;')
  println('HALIDE_ATTRIBUTE_ALIGN(1) bool host_dirty;')
  println('HALIDE_ATTRIBUTE_ALIGN(1) bool dev_dirty;')
  println('HALIDE_ATTRIBUTE_ALIGN(1) uint8_t _padding[10 - sizeof(void *)];')
  un_indent()
  println('} buffer_t;')
  println('#endif//BUFFER_T_DEFINED')
  println()

  println('#ifndef HALIDE_FUNCTION_ATTRS')
  println('#define HALIDE_FUNCTION_ATTRS')
  println('#endif//HALIDE_FUNCTION_ATTRS')
  println()

  tensors = stencil.input_names + stencil.output_names + stencil.param_names
  println('int {}({}const char* xclbin) HALIDE_FUNCTION_ATTRS;'.format(
      stencil.app_name,
      ''.join(map('buffer_t *var_{}_buffer, '.format, tensors))))
  println()

  println('#endif//HALIDE_%s_H_' % stencil.app_name.upper())
  println()
Beispiel #2
0
def print_code(stencil, output_file):
    _logger.info('generate kernel code as %s' % output_file.name)
    printer = util.Printer(output_file)

    print_header(printer)

    printer.println()

    util.print_define(printer, 'BURST_WIDTH', stencil.burst_width)
    printer.println()

    util.print_guard(printer, 'UNROLL_FACTOR', stencil.unroll_factor)
    for i in range(len(stencil.tile_size) - 1):
        util.print_guard(printer, 'TILE_SIZE_DIM_%d' % i, stencil.tile_size[i])
    util.print_guard(printer, 'BURST_WIDTH', stencil.burst_width)
    printer.println()

    _print_data_struct(printer)
    _print_reinterpret(printer)
    _print_read_data(printer)
    _print_write_data(printer)

    _print_burst_read(printer)
    _print_burst_write(printer)

    for module_trait_id, module_trait in enumerate(stencil.module_traits):
        _print_module_definition(printer,
                                 module_trait,
                                 module_trait_id,
                                 burst_width=stencil.burst_width)

    outputs = []
    inputs = []
    for stmt in stencil.output_stmts:
        for bank in sorted(stmt.dram):
            outputs.append(
                (stmt.name, 'ap_uint<%d>' % stencil.burst_width, bank, 65536))
    for stmt in stencil.input_stmts:
        for bank in sorted(stmt.dram):
            inputs.append(
                (stmt.name, 'ap_uint<%d>' % stencil.burst_width, bank, 65536))
    for stmt in stencil.param_stmts:
        inputs.append(('var_%s' % stmt.name, stmt.type, 0,
                       functools.reduce(operator.mul, stmt.size)))
    _print_interface(printer, stencil.app_name + '_kernel', inputs, outputs,
                     stencil.dataflow_super_source)
Beispiel #3
0
def print_code(stencil, xo_file, platform=None, jobs=os.cpu_count()):
    """Generate hardware object file for the given Stencil.

  Working `vivado` and `vivado_hls` is required in the PATH.

  Args:
    stencil: Stencil object to generate from.
    xo_file: file object to write to.
    platform: path to the SDAccel platform directory.
    jobs: maximum number of jobs running in parallel.
  """

    m_axi_names = []
    m_axi_bundles = []
    inputs = []
    outputs = []
    for stmt in stencil.output_stmts + stencil.input_stmts:
        for bank in stmt.dram:
            haoda_type = 'uint%d' % stencil.burst_width
            bundle_name = util.get_bundle_name(stmt.name, bank)
            m_axi_names.append(bundle_name)
            m_axi_bundles.append((bundle_name, haoda_type))

    for stmt in stencil.output_stmts:
        for bank in stmt.dram:
            haoda_type = 'uint%d' % stencil.burst_width
            bundle_name = util.get_bundle_name(stmt.name, bank)
            outputs.append((util.get_port_name(stmt.name,
                                               bank), bundle_name, haoda_type,
                            util.get_port_buf_name(stmt.name, bank)))
    for stmt in stencil.input_stmts:
        for bank in stmt.dram:
            haoda_type = 'uint%d' % stencil.burst_width
            bundle_name = util.get_bundle_name(stmt.name, bank)
            inputs.append((util.get_port_name(stmt.name,
                                              bank), bundle_name, haoda_type,
                           util.get_port_buf_name(stmt.name, bank)))

    top_name = stencil.app_name + '_kernel'

    if 'XDEVICE' in os.environ:
        xdevice = os.environ['XDEVICE'].replace(':', '_').replace('.', '_')
        if platform is None or not os.path.exists(platform):
            platform = os.path.join('/opt/xilinx/platforms', xdevice)
        if platform is None or not os.path.exists(platform):
            if 'XILINX_SDX' in os.environ:
                platform = os.path.join(os.environ['XILINX_SDX'], 'platforms',
                                        xdevice)
    if platform is None or not os.path.exists(platform):
        raise ValueError('Cannot determine platform from environment.')
    device_info = backend.get_device_info(platform)

    with tempfile.TemporaryDirectory(prefix='sodac-xrtl-') as tmpdir:
        dataflow_kernel = os.path.join(tmpdir, 'dataflow_kernel.cpp')
        with open(dataflow_kernel, 'w') as dataflow_kernel_obj:
            print_dataflow_hls_interface(util.Printer(dataflow_kernel_obj),
                                         top_name, inputs, outputs)

        kernel_xml = os.path.join(tmpdir, 'kernel.xml')
        with open(kernel_xml, 'w') as kernel_xml_obj:
            backend.print_kernel_xml(top_name, outputs + inputs,
                                     kernel_xml_obj)

        kernel_file = os.path.join(tmpdir, 'kernel.cpp')
        with open(kernel_file, 'w') as kernel_fileobj:
            hls_kernel.print_code(stencil, kernel_fileobj)

        super_source = stencil.dataflow_super_source
        with concurrent.futures.ThreadPoolExecutor(
                max_workers=jobs) as executor:
            threads = []
            for module_id in range(len(super_source.module_traits)):
                threads.append(
                    executor.submit(synthesis_module, tmpdir, [kernel_file],
                                    util.get_func_name(module_id),
                                    device_info))
            threads.append(
                executor.submit(synthesis_module, tmpdir, [dataflow_kernel],
                                top_name, device_info))
            for future in concurrent.futures.as_completed(threads):
                returncode, stdout, stderr = future.result()
                log_func = _logger.error if returncode != 0 else _logger.debug
                if stdout:
                    log_func(stdout.decode())
                if stderr:
                    log_func(stderr.decode())
                if returncode != 0:
                    util.pause_for_debugging()
                    sys.exit(returncode)

        hdl_dir = os.path.join(tmpdir, 'hdl')
        with open(os.path.join(hdl_dir, 'Dataflow.v'), mode='w') as dataflow_v:
            print_top_module(backend.VerilogPrinter(dataflow_v),
                             stencil.dataflow_super_source, inputs, outputs)

        util.pause_for_debugging()

        xo_filename = os.path.join(tmpdir, stencil.app_name + '.xo')
        with backend.PackageXo(xo_filename, top_name, kernel_xml, hdl_dir,
                               m_axi_names, [dataflow_kernel]) as proc:
            stdout, stderr = proc.communicate()
        log_func = _logger.error if proc.returncode != 0 else _logger.debug
        log_func(stdout.decode())
        log_func(stderr.decode())
        with open(xo_filename, mode='rb') as xo_fileobj:
            shutil.copyfileobj(xo_fileobj, xo_file)