Created
October 10, 2016 03:22
-
-
Save k3kaimu/3239a0839d3f6a456e7cd4f8adcc26c8 to your computer and use it in GitHub Desktop.
TUTのHPCクラスタマシンでぶん回すコード
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.algorithm; | |
import std.datetime; | |
import std.range; | |
import std.stdio; | |
import std.typecons; | |
import tuthpc.mpi; | |
import tuthpc.taskqueue; | |
void main() | |
{ | |
// 第1引数はノード数 | |
// 第2引数はノード当たりの起動プロセス数 | |
jobRun(4, 20, { | |
// スケジューラ | |
auto scheduler = new MPITaskScheduler(); | |
foreach(i; 0 .. 10){ | |
// 全プロセスで並列に100個の数字を表示する | |
// 80ノードに対して100個の値は自動で割り振られる | |
scheduler.run!(a => writeln(a[0], a[1]))(iota(100*i, 100*(i+1)).zip(repeat("times."))); | |
} | |
// 複数の関数を各ノードで手分けしたい場合 | |
// 例では,四則演算を10回ずつするタスク(計40タスク)を並列実行する | |
auto list = new MultiTaskList; | |
foreach(i; 0 .. 10) list.append((int a, int b) => writefln("%s + %s = %s", a, b, a + b), i, i*2); | |
foreach(i; 0 .. 10) list.append((int a, int b) => writefln("%s - %s = %s", a, b, a - b), i, i*2); | |
foreach(i; 0 .. 10) list.append((int a, int b) => writefln("%s * %s = %s", a, b, a * b), i, i*2); | |
foreach(i; 1 .. 11) list.append((int a, int b) => writefln("%s / %s = %s", b, a, b / a), i, i*2); | |
// スケジューラでlistに入っているタスクを並列実行する | |
scheduler.run(list); | |
}); | |
// 第2引数に0を指定すると,自動で最大プロセス数が選択される(wdev=20, cdev=16) | |
jobRun(1, 0, { | |
auto scheduler = new MPITaskScheduler(); | |
ulong serialMSec; | |
if(scheduler.environment.isMaster){ | |
// Masterプロセスとは,Workerプロセスにタスクを割り振るプロセス | |
writeln("I am a master process."); | |
StopWatch sw; | |
sw.start(); | |
size_t cnt; | |
foreach(i; 0 .. 1000*1000*30) | |
if(isPrime(i)) | |
++cnt; | |
writeln(cnt); | |
sw.stop(); | |
writeln("Serial Time: ", sw.peek.msecs, " [ms]"); | |
serialMSec = sw.peek.msecs; | |
}else{ | |
// Workerプロセスとは,Masterプロセスから渡されたタスクを実行するプロセス | |
writeln("I am a worker process."); | |
} | |
// 全プロセスでBarrierが呼ばれるまで,全プロセス待つ | |
scheduler.communicator.barrier(); | |
StopWatch sw; | |
if(scheduler.environment.isMaster) sw.start(); | |
ulong res; | |
scheduler.run!((a, p){ *p += iota(a[0], a[1]).map!isPrime.count!"a"(); })( | |
iota(0, 300).map!(a => tuple(a*100_000, (a+1)*100_000)), | |
&res // 第1引数はMasterにより各プロセスに割り振られるが,第2引数以降は各Workerプロセス固有の値となる | |
); | |
if(scheduler.environment.isMaster){ | |
sw.stop(); | |
writefln("Parallel time: %s[ms], %s times faster than serial", sw.peek.msecs, serialMSec*1.0 / sw.peek.msecs); | |
}else{ | |
writeln(res); | |
} | |
}); | |
} | |
import std.math; | |
pure bool isPrime(T)(T src){ | |
if(src <= 1)return false; | |
else if(src < 4)return true; | |
else if(!(src&1))return false; | |
else if(((src+1)%6) && ((src-1)%6))return false; | |
T root = cast(T)sqrt(cast(real)src) + 1; | |
for(T i = 5; i < root; i += 6) | |
if(!((src%i) && ((src)%(i+2)))) | |
return false; | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment