将来のパッケージの目的は、ユーザーが利用できるさまざまなリソースを使用して、R式を非同期的に評価する非常にシンプルで均一な方法を提供することです。
プログラミングでは、未来は、将来のある時点で利用できる値の抽象化です。未来の状態は、未解決または解決される可能性があります。解決するとすぐに、値は瞬時に利用可能になります。将来がまだ解決されていない間に値が照会された場合、現在のプロセスは将来が解決されるまでブロックされます。ブロックせずに未来が解決されているかどうかを確認することができます。未来がどのようにどのように解決されるかは、それらを評価するために使用される戦略によって正確にどのように、いつ解決されるかによって異なります。たとえば、シーケンシャル戦略を使用して未来を解決できます。つまり、現在のRセッションで解決されます。他の戦略は、たとえば、現在のマシンで並行して式を評価するか、計算クラスターで同時に式を評価することにより、未来を非同期に解決することです。
以下は、先物の基本がどのように機能するかを示す例です。まず、プレーンRコードを使用する次のコードスニペットを考えてみましょう。
> v <- {
+ cat( " Hello world! n " )
+ 3.14
+ }
Hello world !
> v
[ 1 ] 3.14
式の値を変数v
に割り当てることで機能し、 v
の値を印刷します。さらに、 v
の式が評価されると、メッセージも印刷します。
代わりに先物を使用するように変更された同じコードスニペットが次のとおりです。
> library( future )
> v % <- % {
+ cat( " Hello world! n " )
+ 3.14
+ }
> v
Hello world !
[ 1 ] 3.14
違いは、 v
構築方法にあります。プレーンrでは<-
先物では%<-%
使用します。もう1つの違いは、将来が解決された後に出力が中継され、値が照会されたときに中継されることです(ビネット「テキストの出力」を参照)。
では、なぜ先物が有用なのですか?設定を次のように切り替えるだけで、別のRプロセスで非同期に将来の式を評価することを選択できるため
> library( future )
> plan( multisession )
> v % <- % {
+ cat( " Hello world! n " )
+ 3.14
+ }
> v
Hello world !
[ 1 ] 3.14
非同期先物では、現在/メインのRプロセスはブロックされません。つまり、バックグラウンドで実行されている個別のプロセスで先物が解決されている間、さらに処理できます。言い換えれば、先物は、Rの並列処理および /または分散処理のためのシンプルだが強力な構成要素を提供します。
さて、先物に関するすべての核心の詳細を読むことができないが、それらを試してみたいだけなら、並列評価と非平行評価の両方を使用してマンデルブロットデモで遊ぶためにスキップしてください。
先物は、暗黙的または明示的に作成できます。上記の紹介例ではv %<-% { expr }
constructを介して作成された暗黙の先物を使用しました。別の方法は、 f <- future({ expr })
およびv <- value(f)
コンストラクトを使用した明示的な先物です。これらを使用すると、私たちの例は代わりに次のように書くことができます。
> library( future )
> f <- future({
+ cat( " Hello world! n " )
+ 3.14
+ })
> v <- value( f )
Hello world !
> v
[ 1 ] 3.14
いずれかの将来の構造のスタイルが等しく機能します(*)まあ。暗黙的なスタイルは、通常のRコードの書き込み方法に最も似ています。原則として、あなたがしなければならないのは、割り当てを将来の割り当てに変えるために<-
%<-%
に置き換えることです。一方、このシンプルさは、特に非同期の未来が使用されている場合にも欺く可能性があります。対照的に、明示的なスタイルにより、先物が使用されていることがはるかに明確になり、ミスのリスクが低下し、デザインをコードを読んでいる人とよりよく伝えます。
(*)(小さな)変更なしで%<-%
使用できない場合があります。このドキュメントの終わり近くに、暗黙の先物を使用する場合、セクション「制約」のセクションでこれに戻ります。
要約すると、明示的な先物については、次のことを使用します。
f <- future({ expr })
- 未来を作成しますv <- value(f)
- 将来の値を取得します(まだ解決していない場合はブロック)暗黙の未来には、以下を使用します。
v %<-% { expr }
- その価値に対する未来と約束を作成しますシンプルに保つために、このドキュメントの残りの部分で暗黙的なスタイルを使用しますが、議論されているすべては明示的な先物にも適用されます。
将来のパッケージは、次の種類の先物を実装しています。
名前 | OS | 説明 |
---|---|---|
同期: | 非平行: | |
sequential | 全て | 順番に、現在のRプロセスで |
非同期: | 平行: | |
multisession | 全て | 背景rセッション(現在のマシン上) |
multicore | Windowsではなく/rstudioではありません | フォーク付きRプロセス(現在のマシン上) |
cluster | 全て | 現在、ローカル、および/またはリモートマシンに関する外部Ressions |
将来のパッケージは、追加の戦略のサポートも実装できるように設計されています。たとえば、Future.Callrパッケージは、CallRパッケージを使用してバックグラウンドRプロセスの先物を評価する将来のバックエンドを提供します - それらはmultisession
先物と同様に機能しますが、いくつかの利点があります。継続的に、The Future.BatchToolsパッケージは、BatchToolsパッケージがサポートするあらゆるタイプのクラスター関数(「バックエンド」)に先物を提供します。具体的には、Slurm、Torque/PBS、Oracle/Sunグリッドエンジン(SGE)、ロード共有施設(LSF)などのジョブスケジューラを介してR式を評価するための先物も利用できます。
デフォルトでは、将来の式が熱心に(=瞬時に)評価され、同期して(現在のRセッションで)評価されます。この評価戦略は「シーケンシャル」と呼ばれます。このセクションでは、これらの戦略のそれぞれを調べて、それらが共通しているものとそれらがどのように異なるかを議論します。
それぞれの異なる将来の戦略を通過する前に、将来のAPIの目的を明確にすることがおそらく役立つでしょう(将来のパッケージで定義されています)。先物と一緒にプログラミングする場合、コードを実行するために将来の戦略が使用されることは実際には問題ではありません。これは、ユーザーがどのような計算リソースにアクセスできるかを実際に知ることができないため、評価戦略の選択は、開発者ではなくユーザーの手にあるはずです。言い換えれば、コードは、同期または非同期など、使用される先物の種類について仮定を立てるべきではありません。
将来のAPIのデザインの1つは、すべてのタイプの先物が同じように機能するようになるように、違いをカプセル化することでした。これは、表現が現在のRセッションまたはリモートRセッションで世界中でローカルに評価される場合があります。さまざまなタイプの未来の間で一貫したAPIと動作を持つことのもう1つの明らかな利点は、プロトタイピング中に役立つことです。通常、スクリプトの構築中に順次評価を使用し、後でスクリプトが完全に開発されると、非同期処理をオンにすることができます。
このため、さまざまな戦略のデフォルトは、将来の表現を評価する結果と副作用が可能な限り似ているようなものです。より具体的には、以下はすべての未来に当てはまります。
すべての評価は、ローカル環境(つまり、 local({ expr })
)で行われるため、割り当てが呼び出し環境に影響を与えません。これは、外部Rプロセスで評価するときは自然ですが、現在のRセッションで評価するときにも強制されます。
未来が構築されると、グローバル変数が識別されます。非同期評価のために、グローバルは将来の表現を評価するRプロセス/セッションにエクスポートされます。怠zyな評価( lazy = TRUE
)を備えた連続した先物の場合、グローバルは「凍結」されます(未来の地域環境にクローニングされます)。また、誤って大きなオブジェクトをエクスポートすることから保護するために、すべてのグローバルの総サイズが与えられたしきい値よりも少ないという組み込みの主張があります( help("future.options")
)。しきい値を超えると、有益なエラーがスローされます。
将来の表現は一度だけ評価されます。値(またはエラー)が収集されるとすぐに、後続のすべてのリクエストで利用可能になります。
以下は、すべての課題がローカル環境に対して行われていることを示す例です。
> plan( sequential )
> a <- 1
> x % <- % {
+ a <- 2
+ 2 * a
+ }
> x
[ 1 ] 4
> a
[ 1 ] 1
今、私たちはさまざまな将来の戦略を探求する準備ができています。
同期先物は次々と解決され、最も一般的にはそれらを作成するRプロセスによって解決されます。同期の未来が解決されている場合、それは解決されるまで主要なプロセスをブロックします。
特に指定されていない限り、シーケンシャル先物はデフォルトです。それらは、将来のAPIとその動作を満たしながら、定期的なR評価にできるだけ同様に振る舞うように設計されています。以下は、それらの特性を示す例です。
> plan( sequential )
> pid <- Sys.getpid()
> pid
[ 1 ] 1437557
> a % <- % {
+ pid <- Sys.getpid()
+ cat( " Future 'a' ... n " )
+ 3.14
+ }
> b % <- % {
+ rm( pid )
+ cat( " Future 'b' ... n " )
+ Sys.getpid()
+ }
> c % <- % {
+ cat( " Future 'c' ... n " )
+ 2 * a
+ }
Future ' a ' ...
> b
Future ' b ' ...
[ 1 ] 1437557
> c
Future ' c ' ...
[ 1 ] 6.28
> a
[ 1 ] 3.14
> pid
[ 1 ] 1437557
熱心な連続評価が行われているため、3つの先物のそれぞれが作成された瞬間に瞬時に解決されます。また、現在のプロセスのプロセスIDを割り当てられた呼び出し環境でのpid
上書きも削除もどのように割り当てられているかに注意してください。これは、先物がローカル環境で評価されているためです。同期(uni-)処理が使用されるため、将来のb
メインRプロセス(まだローカル環境内)によって解決されます。そのため、 b
とpid
の値は同じです。
次に、バックグラウンドで解決された未来である非同期先物に目を向けます。設計上、これらの先物は非ブロッキングです。つまり、作成された後、追加の先物の作成を含む他のタスクで呼び出しプロセスが利用できます。呼び出しプロセスが、まだ解決されていない未来の価値にアクセスしようとするとき、または利用可能なすべてのRプロセスが他の未来に奉仕するのに忙しい場合、別の非同期未来を作成しようとするときのみです。
マルチセッション先物は、すべてのオペレーティングシステムでサポートされているためです。マルチセッションの将来は、呼び出しRプロセスと同じマシンで実行されているバックグラウンドRセッションで評価されます。マルチセッション評価の例は次のとおりです。
> plan( multisession )
> pid <- Sys.getpid()
> pid
[ 1 ] 1437557
> a % <- % {
+ pid <- Sys.getpid()
+ cat( " Future 'a' ... n " )
+ 3.14
+ }
> b % <- % {
+ rm( pid )
+ cat( " Future 'b' ... n " )
+ Sys.getpid()
+ }
> c % <- % {
+ cat( " Future 'c' ... n " )
+ 2 * a
+ }
Future ' a ' ...
> b
Future ' b ' ...
[ 1 ] 1437616
> c
Future ' c ' ...
[ 1 ] 6.28
> a
[ 1 ] 3.14
> pid
[ 1 ] 1437557
私たちが最初に観察することは、 a
、 c
およびpid
の値が以前と同じであるということです。ただし、 b
以前とは異なることがわかります。これは、将来のb
異なるRプロセスで評価されるため、異なるプロセスIDを返すためです。
マルチセッション評価を使用すると、パッケージは、作成された表現を評価することにより、マルチセッション先物に役立つバックグラウンドで一連のRセッションを開始します。すべてのバックグラウンドセッションが他の未来に奉仕するのに忙しい場合、次の多重係員の未来の作成は、バックグラウンドセッションが再び利用可能になるまでブロックされます。起動したバックグラウンドプロセスの総数は、 availableCores()
の値によって決定されます。
> availableCores()
mc.cores
2
この特定の結果は、 mc.cores
オプションが設定されており、メインプロセスを含む合計2つのプロセスで使用できるようになったことを示しています。言い換えれば、これらの設定では、マルチセッション先物にサービスを提供する2つの背景プロセスがあります。 availableCores()
、さまざまなオプションやシステム環境変数にもアジャイルです。たとえば、Compute Clusterスケジューラを使用する場合(トルク/PBSやスラームなど)、特定のジョブに割り当てられたコアの数を指定する特定の環境変数を設定します。 availableCores()
もこれらを認めています。他に何も指定されていない場合、マシン上の利用可能なすべてのコアが利用されます、cf。 parallel::detectCores()
。詳細については、 help("availableCores", package = "parallelly")
を参照してください。
RがWindowsを除くすべてのオペレーティングシステムであるプロセスの分岐をサポートするオペレーティングシステムでは、バックグラウンドでRSセッションを生み出す代わりに、既存のRプロセスを分岐することです。マルチコア先物を使用するには、サポートされている場合、指定します。
plan( multicore )
マルチセッション先物の場合と同様に、実行中の並列プロセスの最大数は、両方の場合にローカルマシンで行われるため、 availableCores()
によって決定されます。
Rプロセスの分岐は、バックグラウンドで実行されている別のRセッションで作業するよりも速い場合があります。理由の1つは、大きなグローバルをバックグラウンドセッションにエクスポートするオーバーヘッドが、フォーキング、したがって共有メモリが使用される場合よりも大きくなる可能性があることです。一方、共有メモリは読み取られます。つまり、フォークプロセスの1つ(「ワーカー」)による共有オブジェクトの変更は、オペレーティングシステムごとにコピーを引き起こします。これは、Rガベージコレクターがフォークされたプロセスの1つで実行される場合にも発生する可能性があります。
一方、プロセスフォーキングは、一部のR環境でも不安定であると見なされます。たとえば、RSTUDIOプロセス内からRを実行すると、転倒が発生する可能性があり、Ressionsがクラッシュします。このため、将来のパッケージは、RSTUDIOから実行するときにデフォルトでマルチコア先物を無効にします。詳細については、 help("supportsMulticore")
を参照してください。
クラスター先物は、アドホッククラスターで式を評価します(並列パッケージで実装されています)。たとえば、3つのノードn1
、 n2
、 n3
にアクセスできると仮定して、これらを非同期評価に使用できます。
> plan( cluster , workers = c( " n1 " , " n2 " , " n3 " ))
> pid <- Sys.getpid()
> pid
[ 1 ] 1437557
> a % <- % {
+ pid <- Sys.getpid()
+ cat( " Future 'a' ... n " )
+ 3.14
+ }
> b % <- % {
+ rm( pid )
+ cat( " Future 'b' ... n " )
+ Sys.getpid()
+ }
> c % <- % {
+ cat( " Future 'c' ... n " )
+ 2 * a
+ }
Future ' a ' ...
> b
Future ' b ' ...
[ 1 ] 1437715
> c
Future ' c ' ...
[ 1 ] 6.28
> a
[ 1 ] 3.14
> pid
[ 1 ] 1437557
parallel::makeCluster()
作成されたあらゆる種類のクラスターは、クラスター先物に使用できます。たとえば、上記のクラスターは、次のように明示的に設定できます。
cl <- parallel :: makeCluster(c( " n1 " , " n2 " , " n3 " ))
plan( cluster , workers = cl )
また、Cluster cl
が不要になったとき、つまりparallel::stopCluster(cl)
呼び出すのは良いスタイルと考えられています。ただし、メインプロセスが終了すると、シャットダウンされます。このようなクラスターのセットアップと管理方法の詳細については、 help("makeCluster", package = "parallel")
を参照してください。クラスターは、メインRセッションが終了するとき、または将来の戦略が変更されたときに、 plan(sequential)
を呼び出すことによって、ホストがキャラクターベクトルである場合も、 hosts
がキャラクターベクトルであるplan(cluster, workers = hosts)
、ワーカー=ホスト)を使用して暗黙的に作成されました。
自動認証セットアップ(SSHキーペアなど)では、リモートマシンのクラスターを使用するために同じアプローチを使用することを妨げるものは何もないことに注意してください。
各ノードで複数のワーカーを実行したい場合は、ノード名をそのノードで実行する労働者の数と同じくらい数倍複製します。例えば、
> plan(cluster, workers = c(rep("n1", times = 3), "n2", rep("n3", times = 5)))
n1
で3人、 n2
に1人、 n3
に5人が合計9人の並列労働者で走ります。
これは、先物の「フラットトポロジー」と呼ばれるもの、つまりすべての先物が同じ環境に作成され、割り当てられるものについて議論しました。ただし、先物の「ネストされたトポロジー」を使用することを妨げるものは何もありません。ここでは、1つの未来のセットが、内部で別の先物セットを作成する可能性があります。
たとえば、マルチセッション評価を使用し、2番目の将来( b
)が2つの内部先物を使用する2つの「トップ」未来( a
とb
)の例を次に示します。
> plan( multisession )
> pid <- Sys.getpid()
> a % <- % {
+ cat( " Future 'a' ... n " )
+ Sys.getpid()
+ }
> b % <- % {
+ cat( " Future 'b' ... n " )
+ b1 % <- % {
+ cat( " Future 'b1' ... n " )
+ Sys.getpid()
+ }
+ b2 % <- % {
+ cat( " Future 'b2' ... n " )
+ Sys.getpid()
+ }
+ c( b.pid = Sys.getpid(), b1.pid = b1 , b2.pid = b2 )
+ }
> pid
[ 1 ] 1437557
> a
Future ' a ' ...
[ 1 ] 1437804
> b
Future ' b ' ...
Future ' b1 ' ...
Future ' b2 ' ...
b.pid b1.pid b2.pid
1437805 1437805 1437805
プロセスIDを検査することにより、先物を解決するための合計3つの異なるプロセスがあることがわかります。主なRプロセス(PID 1437557)があり、 a
(PID 1437804)とb
(PID 1437805)で使用される2つのプロセスがあります。ただし、 b
によってネストされる2つの先物( b1
とb2
)は、 b
と同じRプロセスによって評価されます。これは、ネストされた先物が特に指定されていない限り、連続評価を使用するためです。これにはいくつかの理由がありますが、主な理由は、たとえば、再帰的な呼び出しを介して、誤って多数のバックグラウンドプロセスを産むことから私たちを守ることです。
異なるタイプの評価トポロジを指定するために、マルチセッション評価によって解決される先物レベルと順次評価によって2番目のレベルを除き、 plan()
に評価戦略のリストを提供できます。まず、上記と同じ評価戦略を明示的に指定できます。
plan( list ( multisession , sequential ))
複数のレベルのマルチセッション評価を試してみると、実際に同じ動作が得られます。
> plan( list ( multisession , multisession ))
[ ... ]
> pid
[ 1 ] 1437557
> a
Future ' a ' ...
[ 1 ] 1437901
> b
Future ' b ' ...
Future ' b1 ' ...
Future ' b2 ' ...
b.pid b1.pid b2.pid
1437902 1437902 1437902
この理由は、ここでも、マシンがサポートできるものよりも多くのプロセスを開始することから私たちを保護するためです。内部的には、これはmc.cores = 1
を設定することによって行われparallel::mclapply()
のような関数が順番に実行されるようになります。これは、マルチセッションとマルチコア評価の両方の場合です。
継続して、順次評価から始めてから、ネストされた先物にマルチセッション評価を使用した場合、次のようになります。
> plan( list ( sequential , multisession ))
[ ... ]
> pid
[ 1 ] 1437557
> a
Future ' a ' ...
[ 1 ] 1437557
> b
Future ' b ' ...
Future ' b1 ' ...
Future ' b2 ' ...
b.pid b1.pid b2.pid
1437557 1438017 1438016
これは、 a
とb
呼び出しプロセス(PID 1437557)で解決され、2つのネストされた先物( b1
とb2
)が2つの別々のRプロセス(PID 1438017および1438016)で解決されることを明確に示しています。
これを言って、各レベルで利用可能なコアの数を明示的に指定する(強制的に)明示的に指定する場合、ネストされたマルチセッション評価戦略を使用することは確かに可能です。これを行うには、デフォルト設定を「調整」する必要があります。これは次のように行うことができます。
> plan( list (tweak( multisession , workers = 2 ), tweak( multisession ,
+ workers = 2 )))
[ ... ]
> pid
[ 1 ] 1437557
> a
Future ' a ' ...
[ 1 ] 1438105
> b
Future ' b ' ...
Future ' b1 ' ...
Future ' b2 ' ...
b.pid b1.pid b2.pid
1438106 1438211 1438212
まず、 a
とb
両方が、呼び出しプロセス(PID 1437557)よりも異なるプロセス(PIDS 1438105および1438106)で解決されていることがわかります。第二に、2つのネストされた先物( b1
とb2
)は、まだ2つのRプロセス(PIDS 1438211および1438212)で解決されます。
ネストされた先物と各レベルでのさまざまな評価戦略の操作の詳細については、vignette 'Futures in R:Future Topologies」を参照してください。
将来が解決されたかどうかを確認することが可能です。これは、 resolved(f)
関数を使用して実行できます。これにより、明示的な将来f
入力として使用できます。 (上記のすべての例のように)暗黙の先物と連携する場合、 f <- futureOf(a)
関数を使用して、暗黙の将来から明示的な未来を取得できます。例えば、
> plan( multisession )
> a % <- % {
+ cat( " Future 'a' ... " )
+ Sys.sleep( 2 )
+ cat( " done n " )
+ Sys.getpid()
+ }
> cat( " Waiting for 'a' to be resolved ... n " )
Waiting for ' a ' to be resolved ...
> f <- futureOf( a )
> count <- 1
> while ( ! resolved( f )) {
+ cat( count , " n " )
+ Sys.sleep( 0.2 )
+ count <- count + 1
+ }
1
2
3
4
5
6
7
8
9
10
> cat( " Waiting for 'a' to be resolved ... DONE n " )
Waiting for ' a ' to be resolved ... DONE
> a
Future ' a ' ... done
[ 1 ] 1438287
時々、未来はあなたが期待していたものではありません。将来の評価中にエラーが発生した場合、将来の値が要求されたときに、呼び出し環境のエラーとしてエラーが伝播され、スローされます。たとえば、エラーを生成する未来に怠zyな評価を使用すると、次のようなものが表示される場合があります
> plan( sequential )
> b <- " hello "
> a % <- % {
+ cat( " Future 'a' ... n " )
+ log( b )
+ } % lazy % TRUE
> cat( " Everything is still ok although we have created a future that will fail. n " )
Everything is still ok although we have created a future that will fail.
> a
Future ' a ' ...
Error in log( b ) : non - numeric argument to mathematical function
値が要求されるたびにエラーがスローされます。つまり、値を再度取得しようとすると、同じエラー(および出力)が生成されます。
> a
Future ' a ' ...
Error in log( b ) : non - numeric argument to mathematical function
In addition : Warning message :
restarting interrupted promise evaluation
エラーを与えたコールスタックの最後の呼び出しを表示するには、将来にbacktrace()
関数(*)を使用できます。
> backtrace( a )
[[ 1 ]]
log( a )
(*)一般的に使用されるtraceback()
先物のコンテキストで関連情報を提供しません。さらに、残念ながら、エラーにつながった呼び出しのリスト(評価された式)を見ることはできません。エラーを与えた呼び出しのみ(これは、内部で使用されるtryCatch()
の制限によるものです)。
R式が非同期に(並行して)評価されるか、怠zyな評価を介して連続的に評価される場合はいつでも、グローバル(「無料」)オブジェクトを識別して評価者に渡す必要があります。怠zyな評価のために、それ以外の場合、グローバルはそれが作成されたときと解決されたときに変化する可能性があるため、彼らは未来が作成された時点で正確に合格する必要があります。非同期処理の場合、グローバルを特定する必要がある理由は、将来を評価するプロセスにエクスポートできるようにするためです。
将来のパッケージは、これらのタスクを可能な限り自動化しようとします。これは、静的コード検査を使用してグローバル変数を識別するGlobalsパッケージのヘルプを使用して行います。グローバル変数が識別された場合、それはキャプチャされ、評価プロセスが利用可能になります。さらに、グローバルがパッケージで定義されている場合、そのグローバルはエクスポートされません。代わりに、将来が評価されたときに対応するパッケージが添付されていることを確認します。これは、メインRセッションのセットアップをよりよく反映するだけでなく、特にリモートコンピューティングノードを使用する場合、メモリだけでなく時間と帯域幅も節約するグローバルをエクスポートする必要性を最小限に抑えます。
最後に、静的コード検査だけでグローバルを特定することが困難な問題であることを明確にする必要があります。グローバルの自動識別が失敗するため、偽のグローバルが識別されるか(懸念されることが少ない)または真のグローバルの一部が欠落している(これが実行時エラーまたは誤った結果が発生する)コーナーケースが常にあります。 vignette「Rの先物:ソリューションの一般的な問題」は、一般的なケースの例を提供し、それらを回避する方法と、グローバルを特定したり、誤って特定されたグローバルを無視してパッケージを支援する方法を説明します。それで十分でない場合、名前でグローバル変数globals = list(a = 42, slow_sum = my_sum)
手動で指定することが常に可能です(例: globals = c("a", "slow_sum")
) globals = list(a = 42, slow_sum = my_sum)
)。
明示的な先物には存在しない暗黙の先物には1つの制限があります。明示的な未来は、Rの他のオブジェクトとまったく同じように、どこにでも割り当てることができます。たとえば、それらのいくつかをループに作成して、それらをリストに割り当てることができます。
> plan( multisession )
> f <- list ()
> for ( ii in 1 : 3 ) {
+ f [[ ii ]] <- future({
+ Sys.getpid()
+ })
+ }
> v <- lapply( f , FUN = value )
> str( v )
List of 3
$ : int 1438377
$ : int 1438378
$ : int 1438377
これは、暗黙の未来を使用する場合にはできません。これは、通常の<-
%<-%
-%割り当て演算子を使用できないためです。将来の値を環境(呼び出し環境を含む)に割り当てるassign(name, value, envir)
の動作と同じように使用するためにのみ使用できます。ただし、指定されたインデックスを使用して環境に暗黙の先物を割り当てることができます。
> plan( multisession )
> v <- new.env()
> for ( name in c( " a " , " b " , " c " )) {
+ v [[ name ]] % <- % {
+ Sys.getpid()
+ }
+ }
> v <- as.list( v )
> str( v )
List of 3
$ a : int 1438485
$ b : int 1438486
$ c : int 1438485
as.list(v)
は、環境Vのすべての先物v
が解決されるまでブロックします。その後、それらの値は収集され、通常のリストとして返されます。
数値インデックスが必要な場合は、リスト環境を使用できます。 ListenVパッケージによって実装されているリスト環境は、カスタマイズされたサブセットオペレーターを備えた通常の環境であり、リストをインデックス作成する方法と同じようにインデックスを作成することを可能にします。それ以外の場合はリストを使用するリスト環境を使用することにより、数値インデックスを使用してリストのようなオブジェクトに暗黙の先物を割り当てることもできます。例えば、
> library( listenv )
> plan( multisession )
> v <- listenv()
> for ( ii in 1 : 3 ) {
+ v [[ ii ]] % <- % {
+ Sys.getpid()
+ }
+ }
> v <- as.list( v )
> str( v )
List of 3
$ : int 1438582
$ : int 1438583
$ : int 1438582
以前のように、 as.list(v)
すべての先物が解決されるまでブロックします。
さまざまな種類の先物がどのように評価されるかをライブイラストを表示するには、このパッケージのマンデルブロットデモを実行します。まず、シーケンシャル評価を試してみてください。
library( future )
plan( sequential )
demo( " mandelbrot " , package = " future " , ask = FALSE )
先物が使用されていない場合、スクリプトがどのように実行されるかに似ています。次に、バックグラウンドで実行されている並列Rプロセスを使用して、異なるマンデルブロットプレーンを計算するマルチセッション評価を試してください。試す、
plan( multisession )
demo( " mandelbrot " , package = " future " , ask = FALSE )
最後に、複数のマシンにアクセスできる場合は、労働者のクラスターをセットアップして使用することができます。
plan( cluster , workers = c( " n2 " , " n5 " , " n6 " , " n6 " , " n9 " ))
demo( " mandelbrot " , package = " future " , ask = FALSE )
RパッケージのFutureはCRANで利用でき、次のようにrにインストールできます。
install.packages( " future " )
GitSubでGit Branch develop
で利用可能なプレリリースバージョンをインストールするには、以下を使用してください。
remotes :: install_github( " futureverse/future " , ref = " develop " )
これにより、ソースからパッケージがインストールされます。
このパッケージに貢献するには、converting.mdを参照してください。