configs, tests: Ruby.create_system cpus option

This patch is adding an extra parameter to the Ruby.create_system
function. The idea is to remove any assumption about cpu configuration
in the ruby scripts.

At the moment the scripts are assuming a flat list of cpu assigned
to the system object. Unfortunately this is not standardized, as
some systems might empoloy a different layout of cpus, like grouping
them in cluster objects.

With this patch we are allowing client scripts to provide the cpu list
as an extra argument

This has the extra benefit of removing the indexing hack

if len(system.cpu) == 1:

which was present in most scripts

Change-Id: Ibc06b920273cde4f7c394d61c0ca664a7143cd27
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/43287
Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
Giacomo Travaglini
2021-03-23 10:27:50 +00:00
parent 51c17ac398
commit 918a01f42e
14 changed files with 58 additions and 94 deletions

View File

@@ -97,7 +97,13 @@ system.clk_domain = SrcClockDomain(clock = options.sys_clock,
system.cpu = RubyDirectedTester(requests_to_complete = options.requests,
generator = generator)
Ruby.create_system(options, False, system)
# the ruby tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu
cpu_list = [ system.cpu ] * options.num_cpus
Ruby.create_system(options, False, system, cpus=cpu_list)
# Since Ruby runs at an independent frequency, create a seperate clock
system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,

View File

@@ -249,8 +249,15 @@ system.dma_devices = dma_devices
#
# Create the Ruby system
#
# the ruby tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu
cpu_list = [ system.cpu ] * options.num_cpus
Ruby.create_system(options = options, full_system = False,
system = system, dma_ports = system.dma_devices)
system = system, dma_ports = system.dma_devices,
cpus = cpu_list)
#
# The tester is most effective when randomization is turned on and

View File

@@ -103,7 +103,13 @@ system.voltage_domain = VoltageDomain(voltage = options.sys_voltage)
system.clk_domain = SrcClockDomain(clock = options.sys_clock,
voltage_domain = system.voltage_domain)
Ruby.create_system(options, False, system)
# the ruby tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu
cpu_list = [ system.cpu ] * options.num_cpus
Ruby.create_system(options, False, system, cpus=cpu_list)
# Create a seperate clock domain for Ruby
system.ruby.clk_domain = SrcClockDomain(clock = options.ruby_clock,

View File

@@ -646,7 +646,7 @@ def noc_params_from_config(config, noc_params):
def create_system(options, full_system, system, dma_ports, bootmem,
ruby_system):
ruby_system, cpus):
if buildEnv['PROTOCOL'] != 'CHI':
m5.panic("This script requires the CHI build")
@@ -721,10 +721,10 @@ def create_system(options, full_system, system, dma_ports, bootmem,
all_cntrls = []
# Creates on RNF per cpu with priv l2 caches
assert(len(system.cpu) == options.num_cpus)
assert(len(cpus) == options.num_cpus)
ruby_system.rnf = [ CHI_RNF([cpu], ruby_system, L1ICache, L1DCache,
system.cache_line_size.value)
for cpu in system.cpu ]
for cpu in cpus ]
for rnf in ruby_system.rnf:
rnf.addPrivL2Cache(L2Cache)
cpu_sequencers.extend(rnf.getSequencers())

View File

@@ -58,7 +58,7 @@ def define_options(parser):
return
def create_system(options, full_system, system, dma_ports, bootmem,
ruby_system):
ruby_system, cpus):
if buildEnv['PROTOCOL'] != 'MESI_Three_Level':
fatal("This script requires the MESI_Three_Level protocol to be\
@@ -108,17 +108,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
start_index_bit = block_size_bits,
replacement_policy = LRURP())
# the ruby random tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu; therefore if len(system.cpu) == 1
# we use system.cpu[0] to set the clk_domain, thereby ensuring
# we don't index off the end of the cpu list.
if len(system.cpu) == 1:
clk_domain = system.cpu[0].clk_domain
else:
clk_domain = system.cpu[i].clk_domain
clk_domain = cpus[i].clk_domain
# Ruby prefetcher
prefetcher = RubyPrefetcher(

View File

@@ -58,7 +58,7 @@ def define_options(parser):
return
def create_system(options, full_system, system, dma_ports, bootmem,
ruby_system):
ruby_system, cpus):
if buildEnv['PROTOCOL'] != 'MESI_Three_Level_HTM':
fatal("This script requires the MESI_Three_Level protocol to be\
@@ -108,17 +108,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
start_index_bit = block_size_bits,
replacement_policy = LRURP())
# the ruby random tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu; therefore if len(system.cpu) == 1
# we use system.cpu[0] to set the clk_domain, thereby ensuring
# we don't index off the end of the cpu list.
if len(system.cpu) == 1:
clk_domain = system.cpu[0].clk_domain
else:
clk_domain = system.cpu[i].clk_domain
clk_domain = cpus[i].clk_domain
# Ruby prefetcher
prefetcher = RubyPrefetcher(

View File

@@ -42,7 +42,7 @@ def define_options(parser):
return
def create_system(options, full_system, system, dma_ports, bootmem,
ruby_system):
ruby_system, cpus):
if buildEnv['PROTOCOL'] != 'MESI_Two_Level':
fatal("This script requires the MESI_Two_Level protocol to be built.")
@@ -80,17 +80,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
prefetcher = RubyPrefetcher()
# the ruby random tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu; therefore if len(system.cpu) == 1
# we use system.cpu[0] to set the clk_domain, thereby ensuring
# we don't index off the end of the cpu list.
if len(system.cpu) == 1:
clk_domain = system.cpu[0].clk_domain
else:
clk_domain = system.cpu[i].clk_domain
clk_domain = cpus[i].clk_domain
l1_cntrl = L1Cache_Controller(version = i, L1Icache = l1i_cache,
L1Dcache = l1d_cache,

View File

@@ -41,7 +41,7 @@ def define_options(parser):
return
def create_system(options, full_system, system, dma_ports, bootmem,
ruby_system):
ruby_system, cpus):
if buildEnv['PROTOCOL'] != 'MI_example':
panic("This script requires the MI_example protocol to be built.")
@@ -73,17 +73,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
start_index_bit = block_size_bits)
# the ruby random tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu; therefore if len(system.cpu) == 1
# we use system.cpu[0] to set the clk_domain, thereby ensuring
# we don't index off the end of the cpu list.
if len(system.cpu) == 1:
clk_domain = system.cpu[0].clk_domain
else:
clk_domain = system.cpu[i].clk_domain
clk_domain = cpus[i].clk_domain
# Only one unified L1 cache exists. Can cache instructions and data.
l1_cntrl = L1Cache_Controller(version=i, cacheMemory=cache,

View File

@@ -59,7 +59,7 @@ def define_options(parser):
return
def create_system(options, full_system, system, dma_ports, bootmem,
ruby_system):
ruby_system, cpus):
if buildEnv['PROTOCOL'] != 'MOESI_CMP_directory':
panic("This script requires the MOESI_CMP_directory protocol to be built.")
@@ -94,17 +94,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
start_index_bit = block_size_bits,
is_icache = False)
# the ruby random tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu; therefore if len(system.cpu) == 1
# we use system.cpu[0] to set the clk_domain, thereby ensuring
# we don't index off the end of the cpu list.
if len(system.cpu) == 1:
clk_domain = system.cpu[0].clk_domain
else:
clk_domain = system.cpu[i].clk_domain
clk_domain = cpus[i].clk_domain
l1_cntrl = L1Cache_Controller(version=i, L1Icache=l1i_cache,
L1Dcache=l1d_cache,

View File

@@ -49,7 +49,7 @@ def define_options(parser):
help="allow migratory sharing for atomic only accessed blocks")
def create_system(options, full_system, system, dma_ports, bootmem,
ruby_system):
ruby_system, cpus):
if buildEnv['PROTOCOL'] != 'MOESI_CMP_token':
panic("This script requires the MOESI_CMP_token protocol to be built.")
@@ -89,17 +89,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
assoc = options.l1d_assoc,
start_index_bit = block_size_bits)
# the ruby random tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu; therefore if len(system.cpu) == 1
# we use system.cpu[0] to set the clk_domain, thereby ensuring
# we don't index off the end of the cpu list.
if len(system.cpu) == 1:
clk_domain = system.cpu[0].clk_domain
else:
clk_domain = system.cpu[i].clk_domain
clk_domain = cpus[i].clk_domain
l1_cntrl = L1Cache_Controller(version=i, L1Icache=l1i_cache,
L1Dcache=l1d_cache,

View File

@@ -52,7 +52,7 @@ def define_options(parser):
help="Hammer: enable Full-bit Directory")
def create_system(options, full_system, system, dma_ports, bootmem,
ruby_system):
ruby_system, cpus):
if buildEnv['PROTOCOL'] != 'MOESI_hammer':
panic("This script requires the MOESI_hammer protocol to be built.")
@@ -88,17 +88,7 @@ def create_system(options, full_system, system, dma_ports, bootmem,
assoc = options.l2_assoc,
start_index_bit = block_size_bits)
# the ruby random tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu; therefore if len(system.cpu) == 1
# we use system.cpu[0] to set the clk_domain, thereby ensuring
# we don't index off the end of the cpu list.
if len(system.cpu) == 1:
clk_domain = system.cpu[0].clk_domain
else:
clk_domain = system.cpu[i].clk_domain
clk_domain = cpus[i].clk_domain
l1_cntrl = L1Cache_Controller(version=i, L1Icache=l1i_cache,
L1Dcache=l1d_cache, L2cache=l2_cache,

View File

@@ -172,7 +172,7 @@ def create_topology(controllers, options):
return topology
def create_system(options, full_system, system, piobus = None, dma_ports = [],
bootmem=None):
bootmem=None, cpus=None):
system.ruby = RubySystem()
ruby = system.ruby
@@ -185,12 +185,15 @@ def create_system(options, full_system, system, piobus = None, dma_ports = [],
Network.create_network(options, ruby)
ruby.network = network
if cpus is None:
cpus = system.cpu
protocol = buildEnv['PROTOCOL']
exec("from . import %s" % protocol)
try:
(cpu_sequencers, dir_cntrls, topology) = \
eval("%s.create_system(options, full_system, system, dma_ports,\
bootmem, ruby)"
bootmem, ruby, cpus)"
% protocol)
except:
print("Error: could not create sytem for ruby protocol %s" % protocol)

View File

@@ -100,7 +100,13 @@ system.clk_domain = SrcClockDomain(clock = '1GHz',
system.mem_ranges = AddrRange('256MB')
Ruby.create_system(options, False, system)
# the ruby tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu
cpu_list = [ system.cpu ] * options.num_cpus
Ruby.create_system(options, False, system, cpus=cpu_list)
# Create a separate clock domain for Ruby
system.ruby.clk_domain = SrcClockDomain(clock = '1GHz',

View File

@@ -80,7 +80,13 @@ system.clk_domain = SrcClockDomain(clock = '1GHz',
system.mem_ranges = AddrRange('256MB')
Ruby.create_system(options, False, system)
# the ruby tester reuses num_cpus to specify the
# number of cpu ports connected to the tester object, which
# is stored in system.cpu. because there is only ever one
# tester object, num_cpus is not necessarily equal to the
# size of system.cpu
cpu_list = [ system.cpu ] * options.num_cpus
Ruby.create_system(options, False, system, cpus=cpu_list)
# Create a separate clock domain for Ruby
system.ruby.clk_domain = SrcClockDomain(clock = '1GHz',