Exemple #1
0
 def warm_fpga_cache(self, handle, dsm, src, dst):
     dsm.fill(0)
     ctl = nlb.CTL(width=32)
     cfg = nlb.CFG(width=32)
     self.logger.info("warming fpga cache for mode: %s", self.args.mode)
     self.write_csr64(handle, self.DSM_ADDR, dsm.io_address())
     self.write_csr32(handle, ctl.offset(), ctl.value(reset=0))
     self.write_csr32(handle, ctl.offset(), ctl.value(reset=1))
     self.write_csr64(handle, self.SRC_ADDR, cl_align(src.io_address()))
     self.write_csr64(handle, self.DST_ADDR, cl_align(dst.io_address()))
     self.write_csr32(handle, self.NUM_LINES, src.size() / CACHELINE_BYTES)
     cfg_offset = cfg.offset()
     if self.args.mode == "read":
         cfg_value = cfg.value(mode=int(self.modes("read")),
                               rd_chsel=int(self.rd_chsel("vl0")))
     else:
         cfg_value = cfg.value(mode=int(self.modes("write")),
                               rd_chsel=int(self.wr_chsel("vl0")))
     self.write_csr32(handle, cfg_offset, cfg_value)
     self.write_csr32(handle, ctl.offset(), ctl.value(reset=1, start=1))
     if not self.wait_for_dsm(dsm):
         raise RuntimeError("DSM Complete timeout during warm fpga cache")
     self.write_csr32(handle, ctl.offset(),
                      ctl.value(stop=1, reset=1, start=1))
     self.logger.info("fpga cache warmed")
Exemple #2
0
    def __init__(self, mode, parser):
        self._mode = mode
        self.cfg = nlb.CFG(width=32)
        self.ctl = nlb.CTL(width=32)
        self._parser = parser
        logger_name = "fpgadiag.{}".format(self.__class__.__name__)
        self.logger = logging.getLogger(logger_name)

        parser.add_argument("-c", "--config", help="Path to test config file")
        parser.add_argument("-t", "--target", help="one of {fpga, ase}")
        parser.add_argument('-B',
                            '--bus',
                            help='PCIe bus number',
                            type=parse_int)
        parser.add_argument('-D',
                            '--device',
                            help='PCIe device number',
                            type=parse_int)
        parser.add_argument('-F',
                            '--function',
                            help='PCIe function number',
                            type=parse_int)
        parser.add_argument('--segment',
                            help='PCIe segment number',
                            type=parse_int)
        parser.add_argument('-S',
                            '--socket_id',
                            help='socket id encoded in BBS',
                            type=parse_int)
        parser.add_argument('-G',
                            '--guid',
                            help='GUID of accelerator',
                            default=self.guid)
Exemple #3
0
 def cool_fpga_cache(self, handle, dsm):
     ice = fpga.allocate_shared_buffer(handle, COOL_CACHE_SIZE)
     dsm.fill(0)
     ctl = nlb.CTL(width=32)
     cfg = nlb.CFG(width=32)
     self.logger.info("cooling fpga cache for mode: %s", self.args.mode)
     self.write_csr64(handle, self.DSM_ADDR, dsm.io_address())
     self.write_csr32(handle, ctl.offset(), ctl.value(reset=0))
     self.write_csr32(handle, ctl.offset(), ctl.value(reset=1))
     self.write_csr64(handle, self.SRC_ADDR, cl_align(ice.io_address()))
     self.write_csr32(handle, self.NUM_LINES, COOL_CACHE_LINES)
     cfg_offset = cfg.offset()
     cfg_value = cfg.value(mode=int(self.modes["read"]),
                           rd_chsel=int(self.rd_chsel("vl0")),
                           cache_hint=int(self.cache_hint("rdline-I")))
     self.write_csr32(handle, cfg_offset, cfg_value)
     self.write_csr32(handle, ctl.offset(), ctl.value(reset=1, start=1))
     if not self.wait_for_dsm(dsm):
         raise RuntimeError("DSM Complete timeout during cool fpga cache")
     self.write_csr32(handle, ctl.offset(),
                      ctl.value(stop=1, reset=1, start=1))
     self.logger.info("fpga cache cooled")
Exemple #4
0
    def __init__(self, mode, parser):
        self._mode = mode
        self.cfg = nlb.CFG(width=32)
        self.ctl = nlb.CTL(width=32)
        self._parser = parser
        self.logger = logging.getLogger(self.__class__.__name__)
        stream_handler = logging.StreamHandler(stream=sys.stderr)
        stream_handler.setFormatter(
            logging.Formatter(
                '%(asctime)s: [%(name)-8s][%(levelname)-6s] - %(message)s'))
        self.logger.addHandler(stream_handler)

        parser.add_argument("-c", "--config", help="Path to test config file")
        parser.add_argument("-t", "--target", help="one of {fpga, ase}")
        parser.add_argument('-B',
                            '--bus',
                            help='PCIe bus number',
                            type=parse_int)
        parser.add_argument('-D',
                            '--device',
                            help='PCIe device number',
                            type=parse_int)
        parser.add_argument('-F',
                            '--function',
                            help='PCIe function number',
                            type=parse_int)
        parser.add_argument('--segment',
                            help='PCIe segment number',
                            type=parse_int)
        parser.add_argument('-S',
                            '--socket_id',
                            help='socket id encoded in BBS',
                            type=parse_int)
        parser.add_argument('-G',
                            '--guid',
                            help='GUID of accelerator',
                            default=self.guid)
Exemple #5
0
class diagtest(object):
    guid = None
    cfg = nlb.CFG()
    ctl = nlb.CTL()
    NUM_LINES = 0x130
    SRC_ADDR = 0x0120
    DST_ADDR = 0x0128
    DSM_ADDR = 0x0110
    STATUS2 = 0x0170
    DSM_COMPLETE = 0x40
    DSM_TIMEOUT_USEC = 10000
    MODE_LPBK1 = "lpbk1"
    MODE_READ = "read"
    MODE_WRITE = "write"
    MODE_TRPUT = "trput"
    MODE_SW = "sw"

    cache_policy = csr.f_enum({"wrline-M": 0, "wrline-I": 1, "wrpush-I": 1})

    cache_hint = csr.f_enum({"rdline-I": 1, "rdline-S": 0})

    rd_chsel = csr.f_enum({
        "auto": 0,
        "vl0": 1,
        "vh0": 2,
        "vh1": 3,
        "random": 4
    })
    wr_chsel = csr.f_enum({
        "auto": 0,
        "vl0": 1,
        "vh0": 2,
        "vh1": 3,
        "random": 4
    })
    wf_chsel = csr.f_enum({"auto": 0, "vl0": 1, "vh0": 2, "vh1": 3})
    modes = csr.f_enum(name="mode", lbpk1=0, read=1, write=2, trput=3, sw=7)

    def __init__(self, mode, parser):
        self._mode = mode
        self.cfg = nlb.CFG(width=32)
        self.ctl = nlb.CTL(width=32)
        self._parser = parser
        self.logger = logging.getLogger(self.__class__.__name__)
        stream_handler = logging.StreamHandler(stream=sys.stderr)
        stream_handler.setFormatter(
            logging.Formatter(
                '%(asctime)s: [%(name)-8s][%(levelname)-6s] - %(message)s'))
        self.logger.addHandler(stream_handler)

        parser.add_argument("-c", "--config", help="Path to test config file")
        parser.add_argument("-t", "--target", help="one of {fpga, ase}")
        parser.add_argument('-B',
                            '--bus',
                            help='PCIe bus number',
                            type=parse_int)
        parser.add_argument('-D',
                            '--device',
                            help='PCIe device number',
                            type=parse_int)
        parser.add_argument('-F',
                            '--function',
                            help='PCIe function number',
                            type=parse_int)
        parser.add_argument('--segment',
                            help='PCIe segment number',
                            type=parse_int)
        parser.add_argument('-S',
                            '--socket_id',
                            help='socket id encoded in BBS',
                            type=parse_int)
        parser.add_argument('-G',
                            '--guid',
                            help='GUID of accelerator',
                            default=self.guid)

    def enumerate(self, **kwargs):
        args, _ = self._parser.parse_known_args()
        prop_names = [
            'bus', 'device', 'function', 'segment', 'socket_id', 'guid'
        ]
        filt = dict([(p, getattr(args, p)) for p in prop_names
                     if getattr(args, p)])
        tokens = fpga.enumerate(type=fpga.ACCELERATOR, **filt)
        if not tokens:
            self.logger.error("could not find resources")
            return None
        if len(tokens) > 1:
            self.logger.warn("found more than one accelerator")
        return tokens

    def add_arguments(self, parser):
        parser.add_argument("-b",
                            "--begin",
                            default=1,
                            type=int,
                            help="where 1 <= <value> <= 65535")
        parser.add_argument("-e",
                            "--end",
                            type=int,
                            help="where 1 <= <value> <= 65535")
        parser.add_argument("-u",
                            "--multi-cl",
                            type=int,
                            default=1,
                            choices=[1, 2, 4],
                            help="one of {1, 2, 4}")
        parser.add_argument("-L",
                            "--cont",
                            default=False,
                            action='store_true',
                            help="Continuous mode")
        parser.add_argument("-p",
                            "--cache-policy",
                            choices=self.cache_policy.keys(),
                            type=self.cache_policy,
                            default='wrline-M',
                            help="write cache policy")
        parser.add_argument("-i",
                            "--cache-hint",
                            choices=self.cache_hint.keys(),
                            type=self.cache_hint,
                            default="rdline-I",
                            help="rd cache hint")
        parser.add_argument("-r",
                            "--read-vc",
                            choices=self.rd_chsel.keys(),
                            type=self.rd_chsel,
                            default="auto",
                            help="read channel select")
        parser.add_argument("-w",
                            "--write-vc",
                            choices=self.wr_chsel.keys(),
                            type=self.wr_chsel,
                            default="auto",
                            help="write channel select")
        parser.add_argument("-f",
                            "--wrfence-vc",
                            choices=self.wf_chsel.keys(),
                            type=self.wf_chsel,
                            help="auto")
        parser.add_argument("--dsm-timeout-usec",
                            type=int,
                            help="Timeout for test completion")
        parser.add_argument(
            "--timeout-usec",
            type=int,
            default=0,
            help="Timeout for continuous mode (microseconds portion)")
        parser.add_argument(
            "--timeout-msec",
            type=int,
            default=0,
            help="Timeout for continuous mode (milliseconds portion)")
        parser.add_argument(
            "--timeout-sec",
            type=int,
            default=0,
            help="Timeout for continuous mode (seconds portion)")
        parser.add_argument(
            "--timeout-min",
            type=int,
            default=0,
            help="Timeout for continuous mode (minutes portion)")
        parser.add_argument("--timeout-hour",
                            type=int,
                            default=0,
                            help="Timeout for continuous mode (hours portion)")
        parser.add_argument("-T",
                            "--freq",
                            type=int,
                            default=400000000,
                            help="Clock frequency (used for bw measurements)")
        parser.add_argument("-V",
                            "--csv",
                            default=False,
                            action='store_true',
                            help="Comma separated value format")
        parser.add_argument("--suppress-hdr",
                            default=False,
                            action='store_true',
                            help="Suppress column headers")
        parser.add_argument("--suppress-stats",
                            default=False,
                            action='store_true',
                            help="Hide stats at end")
        parser.add_argument(
            "--mem-timeout",
            default=0.5,
            type=float,
            help="Seconds to wait before timing out on memory poll")

    def setup(self, in_args=None):
        """setup is called to validate arguments and will return True
           if arguments are valid, False otherwise."""
        parser = self._parser.add_argument_group(self._mode)
        self.add_arguments(parser)
        self.args, _ = self._parser.parse_known_args(in_args)
        if self.args.end is None:
            self.args.end = self.args.begin
        return True

    def configure_test(self):
        """configure_test is used to configure the configuration register
           and to perform any other test configuration steps before the test
           starts"""
        args = self.args

        if self.args.target == 'ase':
            self.DSM_TIMEOUT_USEC = 10000000

        if args.dsm_timeout_usec:
            self.DSM_TIMEOUT_USEC = args.dsm_timeout_usec

        self.cfg["mode"] = int(self.modes(args.mode))

        if str(args.cache_policy) == "wrpush-I":
            self.cfg["wrpush_i"] = int(args.cache_policy)
        else:
            self.cfg["wrthru_en"] = int(args.cache_policy)
        self.cfg["rdsel"] = int(args.cache_hint)
        self.cfg["rd_chsel"] = int(args.read_vc)
        self.cfg["wr_chsel"] = int(args.write_vc)
        if args.wrfence_vc is None:
            self.cfg["wf_chsel"] = int(self.wf_chsel[str(args.write_vc)])
        else:
            self.cfg["wf_chsel"] = int(args.wrfence_vc)

        if args.cont:
            self.cfg["cont"] = 1

    def buffer_size(self):
        """buffer_size is used to get the number of bytes necessary for each
           test buffer (src and dst)."""
        return self.args.end * CACHELINE_BYTES

    def get_buffers(self, handle):
        """get_buffers gets the three basic buffers needed for test.
           dsm (device status memory), src (source or input),
           and dst (destination or output).

        :param handle: Use given handle for allocating buffers and preparing
                       for use with accelerator
        """
        bsize = self.buffer_size()
        dsm = fpga.allocate_shared_buffer(handle, int(KiB(4)))
        # allocate the smallest possible workspace for DSM, SRC, DST
        scratch = None

        if KiB(2) >= bsize or (KiB(4) < bsize
                               and MiB(1) >= bsize) or (MiB(2) < bsize
                                                        and MiB(512) > bsize):
            scratch = fpga.allocate_shared_buffer(handle, bsize * 2)
            src, dst = scratch.split(bsize, bsize)
        else:
            src = fpga.allocate_shared_buffer(handle, bsize)
            dst = fpga.allocate_shared_buffer(handle, bsize)
        return (dsm, src, dst)

    def run(self, handle, device):
        """run Run the test flow which consists of:
            1. Allocating buffers
            2. Initializing or priming the buffers
            3. Telling the accelerator about the buffers' io addresses
            4. Setting up the configuration register based on mode/arguments
            5. Writing the configuration data to the register
            6. Begin iterating on the number of cachelines as indicated by
               begin and end arguments. Each iteration will write to the
               control register to start and then test/wait on buffers like
               DSM before continuing to the next iteration. Counters will also
               be read at the beginning and at the end of the iteration and
               their deltas will be used when printing out statistics.

        :param handle: A handle to an accelerator
        :param device: A handle to the device object
        """
        args = self.args
        ctl = self.ctl
        # TODO: replace with get_user_clocks API
        status2 = handle.read_csr64(self.STATUS2)
        freq = (status2 >> 32) & 0xffff
        if freq > 0:
            args.freq = freq * 1E6

        self.logger.info("allocating bufers")
        (dsm, src, dst) = self.get_buffers(handle)

        self.logger.info("setup buffers")
        self.setup_buffers(handle, dsm, src, dst)

        self.logger.info("writing dsm address")
        self.write_csr64(handle, self.DSM_ADDR, dsm.io_address())

        self.logger.info("deassert/assert reset bit")
        self.write_csr32(handle, ctl.offset(), ctl.value(reset=0))
        self.write_csr32(handle, ctl.offset(), ctl.value(reset=1))

        self.logger.info(
            "writing src/dst buffer addresses (cacheline aligned)")
        self.write_csr64(handle, self.SRC_ADDR, cl_align(src.io_address()))
        self.write_csr64(handle, self.DST_ADDR, cl_align(dst.io_address()))

        self.logger.info("configuring test values to write")
        self.configure_test()
        self.logger.info("writing cfg register")
        self.write_csr32(handle, self.cfg.offset(), self.cfg.value())

        c_counters = nlb.cache_counters(device)
        f_counters = nlb.fabric_counters(device)

        dsm_tpl = nlb.dsm_tuple()
        for i in range(args.begin, args.end + 1, args.multi_cl):
            self.logger.debug("running test with cl: %s", i)
            dsm.fill(0)
            self.logger.info("deassert/assert reset bit")
            self.write_csr32(handle, ctl.offset(), ctl.value(reset=0))
            self.write_csr32(handle, ctl.offset(), ctl.value(reset=1))

            self.logger.info("writing number of cachelines")
            self.write_csr64(handle, self.NUM_LINES, i)

            self.logger.info("getting begin counters")
            with c_counters.reader() as r:
                begin_cache = r.read()

            with f_counters.reader() as r:
                begin_fabric = r.read()

            self.logger.debug("starting test")
            self.write_csr32(handle, ctl.offset(), ctl.value(reset=1, start=1))

            self.logger.info("testing buffers")
            self.test_buffers(handle, i, dsm, src, dst)
            self.logger.info("stopping test")

            handle.write_csr32(ctl.offset(), ctl.value(stop=1,
                                                       reset=1,
                                                       start=1))

            self.logger.info("getting end counters")
            with c_counters.reader() as r:
                end_cache = r.read()

            with f_counters.reader() as r:
                end_fabric = r.read()

            if args.suppress_stats:
                dsm_tpl += nlb.dsm_tuple(dsm)
            else:
                self.display_stats(i, nlb.dsm_tuple(dsm),
                                   end_cache - begin_cache,
                                   end_fabric - begin_fabric)

            self.logger.info("validating results")
            self.validate_results(i, dsm, src, dst)
            self.logger.info("end of test")

    def test_buffers(self, handle, cachelines, dsm, src, dst):
        """test_buffers The base version of test_buffers only waits for the
                         DSM complete bit to be set or for the timeout period
                         if continuous mode is selected.

        :param handle: A handle to the accelerator being tested
        :param cachelines: The number of cachelines for the current iteration.
        :param dsm: The DSM buffer
        :param src: The source or input buffer
        :param dst: The destination or output buffer
        """
        if self.args.cont:
            time.sleep(to_seconds(self.args))
        else:
            self.wait_for_dsm(dsm)

    def setup_buffers(self, handle, dsm, src, dst):
        src.fill(0xAE)
        dst.fill(0x00)

    def validate_results(self, num_cl, dsm, src, dst):
        pass

    def wait_for_dsm(self, dsm):
        if not dsm.poll(self.DSM_COMPLETE,
                        0x1,
                        mask=0x1,
                        timeout_usec=self.DSM_TIMEOUT_USEC):
            self.logger.error("Timeout waiting for DSM")
            return False
        return True

    def display_stats(self, cachelines, dsm, cache, fabric):
        stats = nlb.nlb_stats(cachelines,
                              dsm,
                              cache,
                              fabric,
                              frequency=self.args.freq,
                              cont=self.args.cont)
        if self.args.csv:
            print(stats.to_csv(not self.args.suppress_hdr))
        else:
            print(stats.to_str())

    def write_csr32(self, handle, offset, value):
        self.logger.debug("write_csr32(0x{:016x}, 0x{:08x})".format(
            offset, value))
        handle.write_csr32(offset, value)

    def write_csr64(self, handle, offset, value):
        self.logger.debug("write_csr64(0x{:016x}, 0x{:016x})".format(
            offset, value))
        handle.write_csr64(offset, value)