並列プログラミング入門( 編) ·...

48
0 並列プログラミング入門(MPI編) 高度情報科学技術研究機構 神戸センター 宮内

Upload: others

Post on 13-Jul-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

0

並列プログラミング入門(MPI編)

高度情報科学技術研究機構 神戸センター 宮内 敦

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 1

並列処理に関する様々な分類

◼ ハードウェア的観点からの分類 プロセッサとメモリの配置

アドレス空間

プロセッサとOSの関係

相互結合網

Flynnの分類

◼ ソフトウェア的観点からの分類 プログラムの実行方法

SPMDにおける処理の分割

実行資源の共有状況

通信ライブライ内の手順

通信のスケジュール

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 2

bull 共有記憶型(Shared Memory)

bull 全プロセッサが一つのメモリを共有bull プロセッサ間の通信は不要bull メモリアクセスの排他制御が必要bull プロセッサ数は100程度まで

bull 分散記憶型(Distributed Memory)

bull プロセッサ毎に独立したメモリをもつbull プロセッサ間の通信が必要bull 局所メモリ内は排他制御不要bull プロセッサ数は10000以上も可

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

プロセッサとメモリの配置(1コア)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 3

bull 共有記憶型(Shared Memory)

bull CPU内のメモリコントローラを相互通信網の一部と見做せばシングルコアの場合と同じ

bull 分散共有記憶型(Distributed Shared Memory)

bull 分散記憶と共有記憶の両方の特徴を併せ持つ

CPU

memory

interconnect

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

bus arbiter

me

mo

ry

interconnect

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

me

mo

ry

me

mo

ry

me

mo

ry

CPU

bus arbiter

≒ 8core共有 ≒ 2core共有times4node分散

プロセッサとメモリの配置(マルチコア)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 4

bull 異種分散共有記憶型(Heterogeneously Distributed Shared Memory)

bull 分散共有記憶型CPUの各ノード内に共有記憶型GPUbull GPUは内部に共有記憶領域を持つbull 主記憶はCPUとGPUの双方で共有される

≒ (2core+24 GPU-core 共有)times2node分散

CUDA cores

Internal bus (Nvlink)

CPU

interconnect

local

memoryc

ore

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

rem

em

ory

local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

HBM2local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

rem

em

ory

local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

プロセッサとメモリの配置(GPGPU)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 5

bull 単一アドレス空間(Single Address Space)すべてプロセッサが一つのアドレス空間を共有bull UMA(Uniform Memory Access)

物理メモリは共有記憶型空間内のどのアドレスにもアクセス時間は同じ

bull NUMA(Non-Uniform Memory Access)物理メモリは分散記憶型一部のアドレスへのアクセスは速いその他のアドレスへのアクセスは遅い通信用キャッシュを持つ場合はccNUMA (cache coherent NUMA)

bull COMA(Cache-Only Memory Access)物理メモリは分散記憶型論理アドレスは不変物理アドレスは動的に変化データはシステムが最適な場所に配置

bull 分散アドレス空間(Distributed Address Space)プロセッサ毎に独立したアドレス空間を持つ物理メモリは分散記憶型

アドレス空間

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 6

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ryinterconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x0

0xff

0x0

0xff

0x0

0xff

0x0

0xff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x300

0x3ff

0x0

0xff

0x100

0x1ff

0x200

0x2ff

UMA NUMA

COMA Distributed

メモリマネージャが動的にデータ再配置

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 7

bull 共有記憶型システムはプロセッサの役割でさらに分類されるbull SMP(Symmetric Multi-Processing)

全プロセッサが同じ機能と権限を持ち特権的なプロセッサがない現在の共有記憶はほとんどこのタイプマルチコアCPUとメモリの場合もこのタイプと見なせる

bull AMP(Asymmetric Multi-Processing)

全体を制御するメインプロセッサとそれ以外で役割を分担80年代までは大型汎用機やPC(Fujitsu FM-8)の例があった現在ではGPUアクセラレータとCPUの組み合わせがこのタイプと見なせる

bull OSの管理が及ぶ範囲による分類bull 密結合(Tightly Coupled System)

1つのOSが管理する資源を複数のプロセッサが使用するSMPでは自然な選択となる

bull 疎結合(Loosely Coupled System)

プロセッサ毎にOSが存在し個別に資源を管理する分散記憶型では自然な選択となる

プロセッサとOSの関係

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 8

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

SMP AMP

密結合 疎結合

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

OS

me

mo

ry

core

CPU

core

CPU

core

CPU

core

CPU

OS OS OS OS

me

mo

ry

me

mo

ry

me

mo

ry

interconnect

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 9

相互結合網の方式は非常に多いここでは代表的なものだけ紹介

相互結合網(Interconnect)

バス同時にバスにアクセスできるのは1ノードだけ

n次元メッシュ隣接ノード間のみの通信平均ホップ数はradicN程度

n次元トーラス隣接ノード間のみの通信平均ホップ数はradicN程度

最大ホップ数はメッシュの半分

ファットツリーツリー結合で上位が太い平均ホップ数はlog2N程度

n次元ハイパーキューブ各ノードがn個のノードと結合平均ホップ数はlog2N程度

クロスバースイッチで動的結合1ホップでN対N通信

結線

ノード

スイッチON

スイッチOFF

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 10

並列計算機の最初期の分類法プロセッサの動作を命令列とデータ列のみで抽象化可能な組み合わせとして以下の4通りを考えた

bull SISD(Single Instruction Single Data Stream)

bull SIMD(Single Instruction Multiple Data Stream)

bull MISD(Multiple Instruction Single Data Stream)

bull MIMD(Multiple Instruction Multiple Data Stream)

概念モデルなので適用するレベルによって分類が異なることもある命令列とデータ列の単位をどう解釈するかで分類が変わる

(例えばVLIWでは一つの長ワード命令に複数の命令が埋め込まれる)プロセッサのSIMD命令以外では最近あまり使われない

Flynnの分類(Flynnrsquos Taxonomy)

M J Flynn Very High-Speed Computing Systems Proceedings of IEEE Vol 54 1901-1909 1966

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 2: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 1

並列処理に関する様々な分類

◼ ハードウェア的観点からの分類 プロセッサとメモリの配置

アドレス空間

プロセッサとOSの関係

相互結合網

Flynnの分類

◼ ソフトウェア的観点からの分類 プログラムの実行方法

SPMDにおける処理の分割

実行資源の共有状況

通信ライブライ内の手順

通信のスケジュール

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 2

bull 共有記憶型(Shared Memory)

bull 全プロセッサが一つのメモリを共有bull プロセッサ間の通信は不要bull メモリアクセスの排他制御が必要bull プロセッサ数は100程度まで

bull 分散記憶型(Distributed Memory)

bull プロセッサ毎に独立したメモリをもつbull プロセッサ間の通信が必要bull 局所メモリ内は排他制御不要bull プロセッサ数は10000以上も可

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

プロセッサとメモリの配置(1コア)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 3

bull 共有記憶型(Shared Memory)

bull CPU内のメモリコントローラを相互通信網の一部と見做せばシングルコアの場合と同じ

bull 分散共有記憶型(Distributed Shared Memory)

bull 分散記憶と共有記憶の両方の特徴を併せ持つ

CPU

memory

interconnect

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

bus arbiter

me

mo

ry

interconnect

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

me

mo

ry

me

mo

ry

me

mo

ry

CPU

bus arbiter

≒ 8core共有 ≒ 2core共有times4node分散

プロセッサとメモリの配置(マルチコア)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 4

bull 異種分散共有記憶型(Heterogeneously Distributed Shared Memory)

bull 分散共有記憶型CPUの各ノード内に共有記憶型GPUbull GPUは内部に共有記憶領域を持つbull 主記憶はCPUとGPUの双方で共有される

≒ (2core+24 GPU-core 共有)times2node分散

CUDA cores

Internal bus (Nvlink)

CPU

interconnect

local

memoryc

ore

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

rem

em

ory

local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

HBM2local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

rem

em

ory

local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

プロセッサとメモリの配置(GPGPU)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 5

bull 単一アドレス空間(Single Address Space)すべてプロセッサが一つのアドレス空間を共有bull UMA(Uniform Memory Access)

物理メモリは共有記憶型空間内のどのアドレスにもアクセス時間は同じ

bull NUMA(Non-Uniform Memory Access)物理メモリは分散記憶型一部のアドレスへのアクセスは速いその他のアドレスへのアクセスは遅い通信用キャッシュを持つ場合はccNUMA (cache coherent NUMA)

bull COMA(Cache-Only Memory Access)物理メモリは分散記憶型論理アドレスは不変物理アドレスは動的に変化データはシステムが最適な場所に配置

bull 分散アドレス空間(Distributed Address Space)プロセッサ毎に独立したアドレス空間を持つ物理メモリは分散記憶型

アドレス空間

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 6

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ryinterconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x0

0xff

0x0

0xff

0x0

0xff

0x0

0xff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x300

0x3ff

0x0

0xff

0x100

0x1ff

0x200

0x2ff

UMA NUMA

COMA Distributed

メモリマネージャが動的にデータ再配置

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 7

bull 共有記憶型システムはプロセッサの役割でさらに分類されるbull SMP(Symmetric Multi-Processing)

全プロセッサが同じ機能と権限を持ち特権的なプロセッサがない現在の共有記憶はほとんどこのタイプマルチコアCPUとメモリの場合もこのタイプと見なせる

bull AMP(Asymmetric Multi-Processing)

全体を制御するメインプロセッサとそれ以外で役割を分担80年代までは大型汎用機やPC(Fujitsu FM-8)の例があった現在ではGPUアクセラレータとCPUの組み合わせがこのタイプと見なせる

bull OSの管理が及ぶ範囲による分類bull 密結合(Tightly Coupled System)

1つのOSが管理する資源を複数のプロセッサが使用するSMPでは自然な選択となる

bull 疎結合(Loosely Coupled System)

プロセッサ毎にOSが存在し個別に資源を管理する分散記憶型では自然な選択となる

プロセッサとOSの関係

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 8

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

SMP AMP

密結合 疎結合

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

OS

me

mo

ry

core

CPU

core

CPU

core

CPU

core

CPU

OS OS OS OS

me

mo

ry

me

mo

ry

me

mo

ry

interconnect

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 9

相互結合網の方式は非常に多いここでは代表的なものだけ紹介

相互結合網(Interconnect)

バス同時にバスにアクセスできるのは1ノードだけ

n次元メッシュ隣接ノード間のみの通信平均ホップ数はradicN程度

n次元トーラス隣接ノード間のみの通信平均ホップ数はradicN程度

最大ホップ数はメッシュの半分

ファットツリーツリー結合で上位が太い平均ホップ数はlog2N程度

n次元ハイパーキューブ各ノードがn個のノードと結合平均ホップ数はlog2N程度

クロスバースイッチで動的結合1ホップでN対N通信

結線

ノード

スイッチON

スイッチOFF

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 10

並列計算機の最初期の分類法プロセッサの動作を命令列とデータ列のみで抽象化可能な組み合わせとして以下の4通りを考えた

bull SISD(Single Instruction Single Data Stream)

bull SIMD(Single Instruction Multiple Data Stream)

bull MISD(Multiple Instruction Single Data Stream)

bull MIMD(Multiple Instruction Multiple Data Stream)

概念モデルなので適用するレベルによって分類が異なることもある命令列とデータ列の単位をどう解釈するかで分類が変わる

(例えばVLIWでは一つの長ワード命令に複数の命令が埋め込まれる)プロセッサのSIMD命令以外では最近あまり使われない

Flynnの分類(Flynnrsquos Taxonomy)

M J Flynn Very High-Speed Computing Systems Proceedings of IEEE Vol 54 1901-1909 1966

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 3: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 2

bull 共有記憶型(Shared Memory)

bull 全プロセッサが一つのメモリを共有bull プロセッサ間の通信は不要bull メモリアクセスの排他制御が必要bull プロセッサ数は100程度まで

bull 分散記憶型(Distributed Memory)

bull プロセッサ毎に独立したメモリをもつbull プロセッサ間の通信が必要bull 局所メモリ内は排他制御不要bull プロセッサ数は10000以上も可

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

プロセッサとメモリの配置(1コア)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 3

bull 共有記憶型(Shared Memory)

bull CPU内のメモリコントローラを相互通信網の一部と見做せばシングルコアの場合と同じ

bull 分散共有記憶型(Distributed Shared Memory)

bull 分散記憶と共有記憶の両方の特徴を併せ持つ

CPU

memory

interconnect

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

bus arbiter

me

mo

ry

interconnect

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

me

mo

ry

me

mo

ry

me

mo

ry

CPU

bus arbiter

≒ 8core共有 ≒ 2core共有times4node分散

プロセッサとメモリの配置(マルチコア)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 4

bull 異種分散共有記憶型(Heterogeneously Distributed Shared Memory)

bull 分散共有記憶型CPUの各ノード内に共有記憶型GPUbull GPUは内部に共有記憶領域を持つbull 主記憶はCPUとGPUの双方で共有される

≒ (2core+24 GPU-core 共有)times2node分散

CUDA cores

Internal bus (Nvlink)

CPU

interconnect

local

memoryc

ore

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

rem

em

ory

local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

HBM2local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

rem

em

ory

local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

プロセッサとメモリの配置(GPGPU)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 5

bull 単一アドレス空間(Single Address Space)すべてプロセッサが一つのアドレス空間を共有bull UMA(Uniform Memory Access)

物理メモリは共有記憶型空間内のどのアドレスにもアクセス時間は同じ

bull NUMA(Non-Uniform Memory Access)物理メモリは分散記憶型一部のアドレスへのアクセスは速いその他のアドレスへのアクセスは遅い通信用キャッシュを持つ場合はccNUMA (cache coherent NUMA)

bull COMA(Cache-Only Memory Access)物理メモリは分散記憶型論理アドレスは不変物理アドレスは動的に変化データはシステムが最適な場所に配置

bull 分散アドレス空間(Distributed Address Space)プロセッサ毎に独立したアドレス空間を持つ物理メモリは分散記憶型

アドレス空間

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 6

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ryinterconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x0

0xff

0x0

0xff

0x0

0xff

0x0

0xff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x300

0x3ff

0x0

0xff

0x100

0x1ff

0x200

0x2ff

UMA NUMA

COMA Distributed

メモリマネージャが動的にデータ再配置

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 7

bull 共有記憶型システムはプロセッサの役割でさらに分類されるbull SMP(Symmetric Multi-Processing)

全プロセッサが同じ機能と権限を持ち特権的なプロセッサがない現在の共有記憶はほとんどこのタイプマルチコアCPUとメモリの場合もこのタイプと見なせる

bull AMP(Asymmetric Multi-Processing)

全体を制御するメインプロセッサとそれ以外で役割を分担80年代までは大型汎用機やPC(Fujitsu FM-8)の例があった現在ではGPUアクセラレータとCPUの組み合わせがこのタイプと見なせる

bull OSの管理が及ぶ範囲による分類bull 密結合(Tightly Coupled System)

1つのOSが管理する資源を複数のプロセッサが使用するSMPでは自然な選択となる

bull 疎結合(Loosely Coupled System)

プロセッサ毎にOSが存在し個別に資源を管理する分散記憶型では自然な選択となる

プロセッサとOSの関係

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 8

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

SMP AMP

密結合 疎結合

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

OS

me

mo

ry

core

CPU

core

CPU

core

CPU

core

CPU

OS OS OS OS

me

mo

ry

me

mo

ry

me

mo

ry

interconnect

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 9

相互結合網の方式は非常に多いここでは代表的なものだけ紹介

相互結合網(Interconnect)

バス同時にバスにアクセスできるのは1ノードだけ

n次元メッシュ隣接ノード間のみの通信平均ホップ数はradicN程度

n次元トーラス隣接ノード間のみの通信平均ホップ数はradicN程度

最大ホップ数はメッシュの半分

ファットツリーツリー結合で上位が太い平均ホップ数はlog2N程度

n次元ハイパーキューブ各ノードがn個のノードと結合平均ホップ数はlog2N程度

クロスバースイッチで動的結合1ホップでN対N通信

結線

ノード

スイッチON

スイッチOFF

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 10

並列計算機の最初期の分類法プロセッサの動作を命令列とデータ列のみで抽象化可能な組み合わせとして以下の4通りを考えた

bull SISD(Single Instruction Single Data Stream)

bull SIMD(Single Instruction Multiple Data Stream)

bull MISD(Multiple Instruction Single Data Stream)

bull MIMD(Multiple Instruction Multiple Data Stream)

概念モデルなので適用するレベルによって分類が異なることもある命令列とデータ列の単位をどう解釈するかで分類が変わる

(例えばVLIWでは一つの長ワード命令に複数の命令が埋め込まれる)プロセッサのSIMD命令以外では最近あまり使われない

Flynnの分類(Flynnrsquos Taxonomy)

M J Flynn Very High-Speed Computing Systems Proceedings of IEEE Vol 54 1901-1909 1966

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 4: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 3

bull 共有記憶型(Shared Memory)

bull CPU内のメモリコントローラを相互通信網の一部と見做せばシングルコアの場合と同じ

bull 分散共有記憶型(Distributed Shared Memory)

bull 分散記憶と共有記憶の両方の特徴を併せ持つ

CPU

memory

interconnect

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

bus arbiter

me

mo

ry

interconnect

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

me

mo

ry

me

mo

ry

me

mo

ry

CPU

bus arbiter

≒ 8core共有 ≒ 2core共有times4node分散

プロセッサとメモリの配置(マルチコア)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 4

bull 異種分散共有記憶型(Heterogeneously Distributed Shared Memory)

bull 分散共有記憶型CPUの各ノード内に共有記憶型GPUbull GPUは内部に共有記憶領域を持つbull 主記憶はCPUとGPUの双方で共有される

≒ (2core+24 GPU-core 共有)times2node分散

CUDA cores

Internal bus (Nvlink)

CPU

interconnect

local

memoryc

ore

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

rem

em

ory

local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

HBM2local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

rem

em

ory

local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

プロセッサとメモリの配置(GPGPU)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 5

bull 単一アドレス空間(Single Address Space)すべてプロセッサが一つのアドレス空間を共有bull UMA(Uniform Memory Access)

物理メモリは共有記憶型空間内のどのアドレスにもアクセス時間は同じ

bull NUMA(Non-Uniform Memory Access)物理メモリは分散記憶型一部のアドレスへのアクセスは速いその他のアドレスへのアクセスは遅い通信用キャッシュを持つ場合はccNUMA (cache coherent NUMA)

bull COMA(Cache-Only Memory Access)物理メモリは分散記憶型論理アドレスは不変物理アドレスは動的に変化データはシステムが最適な場所に配置

bull 分散アドレス空間(Distributed Address Space)プロセッサ毎に独立したアドレス空間を持つ物理メモリは分散記憶型

アドレス空間

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 6

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ryinterconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x0

0xff

0x0

0xff

0x0

0xff

0x0

0xff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x300

0x3ff

0x0

0xff

0x100

0x1ff

0x200

0x2ff

UMA NUMA

COMA Distributed

メモリマネージャが動的にデータ再配置

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 7

bull 共有記憶型システムはプロセッサの役割でさらに分類されるbull SMP(Symmetric Multi-Processing)

全プロセッサが同じ機能と権限を持ち特権的なプロセッサがない現在の共有記憶はほとんどこのタイプマルチコアCPUとメモリの場合もこのタイプと見なせる

bull AMP(Asymmetric Multi-Processing)

全体を制御するメインプロセッサとそれ以外で役割を分担80年代までは大型汎用機やPC(Fujitsu FM-8)の例があった現在ではGPUアクセラレータとCPUの組み合わせがこのタイプと見なせる

bull OSの管理が及ぶ範囲による分類bull 密結合(Tightly Coupled System)

1つのOSが管理する資源を複数のプロセッサが使用するSMPでは自然な選択となる

bull 疎結合(Loosely Coupled System)

プロセッサ毎にOSが存在し個別に資源を管理する分散記憶型では自然な選択となる

プロセッサとOSの関係

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 8

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

SMP AMP

密結合 疎結合

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

OS

me

mo

ry

core

CPU

core

CPU

core

CPU

core

CPU

OS OS OS OS

me

mo

ry

me

mo

ry

me

mo

ry

interconnect

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 9

相互結合網の方式は非常に多いここでは代表的なものだけ紹介

相互結合網(Interconnect)

バス同時にバスにアクセスできるのは1ノードだけ

n次元メッシュ隣接ノード間のみの通信平均ホップ数はradicN程度

n次元トーラス隣接ノード間のみの通信平均ホップ数はradicN程度

最大ホップ数はメッシュの半分

ファットツリーツリー結合で上位が太い平均ホップ数はlog2N程度

n次元ハイパーキューブ各ノードがn個のノードと結合平均ホップ数はlog2N程度

クロスバースイッチで動的結合1ホップでN対N通信

結線

ノード

スイッチON

スイッチOFF

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 10

並列計算機の最初期の分類法プロセッサの動作を命令列とデータ列のみで抽象化可能な組み合わせとして以下の4通りを考えた

bull SISD(Single Instruction Single Data Stream)

bull SIMD(Single Instruction Multiple Data Stream)

bull MISD(Multiple Instruction Single Data Stream)

bull MIMD(Multiple Instruction Multiple Data Stream)

概念モデルなので適用するレベルによって分類が異なることもある命令列とデータ列の単位をどう解釈するかで分類が変わる

(例えばVLIWでは一つの長ワード命令に複数の命令が埋め込まれる)プロセッサのSIMD命令以外では最近あまり使われない

Flynnの分類(Flynnrsquos Taxonomy)

M J Flynn Very High-Speed Computing Systems Proceedings of IEEE Vol 54 1901-1909 1966

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 5: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 4

bull 異種分散共有記憶型(Heterogeneously Distributed Shared Memory)

bull 分散共有記憶型CPUの各ノード内に共有記憶型GPUbull GPUは内部に共有記憶領域を持つbull 主記憶はCPUとGPUの双方で共有される

≒ (2core+24 GPU-core 共有)times2node分散

CUDA cores

Internal bus (Nvlink)

CPU

interconnect

local

memoryc

ore

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

rem

em

ory

local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

HBM2local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

rem

em

ory

local

memory

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

co

re

プロセッサとメモリの配置(GPGPU)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 5

bull 単一アドレス空間(Single Address Space)すべてプロセッサが一つのアドレス空間を共有bull UMA(Uniform Memory Access)

物理メモリは共有記憶型空間内のどのアドレスにもアクセス時間は同じ

bull NUMA(Non-Uniform Memory Access)物理メモリは分散記憶型一部のアドレスへのアクセスは速いその他のアドレスへのアクセスは遅い通信用キャッシュを持つ場合はccNUMA (cache coherent NUMA)

bull COMA(Cache-Only Memory Access)物理メモリは分散記憶型論理アドレスは不変物理アドレスは動的に変化データはシステムが最適な場所に配置

bull 分散アドレス空間(Distributed Address Space)プロセッサ毎に独立したアドレス空間を持つ物理メモリは分散記憶型

アドレス空間

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 6

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ryinterconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x0

0xff

0x0

0xff

0x0

0xff

0x0

0xff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x300

0x3ff

0x0

0xff

0x100

0x1ff

0x200

0x2ff

UMA NUMA

COMA Distributed

メモリマネージャが動的にデータ再配置

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 7

bull 共有記憶型システムはプロセッサの役割でさらに分類されるbull SMP(Symmetric Multi-Processing)

全プロセッサが同じ機能と権限を持ち特権的なプロセッサがない現在の共有記憶はほとんどこのタイプマルチコアCPUとメモリの場合もこのタイプと見なせる

bull AMP(Asymmetric Multi-Processing)

全体を制御するメインプロセッサとそれ以外で役割を分担80年代までは大型汎用機やPC(Fujitsu FM-8)の例があった現在ではGPUアクセラレータとCPUの組み合わせがこのタイプと見なせる

bull OSの管理が及ぶ範囲による分類bull 密結合(Tightly Coupled System)

1つのOSが管理する資源を複数のプロセッサが使用するSMPでは自然な選択となる

bull 疎結合(Loosely Coupled System)

プロセッサ毎にOSが存在し個別に資源を管理する分散記憶型では自然な選択となる

プロセッサとOSの関係

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 8

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

SMP AMP

密結合 疎結合

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

OS

me

mo

ry

core

CPU

core

CPU

core

CPU

core

CPU

OS OS OS OS

me

mo

ry

me

mo

ry

me

mo

ry

interconnect

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 9

相互結合網の方式は非常に多いここでは代表的なものだけ紹介

相互結合網(Interconnect)

バス同時にバスにアクセスできるのは1ノードだけ

n次元メッシュ隣接ノード間のみの通信平均ホップ数はradicN程度

n次元トーラス隣接ノード間のみの通信平均ホップ数はradicN程度

最大ホップ数はメッシュの半分

ファットツリーツリー結合で上位が太い平均ホップ数はlog2N程度

n次元ハイパーキューブ各ノードがn個のノードと結合平均ホップ数はlog2N程度

クロスバースイッチで動的結合1ホップでN対N通信

結線

ノード

スイッチON

スイッチOFF

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 10

並列計算機の最初期の分類法プロセッサの動作を命令列とデータ列のみで抽象化可能な組み合わせとして以下の4通りを考えた

bull SISD(Single Instruction Single Data Stream)

bull SIMD(Single Instruction Multiple Data Stream)

bull MISD(Multiple Instruction Single Data Stream)

bull MIMD(Multiple Instruction Multiple Data Stream)

概念モデルなので適用するレベルによって分類が異なることもある命令列とデータ列の単位をどう解釈するかで分類が変わる

(例えばVLIWでは一つの長ワード命令に複数の命令が埋め込まれる)プロセッサのSIMD命令以外では最近あまり使われない

Flynnの分類(Flynnrsquos Taxonomy)

M J Flynn Very High-Speed Computing Systems Proceedings of IEEE Vol 54 1901-1909 1966

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 6: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 5

bull 単一アドレス空間(Single Address Space)すべてプロセッサが一つのアドレス空間を共有bull UMA(Uniform Memory Access)

物理メモリは共有記憶型空間内のどのアドレスにもアクセス時間は同じ

bull NUMA(Non-Uniform Memory Access)物理メモリは分散記憶型一部のアドレスへのアクセスは速いその他のアドレスへのアクセスは遅い通信用キャッシュを持つ場合はccNUMA (cache coherent NUMA)

bull COMA(Cache-Only Memory Access)物理メモリは分散記憶型論理アドレスは不変物理アドレスは動的に変化データはシステムが最適な場所に配置

bull 分散アドレス空間(Distributed Address Space)プロセッサ毎に独立したアドレス空間を持つ物理メモリは分散記憶型

アドレス空間

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 6

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ryinterconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x0

0xff

0x0

0xff

0x0

0xff

0x0

0xff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x300

0x3ff

0x0

0xff

0x100

0x1ff

0x200

0x2ff

UMA NUMA

COMA Distributed

メモリマネージャが動的にデータ再配置

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 7

bull 共有記憶型システムはプロセッサの役割でさらに分類されるbull SMP(Symmetric Multi-Processing)

全プロセッサが同じ機能と権限を持ち特権的なプロセッサがない現在の共有記憶はほとんどこのタイプマルチコアCPUとメモリの場合もこのタイプと見なせる

bull AMP(Asymmetric Multi-Processing)

全体を制御するメインプロセッサとそれ以外で役割を分担80年代までは大型汎用機やPC(Fujitsu FM-8)の例があった現在ではGPUアクセラレータとCPUの組み合わせがこのタイプと見なせる

bull OSの管理が及ぶ範囲による分類bull 密結合(Tightly Coupled System)

1つのOSが管理する資源を複数のプロセッサが使用するSMPでは自然な選択となる

bull 疎結合(Loosely Coupled System)

プロセッサ毎にOSが存在し個別に資源を管理する分散記憶型では自然な選択となる

プロセッサとOSの関係

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 8

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

SMP AMP

密結合 疎結合

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

OS

me

mo

ry

core

CPU

core

CPU

core

CPU

core

CPU

OS OS OS OS

me

mo

ry

me

mo

ry

me

mo

ry

interconnect

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 9

相互結合網の方式は非常に多いここでは代表的なものだけ紹介

相互結合網(Interconnect)

バス同時にバスにアクセスできるのは1ノードだけ

n次元メッシュ隣接ノード間のみの通信平均ホップ数はradicN程度

n次元トーラス隣接ノード間のみの通信平均ホップ数はradicN程度

最大ホップ数はメッシュの半分

ファットツリーツリー結合で上位が太い平均ホップ数はlog2N程度

n次元ハイパーキューブ各ノードがn個のノードと結合平均ホップ数はlog2N程度

クロスバースイッチで動的結合1ホップでN対N通信

結線

ノード

スイッチON

スイッチOFF

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 10

並列計算機の最初期の分類法プロセッサの動作を命令列とデータ列のみで抽象化可能な組み合わせとして以下の4通りを考えた

bull SISD(Single Instruction Single Data Stream)

bull SIMD(Single Instruction Multiple Data Stream)

bull MISD(Multiple Instruction Single Data Stream)

bull MIMD(Multiple Instruction Multiple Data Stream)

概念モデルなので適用するレベルによって分類が異なることもある命令列とデータ列の単位をどう解釈するかで分類が変わる

(例えばVLIWでは一つの長ワード命令に複数の命令が埋め込まれる)プロセッサのSIMD命令以外では最近あまり使われない

Flynnの分類(Flynnrsquos Taxonomy)

M J Flynn Very High-Speed Computing Systems Proceedings of IEEE Vol 54 1901-1909 1966

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 7: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 6

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry0x0

0xff

0x100

0x1ff

0x200

0x2ff

0x300

0x3ff

me

mo

ryinterconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x0

0xff

0x0

0xff

0x0

0xff

0x0

0xff

me

mo

ry

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

me

mo

ry

me

mo

ry

me

mo

ry

0x300

0x3ff

0x0

0xff

0x100

0x1ff

0x200

0x2ff

UMA NUMA

COMA Distributed

メモリマネージャが動的にデータ再配置

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 7

bull 共有記憶型システムはプロセッサの役割でさらに分類されるbull SMP(Symmetric Multi-Processing)

全プロセッサが同じ機能と権限を持ち特権的なプロセッサがない現在の共有記憶はほとんどこのタイプマルチコアCPUとメモリの場合もこのタイプと見なせる

bull AMP(Asymmetric Multi-Processing)

全体を制御するメインプロセッサとそれ以外で役割を分担80年代までは大型汎用機やPC(Fujitsu FM-8)の例があった現在ではGPUアクセラレータとCPUの組み合わせがこのタイプと見なせる

bull OSの管理が及ぶ範囲による分類bull 密結合(Tightly Coupled System)

1つのOSが管理する資源を複数のプロセッサが使用するSMPでは自然な選択となる

bull 疎結合(Loosely Coupled System)

プロセッサ毎にOSが存在し個別に資源を管理する分散記憶型では自然な選択となる

プロセッサとOSの関係

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 8

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

SMP AMP

密結合 疎結合

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

OS

me

mo

ry

core

CPU

core

CPU

core

CPU

core

CPU

OS OS OS OS

me

mo

ry

me

mo

ry

me

mo

ry

interconnect

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 9

相互結合網の方式は非常に多いここでは代表的なものだけ紹介

相互結合網(Interconnect)

バス同時にバスにアクセスできるのは1ノードだけ

n次元メッシュ隣接ノード間のみの通信平均ホップ数はradicN程度

n次元トーラス隣接ノード間のみの通信平均ホップ数はradicN程度

最大ホップ数はメッシュの半分

ファットツリーツリー結合で上位が太い平均ホップ数はlog2N程度

n次元ハイパーキューブ各ノードがn個のノードと結合平均ホップ数はlog2N程度

クロスバースイッチで動的結合1ホップでN対N通信

結線

ノード

スイッチON

スイッチOFF

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 10

並列計算機の最初期の分類法プロセッサの動作を命令列とデータ列のみで抽象化可能な組み合わせとして以下の4通りを考えた

bull SISD(Single Instruction Single Data Stream)

bull SIMD(Single Instruction Multiple Data Stream)

bull MISD(Multiple Instruction Single Data Stream)

bull MIMD(Multiple Instruction Multiple Data Stream)

概念モデルなので適用するレベルによって分類が異なることもある命令列とデータ列の単位をどう解釈するかで分類が変わる

(例えばVLIWでは一つの長ワード命令に複数の命令が埋め込まれる)プロセッサのSIMD命令以外では最近あまり使われない

Flynnの分類(Flynnrsquos Taxonomy)

M J Flynn Very High-Speed Computing Systems Proceedings of IEEE Vol 54 1901-1909 1966

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 8: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 7

bull 共有記憶型システムはプロセッサの役割でさらに分類されるbull SMP(Symmetric Multi-Processing)

全プロセッサが同じ機能と権限を持ち特権的なプロセッサがない現在の共有記憶はほとんどこのタイプマルチコアCPUとメモリの場合もこのタイプと見なせる

bull AMP(Asymmetric Multi-Processing)

全体を制御するメインプロセッサとそれ以外で役割を分担80年代までは大型汎用機やPC(Fujitsu FM-8)の例があった現在ではGPUアクセラレータとCPUの組み合わせがこのタイプと見なせる

bull OSの管理が及ぶ範囲による分類bull 密結合(Tightly Coupled System)

1つのOSが管理する資源を複数のプロセッサが使用するSMPでは自然な選択となる

bull 疎結合(Loosely Coupled System)

プロセッサ毎にOSが存在し個別に資源を管理する分散記憶型では自然な選択となる

プロセッサとOSの関係

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 8

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

SMP AMP

密結合 疎結合

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

OS

me

mo

ry

core

CPU

core

CPU

core

CPU

core

CPU

OS OS OS OS

me

mo

ry

me

mo

ry

me

mo

ry

interconnect

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 9

相互結合網の方式は非常に多いここでは代表的なものだけ紹介

相互結合網(Interconnect)

バス同時にバスにアクセスできるのは1ノードだけ

n次元メッシュ隣接ノード間のみの通信平均ホップ数はradicN程度

n次元トーラス隣接ノード間のみの通信平均ホップ数はradicN程度

最大ホップ数はメッシュの半分

ファットツリーツリー結合で上位が太い平均ホップ数はlog2N程度

n次元ハイパーキューブ各ノードがn個のノードと結合平均ホップ数はlog2N程度

クロスバースイッチで動的結合1ホップでN対N通信

結線

ノード

スイッチON

スイッチOFF

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 10

並列計算機の最初期の分類法プロセッサの動作を命令列とデータ列のみで抽象化可能な組み合わせとして以下の4通りを考えた

bull SISD(Single Instruction Single Data Stream)

bull SIMD(Single Instruction Multiple Data Stream)

bull MISD(Multiple Instruction Single Data Stream)

bull MIMD(Multiple Instruction Multiple Data Stream)

概念モデルなので適用するレベルによって分類が異なることもある命令列とデータ列の単位をどう解釈するかで分類が変わる

(例えばVLIWでは一つの長ワード命令に複数の命令が埋め込まれる)プロセッサのSIMD命令以外では最近あまり使われない

Flynnの分類(Flynnrsquos Taxonomy)

M J Flynn Very High-Speed Computing Systems Proceedings of IEEE Vol 54 1901-1909 1966

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 9: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 8

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

SMP AMP

密結合 疎結合

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

memory

interconnect

core

CPU

core

CPU

core

CPU

core

CPU

OS

me

mo

ry

core

CPU

core

CPU

core

CPU

core

CPU

OS OS OS OS

me

mo

ry

me

mo

ry

me

mo

ry

interconnect

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 9

相互結合網の方式は非常に多いここでは代表的なものだけ紹介

相互結合網(Interconnect)

バス同時にバスにアクセスできるのは1ノードだけ

n次元メッシュ隣接ノード間のみの通信平均ホップ数はradicN程度

n次元トーラス隣接ノード間のみの通信平均ホップ数はradicN程度

最大ホップ数はメッシュの半分

ファットツリーツリー結合で上位が太い平均ホップ数はlog2N程度

n次元ハイパーキューブ各ノードがn個のノードと結合平均ホップ数はlog2N程度

クロスバースイッチで動的結合1ホップでN対N通信

結線

ノード

スイッチON

スイッチOFF

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 10

並列計算機の最初期の分類法プロセッサの動作を命令列とデータ列のみで抽象化可能な組み合わせとして以下の4通りを考えた

bull SISD(Single Instruction Single Data Stream)

bull SIMD(Single Instruction Multiple Data Stream)

bull MISD(Multiple Instruction Single Data Stream)

bull MIMD(Multiple Instruction Multiple Data Stream)

概念モデルなので適用するレベルによって分類が異なることもある命令列とデータ列の単位をどう解釈するかで分類が変わる

(例えばVLIWでは一つの長ワード命令に複数の命令が埋め込まれる)プロセッサのSIMD命令以外では最近あまり使われない

Flynnの分類(Flynnrsquos Taxonomy)

M J Flynn Very High-Speed Computing Systems Proceedings of IEEE Vol 54 1901-1909 1966

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 10: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 9

相互結合網の方式は非常に多いここでは代表的なものだけ紹介

相互結合網(Interconnect)

バス同時にバスにアクセスできるのは1ノードだけ

n次元メッシュ隣接ノード間のみの通信平均ホップ数はradicN程度

n次元トーラス隣接ノード間のみの通信平均ホップ数はradicN程度

最大ホップ数はメッシュの半分

ファットツリーツリー結合で上位が太い平均ホップ数はlog2N程度

n次元ハイパーキューブ各ノードがn個のノードと結合平均ホップ数はlog2N程度

クロスバースイッチで動的結合1ホップでN対N通信

結線

ノード

スイッチON

スイッチOFF

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 10

並列計算機の最初期の分類法プロセッサの動作を命令列とデータ列のみで抽象化可能な組み合わせとして以下の4通りを考えた

bull SISD(Single Instruction Single Data Stream)

bull SIMD(Single Instruction Multiple Data Stream)

bull MISD(Multiple Instruction Single Data Stream)

bull MIMD(Multiple Instruction Multiple Data Stream)

概念モデルなので適用するレベルによって分類が異なることもある命令列とデータ列の単位をどう解釈するかで分類が変わる

(例えばVLIWでは一つの長ワード命令に複数の命令が埋め込まれる)プロセッサのSIMD命令以外では最近あまり使われない

Flynnの分類(Flynnrsquos Taxonomy)

M J Flynn Very High-Speed Computing Systems Proceedings of IEEE Vol 54 1901-1909 1966

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 11: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 10

並列計算機の最初期の分類法プロセッサの動作を命令列とデータ列のみで抽象化可能な組み合わせとして以下の4通りを考えた

bull SISD(Single Instruction Single Data Stream)

bull SIMD(Single Instruction Multiple Data Stream)

bull MISD(Multiple Instruction Single Data Stream)

bull MIMD(Multiple Instruction Multiple Data Stream)

概念モデルなので適用するレベルによって分類が異なることもある命令列とデータ列の単位をどう解釈するかで分類が変わる

(例えばVLIWでは一つの長ワード命令に複数の命令が埋め込まれる)プロセッサのSIMD命令以外では最近あまり使われない

Flynnの分類(Flynnrsquos Taxonomy)

M J Flynn Very High-Speed Computing Systems Proceedings of IEEE Vol 54 1901-1909 1966

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 12: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 11

bull SPMD (Single Program Multiple Data stream)bull 全プロセッサは同一のプログラムを実行 (領域分割マスターワーカ)bull プロセッサ毎に異なるデータを処理

bull MPMD (Multiple Program Multiple Data stream)bull プロセッサ毎に異なったプログラムを実行 (大気‐海洋流体‐構造)bull プロセッサ毎に異なるデータを処理

プログラムの実行方法

PROG

DATA2

interconnect

PROG

DATA1

PROG

DATA0

interconnect

PROG

DATA0 DATA2

PROG

DATA1

PROG

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 13: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 12

主に2つの並列化方法が用いられる

bull データ並列 (Data Parallelism)bull 配列に対する処理を分割して並列に処理する

SPMDにおける処理の分割

int a[30] b[30]

a = a+b

for(i=0 ilt9 ++i)

a[i] = a[i] + b[i]processor 0

for(i=10 ilt19 ++i)

a[i] = a[i] + b[i]processor 1

for(i=20 ilt29 ++i)

a[i] = a[i] + b[i]Processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 14: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 13

bull タスク並列 (Task Parallelism)bull プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理

SMPの場合はデータ並列タスク並列はコンパイラが自動的に行うことが多い

後述するスレッド並列でもこれらの方法が中心であるが

その場合にはユーザが陽に指示行(directive)を書く必要がある

main ()

ProcedureA()ProcedureB()ProcedureC()

main ()

ProcedureA()

processor 0

main ()

ProcedureB()

processor 1

main ()

ProecdureC()

processor 2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 15: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 14

bull プロセス並列 (Process-level Parallelism)bull プロセスとは仮想的なCPUメモリファイルを持つOS内の実体bull OSはプロセス上でプログラムを実行するbull 同時に複数のプロセスを生成し実行できるbull プロセスはリモートOS上でも実行できる (ssh rsh)bull 相互結合網で接続したマシン上で複数プロセスを並列に実行

実行資源の共有状況

OS

Process

CPU

Memory

File

Program0

Process

CPU

Memory

File

Program1 OS

Process

CPU

Memory

File

Program2

OS

Process

CPU

Memory

File

Program3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 16: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 15

bull スレッド並列 (Thread-level Parallelism)bull スレッドとはプログラムから切り出した連続的な命令の列bull プロセス内で複数のスレッドを生成実行できるbull スレッドはプロセスのメモリファイルを共有するbull CPUコア毎にスレッドを1つ割り当てる場合が多い(Hyper-threadingでは1つのCPUコアに複数のスレッドを割り当てる)

bull 実際のプログラミングではOpenMPかpthreadを用いる

現在主流となっているハイブリッド並列化は

まず全体をプロセス並列化しさらにプロセス内をスレッド並列化する

OS

Process

Core

Memory

File

Program

Core Core Core

Thread0 Thread1 Thread2 Thread3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 17: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 16

bull メッセージ交換(Message Passing)送信と受信の両側で関数呼び出しbull PVM(Parallel Virtual Machine)

最初期の規格比較的単純な機能bull MPI-123(Message Passing Interface)

複合データ型や集団通信を提供

bull 直接メモリアクセス(Direct Memory Access)送信または受信の片側のみ関数呼び出しbull PGAS(Partitioned Global Address Space)

分散記憶型に単一アドレスを提供する通常は言語に組込まれている (UPC Chapel Coarray etc)ライブラリとしてOpenSHMEM(CrayT3Dのshmemのオープンソース版)やGASPIなどがある

bull MPI-23(Message Passing Interface)片側通信として提供されている単一アドレスは提供されない(ユーザ自身で実装することは可能)

通信ライブラリ内の手順

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 18: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 17

bull BSPモデル (Bulk Synchronous Parallel)bull 計算と通信をバリア同期で完全に分離するbull 通信は全プロセスが同時に行う

bull マスターワーカモデル (Master-worker Server-client)bull ワーカはマスタとだけマスタは全てのワーカと通信するbull 通信はマスタと一つのプロセスの間でランダムに行う

通信のスケジュール

Process0 comp comm comp comm comp comm

Process1 comp comm comp comm comp comm

Process2 comp comm comp comm comp comm

Process3 comp comm comp comm comp comm

barrier barrier barrier barrier barrier barrier

time

Master wait-loop comm wait-loop comm wait-loop comm

Worker1 comp comm comp

Worker2 comp comm comp

Worker3 comp comm

time

sendrecv

sendrecv

sendrecv

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 19: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 18

bull 現在の計算機システムは多層的かつ複合的bull ハードソフト両面において多様な評価軸で分類が可能bull 一つの評価軸で全てを分類するのは合理的ではないbull 評価軸の間には重複や例外が存在することも少なくない(カモノハシ蝙蝠)

大事なことは

bull 分類の基となる概念を良く理解するbull 自分が使うハードウェアや環境を概念的に捉えるbull 自分が解決すべき問題に適した手法を選択する

並列方式手法のまとめ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 20: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 19

MPIプログラミングの初歩

◼ MPIについて 特徴

MPI Standard

MPIライブラリ

バージョンの変遷

提供される機能

◼ プログラムの実行 簡単なプログラムの実行例

例題1 数値積分(円周率の計算)

例題2 差分法(ソリトンの伝播)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 21: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 20

bull 並列化に関する関数などのAPI(Application Programming Interface)レベルの規格であり実体はライブラリ形式で提供される

bull プロセス並列モデルを前提とする

bull プロセス間のメッセージ交換に関する標準仕様

bull プログラム実行方法はSPMDモデル

bull プロセス並列でありさえすれば分散記憶共有記憶SMPAMP密結合疎結合といった方式の違いは問わない

bull 但しアドレス空間はプロセス毎の分散アドレス

bull ネットワーク接続された異機種クラスター環境にも対応

bull 先行したPVM(Parallel Virtual Machine)に不足していた機能(ユーザ定義型集団通信等)を採り入れている

bull 最新版では一部限定的だが直接メモリアクセスMPMDスレッド並列モデルの機能も提供されている

特徴

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 22: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 21

bull MPI Forumが発行する規格書

bull 全ての基準となる最も重要な文献

bull 最新版はversion31現在40へ向け改訂作業中

bull MPI Standardに準拠して開発される

bull オープンソフトから商用ソフトまで多数bull OpenMPI 最もユーザ数が多い

bull MPICH Forum中心メンバーが開発現在でも人気

bull MVAPICH GPUに強いと謂われる

bull CRAY-MPI Intel-MPI Fujitsu-MPI HP-MPI etc

bull ライブラリによって性能の違いやバグがある

MPI Standard

httpmpi-forumorgdocsmpi-31mpi31-reportpdf

MPI Forum = 大学研究機関ベンダーから構成されるボランティアベースの協議会MPICH is pronounced ldquoEm Pee Eye See Aychrdquo not ldquoEmm Pitchrdquo Using MPI 2nd ed p329

MPIライブラリ

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 23: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 22

バージョンの変遷

10May lsquo94

11Jun lsquo95

12Jul lsquo97

13May lsquo08

20Jul lsquo97

21Jun lsquo08

22Sep lsquo09

30Sep lsquo12

31Jun lsquo15

Point to Point CommunicationDatatypesCollective CommunicationProcess Topology

One-Sided CommunicationsParallel IOProcess Creation

Nonblocking CollectivesEnhancement in One-Sided CommEnhancement in Process TopologyTool Information Interface

Distributed Graph

Topology

Final

version

Minor Changes or

Error Corrections

40

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 24: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 23

bull 要素通信(Point-to-Point Communication)

bull データ型(Datatype)

bull 集団通信(Collective Communication)

bull コミュニーケータ(Groups Contexts Communicators and Cashing)

bull プロセストポロジー(Process Topologies)

bull 環境の管理(MPI Environmental Management)

bull 情報オブジェクト(The Info Object)

bull プロセスの生成と管理(Process Creation and Management)

bull 片側通信(One-Sided Communications)

bull 外部インターフェース(External Interface)

bull ファイル入出力(IO)

bull ツール支援(Tool Support)

提供される機能 (MPI Standard 31)

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 25: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 24

bull SPMDモデルの最も簡単なプログラム helloc

bull このプログラムを2つのプロセスで実行する

簡単なプログラムの実行例

1 include ltstdiohgt2 include ldquompihrdquo3 4 int main( int argc char argv[] )5 6 int size rank7 MPI_Init( ampargc ampargv )8 MPI_Comm_size( MPI_COMM_WORLD ampsize ) 9 MPI_Comm_rank( MPI_COMM_WORLD amprank )10 printf( ldquoHello World I am d of dyennrdquo rank size )11 MPI_Finalize()12 return 013

helloc

関数や定数の定義

引数は省略可能

$ mpicc ndasho hello helloc$ mpiexec ndashn 2 helloHello World I am 0 of 2Hello World I am 1 of 2$

mpirun ndashnp 2 hello でも可

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 26: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 25

bull 使用した関数定数コマンドの説明

bull 関数int MPI_Init(int argc char argv)

MPI関数の使用を開始する(これ以前にMPI関数は呼べない)

int MPI_Finalize(void)

MPI関数の使用を終了する(これ以降はMPI関数を呼べない)

int MPI_Comm_size(MPI_Comm comm int size)

コミュニーケータcomm内に存在するプロセス数をsizeに返す

int MPI_Comm_rank(MPI_Comm comm int rank)

コミュニーケータcomm内での自プロセスのID番号をrankに返す

(rankの値は0からsize-1までの何れかの整数)

bull 定数

MPI_COMM_WORLD 全てのプロセスを含む集合

bull コマンド

mpicc C言語で書いたMPIプログラム用のコンパイラリンカ

mpiexec コンパイルしたMPIプログラムを並列実行するためのコマンド

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 27: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 26

bull 問題 を数値的に求める

bull 計算方法 台形近似

bull 関数 とx軸との間の面積を台形で近似でする

bull 下図の着色部に台形近似を適用すると面積は右の式となる

bull x軸の分割を細かくすると真の値に近づく

例題1 数値積分(円周率の計算)

නminus1

1 2

1 + 1199092119889119909 = 120587

119891(119909)

න119891 119909 119889119909 cong

119894

1

2119891119894+1 + 119891119894 119909119894+1 minus 119909119894

119909119894 119909119894+1

119891119894+1

119891119894

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 28: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 27

bull 並列化手法 データ並列

bull 全てのプロセスにx軸のコピーを持たせる

bull 分割した小領域を各プロセスで分担して計算する(データ並列)

bull 担当する場所はサイクリックとする(下図参照)

bull 計算した値をルートプロセスに集めて加算する(BSPモデル)

1199090= -1 11990919 = 1

全領域(-1ltxlt1)をN個(上図では20)に分割し4プロセスで並列実行する場合

1199090 11990919

process 0

process 1

process 2

process 3

1199090 11990919

process 0

MPI_Reduce

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 29: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 28

1112 if( rank==0 )13 14 printf( ldquoEnter the number of intervalsyennrdquo )15 err = scanf( ldquodrdquo ampn )16 17 MPI_Bcast( ampn 1 MPI_INT 0 MPI_COMM_WORLD )18 const double h = 20n19 20 double sum = 00 pi = 0021 for( int i=rank iltn i+=size ) 22 23 const double x0 = i h ndash 1024 const double x1 = (i+1)h ndash 1025 const double f0 = 20 ( 10 + x0x0 )26 const double f1 = 20 ( 10 + x1x1 )27 sum += 05( f0 + f1 )( x1 ndash x0 )28 29 MPI_Reduce( ampsum amppi 1 MPI_DOUBLE MPI_SUM 0 MPI_COMM_WORLD )30 31 if( rank==0 )32 printf( ldquopi is approximately 16fyennrdquo pi )33

trapezoidc

台形近似

通信

データ並列

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 30: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 29

bull 前頁はプログラム主要部プログラムの動作内容は以下の通り(表示していない前後の部分はhellocと同じ)

bull 11~15行目でルートプロセスが分割数nを読み込む

bull 16行目で全てのプロセスにnを送信する

bull 20~27行目で各プロセスは短冊部をsize個おきに計算し部分和を求める

bull 28行目で部分和をルートプロセスに集めて総和をとる

bull 30~31行目でルートプロセスが結果を画面に表示する

bull 実行例

$ mpicc ndasho trapeziod trapezoidc$ mpiexec ndashn 8 trapezoidEnter the number of intervals10000pi is approximately 31415926469231241 $

intervals pi100 314152598692325351000 3141591986923126410000 31415926469231241100000 314159265352313091000000 31415926535891256

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 31: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 30

bull 使用した関数データ型演算の説明

bull 関数int MPI_Bcast(void buffer int count MPI_Datatype datatype

int root MPI_Comm comm)

ルートプロセスrootからコミュニーケータcomm内に存在するすべてのプロセスにdatatype型の値をcount個送信する

int MPI_Reduce(const void sendbuf void recvbuf int count MPI_Datatype datatype MPI_Op op int rootMPI_Comm comm)

コミュニーケータcomm内に存在するすべてのプロセスのsendbufから始まるdatatype型の値count個に演算opを施しルートプロセスrootのrecvbufから始まる場所に格納する

bull データ型演算MPI_INT 整数型MPI_DOUBLE 倍精度実数型MPI_SUM 加算

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 32: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 31

bull MPI_BcastとMPI_Reduceの通信動作

bull MPI_Bcast(ampn 1 MPI_INT 0 hellip )

ポインタampnから始まる1つの整数をプロセス0からその他のプロセスに送る

MPI_COMM_WORLD

P0

P3P1

P2

n

nn

n

bull MPI_Reduce(ampn ampm 1 MPI_INT MPI_SUM 0 hellip)

ポインタampnから始まる1つの整数をプロセス0以外からプロセス0に送り

総和を計算しampmに格納する

MPI_COMM_WORLD

P0

P3P1

P2

m=Σn

nn

n

n

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 33: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 32

bull ソリトン 衝突しても形の変わらない波 (孤立波)

bull KdV方程式 ソリトン解をもつ代表的な方程式bull 移流方程式に3次の分散項を加えたもの

bull パラメータδが0の時に移流方程式となる

bull 計算方法 Zabusky-Kruskalスキームbull KdV方程式を差分法で近似する

bull 移流速度を3点で平均した時間空間中心差分

bull 一点の計算に時間3点(n+1 n n-1)空間5点(i+2 i+1 i i-1 i-2)が必要

bull 初期条件

bull その他

例題2 差分法(ソリトンの伝播)

120597119905119906 + 119906120597119909119906 + 1205752120597119909119909119909119906 = 0

119906119894119899+1 minus 119906119894

119899minus1

2∆119905+1

3119906119894+1119899 + 119906119894

119899 + 119906119894minus1119899 119906119894+1

119899 minus 119906119894minus1119899

2∆119909+ 1205752

119906119894+2119899 minus 2119906119894+1

119899 + 2119906119894minus1119899 minus 119906119894minus2

119899

2∆1199093= 0

KdV Korteweg de Vries

Zabusky Kruskal Phys Rev Lett v15(6) p240 1965

1199060 119909 = 119888119900119904 120587119909 0 le 119909 le 2

120575 = 0022 CFL = 01

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 34: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 33

bull 時間と空間の離散化

bull を時間間隔 空間間隔 の点上の値だけで近似する(離散化)

bull 時間の位置を 空間の位置を で表す

bull 黄点の計算には赤点と青点のデータが必要

bull 計算を進めるには左右の外側に境界条件の設定が必要

bull ここでは周期境界条件を課す(右端と左端をつなげる)

∆119909∆119905119906

119899 119894

∆119909

∆119905

119909

119905n+2

n+1

n

n-1

n-2i-2 i-1 i i+1 i+2i-3 i+3

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 35: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 34

bull 並列化手法 領域分割

bull 準備(図左)

x軸を部分領域に分割する

各プロセスは一つの分領域のみ担当する

bull 計算手順(図右)

1)隣接する左右のプロセスから境界データをもらう

2)担当領域内でZabusky-Kruskalスキームを実行する

3)予め設定した計算時間に達したら終了

4)1)へ戻る

空間格子100点を4プロセスで並列実行する場合

1199090 11990999

ξ0 ξ24

領域分割

process 0 process 1 process 2 process 3

ξ0 ξ24 ξ0 ξ24 ξ0 ξ24

注 各プロセス内は分散アドレスとなる

computational domainprocess 0 process 1 process 2 process 3

隣接通信

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 36: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 35

72 ghost exchange73 MPI_Sendrecv( amp(ue[NN ]) 2 type right 0 74 amp(ue[ 0]) 2 type left 0 comm stat )75 MPI_Sendrecv( amp(ue[ 2]) 2 type left 0 76 amp(ue[NN+2]) 2 type right 0 comm stat )77 78 even steps79 for(int i=2 iltNN+2 ++i) 80 uo[i] += -coef1( ue[i+1] + ue[i] + ue[i-1] )( ue[i+1] ndash ue[i-1] )81 -coef2( ue[i+2] ndash 20ue[i+1] + 20ue[i-1] + ue[i-2] )82 83 ghost exchange 84 MPI_Sendrecv( amp(uo[NN ]) 2 type right 0 85 amp(uo[ 0]) 2 type left 0 comm stat )86 MPI_Sendrecv( amp(uo[ 2]) 2 type left 0 87 amp(uo[NN+2]) 2 type right 0 comm stat )88 89 odd steps90 for(int i=2 iltNN+2 ++i)91 ue[i] += -coef1( uo[i+1] + uo[i] + uo[i-1] )( uo[i+1] ndash uo[i-1] )92 -coef2( uo[i+2] ndash 20uo[i+1] + 20uo[i-1] + uo[i-2] )93

KdVc

隣接通信

隣接通信

Zabusky-Kruskal

Zabusky-Kruskal

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 37: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 36

bull 前頁は通信と計算の部分のみプログラムの動作内容は以下の通り

bull 下図のようなプログラムではメモリコピーが発生し効率が悪いこれを避けるためにnの偶奇で分けて処理する

bull 73~81行目はnが偶数の時の処理

73~74行目で図の青色の通信を行う

75~76行目で図の橙色の通信を行う

79~81行目でZabusky-Kruskalの計算を行う

bull 84~92行目はnが奇数の時の処理

84~85行目で図の青色の通信を行う

86~87行目で図の橙色の通信を行う

90~92行目でZabusky-Kruskalの計算を行う

for(int i=2 iltNN+2 ++i) new[i] = old[i] - coef1( u[i+1] + u[i] + u[i-1] )( u[i+1] ndash u[i-1] )

- coef2( u[i+2] ndash 20u[i+1] + 20u[i-1] + u[i-2] )

for(int i=2 iltNN+2 ++i) old[i] = u[i] u[i] = new[i]

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 38: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 37

bull 使用した関数の説明

bull 関数int MPI_Sendrecv(void sendbuf

int sendcount MPI_Datatype sendtype

int dest int sendtag void recvbuf int recvcount

MPI_Datatype recvtype int source int recvtag

MPI_Comm comm MPI_Status status)

sendbufから始まるsendcount個のsendtype型データをプロセスdestに送信 recvbufから始まるrecvcount個のrecvtype型データをプロセスsourceから受信送信データにはsendtagをつけ受信データはrecvtagが付いたものだけ受けとる一回の送信と一回の受信を一つの関数で実現する(デッドロック回避に有効)

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 39: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 38

bull ファイルには書式付き(テキスト)と書式無し(バイナリ)がある

bull 書式付きファイルは通常のエディタ(vim emacs等)で読み書きできる

bull 書式無しファイルを読むには専用のプログラムを作る必要がある(データ形式は書いた人にしか判らない)

bull 書式無しの方が高速に読み書き可能

bull MPIでは書式無しファイルのみ利用可能

bull さらに分散ファイルと単一ファイルの二種類がある

bull 分散ファイルではプロセス毎に専用のファイルを使う

bull 分散ファイルはプログラミングが容易だがファイル数が多くなり取扱い煩瑣

bull 単一ファイルでは全プロセスが一つのファイルを読み書きする

bull 単一ファイルはプログラミングは面倒で巨大ファイルになるが取扱い容易

bull サンプルプログラムは単一ファイルの書式付きと書式無しの例

bull 6行目のdefine文でMPI_IOが有効の時は書式無し無効で書式付き

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 40: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 39

bull 書式付き単一ファイルの場合

51 File fp5253 double buf54 if( rank==0 )55 56 fp = fopen( ldquosolitontxtrdquo rdquowtrdquo )57 buf = (double )malloc( Nsizeof(double) )58

100 MPI_Gather( amp(ue[2]) NN type buf NN type 0 comm )101 if( rank==0 )102 103 fprintf( fh rdquon=d yennrdquo n )104 for(int i=0 iltN ++i) fprintf( fp rdquo63lf rdquo buf[i] )105 frpintf( fp rdquo yennrdquo )106

114 if( rank==0 ) flose( fp )

KdVc

データ収集

ファイルへの書き込み

ファイル終了

ファイル初期化

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 41: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 40

bull プログラムの動作内容は以下の通り

bull 56行目でルートプロセスのみファイルを開く

bull 57行目でルートプロセスのみデータ受信用バッファを割り当てる

bull 100行目で各プロセスのデータをルートプロセスに集める

bull 104行目で集めたデータをルートプロセスがファイルに書き込む

bull 114行目でルートプロセスのみファイルを閉じる

bull 使用した関数の説明bull 関数

int MPI_Gather(void sendbuf int sendcount

MPI_Datatype sendtype void recvbuf int recvcount

MPI_Datatype recvtype int root

MPI_Comm comm)

sendbufから始まるsendcount個のsendtype型データをルートrootへ送信 recvbufから始まるrecvcount個のrecvtype型データとしてルートrootが受信ルートは表面上は自分自身に送信することになるが問題は無い

送信情報

受信情報

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 42: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 41

bull 書式無し単一ファイルの場合

35 MPI_Datatype type = MPI_DOUBLE

39 MPI_Info info = MPI_INFO_NULL40 MPI_Offset disp = NNsizeof(type)rank41 const int amode = MPI_MODE_CREATE | MPI_MODE_WRONLY4243 MPI_Datatype localdata filetype44 MPI_Type_contiguous( NN type amplocaldata )45 MPI_Type_create_resized( localdata 0 Nsizeof(type) ampfiletype )46 MPI_Type_commit( ampfiletype )47 MPI_File fh48 MPI_File_open( comm ldquosolitonbinrdquo amode info ampfh )49 MPI_File_set_view( fh disp type filetype ldquonativerdquo info )

98 MPI_File_write_all( fh amp(ue[2]) NN type stat )

112 MPI_File_close( ampfh )

KdVc

ファイル形式の定義

定数

ファイルへの書き込み

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 43: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 42

bull プログラムの動作内容は以下の通り

bull 40行目でプロセス毎に書き込み開始位置を設定する

bull 41行目でファイルの属性を設定する(新規作成書き込み専用)

bull 44行目でプロセス毎の連続データを定義しlocaldata型とする

bull 45行目で連続データの間にギャップを挟んだfiletype型を定義する

bull 46行目でfiletype型を登録する

bull 48行目でsolitonbinという名前のファイルを記述子fhとして開く

bull 49行目でプロセス毎にfhのファイルビューを設定する

bull 98行目で全てのプロセスが連続データをファイルに書き込む

bull 112行目でファイルを閉じる

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 44: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 43

bull ファイルビューについて

bull プロセス毎のファイル書き込み可能領域

bull ファイル先頭からdispバイト後に置かれるfiletypeの繰り返し

bull filetypeはetype(char int float etc)の列と空白領域を含む

etype filetype

fileview (case2)

fileview (case1)disp

proc0

proc1

proc2

disp

proc0

proc1

proc2

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 45: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 44

bull 使用した関数の説明

bull 関数

int MPI_Type_contiguous(int count MPI_Datatype oldtype MPI_Datatype newtype)

count個のoldtype型からnewtype型を作る

int MPI_Type_create_resized(MPI_Datatype oldtype MPI_Aint lb MPI_Aint extent MPI_Datatype newtype)

下からlbバイトの位置にoldtypeを置いたextentバイトのnewtype型を作る

int MPI_Type_commit(MPI_Datatype datatype)

通信に使えるようdatatypeを登録する

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

oldtype newtypecount=5 の場合

oldtype newtypelb=8 extent=32 の場合

8bytes

32bytes

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 46: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 45

bull 関数int MPI_File_open(MPI_Comm comm const char filename int amode

MPI_Info info MPI_File fh)

コミュニーケータcomm内に名前がfilenameで属性amodeを持つファイルを開きファイル記述子fhを返す

int MPI_File_set_view(MPI_File fh MPI_Offset disp MPI_Datatype etype MPI_Datatype filetype const char datarep MPI_Info info)

記述子fhのファイルにデータ型etypeを書き込むファイルビューを設定する

int MPI_File_write_all(MPI_File fh void buf int count MPI_Datatype datatype MPI_Status status)

bufから始まるcount個のdatatype型の値を記述子fhのファイルに書き込みstatusを返す

int MPI_File_close(MPI_File fh)

記述子fhのファイルを閉じる

注 本講習では引数の色は変数の属性を示し入力出力入出力を表す

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 47: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 46

並列プログラミング入門(MPI編)はこれで終了です

お疲れ様でした

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)

Page 48: 並列プログラミング入門( 編) · •プログラムを相互に依存性のない複数の部分(タスク)に分割し並列に処理 smpの場合はデータ並列・タスク並列はコンパイラが自動的に行うことが多い

Copyright 2018 RIST平成30年度 第3回HPCプログラミングセミナー 並列プログラミング入門(MPI編) 47

      2018年11月

一般財団法人 高度情報科学技術研究機構(著作者)

本資料を教育目的等で利用いただいて構いません利用に際しては以下の点に留意いただくとともに下記のヘルプデスクにお問い合わせ下さい

◼ 本資料は構成文章画像などの全てにおいて著作権法上の保護を受けています

◼ 本資料の一部あるいは全部についていかなる方法においても無断での転載複製を禁じます

◼ 本資料に記載された内容などは予告なく変更される場合があります◼ 本資料に起因して使用者に直接または間接的損害が生じても著作者

はいかなる責任も負わないものとします

問い合わせ先ヘルプデスク helpdesk[-at-]hpci-officejp ([-at-]をにしてください)