-
Notifications
You must be signed in to change notification settings - Fork 26
Developer backdoor to manually replace generated C
perrydv edited this page Jun 3, 2017
·
7 revisions
For development purposes, it is useful to be able to repeatedly modify generated C++ during compileNimble workflow. The flag nimbleOptions('pauseAfterWritingFiles') allows one simple way to do this. The compiler will pause and allow any modification. After discussion we wanted a slightly more controllable system. That is drafted for RCfunctions (nimbleFunctions without setup code). The following example should work (currently on branch compile-backdoor):
library(nimble)
## Go through a regular compilation process
nf1 <- nimbleFunction(
name = 'nf1', ## will become second part of filename
run = function(x = double(1)) {
print("Hello from original nf1")
return(sum(x))
returnType(double(0))
})
## projectName argument will become first part of filename
cnf1 <- compileNimble(nf1, dirName = '.', projectName = 'myProject')
cnf1(rnorm(3))
## Now we have myProject_nf1.[h, cpp, .o] and myProject_nf1_<time-date-stamp>.[so, log]
## Now we wish to modify C++
## An RCfunction is not one-to-one with its compiled version (the way an instance of a nimbleFunction class is)
## We can (1) make a new nimbleFunction with same prototype if that is a useful way to manage work
## or (2) re-use an old one.
## Method (1): Make a new (identical in interface) nimbleFunction
nf1 <- nimbleFunction(
name = 'nf1', ## must match above to be used in C++ names
run = function(x = double(1)) {
returnType(double(0))
})
## set this to use files called myNimbleFunctionWork.[h, cpp]
nimble:::specialHandling(nf1) <- list(filename = 'myNimbleFunctionWork') ## setter
nimble:::specialHandling(nf1) ## getter
## Modify previous files as you wish.
## I will copy and replace the text instead of hand-editing.
## (i) Modify the message printed
system('sed s/original/modified/g myProject_nf1.cpp > myNimbleFunctionWork.cpp')
## (ii) Modify the #include line
system('sed -i.bak s/myProject_nf1/myNimbleFunctionWork/g myNimbleFunctionWork.cpp')
## (iii) copy the .h
system('cp myProject_nf1.h myNimbleFunctionWork.h')
nimbleOptions(enableSpecialHandling = TRUE)
cnf1modified <- compileNimble(nf1, dirName = '.')
cnf1modified(rnorm(3))
## Method (2)
## re-use nf1 (this will be the second one created above, but it could be the first one)
## set this to use files called myNimbleFunctionWork2.[h, cpp]
nimble:::specialHandling(nf1) <- list(filename = 'myNimbleFunctionWork2') ## setter
nimble:::specialHandling(nf1) ## getter
## Customize to say "Hello from twice-modified nf1"
system('sed s/modified/twice-modified/g myNimbleFunctionWork.cpp > myNimbleFunctionWork2.cpp')
## (ii) Modify the #include line
system('sed -i.bak s/myNimbleFunctionWork/myNimbleFunctionWork2/g myNimbleFunctionWork2.cpp')
## (iii) copy the .h
system('cp myNimbleFunctionWork.h myNimbleFunctionWork2.h')
cnf1twiceModified <- compileNimble(nf1, dirName = '.')
cnf1twiceModified(rnorm(3))