From c1aecc05e6cad977423a15905f6bd4f5f33b53c8 Mon Sep 17 00:00:00 2001 From: Nilay Vaish Date: Sat, 11 Oct 2014 16:16:00 -0500 Subject: ext: dsent: adds a Python interface, drops C++ one This patch extensively modifies DSENT so that it can be accessed using Python. To access the Python interface, DSENT needs to compiled as a shared library. For this purpose a CMakeLists.txt file has been added. Some of the code that is not required is being removed. --- ext/dsent/interface.cc | 213 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 ext/dsent/interface.cc (limited to 'ext/dsent/interface.cc') diff --git a/ext/dsent/interface.cc b/ext/dsent/interface.cc new file mode 100644 index 000000000..b57c33ea8 --- /dev/null +++ b/ext/dsent/interface.cc @@ -0,0 +1,213 @@ +/* Copyright (c) 2014 Mark D. Hill and David A. Wood + * 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. + */ + +#include +#include + +#include "DSENT.h" +#include "libutil/String.h" +#include "model/Model.h" + +using namespace std; +using namespace LibUtil; + +static PyObject *DSENTError; +static PyObject* dsent_initialize(PyObject*, PyObject*); +static PyObject* dsent_finalize(PyObject*, PyObject*); +static PyObject* dsent_computeRouterPowerAndArea(PyObject*, PyObject*); +static PyObject* dsent_computeLinkPower(PyObject*, PyObject*); + +// Create DSENT configuration map. This map is supposed to retain all +// the information between calls to initialize() and finalize(). +map params; +DSENT::Model *ms_model; + + +static PyMethodDef DSENTMethods[] = { + {"initialize", dsent_initialize, METH_O, + "initialize dsent using a config file."}, + + {"finalize", dsent_finalize, METH_NOARGS, + "finalize dsent by dstroying the config object"}, + + {"computeRouterPowerAndArea", dsent_computeRouterPowerAndArea, + METH_VARARGS, "compute quantities related power consumption of a router"}, + + {"computeLinkPower", dsent_computeLinkPower, METH_O, + "compute quantities related power consumption of a link"}, + + {NULL, NULL, 0, NULL} +}; + + +PyMODINIT_FUNC +initdsent(void) +{ + PyObject *m; + + m = Py_InitModule("dsent", DSENTMethods); + if (m == NULL) return; + + DSENTError = PyErr_NewException("dsent.error", NULL, NULL); + Py_INCREF(DSENTError); + PyModule_AddObject(m, "error", DSENTError); + + ms_model = nullptr; +} + + +static PyObject * +dsent_initialize(PyObject *self, PyObject *arg) +{ + const char *config_file = PyString_AsString(arg); + //Read the arguments sent from the python script + if (!config_file) { + Py_RETURN_NONE; + } + + // Initialize DSENT + ms_model = DSENT::initialize(config_file, params); + Py_RETURN_NONE; +} + + +static PyObject * +dsent_finalize(PyObject *self, PyObject *args) +{ + // Finalize DSENT + DSENT::finalize(params, ms_model); + ms_model = nullptr; + Py_RETURN_NONE; +} + + +static PyObject * +dsent_computeRouterPowerAndArea(PyObject *self, PyObject *args) +{ + uint64_t frequency; + unsigned int num_in_port; + unsigned int num_out_port; + unsigned int num_vclass; + unsigned int num_vchannels; + unsigned int num_buffers; + + unsigned int flit_width; + const char *input_port_buffer_model; + const char *crossbar_model; + const char *sa_arbiter_model; + const char *clk_tree_model; + unsigned int clk_tree_num_levels; + const char *clk_tree_wire_layer; + double clk_tree_wire_width_mult; + + // Read the arguments sent from the python script + if (!PyArg_ParseTuple(args, "KIIIIII", &frequency, &num_in_port, + &num_out_port, &num_vclass, &num_vchannels, + &num_buffers, &flit_width)) { + Py_RETURN_NONE; + } + + assert(frequency > 0.0); + assert(num_in_port != 0); + assert(num_out_port != 0); + assert(num_vclass != 0); + assert(flit_width != 0); + + vector num_vchannels_vec(num_vclass, num_vchannels); + vector num_buffers_vec(num_vclass, num_buffers); + // DSENT outputs + map outputs; + + params["Frequency"] = String(frequency); + params["NumberInputPorts"] = String(num_in_port); + params["NumberOutputPorts"] = String(num_out_port); + params["NumberVirtualNetworks"] = String(num_vclass); + params["NumberVirtualChannelsPerVirtualNetwork"] = + vectorToString(num_vchannels_vec); + params["NumberBuffersPerVirtualChannel"] = + vectorToString(num_buffers_vec); + params["NumberBitsPerFlit"] = String(flit_width); + + // Run DSENT + DSENT::run(params, ms_model, outputs); + + // Store outputs + PyObject *r = PyTuple_New(outputs.size()); + int index = 0; + + // Prepare the output. The assumption is that all the output + for (const auto &it : outputs) { + PyObject *s = PyTuple_New(2); + PyTuple_SetItem(s, 0, PyString_FromString(it.first.c_str())); + PyTuple_SetItem(s, 1, PyFloat_FromDouble(it.second)); + + PyTuple_SetItem(r, index, s); + index++; + } + + return r; +} + + +static PyObject * +dsent_computeLinkPower(PyObject *self, PyObject *arg) +{ + uint64_t frequency = PyLong_AsLongLong(arg); + + // Read the arguments sent from the python script + if (frequency == -1) { + Py_RETURN_NONE; + } + + // DSENT outputs + map outputs; + params["Frequency"] = String(frequency); + + // Run DSENT + DSENT::run(params, ms_model, outputs); + + // Store outputs + PyObject *r = PyTuple_New(outputs.size()); + int index = 0; + + // Prepare the output. The assumption is that all the output + for (const auto &it : outputs) { + PyObject *s = PyTuple_New(2); + PyTuple_SetItem(s, 0, PyString_FromString(it.first.c_str())); + PyTuple_SetItem(s, 1, PyFloat_FromDouble(it.second)); + + PyTuple_SetItem(r, index, s); + index++; + } + + return r; +} + +static PyObject * +dsent_printAvailableModels(PyObject* self, PyObject *args) +{ +} -- cgit v1.2.3