0

I have an R project which uses Rcpp for long simulations. When I try to stop such a program (e.g. it is taking too long or I am no longer interested in those results) using in Rstudio, then Rstudio crashes. Essentially I am looking for a way to kill the Rcpp function without crashing Rstudio so that I can run it again with some different parameters without losing variables in the R environment (when R studio crashes). I can save and load the environment before calling the function but I am hoping there might be an elegant solution. Any suggestions?

Here is an example.

testR <- function(){
    i=1  
    while(i>0){}}

Another function in a C++ file

// [[Rcpp::export]]
int testCpp( ) {
  double x=3;
  do{
  } while (x>0);
  return x;
}

When I call testR and then click on the red stop icon in the console then it exits normally. Instead, if I call testCpp and do the same I receive the following message (I have to press the red stop icon twice as nothing happens if I click it only once). If I click yes, the session is restarted and I lose the variables. enter image description here

""

user8401743
  • 110
  • 8
  • 2
    As far as I know, there isn't an analog to base R stop(). You have to consider that Rcpp is compiled and thus not interactive. What I have done in the past is given a for loop in Rcpp that could potentially take a while, I will create an argument for how many iterations I want the for loop to run and add some print statements to see what is going on. As Dirk always says *"There are no free lunches"*. – Joseph Wood Jul 25 '18 at 12:57
  • 1
    This has nothing to do with Rcpp. You should simply run it outside of RStudio in another session. – Dirk Eddelbuettel Jul 25 '18 at 14:07
  • @DirkEddelbuettel Yes, I agree it is indeed about how Rsudio handles the interrupts to Rcpp functions and perhaps that may be improved. As many of the inputs to the Rcpp function are outputs of previous R functions, I have to use the same session or save the results in a file so that they can be used by the Rcpp. function. – user8401743 Jul 25 '18 at 15:37
  • 1
    Ok, I just checked. You cannot stop an R function. It is the same on the command-line. So not an RStudio issue either -- you would have to teach your routine to look for interrupts. – Dirk Eddelbuettel Jul 25 '18 at 15:47
  • @DirkEddelbuettel I can stop an R function inside the Rstudio without any explicit interrupts (I am not sure how exactly it works). To clarify my point, I have updated my question with two test cases involving infinite loops. The R function "stops" without crashing Rsudio but the Rcpp function doesn't. – user8401743 Jul 25 '18 at 16:37
  • I just ran a `while` around a one sec `sleep` followed by `Rprintf`. That one I could not stop in a remote shell session. – Dirk Eddelbuettel Jul 25 '18 at 16:46
  • Ie `Rcpp::cppFunction("void foo() { while(true) { sleep(1); Rprintf(\".\"); } }", includes="#include ")` -- running that one in a terminal required me to kill the R session around it. – Dirk Eddelbuettel Jul 25 '18 at 17:17
  • @DirkEddelbuettel Sorry but I didn't get your point. Does this imply that this behavior depends on how .call is implemented in R and using interrupts in the Cpp function is the only solution? I just found a related question https://stackoverflow.com/questions/43148981/r-not-responding-request-to-interrupt-stop-process where they mention that Rstudio can't handle such kill requests. – user8401743 Jul 25 '18 at 17:41

1 Answers1

4

You can use Rcpp::checkUserInterrupt(). For example:

#include <unistd.h>
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void forever() {

  try
  {
    for (int i = 0; ; i++)
    {
      Rcout << "Iteration: " << i << std::endl;
      ::sleep(1);
      Rcpp::checkUserInterrupt();
    }
  }
  catch (Rcpp::internal::InterruptedException& e)
  {
    Rcout << "Caught an interrupt!" << std::endl;
  }

}

/*** R
forever()
*/

If you attempt to interrupt R while this is running you should see something like:

> Rcpp::sourceCpp('scratch/interrupt.cpp')
> forever()
Iteration: 0
Iteration: 1
Iteration: 2

Caught an interrupt!

Note that the try-catch block is unnecessary if you're using Rcpp attributes as the associated try-catch exception handlers will automagically be generated in a wrapper function for you. I just add them here to illustrate that Rcpp responds to interrupts with this API by throwing a special exception.

Kevin Ushey
  • 20,530
  • 5
  • 56
  • 88
  • Thanks, how does Rstudio handles requests using stop and keeps the variables if the R session is killed? – user8401743 Jul 28 '18 at 20:55
  • 1
    Maybe I'm misunderstanding your question, but it doesn't. If the R session is killed, the global workspace is lost. (If the interrupt is properly handled then of course the session doesn't need to be killed) – Kevin Ushey Jul 30 '18 at 05:10