110152Satgutier@umich.edu/*****************************************************************************
210152Satgutier@umich.edu *                                McPAT
310152Satgutier@umich.edu *                      SOFTWARE LICENSE AGREEMENT
410152Satgutier@umich.edu *            Copyright 2012 Hewlett-Packard Development Company, L.P.
510234Syasuko.eckert@amd.com *            Copyright (c) 2010-2013 Advanced Micro Devices, Inc.
610152Satgutier@umich.edu *                          All Rights Reserved
710152Satgutier@umich.edu *
810152Satgutier@umich.edu * Redistribution and use in source and binary forms, with or without
910152Satgutier@umich.edu * modification, are permitted provided that the following conditions are
1010152Satgutier@umich.edu * met: redistributions of source code must retain the above copyright
1110152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer;
1210152Satgutier@umich.edu * redistributions in binary form must reproduce the above copyright
1310152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the
1410152Satgutier@umich.edu * documentation and/or other materials provided with the distribution;
1510152Satgutier@umich.edu * neither the name of the copyright holders nor the names of its
1610152Satgutier@umich.edu * contributors may be used to endorse or promote products derived from
1710152Satgutier@umich.edu * this software without specific prior written permission.
1810152Satgutier@umich.edu
1910152Satgutier@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2010152Satgutier@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2110152Satgutier@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2210152Satgutier@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2310152Satgutier@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2410152Satgutier@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2510152Satgutier@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2610152Satgutier@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2710152Satgutier@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2810152Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2910234Syasuko.eckert@amd.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3010152Satgutier@umich.edu *
3110152Satgutier@umich.edu ***************************************************************************/
3210152Satgutier@umich.edu
3310152Satgutier@umich.edu#include <cassert>
3410152Satgutier@umich.edu#include <cmath>
3510152Satgutier@umich.edu#include <iostream>
3610152Satgutier@umich.edu
3710152Satgutier@umich.edu#include "basic_components.h"
3810234Syasuko.eckert@amd.com#include "cacheunit.h"
3910234Syasuko.eckert@amd.com#include "common.h"
4010234Syasuko.eckert@amd.com
4110234Syasuko.eckert@amd.com// Turn this to true to get debugging messages
4210234Syasuko.eckert@amd.combool McPATComponent::debug = false;
4310234Syasuko.eckert@amd.com
4410234Syasuko.eckert@amd.combool McPATComponent::opt_for_clk = true;
4510234Syasuko.eckert@amd.comint McPATComponent::longer_channel_device = 0;
4610234Syasuko.eckert@amd.com// Number of cycles per second, 2GHz = 2e9
4710234Syasuko.eckert@amd.comdouble McPATComponent::target_core_clockrate = 2e9;
4810234Syasuko.eckert@amd.comdouble McPATComponent::total_cycles = 0.0f;
4910234Syasuko.eckert@amd.comdouble McPATComponent::execution_time = 0.0f;
5010234Syasuko.eckert@amd.comint McPATComponent::physical_address_width = 0;
5110234Syasuko.eckert@amd.comint McPATComponent::virtual_address_width = 0;
5210234Syasuko.eckert@amd.comint McPATComponent::virtual_memory_page_size = 0;
5310234Syasuko.eckert@amd.comint McPATComponent::data_path_width = 0;
5410234Syasuko.eckert@amd.com
5510234Syasuko.eckert@amd.comvoid McPATOutput::reset() {
5610234Syasuko.eckert@amd.com    storage = 0.0;
5710234Syasuko.eckert@amd.com    area = 0.0;
5810234Syasuko.eckert@amd.com    peak_dynamic_power = 0.0;
5910234Syasuko.eckert@amd.com    subthreshold_leakage_power = 0.0;
6010234Syasuko.eckert@amd.com    gate_leakage_power = 0.0;
6110234Syasuko.eckert@amd.com    runtime_dynamic_energy = 0.0;
6210234Syasuko.eckert@amd.com}
6310234Syasuko.eckert@amd.com
6410234Syasuko.eckert@amd.comMcPATOutput operator+(const McPATOutput &lhs, const McPATOutput &rhs) {
6510234Syasuko.eckert@amd.com    McPATOutput to_return;
6610234Syasuko.eckert@amd.com    to_return.storage = lhs.storage + rhs.storage;
6710234Syasuko.eckert@amd.com    to_return.area = lhs.area + rhs.area;
6810234Syasuko.eckert@amd.com    to_return.peak_dynamic_power = lhs.peak_dynamic_power +
6910234Syasuko.eckert@amd.com        rhs.peak_dynamic_power;
7010234Syasuko.eckert@amd.com    to_return.subthreshold_leakage_power = lhs.subthreshold_leakage_power +
7110234Syasuko.eckert@amd.com        rhs.subthreshold_leakage_power;
7210234Syasuko.eckert@amd.com    to_return.gate_leakage_power = lhs.gate_leakage_power +
7310234Syasuko.eckert@amd.com        rhs.gate_leakage_power;
7410234Syasuko.eckert@amd.com    to_return.runtime_dynamic_energy = lhs.runtime_dynamic_energy +
7510234Syasuko.eckert@amd.com        rhs.runtime_dynamic_energy;
7610234Syasuko.eckert@amd.com    return to_return;
7710234Syasuko.eckert@amd.com}
7810234Syasuko.eckert@amd.com
7910234Syasuko.eckert@amd.comvoid McPATOutput::operator+=(const McPATOutput &rhs) {
8010234Syasuko.eckert@amd.com    storage += rhs.storage;
8110234Syasuko.eckert@amd.com    area += rhs.area;
8210234Syasuko.eckert@amd.com    peak_dynamic_power += rhs.peak_dynamic_power;
8310234Syasuko.eckert@amd.com    subthreshold_leakage_power += rhs.subthreshold_leakage_power;
8410234Syasuko.eckert@amd.com    gate_leakage_power += rhs.gate_leakage_power;
8510234Syasuko.eckert@amd.com    runtime_dynamic_energy += rhs.runtime_dynamic_energy;
8610234Syasuko.eckert@amd.com}
8710234Syasuko.eckert@amd.com
8810234Syasuko.eckert@amd.comMcPATComponent::McPATComponent()
8910234Syasuko.eckert@amd.com        : xml_data(NULL), name("") {
9010234Syasuko.eckert@amd.com}
9110234Syasuko.eckert@amd.com
9210234Syasuko.eckert@amd.comMcPATComponent::McPATComponent(XMLNode* _xml_data)
9310234Syasuko.eckert@amd.com        : xml_data(_xml_data), name("") {
9410234Syasuko.eckert@amd.com}
9510234Syasuko.eckert@amd.com
9610234Syasuko.eckert@amd.comMcPATComponent::McPATComponent(XMLNode* _xml_data,
9710234Syasuko.eckert@amd.com                               InputParameter* _interface_ip)
9810234Syasuko.eckert@amd.com        : xml_data(_xml_data), interface_ip(*_interface_ip), name("") {
9910234Syasuko.eckert@amd.com}
10010234Syasuko.eckert@amd.com
10110234Syasuko.eckert@amd.comMcPATComponent::~McPATComponent() {
10210234Syasuko.eckert@amd.com}
10310234Syasuko.eckert@amd.com
10410234Syasuko.eckert@amd.comvoid McPATComponent::recursiveInstantiate() {
10510234Syasuko.eckert@amd.com    if (debug) {
10610234Syasuko.eckert@amd.com        fprintf(stderr, "WARNING: Called recursiveInstantiate from %s, with ",
10710234Syasuko.eckert@amd.com                "'type' %s\n", name.c_str(), xml_data->getAttribute("type"));
10810234Syasuko.eckert@amd.com    }
10910234Syasuko.eckert@amd.com    int i;
11010234Syasuko.eckert@amd.com    int numChildren = xml_data->nChildNode("component");
11110234Syasuko.eckert@amd.com    for (i = 0; i < numChildren; i++ ) {
11210234Syasuko.eckert@amd.com        // For each child node of the system,
11310234Syasuko.eckert@amd.com        XMLNode* childXML = xml_data->getChildNodePtr("component", &i);
11410234Syasuko.eckert@amd.com        XMLCSTR type = childXML->getAttribute("type");
11510234Syasuko.eckert@amd.com
11610234Syasuko.eckert@amd.com        if (!type)
11710234Syasuko.eckert@amd.com            warnMissingComponentType(childXML->getAttribute("id"));
11810234Syasuko.eckert@amd.com
11910234Syasuko.eckert@amd.com        STRCMP(type, "Core")
12010234Syasuko.eckert@amd.com            warnIncompleteComponentType(type);
12110234Syasuko.eckert@amd.com        STRCMP(type, "CacheUnit")
12210234Syasuko.eckert@amd.com            children.push_back(new CacheUnit(childXML, &interface_ip));
12310234Syasuko.eckert@amd.com        STRCMP(type, "CacheController")
12410234Syasuko.eckert@amd.com            warnIncompleteComponentType(type);
12510234Syasuko.eckert@amd.com        STRCMP(type, "MemoryController")
12610234Syasuko.eckert@amd.com            warnIncompleteComponentType(type);
12710234Syasuko.eckert@amd.com        STRCMP(type, "Memory")
12810234Syasuko.eckert@amd.com            warnIncompleteComponentType(type);
12910234Syasuko.eckert@amd.com        STRCMP(type, "OnChipNetwork")
13010234Syasuko.eckert@amd.com            warnIncompleteComponentType(type);
13110234Syasuko.eckert@amd.com        STRCMP(type, "BusInterconnect")
13210234Syasuko.eckert@amd.com            warnIncompleteComponentType(type);
13310234Syasuko.eckert@amd.com        STRCMP(type, "Directory")
13410234Syasuko.eckert@amd.com            warnIncompleteComponentType(type);
13510234Syasuko.eckert@amd.com
13610234Syasuko.eckert@amd.com        else
13710234Syasuko.eckert@amd.com            warnUnrecognizedComponent(type);
13810234Syasuko.eckert@amd.com    }
13910234Syasuko.eckert@amd.com}
14010234Syasuko.eckert@amd.com
14110234Syasuko.eckert@amd.comvoid McPATComponent::computeArea() {
14210234Syasuko.eckert@amd.com    if (debug) {
14310234Syasuko.eckert@amd.com        fprintf(stderr, "WARNING: Called computeArea from %s, with 'type' ",
14410234Syasuko.eckert@amd.com                "%s\n", name.c_str(), xml_data->getAttribute("type"));
14510234Syasuko.eckert@amd.com    }
14610234Syasuko.eckert@amd.com
14710234Syasuko.eckert@amd.com    // TODO: This calculation is incorrect and is overwritten by computeEnergy
14810234Syasuko.eckert@amd.com    // Fix it up so that the values are available at the correct times
14910234Syasuko.eckert@amd.com    int i;
15010234Syasuko.eckert@amd.com    int numChildren = children.size();
15110234Syasuko.eckert@amd.com    area.set_area(0.0);
15210234Syasuko.eckert@amd.com    output_data.area = 0.0;
15310234Syasuko.eckert@amd.com    for (i = 0; i < numChildren; i++) {
15410234Syasuko.eckert@amd.com        children[i]->computeArea();
15510234Syasuko.eckert@amd.com        output_data.area += area.get_area();
15610234Syasuko.eckert@amd.com    }
15710234Syasuko.eckert@amd.com}
15810234Syasuko.eckert@amd.com
15910234Syasuko.eckert@amd.comvoid McPATComponent::computeEnergy() {
16010234Syasuko.eckert@amd.com    if (debug) {
16110234Syasuko.eckert@amd.com        fprintf(stderr, "WARNING: Called computeEnergy from %s, with 'type' ",
16210234Syasuko.eckert@amd.com                "%s\n", name.c_str(), xml_data->getAttribute("type"));
16310234Syasuko.eckert@amd.com    }
16410234Syasuko.eckert@amd.com
16510234Syasuko.eckert@amd.com    power.reset();
16610234Syasuko.eckert@amd.com    rt_power.reset();
16710234Syasuko.eckert@amd.com    memset(&output_data, 0, sizeof(McPATOutput));
16810234Syasuko.eckert@amd.com    int i;
16910234Syasuko.eckert@amd.com    int numChildren = children.size();
17010234Syasuko.eckert@amd.com    for (i = 0; i < numChildren; i++) {
17110234Syasuko.eckert@amd.com        children[i]->computeEnergy();
17210234Syasuko.eckert@amd.com        output_data += children[i]->output_data;
17310234Syasuko.eckert@amd.com    }
17410234Syasuko.eckert@amd.com}
17510234Syasuko.eckert@amd.com
17610234Syasuko.eckert@amd.comvoid McPATComponent::displayData(uint32_t indent, int plevel) {
17710234Syasuko.eckert@amd.com    if (debug) {
17810234Syasuko.eckert@amd.com        fprintf(stderr, "WARNING: Called displayData from %s, with 'type' ",
17910234Syasuko.eckert@amd.com                "%s\n", name.c_str(), xml_data->getAttribute("type"));
18010234Syasuko.eckert@amd.com    }
18110234Syasuko.eckert@amd.com
18210234Syasuko.eckert@amd.com    string indent_str(indent, ' ');
18310234Syasuko.eckert@amd.com    string indent_str_next(indent + 2, ' ');
18410234Syasuko.eckert@amd.com
18510234Syasuko.eckert@amd.com    double leakage_power = output_data.subthreshold_leakage_power +
18610234Syasuko.eckert@amd.com        output_data.gate_leakage_power;
18710234Syasuko.eckert@amd.com    double total_runtime_energy = output_data.runtime_dynamic_energy +
18810234Syasuko.eckert@amd.com        leakage_power * execution_time;
18910234Syasuko.eckert@amd.com    cout << indent_str << name << ":" << endl;
19010234Syasuko.eckert@amd.com    cout << indent_str_next << "Area = " << output_data.area << " mm^2"
19110234Syasuko.eckert@amd.com         << endl;
19210234Syasuko.eckert@amd.com    cout << indent_str_next << "Peak Dynamic Power = "
19310234Syasuko.eckert@amd.com         << output_data.peak_dynamic_power << " W" << endl;
19410234Syasuko.eckert@amd.com    cout << indent_str_next << "Subthreshold Leakage Power = "
19510234Syasuko.eckert@amd.com         << output_data.subthreshold_leakage_power << " W" << endl;
19610234Syasuko.eckert@amd.com    cout << indent_str_next << "Gate Leakage Power = "
19710234Syasuko.eckert@amd.com         << output_data.gate_leakage_power << " W" << endl;
19810234Syasuko.eckert@amd.com    cout << indent_str_next << "Runtime Dynamic Power = "
19910234Syasuko.eckert@amd.com         << (output_data.runtime_dynamic_energy / execution_time) << " W"
20010234Syasuko.eckert@amd.com         << endl;
20110234Syasuko.eckert@amd.com    cout << indent_str_next << "Runtime Dynamic Energy = "
20210234Syasuko.eckert@amd.com         << output_data.runtime_dynamic_energy << " J" << endl;
20310234Syasuko.eckert@amd.com    cout << indent_str_next << "Total Runtime Energy = "
20410234Syasuko.eckert@amd.com         << total_runtime_energy << " J" << endl;
20510234Syasuko.eckert@amd.com    cout << endl;
20610234Syasuko.eckert@amd.com
20710234Syasuko.eckert@amd.com    // Recursively print children
20810234Syasuko.eckert@amd.com    int i;
20910234Syasuko.eckert@amd.com    int numChildren = children.size();
21010234Syasuko.eckert@amd.com    for (i = 0; i < numChildren; i++) {
21110234Syasuko.eckert@amd.com        children[i]->displayData(indent + 4, plevel);
21210234Syasuko.eckert@amd.com    }
21310234Syasuko.eckert@amd.com}
21410234Syasuko.eckert@amd.com
21510234Syasuko.eckert@amd.comvoid McPATComponent::errorUnspecifiedParam(string param) {
21610234Syasuko.eckert@amd.com    fprintf(stderr, "ERROR: Parameter must be specified in %s: %s\n",
21710234Syasuko.eckert@amd.com            name.c_str(), param.c_str());
21810234Syasuko.eckert@amd.com    exit(1);
21910234Syasuko.eckert@amd.com}
22010234Syasuko.eckert@amd.com
22110234Syasuko.eckert@amd.comvoid McPATComponent::errorNonPositiveParam(string param) {
22210234Syasuko.eckert@amd.com    fprintf(stderr, "ERROR: Parameter must be positive in %s: %s\n",
22310234Syasuko.eckert@amd.com            name.c_str(), param.c_str());
22410234Syasuko.eckert@amd.com    exit(1);
22510234Syasuko.eckert@amd.com}
22610234Syasuko.eckert@amd.com
22710234Syasuko.eckert@amd.comvoid McPATComponent::warnUnrecognizedComponent(XMLCSTR component) {
22810234Syasuko.eckert@amd.com    fprintf(stderr, "WARNING: Component type not recognized in %s: %s\n",
22910234Syasuko.eckert@amd.com            name.c_str(), component);
23010234Syasuko.eckert@amd.com}
23110234Syasuko.eckert@amd.com
23210234Syasuko.eckert@amd.comvoid McPATComponent::warnUnrecognizedParam(XMLCSTR param) {
23310234Syasuko.eckert@amd.com    fprintf(stderr, "WARNING: Parameter not recognized in %s: %s\n",
23410234Syasuko.eckert@amd.com            name.c_str(), param);
23510234Syasuko.eckert@amd.com}
23610234Syasuko.eckert@amd.com
23710234Syasuko.eckert@amd.comvoid McPATComponent::warnUnrecognizedStat(XMLCSTR stat) {
23810234Syasuko.eckert@amd.com    fprintf(stderr, "WARNING: Statistic not recognized in %s: %s\n",
23910234Syasuko.eckert@amd.com            name.c_str(), stat);
24010234Syasuko.eckert@amd.com}
24110234Syasuko.eckert@amd.com
24210234Syasuko.eckert@amd.comvoid McPATComponent::warnIncompleteComponentType(XMLCSTR type) {
24310234Syasuko.eckert@amd.com    fprintf(stderr, "  WARNING: %s handling not yet complete\n", type);
24410234Syasuko.eckert@amd.com}
24510234Syasuko.eckert@amd.com
24610234Syasuko.eckert@amd.comvoid McPATComponent::warnMissingComponentType(XMLCSTR id) {
24710234Syasuko.eckert@amd.com    if (id) {
24810234Syasuko.eckert@amd.com        fprintf(stderr,
24910234Syasuko.eckert@amd.com                "WARNING: Ignoring a component due to the missing type: %s\n",
25010234Syasuko.eckert@amd.com                id);
25110234Syasuko.eckert@amd.com    } else {
25210234Syasuko.eckert@amd.com        fprintf(stderr,
25310234Syasuko.eckert@amd.com                "WARNING: Ignoring a component in %s due to the missing type\n",
25410234Syasuko.eckert@amd.com                name.c_str());
25510234Syasuko.eckert@amd.com    }
25610234Syasuko.eckert@amd.com}
25710234Syasuko.eckert@amd.com
25810234Syasuko.eckert@amd.comvoid McPATComponent::warnMissingParamName(XMLCSTR id) {
25910234Syasuko.eckert@amd.com    if (id) {
26010234Syasuko.eckert@amd.com        fprintf(stderr,
26110234Syasuko.eckert@amd.com                "WARNING: Ignoring a parameter due to the missing name: %s\n",
26210234Syasuko.eckert@amd.com                id);
26310234Syasuko.eckert@amd.com    } else {
26410234Syasuko.eckert@amd.com        fprintf(stderr,
26510234Syasuko.eckert@amd.com                "WARNING: Ignoring a parameter in %s due to the missing name\n",
26610234Syasuko.eckert@amd.com                name.c_str());
26710234Syasuko.eckert@amd.com    }
26810234Syasuko.eckert@amd.com}
26910234Syasuko.eckert@amd.com
27010234Syasuko.eckert@amd.comvoid McPATComponent::warnMissingStatName(XMLCSTR id) {
27110234Syasuko.eckert@amd.com    if (id) {
27210234Syasuko.eckert@amd.com        fprintf(stderr,
27310234Syasuko.eckert@amd.com                "WARNING: Ignoring a statistic due to the missing name: %s\n",
27410234Syasuko.eckert@amd.com                id);
27510234Syasuko.eckert@amd.com    } else {
27610234Syasuko.eckert@amd.com        fprintf(stderr,
27710234Syasuko.eckert@amd.com                "WARNING: Ignoring a statistic in %s due to the missing name\n",
27810234Syasuko.eckert@amd.com                name.c_str());
27910234Syasuko.eckert@amd.com    }
28010234Syasuko.eckert@amd.com}
28110152Satgutier@umich.edu
28210152Satgutier@umich.edudouble longer_channel_device_reduction(
28310234Syasuko.eckert@amd.com    enum Device_ty device_ty,
28410234Syasuko.eckert@amd.com    enum Core_type core_ty) {
28510152Satgutier@umich.edu
28610234Syasuko.eckert@amd.com    double longer_channel_device_percentage_core;
28710234Syasuko.eckert@amd.com    double longer_channel_device_percentage_uncore;
28810234Syasuko.eckert@amd.com    double longer_channel_device_percentage_llc;
28910152Satgutier@umich.edu
29010234Syasuko.eckert@amd.com    double long_channel_device_reduction;
29110152Satgutier@umich.edu
29210234Syasuko.eckert@amd.com    longer_channel_device_percentage_llc    = 1.0;
29310234Syasuko.eckert@amd.com    longer_channel_device_percentage_uncore = 0.82;
29410234Syasuko.eckert@amd.com    if (core_ty == OOO) {
29510234Syasuko.eckert@amd.com        //0.54 Xeon Tulsa //0.58 Nehelam
29610234Syasuko.eckert@amd.com        longer_channel_device_percentage_core   = 0.56;
29710234Syasuko.eckert@amd.com    } else {
29810234Syasuko.eckert@amd.com        //0.8;//Niagara
29910234Syasuko.eckert@amd.com        longer_channel_device_percentage_core   = 0.8;
30010234Syasuko.eckert@amd.com    }
30110152Satgutier@umich.edu
30210234Syasuko.eckert@amd.com    if (device_ty == Core_device) {
30310234Syasuko.eckert@amd.com        long_channel_device_reduction =
30410234Syasuko.eckert@amd.com            (1 - longer_channel_device_percentage_core) +
30510234Syasuko.eckert@amd.com            longer_channel_device_percentage_core *
30610234Syasuko.eckert@amd.com            g_tp.peri_global.long_channel_leakage_reduction;
30710234Syasuko.eckert@amd.com    } else if (device_ty == Uncore_device) {
30810234Syasuko.eckert@amd.com        long_channel_device_reduction =
30910234Syasuko.eckert@amd.com            (1 - longer_channel_device_percentage_uncore) +
31010234Syasuko.eckert@amd.com            longer_channel_device_percentage_uncore *
31110234Syasuko.eckert@amd.com            g_tp.peri_global.long_channel_leakage_reduction;
31210234Syasuko.eckert@amd.com    } else if (device_ty == LLC_device) {
31310234Syasuko.eckert@amd.com        long_channel_device_reduction =
31410234Syasuko.eckert@amd.com            (1 - longer_channel_device_percentage_llc) +
31510234Syasuko.eckert@amd.com            longer_channel_device_percentage_llc *
31610234Syasuko.eckert@amd.com            g_tp.peri_global.long_channel_leakage_reduction;
31710234Syasuko.eckert@amd.com    } else {
31810234Syasuko.eckert@amd.com        cout << "ERROR: Unknown device category: " << device_ty << endl;
31910234Syasuko.eckert@amd.com        exit(0);
32010234Syasuko.eckert@amd.com    }
32110152Satgutier@umich.edu
32210234Syasuko.eckert@amd.com    return long_channel_device_reduction;
32310152Satgutier@umich.edu}
32410152Satgutier@umich.edu
32510234Syasuko.eckert@amd.comstatsComponents operator+(const statsComponents & x, const statsComponents & y) {
32610234Syasuko.eckert@amd.com    statsComponents z;
32710152Satgutier@umich.edu
32810234Syasuko.eckert@amd.com    z.access = x.access + y.access;
32910234Syasuko.eckert@amd.com    z.hit    = x.hit + y.hit;
33010234Syasuko.eckert@amd.com    z.miss   = x.miss  + y.miss;
33110152Satgutier@umich.edu
33210234Syasuko.eckert@amd.com    return z;
33310152Satgutier@umich.edu}
33410152Satgutier@umich.edu
33510234Syasuko.eckert@amd.comstatsComponents operator*(const statsComponents & x, double const * const y) {
33610234Syasuko.eckert@amd.com    statsComponents z;
33710152Satgutier@umich.edu
33810234Syasuko.eckert@amd.com    z.access = x.access * y[0];
33910234Syasuko.eckert@amd.com    z.hit    = x.hit * y[1];
34010234Syasuko.eckert@amd.com    z.miss   = x.miss * y[2];
34110152Satgutier@umich.edu
34210234Syasuko.eckert@amd.com    return z;
34310152Satgutier@umich.edu}
34410152Satgutier@umich.edu
34510234Syasuko.eckert@amd.comstatsDef operator+(const statsDef & x, const statsDef & y) {
34610234Syasuko.eckert@amd.com    statsDef z;
34710152Satgutier@umich.edu
34810234Syasuko.eckert@amd.com    z.readAc   = x.readAc  + y.readAc;
34910234Syasuko.eckert@amd.com    z.writeAc  = x.writeAc + y.writeAc;
35010234Syasuko.eckert@amd.com    z.searchAc  = x.searchAc + y.searchAc;
35110234Syasuko.eckert@amd.com    return z;
35210152Satgutier@umich.edu}
35310152Satgutier@umich.edu
35410234Syasuko.eckert@amd.comstatsDef operator*(const statsDef & x, double const * const y) {
35510234Syasuko.eckert@amd.com    statsDef z;
35610152Satgutier@umich.edu
35710234Syasuko.eckert@amd.com    z.readAc   = x.readAc * y;
35810234Syasuko.eckert@amd.com    z.writeAc  = x.writeAc * y;
35910234Syasuko.eckert@amd.com    z.searchAc  = x.searchAc * y;
36010234Syasuko.eckert@amd.com    return z;
36110152Satgutier@umich.edu}
362