Exemple #1
0
        def run(xclbin: SourceType.Path) -> SourceType.String:
            """Run the xclbin with datafile"""

            if self.data_path is None:
                raise errors.MissingDynamicConfiguration("fpga.data")

            data = sjson.load(open(self.data_path), use_decimal=True)
            xclbin_source = xclbin.open("rb").read()

            # create a temporary directory with an xrt.ini file that redirects
            # the runtime log to a file so that we can control how it's printed.
            # This is hacky, but it's the only way to do it
            tmp_dir = TmpDir()
            os.chdir(tmp_dir.name)
            xrt_output_logname = "output.log"
            with open("xrt.ini", "w+") as f:
                f.writelines(
                    ["[Runtime]\n", f"runtime_log={xrt_output_logname}"])

            ctx = self.cl.create_some_context(0)
            dev = ctx.devices[0]
            cmds = self.cl.CommandQueue(ctx, dev)
            prg = self.cl.Program(ctx, [dev], [xclbin_source])

            prg.build()

            buffers = {}
            for mem in data.keys():
                # allocate memory on the device
                buf = self.cl.Buffer(
                    ctx,
                    self.cl.mem_flags.READ_WRITE
                    | self.cl.mem_flags.COPY_HOST_PTR,
                    hostbuf=np.array(data[mem]["data"]).astype(np.uint32),
                )
                # TODO: use real type information
                buffers[mem] = buf

            start_time = time.time()
            prg.Toplevel(cmds, (1, ), (1, ), np.uint32(10000),
                         *buffers.values())
            end_time = time.time()

            # read the result
            output = {"memories": {}, "runtime": end_time - start_time}
            for name, buf in buffers.items():
                out_buf = np.zeros_like(data[name]["data"]).astype(np.uint32)
                self.cl.enqueue_copy(cmds, out_buf, buf)
                buf.release()
                output["memories"][name] = list(map(lambda x: int(x), out_buf))

            # cleanup
            del ctx
            # add xrt log output to our debug output
            with open(xrt_output_logname, "r") as f:
                for line in f.readlines():
                    log.debug(line.strip())

            return sjson.dumps(output, indent=2, use_decimal=True)
Exemple #2
0
 def download_xclbin(
     client: SourceType.UnTyped,
     tmpdir: SourceType.String,
 ) -> SourceType.Stream:
     """
     Download xclbin file
     """
     local_tmpdir = TmpDir()
     xclbin_path = Path(local_tmpdir.name) / "kernel.xclbin"
     with self.SCPClient(client.get_transport()) as scp:
         scp.get(f"{tmpdir}/xclbin/kernel.xclbin",
                 local_path=str(xclbin_path))
     return xclbin_path.open("rb")
Exemple #3
0
 def download_wdb(
     client: SourceType.UnTyped,
     tmpdir: SourceType.String,
 ) -> SourceType.Stream:
     """
     Download xclbin file
     """
     local_tmpdir = TmpDir()
     wdb_path = Path(local_tmpdir.name) / "kernel.wdb"
     with SCPClient(client.get_transport()) as scp:
         scp.get(
             f"{tmpdir}/xilinx_u50_gen3x16_xdma_201920_3-0-kernel.wdb",
             local_path=str(wdb_path),
         )
     return wdb_path.open("rb")
Exemple #4
0
    def create(self, input_files):
        """Copy input files to a fresh temporary directory.

        `input_files` is a dict with the same format as `open_and_send`:
        it maps local Source paths to destination strings.

        Return a path to the newly-created temporary directory.
        """
        def copy_file(tmpdir, src, dst):

            src_str = "{src}" if isinstance(src, Source) else str(src)
            dst_str = "{dst}" if isinstance(dst, Source) else str(dst)
            tmp_str = "{tmpdir}" if isinstance(tmpdir, Source) else str(tmpdir)

            @self.builder.step(
                description=f"copy {src_str} to {tmp_str}/{dst_str}")
            def copy(
                tmpdir: SourceType.String,
                src_path: SourceType.Path,
                dest_path: SourceType.String,
            ):
                shutil.copyfile(src_path, Path(tmpdir) / dest_path)

            if not isinstance(src, Source):
                src = Source(src, SourceType.Path)
            if not isinstance(dst, Source):
                dst = Source(dst, SourceType.String)

            return copy(tmpdir, src, dst)

        # Schedule
        tmpdir = Source(
            FreshDir() if self.save_temps else TmpDir(),
            SourceType.Directory,
        )

        for src_path, dest_path in input_files.items():
            copy_file(tmpdir, src_path, dest_path)

        self.tmpdir = tmpdir
        return tmpdir
Exemple #5
0
 def mktmp() -> SourceType.Directory:
     """
     Make temporary directory to store Verilator build files.
     """
     return TmpDir()
Exemple #6
0
        def run(xclbin: SourceType.Path) -> SourceType.String:
            """Run the xclbin with datafile"""

            if data_path is None:
                raise errors.MissingDynamicConfiguration("fpga.data")

            data = sjson.load(open(data_path), use_decimal=True)
            xclbin_source = xclbin.open("rb").read()

            # create a temporary directory with an xrt.ini file that redirects
            # the runtime log to a file so that we can control how it's printed.
            # This is hacky, but it's the only way to do it
            tmp_dir = TmpDir()
            os.chdir(tmp_dir.name)
            xrt_output_logname = "output.log"
            with open("xrt.ini", "w") as f:
                f.writelines(
                    [
                        "[Runtime]\n",
                        f"runtime_log={xrt_output_logname}\n",
                        "[Emulation]\n",
                        "print_infos_in_console=false\n",
                    ]
                )

            ctx = self.cl.create_some_context(0)
            dev = ctx.devices[0]
            cmds = self.cl.CommandQueue(ctx, dev)
            prg = self.cl.Program(ctx, [dev], [xclbin_source])

            prg.build()

            # Work around an intermittent PyOpenCL bug. Using prg.Toplevel
            # internally accesses prg._source, expecting it to be a normal
            # attribute instead of a kernel name.
            kern = self.cl.Kernel(prg, "Toplevel")

            buffers = {}
            for mem in data.keys():
                # allocate memory on the device
                buf = self.cl.Buffer(
                    ctx,
                    self.cl.mem_flags.READ_WRITE | self.cl.mem_flags.COPY_HOST_PTR,
                    hostbuf=np.array(data[mem]["data"]).astype(np.uint32),
                )
                # TODO: use real type information
                buffers[mem] = buf

            start_time = time.time()
            kern(cmds, (1,), (1,), np.uint32(10000), *buffers.values())
            end_time = time.time()
            log.debug(f"Emulation time: {end_time - start_time} sec")

            # read the result
            output = {"memories": {}}
            for name, buf in buffers.items():
                out_buf = np.zeros_like(data[name]["data"]).astype(np.uint32)
                self.cl.enqueue_copy(cmds, out_buf, buf)
                buf.release()
                output["memories"][name] = list(map(lambda x: int(x), out_buf))

            # cleanup
            del ctx

            # Add xrt log output to our debug output.
            if os.path.exists(xrt_output_logname):
                log.debug("XRT log:")
                with open(xrt_output_logname, "r") as f:
                    for line in f.readlines():
                        log.debug(line.strip())

            # And, in emulation mode, also include the emulation log.
            emu_log = "emulation_debug.log"
            if os.path.exists(emu_log):
                log.debug("Emulation log:")
                with open(emu_log, "r") as f:
                    for line in f.readlines():
                        log.debug(line.strip())

            return sjson.dumps(output, indent=2, use_decimal=True)
Exemple #7
0
 def mktmp() -> SourceType.Directory:
     """
     Make temporary directory to store Vivado synthesis files.
     """
     return TmpDir()