今更ですが、四月馬鹿のジョーク記事で、18世紀風?の古雅な英語で書かれた Fortran インストールおよび、”Hello World!" ならぬ "Good morrow, and well met, O world!" 表示までの紹介記事がありました。
ちょっと面白かったです。作者はクラウドコンピューティングサービス会社のテクニカルライターの方のようです。
今更ですが、四月馬鹿のジョーク記事で、18世紀風?の古雅な英語で書かれた Fortran インストールおよび、”Hello World!" ならぬ "Good morrow, and well met, O world!" 表示までの紹介記事がありました。
ちょっと面白かったです。作者はクラウドコンピューティングサービス会社のテクニカルライターの方のようです。
Fortran 2008 の新機能 pointer function を用いて、簡単な連想配列 (associative array) を作ってみます。
ここでは古典的な手法で、文字列をインデックスとした整数型連想配列を作ってみます。
まず文字列を適当な整数に変換し、あらかじめ用意した配列のサイズの剰余をとって、それを実際の引数とします。このとき、単射性が無いため数値が重なることがあります(いわゆる衝突)、これが起きた場合は、適当な数を足して空いている場所が見つかるまでずらします。
文字列を数値に変換するために、まず文字列を文字配列に直し、次にそれをASCIIコードに直し、総和を取って、適当な素数で剰余を取っています。また衝突時にずらす数も素数に取れば、全ての空きを探すことになります(全射)。
module m_hash implicit none ! private integer, parameter :: nhash = 17, nd = 13 type :: t_key character(len = :), allocatable :: key end type t_key type (t_key) :: keyc(nhash) integer, target :: vals(nhash) = 0 contains integer function ihash(text) character(len = *), intent(in) :: text ihash = mod(sum(iachar(transfer(text, ' ', size = len_trim(text)))), nhash) + 1 end function ihash function ia(text) result(ires) character(len = *), intent(in) :: text integer, pointer :: ires integer :: key, loc, i key = ihash(text) do i = 1, nhash if (.not. allocated(keyc(key)%key)) then keyc(key)%key = trim(text) ires => vals(key) exit else if (keyc(key)%key == trim(text)) then ires => vals(key) exit else ! collision key = mod(key + nd, nhash) + 1 end if end do if (i > nhash) stop 'associative array exhausted!' end function ia end module m_hash program Hash use m_hash implicit none ia('a') = 41 print *, ia('a') ia('a') = 100 print *, ia('a') ia('b') = 200 print *, ia('a') + ia('b') ia('FORTRAN77') = 1978 ia('Fortran90') = 1991 ia('Donald Trump') = 1 ia('Steve Bannon') = 4 ia('Milo Yiannopoulos') = 10 block integer :: i do i = 1, nhash print '(i3,a,a20,a,i10)', i, ':', keyc(i)%key, '=>', ia(keyc(i)%key) end do end block end program Hash
41 100 300 1: => 0 2: Fortran90=> 1991 3: => 0 4: => 0 5: FORTRAN77=> 1978 6: => 0 7: Donald Trump=> 1 8: => 0 9: => 0 10: Milo Yiannopoulos=> 10 11: => 0 12: => 0 13: a=> 100 14: b=> 200 15: => 0 16: => 0 17: Steve Bannon=> 4 続行するには何かキーを押してください . . .
Fortran 2008 の新機能に、pointer を返り値としてもつ関数が、あたかも変数のように扱えるというものがあります。Modern Fortran Explained の 20.5.2 pointer functions denoting variables や The new features of Fortran 2008 の 6.2 Pointer functions に記述があります。
連想配列のようなものに適しているのではないかと思います。
module m_sub implicit none contains function storage(key) result(loc) integer, intent(in) :: key integer, pointer :: loc integer, target :: m(100) = 0 loc => m(key) end function storage end module m_sub program Console2 use m_sub implicit none integer :: i do i = 1, 10 storage(i) = i**2 end do do i = 1, 10 print *, storage(i) end do end program Console2
1 4 9 16 25 36 49 64 81 100 続行するには何かキーを押してください . . .
フィボナッチ数列を再帰で求めますが、一度求めた値はテーブルに記録して再利用します。フィボナッチ数の計算では意味がないのですが、テーブルのインデックスはとびとびの値でよくなっています。
二重再帰を使っています。
module m_fib implicit none integer, private, parameter :: nmax = 1000 integer, private :: nx = 0 integer, private :: keys(nmax) = -huge(0) integer, private, target :: vals(nmax) = 0 contains recursive function fib(n) result(ires) integer, intent(in) :: n integer :: ires select case(n) case (1:2) ires = 1 case (3:) ires = fib_table(n) case default ires = 0 end select end function fib recursive function fib_table(key) result(ires) integer, intent(in) :: key integer, pointer :: ires integer :: loc loc = findloc(keys(:nx), key, dim = 1) if (loc <= 0) then nx = nx + 1 keys (nx) = key vals(nx) = fib(key - 1) + fib(key - 2) loc = nx end if ires => vals(loc) end function fib_table end module m_fib program fibonacci use m_fib implicit none integer :: i do i = 1, 40 print *, i, fib(i) end do end program fibonacci
1 1 2 1 3 2 4 3 5 5 6 8 7 13 8 21 9 34 10 55 11 89 12 144 13 233 14 377 15 610 16 987 17 1597 18 2584 19 4181 20 6765 21 10946 22 17711 23 28657 24 46368 25 75025 26 121393 27 196418 28 317811 29 514229 30 832040 31 1346269 32 2178309 33 3524578 34 5702887 35 9227465 36 14930352 37 24157817 38 39088169 続行するには何かキーを押してください . . .
module m_fib2 implicit none contains recursive function fib(n) result(ires) integer, intent(in) :: n integer :: ires select case(n) case (1:2) ires = 1 case (3:) ires = fib(n - 1) + fib(n - 2) case default ires = 0 end select end function fib recursive function fib4(n) result(ires) integer, intent(in) :: n integer :: ires integer, save :: stor(100) = 0 select case(n) case(1:2) ires = 1 case(3:) if (stor(n) == 0) stor(n) = fib4(n - 1) + fib4(n - 2) ires = stor(n) case default ires = 0 end select end function fib4 end module m_fib2 program fibonacci use m_fib2 implicit none integer :: i do i = 1, 38 print *, i, fib(i) end do pause do i = 1, 38 print *, i, fib4(i) end do end program fibonacci
Fortran 2008 では、派生型の成分に自分自身を allocatable 属性で持てます。つまり再帰的に派生型を定義できます。再帰的定義は古典的なリスト構造によく使われます。
Fortran 2003 までは、派生型の再帰的な成分は pointer 型に限られていました。pointer 型の成分に記憶領域の割り付けをする場合、解放時の処理を利用者側が自分でやらなければなりませんでした。記憶領域の解放漏れが起きないよう慎重に解放処理を用意する必要がありました。
ところが allocatable 属性の場合は、記憶領域解放時の処理を、処理系側が引き受けてくれるので、利用者側の負担が大幅に減ります。
根元を解放すれば、そこから連なる子・孫・末代まで皆、処理系側が解放してくれます。根元を解放するとそこから連なる記憶領域がアクセス不能の死に領域になってしまう pointer 型との大きな違いです。
古典的な一次元単方向リストを定義して、整数値を入れてゆきます。つぎに根元からリストをたぐって代入した整数値を出力します。最後に、リストの根元を解放します。この時、ファイナライザ(いわゆるデストラクタ)を用意して、いまわの際に成分を出力させています。
module m_final type :: t_list integer :: ival type (t_list), allocatable :: next contains final :: destruct end type t_list contains subroutine destruct(this) type (t_list), intent(in) :: this print *, this%ival end subroutine destruct end module m_final program final use m_final implicit none type (t_list), allocatable, target :: root type (t_list), pointer :: last integer :: i allocate(root, source = t_list(0)) last => root do i = 1, 10 allocate(last%next, source = t_list(i)) last => last%next end do last => root print *, 'print list' do if (.not. associated(last)) exit print *, last%ival last => last%next end do print *, 'finalizer' deallocate(root) end program final
直リンが多くて申し訳ないが検索で飛んだ場所なので・・・
・Modern Fortran
www.admin-magazine.com
www.admin-magazine.com
www.admin-magazine.com
・フィンランド Fortran 講義 CAFあり
Modern Fortran Programming for Chemists and Physicists
・CAF スライド NEC
2012 F2008の並列処理関連機能
http://www.hpfpc.org/documents/soukai_120419/F2008Para.pdf
2013 Fortran 2008 のcoarray機能
http://www.pccluster.org/ja/event/xmpws1st/hayashi.pdf
2016 Fortran規格のcoarray機能 - Fortran 2008 と Fortran 2015
http://site.hpfpc.org/home/events/parallel_fortran_sympo2/documents_16060/hayashi_160601v2.pdf?attredirects=0&d=1
並列Fortranに関するシンポジウムのご案内(第2回) - 高性能Fortran 推進協議会
fujitu
2016 富士通のFortranへの取り組み ~Coarrayの実装と性能~
http://site.hpfpc.org/home/events/parallel_fortran_sympo2/documents_16060/haraguchi_160601.pdf?attredirects=0&d=1
・Xcalable + CAF
XcalableMP WebSite
2014
https://www.aics.riken.jp/aicssite/wp-content/uploads/2014/12/2014sympo_0307_1010.pdf
https://www.gfd-dennou.org/arch/davis/workshop/2014-03-10/murai.pdf
2016
http://www.xcalablemp.org/download/workshop/4th/iwashita.pdf
・CAF2.0
Coarray Fortran 2.0 at Rice University
スライド
2009
http://open-supercomputer.org/wp-content/uploads/2012/03/WPSE2009-06-Scherer.pdf
2012
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.648.5708&rep=rep1&type=pdf
2013
https://crd.lbl.gov/assets/Uploads/FTG/Projects/DEGAS/RetreatSummer13/CAF2.0.pdf
・MPI: William Gropp の講義
Designing and Building Applications for Extreme Scale Systems
Fortran v.18 は、パッと見たところ Fortan2008 規格の主な機能にほぼ完全に対応した感じです。長らく待たれていた、リスト構造を扱い易くする type 中での再帰型 allocatable や、再帰関数での無駄な計算を減らすための変数の蓄積を容易にする ポインタ関数への代入や、テーブルルックアップを容易にする finloc 関数などが一気に実装されました。
以下の記事でコンパイラごとの実装状況の比較ができます。残念ながら NEC、Fujitsu のコンパイラは入っていません。メーカが情報を送れば載せるみたいです?
Compiler support for Fortran 2003, 2008 & TS 29113 Standard - rev 20 (December 2016)
www.fortranplus.co.uk
なお最新版の rev.21 は
Ian Chivers, Jane Sleightholme:
Compiler Support for the Fortran 2003 and 2008 Standards Revision 21
ACM SIGPLAN Fortran Forum
(有料)
来週、2018 beta の内容紹介 webinar があります。
Get Onboard with the Intel® Parallel Studio XE 2018 Beta (Online)
High Performance Computing (HPC) Webinars | Intel® Software
トランプ米大統領の躍進の陰には、米白人弱者の困難な社会的状況があると言われていました。その証拠として、米白人庶民層の寿命低下がよく取り上げられています。背後には、生きる意味の喪失とそれに伴う酒・薬物依存すなわち自暴自棄(今風にいえばセルフネグレクトw)があるとされています。
これはソ連崩壊後のロシア人や、アメリカ人宣教師到来後の南洋土人・エスキモーに見られた現象と同質のものだと思われます。すなわち、民話や土着宗教的な神話を破壊されたときに起きる、人生の意味の喪失による内側からの崩壊だと思います。
ロシアではソ連崩壊により、マルクス・レーニン主義という、過去に原始共産主義の楽園があったとする素朴な民間宗教が崩壊した後、ウォッカや薬物への依存が蔓延しました。南洋土人やエスキモーも、善意のキリスト教宣教師が、いわゆる野蛮な土着信仰や民話・民謡・祭りの類を根絶したあと、アル中や薬中が蔓延しました。
このような普段見過ごされて、無駄だと見なされがちな素朴な習俗が、生きる意味などを与えていることは、決して軽視してはならないものだと思います。
近年のアメリカでは、クリスマスのような民衆レベルの素朴な風習への攻撃が行われていることがよくニュースになっています。これは上述の素朴な土着民話や宗教への攻撃と同類のものだと思われます。
かつてのティー・パーティーの諸子やスティーブ・バノン氏の登場は、このことに直観的に気付いて、それに対抗しようとした無意識の動きなのだと思います。それがいずれも、振り出し方を間違えて力を失うのは、まこと哀れな感じがします。「鳥の将に死なんとする其の鳴くや哀し」といった趣きです。
しかしながら逆に、我が国はこれを応用して敵国を内部から崩壊させることを是非とも研究しておくべきだと思います。そのためには諸外国の宗教・習俗・民話などを軽視せず、よく研究しておいて、いざという時に自己矛盾に追い込んで、根本から社会を崩壊させる手段を整えておくべきだと思います。
ここで思い起こすのは、江戸時代の日本の宋学批判から始まった儒学テキスト校訂作業が清朝支那に伝わって考証学を引き起こし、それが国家宗教の朱子学儒教への懐疑を産み、支那の精神的支柱を破壊したことです。純粋な学問研究が、うまい具合に一国家の衰運・滅亡を引き起こせたことは、学問の力の特筆すべき偉業と言えると思います。