RcppProgress/0000755000176200001440000000000013617001040012673 5ustar liggesusersRcppProgress/NAMESPACE0000644000176200001440000000000013275267430014121 0ustar liggesusersRcppProgress/README.md0000644000176200001440000000326213275125021014163 0ustar liggesusers# RcppProgress [![Build Status](https://travis-ci.org/kforner/rcpp_progress.svg?branch=dev)](https://travis-ci.org/kforner/rcpp_progress?branch=dev) [![codecov](https://codecov.io/github/kforner/rcpp_progress/coverage.svg?branch=dev)](https://codecov.io/github/kforner/rcpp_progress?branch=dev) [![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/RcppProgress)](https://cran.r-project.org/package=RcppProgress) a R package that provides a c++ interruptible progress bar with OpenMP support for c++ code in R packages ## example see a detailed example on Rcpp Gallery: http://gallery.rcpp.org/articles/using-rcppprogress/ ## How to build Prerequisites: - OpenMP support to use the multithreaded parallelized version. OpenMP is available in GCC >= 4.2 Just install it the usual way. If you want more control, unarchive it, cd to the source directory, then type R CMD INSTALL . in the console. ## Contribute Send me a pull request with at least one test or example ## For developers ### tests and check If you have all the RcppProgress dependencies (and suggests) installed: type: - `make tests`: to run the tests - `make check`: to check the package ### docker-checker A Dockerfile () is provided to help building the dev environment (built on rocker/r-devel) in which to develop and test RcppProgress. type: - `make docker/build`: to build the docker - `make docker/run`: to run a shell in the docker with the current dir mounted inside - `make docker/check`: to check the package inside the docker - `make docker/tests`: to run test tests of the package inside the docker ### test on windows using rhub ``` make docker/run make check_rhub_windows ``` RcppProgress/man/0000755000176200001440000000000013275125021013454 5ustar liggesusersRcppProgress/man/RcppProgress-package.Rd0000644000176200001440000001457613275125021020002 0ustar liggesusers\name{RcppProgress-package} \alias{RcppProgress-package} \alias{RcppProgress} \docType{package} \title{ An interruptible progress bar with OpenMP support for c++ in R packages } \description{ This package allows to display a progress bar in the R console for long running computations taking place in c++ code, and provides support for interrupting those computations even in a multithreaded code. } \details{ When implementing CPU intensive computations in C++ in R packages, it is natural to want to monitor the progress of those computations, and to be able to interrupt them, even when using multithreading for example with OpenMP. Another feature is that it can be done so that the code will still work even without OpenMP support. This package offers some facilities to help implementing those features. It it biased towards the use of OpenMP, but it should be compatible when using multithreading in other ways. \subsection{quick try}{ There are two tests functions provided by the package to get a quick overview of what can be done. These tests are: \describe{ \item{ RcppProgress:::test_sequential(max, nb, display_progress) }{ - a sequential code, i.e. single threaded } \item{ RcppProgress:::test_multithreaded(max, nb, threads, display_progress) }{ - a multithreaded code using OpenMP} } They both are wrappers for examples implemented in the RcppProgressExample package located in the \code{examples} directory of the RcppProgress installed package. Both tests call the very same function that implements a long computation. The \bold{max} parameter controls the number of computations, and \bold{nb} controls the duration of a single computation, that is quadratic in \bold{nb}. The \bold{threads} is as expected the number of threads to use for the computation. The \bold{progress} parameter toggles the display of the progress bar. On my platform, \preformatted{ system.time( RcppProgress:::test_multithreaded(100, 3000, 4) ) } is a good start. } \subsection{c++ usage}{ There are usually two locations in the c++ code that needs to be modified. The first one is the main loop, typically on the number of jobs or tasks. This loop is a good candidate to be parallelized using OpenMP. I will comment the code corresponding to the tests included with the package. \preformatted{ void test_multithreaded_omp(int max, int nb, int threads , bool display\_progress) \{ \#ifdef _OPENMP if ( threads > 0 ) omp_set_num_threads( threads ); REprintf(\"Number of threads=\%i\n\", omp_get_max_threads()); \#endif Progress p(max, display_progress); // create the progress monitor #pragma omp parallel for schedule(dynamic) for (int i = 0; i < max; ++i) \{ if ( ! p.is_aborted() ) \{ // the only way to exit an OpenMP loop long_computation(nb); p.increment(); // update the progress \} \} \} } Here we create a Progress object with the number of tasks to perform, then before performing a task we test for abortion (\code{p.is_aborted()}), because we can not exit an OpenMP loop the usual way, suing a break for example, then when after the computation, we increment the progress monitor. Then let us look at the computation function (that is completely useless) : \preformatted{ double long_computation(int nb) \{ double sum = 0; for (int i = 0; i < nb; ++i) \{ if ( Progress::check_abort() ) // check for user abort return -1; for (int j = 0; j < nb; ++j) \{ sum += Rf_dlnorm(i+j, 0.0, 1.0, 0); \} \} \} return sum; \} } Here the only interesting line is the \code{Progress::check_abort()} call. If called from the master thread, it will check for user interruption, and if needed set the abort status code. When called from another thread it will just check the status. So all the art is to decide where to put his call: it should not be called not too often or not frequently enough. As a rule of thumb it should be called roughly evevry second. } \subsection{Using RcppProgress in your package}{ Please note that we provide the \bold{RcppProgressExample} example package along with this package, located in the \code{examples} directory of the installed package. Here are the steps to use RcppProgress in a new package: \describe{ \item{ skeleton }{ create a package skeleton using Rcpp \preformatted{ library(Rcpp) Rcpp.package.skeleton("RcppProgressExample")} } \item{ DESCRIPTION }{ edit the \bold{DESCRIPTION} file and add RcppProgress to the \strong{Depends:} and \strong{LinkingTo:} lines. e.g. \preformatted{ Depends: Rcpp (>= 0.9.4), RcppProgress (>= 0.1) LinkingTo: Rcpp, RcppProgress } } \item{ MakeVars }{ edit \bold{src/MakeVars} and replace its content by PKG_LIBS = `$(R_HOME)/bin/Rscript -e "Rcpp:::LdFlags()"` $(SHLIB_OPENMP_CXXFLAGS) `$(R_HOME)/bin/Rscript -e "RcppProgress:::CxxFlags()"` and PKG_CXXFLAGS +=-Ilibsrc $(SHLIB_OPENMP_CXXFLAGS) `$(R_HOME)/bin/Rscript -e "RcppProgress:::CxxFlags()"` } \item{ c++ code }{ Put your code in \bold{src}. You may for instance copy the RcppProgressExample/src/tests.cpp file in \bold{src}, and RcppProgressExample/R/tests.R in \bold{R}, and try to compile the package (\code{R CMD INSTALL -l test .}) and execute the tests: \preformatted{ %R >library(RcppProgressExample, lib.loc="test") >RcppProgressExample::test_multithreaded(100, 600, 4) } } } } % subsection \subsection{Using RcppProgress with RcppArmadillo}{ We also provide the \bold{RcppProgressArmadillo} example package along with this package, located in the \code{examples} directory of the installed package. The peculiarity is that you have to include the RcppArmadillo.h header before the progress.hpp RcppProgress header, and add the RcppArmadillo in the LinkingTo: field of the package DESCRIPTION file. } % subsection } % details \seealso{ \describe{ \item{ OpenMP }{API specification for parallel programming: \url{http://openmp.org} } \item{ Rcpp }{\url{http://r-forge.r-project.org/projects/rcpp}} } } \author{ Karl Forner Maintainer: Karl Forner } \examples{ # these are implemented as examples inside RcppProgress provided # example package: examples/RcppProgressExample # check the source code # the underlying test_test_multithreaded c++ function is multithreaded # , has a progress bar and is still interruptible \dontrun{ RcppProgress:::test_multithreaded(nb = 300, threads = 4, recompile = TRUE) } } \keyword{ package } RcppProgress/DESCRIPTION0000644000176200001440000000147313617001040014406 0ustar liggesusersPackage: RcppProgress Maintainer: Karl Forner License: GPL (>= 3) Title: An Interruptible Progress Bar with OpenMP Support for C++ in R Packages Type: Package LazyLoad: yes Author: Karl Forner Description: Allows to display a progress bar in the R console for long running computations taking place in c++ code, and support for interrupting those computations even in multithreaded code, typically using OpenMP. URL: https://github.com/kforner/rcpp_progress BugReports: https://github.com/kforner/rcpp_progress/issues Version: 0.4.2 Date: 2020-02-06 Suggests: RcppArmadillo, devtools, roxygen2, testthat RoxygenNote: 6.1.1 Encoding: UTF-8 NeedsCompilation: no Packaged: 2020-02-06 10:57:24 UTC; karl Repository: CRAN Date/Publication: 2020-02-06 12:10:08 UTC RcppProgress/tests/0000755000176200001440000000000013275125021014043 5ustar liggesusersRcppProgress/tests/testthat/0000755000176200001440000000000013617001040015675 5ustar liggesusersRcppProgress/tests/testthat/test-pkg_examples.R0000644000176200001440000000146513275267430021503 0ustar liggesuserssource("wrap_examples.R") context('RcppProgressExample sequential\n') .test_sequential <- function() { expect_error(test_sequential(nb = 500), NA) } test_that("test_sequential", .test_sequential()) context('RcppProgressExample multithreaded\n') .test_multithreaded <- function() { expect_error(test_multithreaded(nb = 1000, threads = 4), NA) } test_that("test_multithreaded", .test_multithreaded()) context('RcppProgressArmadillo multithreaded\n') .amardillo_multithreaded <- function() { expect_error(amardillo_multithreaded(nb = 1000, threads = 4), NA) } test_that("amardillo_multithreaded", .amardillo_multithreaded()) context('RcppProgressETA:custom progress bar\n') .eta_progress_bar <- function() { expect_error(eta_progress_bar(nb = 1000), NA) } test_that("eta_progress_bar", .eta_progress_bar()) RcppProgress/tests/testthat/wrap_examples.R0000644000176200001440000000320713275267430020712 0ustar liggesusers load_my_example_pkg <- function(pkg, ...) { skip_if(!requireNamespace("devtools", quietly = TRUE), message = "Package devtools must be installed to run unit tests.") from <- system.file(file.path('examples', pkg), package = 'RcppProgress') dir <- tempfile() dir.create(dir) file.copy(from, dir, recursive = TRUE) path <- file.path(dir, pkg) devtools::load_all(path, quiet = TRUE, ...) } get_function_from_pkg <- function(pkg, fun) { get(fun, getNamespace(pkg)) } test_sequential <- function(max = 100, nb = 1000, display_progress= TRUE, ...) { pkg <- 'RcppProgressExample' load_my_example_pkg(pkg, ...) fun <- get_function_from_pkg(pkg, 'test_sequential') fun(max, nb, display_progress) } # R wrapper for the example function #2 test_multithreaded <- function(max = 100, nb = 1000, threads = 0, display_progress = TRUE, ...) { pkg <- 'RcppProgressExample' load_my_example_pkg(pkg, ...) fun <- get_function_from_pkg(pkg, 'test_multithreaded') fun(max, nb, threads, display_progress) } amardillo_multithreaded <- function(max = 100, nb = 1000, threads = 0, display_progress = TRUE, ...) { skip_if(!requireNamespace("RcppArmadillo", quietly = TRUE), message = "Package RcppArmadillo must be installed to run this test.") pkg <- 'RcppProgressArmadillo' load_my_example_pkg(pkg, ...) fun <- get_function_from_pkg(pkg, 'test_multithreaded') fun(max, nb, threads, display_progress) } eta_progress_bar <- function(max = 100, nb = 1000, display_progress = TRUE) { pkg <- 'RcppProgressETA' load_my_example_pkg(pkg) fun <- get_function_from_pkg(pkg, 'test_sequential') fun(max, nb, display_progress) } RcppProgress/tests/testthat.R0000644000176200001440000000010413275125021016021 0ustar liggesuserslibrary(testthat) library(RcppProgress) test_check("RcppProgress") RcppProgress/MD50000644000176200001440000000516313617001040013210 0ustar liggesusers73a93d0217735be0f9c6d1e249e2e638 *DESCRIPTION d41d8cd98f00b204e9800998ecf8427e *NAMESPACE d9692d099a33ec63c58a280948f0a88d *README.md ed85ae455fd74c65cf56d14906f19fb2 *inst/examples/RcppProgressArmadillo/DESCRIPTION fc0bd5a713423c04f38afa1f19739501 *inst/examples/RcppProgressArmadillo/NAMESPACE 8a23e0d00fd8c3d976eb02caaca54d92 *inst/examples/RcppProgressArmadillo/R/examples.R 450a55b1530aebd9bc07a9a8c9be0119 *inst/examples/RcppProgressArmadillo/man/RcppProgressExample-package.Rd 491ec45ab8720dbe859c1e059e9a3351 *inst/examples/RcppProgressArmadillo/man/test_multithreaded.Rd f3544be12aeb659d48214aa2cd8bcc9a *inst/examples/RcppProgressArmadillo/man/test_sequential.Rd 64b6726bc0339b76889c3ea604298343 *inst/examples/RcppProgressArmadillo/src/Makevars 0a1c45f47d22378975eaae97d57384ee *inst/examples/RcppProgressArmadillo/src/example.cpp fd5fc67c2cd61e24e4bc87cc67767f18 *inst/examples/RcppProgressETA/DESCRIPTION c7a981894f846bf2b48bb40c5e7591f9 *inst/examples/RcppProgressETA/NAMESPACE cc1307d5047888ca69b6f736f851ec9a *inst/examples/RcppProgressETA/R/examples.R 64b6726bc0339b76889c3ea604298343 *inst/examples/RcppProgressETA/src/Makevars 5b83ef7d336ff38b6ac5ffc959c1bd23 *inst/examples/RcppProgressETA/src/eta_progress_bar.hpp bcec214a6ddadd27c1fd0cd8cfb6ea7d *inst/examples/RcppProgressETA/src/example.cpp f28f88e40b610c586a800a9c4af8d953 *inst/examples/RcppProgressExample/DESCRIPTION a8a0bf142fb441f337772494379e0b45 *inst/examples/RcppProgressExample/NAMESPACE 9de355ba31384800d82474944b0487d7 *inst/examples/RcppProgressExample/R/examples.R 450a55b1530aebd9bc07a9a8c9be0119 *inst/examples/RcppProgressExample/man/RcppProgressExample-package.Rd 491ec45ab8720dbe859c1e059e9a3351 *inst/examples/RcppProgressExample/man/test_multithreaded.Rd f3544be12aeb659d48214aa2cd8bcc9a *inst/examples/RcppProgressExample/man/test_sequential.Rd 64b6726bc0339b76889c3ea604298343 *inst/examples/RcppProgressExample/src/Makevars ce8d73330c86439fcae88bf5a549dda4 *inst/examples/RcppProgressExample/src/dummy.cpp 1f258902c354004953e0f7dc974c8c23 *inst/examples/RcppProgressExample/src/example.cpp 9a7f25b31a2089a94eb1c208fe9a9a2b *inst/include/interruptable_progress_monitor.hpp d6526b9eb1fa635823a1149edf9cc7ee *inst/include/interrupts.hpp d65e616bdc31263588a05974d2f69a65 *inst/include/progress.hpp d901380ced3b5323a9761820bdd594e7 *inst/include/progress_bar.hpp 7e851a23692fbf3b5bbba4a4e6e9df62 *inst/include/simple_progress_bar.hpp 9660192329702646dbee4ccbbdd358c3 *man/RcppProgress-package.Rd 362bdc0bfae20dc64527821edba07de9 *tests/testthat.R 5e1c1261dc7833d84269f821079f7325 *tests/testthat/test-pkg_examples.R 4739a5ab656a3ed01cbde51a0ba8cb64 *tests/testthat/wrap_examples.R RcppProgress/inst/0000755000176200001440000000000013616770424013672 5ustar liggesusersRcppProgress/inst/examples/0000755000176200001440000000000013275125021015474 5ustar liggesusersRcppProgress/inst/examples/RcppProgressExample/0000755000176200001440000000000013275125021021441 5ustar liggesusersRcppProgress/inst/examples/RcppProgressExample/NAMESPACE0000644000176200001440000000007613275125021022663 0ustar liggesusersuseDynLib(RcppProgressExample) exportPattern("^[[:alpha:]]+") RcppProgress/inst/examples/RcppProgressExample/man/0000755000176200001440000000000013275125021022214 5ustar liggesusersRcppProgress/inst/examples/RcppProgressExample/man/test_sequential.Rd0000644000176200001440000000147013275125021025716 0ustar liggesusers\name{test_multithreaded} \alias{test_multithreaded} \title{ Test/example of using RcppProgress in multithreaded code } \description{ Test function for the package rngOpenMP in a multithreaded mode. } \usage{ test_multithreaded(max=100, nb=1000, threads=0, display_progress=TRUE) } \arguments{ \item{max}{ number of long computation jobs to perform } \item{nb}{ number of interruptible steps a long computaton job is made of } \item{threads}{ number of threads to use, or 0 to use the default OpenMP number, that is usually the number of cores } \item{display_progress}{ whether to display the progress bar or not } } \details{ Will perform max long jobs made of nb interruptible steps. The jobs are parallelized. The computation can be interrupted by the user. } \value{ None } \author{ Karl Forner } RcppProgress/inst/examples/RcppProgressExample/man/test_multithreaded.Rd0000644000176200001440000000131613275125021026376 0ustar liggesusers\name{test_sequential} \alias{test_sequential} \title{ Test/example of using RcppProgress in sequential code, i.e not in multithreaded code } \description{ Test function for the package rngOpenMP in a sequential mode. } \usage{ test_sequential(max=100, nb=1000, display_progress=TRUE) } \arguments{ \item{max}{ number of long computation jobs to perform } \item{nb}{ number of interruptible steps a long computaton job is made of } \item{display_progress}{ whether to display the progress bar or not } } \details{ Will perform max long jobs made of nb interruptible steps. The jobs are performed sequentially. The computation can be interrupted by the user. } \value{ None } \author{ Karl Forner } RcppProgress/inst/examples/RcppProgressExample/man/RcppProgressExample-package.Rd0000644000176200001440000000130213275125021030035 0ustar liggesusers\name{RcppProgressExample-package} \alias{RcppProgressExample-package} \alias{RcppProgressExample} \docType{package} \title{ This package is an example of how to use RcppProgress in your own package. } \description{ This package is an example of how to use RcppProgress in your own package. } \details{ \tabular{ll}{ Package: \tab RcppProgressExample\cr Type: \tab Package\cr Version: \tab 0.1\cr Date: \tab 2012-04-17\cr License: \tab GPL\cr } ~~ An overview of how to use the package, including the most important ~~ ~~ functions ~~ } \author{ Karl FORNER Maintainer: Karl Forner } \keyword{ package } \seealso{ \code{\link[RcppProgress:RcppProgress-package]{RcppProgress}} } RcppProgress/inst/examples/RcppProgressExample/DESCRIPTION0000644000176200001440000000060013275125021023143 0ustar liggesusersPackage: RcppProgressExample Type: Package Title: Example use of the RcppProgress package Version: 0.2 Date: 2012-04-17 Author: Karl Forner Maintainer: Karl Forner Description: Example use of the RcppProgress package in a package License: GPL (>=3) Depends: Rcpp (>= 0.9.10), RcppProgress (>= 0.1) LinkingTo: Rcpp, RcppProgress RcppProgress/inst/examples/RcppProgressExample/src/0000755000176200001440000000000013275125021022230 5ustar liggesusersRcppProgress/inst/examples/RcppProgressExample/src/example.cpp0000644000176200001440000000271613275125021024375 0ustar liggesusers#include "progress.hpp" #include #include using namespace Rcpp; // your function for which to provide support void your_long_computation(int nb) { double sum = 0; for (int i = 0; i < nb; ++i) { if ( Progress::check_abort() ) return; for (int j = 0; j < nb; ++j) { sum += Rf_dlnorm(i+j, 0.0, 1.0, 0); } } } void test_sequential2(int max, int nb, bool display_progress) { Progress p(max, display_progress); for (int i = 0; i < max; ++i) { if ( p.increment() ) { your_long_computation(nb); } } } void test_multithreaded_omp2(int max, int nb, int threads, bool display_progress) { #ifdef _OPENMP if ( threads > 0 ) omp_set_num_threads( threads ); REprintf("Number of threads=%i\n", omp_get_max_threads()); #endif Progress p(max, display_progress); // create the progress monitor #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) #endif for (int i = 0; i < max; ++i) { if ( p.increment() ) { // the only way to exit an OpenMP loop your_long_computation(nb); } } } RcppExport SEXP test_sequential_wrapper2(SEXP __max, SEXP __nb, SEXP __display_progress) { test_sequential2(as(__max), as(__nb), as(__display_progress)); return R_NilValue; } RcppExport SEXP test_multithreaded_wrapper2(SEXP __max, SEXP __nb, SEXP __threads, SEXP __display_progress) { test_multithreaded_omp2(as(__max), as(__nb), as(__threads), as(__display_progress)); return R_NilValue; } RcppProgress/inst/examples/RcppProgressExample/src/dummy.cpp0000644000176200001440000000025713275125021024073 0ustar liggesusers/* regression test dummy source to test impact of multiple inclusions of RcppProgress header files. */ #include "progress.hpp" void toto() { Progress p(100, false); } RcppProgress/inst/examples/RcppProgressExample/src/Makevars0000644000176200001440000000031613275125021023724 0ustar liggesusers## Use the R_HOME indirection to support installations of multiple R version PKG_LIBS = `$(R_HOME)/bin/Rscript -e "Rcpp:::LdFlags()"` $(SHLIB_OPENMP_CXXFLAGS) PKG_CXXFLAGS += -Wall $(SHLIB_OPENMP_CXXFLAGS) RcppProgress/inst/examples/RcppProgressExample/R/0000755000176200001440000000000013275125021021642 5ustar liggesusersRcppProgress/inst/examples/RcppProgressExample/R/examples.R0000644000176200001440000000060513275125021023604 0ustar liggesusers test_sequential <- function(max=100, nb=1000, display_progress=TRUE) { .Call("test_sequential_wrapper2", max, nb, display_progress, PACKAGE = "RcppProgressExample") invisible() } test_multithreaded <- function(max=100, nb=1000, threads=0, display_progress=TRUE) { .Call("test_multithreaded_wrapper2", max, nb, threads, display_progress, PACKAGE = "RcppProgressExample") invisible() }RcppProgress/inst/examples/RcppProgressArmadillo/0000755000176200001440000000000013275125021021752 5ustar liggesusersRcppProgress/inst/examples/RcppProgressArmadillo/NAMESPACE0000644000176200001440000000010013275125021023160 0ustar liggesusersuseDynLib(RcppProgressArmadillo) exportPattern("^[[:alpha:]]+") RcppProgress/inst/examples/RcppProgressArmadillo/man/0000755000176200001440000000000013275125021022525 5ustar liggesusersRcppProgress/inst/examples/RcppProgressArmadillo/man/test_sequential.Rd0000644000176200001440000000147013275125021026227 0ustar liggesusers\name{test_multithreaded} \alias{test_multithreaded} \title{ Test/example of using RcppProgress in multithreaded code } \description{ Test function for the package rngOpenMP in a multithreaded mode. } \usage{ test_multithreaded(max=100, nb=1000, threads=0, display_progress=TRUE) } \arguments{ \item{max}{ number of long computation jobs to perform } \item{nb}{ number of interruptible steps a long computaton job is made of } \item{threads}{ number of threads to use, or 0 to use the default OpenMP number, that is usually the number of cores } \item{display_progress}{ whether to display the progress bar or not } } \details{ Will perform max long jobs made of nb interruptible steps. The jobs are parallelized. The computation can be interrupted by the user. } \value{ None } \author{ Karl Forner } RcppProgress/inst/examples/RcppProgressArmadillo/man/test_multithreaded.Rd0000644000176200001440000000131613275125021026707 0ustar liggesusers\name{test_sequential} \alias{test_sequential} \title{ Test/example of using RcppProgress in sequential code, i.e not in multithreaded code } \description{ Test function for the package rngOpenMP in a sequential mode. } \usage{ test_sequential(max=100, nb=1000, display_progress=TRUE) } \arguments{ \item{max}{ number of long computation jobs to perform } \item{nb}{ number of interruptible steps a long computaton job is made of } \item{display_progress}{ whether to display the progress bar or not } } \details{ Will perform max long jobs made of nb interruptible steps. The jobs are performed sequentially. The computation can be interrupted by the user. } \value{ None } \author{ Karl Forner } RcppProgress/inst/examples/RcppProgressArmadillo/man/RcppProgressExample-package.Rd0000644000176200001440000000130213275125021030346 0ustar liggesusers\name{RcppProgressExample-package} \alias{RcppProgressExample-package} \alias{RcppProgressExample} \docType{package} \title{ This package is an example of how to use RcppProgress in your own package. } \description{ This package is an example of how to use RcppProgress in your own package. } \details{ \tabular{ll}{ Package: \tab RcppProgressExample\cr Type: \tab Package\cr Version: \tab 0.1\cr Date: \tab 2012-04-17\cr License: \tab GPL\cr } ~~ An overview of how to use the package, including the most important ~~ ~~ functions ~~ } \author{ Karl FORNER Maintainer: Karl Forner } \keyword{ package } \seealso{ \code{\link[RcppProgress:RcppProgress-package]{RcppProgress}} } RcppProgress/inst/examples/RcppProgressArmadillo/DESCRIPTION0000644000176200001440000000101413275125021023454 0ustar liggesusersPackage: RcppProgressArmadillo Type: Package Title: Example use of the RcppProgress package to reproduce a bug with RcppArmadillo Version: 0.2 Date: 2014-11-25 Author: Karl Forner Maintainer: Karl Forner Description: Example use of the RcppProgress package in a package, cf http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2013-August/006288.html License: GPL (>=3) Depends: Rcpp (>= 0.9.10), RcppProgress (>= 0.1) LinkingTo: Rcpp, RcppProgress, RcppArmadillo RcppProgress/inst/examples/RcppProgressArmadillo/src/0000755000176200001440000000000013275125021022541 5ustar liggesusersRcppProgress/inst/examples/RcppProgressArmadillo/src/example.cpp0000644000176200001440000000310413275125021024676 0ustar liggesusers#include #include "progress.hpp" using namespace Rcpp; // your function for which to provide support double your_long_computation(int nb) { double sum = 0; for (int i = 0; i < nb; ++i) { if ( Progress::check_abort() ) return -1; for (int j = 0; j < nb; ++j) { arma::mat m1 = arma::eye(3, 3); arma::mat m2 = arma::eye(3, 3); m1 = m1 + 3 * (m1 + m2); sum += m1[0]; } } return sum; } void test_sequential2(int max, int nb, bool display_progress) { Progress p(max, display_progress); for (int i = 0; i < max; ++i) { if ( p.increment() ) { your_long_computation(nb); } } } void test_multithreaded_omp2(int max, int nb, int threads, bool display_progress) { #ifdef _OPENMP if ( threads > 0 ) omp_set_num_threads( threads ); REprintf("Number of threads=%i\n", omp_get_max_threads()); #endif Progress p(max, display_progress); // create the progress monitor #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) #endif for (int i = 0; i < max; ++i) { if ( p.increment() ) { // the only way to exit an OpenMP loop your_long_computation(nb); } } } RcppExport SEXP test_sequential_wrapper2(SEXP __max, SEXP __nb, SEXP __display_progress) { test_sequential2(as(__max), as(__nb), as(__display_progress)); return R_NilValue; } RcppExport SEXP test_multithreaded_wrapper2(SEXP __max, SEXP __nb, SEXP __threads, SEXP __display_progress) { test_multithreaded_omp2(as(__max), as(__nb), as(__threads), as(__display_progress)); return R_NilValue; } RcppProgress/inst/examples/RcppProgressArmadillo/src/Makevars0000644000176200001440000000031613275125021024235 0ustar liggesusers## Use the R_HOME indirection to support installations of multiple R version PKG_LIBS = `$(R_HOME)/bin/Rscript -e "Rcpp:::LdFlags()"` $(SHLIB_OPENMP_CXXFLAGS) PKG_CXXFLAGS += -Wall $(SHLIB_OPENMP_CXXFLAGS) RcppProgress/inst/examples/RcppProgressArmadillo/R/0000755000176200001440000000000013275125021022153 5ustar liggesusersRcppProgress/inst/examples/RcppProgressArmadillo/R/examples.R0000644000176200001440000000061113275125021024112 0ustar liggesusers test_sequential <- function(max=100, nb=1000, display_progress=TRUE) { .Call("test_sequential_wrapper2", max, nb, display_progress, PACKAGE = "RcppProgressArmadillo") invisible() } test_multithreaded <- function(max=100, nb=1000, threads=0, display_progress=TRUE) { .Call("test_multithreaded_wrapper2", max, nb, threads, display_progress, PACKAGE = "RcppProgressArmadillo") invisible() }RcppProgress/inst/examples/RcppProgressETA/0000755000176200001440000000000013275125021020457 5ustar liggesusersRcppProgress/inst/examples/RcppProgressETA/NAMESPACE0000644000176200001440000000007213275125021021675 0ustar liggesusersuseDynLib(RcppProgressETA) exportPattern("^[[:alpha:]]+") RcppProgress/inst/examples/RcppProgressETA/DESCRIPTION0000644000176200001440000000064113275125021022166 0ustar liggesusersPackage: RcppProgressETA Type: Package Title: Example use of the RcppProgress package with an ETAProgressBar Version: 0.1 Date: 2017-11-10 Author: Karl Forner Maintainer: Karl Forner Description: Example use of the RcppProgress package with a custom progress bar License: GPL (>=3) Depends: Rcpp (>= 0.9.10), RcppProgress (>= 0.1) LinkingTo: Rcpp, RcppProgress RcppProgress/inst/examples/RcppProgressETA/src/0000755000176200001440000000000013275125021021246 5ustar liggesusersRcppProgress/inst/examples/RcppProgressETA/src/example.cpp0000644000176200001440000000303613275125021023407 0ustar liggesusers#include "progress.hpp" #include "eta_progress_bar.hpp" #include #include using namespace Rcpp; // your function for which to provide support void your_long_computation(int nb) { double sum = 0; for (int i = 0; i < nb; ++i) { if ( Progress::check_abort() ) return; for (int j = 0; j < nb; ++j) { sum += Rf_dlnorm(i+j, 0.0, 1.0, 0); } } } void test_sequential2(int max, int nb, bool display_progress) { ETAProgressBar pb; Progress p(max, display_progress, pb); for (int i = 0; i < max; ++i) { if ( p.increment() ) { your_long_computation(nb); } } } void test_multithreaded_omp2(int max, int nb, int threads, bool display_progress) { #ifdef _OPENMP if ( threads > 0 ) omp_set_num_threads( threads ); REprintf("Number of threads=%i\n", omp_get_max_threads()); #endif ETAProgressBar pb; Progress p(max, display_progress, pb); // create the progress monitor #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) #endif for (int i = 0; i < max; ++i) { if ( p.increment() ) { // the only way to exit an OpenMP loop your_long_computation(nb); } } } RcppExport SEXP test_sequential_wrapper2(SEXP __max, SEXP __nb, SEXP __display_progress) { test_sequential2(as(__max), as(__nb), as(__display_progress)); return R_NilValue; } RcppExport SEXP test_multithreaded_wrapper2(SEXP __max, SEXP __nb, SEXP __threads, SEXP __display_progress) { test_multithreaded_omp2(as(__max), as(__nb), as(__threads), as(__display_progress)); return R_NilValue; } RcppProgress/inst/examples/RcppProgressETA/src/eta_progress_bar.hpp0000644000176200001440000001140013275125021025274 0ustar liggesusers/* * eta_progress_bar.hpp * * A custom ProgressBar class to display a progress bar with time estimation * * Author: clemens@nevrome.de * */ #ifndef _RcppProgress_ETA_PROGRESS_BAR_HPP #define _RcppProgress_ETA_PROGRESS_BAR_HPP #include #include #include #include #include #include "progress_bar.hpp" // for unices only #if !defined(WIN32) && !defined(__WIN32) && !defined(__WIN32__) #include #endif class ETAProgressBar: public ProgressBar{ public: // ====== LIFECYCLE ===== /** * Main constructor */ ETAProgressBar() { _max_ticks = 50; _finalized = false; _timer_flag = true; } ~ETAProgressBar() { } public: // ===== main methods ===== void display() { REprintf("0%% 10 20 30 40 50 60 70 80 90 100%%\n"); REprintf("[----|----|----|----|----|----|----|----|----|----|\n"); flush_console(); } // update display void update(float progress) { // stop if already finalized if (_finalized) return; // start time measurement when update() is called the first time if (_timer_flag) { _timer_flag = false; // measure start time time(&start); } else { // measure current time time(&end); // calculate passed time and remaining time (in seconds) double pas_time = std::difftime(end, start); double rem_time = (pas_time / progress) * (1 - progress); // convert seconds to time string std::string time_string = _time_to_string(rem_time); // create progress bar string std::string progress_bar_string = _current_ticks_display(progress); // ensure overwriting of old time info int empty_length = time_string.length(); std::string empty_space = std::string(empty_length, ' '); // merge progress bar and time string std::stringstream strs; strs << "|" << progress_bar_string << "| " << time_string << empty_space; std::string temp_str = strs.str(); char const* char_type = temp_str.c_str(); // print: remove old and replace with new REprintf("\r"); REprintf("%s", char_type); // finalize display when ready if(progress == 1) { _finalize_display(); } } } void end_display() { update(1); } protected: // ==== other instance methods ===== // convert double with seconds to time string std::string _time_to_string(double seconds) { int time = (int) seconds; int hour = 0; int min = 0; int sec = 0; hour = time / 3600; time = time % 3600; min = time / 60; time = time % 60; sec = time; std::stringstream time_strs; if (hour != 0) time_strs << hour << "h "; if (min != 0) time_strs << min << "min "; if (sec != 0) time_strs << sec << "s "; std::string time_str = time_strs.str(); return time_str; } // update the ticks display corresponding to progress std::string _current_ticks_display(float progress) { int nb_ticks = _compute_nb_ticks(progress); std::string cur_display = _construct_ticks_display_string(nb_ticks); return cur_display; } // construct progress bar display std::string _construct_ticks_display_string(int nb) { std::stringstream ticks_strs; for (int i = 0; i < (_max_ticks - 1); ++i) { if (i < nb) { ticks_strs << "*"; } else { ticks_strs << " "; } } std::string tick_space_string = ticks_strs.str(); return tick_space_string; } // finalize void _finalize_display() { if (_finalized) return; REprintf("\n"); flush_console(); _finalized = true; } // compute number of ticks according to progress int _compute_nb_ticks(float progress) { return int(progress * _max_ticks); } // N.B: does nothing on windows void flush_console() { #if !defined(WIN32) && !defined(__WIN32) && !defined(__WIN32__) R_FlushConsole(); #endif } private: // ===== INSTANCE VARIABLES ==== int _max_ticks; // the total number of ticks to print bool _finalized; bool _timer_flag; time_t start,end; }; #endif RcppProgress/inst/examples/RcppProgressETA/src/Makevars0000644000176200001440000000031613275125021022742 0ustar liggesusers## Use the R_HOME indirection to support installations of multiple R version PKG_LIBS = `$(R_HOME)/bin/Rscript -e "Rcpp:::LdFlags()"` $(SHLIB_OPENMP_CXXFLAGS) PKG_CXXFLAGS += -Wall $(SHLIB_OPENMP_CXXFLAGS) RcppProgress/inst/examples/RcppProgressETA/R/0000755000176200001440000000000013275125021020660 5ustar liggesusersRcppProgress/inst/examples/RcppProgressETA/R/examples.R0000644000176200001440000000057613275125021022631 0ustar liggesusers test_sequential <- function(max=100, nb=1000, display_progress=TRUE) { .Call("test_sequential_wrapper2", max, nb, display_progress, PACKAGE = "RcppProgressETA") invisible() } test_multithreaded <- function(max=100, nb=1000, threads=0, display_progress=TRUE) { .Call("test_multithreaded_wrapper2", max, nb, threads, display_progress, PACKAGE = "RcppProgressETA") invisible() } RcppProgress/inst/include/0000755000176200001440000000000013616765256015324 5ustar liggesusersRcppProgress/inst/include/interruptable_progress_monitor.hpp0000644000176200001440000001123213275125021024364 0ustar liggesusers/* * interruptable_progress_monitor.hpp * * A class that monitors the progress of computations: * - can display a progress bar * - can handle user interrupt (R user level) or programmatic abort * - can be used in OpenMP loops * * Author: karl.forner@gmail.com * */ #ifndef _RcppProgress_INTERRUPTABLE_PROGRESS_MONITOR_HPP #define _RcppProgress_INTERRUPTABLE_PROGRESS_MONITOR_HPP #include "interrupts.hpp" #include "progress_bar.hpp" //#include "fetch_raw_gwas_bar.hpp" #ifdef _OPENMP #include #endif class InterruptableProgressMonitor { public: // ====== LIFECYCLE ===== /** * Main constructor * * @param max the expected number of tasks to perform * @param display_progress whether to display a progress bar in the console * @param pb the ProgressBar instance to use */ InterruptableProgressMonitor( unsigned long max, bool display_progress, ProgressBar& pb ) : _progress_bar(pb) { reset(max, display_progress); if (is_display_on()) { _progress_bar.display(); } } ~InterruptableProgressMonitor() { if (is_display_on() && !is_aborted()) _progress_bar.end_display(); } public: // ===== ACCESSORS/SETTERS ===== void set_display_status(bool on) { _display_progress = on; } bool is_display_on() const { return _display_progress; } unsigned long get_max() const { return _max; } bool is_aborted() const { return _abort; } public: // ===== PBLIC MAIN INTERFACE ===== /** * increment the current progress. * * Iff called by the master thread, it will also update the display if needed * * @param amount the number of newly performed tasks to report * * @return false iff the computation is aborted */ bool increment(unsigned long amount=1) { if ( is_aborted() ) return false; return is_master() ? update_master(_current + amount) : atomic_increment(amount); } /** * set the current progress indicator * * Iff called by the master thread, it will also update the display if needed * * @param current the total number of performed tasks so far (by all threads) * * @return false iff the computation is aborted */ bool update(unsigned long current) { if ( is_aborted() ) return false; return is_master() ? update_master(current) : atomic_update(current); } /** * check that the no interruption has been requested and return the current status * * Iff called by the master thread, it will check for R-user level interruption. * * @return true iff the computation is aborted */ bool check_abort() { if ( is_aborted() ) return true; if ( is_master() ) { check_user_interrupt_master(); } return is_aborted(); } /** * request computation abortion */ void abort() { #ifdef _OPENMP #pragma omp critical #endif _abort = true; } /** * return true iff the thread is the master. * In case of non-OpenMP loop, always return true */ bool is_master() const { #ifdef _OPENMP return omp_get_thread_num() == 0; #else return true; #endif } public: // ===== methods for MASTER thread ===== /** * set the current progress indicator and update the progress bar display if needed. * * * @param current the total number of performed tasks * * @return false iff the computation is aborted */ bool update_master(unsigned long current) { _current = current; if (is_display_on()) _progress_bar.update(progress(current)); return ! is_aborted(); } void check_user_interrupt_master() { if ( !is_aborted() && checkInterrupt() ) { abort(); } } public: // ===== methods for non-MASTER threads ===== bool atomic_increment(unsigned long amount=1) { #ifdef _OPENMP #pragma omp atomic #endif _current+=amount; return ! is_aborted(); } bool atomic_update(unsigned long current) { #ifdef _OPENMP #pragma omp critical #endif _current=current; return ! is_aborted(); } protected: // ==== other instance methods ===== // convert current value to [0-1] progress double progress(unsigned long current) { return double(current) / double(_max); } /** * reset the monitor. * * Currently not really useful * * @param max the expected number of tasks to perform * @param display_progress whether to display a progress bar in the console * */ void reset(unsigned long max = 1, bool display_progress = true) { _max = max; if ( _max <= 0 ) _max = 1; _current = 0; _display_progress = display_progress; _abort = false; } private: // ===== INSTANCE VARIABLES ==== ProgressBar& _progress_bar; unsigned long _max; // the nb of tasks to perform unsigned long _current; // the current nb of tasks performed bool _abort; // whether the process should abort bool _display_progress; // whether to display the progress bar }; #endif RcppProgress/inst/include/interrupts.hpp0000644000176200001440000000213113275125021020226 0ustar liggesusers/* * Check for user interruption in C++ code interrupting execution of the current code * * This code has been written by Simon Urbanek * I took it from the R-devel mailing list * in the thread "[Rd] Interrupting C++ code execution" * The mail is dated: 25 april 2011 * * It allows to check for user interruption without * leaving the c++ function that calls it. * * Potential drawbacks according to its author: * The problem with it is that it will eat all errors, even if they were not yours * (e.g. those resulting from events triggered the event loop), so I would not recommend it for general use. * */ #ifndef _RcppProgress_INTERRUPTS_HPP #define _RcppProgress_INTERRUPTS_HPP // N.B: seems the right way to include Rinternals.h in a Rcpp package #include static void chkIntFn(void *dummy) { R_CheckUserInterrupt(); } // this will call the above in a top-level context so it won't longjmp-out of your context inline bool checkInterrupt() { return (R_ToplevelExec(chkIntFn, NULL) == FALSE); } // fix a bug because of the length macro (in sglOptim_1.0.122.1) #undef length #endif RcppProgress/inst/include/simple_progress_bar.hpp0000644000176200001440000000426613275125021022063 0ustar liggesusers/* * simple_progress_bar.hpp * * A class that display a progress bar * * Author: karl.forner@gmail.com * */ #ifndef _RcppProgress_SIMPLE_PROGRESS_BAR_HPP #define _RcppProgress_SIMPLE_PROGRESS_BAR_HPP #include "progress_bar.hpp" #include // for unices only #if !defined(WIN32) && !defined(__WIN32) && !defined(__WIN32__) #include #endif class SimpleProgressBar: public ProgressBar{ public: // ====== LIFECYCLE ===== /** * Main constructor */ SimpleProgressBar() { reset(); } ~SimpleProgressBar() {} public: // ===== main methods ===== void display() { REprintf("0%% 10 20 30 40 50 60 70 80 90 100%%\n"); REprintf("[----|----|----|----|----|----|----|----|----|----|\n"); flush_console(); } // will finalize display if needed void update(float progress) { _update_ticks_display(progress); if (_ticks_displayed >= _max_ticks) _finalize_display(); } void end_display() { update(1); reset(); } void reset() { _max_ticks = 50; _ticks_displayed = 0; _finalized = false; } protected: // ==== other instance methods ===== // update the ticks display corresponding to progress void _update_ticks_display(float progress) { int nb_ticks = _compute_nb_ticks(progress); int delta = nb_ticks - _ticks_displayed; if (delta > 0) { _display_ticks(delta); _ticks_displayed = nb_ticks; } } void _finalize_display() { if (_finalized) return; REprintf("|\n"); flush_console(); _finalized = true; } int _compute_nb_ticks(float progress) { return int(progress * _max_ticks); } void _display_ticks(int nb) { for (int i = 0; i < nb; ++i) { REprintf("*"); R_FlushConsole(); } } // N.B: does nothing on windows void flush_console() { #if !defined(WIN32) && !defined(__WIN32) && !defined(__WIN32__) R_FlushConsole(); #endif } private: int _max_ticks; // the total number of ticks to print int _ticks_displayed; // the nb of ticks already displayed bool _finalized; }; #endif RcppProgress/inst/include/progress.hpp0000644000176200001440000000532013616765256017701 0ustar liggesusers/* * progress.hpp * * A Front-end class for InterruptableProgressMonitor. * * Author: karl.forner@gmail.com * */ #ifndef _RcppProgress_PROGRESS_HPP #define _RcppProgress_PROGRESS_HPP #include "interruptable_progress_monitor.hpp" #include "simple_progress_bar.hpp" // e.g. for Rf_error #include class Progress { public: /** * * Main constructor * @param max the expected number of tasks to perform * @param display_progress whether to display a progress bar in the console * @param pb the ProgressBar instance to use */ Progress( unsigned long max, bool display_progress = true, ProgressBar& pb = default_progress_bar() ) { cleanup(); monitor_singleton() = new InterruptableProgressMonitor(max, display_progress, pb); } ~Progress() { cleanup(); } public: // ==== USER INTERFACE ===== /** * cleanup * * should normally not be called, unless a something bad happens ( * a process/thread that crashes). * */ void cleanup() { if (monitor_singleton() != 0) delete monitor_singleton(); monitor_singleton() = 0; } /** * increment the current progress. * * This method should preferably be used intead of update in a OpenMP context. * * Iff called by the master thread, it will also update the display if needed * * @param amount the number of newly performed tasks to report * * @return false iff the computation is aborted */ bool increment(unsigned long amount=1) { return monitor().increment(amount); } /** * set the current progress indicator * * Iff called by the master thread, it will also update the display if needed * * @param current the total number of performed tasks so far (by all threads) * * @return false iff the computation is aborted */ bool update(unsigned long current) { return monitor().update(current); } /** * return if the computation has been aborted. * N.B: do not perform any check by itselfd */ bool is_aborted() const { return monitor().is_aborted(); } /** * check that the no interruption has been requested and return the current status * * Iff called by the master thread, it will check for R-user level interruption. * * @return true iff the computation is aborted */ static bool check_abort() { return monitor().check_abort(); } private: static InterruptableProgressMonitor*& monitor_singleton() { static InterruptableProgressMonitor* p = 0; return p; } // trick to provide a default static member in a header file static SimpleProgressBar& default_progress_bar() { static SimpleProgressBar pb; pb.reset(); return pb; } public: // ==== OTHER PUBLIC INTERFACE ===== static InterruptableProgressMonitor& monitor() { return *monitor_singleton(); } }; #endif RcppProgress/inst/include/progress_bar.hpp0000644000176200001440000000121713275125021020503 0ustar liggesusers/* * progress_bar.hpp * * An abstract class for classes that display a progress bar * * Author: karl.forner@gmail.com * */ #ifndef _RcppProgress_PROGRESS_BAR_HPP #define _RcppProgress_PROGRESS_BAR_HPP class ProgressBar { public: // subclasses should not rely on the destructor to finalize the display virtual ~ProgressBar() = 0; // start the display. It will be updated by subsequent calls to update() virtual void display() = 0; // update if needed the display virtual void update(float progress) = 0; // finalize the display virtual void end_display() = 0; }; inline ProgressBar::~ProgressBar() {} #endif