// -*- C++ -*- // //----------------------------------------------------------------------------- // // TAU Development Team // University of Oregon, Los Alamos National Laboratory, // FZJ Germany // (C) 2003 All Rights Reserved // // // //----------------------------------------------------------------------------- // // $Log: PyTimer.cpp,v $ // Revision 1.11 2009/03/26 19:15:39 sameer // Updated the start/stop calls with the additional tid argument. Before: // // Tau_start_timer(void *timer, int phase) // { // int tid = RtsLayer::myThread(); // // p->Start(); // Start internally calls tid = RtsLayer::myThread() // } // // After: // // Tau_start_timer(void *timer, int phase, int tid) // { // // int tid = RtsLayer::myThread(); // p->Start(tid); // } // // This is used extensively in the new TASK API. See examples/profilercreate/taskc++. // // Revision 1.10 2009/02/24 21:30:23 amorris // Getting rid of Profiler::CurrentProfiler, it doesn't make sense to maintain // this linked list if we have an explicit data structure for the callstack. It's // replaced with a routine: TauInternal_CurrentProfiler(tid) // // Revision 1.9 2009/01/15 02:47:23 amorris // Changes for C++ measurement API // // Revision 1.8 2008/10/16 22:58:24 amorris // // Revision 1.7 2007/03/02 02:36:24 amorris // Made explicit the phase calls, true and false. // // Revision 1.6 2007/03/01 22:17:28 amorris // Added phase API for python // // Revision 1.5 2007/03/01 02:45:39 amorris // The map for reusing timers was not taking the 'type' into account, so when // different routines with the same name occurred, they were both assigned to the // same timer with the file/line information of whichever occurred first. We now // hash on the combined name+type. // // Revision 1.4 2003/03/20 18:41:05 sameer // Added TAU_HPUX guards for header. // // Revision 1.3 2003/03/15 01:49:13 sameer // Python bindings and wish fix. // // Revision 1.2 2003/03/15 01:39:11 sameer // Added [HP-UX] and moved funcDB in PyTimer.cpp to inside the profileTimer routine. // // Revision 1.1 2003/02/28 23:26:52 sameer // Added Python Bindings to TAU [Julian Cummings, Brian Miller]. // // // #ifdef TAU_HPUX #include #endif /* TAU_HPUX */ #include // Tau includes #include "Profile/Profiler.h" #include #include using namespace std; // Utility routines struct ltstr{ bool operator()(const char* s1, const char* s2) const{ return strcmp(s1, s2) < 0; }//operator() }; // tells whether a FunctionInfo object is a phase or not static map phaseMap; static PyObject *createTimer(PyObject *self, PyObject *args, PyObject *kwargs, bool phase) { // Extract name, type and group strings and return the id of the routine int tauid = 0; char *name = "None"; char *type = ""; char *group = "TAU_PYTHON"; static char *argnames[] = { "name", "type", "group", NULL}; /* GLOBAL database of function names */ static map funcDB; map::iterator it; // Get Python arguments if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|sss", argnames, &name, &type, &group)) { return NULL; } #ifdef DEBUG printf("Got Name = %s, Type = %s, Group = %s, tauid = %d\n", name, type, group, tauid); #endif /* DEBUG */ char * functionName = new char[strlen(name) + strlen(type) +5]; // create a new storage - STL req. sprintf (functionName,"%s %s",name,type); if (( it = funcDB.find((const char *)functionName)) != funcDB.end()) { #ifdef DEBUG printf("Found the name %s\n", functionName); #endif /* DEBUG */ tauid = (*it).second; delete functionName; // don't need this if its already there. } else { if (phase) { // Add TAU_PHASE to the group group = Tau_phase_enable(group); } TauGroup_t groupid = RtsLayer::getProfileGroup(group); FunctionInfo *f = new FunctionInfo(functionName, "", groupid, group, true); tauid = TheFunctionDB().size() - 1; // These two need to be an atomic operation if threads are involved. LockDB happens // inside FunctionInfoInit() // Store the id in our map funcDB[(const char *)functionName] = tauid; // Do not delete functionName, STL requirement! if (phase) { phaseMap[tauid] = true; } else { phaseMap[tauid] = false; } } return Py_BuildValue("i", tauid); } char pytau_profileTimer__name__[] = "profileTimer"; char pytau_profileTimer__doc__[] = "access or create a TAU timer"; extern "C" PyObject * pytau_profileTimer(PyObject *self, PyObject *args, PyObject *kwargs) { // create non-phase timer return createTimer(self, args, kwargs, false); } char pytau_phase__name__[] = "phase"; char pytau_phase__doc__[] = "access or create a TAU phase"; extern "C" PyObject * pytau_phase(PyObject *self, PyObject *args, PyObject *kwargs) { // create phase timer return createTimer(self, args, kwargs, true); } char pytau_start__name__[] = "start"; char pytau_start__doc__[] = "start a TAU timer"; extern "C" PyObject * pytau_start(PyObject *self, PyObject *args) { int id; if (!PyArg_ParseTuple(args, "i", &id)) { printf("Couldn't Parse the tuple!\n"); return NULL; } FunctionInfo *f = TheFunctionDB()[id]; #ifdef DEBUG printf("Received timer Named %s, id = %d\n", f->GetName(), id); #endif /* DEBUG */ int tid = RtsLayer::myThread(); /* Get the FunctionInfo object */ bool isPhase = phaseMap[id]; int phase = 0; if (isPhase) { phase = 1; } Tau_start_timer(f, phase, Tau_get_tid()); Py_INCREF(Py_None); return Py_None; } int tau_check_and_set_nodeid(void) { if (RtsLayer::myNode() == -1) { #ifndef TAU_MPI TAU_PROFILE_SET_NODE(0); #endif /* TAU_MPI */ } return 0; } char pytau_stop__name__[] = "stop"; char pytau_stop__doc__[] = "stop a TAU timer"; extern "C" PyObject * pytau_stop(PyObject *self, PyObject *args) { int tid = RtsLayer::myThread(); static int taunode = tau_check_and_set_nodeid(); Profiler *p = TauInternal_CurrentProfiler(tid); if (p != (Profiler *) NULL) { Tau_stop_timer(p->ThisFunction, Tau_get_tid()); Py_INCREF(Py_None); return Py_None; } else { printf("pytau_stop: Stack error. Profiler is NULL!"); return NULL; } Py_INCREF(Py_None); return Py_None; } // version // $Id: PyTimer.cpp,v 1.11 2009/03/26 19:15:39 sameer Exp $ // End of file