Example #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)
Example #2
0
 def check_verilog_for_mem_read(verilog_src: SourceType.String):
     """
     Read input verilog to see if `icarus-verilog.data` needs to be set.
     """
     if "readmemh" in verilog_src:
         raise errors.MissingDynamicConfiguration("verilog.data")
Example #3
0
 def check_host_cpp():
     """
     Make sure that `-s wdb.host` is provided
     """
     if self.host_cpp is None:
         raise errors.MissingDynamicConfiguration("wdb.host")
Example #4
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)