@@ -3,6 +3,8 @@ title: Using RcppProgress to control the long computations in C++
33author : Karl Forner
44license : GPL (>= 2)
55tags : interrupt openmp
6+ updated : Jul 09, 2017
7+ updateauthor : Matt Dziubinski
68summary : Demonstrates how to display a progress bar and interrupt C++ code.
79layout : post
810src : 2013-05-16-using-rcppprogress.Rmd
@@ -41,7 +43,6 @@ double long_computation(int nb) {
4143{% endhighlight %}
4244
4345
44-
4546{% highlight r %}
4647 system.time(s <- long_computation(1000))
4748{% endhighlight %}
@@ -50,7 +51,7 @@ double long_computation(int nb) {
5051
5152<pre class =" output " >
5253 user system elapsed
53- 0.116 0.000 0.116
54+ 0.116 0.000 0.114
5455</pre >
5556
5657
@@ -62,11 +63,10 @@ double long_computation(int nb) {
6263
6364
6465<pre class =" output " >
65- [1] 1002
66+ [1] 1002.32
6667</pre >
6768
6869
69-
7070## Checking for user interrupts
7171
7272Let's modify our code to add a check for user interruption by calling the function
@@ -97,7 +97,6 @@ double long_computation2(int nb) {
9797{% endhighlight %}
9898
9999
100-
101100{% highlight r %}
102101 system.time(s <- long_computation2(3000)) # interrupt me
103102{% endhighlight %}
@@ -106,7 +105,7 @@ double long_computation2(int nb) {
106105
107106<pre class =" output " >
108107 user system elapsed
109- 1.044 0.000 1.044
108+ 1.012 0.000 1.022
110109</pre >
111110
112111
@@ -118,11 +117,10 @@ double long_computation2(int nb) {
118117
119118
120119<pre class =" output " >
121- [1] 3002
120+ [1] 3002.32
122121</pre >
123122
124123
125-
126124You may wonder why we put the ` check_abort ` call in the first loop instead
127125that in the second. The performance cost of ` check_abort ` call is not
128126negligible. It should be put in a place called often enough (once per
@@ -139,6 +137,7 @@ it at a place called at least every second.
139137{% highlight cpp %}
140138// [[ Rcpp::depends(RcppProgress)]]
141139#include <progress.hpp>
140+ #include <progress_bar.hpp>
142141// [[ Rcpp::export]]
143142double long_computation3(int nb, bool display_progress=true) {
144143 double sum = 0;
@@ -156,7 +155,6 @@ double long_computation3(int nb, bool display_progress=true) {
156155{% endhighlight %}
157156
158157
159-
160158{% highlight r %}
161159 system.time(s <- long_computation3(3000)) # interrupt me
162160{% endhighlight %}
@@ -165,7 +163,7 @@ double long_computation3(int nb, bool display_progress=true) {
165163
166164<pre class =" output " >
167165 user system elapsed
168- 1.072 0.000 1.073
166+ 1.156 0.004 1.196
169167</pre >
170168
171169
@@ -177,22 +175,21 @@ double long_computation3(int nb, bool display_progress=true) {
177175
178176
179177<pre class =" output " >
180- [1] 3002
178+ [1] 3002.32
181179</pre >
182180
183-
184181## OpenMP support
185182
186- First we need this to enable OpenMP support for gcc:
183+ First we need this to enable OpenMP support for ` gcc ` . In the early days we used
187184
188185
189186{% highlight r %}
190187Sys.setenv("PKG_CXXFLAGS"="-fopenmp")
191188Sys.setenv("PKG_LIBS"="-fopenmp")
192189{% endhighlight %}
193190
194-
195- Future Rcpp versions should have a plugin which does this for us.
191+ and more recent version of Rcpp have a plugin
192+ Recent Rcpp versions should have a plugin which does this for us.
196193
197194Here is an OpenMP version of our function:
198195
@@ -201,6 +198,7 @@ Here is an OpenMP version of our function:
201198#ifdef _ OPENMP
202199#include <omp.h>
203200#endif
201+ // [[ Rcpp::plugins(openmp)]]
204202// [[ Rcpp::depends(RcppProgress)]]
205203#include <progress.hpp>
206204// [[ Rcpp::export]]
@@ -224,7 +222,6 @@ double long_computation_omp(int nb, int threads=1) {
224222}
225223{% endhighlight %}
226224
227-
228225Now check that it is parallelized:
229226
230227{% highlight r %}
@@ -235,7 +232,7 @@ Now check that it is parallelized:
235232
236233<pre class =" output " >
237234 user system elapsed
238- 4.208 0.000 1.069
235+ 2.848 0.004 0.990
239236</pre >
240237
241238
@@ -247,7 +244,7 @@ Now check that it is parallelized:
247244
248245
249246<pre class =" output " >
250- [1] 5002
247+ [1] 5002.14
251248</pre >
252249
253250
@@ -260,7 +257,7 @@ Now check that it is parallelized:
260257
261258<pre class =" output " >
262259 user system elapsed
263- 2.948 0.000 2.949
260+ 2.836 0.004 2.851
264261</pre >
265262
266263
@@ -272,28 +269,29 @@ Now check that it is parallelized:
272269
273270
274271<pre class =" output " >
275- [1] 5002
272+ [1] 5002.32
276273</pre >
277274
278-
279275## adding progress monitoring to the openMP function
280276
281277
282278{% highlight cpp %}
283279#ifdef _ OPENMP
284280#include <omp.h>
285281#endif
282+ // [[ Rcpp::plugins(openmp)]]
286283// [[ Rcpp::depends(RcppProgress)]]
287284#include <progress.hpp>
285+ #include <progress_bar.hpp>
288286// [[ Rcpp::export]]
289- double long_computation_omp2(int nb, int threads=1) {
287+ double long_computation_omp2(const int nb, int threads=1) {
290288#ifdef _ OPENMP
291289 if ( threads > 0 )
292290 omp_set_num_threads( threads );
293291#endif
294292 Progress p(nb, true);
295293 double sum = 0;
296- #pragma omp parallel for schedule(dynamic)
294+ #pragma omp parallel for default(none) reduction(+ : sum) schedule(dynamic)
297295 for (int i = 0; i < nb; ++i) {
298296 double thread_sum = 0;
299297 if ( ! Progress::check_abort() ) {
@@ -309,37 +307,26 @@ double long_computation_omp2(int nb, int threads=1) {
309307{% endhighlight %}
310308
311309
312-
313310{% highlight r %}
314- system.time(s <- long_computation_omp2(5000, 4))
311+ system.time(s <- long_computation_omp2(5000, 4))
315312{% endhighlight %}
316313
317-
318-
319- <pre class =" output " >
320- user system elapsed
321- 4.108 0.000 1.049
322- </pre >
323-
324-
325314## Test it now
326315
327316If you want to test it now in your R console, just paste the following code
328317(after installing the
329318[ RcppProgress] ( http://cran.r-project.org/web/packages/RcppProgress/index.html )
330319package, of course):
331320
332- {% highlight r %}
333- library(Rcpp)
334- Sys.setenv("PKG_CXXFLAGS"="-fopenmp")
335- Sys.setenv("PKG_LIBS"="-fopenmp")
336321
337- code='
322+ {% highlight cpp %}
338323#ifdef _ OPENMP
339324#include <omp.h>
340325#endif
326+ // [[ Rcpp::plugins(openmp)]]
341327// [[ Rcpp::depends(RcppProgress)]]
342328#include <progress.hpp>
329+ #include <progress_bar.hpp>
343330
344331// [[ Rcpp::export]]
345332double long_computation_omp2(int nb, int threads=1) {
@@ -364,9 +351,13 @@ double long_computation_omp2(int nb, int threads=1) {
364351
365352 return sum + nb;
366353}
367- '
354+ {% endhighlight %}
368355
369- sourceCpp(code=code)
356+ and run
357+
358+
359+ {% highlight r %}
360+ Rcpp::sourceCpp(code=code)
370361s <- long_computation_omp2(10000, 4)
371362{% endhighlight %}
372363
0 commit comments