Недавно я обнаружил чудеса TMB, и я работаю над пакетом, который в идеале включал бы в себя шаблоны TMB c ++ для довольно дорогих в вычислительном отношении моделей.
Я предполагаю, что есть возможность:
но я не могу найти четких указаний в документации TMB по этому поводу. На данный момент моя альтернатива — писать функции, которые компилируют код TMB при первом вызове функции, которая использует не скомпилированный класс … но у меня есть ощущение, что есть более хорошие способы сделать это.
Кто-нибудь успешно включил функции TMB в другой пакет и может указать мне направление соответствующей документации или примеров?
С немного большим поиском я наконец нашел свой ответ в этом нить. Я думаю, что я пропустил это, потому что детали его разрешения были перенесены на вики-страницу под названием развитие, где контент специально предназначен для пользователей, желающих внести свой вклад в развитие TMB, тогда как я просто хочу распространять код, который работает с TMB.
Подводя итог, ветка предлагает некоторые изменения, которые я принял, как это (мойпакет должно быть название вашей посылки):
.cpp
шаблон в mypkg/src
, Затем он будет автоматически скомпилирован R при сборке вашего пакета.Добавьте эти строки в файл описания, чтобы R имел все инструменты, необходимые для компиляции шаблона модели.
Depends: TMB, RcppEigen
LinkingTo: TMB, RcppEigen
Теперь нам нужно добавить наш шаблон TMB в файл пространства имен. Мы можем сделать это легко с помощью roxygen, сделав фиктивный файл следующим образом:
#' Roxygen commands
#'
#' @useDynLib myPkg
#'
dummy <- function(){
return(NULL)
}
Функция-пустышка — это просто повод иметь тег @useDynLib myPkg
где-то в моем исходном коде, где я не буду связываться с ним. Этот тег заполнит ваш NAMESPACE с useDynLib(myPkg)
… и как я понимаю, это загружает общие библиотеки при загрузке пакета для вас.
Наконец при звонке MakeADFun
, задавать DLL="myPkg"
, С помощью этой настройки вы можете скомпилировать не замужем Модель ТМБ в вашу упаковку. Это потому, что контент, скомпилированный в вашем ./src/
папка будет автоматически переименована в соответствии с именем вашего пакета, поэтому вы не можете создавать модели с уникальными именами.
После некоторого дополнительного поиска (тот же поток, на который ссылаются выше) … Я понял, что решение, описанное в официальной вики (и подробно описано выше), имеет отношение только к распространению одной DLL (то есть одной модели TMB).
Если вы хотите распространять несколько моделей TMB в пакете, вам придется использовать свой собственный make-файл. Я дал более подробное описание в моем блоге, поэтому я только кратко опишу здесь шаги относительно того, как они отличаются от предыдущих шагов, которые я описал.
Вы должны будете определить свой собственный Makefile
(или же Makefile.win
для пользователей Windows) и поместите его в свой src/
каталог. Вот пример, который работает для меня:
all: template1.so template2.so
# Comment here preserves the prior tab
template1.so: template1.cpp
Rscript --vanilla -e "TMB::compile('template1.cpp','-O0 -g')"template2.so: template2.cpp
Rscript --vanilla -e "TMB::compile('template2.cpp','-O0 -g')"
clean:
rm -rf *o
Для окон замените so
, с dll
и используйте соответствующие флаги компилятора (для отладки). Увидеть ?TMB::compile
для информации относительно флагов компилятора для отладки.
Это немного отличается от выше:
#' Roxygen commands
#'
#' This is a dummy function who's purpose is to hold the useDynLib roxygen tag.
#' This tag will populate the namespace with compiled c++ functions upon package install.
#'
#' @useDynLib template1
#' @useDynLib template2
#'
dummy <- function(){
return(NULL)
}
Наконец, вышеуказанные изменения скомпилируют несколько шаблонов TMB с уникальным именем и загрузят их в пространство имен. Чтобы назвать эти модели в вашей упаковке, вот пример:
obj <- MakeADFun(data = data,
parameters = params,
DLL="template1",
inner.control = list(maxit = 10000),
silent=F)
У меня были проблемы, когда я пытался скомпилировать это на компьютере с Windows … оказалось, что это связано с неправильной очисткой папки src, и у меня там застряли старые скомпилированные файлы linux. Если у вас есть проблемы с компиляцией, то стоит вручную очистить оставшиеся файлы в вашем src/
каталог из предыдущих сборок … или, может быть, кто-то может дать хороший совет по написанию лучшего файла make!
Других решений пока нет …