def __init__(self, ruby_system, ranges, mem_ctrls): if len(mem_ctrls) > 1: panic("the system can only have one memory control") self.version = versionCount() self.addr_ranges = ranges self.ruby_system = ruby_system self.directory = RubyDirectoryMemory() self.memory = mem_ctrls[0].port self.connectQueues(ruby_system)
def store_stat_value(stat, session, dumpCount): """ Stores the value of a stat. Args: stat: The stat itself. session: The session associated with the database. dumpCount: The number of dumps that have occured. Used to store multiple stats dumps in one database. """ if isinstance(stat, ScalarInfo): temp = ScalarValueClass(id = stat.id, dump = dumpCount, value = stat.value()) session.add(temp) elif isinstance(stat, VectorInfo) or isinstance(stat, FormulaInfo): temp = VectorValueClass(id = stat.id, dump = dumpCount, value = stat.result()) session.add(temp) elif isinstance(stat, Vector2dInfo): temp = VectorValueClass(id = stat.id, dump = dumpCount, value = stat.cvec) session.add(temp) elif isinstance(stat, DistInfo): import array data = stat.data temp = DistValueClass(id = stat.id, dump = dumpCount) temp.sum = data.sum temp.squares = data.squares temp.samples = data.samples if data.type == Dist or data.type == Hist: temp.min = data.min temp.max = data.max temp.bucket = data.bucket_size a = array.array('f', data.cvec) temp.vector = a.tostring() if data.type == Dist: temp.min_val = data.min_val temp.max_val = data.max_val temp.underflow = data.underflow temp.overflow = data.overflow session.add(temp) else: panic("Unable to output stat %s. Unsupported stat type!", stat)
def __init__(self, ruby_system, ranges, mem_ctrls): """ranges are the memory ranges assigned to this controller. """ if len(mem_ctrls) > 1: panic("This cache system can only be connected to one mem ctrl") super(DirController, self).__init__() self.version = self.versionCount() self.addr_ranges = ranges self.ruby_system = ruby_system self.directory = RubyDirectoryMemory() # Connect this directory to the memory side. self.memory_out_port = mem_ctrls[0].port self.connectQueues(ruby_system)
def __init__(self, ruby_system, ranges, mem_ctrls): """ranges are the memory ranges assigned to this controller. """ if len(mem_ctrls) > 1: panic("This cache system can only be connected to one mem ctrl") super(DirController, self).__init__() self.version = self.versionCount() self.addr_ranges = ranges self.ruby_system = ruby_system self.directory = RubyDirectoryMemory() # Connect this directory to the memory side. self.memory = mem_ctrls[0].port self.connectQueues(ruby_system)
def create_database(filename): """ Create the database used to store the stats. If it exists, delete it. Args: filename: The filename usd to store the stats. Return: A handle to the database. """ if os.path.exists(filename): os.remove(filename) try: db = create_engine('sqlite:///' + filename) except: panic("Failed to open database %s!", filename) db.echo = False return db
def getBlockSizeBits(self, system): bits = int(math.log(system.cache_line_size, 2)) if 2**bits != system.cache_line_size.value: panic("Cache line size not a power of 2!") return bits
# # Full system configuraiton for ruby # import os import optparse import sys from os.path import join as joinpath import m5 from m5.defines import buildEnv from m5.objects import * from m5.util import addToPath, panic if not buildEnv['FULL_SYSTEM']: panic("This script requires full-system mode (*_FS).") addToPath('../common') addToPath('../ruby') import Ruby from FSConfig import * from SysPaths import * from Benchmarks import * import Simulation from Caches import * # Get paths we might need. It's expected this file is in m5/configs/example. config_path = os.path.dirname(os.path.abspath(__file__)) config_root = os.path.dirname(config_path)
def __init__(self): if buildEnv['PROTOCOL'] != 'MSI': panic("This system assumes MSI to be the protocol") super(MyCacheSystem, self).__init__()
# Simple test script # # "m5 test.py" import os import optparse import sys from os.path import join as joinpath import m5 from m5.defines import buildEnv from m5.objects import * from m5.util import addToPath, panic if buildEnv['FULL_SYSTEM']: panic("This script requires syscall emulation mode (*_SE).") addToPath('../common') addToPath('../ruby') import Ruby import Simulation from cpu2000 import * # Get paths we might need. It's expected this file is in m5/configs/example. config_path = os.path.dirname(os.path.abspath(__file__)) config_root = os.path.dirname(config_path) m5_root = os.path.dirname(config_root) parser = optparse.OptionParser()
def makeGpuFSSystem(args): # Boot options are standard gem5 options plus: # - Framebuffer device emulation 0 to reduce driver code paths. # - Blacklist amdgpu as it cannot (currently) load in KVM CPU. # - Blacklist psmouse as amdgpu driver adds proprietary commands that # cause gem5 to panic. boot_options = ['earlyprintk=ttyS0', 'console=ttyS0,9600', 'lpj=7999923', 'root=/dev/sda1', 'drm_kms_helper.fbdev_emulation=0', 'modprobe.blacklist=amdgpu', 'modprobe.blacklist=psmouse'] cmdline = ' '.join(boot_options) if MemorySize(args.mem_size) < MemorySize('2GB'): panic("Need at least 2GB of system memory to load amdgpu module") # Use the common FSConfig to setup a Linux X86 System (TestCPUClass, test_mem_mode, FutureClass) = Simulation.setCPUClass(args) bm = SysConfig(disks=[args.disk_image], mem=args.mem_size) system = makeLinuxX86System(test_mem_mode, args.num_cpus, bm, True, cmdline=cmdline) system.workload.object_file = binary(args.kernel) # Set the cache line size for the entire system. system.cache_line_size = args.cacheline_size # Create a top-level voltage and clock domain. system.voltage_domain = VoltageDomain(voltage = args.sys_voltage) system.clk_domain = SrcClockDomain(clock = args.sys_clock, voltage_domain = system.voltage_domain) # Create a CPU voltage and clock domain. system.cpu_voltage_domain = VoltageDomain() system.cpu_clk_domain = SrcClockDomain(clock = args.cpu_clock, voltage_domain = system.cpu_voltage_domain) # Setup VGA ROM region system.shadow_rom_ranges = [AddrRange(0xc0000, size = Addr('128kB'))] # Create specified number of CPUs. GPUFS really only needs one. system.cpu = [TestCPUClass(clk_domain=system.cpu_clk_domain, cpu_id=i) for i in range(args.num_cpus)] if ObjectList.is_kvm_cpu(TestCPUClass) or \ ObjectList.is_kvm_cpu(FutureClass): system.kvm_vm = KvmVM() # Create AMDGPU and attach to southbridge shader = createGPU(system, args) connectGPU(system, args) # This arbitrary address is something in the X86 I/O hole hsapp_gpu_map_paddr = 0xe00000000 gpu_hsapp = HSAPacketProcessor(pioAddr=hsapp_gpu_map_paddr, numHWQueues=args.num_hw_queues) dispatcher = GPUDispatcher() gpu_cmd_proc = GPUCommandProcessor(hsapp=gpu_hsapp, dispatcher=dispatcher) shader.dispatcher = dispatcher shader.gpu_cmd_proc = gpu_cmd_proc # GPU, HSAPP, and GPUCommandProc are DMA devices system._dma_ports.append(gpu_hsapp) system._dma_ports.append(gpu_cmd_proc) system._dma_ports.append(system.pc.south_bridge.gpu) gpu_hsapp.pio = system.iobus.mem_side_ports gpu_cmd_proc.pio = system.iobus.mem_side_ports system.pc.south_bridge.gpu.pio = system.iobus.mem_side_ports # Create Ruby system using Ruby.py for now Ruby.create_system(args, True, system, system.iobus, system._dma_ports) # Create a seperate clock domain for Ruby system.ruby.clk_domain = SrcClockDomain(clock = args.ruby_clock, voltage_domain = system.voltage_domain) for (i, cpu) in enumerate(system.cpu): # # Tie the cpu ports to the correct ruby system ports # cpu.clk_domain = system.cpu_clk_domain cpu.createThreads() cpu.createInterruptController() system.ruby._cpu_ports[i].connectCpuPorts(cpu) # The shader core will be whatever is after the CPU cores are accounted for shader_idx = args.num_cpus system.cpu.append(shader) gpu_port_idx = len(system.ruby._cpu_ports) \ - args.num_compute_units - args.num_sqc \ - args.num_scalar_cache gpu_port_idx = gpu_port_idx - args.num_cp * 2 # Connect token ports. For this we need to search through the list of all # sequencers, since the TCP coalescers will not necessarily be first. Only # TCP coalescers use a token port for back pressure. token_port_idx = 0 for i in range(len(system.ruby._cpu_ports)): if isinstance(system.ruby._cpu_ports[i], VIPERCoalescer): system.cpu[shader_idx].CUs[token_port_idx].gmTokenPort = \ system.ruby._cpu_ports[i].gmTokenPort token_port_idx += 1 wavefront_size = args.wf_size for i in range(args.num_compute_units): # The pipeline issues wavefront_size number of uncoalesced requests # in one GPU issue cycle. Hence wavefront_size mem ports. for j in range(wavefront_size): system.cpu[shader_idx].CUs[i].memory_port[j] = \ system.ruby._cpu_ports[gpu_port_idx].in_ports[j] gpu_port_idx += 1 for i in range(args.num_compute_units): if i > 0 and not i % args.cu_per_sqc: gpu_port_idx += 1 system.cpu[shader_idx].CUs[i].sqc_port = \ system.ruby._cpu_ports[gpu_port_idx].in_ports gpu_port_idx = gpu_port_idx + 1 for i in range(args.num_compute_units): if i > 0 and not i % args.cu_per_scalar_cache: gpu_port_idx += 1 system.cpu[shader_idx].CUs[i].scalar_port = \ system.ruby._cpu_ports[gpu_port_idx].in_ports gpu_port_idx = gpu_port_idx + 1 return system