Проверить на прерывание - PullRequest
0 голосов
/ 10 мая 2018

Раньше я зависел от пакета RcppProgress для проверки абортов пользователя в длинном цикле с Progress::check_abort().Но я только что получил электронное письмо от команды CRAN, чтобы сказать мне (и другим сопровождающим), что RcppProgress имеет ошибки и скоро будет удален в отсутствие сопровождающего (на самом деле он, кажется, уже удален).Есть ли другой способ проверить аборт?

Я обнаружил, что существует R_CheckUserInterrupt.Как изменить мой код для использования этой функции?В Запись R расширений функция возвращает void, поэтому я не понимаю, как она работает.Кажется, он немедленно завершается.

Rcpp::checkUserInterrupt, похоже, демонстрирует то же поведение.И R: Как написать прерываемую функцию C ++ и восстановить частичные результаты представляет собой своего рода хак, не рекомендованный его автором.Я хотел бы выйти из цикла корректной очистки объекта, выделенного в куче, и вернуть частичный вывод

// [[Rcpp::depends(RcppProgress)]]
#include <progress.hpp>
#include <Rcpp.h>

// [[Rcpp::export]]
SEXP f()
{
  for( int i = 0 ; i < 100000 ; i++)
  {
    if (Progress::check_abort())
    {
       delete some_var;
       return partial_output;
    }
    else
      //do_stuff();
  }
}

1 Ответ

0 голосов
/ 10 мая 2018

После прочтения источников Rcpp я обнаружил, что Rcpp::checkUserInterrupt() бросает internal::InterruptedException.Это работает:

for (long i = 0 ; i < 100000000 ; i++)
{
    try 
    {
      Rcpp::checkUserInterrupt();
    }
    catch(Rcpp::internal::InterruptedException e) 
    {
      delete some_var;
      return partial_output;
    }
 }

Это медленно, но точно так же, как Process::check_abort.При желании, как указано в Атрибуты Rcpp , для ускорения кода можно проверять только каждые 100 или 1000 итераций.

for (long i = 0 ; i < 100000000 ; i++)
{
  if (i % 100 == 0)
  {
     try 
     {
       Rcpp::checkUserInterrupt();
     }
     catch(Rcpp::internal::InterruptedException e) 
     {
       delete some_var;
       return partial_output;
     }
   }
 }
...