[Rcpp-devel] [Lme4-authors] got a minute to answer dumb questions about throw/catch in Rcpp?

Douglas Bates bates at stat.wisc.edu
Tue Jan 4 19:35:12 CET 2011


rcpp-devel readers will be coming in to the middle of a conversation
but it's all there if you want to catch up.

On Tue, Jan 4, 2011 at 11:47 AM, Dirk Eddelbuettel <edd at debian.org> wrote:
>
> Hi Ben,
>
> On 4 January 2011 at 12:24, Ben Bolker wrote:
> | -----BEGIN PGP SIGNED MESSAGE-----
> | Hash: SHA1
> |
> |   (Sorry for bothering you guys personally, it's just that you're so
> | helpful :-) -- if you'd prefer that this go somewhere else, like the
> | Rcpp list, I could do that ...)
>
> We do have a very strong preference for questions on-list.
>
> |   On my system (32-bit Ubuntu 10.10), some exceptions in C++ code are
> | still getting through/not being caught, leading to a rather ungraceful
> | termination of R ["terminate called after throwing an instance of
> | 'Rcpp::eval_error' what():  Lapack routine dpotrf returned error code
> | [char/double]"]
> |
> |   The code is below -- it explicitly throws std::runtime_error
> | (according to a bit of googling, runtime_error is a subclass of
> | exception ... ? so it should be caught by VOID_END_RCPP, which is
> |
> | } catch( std::exception& __ex__ ){ forward_exception_to_r( __ex__ ) ; }
> | catch(...){ ::Rf_error( "c++ exception (unknown reason)" ) ; }
> |
> |  ... right?
>
> Right. The std::execption part should catch it.
>
> And note that we _do_ get some context-specific text rather than the
> boilerplate alternativ "c++ exception (unknown reason)" from the default
> alternative.
>
> |   On my MacOS virtual machine (and on whatever machines Doug Bates and
> | Martin Maechler are using, apparently) this works fine, even *without*
> | the BEGIN_RCPP, VOID_END_RCPP.
>
> Doesn't matter.  Gcc/G++ smile on you, it is the wrong way to do this as we
> learned.
>
> And forget the macros, they simply provide pixie dust and confuse, or as
> Romain claims help the user (and I tend to differ somewhat in my view of
> their helpfulness).
>
> What matters is the try ... catch() block inside them.  And _if_ you have a
> throw() somewhere, you must have try/catch around it if you want any chance
> of deterministic behaviour.
>
> On some systems one gets by without them (see your MacOS/Doug/Martin comment)
> and we thought it was a general feature. It is not. try/catch is the language
> spec.
>
> | Linux ubuntu-10 2.6.32-27-generic #49-Ubuntu SMP Wed Dec 1 23:52:12 UTC
> | 2010 i686 GNU/Linux
> |
> | with Rcpp 0.9.0 it crashes even with BEGIN_RCPP and VOID_END_RCPP.
> |
> |   Any hints about how to learn more about this or diagnose what is going
> | wrong would be much appreciated ...
> |
> |   If you want to try the whole thing for yourself, or see the code in
> | context, it's in the current SVN version of lme4a on R-forge: code to
> | make it crash is in tests/throw.R ...
>
> Sorry. I don't have lme4a in the list of several dozen SVN repos I track....
>
> |   cheers (and apologies),
> |     Ben
> |
> | ============
> |
> |    void Cholesky::update(char Tr, double alpha, const dgeMatrix &A,
> |                         double beta, const dsyMatrix &C) throw (std::runtime_error) {
> |       BEGIN_RCPP
> |       const char tr = Trans(Tr);
> |       const bool NTR = tr == 'N';
> |       int Anr = A.nrow(), Anc = A.ncol(), Cnr = C.nrow();
> |       if (d_nrow != Cnr || NTR ? Anr : Anc != d_nrow)
> |           throw std::runtime_error("dimension mismatch");
> |       d_ul = C.uplo();
> |       copy(C.x().begin(), C.x().end(), d_x.begin());
> |       F77_CALL(dsyrk)(&d_ul, &tr, &d_nrow, NTR ? &Anc : &Anr, &alpha,
> |                       A.x().begin(), &Anr, &beta, d_x.begin(), &d_nrow);
> |       int info;
> |       F77_CALL(dpotrf)(&d_ul, &d_nrow, d_x.begin(), &d_nrow, &info);
> |       if (info)
> |           throw std::runtime_error("Lapack routine dpotrf returned error code
> | [char/double]");
> |       VOID_END_RCPP
> |     }
>
> This seems legit.  You have an error condition.  You detect it. The exception
> is caught.  Someone else somewhere perturbs the system and you crash.
>
> Try without LAPACK.  It may work.  That would point to a suitable suspect. I
> do not know what happens there I only know it interferes.

It is possible that an error condition is being raised in the code
implementing Lapack routines (probably Veclib in Ben's case) but the
sequence would be peculiar.  The error condition is detected in the
Lapack routine dpotrf_ and should be passed back by assigning a
nonzero value to info through the pointer.  (it is a dumb design but
that's the way things are done in Fortran).  Notice that Ben's error
message does include the text from the std::exception instance.  It
would be very peculiar to be able to get to that part of the code if
the Veclib routine did some kind of long jump that would interfere
with the C++ throw/catch mechanism.

> In other words, when I do
>
>   library(inline)
>
>   foo <- cxxfunction(, 'throw std::runtime_error("Testing 1 2 3");', plugin="Rcpp")
>   foo()
>
>   cat("Still here\n")
>
> via a source() I do get back to the prompt but never see 'Still here':
>
> edd at max:~$ R
>
> R version 2.12.1 (2010-12-16)
> Copyright (C) 2010 The R Foundation for Statistical Computing
> ISBN 3-900051-07-0
> Platform: x86_64-pc-linux-gnu (64-bit)
>
> R is free software and comes with ABSOLUTELY NO WARRANTY.
> You are welcome to redistribute it under certain conditions.
> Type 'license()' or 'licence()' for distribution details.
>
>  Natural language support but running in an English locale
>
> R is a collaborative project with many contributors.
> Type 'contributors()' for more information and
> 'citation()' on how to cite R or R packages in publications.
>
> Type 'demo()' for some demos, 'help()' for on-line help, or
> 'help.start()' for an HTML browser interface to help.
> Type 'q()' to quit R.
>
> R> source("/tmp/ben.R")
> Error in foo() : Testing 1 2 3
> R>
>
> So you may have to get down to simulating how Lapack is built, linked, ... to
> chase this.

Well, it's the version of the accelerated BLAS/Lapack code that is
more at fault than Lapack itself.  As this occurs on Mac OS X and not
on other operating systems one test would be to build a OS X version
of R that used the reference BLAS and the reference Lapack code
shipped with R (i.e. use the --without-blas and --without-lapack
flags) and see if the problem persists.

> Sorry,  Dirk
>
>
> | -----BEGIN PGP SIGNATURE-----
> | Version: GnuPG v1.4.10 (GNU/Linux)
> | Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
> |
> | iEYEARECAAYFAk0jV8UACgkQc5UpGjwzenMTkQCgkY23pUTl65Ur0oSl/eOkf+Z2
> | XMwAmwRTyl35nTgGYrTcHlIAGJnqHfR2
> | =XbAh
> | -----END PGP SIGNATURE-----
>
> --
> Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com
> _______________________________________________
> Lme4-authors mailing list
> Lme4-authors at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/lme4-authors
>


More information about the Rcpp-devel mailing list