116 votes

Erreur : L'utilisation de la pile C est trop proche de la limite

J'essaie d'exécuter un code récursif assez profond dans R et il continue à me donner cette erreur :

Erreur : L'utilisation de la pile C est trop proche de la limite

Ma sortie de CStack_info() es:

Cstack_info()
    size    current  direction eval_depth 
67108864       8120          1          2 

J'ai beaucoup de mémoire sur ma machine, j'essaie juste de comprendre comment je peux augmenter la pile CS pour R.

EDIT : Quelqu'un a demandé un exemple reproductible. Voici un exemple de code basique qui cause le problème. En exécutant f(1,1) plusieurs fois, vous obtiendrez l'erreur. Notez que j'ai déjà défini --max-ppsize = 500000 et options(expressions=500000), donc si vous ne les définissez pas, vous obtiendrez une erreur sur l'une de ces deux choses. Comme vous pouvez le voir, la récursion peut être assez profonde ici et je n'ai aucune idée de la façon dont on peut la faire fonctionner de manière cohérente. Merci.

f <- function(root=1,lambda=1) {
    x <- c(0,1);
    prob <- c(1/(lambda+1),lambda/(lambda+1));
        repeat {
      if(root == 0) {
        break;
      }
      else {
        child <- sample(x,2,replace=TRUE,prob);
        if(child[1] == 0 && child[2] == 0) {
          break;
        }
        if(child[1] == 1) {
          child[1] <- f(root=child[1],lambda);
        }
        if(child[2] == 1 && child[1] == 0) {
          child[2] <- f(root=child[2],lambda);
        }
      }
      if(child[1] == 0 && child[2] == 0) {
        break;
      }
      if(child[1] == 1 || child[2] == 1) {
        root <- sample(x,1,replace=TRUE,prob);
      }
        }
    return(root)
}

66voto

Zack Points 44583

La taille de la pile est un paramètre du système d'exploitation, réglable par processus (voir setrlimit(2) ). Vous ne pouvez pas l'ajuster depuis R pour autant que je sache, mais vous pouvez l'ajuster depuis le shell avant de lancer R, avec la commande ulimit commande. Cela fonctionne comme suit :

$ ulimit -s # print default
8192
$ R --slave -e 'Cstack_info()["size"]'
   size 
8388608

8388608 = 1024 * 8192 ; R imprime la même valeur que ulimit -s mais en octets au lieu de kilo-octets.

$ ulimit -s 16384 # enlarge stack limit to 16 megs
$ R --slave -e 'Cstack_info()["size"]'
    size 
16777216 

Pour effectuer un ajustement permanent de ce paramètre, ajoutez l'option ulimit au fichier de démarrage de votre shell, afin qu'elle soit exécutée à chaque fois que vous vous connectez. Je ne peux pas donner d'indications plus précises que cela, car cela dépend du shell que vous avez et d'autres choses. Je ne sais pas non plus comment le faire pour se connecter à un environnement graphique (ce qui sera pertinent si vous n'exécutez pas R dans une fenêtre de terminal).

30voto

Martin Morgan Points 19965

Je soupçonne que, quelle que soit la limite de la pile, vous finirez par avoir des récursions trop profondes. Par exemple, avec lambda = Inf, f(1) conduit à une récursion immédiate, indéfiniment. La profondeur de la récursion semble être une marche aléatoire, avec une certaine probabilité r d'aller plus loin, 1 - r de finir la récursion actuelle. Au moment où vous atteignez la limite de la pile, vous avez fait un grand nombre d'étapes "plus profondes". Cela implique que r > 1 / 2, et la très grande majorité du temps, vous continuerez simplement à récursionner.

De plus, il semble qu'il soit presque possible de dériver une solution analytique ou au moins numérique même face à une récursion infinie. On peut définir p comme la probabilité que f(1) == 1, écrire des expressions implicites pour les états "enfants" après une seule itération, les mettre en équation avec p, et résoudre. p peut alors être utilisé comme la chance de succès d'un seul tirage d'une distribution binomiale.

29voto

Tom Kelly Points 427

Cette erreur n'est pas due à mémoire il est dû à récursion . Une fonction s'appelle elle-même. Ce n'est pas toujours évident en examinant la définition d'une seule fonction. Pour illustrer le propos, voici un exemple minimal de 2 fonctions qui s'appellent l'une l'autre :

change_to_factor <- function(x){
  x <- change_to_character(x)
  as.factor(x)
} 

change_to_character <- function(x){
  x <- change_to_factor(x)
  as.character(x)
}

change_to_character("1")

Erreur : L'utilisation de la pile C 7971600 est trop proche de la limite

Les fonctions continueront à s'appeler les unes les autres de manière récursive et ne seront théoriquement jamais complètes, même si vous augmentez la limite, elle sera toujours dépassée. Seules des vérifications au sein de votre système empêchent ce phénomène de se produire indéfiniment et de consommer toutes les ressources de calcul de votre machine. Vous devez modifier les fonctions pour vous assurer qu'elles ne s'appelleront pas indéfiniment (ou ne s'appelleront pas entre elles) de manière récursive.

13voto

Alex Joseph Points 1631

Cela m'est arrivé pour une raison complètement différente. J'ai accidentellement créé une chaîne superlongue en combinant deux colonnes :

output_table_subset = mutate(big_data_frame,
     combined_table = paste0(first_part, second_part, col = "_"))

au lieu de

output_table_subset = mutate(big_data_frame,
     combined_table = paste0(first_part, second_part, sep = "_"))

J'ai mis du temps à comprendre, car je ne pensais pas que la pâte avait causé le problème.

5voto

DAW Points 111

J'ai rencontré le même problème en recevant l'erreur "C stack usage is too close to the limit" (bien que pour une autre application que celle mentionnée par l'utilisateur2045093 ci-dessus). J'ai essayé la proposition de zwol mais cela n'a pas fonctionné.

À ma grande surprise, j'ai pu résoudre le problème en installant la dernière version de R pour OS X (actuellement : version 3.2.3) ainsi que la dernière version de R Studio pour OS X (actuellement : 0.99.840), puisque je travaille avec R Studio.

J'espère que cela pourra vous être utile à vous aussi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X