My functions in R package using Rcpp and snowfall are slower than not in the package - rcpp

I am developing an R package that uses mainly Rcpp, RcppArmadillo and snowfall (for parallel computing). It passed both `devtools::check' and 'devtools::check_rhub()'. However, I noticed that my code is slower in the package and would like to close the gap between the two. For example,
This is the system.time() result for running my code in the package.
user system elapsed
18.72 31.12 135.56
On the other hand, here is the system.time() result running my code normally outside of the package.
user system elapsed
4.23 2.98 102.18
In addition, I also profiled (profvis) both and noticed a significantly longer time for sfLapply(for parallel computing) in the package environment. Here I provide a short summary of my code structure between the two. If needed, I'll add a link to my github code page.
Code in package
The cpp functions are built into a DLL.
foo = function(...,core=10){
sfInit(parallel=TRUE,cpus=core) ## set number of cores for parallel computing
sfClusterSetupRNG( type="RNGstream",seed=cluster_seed) ## set cluster seed for reproducibility
## read inputs and set parameters
.
.
.
sfExport(list=ls()) ##exporting parameters to cores
node = 0:(core-1)
print(system.time({
for(i in 1:iter){
## update_a and update_b are cpp functions built in DLL using "build and reload"
a = sfLapply(node, update_a, a, b,...)
sfExport("a")
b = sfLapply(node, update_b, a, b,...)
sfExport("b")
.
.
.
}
}))
return(...)
}
Namespace:
export(foo)
import(RcppArmadillo)
import(rlecuyer)
import(snow)
import(rlecuyer)
importFrom("snowfall",...)
importFrom("stats","rgamma")
importFrom("stats","runif")
importFrom(Rcpp,sourceCpp)
useDynLib(mypackage, .registration=TRUE)
Code outside of package
The main difference from above is that I need to:
Export the dependent the package to clusters/cores through sfLibrary("Rcpp", character.only=TRUE) and sfLibrary("RcppArmadillo", character.only=TRUE).
Parses my cpp code via sourceCpp(code = RcppCode) and then load it to the clusters/cores via sfClusterEval(sourceCpp(code = RcppCode)) where RcppCode contains all my cpp code as follows,
RcppCode = '
#include <RcppArmadillo.h>
#include <Rmath.h>
using namespace Rcpp;
// Enable C++11 via this plugin (Rcpp 0.10.3 or later)
// [[Rcpp::plugins("cpp11")]]
//[[Rcpp::depends(RcppArmadillo)]]
.
.
.
// [[Rcpp::export]]
List update_a(...){
.
.
.
return List::create(...)
}
.
.
.
'
Session Info for the dependent packages and platform:
R version 4.0.3 (2020-10-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18363)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] RcppArmadillo_0.10.1.2.0 rlecuyer_0.3-5 Rcpp_1.0.5 snowfall_1.84-6.1 snow_0.4-3
loaded via a namespace (and not attached):
[1] compiler_4.0.3 parallel_4.0.3 tools_4.0.3
Any suggestions on how to close the speed gap between the two are much appreciated. Thank you very much.

Related

\DeclareSymbolFont Not working with Ankiweb app

I am attempting to use math symbols that don't exist by default as part of existing packages in Options for notes (eg. amsmath). I tested the below code in TeXworks (pdfLaTeX) with no issues.
\DeclareSymbolFont{matha}{OML}{txmi}{m}{it}% txfonts
\DeclareMathSymbol{\varv}{\mathord}{matha}{118}
...
$ \varv = 0 $
Upon adding the \DeclareSymbolFont... and \DeclareMathSymbol... lines to
Tools => Manage Note Types => Options, and inserting the lines before \begin{document}, I tried below lines in Ankiweb app Card
\( \varv = 0 \) or [$] \varv = 0 [/$],
but ankiweb app doesnt convert this to the right symbol as it does with TeXworks
Is there something I need to do specifically? Or is the above steps not allowed in Ankiweb app.
Ankiweb app details:
Version ⁨2.1.54 (b6a7760c)⁩
Python 3.9.7 Qt 5.15.2 PyQt 5.15.5

.exe has stopped working when use thread module

I just copy the code from the example on nim's offical documentation:
import std/locks
var
thr: array[0..4, Thread[tuple[a,b: int]]]
L: Lock
proc threadFunc(interval: tuple[a,b: int]) {.thread.} =
for i in interval.a..interval.b:
acquire(L) # lock stdout
echo i
release(L)
initLock(L)
for i in 0..high(thr):
createThread(thr[i], threadFunc, (i*10, i*10+5))
joinThreads(thr)
deinitLock(L)
$ nimble build --threads:on
Verifying dependencies for thread#0.1.0
Building thread/thread.exe using c backend
$ .\thread
then thread.exe crashed...
thread.exe
0.0.0.0
630c5e83
libwinpthread-1.dll
6.3.9600.20512
62cdfc6e
c0000135
00000000000ed1b0
1fc8
01d8bb71e28918ba
F:\MyProjects\Nim\thread\thread.exe
libwinpthread-1.dll
2044d161-2765-11ed-827a-6c86063c07b4
I have no ideas about it...Can anybody help me? Thanks a lot.
Gave it a try in Windows 8.1, it does fail.
Apparently is a recent regression in nim you can make it work if you compile it with --threads:on --tlsEmulation:on (or make sure mingw binaries is on your PATH).

Why do OpenGL-based VTK targets in drake executed via `bazel test` sometimes fail on Linux?

While a binary works with bazel run, when I run a test using bazel test, such as:
$ bazel test //systems/sensors:rgbd_camera_test
I encounter a slew of errors from VTK / OpenGL:
ERROR: In /vtk/Rendering/OpenGL2/vtkXOpenGLRenderWindow.cxx, line 820
vtkXOpenGLRenderWindow (0x55880715b760): failed to create offscreen window
ERROR: In /vtk/Rendering/OpenGL2/vtkOpenGLRenderWindow.cxx, line 816
vtkXOpenGLRenderWindow (0x55880715b760): GLEW could not be initialized.
ERROR: In /vtk/Rendering/OpenGL2/vtkShaderProgram.cxx, line 453
vtkShaderProgram (0x5588071d5aa0): Shader object was not initialized, cannot attach it.
ERROR: In /vtk/Rendering/OpenGL2/vtkOpenGLRenderWindow.cxx, line 1858
vtkXOpenGLRenderWindow (0x55880715b760): Hardware does not support the number of textures defined.
May I ask why this happens?
(Note: This post is a means to migrate from http://drake.mit.edu/faq.html to StackOverflow for user-based questions.)
The best workaround at the moment is to first mark the test as as local in the BUILD.bazel file, either with local = 1, or tags = [.., "local"]. Doing so will make the specific target run without sandboxing, such that it has an environment similar to that of bazel run.
As an example, in systems/sensors/BUILD.bazel:
drake_cc_googletest(
name = "rgbd_camera_test",
# ...
local = 1,
# ...
)
If this does not work, then try running the test in Bazel without sandboxing:
$ bazel test --spawn_strategy=standalone //systems/sensors:rgbd_camera_test
Please note that you can possibly add --spawn_strategy=standalone to your ~/.bazelrc, but be aware that this means your development testing environment may deviate even more from other developer's testing environments.

Reserving physical memory space as early as possible in Linux boot-time

I am trying to find a way to reserve physical memory for a proprietary memory type hardware as early as possible after system boots up (Linux CentOs with Intel Xeon server platform).
I did the following at setup_arch() in arch/x86/kernel/setup.c and it works, but found out that I am not allowed to patch the kernel. The requirement is no BIOS and kernel mod.
setup_arch()
{
....
// Calls a proprietary function that returns custom proprietary memory module's starting address and size.
memblock_reserve(mem_start_addr, mem_size);
.....
}
I cannot use memmap=xx/xx either at Grub, because the start and size of the device is unknown (it has to be "discovered" by software)
Is there any way to do this?
One idea is to write a custom grub module and set memmap=xx using it.
The following is how to do it.
Note that following method only works above CentOS 7 since CentOS 6.x or below uses grub 0.9x .
In that case, you may have to modify code of grub 0.9x and replace /boot/grub/stage1 or /boot/grub/stage2
$ git clone git://git.savannah.gnu.org/grub.git
$ cd grub
$ git checkout grub-2.02-beta2 # CentOS 7 currently uses grub-2.02-beta
$ vim grub-core/Makefile.core.def # add following row
module = {
name = my_custom_module;
common = lib/my_custom_module.c;
};
$ vim grub-core/lib/my_custom_module.c # create following file
#include <grub/dl.h>
#include <grub/env.h>
GRUB_MOD_LICENSE ("GPLv3+");
GRUB_MOD_INIT(my_custom_module){
// Calls a proprietary function that returns custom proprietary memory module's starting address and size.
const char *mem_size = "123";
grub_env_set("my_memsize",mem_size);
}
GRUB_MOD_FINI(my_custom_module){
}
$ ./autogen.sh
$ ./configure
$ make
Now you can find that grub-core/my_custom_module.mod is created.
so copy it to /boot/grub2/i386-pc/ (or whatever your *.mod file exists)
Edit the grub.conf and add something like
insmod my_custom_module
linux /boot/vmlinuz-3.10.el7.x86_64 root=UUID=1a3b5c7d9 ro memmap=${my_memsize}

Example waf project with vala

there is a nice waf vala example here:
https://code.launchpad.net/~asabil/vala/vala-project-template.waf
and it shows a library and an application in vala. Unfortunately the program in this example does not actually USE the library (which defines method "hello"). When I try to call it from the program, I get compilation errors.
I am not able to modify the wscript's to load the library properly. What is the trick here? Thanks.
What I have added is this line in the program:
My.Lib.hello();
But it won't compile:
Waf: Entering directory `/home/lzap/work/shellmail/TEST/vala-template/_build_'
[1/6] valac: src/hello-gtk.vala -> _build_/default/src/hello-gtk.c
../src/hello-gtk.vala:16.9-16.10: error: The name `My' does not exist in the context of `Sample.create_widgets._lambda0_'
Waf: Leaving directory `/home/lzap/work/shellmail/TEST/vala-template/_build_'
Build failed: -> task failed (err #1):
{task: valac_task hello-gtk.vala -> hello-gtk.c}
I guess I need to change the program wscript:
#!/usr/bin/env python
def build(bld):
prog = bld(features='cc cprogram')
# symbolic name used to reference this object
prog.name = 'hello-gtk.program'
# name of the resulting program
prog.target = 'hello-gtk'
prog.source = 'hello-gtk.vala'
# libraries to link against
prog.uselib = 'GTK+'
# Vala packages to use
prog.packages = 'gtk+-2.0'
# Extra vapi dirs
#prog.vapi_dirs = '../my_lib'
# Enable threading
#prog.threading = True
The hello method is not an static method, but an instance method, so, you need to create a My.Lib instance first and then call the method.
var obj = new My.Lib();
obj.hello();
If this still failing, try to add using My; on hello-gtk.vala.

Resources