gem5/ext/dsent/interface.cc
Nilay Vaish c1aecc05e6 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.
2014-10-11 16:16:00 -05:00

213 lines
6.4 KiB
C++

/* 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 <Python.h>
#include <cstdio>
#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<String, String> 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<unsigned int> num_vchannels_vec(num_vclass, num_vchannels);
vector<unsigned int> num_buffers_vec(num_vclass, num_buffers);
// DSENT outputs
map<string, double> 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<unsigned int>(num_vchannels_vec);
params["NumberBuffersPerVirtualChannel"] =
vectorToString<unsigned int>(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<string, double> 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)
{
}