MatsuLab. Lecture Note/sougouenshu2006

TSUBAMEを使って並列プログラミングをしよう

担当:滝澤<takizawa@matsulab.is.titech.ac.jp>
時間:月 13:20 - 15:00  木 15:00 - 16:30

目次

スケジュール

進捗によって変わると思います。

  • 10/16
    • C言語とMPIの簡単な課題の説明
  • 10/19
    • 松岡先生から研究室の説明
  • 10/23
    • 予備日
  • 10/26
    • C言語とMPIの課題のチェック
    • スパコンコンテスト課題の説明
  • 10/31
    • 予備日
  • 11/2
    • 松岡先生から研究室の説明
  • 11/6
    • 予備日
  • 11/9
    • スパコンコンテスト課題のチェック

「予備日」は研究室に来なくてもよい。担当TAは研究室に在室するので質問等あったら訪ねてください。また、この日に実習室で課題を解くのであれば、必要ならサポートに行きます。

講義内容

Cの基礎課題

行列とベクトルの掛け算を行うプログラムを書きなさい。行列のサイズ、ベクトルのサイズはプログラムの引数から取得し、実行時に必要なメモリを確保すること。 また、行列、ベクトルの要素を生成するときに、乱数を用いてランダムな値で初期化するために、プログラムの引数には乱数のシードも取ること。

例えば、以下のように3つの引数を取ればよい。

$ ./serial 乱数シード 行列の行数 行列の列数(ベクトルの要素数)

行列、ベクトルの要素の生成ルーチンをまとめたライブラリのソースを松岡研PCクラスタ上の次の場所に置いた。

/home/takizawa/array_gen.h
/home/takizawa/array_gen.c

このファイル内には以下の1つの関数が用意されている。

  • void array_gen_init(int seed)
    • 引数に乱数生成時のシードを取る
    • プログラム中、1度だけ実行する
  • void create_random_array(int *array, int size)
    • 第1引数で与えられたINT型のポインタが指すアドレスから、第2引数個分の領域に0〜9のランダムな数を入れる。
    • 関数実行後、arrayが初期化されている。

以下のように使うこと。

#include "array_gen.h"

int seed, *matrix, matrix_len;
・・・
array_gen_init(seed);
matrix = (int *)malloc(・・・);
create_random_array(matrix, matrix_len);
・・・
free(matrix);

メインプログラムを「serial.c」とした場合、次のようにコンパイルすれば、実行ファイル「serial」が出来上がる。

$ gcc -c array_gen.c
$ gcc -c -Wall serial.c
$ gcc -o serial serial.o array_gen.o
$ rm serial.o array_gen.o      <- 必要ないなら削除してかまわない

ヒント&注意

  • 行列のメモリ領域は1つの連続的な領域として確保すること。すなわち、以下のように確保すること。
    int *matrix = (int *)malloc(行数 * 列数)
  • 計算結果のオーバーフローは考慮しなくてよい。
  • メモリ管理が必要であること以外はJavaと同じように記述できるはず。
  • 以下のCの関数が参考になるかもしれない。使い方はWEBで検索か、ターミナルで「man 関数名」と打って調べること。
    atoi
    free
    malloc
    printf

MPIの基礎課題

「Cの基礎課題」のプログラムをMPIを使って並列化する。 このとき、行列の分割は、「全てのプロセスが同じ数の要素を処理する」ように分割するのでかまわない。 すなわち、16x16行列が与えられ、2プロセスで計算する場合には、各プロセスは行列中の8x16個の要素の計算を行う。4プロセスで計算する場合には4x16個、8プロセスで計算する場合には2x16個の要素を計算する。

この場合、行列の要素数は使用プロセス数で割り切れる必要がある。 余裕があれば、任意のプロセス数で処理できるようにプログラムを修正すること(自由)。

メインプログラムを「mpi.c」とした場合、次のようにコンパイルすれば、実行ファイル「mpi」が出来上がる。

$ gcc -c array_gen.c
$ mpicc -c -Wall mpi.c
$ mpicc -o mpi mpi.o array_gen.o
$ rm mpi.o array_gen.o      <- 必要ないなら削除してかまわない

以下のように実行できるようにすること。

$ mpirun -np 4 -machinefile machines -nolocal ./mpi 乱数シード 行列の行数 行列の列数

ヒント&注意

  • MPIについては参考文献の1や2、3を参考にするとよい。
  • 行列データ、ベクトルデータの生成は1プロセス上でのみ行い、そのプロセスがMPI関数を使用して他のプロセスに配ること。
  • 最後に各プロセスが計算した結果を1つのプロセスに集めること。
  • 実際、MPI_SendとMPI_Recvだけで実装できてしまう(通信関数に関しては)。しかし、集団通信関数を使うことにより、よりスマートに実装でき、実行効率も良くなる。
  • 集団通信関数は、以下の3つを参考に。
    MPI_Bcast
    MPI_Gather
    MPI_Scatter
  • さらに、任意個のプロセスで実行できるようにするときには、以下の関数を使用するとよい。
    MPI_Gatherv
    MPI_Scatterv

スパコンコンテスト課題

課題(PDF)

課題を解くために必要なファイルをPrestoIIIの以下の場所に置いた。 各自cpコマンドを用いて自分のホームディレクトリにコピーすること。

/home/takizawa/sougouenshu/

このディレクトリには以下のファイルが置かれている。

  • sc06.c & sc06.h
    • コンテスト問題用のルーチンが定義されているファイル。使い方はprogrule.htmlを参考
    • ここで定義されているルーチン自体MPIを使って書かれているので、演習室のMACで使用することはできない
  • matrix/*.mat
    • サンプル行列データとコンテストで用いた行列データ
  • progrule.html
    • コンテスト用のプログラム作成ルールが記述されているファイル。sc06.c & sc06.hの使用方法も書かれている
  • slide.ppt
    • 渡辺先生がコンテストの説明用に作成したスライド

progrule.htmlとslide.pptはPrestoIII上では閲覧できない。 scpコマンドを用いてコピーすること(下記のコマンドをMAC上で実行)。

$ scp eugs0X@nimbus.titech.hpcc.jp:/home/takizawa/sougouenshu/FILE_NAME .

コンパイル方法

$ mpicc -c sc06.c
$ mpicc -c YOUR_FILE.c
$ mpicc -o scon sc06.o YOUR_FILE.o

ヒント&注意

  • 今回もシングルプロセスで動くものを作ってから並列化するとラク
  • スパコンコンテストでは44x16CPU Coreを使っている。今回の講義ではそんなに多くのCPUを使うことはできないので(使えて32CPU程度)、コンテスト結果よりも悪くても気にしない
    • 実は優勝者は1CPUしか使わなかった、という話もあるが

課題の進め方

その1

  • 演習室MACでプログラムを編集
  • scpコマンドでプログラムを実行環境(PrestoIIIクラスタ、TSUBAME)にリモートコピー
  • sshコマンドで実行環境にログイン
  • 実行環境でプログラムをコンパイル&実行

その2

  • sshコマンドで実行環境にログイン
  • 実行環境上でviやemacs( -nw)などでプログラムを編集、コンパイル&実行

松岡研PCクラスタ PrestoIII の使い方

  • ログイン
    1. ログインノードnimbus.titech.hpcc.jpへログイン
      $ ssh -l USERNAME nimbus.titech.hpcc.jp
    2. 実行マシンへログイン
      $ rsh pad018.titech.hpcc.jp
  • リモートコピー
    • 使用端末(演習室のMACなど)から以下のコマンド
      $ scp mpi.c USERNAME@nimbus.titech.hpcc.jp:
  • 使用するマシン
    • 18台
    • /home/eugs0X/sougouenshu/machinesファイルを参考に
    • 使用するMPIはMPICH

TSUBAMEの使い方

TSUBAMEでは「バッチキューイングシステム」が使われている。 バッチキューイングシステムでは、ユーザはジョブ(今回の場合はMPIアプリケーション)を「キュー」と呼ばれる計算機の集合に投げる。 バッチキューイングシステムは、キュー内の計算機に空きができ、ジョブの要求を満たす数の計算機が確保できたらジョブを実行する。

ログイン

  • login.cc.titech.ac.jpにssh
    $ ssh -l YOUR_NAME login.cc.titech.ac.jp
  • ログイン後、自動的にインタラクティブノード(tgg075001〜tgg075004)のどれか1つにフォワードされる
  • インタラクティブノードは4台しかないが、その上でアプリケーションを自由に実行できる。ただし、あまり重たい処理を実行すると、他のユーザに迷惑をかげるので避けること。重たい処理、時間のかかる処理をする場合にはバッチキューイングシステムを使うこと。 リモートコピー
  • 各自のコンピュータ(MAC)から手元のファイルをTSUBAMEにコピー
    $ scp YOUR_FILE YOUR_NAME@login.cc.titech.ac.jp:

プログラムのコンパイル

  • インタラクティブノードで行う。gcc、mpiccが利用可能。ただしmpiccで利用できるオプションが異なる(少なくとも-Wallは使えない)。
    $ mpicc -c sc06.c
    $ mpicc -o scon.c
    $ mpicc -o scon scon.o sc06.o

インタラクティブノード上でのプログラムの実行

  • 通常通りmpirunを使う。「-machinefile」、「-nolocal」オプションは付けない
    $ mpirun -np 4 ./PROG_NAME

バッチキューイングシステムを用いたプログラムの実行

  • ジョブ投入
    $ n1ge -N JOB_NAME -q default -mpi 4:2 ./PROG_NAME
    • -N JOB_NAMEはキューに登録する際のジョブの名前。指定しないと、適当な数字が割り当てられる
    • -q default
      • 使用するキューを指定。今回は「default」キューと「high」キューを使用する。キューで使用されるコンピュータは参考文献7を参照
    • -mpi 4:2
      • MPIアプリケーションを実行することを表す。「-mpi 」の後ろの「n:m」は、nが使用する総プロセッサ数、mが1マシンあたりのプロセッサ数。mの最大値は16。n、mにあまり大きな値を入れると実行開始されるまでに時間がかかる。
    • PROG_NAME
      • アプリケーション実行ファイル。パスで指定する
    • このコマンドはすぐに実行が終わる。バックグラウンドでジョブが実行される。
    • 以下のように出力されたらOK。
      stakizaw@tgg075003:/home0/usr1/stakizaw> n1ge -N bcast.4 -q default -mpi 4:2 ./bcast
      *n1ge> Number of CPUs for each node => 2
      *n1ge> Total number of CPUs => 4
      *n1ge> Checking which tool have the command you specified....
      *n1ge> Reading specific configuration file for each tools....
      *n1ge> Creating qsub options....
      *n1ge> Submitting Job to Cluster......
      Your job 340322 ("bcast.4") has been submitted
    • コマンド実行完了後、コマンドを実行したディレクトリに「JOB_NAME.oNUM」、「JOB_NAME.poNUM」という形式の2つのファイルができる。例えば、上のコマンドの場合次のように生成される。
      bcast.4.o340322
      bcast.4.po340322
      • JOB_NAME.oNUMはジョブの画面への出力(標準出力)をファイルに落としたもの
      • JOB_NAME.poNUMはジョブの情報。開始時刻、使用したコンピュータの情報、終了時刻など
  • ジョブ実行状況の確認
    $ qstat -u USER_NAME
    • 指定したユーザのジョブの状況を確認できる
      stakizaw@tgg075003:/home0/usr1/stakizaw> qstat -u stakizaw
      job-ID  prior   name       user         state submit/start at     queue                          slots ja-task-ID 
      -----------------------------------------------------------------------------------------------------------------
      340258 0.50500 LOGIN      stakizaw     r     10/30/2006 14:17:39 interactive@tgg075003              1        
      340413 0.00000 bcast.4    stakizaw     qw    10/30/2006 15:25:08                                    4        
      • 「r」stateは実行中を表し、「qw」stateは実行待ちを表す
  • ジョブの削除
    $ qdel JOB_ID
    • JOB_IDはqstatの出力の第1要素のjob-ID
    • 終了を待たずにジョブを中断する場合や、実行開始されないジョブをキューから削除する場合に用いる

参考文献(URL)

  1. MPIによる並列プログラミングの基礎(PDF)
  2. MPI-1.1 Document(PDF)
  3. MPI Routines
  4. TSUBAME概要
  5. TSUBAME
  6. TSUBAME利用の手引き(PDF)
  7. 11月からの課金に向けたN1GE変更点について(PDF)

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-05-29 (火) 19:12:57 (2358d)