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()
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)
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)