<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    Hi All,<br>
    <br>
    in my c++ code I've added Python binding via swig. one scenario is
    to pass a python function to do some computational work. the Python
    program runs in serial in the main thread but work is handled by a
    thread pool, the callback is invoked from another thread on unique
    data. Before a thread invokes the Python callback it acquires
    Python's GIL. Also I PyEval_InitThreads during module
    initialization, and have swig'd with -threads flag. However, I'm
    experiencing frequent crashes when thread pool size is greater than
    1, and valgrind is reporting errors from numpy even in case where
    thread pool size is 1.<br>
    <br>
    Here's the essence of the error reported by valgrind:<br>
    <blockquote><tt>==10316== Invalid read of size 4</tt><tt><br>
      </tt><tt>==10316==    at 0x4ED7D73: PyObject_Free
        (obmalloc.c:1013)</tt><tt><br>
      </tt><tt>==10316==    by 0x10D540B0: NpyIter_Deallocate
        (nditer_constr.c:699)</tt><tt><br>
      </tt><tt>....</tt><tt><br>
      </tt><tt>==10316==  Address 0x20034020 is 3,856 bytes inside a
        block of size 4,097 free'd</tt><tt><br>
      </tt><tt>==10316==    at 0x4C29E00: free (vg_replace_malloc.c:530)</tt><tt><br>
      </tt><tt>==10316==    by 0x4F57B22: import_module_level
        (import.c:2278)</tt><tt><br>
      </tt><tt>==10316==    by 0x4F57B22: PyImport_ImportModuleLevel
        (import.c:2292)</tt><tt><br>
      </tt><tt>==10316==    by 0x4F36597: builtin___import__
        (bltinmodule.c:49)</tt><tt><br>
      </tt><tt>==10316==    by 0x4E89AC2: PyObject_Call
        (abstract.c:2546)</tt><tt><br>
      </tt><tt>==10316==    by 0x4E89C1A: call_function_tail
        (abstract.c:2578)</tt><tt><br>
      </tt><tt>==10316==    by 0x4E89C1A: PyObject_CallFunction
        (abstract.c:2602)</tt><tt><br>
      </tt><tt>==10316==    by 0x4F58735: PyImport_Import
        (import.c:2890)</tt><tt><br>
      </tt><tt>==10316==    by 0x4F588B9: PyImport_ImportModule
        (import.c:2133)</tt><tt><br>
      </tt><tt>==10316==    by 0x10D334C2: get_forwarding_ndarray_method
        (methods.c:57)</tt><tt><br>
      </tt><tt>==10316==    by 0x10D372C0: array_mean (methods.c:1932)</tt><tt><br>
      </tt><tt>==10316==    by 0x4F40AC7: call_function (ceval.c:4350)</tt><br>
    </blockquote>
    There are a few of these reported. I'll attach the full output. This
    is from the simplest scenario, where the thread pool has a size of
    1. Although there are 2 threads, the program is serial as the main
    thread passes work tasks to the thread pool and waits for work to
    finish.<br>
    <br>
    Here is the work function where above occurs:<br>
    <blockquote><tt>def execute(port, data_in, req): </tt><br>
      <tt>    sys.stderr.write('descriptive_stats::execute MPI
        %d\n'%(rank))</tt><br>
      <br>
      <tt>    mesh = as_teca_cartesian_mesh(data_in[0])</tt><br>
      <br>
      <tt>    table = teca_table.New()</tt><br>
      <tt>    table.declare_columns(['step','time'], ['ul','d'])</tt><br>
      <tt>    table << mesh.get_time_step() <<
        mesh.get_time()</tt><br>
      <br>
      <tt>    for var_name in var_names:</tt><br>
      <br>
      <tt>        table.declare_columns(['min '+var_name, 'avg
        '+var_name, \</tt><br>
      <tt>            'max '+var_name, 'std '+var_name, 'low_q
        '+var_name, \</tt><br>
      <tt>            'med '+var_name, 'up_q '+var_name], ['d']*7)</tt><br>
      <br>
      <tt>        var = mesh.get_point_arrays().get(var_name).as_array()</tt><br>
      <br>
      <tt>        table << float(np.min(var)) <<
        float(np.average(var)) \</tt><br>
      <tt>            << float(np.max(var)) <<
        float(np.std(var)) \</tt><br>
      <tt>            << map(float, np.percentile(var,
        [25.,50.,75.]))</tt><br>
      <br>
      <tt>    return table</tt><br>
      <br>
    </blockquote>
    Again, I'm acquiring the GIL so this should be executed in serial.
    What am I doing wrong? Have I missed some key aspect of using numpy
    in this scenario? Any documentation on using numpy in a scenario
    like this? Any help is greatly appreciated!<br>
    <br>
    Thanks<br>
    Burlen<br>
    <br>
  </body>
</html>