16821SN/A# Copyright (c) 2009 The Regents of The University of Michigan
28166SLisa.Hsu@amd.com# Copyright (c) 2011 Advanced Micro Devices, Inc.
39991Snilay@cs.wisc.edu# Copyright (c) 2013 Mark D. Hill and David A. Wood
46821SN/A# All rights reserved.
56821SN/A#
66821SN/A# Redistribution and use in source and binary forms, with or without
76821SN/A# modification, are permitted provided that the following conditions are
86821SN/A# met: redistributions of source code must retain the above copyright
96821SN/A# notice, this list of conditions and the following disclaimer;
106821SN/A# redistributions in binary form must reproduce the above copyright
116821SN/A# notice, this list of conditions and the following disclaimer in the
126821SN/A# documentation and/or other materials provided with the distribution;
136821SN/A# neither the name of the copyright holders nor the names of its
146821SN/A# contributors may be used to endorse or promote products derived from
156821SN/A# this software without specific prior written permission.
166821SN/A#
176821SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186821SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196821SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206821SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216821SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226821SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236821SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246821SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256821SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266821SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276821SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286821SN/A#
296821SN/A# Authors: Lisa Hsu
309991Snilay@cs.wisc.edu#          Nilay Vaish
316818SN/A
326818SN/Afrom ConfigParser import ConfigParser
336818SN/Aimport gzip
346818SN/A
359991Snilay@cs.wisc.eduimport sys, re, os
366818SN/A
376818SN/Aclass myCP(ConfigParser):
386818SN/A    def __init__(self):
396818SN/A        ConfigParser.__init__(self)
406818SN/A
416818SN/A    def optionxform(self, optionstr):
426818SN/A        return optionstr
436818SN/A
449991Snilay@cs.wisc.edudef aggregate(output_dir, cpts, no_compress, memory_size):
459991Snilay@cs.wisc.edu    merged_config = None
466818SN/A    page_ptr = 0
476818SN/A
489991Snilay@cs.wisc.edu    output_path = output_dir
499991Snilay@cs.wisc.edu    if not os.path.isdir(output_path):
509991Snilay@cs.wisc.edu        os.system("mkdir -p " + output_path)
516818SN/A
529991Snilay@cs.wisc.edu    agg_mem_file = open(output_path + "/system.physmem.store0.pmem", "wb+")
539991Snilay@cs.wisc.edu    agg_config_file = open(output_path + "/m5.cpt", "wb+")
546818SN/A
559991Snilay@cs.wisc.edu    if not no_compress:
569991Snilay@cs.wisc.edu        merged_mem = gzip.GzipFile(fileobj= agg_mem_file, mode="wb")
576818SN/A
586818SN/A    max_curtick = 0
599991Snilay@cs.wisc.edu    num_digits = len(str(len(cpts)-1))
609991Snilay@cs.wisc.edu
619991Snilay@cs.wisc.edu    for (i, arg) in enumerate(cpts):
627443SLisa.Hsu@amd.com        print arg
639991Snilay@cs.wisc.edu        merged_config = myCP()
646818SN/A        config = myCP()
656818SN/A        config.readfp(open(cpts[i] + "/m5.cpt"))
666818SN/A
676818SN/A        for sec in config.sections():
686818SN/A            if re.compile("cpu").search(sec):
699991Snilay@cs.wisc.edu                newsec = re.sub("cpu", "cpu" + str(i).zfill(num_digits), sec)
709991Snilay@cs.wisc.edu                merged_config.add_section(newsec)
716818SN/A
726818SN/A                items = config.items(sec)
739991Snilay@cs.wisc.edu                for item in items:
749991Snilay@cs.wisc.edu                    if item[0] == "paddr":
759991Snilay@cs.wisc.edu                        merged_config.set(newsec, item[0], int(item[1]) + (page_ptr << 12))
769991Snilay@cs.wisc.edu                        continue
779991Snilay@cs.wisc.edu                    merged_config.set(newsec, item[0], item[1])
789991Snilay@cs.wisc.edu
799991Snilay@cs.wisc.edu                if re.compile("workload.FdMap256$").search(sec):
809991Snilay@cs.wisc.edu                    merged_config.set(newsec, "M5_pid", i)
818166SLisa.Hsu@amd.com
826818SN/A            elif sec == "system":
836818SN/A                pass
846818SN/A            elif sec == "Globals":
856818SN/A                tick = config.getint(sec, "curTick")
866818SN/A                if tick > max_curtick:
876818SN/A                    max_curtick = tick
886818SN/A            else:
899991Snilay@cs.wisc.edu                if i == len(cpts)-1:
909991Snilay@cs.wisc.edu                    merged_config.add_section(sec)
916818SN/A                    for item in config.items(sec):
929991Snilay@cs.wisc.edu                        merged_config.set(sec, item[0], item[1])
936818SN/A
949991Snilay@cs.wisc.edu        if i != len(cpts)-1:
959991Snilay@cs.wisc.edu            merged_config.write(agg_config_file)
966818SN/A
976818SN/A        ### memory stuff
989991Snilay@cs.wisc.edu        pages = int(config.get("system", "pagePtr"))
999991Snilay@cs.wisc.edu        page_ptr = page_ptr + pages
1009991Snilay@cs.wisc.edu        print "pages to be read: ", pages
1019991Snilay@cs.wisc.edu
1029991Snilay@cs.wisc.edu        f = open(cpts[i] + "/system.physmem.store0.pmem", "rb")
1036818SN/A        gf = gzip.GzipFile(fileobj=f, mode="rb")
1046818SN/A
1057443SLisa.Hsu@amd.com        x = 0
1067443SLisa.Hsu@amd.com        while x < pages:
1079991Snilay@cs.wisc.edu            bytesRead = gf.read(1 << 12)
1089991Snilay@cs.wisc.edu            if not no_compress:
1099991Snilay@cs.wisc.edu                merged_mem.write(bytesRead)
1109991Snilay@cs.wisc.edu            else:
1119991Snilay@cs.wisc.edu                agg_mem_file.write(bytesRead)
1127443SLisa.Hsu@amd.com            x += 1
1136818SN/A
1146818SN/A        gf.close()
1156818SN/A        f.close()
1166818SN/A
1179991Snilay@cs.wisc.edu    merged_config.add_section("system")
1189991Snilay@cs.wisc.edu    merged_config.set("system", "pagePtr", page_ptr)
1199991Snilay@cs.wisc.edu    merged_config.set("system", "nextPID", len(cpts))
1209991Snilay@cs.wisc.edu
1219991Snilay@cs.wisc.edu    file_size = page_ptr * 4 * 1024
1229991Snilay@cs.wisc.edu    dummy_data = "".zfill(4096)
1239991Snilay@cs.wisc.edu    while file_size < memory_size:
1249991Snilay@cs.wisc.edu        if not no_compress:
1259991Snilay@cs.wisc.edu            merged_mem.write(dummy_data)
1269991Snilay@cs.wisc.edu        else:
1279991Snilay@cs.wisc.edu            agg_mem_file.write(dummy_data)
1289991Snilay@cs.wisc.edu        file_size += 4 * 1024
1299991Snilay@cs.wisc.edu        page_ptr += 1
1308166SLisa.Hsu@amd.com
1316818SN/A    print "WARNING: "
1328166SLisa.Hsu@amd.com    print "Make sure the simulation using this checkpoint has at least ",
1339991Snilay@cs.wisc.edu    print page_ptr, "x 4K of memory"
1349991Snilay@cs.wisc.edu    merged_config.set("system.physmem.store0", "range_size", page_ptr * 4 * 1024)
1356818SN/A
1369991Snilay@cs.wisc.edu    merged_config.add_section("Globals")
1379991Snilay@cs.wisc.edu    merged_config.set("Globals", "curTick", max_curtick)
1386818SN/A
1399991Snilay@cs.wisc.edu    merged_config.write(agg_config_file)
1406818SN/A
1419991Snilay@cs.wisc.edu    if not no_compress:
1429991Snilay@cs.wisc.edu        merged_mem.close()
1439991Snilay@cs.wisc.edu        agg_mem_file.close()
1449991Snilay@cs.wisc.edu    else:
1459991Snilay@cs.wisc.edu        agg_mem_file.close()
1466818SN/A
1476818SN/Aif __name__ == "__main__":
1489991Snilay@cs.wisc.edu    from argparse import ArgumentParser
1499991Snilay@cs.wisc.edu    parser = ArgumentParser("usage: %prog [options] <directory names which "\
1509991Snilay@cs.wisc.edu                            "hold the checkpoints to be combined>")
1519991Snilay@cs.wisc.edu    parser.add_argument("-o", "--output-dir", action="store",
1529991Snilay@cs.wisc.edu                        help="Output directory")
1539991Snilay@cs.wisc.edu    parser.add_argument("-c", "--no-compress", action="store_true")
1549991Snilay@cs.wisc.edu    parser.add_argument("--cpts", nargs='+')
1559991Snilay@cs.wisc.edu    parser.add_argument("--memory-size", action="store", type=int)
1566818SN/A
1579991Snilay@cs.wisc.edu    # Assume x86 ISA.  Any other ISAs would need extra stuff in this script
1589991Snilay@cs.wisc.edu    # to appropriately parse their page tables and understand page sizes.
1599991Snilay@cs.wisc.edu    options = parser.parse_args()
1609991Snilay@cs.wisc.edu    print options.cpts, len(options.cpts)
1619991Snilay@cs.wisc.edu    if len(options.cpts) <= 1:
1629991Snilay@cs.wisc.edu        parser.error("You must specify atleast two checkpoint files that "\
1639991Snilay@cs.wisc.edu                     "need to be combined.")
1646818SN/A
1659991Snilay@cs.wisc.edu    aggregate(options.output_dir, options.cpts, options.no_compress,
1669991Snilay@cs.wisc.edu              options.memory_size)
167