Rcpp Version 0.9.10
OpenMPandInline.r
Go to the documentation of this file.
00001 #!/usr/bin/r
00002 
00003 library(inline)
00004 library(rbenchmark)
00005 
00006 serialCode <- '
00007    // assign to C++ vector
00008    std::vector<double> x = Rcpp::as<std::vector< double > >(xs);
00009    size_t n = x.size();
00010    for (size_t i=0; i<n; i++) {
00011        x[i] = ::log(x[i]);
00012    }
00013    return Rcpp::wrap(x);
00014 '
00015 funSerial <- cxxfunction(signature(xs="numeric"), body=serialCode, plugin="Rcpp")
00016 
00017 serialStdAlgCode <- '
00018    std::vector<double> x = Rcpp::as<std::vector< double > >(xs);
00019    std::transform(x.begin(), x.end(), x.begin(), ::log);
00020    return Rcpp::wrap(x);
00021 '
00022 funSerialStdAlg <- cxxfunction(signature(xs="numeric"), body=serialStdAlgCode, plugin="Rcpp")
00023 
00024 ## same, but with Rcpp vector just to see if there is measurable difference
00025 serialRcppCode <- '
00026    // assign to C++ vector
00027    Rcpp::NumericVector x = Rcpp::NumericVector(xs);
00028    size_t n = x.size();
00029    for (size_t i=0; i<n; i++) {
00030        x[i] = ::log(x[i]);
00031    }
00032    return x;
00033 '
00034 funSerialRcpp <- cxxfunction(signature(xs="numeric"), body=serialRcppCode, plugin="Rcpp")
00035 
00036 serialStdAlgRcppCode <- '
00037    Rcpp::NumericVector x = Rcpp::NumericVector(xs);
00038    std::transform(x.begin(), x.end(), x.begin(), ::log);
00039    return x;
00040 '
00041 funSerialStdAlgRcpp <- cxxfunction(signature(xs="numeric"), body=serialStdAlgRcppCode, plugin="Rcpp")
00042 
00043 serialImportTransRcppCode <- '
00044    Rcpp::NumericVector x(xs);
00045    return Rcpp::NumericVector::import_transform(x.begin(), x.end(), ::log);
00046 '
00047 funSerialImportTransRcpp <- cxxfunction(signature(xs="numeric"), body=serialImportTransRcppCode, plugin="Rcpp")
00048 
00049 ## now with a sugar expression with internalizes the loop
00050 sugarRcppCode <- '
00051    // assign to C++ vector
00052    Rcpp::NumericVector x = log ( Rcpp::NumericVector(xs) );
00053    return x;
00054 '
00055 funSugarRcpp <- cxxfunction(signature(xs="numeric"), body=sugarRcppCode, plugin="Rcpp")
00056 
00057 ## lastly via OpenMP for parallel use
00058 openMPCode <- '
00059    // assign to C++ vector
00060    std::vector<double> x = Rcpp::as<std::vector< double > >(xs);
00061    size_t n = x.size();
00062 #pragma omp parallel for shared(x, n)
00063    for (size_t i=0; i<n; i++) {
00064        x[i] = ::log(x[i]);
00065    }
00066    return Rcpp::wrap(x);
00067 '
00068 
00069 ## modify the plugin for Rcpp to support OpenMP
00070 settings <- getPlugin("Rcpp")
00071 settings$env$PKG_CXXFLAGS <- paste('-fopenmp', settings$env$PKG_CXXFLAGS)
00072 settings$env$PKG_LIBS <- paste('-fopenmp -lgomp', settings$env$PKG_LIBS)
00073 
00074 funOpenMP <- cxxfunction(signature(xs="numeric"), body=openMPCode, plugin="Rcpp", settings=settings)
00075 
00076 
00077 z <- seq(1, 2e6)
00078 res <- benchmark(funSerial(z), funSerialStdAlg(z),
00079                  funSerialRcpp(z), funSerialStdAlgRcpp(z),
00080                  funSerialImportTransRcpp(z),
00081                  funOpenMP(z), funSugarRcpp(z),
00082                  columns=c("test", "replications", "elapsed",
00083                            "relative", "user.self", "sys.self"),
00084                  order="relative",
00085                  replications=100)
00086 print(res)
00087 
00088 
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines