Hello Gabriel

Just wondered if any further thoughts as how to resolve the CHI assertion error?

I have tried running the failing Parsec/Splash2 benchmarks and if I change to 
private L2 cache, then the tests pass. So the issue is definitely  related to 
the shared L2 cache implementation that I have added.

Furthermore, it is from the shared L2 cache controller that the assertion is 
firing.

Just thinking further, if the cache line is resident in an upstream cache (in 
state UC or UD) but not in the shared L2 cache (hence the final state being 
RU), this would imply that the L2$ is non-inclusive of the upstream L1 caches. 
Can you please confirm if this is the case?

Best regards
J.Osmany

_____________________________________________
From: Javed Osmany
Sent: 04 August 2021 08:38
To: gem5 users mailing list <gem5-users@gem5.org>
Cc: Gabriel Busnot <gabriel.bus...@arteris.com>; Javed Osmany 
<javed.osm...@huawei.com>
Subject: RE: [gem5-users] Re: CHI - Cluster CPUs having a shared L2 cache


Hello Gabriel

>> I would then suggest two non-tested options. You can assign the L2 
>> controller to cpu.l2 after registering it as downstream_components of l1i 
>> and l1d. Let's hope it will set the desired name.

I tried this but was unsuccessful, so have left it for the time being to make 
progress.

I have been trying to run the parsec benchmarks and a majority of them are 
failing due to an assertion firing from CHI-cache-actions.sm.  The assertion 
error being:

panic: Runtime Error at CHI-cache-actions.sm:2611: assert failure.

The system being modelled consists of 8 CPUs, partitioned into three clusters, 
where one of the clusters has shared L2 cache and the other two clusters have 
private L2 cache per CPU.

The command being used to run is (also in the attachment):

./build/ARM/gem5.opt --debug-flags=RubySlicc 
--outdir=m5out_parsec_lu_cb_struct1 configs/example/se_kirin_custom.py --ruby 
--topology=Pt2Pt --cpu-type=DerivO3CPU --num-cpus=8 --num-dirs=1 
--num-l3caches=1 --num-cpu-bigclust=1 --num-cpu-middleclust=1 
--num-cpu-littleclust=2 --num-clusters=3 --cpu-type-bigclust=derivo3 
--cpu-type-middleclust=derivo3 --cpu-type-littleclust=hpi 
--bigclust-l2cache=private --middleclust-l2cache=private 
--littleclust-l2cache=shared --num-bigclust-subclust=1 
--num-middleclust-subclust=2 --num-littleclust-subclust=2 
--num-cpu-bigclust-subclust2=1  --num-cpu-middleclust-subclust2=3 
--num-cpu-littleclust-subclust2=2 --big-cpu-clock=3GHz 
--middle-cpu-clock=2.6GHz --little-cpu-clock=2GHz --verbose=true 
--cmd=tests/parsec/splash2/lu_cb/splash2x.lu_cb.hooks -o " -p7 -n512 -b16"

The code in CHI-cache-actions.sm where the assertion is firing from is:

action(Finalize_UpdateCacheFromTBE, desc="") {
  assert(is_valid(tbe));
  State final := tbe.finalState;
  // JO
   DPRINTF(RubySlicc, "JO: CHI-cache-actions.sm: Final state value is %s\n", 
final);
  if ((final == State:UD_RSC) || (final == State:SD_RSC) || (final == 
State:UC_RSC) ||
      (final == State:SC_RSC) || (final == State:UD)     || (final == 
State:UD_T) ||
      (final == State:SD)     || (final == State:UC)     || (final == State:SC) 
||
      (final == State:UC_RU)  || (final == State:UD_RU)  || (final == 
State:UD_RSD) ||
      (final == State:SD_RSD)) {
    assert(tbe.dataBlkValid.isFull());
    assert(tbe.dataValid);
    assert(is_valid(cache_entry));
    cache_entry.DataBlk := tbe.dataBlk;
    DPRINTF(RubySlicc, "Cached data %s pfb %s\n", tbe.dataBlk, 
cache_entry.HWPrefetched);
  } else {
    // make sure only deallocate the cache entry if data is invalid
    assert(tbe.dataValid == false); <== This is the assertion which is firing.
    if (is_valid(cache_entry)) {
      cache.deallocate(address);
      unset_cache_entry();
    }
  }
}

I added a DPRINTF to check what the final state was before the assertion fires.
The final state being RU. This state is not encoded in the if (xxx) clause, 
hence we go the else clause and the assertion is firing.

21984560500: system.cpu2.l1i.downstream_destinations: 
CHI-cache-actions.sm:2598: JO: CHI-cache-actions.sm: Final state value is RU
panic: Runtime Error at CHI-cache-actions.sm:2611: assert failure.

The issue seems to be the final state, RU. The RU seems to be saying the state 
of the cache line in the upstream cache is unique, but it is not encoding the 
state of the cache line in the L2 cache.

Is this due to missing functionality in the SLICC encoding for CHI or is the 
shared L2$ implementation causing the problem?
Any pointers as how to resolve this assertion issue would be much appreciated.

I am attaching (as a winzip rar file) the updated CHI.py, CHI_config.py files. 
Also included is the custom version of the se.py used to run the test and the 
snippet of the trace file prior to the assertion firing when DPRINTF is enabled.

Best regards
J.Osmany


 << File: chi_parsec_splash2_lu_cb_shared_l2_assertion_error.rar >>
-----Original Message-----
From: Javed Osmany
Sent: 22 July 2021 11:52
To: 'gem5 users mailing list' <gem5-users@gem5.org>
Cc: Gabriel Busnot <gabriel.bus...@arteris.com>; Javed Osmany 
<javed.osm...@huawei.com>
Subject: RE: [gem5-users] Re: CHI - Cluster CPUs having a shared L2 cache

Hi Gabriel

Many thanks for your insight and input.

I have taken on board your suggestion and simplified the customisation of 
CHI.py and CHI_config.py by just using the CHI_Config.CHI_RNF() class object 
and adding another method to CHI_Config.CHI_RNF(), called addSharedL2Cache.

Also I have started testing with 1 cluster which contains 1 CPU and permutating 
with shared/private L2 cache.

>> I would then suggest two non-tested options. You can assign the L2 
>> controller to cpu.l2 after registering it as downstream_components of l1i 
>> and l1d. Let's hope it will set the desired name.

Will try this out.

Best regards
J.Osmany


-----Original Message-----
From: Gabriel Busnot via gem5-users [mailto:gem5-users@gem5.org]
Sent: 22 July 2021 08:40
To: gem5-users@gem5.org
Cc: Gabriel Busnot <gabriel.bus...@arteris.com>
Subject: [gem5-users] Re: CHI - Cluster CPUs having a shared L2 cache

Hi Javed,

Woops, I didn't see the split option in your first post. My bad.

I think the l2 is actually named "system.cpu0.l1i.downstream_destinations" and 
you will find it in the ini file. I think this is due to the way gem5 sets 
SimObject names. When you assign a SimObject to several object attributes 
(cpu.l2, cpu.l1i and finally cpu.l1d), it will have one of the names according 
to the complex SimObject and SimObjectVector logic. for some reason, it does 
not end up as a child of cpu0.l1d despite it being the last in the list. I am 
regularly fighting SimObject naming logic as well, that's normal ;)

Also check the warnings in the output. Some of them will warn you about 
SimObject reparenting. Sadly, SimObject name is determined by the attribute you 
set it to and you are not supposed to change it.

I would then suggest two non-tested options. You can assign the L2 controller 
to cpu.l2 after registering it as downstream_components of l1i and l1d. Let's 
hope it will set the desired name.
The other "last resort" option is to violate SimObject._name privacy and set it 
manually after the SimObject has been assigned for the last time... I would 
advise against that, though.

Whenever possible, it is actually best to assign a SimObject at the time of 
object creation and never assign it again afterwards... Not always possible, 
though. Also make use of "private" attributes (i.e., attributes with a name 
starting with '_') as much as possible. It bypasses the SimObject assignment 
logic and solves many issues.

Gabriel
_______________________________________________
gem5-users mailing list -- gem5-users@gem5.org To unsubscribe send an email to 
gem5-users-le...@gem5.org %(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

_______________________________________________
gem5-users mailing list -- gem5-users@gem5.org
To unsubscribe send an email to gem5-users-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to