Menu

#104 R cannot initialize more than once in process

rpy
open
nobody
Source (9)
5
2014-08-17
2008-08-20
Anonymous
No

Hello,

I am currently working with a software package (ArcGIS) that runs Python “In Process”. There has been a call from our users to be able to integrate R functionality. Our “Out of Proc” version allows us to call rpy over and over again because it is essentially re-initializing the R() instance on each run. But when we switch it over to the “In Proc” version we get the following error message:

Traceback (most recent call last):
File "<string>", line 29, in <module>
File "<string>", line 8, in testPoly2Line
File "C:\Python25\lib\site-packages\rpy.py", line 346, in <module> r = R()
File "C:\Python25\lib\site-packages\rpy.py", line 286, in init _rpy.r_init(HAS_NUMERIC);
RuntimeError: Only one R object may be instantiated per session</module></string></module></string>

The problem can be explained by the following set of issues: 1) We embed Python in our application for use as a scripting engine, 2) Each time a Python script is run in the application, it is from a new Python session (i.e. a brand new set of locals and globals) but in the same process, 3) When importing the Python R libraries, it binds the RPy .DLL into process, 4) In Python R�s startup, there is a static integer in _rpy.r_init used as a flag that determines if R has already been loaded. The rest of the function initializes numeric if sent the flag to do so, and throws a RuntimeError if R was initialized before. Since the library is still resident in memory even after the Python session goes away, this stays set to 1. Looking at the C implementation of the r_init function, this seems unnecessary and there have been no ill effects from patching the Python to ignore the error. After a cursory read over the Python, this appears to be a piece of legacy that isn�t necessary anymore as it does not affect anything else.

We have a hack that allows us to run it In Proc and we wanted to know if it is appropriate: (On Line ~ 286 of rpy.py)

   try:
           _rpy.r_init(HAS_NUMERIC)
   except RuntimeError, e:
          pass
   _rpy.set_mode(NO_DEFAULT)

So in our case, RPython�s refusal to instantiate another instance of the R() object by throwing a RuntimeError is considered a bug, because the binary library is already initialized and resident in memory, its related Python locals just went away and need to be allowed to reset. Ignoring the error is idea, but warning instead of throwing is, at the very least, preferable. Ideally the code in C would more resemble this:

static PyObject *
r_init(PyObject self, PyObject args)
{
static int first=1;
int i;

if (!PyArg_ParseTuple(args, "i:r_init", &i))
return NULL;
use_numeric = i;

if(first==1)
{
#ifdef WITH_NUMERIC
if(use_numeric)
init_numeric();
#endif

  first=0;
}

Py_INCREF(Py_None);
return Py_None;
}

Thanks so much ahead of time. Best wishes,

MJ

Mark Janikas
Product Engineer
ESRI, Geoprocessing
380 New York St.
Redlands, CA 92373
909-793-2853 (2563)
mjanikas@esri.com

Discussion

  • Mark  Janikas

    Mark Janikas - 2008-09-15

    Just found the same error in RPy2.

    <type 'exceptions.runtimeerror'="">: R can only be initialized once.</type>

     
  • lgautier

    lgautier - 2008-09-19

    Could provide version numbers for the version you tried ?
    It was fixed for rpy2 few weeks ago.

    import rpy2.rinterface as ri
    ri.initr()
    0
    ri.initr()
    0

     

Anonymous
Anonymous

Add attachments
Cancel