1/* Copyright (c) 2014 Mark D. Hill and David A. Wood 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer; 8 * redistributions in binary form must reproduce the above copyright 9 * notice, this list of conditions and the following disclaimer in the 10 * documentation and/or other materials provided with the distribution; 11 * neither the name of the copyright holders nor the names of its 12 * contributors may be used to endorse or promote products derived from 13 * this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include <Python.h> 29#include <cstdio> 30 31#include "DSENT.h" 32#include "libutil/String.h" 33#include "model/Model.h" 34 35using namespace std; 36using namespace LibUtil; 37 38static PyObject *DSENTError; 39static PyObject* dsent_initialize(PyObject*, PyObject*); 40static PyObject* dsent_finalize(PyObject*, PyObject*); 41static PyObject* dsent_computeRouterPowerAndArea(PyObject*, PyObject*); 42static PyObject* dsent_computeLinkPower(PyObject*, PyObject*); 43 44// Create DSENT configuration map. This map is supposed to retain all 45// the information between calls to initialize() and finalize(). 46map<String, String> params; 47DSENT::Model *ms_model; 48 49 50static PyMethodDef DSENTMethods[] = { 51 {"initialize", dsent_initialize, METH_O, 52 "initialize dsent using a config file."}, 53 54 {"finalize", dsent_finalize, METH_NOARGS, 55 "finalize dsent by dstroying the config object"}, 56 57 {"computeRouterPowerAndArea", dsent_computeRouterPowerAndArea, 58 METH_VARARGS, "compute quantities related power consumption of a router"}, 59 60 {"computeLinkPower", dsent_computeLinkPower, METH_O, 61 "compute quantities related power consumption of a link"}, 62 63 {NULL, NULL, 0, NULL} 64}; 65 66 67PyMODINIT_FUNC 68initdsent(void) 69{ 70 PyObject *m; 71 72 m = Py_InitModule("dsent", DSENTMethods); 73 if (m == NULL) return; 74 75 DSENTError = PyErr_NewException("dsent.error", NULL, NULL); 76 Py_INCREF(DSENTError); 77 PyModule_AddObject(m, "error", DSENTError); 78 79 ms_model = nullptr; 80} 81 82 83static PyObject * 84dsent_initialize(PyObject *self, PyObject *arg) 85{ 86 const char *config_file = PyString_AsString(arg); 87 //Read the arguments sent from the python script 88 if (!config_file) { 89 Py_RETURN_NONE; 90 } 91 92 // Initialize DSENT 93 ms_model = DSENT::initialize(config_file, params); 94 Py_RETURN_NONE; 95} 96 97 98static PyObject * 99dsent_finalize(PyObject *self, PyObject *args) 100{ 101 // Finalize DSENT 102 DSENT::finalize(params, ms_model); 103 ms_model = nullptr; 104 Py_RETURN_NONE; 105} 106 107 108static PyObject * 109dsent_computeRouterPowerAndArea(PyObject *self, PyObject *args) 110{ 111 uint64_t frequency; 112 unsigned int num_in_port; 113 unsigned int num_out_port; 114 unsigned int num_vclass; 115 unsigned int num_vchannels; 116 unsigned int num_buffers; 117 118 unsigned int flit_width; 119 const char *input_port_buffer_model; 120 const char *crossbar_model; 121 const char *sa_arbiter_model; 122 const char *clk_tree_model; 123 unsigned int clk_tree_num_levels; 124 const char *clk_tree_wire_layer; 125 double clk_tree_wire_width_mult; 126 127 // Read the arguments sent from the python script 128 if (!PyArg_ParseTuple(args, "KIIIIII", &frequency, &num_in_port, 129 &num_out_port, &num_vclass, &num_vchannels, 130 &num_buffers, &flit_width)) { 131 Py_RETURN_NONE; 132 } 133 134 assert(frequency > 0.0); 135 assert(num_in_port != 0); 136 assert(num_out_port != 0); 137 assert(num_vclass != 0); 138 assert(flit_width != 0); 139 140 vector<unsigned int> num_vchannels_vec(num_vclass, num_vchannels); 141 vector<unsigned int> num_buffers_vec(num_vclass, num_buffers); 142 // DSENT outputs 143 map<string, double> outputs; 144 145 params["Frequency"] = String(frequency); 146 params["NumberInputPorts"] = String(num_in_port); 147 params["NumberOutputPorts"] = String(num_out_port); 148 params["NumberVirtualNetworks"] = String(num_vclass); 149 params["NumberVirtualChannelsPerVirtualNetwork"] = 150 vectorToString<unsigned int>(num_vchannels_vec); 151 params["NumberBuffersPerVirtualChannel"] = 152 vectorToString<unsigned int>(num_buffers_vec); 153 params["NumberBitsPerFlit"] = String(flit_width); 154 155 // Run DSENT 156 DSENT::run(params, ms_model, outputs); 157 158 // Store outputs 159 PyObject *r = PyTuple_New(outputs.size()); 160 int index = 0; 161 162 // Prepare the output. The assumption is that all the output 163 for (const auto &it : outputs) { 164 PyObject *s = PyTuple_New(2); 165 PyTuple_SetItem(s, 0, PyString_FromString(it.first.c_str())); 166 PyTuple_SetItem(s, 1, PyFloat_FromDouble(it.second)); 167 168 PyTuple_SetItem(r, index, s); 169 index++; 170 } 171 172 return r; 173} 174 175 176static PyObject * 177dsent_computeLinkPower(PyObject *self, PyObject *arg) 178{ 179 uint64_t frequency = PyLong_AsLongLong(arg); 180 181 // Read the arguments sent from the python script 182 if (frequency == -1) { 183 Py_RETURN_NONE; 184 } 185 186 // DSENT outputs 187 map<string, double> outputs; 188 params["Frequency"] = String(frequency); 189 190 // Run DSENT 191 DSENT::run(params, ms_model, outputs); 192 193 // Store outputs 194 PyObject *r = PyTuple_New(outputs.size()); 195 int index = 0; 196 197 // Prepare the output. The assumption is that all the output 198 for (const auto &it : outputs) { 199 PyObject *s = PyTuple_New(2); 200 PyTuple_SetItem(s, 0, PyString_FromString(it.first.c_str())); 201 PyTuple_SetItem(s, 1, PyFloat_FromDouble(it.second)); 202 203 PyTuple_SetItem(r, index, s); 204 index++; 205 } 206 207 return r; 208} 209 210static PyObject * 211dsent_printAvailableModels(PyObject* self, PyObject *args) 212{ 213} 214