[MOAB-dev] r2887 - in MOAB/trunk/tools/iMesh/python: . perf

jvporter at wisc.edu jvporter at wisc.edu
Fri May 15 18:06:45 CDT 2009


Author: jvporter
Date: 2009-05-15 18:06:45 -0500 (Fri, 15 May 2009)
New Revision: 2887

Added:
   MOAB/trunk/tools/iMesh/python/perf/
   MOAB/trunk/tools/iMesh/python/perf/Makefile
   MOAB/trunk/tools/iMesh/python/perf/perf.c
   MOAB/trunk/tools/iMesh/python/perf/perf.py
Modified:
   MOAB/trunk/tools/iMesh/python/iMesh.c
   MOAB/trunk/tools/iMesh/python/iMesh_Python.h
Log:
Added basic performance tests to compare Python wrapper to C.



Modified: MOAB/trunk/tools/iMesh/python/iMesh.c
===================================================================
--- MOAB/trunk/tools/iMesh/python/iMesh.c	2009-05-15 19:45:47 UTC (rev 2886)
+++ MOAB/trunk/tools/iMesh/python/iMesh.c	2009-05-15 23:06:45 UTC (rev 2887)
@@ -61,7 +61,7 @@
     iBaseEntitySet_Object *set;
     const char *name = 0;
     const char *options = "";
-    if(!PyArg_ParseTuple(args,"Os|s",&set,&name,&options))
+    if(!PyArg_ParseTuple(args,"O!s|s",&iBaseEntitySet_Type,&set,&name,&options))
         return NULL;
 
     int err;
@@ -79,7 +79,7 @@
     iBaseEntitySet_Object *set;
     const char *name = 0;
     const char *options = "";
-    if(!PyArg_ParseTuple(args,"Os|s",&set,&name,&options))
+    if(!PyArg_ParseTuple(args,"O!s|s",&iBaseEntitySet_Type,&set,&name,&options))
         return NULL;
 
     int err;
@@ -1574,6 +1574,11 @@
     PyObject *m;
     PyArray_Descr *descr;
 
+    /* TODO: remove */
+    _MyDeallocType.tp_new = PyType_GenericNew;
+    if (PyType_Ready(&_MyDeallocType) < 0)
+        return;
+
     m = Py_InitModule("iMesh",module_methods);
     import_array();
     import_iBase();

Modified: MOAB/trunk/tools/iMesh/python/iMesh_Python.h
===================================================================
--- MOAB/trunk/tools/iMesh/python/iMesh_Python.h	2009-05-15 19:45:47 UTC (rev 2886)
+++ MOAB/trunk/tools/iMesh/python/iMesh_Python.h	2009-05-15 23:06:45 UTC (rev 2887)
@@ -11,10 +11,61 @@
 #define PY_ARRAY_UNIQUE_SYMBOL itaps_ARRAY_API
 #include <numpy/arrayobject.h>
 
-#define PyArray_NewFromMallocData(nd, dims, typenum, data)      \
+typedef struct {
+PyObject_HEAD
+void *memory;
+} _MyDeallocObject;
+
+static void
+_mydealloc_dealloc(_MyDeallocObject *self)
+{
+free(self->memory);
+self->ob_type->tp_free((PyObject *)self);
+}
+
+static PyTypeObject _MyDeallocType = {
+PyObject_HEAD_INIT(NULL)
+0,                                          /*ob_size*/
+"mydeallocator",                   /*tp_name*/
+sizeof(_MyDeallocObject),    /*tp_basicsize*/
+0,                                          /*tp_itemsize*/
+_mydealloc_dealloc,             /*tp_dealloc*/
+0,                         /*tp_print*/
+0,                         /*tp_getattr*/
+0,                         /*tp_setattr*/
+0,                         /*tp_compare*/
+0,                         /*tp_repr*/
+0,                         /*tp_as_number*/
+0,                         /*tp_as_sequence*/
+0,                         /*tp_as_mapping*/
+0,                         /*tp_hash */
+0,                         /*tp_call*/
+0,                         /*tp_str*/
+0,                         /*tp_getattro*/
+0,                         /*tp_setattro*/
+0,                         /*tp_as_buffer*/
+Py_TPFLAGS_DEFAULT,        /*tp_flags*/
+"Internal deallocator object",           /* tp_doc */
+};
+
+
+/*#define PyArray_NewFromMallocData(nd, dims, typenum, data)    \
     PyArray_New(&PyArray_Type, nd, dims, typenum, NULL,         \
-                data, 0, NPY_CARRAY|NPY_OWNDATA, NULL)
+    data, 0, NPY_CARRAY|NPY_OWNDATA, NULL)*/
 
+static PyObject *
+PyArray_NewFromMallocData(int nd,npy_intp *dims,int typenum,void *data)
+{
+    PyObject *newobj;
+    PyObject *arr =  PyArray_New(&PyArray_Type, nd, dims, typenum, NULL,
+                                 data, 0, NPY_CARRAY, NULL);
+    newobj = (PyObject*)PyObject_New(_MyDeallocObject, &_MyDeallocType);
+    ((_MyDeallocObject *)newobj)->memory = data;
+    PyArray_BASE(arr) = newobj;
+    return arr;
+}
+
+
 PyObject *
 PyArray_TryFromObject(PyObject *obj,int typenum,int min_depth,int max_depth);
 

Added: MOAB/trunk/tools/iMesh/python/perf/Makefile
===================================================================
--- MOAB/trunk/tools/iMesh/python/perf/Makefile	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/perf/Makefile	2009-05-15 23:06:45 UTC (rev 2887)
@@ -0,0 +1,6 @@
+all: perf.c
+	gcc -o perf perf.c -I/home/porterj/moab/include \
+	-L/home/porterj/moab/lib -L/usr/local/hdf5serial/lib \
+	-liMesh -lm -lgcc_s -lc -lMOAB -lnetcdf_c++ -lnetcdf -lhdf5 -lstdc++ \
+	-O2 -DNDEBUG -pthread -g -Wall -Wstrict-prototypes -fPIC \
+	-fno-strict-aliasing -fwrapv
\ No newline at end of file

Added: MOAB/trunk/tools/iMesh/python/perf/perf.c
===================================================================
--- MOAB/trunk/tools/iMesh/python/perf/perf.c	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/perf/perf.c	2009-05-15 23:06:45 UTC (rev 2887)
@@ -0,0 +1,180 @@
+#include <dirent.h>
+#include <iMesh.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+struct timeval timeval_diff(struct timeval *lhs,struct timeval *rhs)
+{
+    const int usec = 1000000;
+    struct timeval result;
+
+    if(lhs->tv_usec < rhs->tv_usec)
+    {
+        int delta = (rhs->tv_usec - lhs->tv_usec) / usec + 1;
+        rhs->tv_usec -= delta*usec;
+        rhs->tv_sec  += delta;
+    }
+
+    if(lhs->tv_usec - rhs->tv_usec > usec)
+    {
+        int *i = 0;
+        *i = 5;
+    }
+
+    result.tv_sec  = lhs->tv_sec  - rhs->tv_sec;
+    result.tv_usec = lhs->tv_usec - rhs->tv_usec;
+
+    return result;
+}
+
+char* format_delta(struct timeval *lhs,struct timeval *rhs)
+{
+    static char str[512];
+    struct timeval delta = timeval_diff(lhs,rhs);
+    snprintf(str,sizeof(str),"%u.%06u",(unsigned int)delta.tv_sec,
+             (unsigned int)delta.tv_usec);
+    return str;
+}
+
+int testable(const char *file)
+{
+    int len = strlen(file);
+    return (file[len-2] == '.' && file[len-1] == 'g') &&
+        strncmp(file,"testquad",8);
+}
+
+int main(int argc,char **argv)
+{
+    DIR *dir;
+    struct dirent *ent;
+
+    if(argc != 2)
+    {
+        fprintf(stderr,"Usage: perf directory-name\n");
+        return 1;
+    }
+
+    dir = opendir(argv[1]);
+    if(dir == NULL)
+        return 1;
+    chdir(argv[1]);
+
+    while((ent = readdir(dir)) != NULL)
+    {
+        struct timeval start,end;
+        int err;
+        iMesh_Instance mesh=0;
+        iBase_EntitySetHandle root;
+        char *file = ent->d_name;
+        int i;
+
+        if(!testable(file))
+            continue;
+
+        printf("%s,",file);
+
+        /***** 1 *****/
+        gettimeofday(&start,0);
+        for(i=0; i<100; i++)
+        {
+            iMesh_Instance mesh;
+            iMesh_newMesh("",&mesh,&err,0);
+            iMesh_getRootSet(mesh,&root,&err);
+            iMesh_load(mesh,root,file,"",&err,strlen(file),0);
+            iMesh_dtor(mesh,&err);
+        }
+        gettimeofday(&end,0);
+        printf("%s,",format_delta(&end,&start));
+
+        iMesh_newMesh("",&mesh,&err,0);
+        iMesh_getRootSet(mesh,&root,&err);
+        iMesh_load(mesh,root,file,"",&err,strlen(file),0);
+
+        /***** 2 *****/
+        iBase_EntityHandle *entities=0;
+        int ent_size=0,ent_alloc;
+        iBase_EntityHandle *adj=0;
+        int adj_size=0,adj_alloc;
+        int *indices=0;
+        int ind_size=0,ind_alloc;
+        int *offsets=0;
+        int off_size=0,off_alloc;
+
+        gettimeofday(&start,0);
+        for(i=0; i<100; i++)
+        {
+            free(entities); entities = 0; ent_size = 0;
+            free(adj);      adj = 0;      adj_size = 0;
+            free(indices);  indices = 0;  ind_size = 0;
+            free(offsets);  offsets = 0;  off_size = 0;
+            
+            iMesh_getAdjEntIndices(mesh,root,iBase_ALL_TYPES,
+                                   iMesh_ALL_TOPOLOGIES,iBase_ALL_TYPES,
+                                   &entities,&ent_size,&ent_alloc,
+                                   &adj,     &adj_size,&adj_alloc,
+                                   &indices, &ind_size,&ind_alloc,
+                                   &offsets, &off_size,&off_alloc,
+                                   &err);
+        }
+        gettimeofday(&end,0);
+        printf("%s,",format_delta(&end,&start));
+
+        /***** 3 *****/
+        {
+            iBase_EntityHandle *adj2=0;
+            int adj2_size=0,adj2_alloc;
+            int *offsets2=0;
+            int off2_size=0,off2_alloc;
+
+            gettimeofday(&start,0);
+            for(i=0; i<100; i++)
+            {
+                adj2 = 0;     adj2_size = 0;
+                offsets2 = 0; off2_size = 0;
+                iMesh_getEntArrAdj(mesh,entities,ent_size,iBase_ALL_TYPES,
+                                   &adj2,&adj2_size,&adj2_alloc,
+                                   &offsets2,&off2_size,&off2_alloc,&err);
+                free(adj2);
+                free(offsets2);
+            }
+            gettimeofday(&end,0);
+            printf("%s,",format_delta(&end,&start));
+        }
+
+        /***** 4 *****/
+        {
+            iBase_EntityHandle *adj2=0;
+            int adj2_size=0,adj2_alloc;
+            int *offsets2=0;
+            int off2_size=0,off2_alloc;
+
+            gettimeofday(&start,0);
+            for(i=0; i<100; i++)
+            {
+                adj2 = 0;     adj2_size = 0;
+                offsets2 = 0; off2_size = 0;
+                iMesh_getEntArr2ndAdj(mesh,entities,ent_size,
+                                      iBase_EDGE,iBase_VERTEX,
+                                      &adj2,&adj2_size,&adj2_alloc,
+                                      &offsets2,&off2_size,&off2_alloc,&err);
+                free(adj2);
+                free(offsets2);
+            }
+            gettimeofday(&end,0);
+            printf("%s\n",format_delta(&end,&start));
+        }
+
+        free(entities);
+        free(adj);
+        free(indices);
+        free(offsets);
+        iMesh_dtor(mesh,&err);
+    }
+
+    closedir(dir);
+
+    return 0;
+}

Added: MOAB/trunk/tools/iMesh/python/perf/perf.py
===================================================================
--- MOAB/trunk/tools/iMesh/python/perf/perf.py	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/perf/perf.py	2009-05-15 23:06:45 UTC (rev 2887)
@@ -0,0 +1,128 @@
+import re
+import os
+import sys
+import subprocess
+import csv
+from datetime import *
+sys.path.append('../build/lib.linux-x86_64-2.5/')
+
+from itaps import *
+
+class stopwatch:
+    def __init__(self):
+        self.reset()
+
+    def delta(self):
+        d = datetime.now() - self.start
+        return d.seconds + d.microseconds/1000000.0
+
+    def reset(self):
+        self.start = datetime.now()
+
+def testable(name):
+    return re.search(r'\.g$',name) != None and \
+        not re.match('testquad',name)
+
+
+c_stats  = {}
+py_stats = {}
+list_stats = {}
+
+path = raw_input('Where da files at: ')
+if(len(path) == 0):
+    path = '/home/porterj/moab-3.99/test'
+
+##### Run some tests in C #####
+lines = csv.reader( subprocess.Popen('./perf %s' % path, shell=True,
+                                     stdout=subprocess.PIPE).stdout )
+for row in lines:
+    c_stats[row[0]] = [float(i)/100 for i in row[1:]]
+
+
+##### Run some tests in Python #####
+os.chdir(path)
+timer = stopwatch()
+
+for file in filter(testable, os.listdir(path)):
+    py_stats[file] = []
+    list_stats[file] = []
+
+    ##### 1 #####
+    timer.reset()
+    for x in range(100):
+        m = iMesh()
+        m.load(m.rootSet, file)
+        m = None
+    py_stats[file].append( timer.delta()/100 )
+    list_stats[file].append(0)
+
+    ##### Intermission #####
+    mesh = iMesh()
+    root = mesh.rootSet
+    mesh.load(root, file)
+
+    ##### 2 #####
+    timer.reset()
+    for x in range(100):
+        mesh.getAdjEntIndices(root, iBase.type.all,
+                              iMesh.topology.all, iBase.type.all)
+    py_stats[file].append( timer.delta()/100 )
+    list_stats[file].append(0)
+
+    ##### Intermission #####
+    arr = mesh.getAdjEntIndices(root, iBase.type.all,
+                                iMesh.topology.all, iBase.type.all)
+    list = map(lambda x: x.tolist(), arr)
+
+    ##### 3 #####
+    timer.reset()
+    for x in range(100):
+        mesh.getEntAdj(arr[0], iBase.type.all)
+    py_stats[file].append( timer.delta()/100 )
+
+    timer.reset()
+    for x in range(100):
+        mesh.getEntAdj(list[0], iBase.type.all)
+    list_stats[file].append( timer.delta()/100 )
+
+    ##### 4 #####
+    timer.reset()
+    for x in range(100):
+        mesh.getEnt2ndAdj(arr[0], iBase.type.edge, iBase.type.vertex)
+    py_stats[file].append( timer.delta()/100 )
+
+    timer.reset()
+    for x in range(100):
+        mesh.getEnt2ndAdj(list[0], iBase.type.edge, iBase.type.vertex)
+    list_stats[file].append( timer.delta()/100 )
+
+    mesh = None
+    arr = None
+    list = None
+
+
+# for some reason, importing this earlier makes pytaps run faster????
+import matplotlib.pyplot as plt
+import numpy
+
+i = 1
+for file in filter(testable, os.listdir(path)):
+    ind = numpy.arange(len(py_stats[file]))
+    width = 0.25
+    plt.figure(i)
+    plt.title(file)
+    plt.ylabel('time (s)')
+    plt.xticks(ind+1.5*width,
+               ('load()','getAdjEntIndices()','getEntAdj()','getEnt2ndAdj()',
+                'getEntities()'))
+
+    bars1 = plt.bar(ind,         py_stats[file],   width, color='r')
+    bars2 = plt.bar(ind+width,   c_stats[file],    width, color='b')
+    bars3 = plt.bar(ind+2*width, list_stats[file], width, color='g')
+
+    plt.legend( (bars1[0], bars2[0], bars3[0]),
+                ('Python (array)', 'C', 'Python (list)'), loc=0 )
+
+    i+=1
+
+plt.show()



More information about the moab-dev mailing list