"@Pragma(Pragma.FINISH_SPMD) finish"を使うと、典型的なSPMD型のfinish処理を高速化できる。しかし、リモートで実行されるアクティビティが at を使うと at の中にasyncがなくても assertion error になる。
リモートで実行されるアクティビティが別のPlaceにアクティビティを投げてもリモートのfinishで待てば、問題ないので、at自体が制限されるべきではない。
調査の結果 ・リモートのfinish(RemoteFinishSPMD)が async の作成を検知する(notifySubActivitySpawn)と assertion error を吐く ・リモートで finish を新たに作った場合は問題ない ・atを使うと、Runtime ではat自体がactivityとして扱われるので、notifySubActivitySpawn()が呼ばれて、RemoteFinishSPMD が assertion error を吐く ・atで作成されるactivityの終了待ちは、Runtime が SimpleLatch を用いて行なっているので、finish の仕組みを使っていない ・at と async at または at async は、本来区別されるべきだが、notifySubActivitySpawnでは区別できない ・普通の(汎用的な)Finishの動作は、atでnofitySubActivitySpawnが呼ばれることに依存しているので、atでnotifySubActivitySpawnが呼ばれることを抑制することはできない
解決方法 at自体が制限されるのはおかしいが、atの中でasyncを使うのは確実にNG。つまり、atした時点ではOKだが、atの中でasyncしたらその時点でNGということになる。
つまり、RemoteFinishSPMD中のアクティビティから、atされた時に使われるべきFinishStateは、atはOKだけど、asyncはダメという動作をするものでなければいけない。このような動作を行うには、nofitySubActivitySpawnで、atによるものか、asyncによるものかを区別できる必要がある。
これを実装しようとすると、変更箇所が多いので、取り敢えず、何もしない、何でも許可の動作をするFinishを、 Pragma.FINISH_NONE で使えるようにした。
RemoteFinishSPMD中のアクティビティからatされたときに、このFinishを使うようにしたいのだが、それも実装が大変なので、取り敢えず、FinishSPMDの中で使われそうなメソッドの at は、 @Pragma(Pragma.FINISH_NONE) finish ~~~ を使うようにすればいいと思う。
PlaceLocalHandle.make* メソッドの at は全て、FINISH_NONEを使うようにした。他のatも使えるところは使うようにした方がいいかもしれない。
RemoteFinishSPMD.nofitySubActivitySpawn() に assert がなければ、こんな実装必要ないのだが、理想とすべきところに向かって進んでいくには、FINISH_NONEは必要なので、仕方ない。
将来的には、コンパイラがFINISH_SPMDなどは、使えるかどうかを自動で判定できるようにすると、言われているが、コンパイラが完璧に自動判別するのは、不可能に近い。メソッドに対して、「このメソッドから起動されるアクティビティは、このメソッドが終了するまでに全て終了する」というようなアノテーションを設けて、人間がメソッドに付けるというのが、現実的な解だと思う。しかし、細かなところの仕様は、もっと考えなければならないことが多いので、これが実装されるまで、まだ時間がかかる。
今のところFINISH_NONEを自分で付けて行かないとFINISH_SPMDがまともに使えるようにならない。RemoteFinishSPMDのassertを削除するというのもありだけど。
TODO: JIRA に同様の問題が報告されていないか確認する
Log in to post a comment.
調査の結果
・リモートのfinish(RemoteFinishSPMD)が async の作成を検知する(notifySubActivitySpawn)と assertion error を吐く
・リモートで finish を新たに作った場合は問題ない
・atを使うと、Runtime ではat自体がactivityとして扱われるので、notifySubActivitySpawn()が呼ばれて、RemoteFinishSPMD が assertion error を吐く
・atで作成されるactivityの終了待ちは、Runtime が SimpleLatch を用いて行なっているので、finish の仕組みを使っていない
・at と async at または at async は、本来区別されるべきだが、notifySubActivitySpawnでは区別できない
・普通の(汎用的な)Finishの動作は、atでnofitySubActivitySpawnが呼ばれることに依存しているので、atでnotifySubActivitySpawnが呼ばれることを抑制することはできない
解決方法
at自体が制限されるのはおかしいが、atの中でasyncを使うのは確実にNG。つまり、atした時点ではOKだが、atの中でasyncしたらその時点でNGということになる。
つまり、RemoteFinishSPMD中のアクティビティから、atされた時に使われるべきFinishStateは、atはOKだけど、asyncはダメという動作をするものでなければいけない。このような動作を行うには、nofitySubActivitySpawnで、atによるものか、asyncによるものかを区別できる必要がある。
これを実装しようとすると、変更箇所が多いので、取り敢えず、何もしない、何でも許可の動作をするFinishを、
Pragma.FINISH_NONE
で使えるようにした。
RemoteFinishSPMD中のアクティビティからatされたときに、このFinishを使うようにしたいのだが、それも実装が大変なので、取り敢えず、FinishSPMDの中で使われそうなメソッドの at は、
@Pragma(Pragma.FINISH_NONE) finish ~~~
を使うようにすればいいと思う。
PlaceLocalHandle.make* メソッドの at は全て、FINISH_NONEを使うようにした。他のatも使えるところは使うようにした方がいいかもしれない。
RemoteFinishSPMD.nofitySubActivitySpawn() に assert がなければ、こんな実装必要ないのだが、理想とすべきところに向かって進んでいくには、FINISH_NONEは必要なので、仕方ない。
Last edit: Koji Ueno 2013-05-11
将来的には、コンパイラがFINISH_SPMDなどは、使えるかどうかを自動で判定できるようにすると、言われているが、コンパイラが完璧に自動判別するのは、不可能に近い。メソッドに対して、「このメソッドから起動されるアクティビティは、このメソッドが終了するまでに全て終了する」というようなアノテーションを設けて、人間がメソッドに付けるというのが、現実的な解だと思う。しかし、細かなところの仕様は、もっと考えなければならないことが多いので、これが実装されるまで、まだ時間がかかる。
今のところFINISH_NONEを自分で付けて行かないとFINISH_SPMDがまともに使えるようにならない。RemoteFinishSPMDのassertを削除するというのもありだけど。
Last edit: Koji Ueno 2013-05-11
TODO: JIRA に同様の問題が報告されていないか確認する