futuro 1.20.1 – O futuro ficou um pouco mais brilhante

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br


[This article was first published on JottR on R, and kindly contributed to R-bloggers]. (Você pode relatar problemas sobre o conteúdo desta página aqui)


Quer compartilhar seu conteúdo em R-bloggers? clique aqui se você tiver um blog, ou aqui se não tiver.



futuro 1.20.1 está no CRAN. Ele adiciona alguns recursos novos, desativa comportamentos antigos e indesejados, adiciona algumas vinhetas e corrige alguns bugs.

O primeiro entre os novos recursos, e uma solicitação de recurso de longa duração, é a adição do argumento split para plan(), que nos permite dividir, ou “tee”, qualquer saída produzida por futuros.

O padrão é split = FALSE para a qual a saída e as condições padrão são capturadas pelo futuro e apenas retransmitidas após o futuro ter sido resolvido, ou seja, a saída capturada é exibida e re-sinalizada na sessão R principal quando o valor do futuro é consultado. Isso emula o que experimentamos em R quando não usamos futuros, por exemplo, podemos adicionar print() e message() declarações ao nosso código para solução rápida de problemas. Você pode ler mais sobre isso na postagem do blog ‘future 1.9.0 – Output from The Future’.

No entanto, se quisermos usar debug() ou browser() para depuração interativa, percebemos rapidamente que eles não são muito úteis porque nenhuma saída é visível, o que ocorre porque sua saída também é capturada pelo futuro. É aqui que o novo recurso de “divisão” vem para resgatar. Usando split = TRUE, a saída padrão e todas as condições de não erro são divididas (“tee: d”) na extremidade do trabalhador, enquanto ainda são capturadas pelo futuro para serem retransmitidas de volta para a sessão R principal em um momento posterior. Isso significa que podemos depurar o futuro ‘sequencial’ interativamente. Aqui está uma ilustração de como usar browser() para depurar um futuro:

> library(future)
> plan(sequential, split = TRUE)
> mysqrt  f  str(x)
 int [1:3] 1 2 3
Browse[1]> 
debug at #1: y  
debug at #1: y
Browse[2]> str(y)
 num [1:3] 1 1.41 1.73
Browse[2]> y[1]  cont

> v  v
[1] 0.000000 1.414214 1.732051

Comente: Observe como a saída produzida durante a depuração é retransmitida também quando value() é chamado. Este é um efeito colateral um tanto infeliz da captura de futuros todos saída produzida enquanto eles estão ativos.

O suporte adicionado para split = TRUE também significa que agora podemos preservar todas as saídas em quaisquer arquivos de log que possam ser produzidos em workers paralelos. Por exemplo, se você usar future.batchtools em um programador Slurm, você pode usar plan(future.batchtools::batchtools_slurm, split = TRUE) para se certificar de que a saída padrão, mensagens, avisos, etc. estão terminando no batchtools arquivos de log enquanto ainda estão sendo retransmitidos para a sessão R principal no final. Desta forma, podemos inspecionar trabalhos de cluster enquanto eles ainda são executados, entre outras coisas. Aqui está um exemplo de prova de conceito usando um futuro ‘batchtools_local’:

> library(future.batchtools)
> plan(batchtools_local, split = TRUE)
> f  v  v
[1] 6.480741
> loggedOutput(f)
 [1] "### [bt]: This is batchtools v0.9.14"                                 
 [2] "### [bt]: Starting calculation of 1 jobs"                             
 [3] "### [bt]: Setting working directory to '/home/alice/repositories/future'"
 [4] "### [bt]: Memory measurement disabled"                                
 [5] "### [bt]: Starting job [batchtools job.id=1]"                         
 [6] "### [bt]: Setting seed to 15794 ..."                                  
 [7] "Hello world"                                                          
 [8] "[1] 42"                                                               
 [9] ""                                                                     
[10] "### [bt]: Job terminated successfully [batchtools job.id=1]"          
[11] "### [bt]: Calculation finished!"  

Sem split = TRUE, não obteríamos as linhas 7 e 8 no batchtools Histórico.

Leia Também  Oficina gratuita sobre aprendizado profundo com Keras e TensorFlow

Em segundo lugar entre os novos recursos estão os futuros ‘multicore’, que agora se juntam aos futuros ‘sequencial’, ‘multissessão’ e (local e remoto) ‘cluster’ na capacidade de retransmitir atualizações de progresso de progressr de uma forma quase ativa. Isso significa que todos os nossos back-ends de paralelização mais comuns oferecem suporte a atualizações de progresso quase em tempo real. Se esta é a primeira vez que você ouve de progressr, aqui está um exemplo de como ele pode ser usado em processamento paralelo:

library(future.apply)
plan(multicore)

library(progressr)
handlers("progress")

xs ------------------------------]  40% x=2

Observe que as atualizações de progresso sinalizadas por p(), atualiza a barra de progresso quase instantaneamente, mesmo se os workers paralelos forem executados em uma máquina remota.

cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br

Em terceiro lugar estão os futuros de ‘multissessão’. Agora ele herda automaticamente o caminho da biblioteca de pacotes da sessão R principal. Por exemplo, se você usar .libPaths() para ajustar o caminho da sua biblioteca e então ligar plan(multisession), os trabalhadores multissessão verão os mesmos pacotes da sessão pai. Esta mudança é baseada em uma solicitação de recurso relacionada ao RStudio Connect. Com esta atualização, não importa mais qual tipo de futuro local você usa – ‘sequencial’, ‘multissessão’ ou ‘multicore’ – seu código futuro terá acesso ao mesmo conjunto de pacotes instalados.

Como uma prova de conceito, suponha que adicionamos tempdir() como uma nova pasta para o caminho da biblioteca de R;

> .libPaths(c(tempdir(), .libPaths()))
> .libPaths()
[1] "/tmp/alice/RtmpwLKdrG"
[2] "/home/alice/R/x86_64-pc-linux-gnu-library/4.0-custom"   
[3] "/home/alice/software/R-devel/tags/R-4-0-3/lib/R/library"

Se lançarmos um futuro de ‘multissessão’, descobriremos que ele usa o mesmo caminho de biblioteca;

> library(future)
> plan(multisession)
> f  value(f)
[1] "/tmp/alice/RtmpwLKdrG"
[2] "/home/alice/R/x86_64-pc-linux-gnu-library/4.0-custom"   
[3] "/home/alice/software/R-devel/tags/R-4-0-3/lib/R/library"

Eu adicionei uma vinheta ‘Best Practices for Package Developers’, que espero que forneça algumas orientações úteis sobre como escrever e validar código futuro para que funcione em tantos back-ends paralelos quanto possível.

Leia Também  tidycovid19: novos dados e documentação

Ok, vamos discutir o que está sendo removido. Usando plan(multiprocess), que era apenas um apelido para “plan(multicore) no Linux e macOS e plan(multisession) no MS Windows ”, está obsoleto. Se usado, você receberá um aviso único:

> plan(multiprocess)
Warning message:
Strategy 'multiprocess' is deprecated in future (>= 1.20.0). Instead, explicitly
specify either 'multisession' or 'multicore'. In the current R session,
'multiprocess' equals 'multicore'.

Eu recomendo que você use plan(multisession) como um substituto para plan(multiprocess). Se você estiver no Linux ou macOS e tiver 100% de certeza de que seu código e todas as suas dependências são seguras para fork, você também pode usar plan(multicore).

Embora ‘multiprocesso’ fosse bom para usar na documentação e nos exemplos, era ao mesmo tempo ambíguo e arriscava a introdução de um comportamento dependente da plataforma para esses exemplos. Por exemplo, pode ser que o código paralelo funcione apenas para usuários no Linux e macOS porque alguns globais não exportáveis ​​foram usados. Se um usuário ou MS Windows tentou o mesmo código, eles podem ter obtido erros de tempo de execução. Vice-versa, também pode ser que o código funcione no MS Windows, mas não no Linux ou macOS. Além disso, em futuro 1.13.0 (08/05/2019), o suporte para futuros ‘multicore’ foi desabilitado ao executar R via RStudio. Isso foi feito porque o processamento paralelo bifurcado foi considerado instável no RStudio. Isso significava que um usuário do macOS que usava plan(multiprocess) acabaria obtendo futuros ‘multicore’ ao executar no terminal, enquanto obteria futuros ‘multissessão’ ao executar no RStudio. Esses tipos de experiências do usuário específicas da plataforma e do ambiente eram confusas e complicavam a solução de problemas e as comunicações, razão pela qual foi decidido abandonar o ‘multiprocesso’ em favor da especificação explícita de ‘multissessão’ ou ‘multicore’.

Em um esforço para refinar a API do Futuro, o uso de future(..., local = FALSE) agora está obsoleto. O único lugar onde ainda é suportado, por motivos de compatibilidade retroativa, é ao usar futuros de ‘cluster’ que são persistentes, ou seja, plan(cluster, ..., persistent = TRUE). Se você usar o último, recomendo que comece a pensar em deixar de usar local = FALSE também nesses casos. Apesar persistent = TRUE raramente é usado, estou ciente de que alguns de vocês têm casos de uso que exigem que os objetos permaneçam nos trabalhadores paralelos também após um futuro ter sido resolvido. Se você tiver essas necessidades, consulte o futuro número 433, especialmente as partes sobre “sticky globals”. Sinta-se à vontade para adicionar seus comentários e sugestões sobre a melhor forma de avançarmos nisso. Os objetivos de longo prazo são livrar-se de ambos local e persistent a fim de harmonizar a API do Futuro em todos back-ends futuros.

Leia Também  Charada: Você consegue resolver o mistério do xadrez?

Para correções de bug recentes, consulte o pacote NEWS.

Ainda há muitas coisas no roteiro. Sem nenhuma ordem específica, aqui estão algumas coisas em andamento:

  • Globais fixos para armazenar em cache globais em workers. Isso diminuirá o número de globais que precisam ser exportados ao lançar futuros. Ele aborda várias solicitações de recursos relacionados, por exemplo, problemas futuros # 273, # 339, # 346, # 431 e # 437.

  • Capacidade de encerrar futuros (para back-ends que o suportem), o que abre a possibilidade de reiniciar futuros com falha e muito mais. Este é um recurso solicitado com frequência, por exemplo, nas edições # 93, # 188, # 205, # 213 e # 236.

  • Função de gancho genérica opcional de custo zero. Tê-los no lugar abre para adicionar uma estrutura para fazer perfis / benchmarking de tempo e memória futuros e seus back-ends. Ser capaz de criar perfis de futuros e seus back-ends ajudará a identificar gargalos e melhorar o desempenho em alguns de nossos back-ends paralelos, por exemplo, os problemas nº 59, nº 142, nº 239 e nº 437.

  • Adicionar suporte para gerenciadores de chamadas globais em progressr. Isso não é específico para a estrutura futura, mas como está intimamente relacionado, imaginei que mencionaria isso aqui também. Um manipulador de chamada global para atualizações de progresso eliminaria a necessidade de usar with_progress() ao monitorar o progresso. Isso também ajudaria a resolver o problema comum em que os desenvolvedores de pacotes desejam fornecer atualizações de progresso sem ter que pedir ao usuário para usar with_progress(), por exemplo progressr Questões nº 78, nº 83 e nº 85.

É tudo por enquanto – feliz futuro!

Veja também



cupom com desconto - o melhor site de cupom de desconto cupomcomdesconto.com.br