def print_footer(term, lock, y_len): footer_buf = [ XBUtil.fg.yellow + "'p'/'n' - Previous/Next Report" + XBUtil.fg.reset, XBUtil.fg.yellow + "'<'/'>' - Dec/Inc Page" + XBUtil.fg.reset, XBUtil.fg.yellow + " 'q' - Quit" + XBUtil.fg.reset ] XBUtil.indented_print(term, lock, footer_buf, 5, y_len - len(footer_buf))
def _print_memory_usage(self, term, lock, start_x, start_y): XBUtil.print_section_heading(term, lock, "Device Memory Usage", start_y) table_offset = 1 if self._df == None: XBUtil.print_warning(term, lock, start_y + table_offset, "Data unavailable. Acceleration image not loaded") return table_offset + 1 try: memories = self._df['board']['memory']['memories'] except: XBUtil.print_warning(term, lock, start_y + table_offset, "Data unavailable. Acceleration image not loaded") return table_offset + 1 mem_usage = [] for memory in memories: size = int(memory['range_bytes'], 16) if size == 0 or memory['enabled'] == "false": continue name = memory['tag'] usage = int(memory['extended_info']['usage']['allocated_bytes'], 0) mem_usage.append("%-16s %s" % (name, XBUtil.progress_bar(usage * 100 / size))) XBUtil.indented_print(term, lock, mem_usage, 3, start_y + table_offset) table_offset += len(mem_usage) return table_offset
def _print_dma_transfer_matrics(self, term, lock, start_x, start_y): XBUtil.print_section_heading(term, lock, "DMA Transfer Matrics", start_y) table_offset = 1 if self._df == None: print_warning(term, lock, start_y + table_offset, "Data unavailable. Acceleration image not loaded") return table_offset + 1 try: dma_metrics = self._df['board']['direct_memory_accesses']['metrics'] except: XBUtil.print_warning(term, lock, start_y + table_offset, "Data unavailable. Acceleration image not loaded") return table_offset + 1 header = [ "", "Channel", "Host-to-Card", "Card-to-Host"] format = ["right", "right", "right", "right"] data = [] dma_metrics = self._df['board']['direct_memory_accesses']['metrics'] for i in range(len(dma_metrics)): line = [] line.append(str(i)) line.append(dma_metrics[i]['channel_id']) line.append(XBUtil.convert_size(int(dma_metrics[i]['host_to_card_bytes'], 16))) line.append(XBUtil.convert_size(int(dma_metrics[i]['card_to_host_bytes'], 16))) data.append(line) table = XBUtil.Table(header, data, format) ascii_table = table.create_table() XBUtil.indented_print(term, lock, ascii_table, 3, start_y + table_offset) table_offset += len(ascii_table) return table_offset
def bdf_header(term, lock, dev): platform_json = dev.get_info(pyxrt.xrt_info_device.platform) platform_raw = json.loads(platform_json) platform = platform_raw['platforms'][0]['static_region'] header_buf = [ ' Shell : %s' % platform['vbnv'], ' UUID : %s' % platform['logic_uuid'], ' BDF : %s' % dev.get_info(pyxrt.xrt_info_device.bdf), ] longest_string = max(header_buf, key=len) header_buf.insert(0, '-' * (len(longest_string))) header_buf.append('-' * (len(longest_string))) XBUtil.indented_print(term, lock, header_buf, 0, 4)
def print_header(term, lock, dev, report_header, page_header, len_x): # Add padding to overwrite previous report padding_width = 35 report_header = XBUtil.pad_string(report_header, padding_width, "center") page_header = XBUtil.pad_string(page_header, padding_width, "center") with lock: center_align = int((len_x - len(report_header)) / 2) term.location(center_align, 2) print(XBUtil.fg.blue + XBUtil.fx.bold + XBUtil.fx.italic + report_header + XBUtil.fx.reset) center_align = int((len_x - len(page_header)) / 2) term.location(center_align, 3) print(XBUtil.fg.blue + XBUtil.fx.bold + XBUtil.fx.italic + page_header + XBUtil.fx.reset) bdf_header(term, lock, dev)
def _print_cu_info(self, term, lock, start_x, start_y, page): XBUtil.print_section_heading(term, lock, "Compute Usage", start_y) table_offset = 1 if self._df is None: XBUtil.print_warning(term, lock, start_y + table_offset, "Data unavailable. Acceleration image not loaded") return table_offset + 1 with lock: term.location(3, start_y+table_offset) print("Xclbin UUID: %s" % self._df['dynamic_regions'][0]['xclbin_uuid']) table_offset += 2 header = [ "", "Name", "Base Address", "Usage", "Status", "Type"] format = ["right", "left", "right", "right", "center", "center"] data = [] cus = [] try: cus = self._df['dynamic_regions'][0]['compute_units'] except: XBUtil.print_warning(term, lock, start_y + table_offset, "Data unavailable. Acceleration image not loaded") return table_offset + 1 # Each page should display however many items a report page can hold for i in range(self.report_length): line = [] # The current element to be parsed depends on what page has been requested index = i + (page * self.report_length) # Ensure that our index does not exceed the input data size. This may happen on the last page if(index < len(cus)): line.append(str(index)) cus_element = cus[index] line.append(cus_element['name']) line.append(cus_element['base_address']) line.append(cus_element['usage']) line.append(cus_element['status']['bit_mask']) line.append(cus_element['type']) data.append(line) # If the index exceeds the input data size leave the for loop as everything is populated on the # last page else: break if len(data) != 0: table = XBUtil.Table(header, data, format) ascii_table = table.create_table() XBUtil.indented_print(term, lock, ascii_table, 3, start_y + table_offset) table_offset += len(ascii_table) return table_offset
def print_report(self, term, lock, start_x, start_y): XBUtil.print_section_heading(term, lock, self.report_name(), start_y) offset = 1 if len(self._df) == 0: print_warning(term, lock, start_y + offset, "Data unavailable. Acceleration image not loaded") return offset power_buf = [ 'Power : %s Watts' % self._df['Power'], 'Max Power : %s Watts' % self._df['Max Power'], 'Warning : %s' % self._df['Warning'] ] XBUtil.indented_print(term, lock, power_buf, 3, start_y + offset) offset += len(power_buf) return offset
def running_reports(term, lock, dev, x_len): global g_report_number report_start_row = 10 num_lines_printed = 0 current_report = -1 while True: global g_refresh_counter global g_reports global g_refresh_rate g_refresh_counter += 1 # Determine if our report has changed if current_report != g_report_number: g_refresh_counter = 0 # Clear the previous reports XBUtil.clear_rows(term, lock, report_start_row, num_lines_printed) # Point to the next report if g_report_number < 0: g_report_number = len(g_reports) - 1 if g_report_number >= len(g_reports): g_report_number = 0 current_report = g_report_number # Update the report header on which report that is currently being displayed report_name = g_reports[current_report].report_name() report_header = "%s (%d/%d)" % (report_name, current_report + 1, len(g_reports)) print_header(term, lock, dev, report_header, x_len) g_reports[current_report].update(dev) # Clear the previous reports XBUtil.clear_rows(term, lock, report_start_row, num_lines_printed) num_lines_printed = g_reports[current_report].print_report(term, lock, 0, report_start_row) # Wait for either for the refresh time to expire or for a new report counter = 0 while counter < (g_refresh_rate * 4): # Note: The sleep time is 0.25 seconds, hence x4. counter += 1 if current_report != g_report_number: break time.sleep(0.25) # Check 4 times a second
def _print_cu_info(self, term, lock, start_x, start_y): XBUtil.print_section_heading(term, lock, "Compute Usage", start_y) table_offset = 1 if self._df is None: XBUtil.print_warning( term, lock, start_y + table_offset, "Data unavailable. Acceleration image not loaded") return table_offset + 1 try: cus = self._df['dynamic_regions'][0]['compute_units'] except: XBUtil.print_warning( term, lock, start_y + table_offset, "Data unavailable. Acceleration image not loaded") return table_offset + 1 with lock: term.location(3, start_y + table_offset) print("Xclbin UUID: %s" % self._df['dynamic_regions'][0]['xclbin_uuid']) table_offset += 2 header = ["", "Name", "Base Address", "Usage", "Status", "Type"] format = ["right", "left", "right", "right", "center", "center"] data = [] cus = self._df['dynamic_regions'][0]['compute_units'] for i in range(len(cus)): line = [] line.append(str(i)) line.append(cus[i]['name']) line.append(cus[i]['base_address']) line.append(cus[i]['usage']) line.append(cus[i]['status']['bit_mask']) line.append(cus[i]['type']) data.append(line) if len(data) != 0: table = XBUtil.Table(header, data, format) ascii_table = table.create_table() XBUtil.indented_print(term, lock, ascii_table, 3, start_y + table_offset) table_offset += len(ascii_table) return table_offset
def print_report(self, term, lock, start_x, start_y, page): offset = 0 # The pages in order are: # 1. Memory Topology # 2. DMA tranfer data # The page values in the individual reports range from 0 - X and # the input page refers to the total number of pages in the memory report # Ex. (0 - (topology_page_count + dma_page_count)). # So the previous page count must be subtracted before passing the # page parameter into the appropriate print function if (page < self.topology_page_count): offset = 1 + self._print_mem_topology(term, lock, start_x, start_y + offset, page) elif (page < self.page_count): offset = 1 + self._print_dma_transfer_metrics( term, lock, start_x, start_y + offset, page - self.topology_page_count) else: XBUtil.print_warning( term, lock, start_y + offset, "Something went wrong! Please report this issue and its conditions." ) return offset
def _print_mem_topology(self, term, lock, start_x, start_y): XBUtil.print_section_heading(term, lock, "Memory Topology", start_y) table_offset = 1 if self._df == None: print_warning(term, lock, start_y + table_offset, "Data unavailable. Acceleration image not loaded") return table_offset + 1 try: memories = self._df['board']['memory']['memories'] except: XBUtil.print_warning(term, lock, start_y + table_offset, "Data unavailable. Acceleration image not loaded") return table_offset + 1 header = [ "", "Tag", "Type", "Temp (C)", "Size", "Mem Usage", "BO Count"] format = ["right", "left", "left", "right", "right", "right", "right"] data = [] memories = self._df['board']['memory']['memories'] for i in range(len(memories)): line = [] line.append(str(i)) line.append(memories[i]['tag']) line.append(memories[i]['type']) line.append(memories[i]['extended_info']['temperature_C'] if 'temperature_C' in memories[i]['extended_info'] else "--") line.append(XBUtil.convert_size(int(memories[i]['range_bytes'],16))) line.append(XBUtil.convert_size(int(memories[i]['extended_info']['usage']['buffer_objects_count'],0))) line.append(memories[i]['extended_info']['usage']['buffer_objects_count']) data.append(line) table = XBUtil.Table(header, data, format) ascii_table = table.create_table() XBUtil.indented_print(term, lock, ascii_table, 3, start_y + table_offset) table_offset += len(ascii_table) return table_offset
def print_report(self, term, lock, start_x, start_y, page): XBUtil.print_section_heading(term, lock, self.report_name(), start_y) offset = 1 if len(self._df) == 0: print_warning(term, lock, start_y + offset, "Data unavailable. Acceleration image not loaded") return offset + 1 if (self.page_count == 0): XBUtil.print_warning( term, lock, start_y + offset, "Data unavailable. Acceleration image not loaded") return offset + 1 # Create the complete power buffer all_data = [ 'Power : %s Watts' % self._df['Power'], 'Max Power : %s Watts' % self._df['Max Power'], 'Warning : %s' % self._df['Warning'] ] # Extract the data elements to be displayed on the requested page page_offset = page * self.report_length # The upper offset is bounded by the size of the full power buffer upper_page_offset = min(self.report_length + page_offset, len(all_data)) data = all_data[page_offset:upper_page_offset] if (not data): XBUtil.print_warning(term, lock, start_y + offset, "Data unavailable") return offset + 1 XBUtil.indented_print(term, lock, data, 3, start_y + offset) offset += len(data) return offset
def print_footer(term, lock, y_len): footer_buf = [ XBUtil.fg.yellow + "'n'/'p' - Next/Previous Report" + XBUtil.fg.reset, XBUtil.fg.yellow + " 'q' - Quit" + XBUtil.fg.reset ] XBUtil.indented_print(term, lock, footer_buf, 5, y_len - len(footer_buf))
def main(): global g_refresh_rate global g_report_number # Get and validate the options opt = options_parser() g_refresh_rate = float(opt.s) if g_refresh_rate < 1: raise RuntimeError("Please specify a refresh rate greater than 1 second") if g_refresh_rate > 60: raise RuntimeError("Please specify a refresh rate less than 60 seconds") dev = pyxrt.device(opt.bdf) # Check the terminal size term_size = get_terminal_size() x_len = term_size.columns y_len = term_size.lines MIN_X = 100 MIN_Y = 44 if x_len < MIN_X or y_len < MIN_Y: raise RuntimeError("Please resize the terminal window. The current size %dx%d is smaller then the required size of %dx%d" % (x_len, y_len, MIN_X, MIN_Y)) with XBUtil.Terminal() as term: term.hide_cursor(True) # creating a lock lock = threading.Lock() # Print the key print_footer(term, lock, y_len) # Running clock t1 = threading.Thread(target=running_clock, args=(term, lock)) t1.daemon = True t1.start() # Running counter t1 = threading.Thread(target=running_counter, args=(term, lock, x_len)) t1.daemon = True t1.start() # Running reports t2 = threading.Thread(target=running_reports, args=(term, lock, dev, x_len)) t2.daemon = True t2.start() # Main thread that consumes the keys pressed by the user. while True: key = XBUtil.get_char() if key in ['q', 'Q']: break if key in ['n', 'N']: g_report_number += 1 if key in ['p', 'P']: g_report_number -= 1 if key in ['+']: # Hidden option g_refresh_rate += 1 if g_refresh_rate > 60: g_refresh_rate = 60 if key in ['-']: # Hidden option g_refresh_rate -= 1 if g_refresh_rate < 1: g_refresh_rate = 1
def _print_memory_usage(self, term, lock, start_x, start_y, page): XBUtil.print_section_heading(term, lock, "Device Memory Usage", start_y) offset = 1 if self._df == None: XBUtil.print_warning( term, lock, start_y + offset, "Data unavailable. Acceleration image not loaded") return offset + 1 data = [] memories = [] try: memories = self._df['board']['memory']['memories'] except: XBUtil.print_warning( term, lock, start_y + offset, "Data unavailable. Acceleration image not loaded") return offset + 1 for i in range(self.report_length): # The current element to be parsed depends on what page has been requested index = i + (page * self.report_length) # Ensure that our index does not exceed the input data size. This may happen on the last page if (index < len(memories)): memory = memories[index] size = int(memory['range_bytes'], self.hexadecimal_converion) if size == 0 or memory['enabled'] == "false": continue name = memory['tag'] usage = int( memory['extended_info']['usage']['allocated_bytes'], 0) data.append("%-16s %s" % (name, XBUtil.progress_bar(usage * 100 / size))) # If the index exceeds the input data size leave the for loop as everything is populated on the # last page else: break if (not data): XBUtil.print_warning(term, lock, start_y + offset, "Data unavailable") return offset + 1 XBUtil.indented_print(term, lock, data, 3, start_y + offset) offset += len(data) return offset
def _print_dma_transfer_metrics(self, term, lock, start_x, start_y, page): XBUtil.print_section_heading(term, lock, "DMA Transfer Metrics", start_y) offset = 1 if self._df == None: print_warning(term, lock, start_y + offset, "Data unavailable. Acceleration image not loaded") return offset + 1 header = ["", "Channel", "Host-to-Card", "Card-to-Host"] format = ["right", "right", "right", "right"] data = [] dma_metrics = [] try: dma_metrics = self._df['board']['direct_memory_accesses'][ 'metrics'] except: XBUtil.print_warning( term, lock, start_y + offset, "Data unavailable. Acceleration image not loaded") return offset + 1 for i in range(self.report_length): line = [] # The current element to be parsed depends on what page has been requested index = i + (page * self.report_length) # Ensure that our index does not exceed the input data size. This may happen on the last page if (index < len(dma_metrics)): dma_metric = dma_metrics[index] line.append(str(i)) line.append(dma_metric['channel_id']) line.append( XBUtil.convert_size( int(dma_metric['host_to_card_bytes'], self.hexadecimal_converion))) line.append( XBUtil.convert_size( int(dma_metric['card_to_host_bytes'], self.hexadecimal_converion))) data.append(line) # If the index exceeds the input data size leave the for loop as everything is populated on the # last page else: break if (not data): XBUtil.print_warning(term, lock, start_y + offset, "Data unavailable") return offset + 1 table = XBUtil.Table(header, data, format) ascii_table = table.create_table() XBUtil.indented_print(term, lock, ascii_table, 3, start_y + offset) offset += len(ascii_table) return offset
def _print_mem_topology(self, term, lock, start_x, start_y, page): XBUtil.print_section_heading(term, lock, "Memory Topology", start_y) offset = 1 if self._df == None: print_warning(term, lock, start_y + offset, "Data unavailable. Acceleration image not loaded") return offset + 1 header = [ "", "Tag", "Type", "Temp (C)", "Size", "Mem Usage", "Utilization", "BO Count" ] format = [ "right", "left", "left", "right", "right", "right", "right", "right" ] data = [] memories = [] try: memories = self._df['board']['memory']['memories'] except: XBUtil.print_warning( term, lock, start_y + offset, "Data unavailable. Acceleration image not loaded") return offset + 1 for i in range(self.report_length): line = [] # The current data element to be parsed depends on what page has been requested index = i + (page * self.report_length) # Ensure that our index does not exceed the data size. This may happen on the last page if (index < len(memories)): line.append(str(index)) memory = memories[index] line.append(memory['tag']) line.append(memory['type']) line.append(memory['extended_info']['temperature_C'] if 'temperature_C' in memory['extended_info'] else "--") line.append( XBUtil.convert_size( int(memory['range_bytes'], self.hexadecimal_converion))) line.append( XBUtil.convert_size( int( memory['extended_info']['usage'] ['buffer_objects_count'], 0))) size = int(memory['range_bytes'], self.hexadecimal_converion) if size == 0 or memory['enabled'] == "false": line.append("-- ") else: usage = int( memory['extended_info']['usage']['allocated_bytes'], 0) line.append(XBUtil.get_percentage(usage, size)) line.append( memory['extended_info']['usage']['buffer_objects_count']) data.append(line) # If the index exceeds the input data size leave the for loop as everything is populated on the # last page else: break if (not data): XBUtil.print_warning(term, lock, start_y + offset, "Data unavailable") return offset + 1 table = XBUtil.Table(header, data, format) ascii_table = table.create_table() XBUtil.indented_print(term, lock, ascii_table, 3, start_y + offset) offset += len(ascii_table) return offset
def running_reports(term, lock, dev, x_len, y_len): global g_report_number global g_reports global g_page_number report_length = 0 report_start_row = 10 report_end_row = 10 # Number of lines above bottom of terminal. Must leave room for footer! num_lines_printed = 0 current_report = -1 current_page = -1 while True: global g_refresh_counter global g_refresh_rate g_refresh_counter += 1 page_count = 0 # Determine if our report has changed if (current_report != g_report_number) or (current_page != g_page_number): g_refresh_counter = 0 # Clear the previous reports XBUtil.clear_rows(term, lock, report_start_row, num_lines_printed) # Point to the next report if g_report_number < 0: g_report_number = len(g_reports) - 1 if g_report_number >= len(g_reports): g_report_number = 0 current_report = g_report_number report_length = y_len - report_start_row - report_end_row page_count = g_reports[current_report].update(dev, report_length) # Point to the next page if overflowing if g_page_number < 0: g_page_number = page_count - 1 if g_page_number >= page_count: g_page_number = 0 current_page = g_page_number # Update the report header on which report that is currently being displayed report_name = g_reports[current_report].report_name() report_header = "%s (%d/%d)" % (report_name, current_report + 1, len(g_reports)) page_header = "Page (%d/%d)" % (current_page + 1, page_count) print_header(term, lock, dev, report_header, page_header, x_len) # Just update the report if no changes have occurred else: page_count = g_reports[current_report].update(dev, report_length) # Clear the previous reports XBUtil.clear_rows(term, lock, report_start_row, num_lines_printed) num_lines_printed = g_reports[current_report].print_report(term, lock, 0, report_start_row, current_page) # Wait for either for the refresh time to expire or for a new report counter = 0 while counter < (g_refresh_rate * 4): # Note: The sleep time is 0.25 seconds, hence x4. counter += 1 if current_report != g_report_number: break time.sleep(0.25) # Check 4 times a second