1 // Copyright (C) 2008-2011 Jakob Schiotz and Center for Individual
2 // Nanoparticle Functionality, Department of Physics, Technical
3 // University of Denmark.  Email: schiotz@fysik.dtu.dk
4 //
5 // This file is part of Asap version 3.
6 // Asap is released under the GNU Lesser Public License (LGPL) version 3.
7 // However, the parts of Asap distributed within the OpenKIM project
8 // (including this file) are also released under the Common Development
9 // and Distribution License (CDDL) version 1.0.
10 //
11 // This program is free software: you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public License
13 // version 3 as published by the Free Software Foundation.  Permission
14 // to use other versions of the GNU Lesser General Public License may
15 // granted by Jakob Schiotz or the head of department of the
16 // Department of Physics, Technical University of Denmark, as
17 // described in section 14 of the GNU General Public License.
18 //
19 // This program is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 // GNU General Public License for more details.
23 //
24 // You should have received a copy of the GNU General Public License
25 // and the GNU Lesser Public License along with this program.  If not,
26 // see <http://www.gnu.org/licenses/>.
27 
28 #include "AsapPython.h"
29 #include "Timing.h"
30 #include "TimingResults.h"
31 #include <map>
32 #include <string>
33 
34 #ifdef TIMING
maketimingresults(std::map<string,Timing_timer * > & pool,int level=0)35 static PyObject *maketimingresults(std::map<string, Timing_timer *> &pool,
36                                    int level = 0)
37 {
38   if (level == 3) {
39     PyErr_SetString(PyExc_RuntimeError,
40                     "Too deep recursion in maketimingresults");
41     return NULL;
42   }
43   int nelem = pool.size();
44   if (nelem == 0) {
45     Py_INCREF(Py_None);
46     return Py_None;
47   }
48   PyObject *result = PyDict_New();
49   if (!result)
50     return NULL;
51   std::map<string, Timing_timer *>::const_iterator p;
52   for (p = pool.begin(); p != pool.end(); ++p)
53     {
54       std::string name;
55       double wall, cpu, wall_c, cpu_c;
56       int count;
57       p->second->Report(name, wall, cpu, wall_c, cpu_c, count);
58       PyObject *key = Py_BuildValue("s", name.c_str());
59       PyObject *value = Py_BuildValue("(ddddiN)", wall, cpu, wall_c, cpu_c,
60                                       count,
61                                       maketimingresults(p->second->masters,
62                                                         level+1));
63       if (!key || !value) {
64         Py_DECREF(result); Py_XDECREF(key); Py_XDECREF(value);
65         return NULL;
66       }
67       int x = PyDict_SetItem(result, key, value);
68       Py_DECREF(key);
69       Py_DECREF(value);
70       if (x == -1) {
71         Py_DECREF(result);
72         return NULL;
73       }
74     }
75   return result;
76 }
77 #endif //TIMING
78 
79 namespace ASAPSPACE {
80 
PyAsap_TimingResults(PyObject * noself,PyObject * noargs)81 PyObject *PyAsap_TimingResults(PyObject *noself, PyObject *noargs) {
82 #ifdef TIMING
83   return maketimingresults(Timing_timerpool);
84 #else // TIMING
85   Py_INCREF(Py_None);
86   return Py_None;
87 #endif //TIMING
88 }
89 
90 } // end namespace
91