Re: Calling python from C with OpenMP

2016-05-13 Thread Paul Rubin
Dennis Lee Bieber  writes:
>   It's been tried -- but the non-GIL implementations tend to be
> slower at everything else.

Has Micropython been compared?  CPython needs the GIL because of its
frequent twiddling of reference counts.  Without the GIL, multi-threaded
CPython would have to acquire and release a lock whenever it touched a
refcount, which slows things down badly.

MicroPython uses a tracing garbage collector instead of refcounts, so
there's no issue of having to lock refcounts all the time.  It's fairly
common in such systems to stop all the user threads during GC, but they
can happily run in parallel the rest of the time.  

Come to think of it, I don't know if MicroPython currently supports
threads at all!  But its implementation style (i.e. no refcounts) is
more parallelism-friendly than CPython's.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Calling python from C with OpenMP

2016-05-13 Thread Øystein Schønning-Johansen
On Friday, May 13, 2016 at 7:12:33 PM UTC+2, MRAB wrote:
> Every PyGILState_Ensure call must be matched with a PyGILState_Release 
> call. The way it's currently written, it won't call PyGILState_Release 
> if ret is NULL.

Yeah, that's tiny bug, however it is not the main problem...
 
> However, I don't think you'll gain much here because you can gain from 
> multi-threading only if the threads can run in parallel. You need to 
> hold the GIL while making Python calls, and only 1 thread can hold the 
> GIL at any time.

In addition to the fact that it still does not work, what you here point out, 
is the main problem. I actually think I'm giving up for now. Maybe I'm able to 
solve this later (when python does not use a GIL anymore...?)

Thanks to Sturla and MRAB anyway!
-Øystein

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Calling python from C with OpenMP

2016-05-13 Thread MRAB

On 2016-05-13 17:22, Øystein Schønning-Johansen wrote:

On Friday, May 13, 2016 at 2:04:53 AM UTC+2, Sturla Molden wrote:

You must own the GIL before you can safely use the Python C API, object
creation and refcounting in particular. Use the "Simplified GIL API" to
grab the GIL and release it when you are done.


I've now read about the GIL and it looks like I am in deep problems.

I've added the GILState lock to the threaded loop like this:

#pragma omp parallel for
for( int i = 0; i < 10; i++ ){
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
PyObject *ret = PyObject_CallMethod( mult_obj, "do_multiply", "i", i );
if( !ret ){
printf("Cannot call 'do_multiply'\n");
continue;
}
printf("The value calculated in Python was: %3d\n", (int) 
PyLong_AsLong(ret));
Py_DECREF(ret);
PyGILState_Release(gstate);
}

 but still no success. Have I done it right?

regs,
-Øystein

Every PyGILState_Ensure call must be matched with a PyGILState_Release 
call. The way it's currently written, it won't call PyGILState_Release 
if ret is NULL.


However, I don't think you'll gain much here because you can gain from 
multi-threading only if the threads can run in parallel. You need to 
hold the GIL while making Python calls, and only 1 thread can hold the 
GIL at any time.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Calling python from C with OpenMP

2016-05-13 Thread Øystein Schønning-Johansen
On Friday, May 13, 2016 at 2:04:53 AM UTC+2, Sturla Molden wrote:
> You must own the GIL before you can safely use the Python C API, object
> creation and refcounting in particular. Use the "Simplified GIL API" to
> grab the GIL and release it when you are done.

I've now read about the GIL and it looks like I am in deep problems. 

I've added the GILState lock to the threaded loop like this:

#pragma omp parallel for
for( int i = 0; i < 10; i++ ){
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
PyObject *ret = PyObject_CallMethod( mult_obj, "do_multiply", "i", i );
if( !ret ){
printf("Cannot call 'do_multiply'\n");
continue;
}
printf("The value calculated in Python was: %3d\n", (int) 
PyLong_AsLong(ret));
Py_DECREF(ret);
PyGILState_Release(gstate);
}

 but still no success. Have I done it right?

regs,
-Øystein
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Calling python from C with OpenMP

2016-05-12 Thread Sturla Molden
 wrote:

> Second and most important question: When I run this code it sometimes
> segementation faults, and sometimes some threads run normal and some
> other threads says "Cannot call 'do_multiply'". Sometimes I get the
> message: Fatal Python error: GC object already tracked. And some times it
> even runs normally...
> I understand there is some kind of race condition here, where python
> tries to refer to some memory that has been already released. But how can
> I avoid this? What am I doing wrong? (or, less likely, is this a bug?)


You must own the GIL before you can safely use the Python C API, object
creation and refcounting in particular. Use the "Simplified GIL API" to
grab the GIL and release it when you are done.

-- 
https://mail.python.org/mailman/listinfo/python-list


Calling python from C with OpenMP

2016-05-12 Thread oysteijo
Hi,

I have a framework written in C and I need to call Python from that framework. 
I have written the code, and it runs fine, however when I recompile with OpenMP 
enabled, I get segmentation faults and some times an error message: 

Fatal Python error: GC object already tracked

I'm able to reconstruct the bug with this simple code:

/* main.c */
#include 
#include 
int main()
{
wchar_t *program = Py_DecodeLocale( "My_problem", NULL );
if( !program ){
fprintf(stderr, "cannot decode python program name\n");
return -1;
}

Py_SetProgramName( program );
Py_Initialize();

PyObject *sys = PyImport_ImportModule("sys");
PyObject *path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyUnicode_FromString("."));

PyObject *module_filename = PyUnicode_FromString( "multiplier" );
if(!module_filename){
printf("Cannot create python module  multiplier.\n");
return -1;
}
PyObject *module = PyImport_Import( module_filename );
if(!module){
printf("Cannot create python.\n");
return -1;
}

PyObject *mult_obj = PyObject_CallMethod( module ,"multiplier", "i", 7);
if(!mult_obj){
printf("Cannot create python multiplier class instance\n");
return -1;
}

Py_DECREF( module );
Py_DECREF( module_filename );
Py_DECREF( path );
Py_DECREF( sys );
/* Up to now we have actually done:
 * >>> import multiplier
 * >>> mult_obj = multipier.multiplier(7)
 */

/* lets try something like:
 * >>> for x in range(10):
 * ... printf(mult_obj.do_multiply(x))
 */

#pragma omp parallel for 
for( int i = 0; i < 10; i++ ){
PyObject *ret = PyObject_CallMethod( mult_obj, "do_multiply", "i", i );
if( !ret ){
printf("Cannot call 'do_multiply'\n");
continue;
}
printf("The value calculated in Python was: %3d\n", (int) 
PyLong_AsLong(ret));
Py_DECREF(ret);
}

Py_DECREF(mult_obj);
Py_Finalize();

return 0;
} 

Compile with:
gcc -std=gnu99 -O3 -Wall -Wextra -fopenmp `pkg-config --cflags --libs python3` 
-lgomp main.c -o main

Then you need the python code:

# multiplier.py
class multiplier(object):
def __init__(self, factor):
self.factor = factor
def do_multiply(self, x):
return self.factor * x

First question: Does my C code leak memory? Valgrind says it does, but the 
memory footprint of the executable is stable while looping?

Second and most important question: When I run this code it sometimes 
segementation faults, and sometimes some threads run normal and some other 
threads says "Cannot call 'do_multiply'". Sometimes I get the message: Fatal 
Python error: GC object already tracked. And some times it even runs normally...
I understand there is some kind of race condition here, where python tries to 
refer to some memory that has been already released. But how can I avoid this? 
What am I doing wrong? (or, less likely, is this a bug?)

Maybe needless to say, but the code works when compiled w/o OpenMP.

Using Python 3.5.1

Thanks,
-Øystein
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: calling python from C#...

2006-01-28 Thread Ravi Teja
Python for .NET
http://www.zope.org/Members/Brian/PythonNet

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: calling python from C#...

2006-01-28 Thread Ravi Teja
I actually find Python for .NET most convenient
http://www.zope.org/Members/Brian/PythonNet

I did not try py2exe with these applications, so I cannot comment.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: calling python from C#...

2006-01-23 Thread Jens Theisen
There is IronPython which compiles to .NET. And there was another project  
bridging the .NET runtime with the standard Python interpreter of which I  
forgot the name.

Jens

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: calling python from C#...

2006-01-22 Thread Mr BigSmoke
I use python for .NET in some applications... I've always used it for
using c# code from python (but i had some problems using it with py2exe
and win2000).  I'll try using it the other way (c# calling python).
I also thought about trying ironpython, but it's too young for my work
projects...
The COM aproach seemed more stable to me what do u think?

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: calling python from C#...

2006-01-22 Thread Ravi Teja
Writing COM Servers is not hard
http://www.python.org/windows/win32com/QuickStartServerCom.html

IronPython is the other way.

Choose COM Server approach if you are using the a lot of standard
library functions (as I recall IronPython is not complete here, yet).
Definitely choose this approach if you are using C extensions to
Python.

IronPython is good for simpler Python tasks at this moment. Expect this
to change in the future. Of course, there is always XML-RPC, SOAP,
CORBA etc for language independence if you don't mind Client/Server
setup.

You can also write code in C# and drive it from Python. Check Python
for .NET.

-- 
http://mail.python.org/mailman/listinfo/python-list


calling python from C#...

2006-01-22 Thread Mr BigSmoke
Hi everybody,
I need write an application in c#, but i wnat to use some functions
that i have already written in python. Is there an "easy" way to call
my python code from c#? I must use COM or there are other ways? And, if
COM is the only way, where can i find some tutorials or examples? I've
never wrote com server and i really don't know where and how to
start
tnx
Fabio

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: segfault when calling Python from C thread

2005-02-21 Thread Greg Chapman
Fredrik Lundh wrote:

> Greg Chapman wrote:
> 
> > Your callback function needs to hold the Python GIL (and have a
> > vaild threadstate) before it calls any Python C-API functions.
> > Change the last part of it to:
> > 
> >PyGILState_STATE state;
> > 
> >/* ... */
> > 
> >/* Time to call the callback */
> > 
> >state = PyGILState_Ensure();
> > 
> >arglist = Py_BuildValue("(s)", str);
> >result = PyEval_CallObject(my_callback, arglist);
> >Py_DECREF(arglist);
> >if(result == NULL)
> >return;
> >Py_DECREF(result);
> > 
> >PyGILState_Release(state);
> > }
> 
> you might wish to make sure you release the GIL even if the callback
> raises an exception...
> 
>  

Argh, thanks for catching that.  You probably put that too politely
though (in case anyone sees this who might think that is optional): one
should absolutely make sure all code paths which call PyGILState_Ensure
have a matching call to PyGILState_Release.

---
Greg Chapman
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: segfault when calling Python from C thread

2005-02-20 Thread Fredrik Lundh
Greg Chapman wrote:

> Your callback function needs to hold the Python GIL (and have a vaild
> threadstate) before it calls any Python C-API functions.  Change the
> last part of it to:
>
>PyGILState_STATE state;
>
>/* ... */
>
>/* Time to call the callback */
>
>state = PyGILState_Ensure();
>
>arglist = Py_BuildValue("(s)", str);
>result = PyEval_CallObject(my_callback, arglist);
>Py_DECREF(arglist);
>if(result == NULL)
>return;
>Py_DECREF(result);
>
>PyGILState_Release(state);
> }

you might wish to make sure you release the GIL even if the callback
raises an exception...

 



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: segfault when calling Python from C thread

2005-02-20 Thread Greg Chapman
Travis Berg wrote:

> 
> I'm running into a problem when trying to perform a callback to a
> Python function from a C extension.  Specifically, the callback is
> being made by a pthread that seems to cause the problem.  If I call
> the callback from the parent process, it works fine.  The PyObject is
> static, and holds the same value in both Parent and thread, so I'm at
> a loss as to what would be different in the pthread from the parent
> that would cause a segfault on the callback.  The machine specifics
> are an x86 intel processor with RedHat linux.
> 
> 
> /* calling callback */
> void callback(char * str) {
> PyObject *arglist;
> PyObject *result;
> if(str == NULL)
> return;
> 
> if(my_callback == NULL) {
> printf("no callback function provided, returning...\n");
> return;
> }
> 
> /* Time to call the callback */
> arglist = Py_BuildValue("(s)", str);
> result = PyEval_CallObject(my_callback, arglist);
> Py_DECREF(arglist);
> if(result == NULL)
> return;
> Py_DECREF(result);
> }

Your callback function needs to hold the Python GIL (and have a vaild
threadstate) before it calls any Python C-API functions.  Change the
last part of it to:

PyGILState_STATE state;

/* ... */

/* Time to call the callback */

state = PyGILState_Ensure();

arglist = Py_BuildValue("(s)", str);
result = PyEval_CallObject(my_callback, arglist);
Py_DECREF(arglist);
if(result == NULL)
return;
Py_DECREF(result);

PyGILState_Release(state);
}

Also, somewhere in your main thread you should call PyEval_InitThreads
before any of the callback threads execute.  (This call is made
automatically if you are creating new threads using Python's thread
module, but if the new threads are created by some C code, you need to
call it yourself.)

---
Greg Chapman
-- 
http://mail.python.org/mailman/listinfo/python-list


segfault when calling Python from C thread

2005-02-19 Thread Travis Berg

I'm running into a problem when trying to perform a callback to a Python
function from a C extension.  Specifically, the callback is being made by
a pthread that seems to cause the problem.  If I call the callback from
the parent process, it works fine.  The PyObject is static, and holds the
same value in both Parent and thread, so I'm at a loss as to what would be
different in the pthread from the parent that would cause a segfault on
the callback.  The machine specifics are an x86 intel processor with
RedHat linux.

Here is some clips of the C callback code showing how I'm storing the
callback, then what the actual callback function is like.  Any ideas?
The function being called is a simply to display the string of text, and
execution never seems to reach back to the Python code at all.

Thanks,
Travis B.


/* callback function to the Python code */
static PyObject * my_callback = NULL;

/* setting callback function */
static PyObject * my_set_callback(PyObject *dummy, PyObject *args)
{
PyObject *result = NULL;
PyObject *temp;
PyObject *arglist;

if (PyArg_ParseTuple(args, "O:set_callback", &temp)) {
if (!PyCallable_Check(temp)) {
PyErr_SetString(PyExc_TypeError,
"parameter must be callable");
return NULL;
}
Py_XINCREF(temp); /* Add a reference to new callback */
Py_XDECREF(my_callback);  /* Dispose of previous callback */
my_callback = temp;   /* Remember new callback */
/* return "None" */
Py_INCREF(Py_None);
result = Py_None;
}
return result;
}

/* calling callback */
void callback(char * str) {
PyObject *arglist;
PyObject *result;
if(str == NULL)
return;

if(my_callback == NULL) {
printf("no callback function provided, returning...\n");
return;
}

/* Time to call the callback */
arglist = Py_BuildValue("(s)", str);
result = PyEval_CallObject(my_callback, arglist);
Py_DECREF(arglist);
if(result == NULL)
return;
Py_DECREF(result);
}
-- 
http://mail.python.org/mailman/listinfo/python-list