Makefile สำหรับใช้กับ แพ็คเกจที่ใช้ RcppArmadillo

พอดีว่าเขียนแพ็คเกจที่มีเรียกใช้งาน armadillo ใน Rcpp แล้วมีปัญหาเวลา compile ในเรื่องของ linking

คำแนะนำที่เจอบ่อยๆก็คือให้สร้างไฟล์ Makefile หรือ Makefile.win ไว้ที่เดียวกันกับ src โดยที่ใน Makefile ก็มีการประกาศตัวแปรตามข้างล่างนี้เลยครับ

CXX_STD = CXX11

PKG_CXXFLAGS = $(SHLIB_OPENMP_CXXFLAGS) 

PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)

หรือแต่ถ้าไม่อยากให้มีปัญหานี้ตั้งแต่แรกก็ให้ใช้ Rcpp แล้วก็สร้างแพ็คเกจจากตัวอย่างที่เขาทำไว้แล้วจากคำสั่ง RcppArmadillo.package.skeleton ครับ

ปัญหา Path ของ Rtools

rtools มันจำเป็นสำหรับ r package ที่มี code จากภาษาอื่น อย่าง c/c++ หรือ fortran ในที่จะต้องมีการ compile ระหว่างการติดตั้ง โดยปกติแล้วมัน จะถูกลงไว้ที่

PATH="C:\Rtools\bin;${PATH}" 

ถ้าลงไว้ที่อื่นและต้องการเรียกใช้ใน R ตัวแปรชื่อ BINPREF จะเป็นตัวแปรที่ R จะเรียกหา path ของ rtools ฉะนั้นถ้าจะเรียกใช้ rtools ที่ลงไว้ที่อื่นก็ต้องเซ็ต path ให้กับตัวแปรนี้ เช่น

BINPREF="X:/R/Rtools-3.5/mingw_$(WIN)/bin/" 

** สังเกตว่า BINPREF ใช้ forward slash นะครับ

ใช้ OpenMP กับ Rcpp

ที่มา https://github.com/RcppCore/Rcpp/blob/master/inst/examples/OpenMP/OpenMPandInline.r

ตัวอย่าง Rcpp กับ OpenMP

library(inline)

openMPCode <- ‘

// assign to C++ vector

std::vector<double> x = Rcpp::as<std::vector< double > >(xs);

size_t n = x.size();

#pragma omp parallel for shared(x, n)

for (size_t i=0; i<n; i++) {

x[i] = ::log(x[i]);

}

return Rcpp::wrap(x);

settings <- getPlugin("Rcpp")
settings$env$PKG_CXXFLAGS <- paste('-fopenmp', settings$env$PKG_CXXFLAGS)
settings$env$PKG_LIBS <- paste('-fopenmp -lgomp', settings$env$PKG_LIBS)

funOpenMP <- cxxfunction(signature(xs="numeric"), body=openMPCode, plugin="Rcpp", settings=settings)

z <- seq(1, 2e6)

funOpenMP(z)

Rcpp::sourceCpp กับปัญหา -Wunused-variable

ใครที่ใช้ sourceCpp สำหรับ compile โค้ดของ Rcpp แล้วเจอปัญหา unsed-variable แล้วอยากที่จะ  ignore มัน ก็สามารถทำได้ด้วยการสร้างไฟล์ Makevars ที่มีบรรทัดนี้ครับ

CXXFLAGS += -O3 -Wall -pipe -Wno-unused

หรือไม่ก็แก้ไขไฟล์ Makeconf ที่ R_HOME/bin/R_ARCH (ไม่ค่อยแนะนำ) โดยเพิ่ม -O3 -Wall -pipe -Wno-unused  ในส่วนของ CXXFLAGS  ครับ