Search code examples
ropenmprcpp

Rcpp Compiler error in r tools for Visual Studio 2015


I am a new user of Rcpp and OpenMP.
I have written code to multiply two arrays.
I want use omp as well just to check its performance with big matrices.

I use R tools in Visual Studio 2015 to work and run this code:

This code

When I compile it in r tools for Visual Studio 2015, I get this error:

c:/Rtools/mingw_64/bin/g++ -m64 -I"C:/PROGRA~1/MIE74D~1/ROPEN~1/R-35~1.1/include" -DNDEBUG   -I"C:/Users/amaa11/Documents/R/win-library/3.5/Rcpp/include" -I"C:/Users/amaa11/DOCUME~1/VISUAL~1/Projects/RPROJE~1/RPROJE~1"   -I"C:/swarm/workspace/External-R-3.5.1/vendor/extsoft/include"     -O2 -Wall  -mtune=core2 -c mul_mat.cpp -o mul_mat.o
mul_mat.cpp:10:4: error: stray '#' in program
/ /#pragma omp parallel for
^
mul_mat.cpp:4:1: error: expected unqualified-id before '/' token
/ / [[Rcpp::export(mul_mat)]]<br>
^
make: *** [mul_mat.o] Error 1

How can I fix it?


Solution

  • The quick and easy answer is: Remove the space between comment forward slashes. For example, change

    / /#pragma omp parallel for
    

    to

    //#pragma omp parallel for
    

    However, I also have other comments/tips for asking questions here in the future:

    • Please don't post a picture of your code. Copy and paste it into your question. Then answerers can easily copy and paste your code to test it. I manually re-typed your code in this case to test it (so I can say with certainty this answer will solve your error), as I'm just sitting bored drinking my morning coffee, but in other situations, would honestly probably have not taken the time to re-do your typing.
    • If what you're wanting is matrix multiplication, go for RcppArmadillo! As several answers to other questions on here have pointed out, it's an obvious choice for matrix multiplication and already uses "multi-threaded OpenBLAS as well as OpenMP".
    • Note that you don't have to initialize the elements of mult to 0; as stated in, for example, the Rcpp Quick Reference Guide, a NumericMatrix constructed in a way such as Rcpp::NumericMatrix x(n, m) creates an n by m matrix already filled with 0.

    Update

    So, for completeness, this is the fixed code that compiled fine for me:

    #include <Rcpp.h>
    #include <omp.h>
    
    using namespace Rcpp;
    
    // [[Rcpp::export]]
    NumericMatrix mul_mat(int n, NumericMatrix A, NumericMatrix B) {
        int i, j, k;
        NumericMatrix mult(n, n);
        for ( i = 0; i < n; ++i ) {
            //#pragma omp parallel for
            for ( j = 0; j < n; ++j ) {
                mult(i, j) = 0;
            }
        }
        for ( i = 0; i < n; ++i ) {
            for ( j = 0; j < n; ++j ) {
                for ( k = 0; k < n; ++k ) {
                    mult(i, j) += A(i, k) * B(k, j);
                }
            }
        }
        return mult;
    }
    

    And we can see it exported the function to R (this part added in response to now deleted comments regarding the proper way to export the function to R):

    > Rcpp::sourceCpp("so-answer.cpp")
    > ls()
    [1] "mul_mat"
    

    You initially had a(n incorrectly typed) comment delimiter before the #pragma omp parallel for; if you really want to use it, remove the comment delimiter as well as add // [[Rcpp::plugins(openmp)]]; this is discussed (among other places) in an Rcpp Gallery post:

    Additionally, we can make use of the OpenMP library to use multiple cores. For the OpenMP implementation, we need to enable OpenMP support. One way of doing so is by adding the required compiler and linker flags as follows:

    Sys.setenv("PKG_CXXFLAGS"="-fopenmp")
    Sys.setenv("PKG_LIBS"="-fopenmp")

    Rcpp version 0.10.5 and later will also provide a plugin to set these variables for us:

    // [[Rcpp::plugins(openmp)]]

    So, try:

    #include <Rcpp.h>
    #include <omp.h>
    
    // [[Rcpp::plugins(openmp)]]
    
    using namespace Rcpp;
    
    // [[Rcpp::export]]
    NumericMatrix mul_mat(int n, NumericMatrix A, NumericMatrix B) {
        int i, j, k;
        NumericMatrix mult(n, n);
        for ( i = 0; i < n; ++i ) {
            omp_set_num_threads(2); // For example
            #pragma omp parallel for
            for ( j = 0; j < n; ++j ) {
                mult(i, j) = 0;
            }
        }
        for ( i = 0; i < n; ++i ) {
            for ( j = 0; j < n; ++j ) {
                for ( k = 0; k < n; ++k ) {
                    mult(i, j) += A(i, k) * B(k, j);
                }
            }
        }
        return mult;
    }
    

    which also compiled just fine on my machine.