Rcpp Modules, suite et mise à jour de la version FinistR2018

Cette présentation de Rcpp Modules est une mise à jour et correctif de la version FinistR2018

Marie-Pierre Etienne https://marieetienne.github.io/ (Agrocampus Ouest)http://agrocampus-ouest.fr , Pierre Gloaguen https://papayoun.github.io/ (AgroParisTech)http://agroparistech.fr , Gabriel Lang (AgroParisTech)http://agroparistech.fr
2019-10-15

Introduction

Pour des raisons de performance, on est fréquemment amené à écrire une partie de son code dans un langage compilé, notamment C++. Pour faire communiquer R et C++, il faut écrire une interface pour passer les objets R à C++ et à l’inverse passer les résultats de C++ à R. Le package Rcpp a été développé pour faciliter l’interfaçage entre les deux langages.

Par ailleurs, la programmation objet permet une structuration forte du code et assure un développement modulaire. Il est intéressant de partager au moins partiellement la structure d’objets entre les deux langages. RcppModules permet d’exposer des classes C++ et les rendre visibles et accessibles depuis R.

L’installation de Rcpp et son utilisation sont décrites dans le document de 2018. On se concentre ici sur la partie RcppModules intégrée au sein d’un package.

Création d’un package contenant des sources C++ au sein d’un package

usethis permet de créer facilement les éléments essentiels du package. Pour ce faire, il suffit d’exécuter la suite de commandes suivantes (dans l’ordre indiqué)

On peut ouvrir le fichier DESCRIPTION et éxécuter ensuite la commande pour constater les modifications qu’il subit.

Le fichier DESCRIPTION est modifié pour ajouter le lien avec roxygen2. Pour indiquer que l’on souhaite utiliser des codes C++, il faut ensuite exécuter la commande suivante:

Le fichier DESCRIPTION a été modifié pour indiquer la dépendance à Rcpp.

Et comme indiqué dans les sorties R de la commande use_rcpp(), il est indispensable de créer un fichier myPackage-package.R (le nom importe peu, mais on adoptera la convention nomPackage-package.R) dans le sous répertoire R du package.

Dans ce fichier myPackage-package.R, il faut copier ce qui est conseillé dans la sortie de la commande précédente, i.e :

Pour illustrer le fonctionnement du package, on veut créer une classe Random_walk. Commençons par une fontion qui simule la position à linstant t, partant de x0.

Création d’une fonction C++

Dans RStudio, on peut demander à créer un nouveau fichier C++ contenant

et enregistrer ce fichier dans src\random_walk.cpp.

On peut ensuite compiler ce package, en cliquant INSTALL and Restart ou avec le raccourci CTL + SHIFT + b.

A l’issue de la compilation plusieurs fichiers sont créés, notamment src\RcppExports.cpp et R\RcppExports.R qui permettent de faire le lien entre R et C++.

Il faut mettre à jour les fichiers de config (NAMESPACE, RcppExports.R, RcppExports.cpp) avec la commande devtools:document(), puis copiler et reinstaller le package avec CTL + SHIFT + b .

La fonction compute_next_pos existe maintenant dans R, elle appelle la fonction du même nom codée en C et passe les arguments.

La marche aléatoire dépend d’un parametre, on veut créer une classe avec un membre (la variance) et des méthodes pour simuler et accéder au membre.

Création d’une classe en C++

Il faut effacer le fichier NAMESPACE et modifier le fichier Random_walk.cpp de la manière suivante :

Enfin, on génère à nouveau le NAMESPACE avec devtools::document() et on recompile, réinstalle.

La classe n’est pas exportée et n’est pas visible depuis R. Il faut écrire des fonctions supplémentaires pour interfacer. La logique à ce stade est d’écrire une fonction c++ qui va faire le travail et notamment créer une instance de la classe Random_walk et d’exporter cette fonction en R pour la rendre accessible à l’utilisateur. Dans ce cas la classe C++ n’a de pas du tout de vocation à être modifié par un code R.

Si on souhaite pouvoir depuis R choisir et/ou modifier la variance de notre objet marche aléatoire il faut exposer la classe dans R. C’est l’objectif de RcppModule.

RcppModules

Pour utiliser RcppModules, il faut ajouter

On va ensuite écrire une fonction R qui a pour rôle de créer l’objet de classe Random_walk dans R et de le rendre accessible dans R. On crée ainsi le fichier create_class.R dans le répertoire R

Le fichier NAMESPACE doit être modifié pour exporter correctement le module. Pour que roxygen s’en charge il faut documenter l’export de la class et ajouter au début du fichier random_walk.cpp.

Dans le fichier DESCRIPTION il faut indiquer que l’on utilise RcppModules et ajouter la ligne RcppModules: rw_Module pour obtenir le fichier suivant.

Il faut ensuite générer à nouveau le NAMESPACE avec devtools::document() et enuiste compiler le package avec CTL + SHIFT + b.

Enfin on peut maintenant créer un objet de type Random_walk dans R


C++ object <0x55fac1f6b330> of class 'Random_walk' <0x55fac3c24040>

C’est une réferérence sur un objet C++.

On a exposé les accesseurs et on peut donc demander la valeur de l’écart type


[1] 3

On peut aussi modifier cette valeur


[1] 2

Enfin on peut utiliser les méthodes de la classe qui ont été exposées

En cas de problème, et si des erreurs se produisent et avant de perdre son calme, il faut nettoyer manuellement le répertoire de développement du package. C’est à dire, il faut supprimer les fichiers

Pour plus de détails sur la syntaxe de RcppModules, on peut consulter (“RcppModules Vignette,” n.d.).