# Copyright (c) 2021 The Regents of the University of California
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""
A run script for running the parsec benchmark suite in gem5.

Notes
-----

* This will download the PARSEC disk image if not found locally. This image is
  8 GB compressed, and 25 GB decompressed.
* This will only function for the X86 ISA.
"""

import m5.stats

from gem5.resources.resource import Resource
from gem5.components.boards.x86_board import X86Board
from gem5.components.memory import SingleChannelDDR3_1600
from gem5.components.processors.simple_switchable_processor import (
    SimpleSwitchableProcessor,
)
from gem5.components.processors.cpu_types import (
    get_cpu_types_str_set,
    get_cpu_type_from_str,
)
from gem5.isas import ISA
from gem5.runtime import get_runtime_isa, get_runtime_coherence_protocol
from gem5.simulate.simulator import Simulator
from gem5.simulate.exit_event import ExitEvent
from gem5.utils.requires import requires

import time
import argparse

requires(isa_required=ISA.X86)


parser = argparse.ArgumentParser(
    description="A script to run the PARSEC benchmarks on a basic X86 full "
    "system."
)

parser.add_argument(
    "-n",
    "--num-cpus",
    type=int,
    choices=(1, 2, 8),
    required=True,
    help="The number of CPUs. Note: 1, 2, and 8 cores supported on KVM; 1 and "
    "2 supported on TimingSimpleCPU.",
)

parser.add_argument(
    "-b",
    "--boot-cpu",
    type=str,
    choices=get_cpu_types_str_set(),
    required=False,
    help="The CPU type to run before and after the ROI. If not specified will "
    "be equal to that of the CPU type used in the ROI.",
)

parser.add_argument(
    "-c",
    "--cpu",
    type=str,
    choices=get_cpu_types_str_set(),
    required=True,
    help="The CPU type used in the ROI.",
)

parser.add_argument(
    "-m",
    "--mem-system",
    type=str,
    choices=("classic", "mesi_two_level"),
    required=True,
    help="The memory system to be used",
)

parser.add_argument(
    "-e",
    "--benchmark",
    type=str,
    choices=(
        "blackscholes",
        "bodytrack",
        "canneal",
        "dedup",
        "facesim",
        "ferret",
        "fluidanimate",
        "freqmine",
        "raytrace",
        "streamcluster",
        "swaptions",
        "vips",
        "x264",
    ),
    required=True,
    help="The PARSEC benchmark to run.",
)

parser.add_argument(
    "-s",
    "--size",
    type=str,
    choices=("simsmall", "simmedium", "simlarge"),
    required=True,
    help="The size of the PARSEC benchmark input size.",
)

parser.add_argument(
    "-r",
    "--resource-directory",
    type=str,
    required=False,
    help="The directory in which resources will be downloaded or exist.",
)

args = parser.parse_args()

# Setup the cachie hierarchy.

if args.mem_system == "classic":

    from gem5.components.cachehierarchies.classic.private_l1_private_l2_cache_hierarchy import (
        PrivateL1PrivateL2CacheHierarchy,
    )

    cache_hierarchy = PrivateL1PrivateL2CacheHierarchy(
        l1d_size="32kB", l1i_size="32kB", l2_size="256kB"
    )
elif args.mem_system == "mesi_two_level":
    from gem5.components.cachehierarchies.ruby.mesi_two_level_cache_hierarchy import (
        MESITwoLevelCacheHierarchy,
    )

    cache_hierarchy = MESITwoLevelCacheHierarchy(
        l1i_size="32kB",
        l1i_assoc=8,
        l1d_size="32kB",
        l1d_assoc=8,
        l2_size="256kB",
        l2_assoc=16,
        num_l2_banks=1,
    )

# Setup the memory system.
memory = SingleChannelDDR3_1600(size="3GB")

roi_type = get_cpu_type_from_str(args.cpu)
if args.boot_cpu != None:
    boot_type = get_cpu_type_from_str(args.boot_cpu)
else:
    boot_type = roi_type


processor = SimpleSwitchableProcessor(
    starting_core_type=boot_type,
    switch_core_type=roi_type,
    isa=ISA.X86,
    num_cores=args.num_cpus,
)

# Setup the board.
board = X86Board(
    clk_freq="3GHz",
    processor=processor,
    memory=memory,
    cache_hierarchy=cache_hierarchy,
)

# The command to run.
command = (
    "cd /home/gem5/parsec-benchmark\n"
    + "source env.sh\n"
    + "parsecmgmt -a run -p {} ".format(args.benchmark)
    + "-c gcc-hooks -i {} ".format(args.size)
    + "-n {}\n".format(str(args.num_cpus))
)

board.set_kernel_disk_workload(
    kernel=Resource(
        "x86-linux-kernel-5.4.49", resource_directory=args.resource_directory
    ),
    disk_image=Resource(
        "x86-parsec", resource_directory=args.resource_directory
    ),
    readfile_contents=command,
)

# Here we define some custom workbegin/workend exit event generators. Here we
# want to switch to detailed CPUs at the beginning of the ROI, then continue to
# the end of of the ROI. Then we exit the simulation.
def workbegin():
    processor.switch()
    yield False


def workend():
    yield True


simulator = Simulator(
    board=board,
    on_exit_event={
        ExitEvent.WORKBEGIN: workbegin(),
        ExitEvent.WORKEND: workend(),
    },
)

global_start = time.time()
simulator.run()
global_end = time.time()
global_time = global_end - global_start

roi_ticks = simulator.get_roi_ticks()
assert len(roi_ticks) == 1


print("Done running the simulation")
print()
print("Performance statistics:")

print("Simulated time in ROI: {}s".format((roi_ticks[0]) / 1e12))
print(
    "Ran a total of {} simulated seconds".format(
        simulator.get_current_tick() / 1e12
    )
)
print(
    "Total wallclock time: {}s, {} min".format(global_time, (global_time) / 60)
)
