Changeset: 9549fb2a415a for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9549fb2a415a
Added Files:
        sql/backends/monet5/Tests/rapi07.sql
        sql/backends/monet5/Tests/rapi07.stable.err
        sql/backends/monet5/Tests/rapi07.stable.out
Modified Files:
        monetdb5/extras/rapi/rapi.R
        monetdb5/extras/rapi/rapi.c
        monetdb5/extras/rapi/rapi.h
        monetdb5/extras/rapi/rapi.mal
        sql/backends/monet5/Tests/All
Branch: RIntegration
Log Message:

R Integration:
- Setting LD_LIBRARY_PATH to RHOME/lib, no more messing with environment 
neccessary
- Fixed race condition when two MAL functions try to initialize R at the same 
time (prelude)
- Test case and approved output for above
- Added row limit of 900M (known to work, 1B does not)
- Replaced R parser assertion by error, since it could be triggered from user 
interaction


diffs (truncated from 3285 to 300 lines):

diff --git a/monetdb5/extras/rapi/rapi.R b/monetdb5/extras/rapi/rapi.R
--- a/monetdb5/extras/rapi/rapi.R
+++ b/monetdb5/extras/rapi/rapi.R
@@ -27,7 +27,8 @@ library <- function(package, help, pos =
     logical.return = FALSE, warn.conflicts = TRUE, quietly = FALSE, 
     verbose = getOption("verbose")) {
 
-       package <- as.character(substitute(package))
+       if (!character.only) 
+           package <- as.character(substitute(package))
        if (!(package %in% installed.packages()[,"Package"])) 
                
install.packages(package,repos=c("http://cran.rstudio.com/";),lib=.rapi.libdir,quiet=T)
        
diff --git a/monetdb5/extras/rapi/rapi.c b/monetdb5/extras/rapi/rapi.c
--- a/monetdb5/extras/rapi/rapi.c
+++ b/monetdb5/extras/rapi/rapi.c
@@ -136,8 +136,10 @@ char* rtypename(int rtypeid) {
 void writeConsoleEx(const char * buf, int buflen, int foo) {
        (void) buflen;
        (void) foo;
-       // TODO: do we really want to write this to the console?
+       (void) buf; // silence compiler
+#ifdef _RAPI_DEBUG_
        THRprintf(GDKout, "# %s", buf);
+#endif
 }
 
 void writeConsole(const char * buf, int buflen) {
@@ -145,9 +147,14 @@ void writeConsole(const char * buf, int 
 }
 
 static int RAPIinitialize(void) {
-       MT_lock_init(&rapiLock, "rapi_lock");
        // set R_HOME for packages etc. We know this from our configure script.
-       setenv("R_HOME", RHOME, TRUE);
+       {
+               char lpath[BUFSIZ];
+               setenv("R_HOME", RHOME, TRUE);
+               // this is so the R interpreter finds libR.so
+               snprintf(lpath, BUFSIZ, "%s%c%s", RHOME, DIR_SEP, "lib");
+               setenv("LD_LIBRARY_PATH", lpath, TRUE);
+       }
 
 #ifdef _RAPI_DEBUG_
        printf("# R libraries installed in %s\n",rlibs);
@@ -160,7 +167,7 @@ static int RAPIinitialize(void) {
        {
                structRstart rp;
                Rstart Rp = &rp;
-               char *rargv[] = { "R" ,"--vanilla"};
+               char *rargv[] = { "R" ,"--slave","--vanilla"};
                int stat;
 
                R_DefParams(Rp);
@@ -187,17 +194,15 @@ static int RAPIinitialize(void) {
 
        /* disable stack checking, because threads will throw it off */
        R_CStackLimit = (uintptr_t) -1;
+       /* redirect input/output and set error handler */
        R_Outputfile = NULL;
        R_Consolefile = NULL;
-
        ptr_R_WriteConsoleEx = writeConsoleEx;
        ptr_R_WriteConsole = writeConsole;
-
        ptr_R_ReadConsole = NULL;
 
        // big boy here
        setup_Rmainloop();
-
        {
                int evalErr;
                ParseStatus status;
@@ -234,7 +239,6 @@ static int RAPIinitialize(void) {
                        return 5;
                }
        }
-
        rapiInitialized++;
        return 0;
 }
@@ -258,6 +262,9 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
        BUN cnt;
        int initstatus = 0;
 
+       // we don't need no context, but the compiler needs us to touch it (...)
+       (void) cntxt;
+
        if (!RAPIEnabled()) {
                throw(MAL, "rapi.eval", "Embedded R has not been enabled. Start 
server with --set %s=true",rapi_enableflag);
        }
@@ -273,9 +280,8 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
                throw(MAL, "rapi.eval", MAL_MALLOC_FAIL);
        }
 
-       // we don't need no context, but the compiler needs us to touch it (...)
-       (void) cntxt;
-
+       // get the lock even before initialization of the R interpreter, as 
this can take a second and must be done only once.
+       MT_lock_set(&rapiLock, "rapi.evaluate");
        /* startup internal R environment if needed */
        if (!rapiInitialized) {
                initstatus = RAPIinitialize();
@@ -285,7 +291,6 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
                }
        }
 
-       MT_lock_set(&rapiLock, "rapi.evaluate");
        env = PROTECT(eval(lang1(install("new.env")),R_GlobalEnv));
        assert(env != NULL);
 
@@ -313,6 +318,12 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
                                goto wrapup;
                        }
                }
+
+               // check the BAT count, if it is bigger than RAPI_MAX_TUPLES, 
fail
+               if (BATcount(b) > RAPI_MAX_TUPLES) {
+                       msg = createException(MAL, "rapi.eval", "Got %lu rows, 
but can only handle %lu. Sorry.",BATcount(b),RAPI_MAX_TUPLES);
+                       goto wrapup;
+               }
                sprintf(buf, "arg%d", k++);
                args[i] = GDKstrdup(buf);
                varname = PROTECT(Rf_install(args[i]));
@@ -388,9 +399,8 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
                        argnames, exprStr, argnames);
 
        x = R_ParseVector(mkString(rcall), 1, &status, R_NilValue);
-       assert(LENGTH(x) == 1);
 
-       if (status != PARSE_OK) {
+       if (LENGTH(x) != 1 || status != PARSE_OK) {
                msg = createException(MAL, "rapi.eval",
                                "Error parsing R expression '%s'. ", exprStr);
                goto wrapup;
@@ -535,3 +545,8 @@ str RAPIeval(Client cntxt, MalBlkPtr mb,
 
        return msg;
 }
+
+str RAPIprelude(void) {
+       MT_lock_init(&rapiLock, "rapi_lock");
+       return MAL_SUCCEED;
+}
diff --git a/monetdb5/extras/rapi/rapi.h b/monetdb5/extras/rapi/rapi.h
--- a/monetdb5/extras/rapi/rapi.h
+++ b/monetdb5/extras/rapi/rapi.h
@@ -38,8 +38,11 @@
 #define rapi_export extern
 #endif
 
+#define RAPI_MAX_TUPLES 900000000L
+
 rapi_export str RAPIeval(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
                InstrPtr pci);
+rapi_export str RAPIprelude(void);
 
 rapi_export void writeConsoleEx(const char * buf, int buflen, int foo);
 rapi_export void writeConsole(const char * buf, int buflen);
diff --git a/monetdb5/extras/rapi/rapi.mal b/monetdb5/extras/rapi/rapi.mal
--- a/monetdb5/extras/rapi/rapi.mal
+++ b/monetdb5/extras/rapi/rapi.mal
@@ -35,6 +35,11 @@ pattern eval_aggr(expr:str,arg:any...):a
 address RAPIeval
 comment "grouped aggregates through R";
 
+# initializer code
+command prelude() :void
+address RAPIprelude;
+rapi.prelude();
+
 # sql compiler needs these functions for bat-wise operations
 module batrapi;
 
@@ -49,6 +54,3 @@ comment "Execute a simple R script value
 pattern eval_aggr(expr:str,arg:any...):any...
 address RAPIeval
 comment "grouped aggregates through R";
-
-#  rapi.subeval_aggr(_15:bat[:oid,:int], _9:bat[:oid,:oid], 
r1_9:bat[:oid,:oid], _17:bit)
-
diff --git a/sql/backends/monet5/Tests/All b/sql/backends/monet5/Tests/All
--- a/sql/backends/monet5/Tests/All
+++ b/sql/backends/monet5/Tests/All
@@ -7,6 +7,7 @@ HAVE_LIBR?rapi03
 HAVE_LIBR?rapi04
 HAVE_LIBR?rapi05
 HAVE_LIBR?rapi06
+HAVE_LIBR?rapi07
 
 #inlineR disabled, we have better R tests
 inlineUDF
diff --git a/sql/backends/monet5/Tests/rapi07.sql 
b/sql/backends/monet5/Tests/rapi07.sql
new file mode 100644
--- /dev/null
+++ b/sql/backends/monet5/Tests/rapi07.sql
@@ -0,0 +1,1007 @@
+START TRANSACTION;
+
+CREATE TABLE rval(val double);
+INSERT INTO rval VALUES (33078.94);
+INSERT INTO rval VALUES (38306.16);
+INSERT INTO rval VALUES (15479.68);
+INSERT INTO rval VALUES (34616.68);
+INSERT INTO rval VALUES (28974.00);
+INSERT INTO rval VALUES (44842.88);
+INSERT INTO rval VALUES (63066.32);
+INSERT INTO rval VALUES (86083.65);
+INSERT INTO rval VALUES (70822.15);
+INSERT INTO rval VALUES (39620.34);
+INSERT INTO rval VALUES (3581.56);
+INSERT INTO rval VALUES (52411.80);
+INSERT INTO rval VALUES (35032.14);
+INSERT INTO rval VALUES (39819.00);
+INSERT INTO rval VALUES (25179.60);
+INSERT INTO rval VALUES (31387.20);
+INSERT INTO rval VALUES (68864.50);
+INSERT INTO rval VALUES (53697.73);
+INSERT INTO rval VALUES (17273.04);
+INSERT INTO rval VALUES (12423.15);
+INSERT INTO rval VALUES (84904.50);
+INSERT INTO rval VALUES (46245.92);
+INSERT INTO rval VALUES (74398.68);
+INSERT INTO rval VALUES (55806.45);
+INSERT INTO rval VALUES (7216.50);
+INSERT INTO rval VALUES (26963.72);
+INSERT INTO rval VALUES (40995.52);
+INSERT INTO rval VALUES (3091.16);
+INSERT INTO rval VALUES (5393.68);
+INSERT INTO rval VALUES (46642.64);
+INSERT INTO rval VALUES (6978.84);
+INSERT INTO rval VALUES (39224.92);
+INSERT INTO rval VALUES (34948.80);
+INSERT INTO rval VALUES (8803.10);
+INSERT INTO rval VALUES (49780.56);
+INSERT INTO rval VALUES (20768.41);
+INSERT INTO rval VALUES (24817.98);
+INSERT INTO rval VALUES (8558.10);
+INSERT INTO rval VALUES (33708.00);
+INSERT INTO rval VALUES (44788.54);
+INSERT INTO rval VALUES (13026.23);
+INSERT INTO rval VALUES (42317.50);
+INSERT INTO rval VALUES (42877.74);
+INSERT INTO rval VALUES (45516.80);
+INSERT INTO rval VALUES (74029.62);
+INSERT INTO rval VALUES (48691.20);
+INSERT INTO rval VALUES (69449.25);
+INSERT INTO rval VALUES (45538.29);
+INSERT INTO rval VALUES (63681.20);
+INSERT INTO rval VALUES (49288.36);
+INSERT INTO rval VALUES (46194.72);
+INSERT INTO rval VALUES (58892.42);
+INSERT INTO rval VALUES (57788.48);
+INSERT INTO rval VALUES (52982.88);
+INSERT INTO rval VALUES (68665.20);
+INSERT INTO rval VALUES (30837.66);
+INSERT INTO rval VALUES (52933.66);
+INSERT INTO rval VALUES (26050.42);
+INSERT INTO rval VALUES (37545.27);
+INSERT INTO rval VALUES (37916.72);
+INSERT INTO rval VALUES (78670.80);
+INSERT INTO rval VALUES (5069.36);
+INSERT INTO rval VALUES (21910.92);
+INSERT INTO rval VALUES (10159.55);
+INSERT INTO rval VALUES (48887.96);
+INSERT INTO rval VALUES (23784.30);
+INSERT INTO rval VALUES (33001.13);
+INSERT INTO rval VALUES (4925.01);
+INSERT INTO rval VALUES (84764.66);
+INSERT INTO rval VALUES (84721.88);
+INSERT INTO rval VALUES (26424.60);
+INSERT INTO rval VALUES (40541.31);
+INSERT INTO rval VALUES (46006.50);
+INSERT INTO rval VALUES (63853.40);
+INSERT INTO rval VALUES (54433.44);
+INSERT INTO rval VALUES (55447.68);
+INSERT INTO rval VALUES (29539.20);
+INSERT INTO rval VALUES (3279.00);
+INSERT INTO rval VALUES (72225.30);
+INSERT INTO rval VALUES (25852.69);
+INSERT INTO rval VALUES (9761.92);
+INSERT INTO rval VALUES (20974.98);
+INSERT INTO rval VALUES (1186.00);
+INSERT INTO rval VALUES (14182.41);
+INSERT INTO rval VALUES (50996.73);
+INSERT INTO rval VALUES (30371.88);
+INSERT INTO rval VALUES (30631.75);
+INSERT INTO rval VALUES (3330.36);
+INSERT INTO rval VALUES (61348.50);
+INSERT INTO rval VALUES (49876.20);
+INSERT INTO rval VALUES (57583.11);
+INSERT INTO rval VALUES (47574.50);
+INSERT INTO rval VALUES (38862.87);
+INSERT INTO rval VALUES (58554.90);
+INSERT INTO rval VALUES (24241.36);
+INSERT INTO rval VALUES (61777.05);
+INSERT INTO rval VALUES (39272.24);
+INSERT INTO rval VALUES (29739.92);
+INSERT INTO rval VALUES (1424.37);
+INSERT INTO rval VALUES (14056.42);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to