[R] anyone has C++ STL classes stability issue if used with R
Hello, is there any one who uses C++ STL classes when programming shared libs for R and has had any problems with STL? In the very simple example below I am constantly getting segfaults when trying to populate the queue. The segfault occurs at what looks like a random index in the loop when pushing another element to the queue. Reproduced on 4 machines. Object x is an Image as in EBImage, i.e. a 3D R-array of numerics for the purpose of this code. LENGTH(x) can be up to 1e6 and the number of elements potentially to be in the queue is about 20% of those. But I get segfaults often on a third of fours element being added. Tried on R2.5.0-devel, R2.4.1-release and all machines were 64bit Linux with kernels 2.6.9 (stable CentOS), 2.6.17 (stable Ubuntu) and 2.6.20 (Ubuntu devel). Here are the compilation options of this particular module (built as part of EBImage, which generally compiles and works just fine): -- g++ -I/home/osklyar/R/R-2.5.0-40659/include -I/home/osklyar/R/R-2.5.0-40659/include -I/usr/local/include -DUSE_GTK -DGLIB_GETTEXT -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -g -O2 -Wall -pthread -I/usr/include -O2 -g -O2 -g -fpic -O2 -g -c filters_watershed.cpp -o filters_watershed.o -- And the linker: -- g++ -shared -L/usr/local/lib64 -o EBImage.so colors.o conversions.o display.o filters_distmap.o filters_magick.o filters_morph.o filters_propagate.o filters_thresh.o filters_watershed.o init.o io.o object_counting.o tools.o -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXfixes -lpango-1.0 -lcairo -lX11 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -L/usr/lib -L/usr/X11R6/lib -lfreetype -lz -L/usr/lib -lMagick -llcms -ltiff -lfreetype -ljasper -ljpeg -lpng -lXext -lSM -lICE -lX11 -lbz2 -lxml2 -lz -lpthread -lm -lpthread -- It could be I am missing something totally simple and therefore get these errors, but I cannot identify what. Thanks for help, Oleg - // common.h also includes R includes: // #include R.h // #include Rdefines.h // #include R_ext/Error.h #include common.h #include queue using namespace std; struct Pixel { int x, y; double intens; /* the code will also fail with the same segfault if I remove all * the constructors here and use the commented block below instead * of pq.push( Pixel(i, j, val) */ Pixel() {x = 0; y = 0; intens = 0; }; Pixel(const Pixel px) { x = px.x; y = px.y; intens = px.intens; }; Pixel(int i, int j, double val): x(i), y(j), intens(val) {}; }; bool operator (const Pixel a, const Pixel b) { return a.intens b.intens; }; typedef priority_queuePixel PixelPrQueue; SEXP lib_filterInvWS (SEXP x) { SEXP res; int i, j, index; double val; PixelPrQueue pq; int nx = INTEGER ( GET_DIM(x) )[0]; int ny = INTEGER ( GET_DIM(x) )[1]; int nz = INTEGER ( GET_DIM(x) )[2]; int nprotect = 0; PROTECT ( res = Rf_duplicate(x) ); nprotect++; // Pixel px; for (int im = 0; im nz; im++ ) { double * src = ( REAL(x)[ im * nx * ny ] ); double * tgt = ( REAL(res)[ im * nx * ny ] ); for ( j = 0; j ny; j++ ) for ( i = 0; i nx; i++ ) { index = i + nx * j; val = src[ index ]; if ( val BG ) { tgt[ index ] = -1; // px.x = i; px.y = j; px.intens = val; pq.push(px); pq.push( Pixel(i, j, val) ); continue; } tgt[ index ] = BG; } } /* my main code was here, but deleted for debug */ UNPROTECT (nprotect); return res; } -- Dr Oleg Sklyar * EBI/EMBL, Cambridge CB10 1SD, England * +44-1223-494466 __ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
[R] anyone has C++ STL classes stability issue if used with R
Continued: With the following modifications (using pointers) it works (needs memory cleaning afterwards and new less operator though) and I do not understand why: typedef priority_queuePixel * PixelPrQueue; ... pq.push( new Pixel(i, j, val) ); ... Oleg Sklyar wrote: Hello, is there any one who uses C++ STL classes when programming shared libs for R and has had any problems with STL? In the very simple example below I am constantly getting segfaults when trying to populate the queue. The segfault occurs at what looks like a random index in the loop when pushing another element to the queue. Reproduced on 4 machines. Object x is an Image as in EBImage, i.e. a 3D R-array of numerics for the purpose of this code. LENGTH(x) can be up to 1e6 and the number of elements potentially to be in the queue is about 20% of those. But I get segfaults often on a third of fours element being added. Tried on R2.5.0-devel, R2.4.1-release and all machines were 64bit Linux with kernels 2.6.9 (stable CentOS), 2.6.17 (stable Ubuntu) and 2.6.20 (Ubuntu devel). Here are the compilation options of this particular module (built as part of EBImage, which generally compiles and works just fine): -- g++ -I/home/osklyar/R/R-2.5.0-40659/include -I/home/osklyar/R/R-2.5.0-40659/include -I/usr/local/include -DUSE_GTK -DGLIB_GETTEXT -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -g -O2 -Wall -pthread -I/usr/include -O2 -g -O2 -g -fpic -O2 -g -c filters_watershed.cpp -o filters_watershed.o -- And the linker: -- g++ -shared -L/usr/local/lib64 -o EBImage.so colors.o conversions.o display.o filters_distmap.o filters_magick.o filters_morph.o filters_propagate.o filters_thresh.o filters_watershed.o init.o io.o object_counting.o tools.o -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXfixes -lpango-1.0 -lcairo -lX11 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -L/usr/lib -L/usr/X11R6/lib -lfreetype -lz -L/usr/lib -lMagick -llcms -ltiff -lfreetype -ljasper -ljpeg -lpng -lXext -lSM -lICE -lX11 -lbz2 -lxml2 -lz -lpthread -lm -lpthread -- It could be I am missing something totally simple and therefore get these errors, but I cannot identify what. Thanks for help, Oleg - // common.h also includes R includes: // #include R.h // #include Rdefines.h // #include R_ext/Error.h #include common.h #include queue using namespace std; struct Pixel { int x, y; double intens; /* the code will also fail with the same segfault if I remove all * the constructors here and use the commented block below instead * of pq.push( Pixel(i, j, val) */ Pixel() {x = 0; y = 0; intens = 0; }; Pixel(const Pixel px) { x = px.x; y = px.y; intens = px.intens; }; Pixel(int i, int j, double val): x(i), y(j), intens(val) {}; }; bool operator (const Pixel a, const Pixel b) { return a.intens b.intens; }; typedef priority_queuePixel PixelPrQueue; SEXP lib_filterInvWS (SEXP x) { SEXP res; int i, j, index; double val; PixelPrQueue pq; int nx = INTEGER ( GET_DIM(x) )[0]; int ny = INTEGER ( GET_DIM(x) )[1]; int nz = INTEGER ( GET_DIM(x) )[2]; int nprotect = 0; PROTECT ( res = Rf_duplicate(x) ); nprotect++; // Pixel px; for (int im = 0; im nz; im++ ) { double * src = ( REAL(x)[ im * nx * ny ] ); double * tgt = ( REAL(res)[ im * nx * ny ] ); for ( j = 0; j ny; j++ ) for ( i = 0; i nx; i++ ) { index = i + nx * j; val = src[ index ]; if ( val BG ) { tgt[ index ] = -1; // px.x = i; px.y = j; px.intens = val; pq.push(px); pq.push( Pixel(i, j, val) ); continue; } tgt[ index ] = BG; } } /* my main code was here, but deleted for debug */ UNPROTECT (nprotect); return res; } -- Dr Oleg Sklyar * EBI/EMBL, Cambridge CB10 1SD, England * +44-1223-494466 __ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Re: [R] anyone has C++ STL classes stability issue if used with R
On 2/13/2007 3:55 AM, Oleg Sklyar wrote: Hello, is there any one who uses C++ STL classes when programming shared libs for R and has had any problems with STL? I don't, but I'd suggest asking a technical question like this on R-devel instead of R-help if you don't get help here. I can see a few probably innocuous changes I'd suggest in your code below, but nothing obvious: use Rinternals.h instead of Rdefines.h, don't use the Rf_ prefix, check the length of inputs before working with the values. Duncan Murdoch In the very simple example below I am constantly getting segfaults when trying to populate the queue. The segfault occurs at what looks like a random index in the loop when pushing another element to the queue. Reproduced on 4 machines. Object x is an Image as in EBImage, i.e. a 3D R-array of numerics for the purpose of this code. LENGTH(x) can be up to 1e6 and the number of elements potentially to be in the queue is about 20% of those. But I get segfaults often on a third of fours element being added. Tried on R2.5.0-devel, R2.4.1-release and all machines were 64bit Linux with kernels 2.6.9 (stable CentOS), 2.6.17 (stable Ubuntu) and 2.6.20 (Ubuntu devel). Here are the compilation options of this particular module (built as part of EBImage, which generally compiles and works just fine): -- g++ -I/home/osklyar/R/R-2.5.0-40659/include -I/home/osklyar/R/R-2.5.0-40659/include -I/usr/local/include -DUSE_GTK -DGLIB_GETTEXT -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -g -O2 -Wall -pthread -I/usr/include -O2 -g -O2 -g -fpic -O2 -g -c filters_watershed.cpp -o filters_watershed.o -- And the linker: -- g++ -shared -L/usr/local/lib64 -o EBImage.so colors.o conversions.o display.o filters_distmap.o filters_magick.o filters_morph.o filters_propagate.o filters_thresh.o filters_watershed.o init.o io.o object_counting.o tools.o -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXfixes -lpango-1.0 -lcairo -lX11 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -L/usr/lib -L/usr/X11R6/lib -lfreetype -lz -L/usr/lib -lMagick -llcms -ltiff -lfreetype -ljasper -ljpeg -lpng -lXext -lSM -lICE -lX11 -lbz2 -lxml2 -lz -lpthread -lm -lpthread -- It could be I am missing something totally simple and therefore get these errors, but I cannot identify what. Thanks for help, Oleg - // common.h also includes R includes: // #include R.h // #include Rdefines.h // #include R_ext/Error.h #include common.h #include queue using namespace std; struct Pixel { int x, y; double intens; /* the code will also fail with the same segfault if I remove all * the constructors here and use the commented block below instead * of pq.push( Pixel(i, j, val) */ Pixel() {x = 0; y = 0; intens = 0; }; Pixel(const Pixel px) { x = px.x; y = px.y; intens = px.intens; }; Pixel(int i, int j, double val): x(i), y(j), intens(val) {}; }; bool operator (const Pixel a, const Pixel b) { return a.intens b.intens; }; typedef priority_queuePixel PixelPrQueue; SEXP lib_filterInvWS (SEXP x) { SEXP res; int i, j, index; double val; PixelPrQueue pq; int nx = INTEGER ( GET_DIM(x) )[0]; int ny = INTEGER ( GET_DIM(x) )[1]; int nz = INTEGER ( GET_DIM(x) )[2]; int nprotect = 0; PROTECT ( res = Rf_duplicate(x) ); nprotect++; // Pixel px; for (int im = 0; im nz; im++ ) { double * src = ( REAL(x)[ im * nx * ny ] ); double * tgt = ( REAL(res)[ im * nx * ny ] ); for ( j = 0; j ny; j++ ) for ( i = 0; i nx; i++ ) { index = i + nx * j; val = src[ index ]; if ( val BG ) { tgt[ index ] = -1; // px.x = i; px.y = j; px.intens = val; pq.push(px); pq.push( Pixel(i, j, val) ); continue; } tgt[ index ] = BG; } } /* my main code was here, but deleted for debug */ UNPROTECT (nprotect); return res; } __ R-help@stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide
Re: [R] anyone has C++ STL classes stability issue if used with R
Duncan, you are right about Rf_..., otherwise the lengths are checked in the R side, this is just one of the functions I have in the package and all arguments are thoroughly checked. But apparently, the same code if redefined for using pointers instead of references works just perfectly fine (given below). And I do not see why the one I posted before fails. I will try to run it outside of R to see if the issue is anyhow connected to R. // comparison operator redefined for pointers: struct Pixel_compare: public binary_functionPixel*, Pixel*, bool { bool operator() (Pixel* a, Pixel* b) { return a-intens b-intens; } }; // was: // struct Pixel_compare: public binary_functionPixel, Pixel, bool { //bool operator() (Pixel a, Pixel b) { //return a.intens b.intens; //} // }; // the queue redefined for pointers typedef priority_queuePixel*, vectorPixel*, Pixel_compare PixelPrQueue; // was: typedef priority_queuePixel, vectorPixel, Pixel_compare PixelPrQueue; SEXP lib_filterInvWS (SEXP x) { SEXP res; int i, j, index; double val; int nx = INTEGER ( GET_DIM(x) )[0]; int ny = INTEGER ( GET_DIM(x) )[1]; int nz = INTEGER ( GET_DIM(x) )[2]; int nprotect = 0; PROTECT ( res = Rf_duplicate(x) ); nprotect++; for (int im = 0; im nz; im++ ) { double * src = ( REAL(x)[ im * nx * ny ] ); double * tgt = ( REAL(res)[ im * nx * ny ] ); PixelPrQueue pq; for ( j = 0; j ny; j++ ) for ( i = 0; i nx; i++ ) { index = i + nx * j; val = src[ index ]; if ( val BG ) { tgt[ index ] = -1; // new pixels are created as pointer to objects // was: pq.push( Pixel(i, j, val) ); pq.push( new Pixel(i, j, val) ); continue; } tgt[ index ] = BG; } // printed and all pointers deleted Pixel * px; while ( !pq.empty() ) { px = pq.top(); pq.pop(); Rprintf(%f\n, px-intens); delete px; } } UNPROTECT (nprotect); return res; } The above works fine. The Compare operator is defined differently from my previous post, but both fail if used with references. Oleg Duncan Murdoch wrote: On 2/13/2007 3:55 AM, Oleg Sklyar wrote: Hello, is there any one who uses C++ STL classes when programming shared libs for R and has had any problems with STL? I don't, but I'd suggest asking a technical question like this on R-devel instead of R-help if you don't get help here. I can see a few probably innocuous changes I'd suggest in your code below, but nothing obvious: use Rinternals.h instead of Rdefines.h, don't use the Rf_ prefix, check the length of inputs before working with the values. Duncan Murdoch In the very simple example below I am constantly getting segfaults when trying to populate the queue. The segfault occurs at what looks like a random index in the loop when pushing another element to the queue. Reproduced on 4 machines. Object x is an Image as in EBImage, i.e. a 3D R-array of numerics for the purpose of this code. LENGTH(x) can be up to 1e6 and the number of elements potentially to be in the queue is about 20% of those. But I get segfaults often on a third of fours element being added. Tried on R2.5.0-devel, R2.4.1-release and all machines were 64bit Linux with kernels 2.6.9 (stable CentOS), 2.6.17 (stable Ubuntu) and 2.6.20 (Ubuntu devel). Here are the compilation options of this particular module (built as part of EBImage, which generally compiles and works just fine): -- g++ -I/home/osklyar/R/R-2.5.0-40659/include -I/home/osklyar/R/R-2.5.0-40659/include -I/usr/local/include -DUSE_GTK -DGLIB_GETTEXT -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -g -O2 -Wall -pthread -I/usr/include -O2 -g -O2 -g -fpic -O2 -g -c filters_watershed.cpp -o filters_watershed.o -- And the linker: -- g++ -shared -L/usr/local/lib64 -o EBImage.so colors.o conversions.o display.o filters_distmap.o filters_magick.o filters_morph.o filters_propagate.o filters_thresh.o filters_watershed.o init.o io.o object_counting.o tools.o -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lfontconfig -lXext -lXrender -lXinerama -lXi -lXrandr -lXcursor -lXfixes -lpango-1.0 -lcairo -lX11 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 -L/usr/lib -L/usr/X11R6/lib -lfreetype -lz -L/usr/lib -lMagick -llcms -ltiff -lfreetype -ljasper -ljpeg