2015-08-17 104 views
0

將一些數據寫入使用PBS的羣集上的MPI文件時遇到很大麻煩。這裏是簡單的問題模擬程序的例子。寫入文件PBS MPI時出錯

#include <mpi.h> 

#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 


#include <iostream> 
#include <fstream> 
#include <string> 
#include <sstream> 
#include <cstdlib> 
#include <unistd.h> 

int main(int argc, char* argv[]){ 
int rank; 
int size; 

MPI_Init(&argc, &argv); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 


// Define hostname 
char hostname[128]; 
gethostname(hostname, 128); 

// check and create dump directory 
    struct stat buf; 
    int rc; 
    char *dir="Res"; 

    rc = stat(dir, &buf); 
    if(rc) // no dir, create 
    { if(rank == 0) 
    { 
     rc = mkdir(dir, 0771); 
     if(rc) 
     {std::ostringstream oss; 
     oss << "Can't create dump directory \"" 
      << dir 
      << "\""; 
     } 
    } 
    else { 
     sleep (2); 
    } 
    } 
    else if(!S_ISDIR(buf.st_mode)) 
    {std::ostringstream oss; 
    oss << "Path \"" 
     << dir 
     << "\" is not directory for dump"; 
    } 


    MPI_Barrier(MPI_COMM_WORLD); 
// Every process defines name of file for output (res_0, res_1, res_2.....) 
std::ostringstream filename; 
filename << dir << "/res_"<< rank; 

// Open file 
std::ofstream file(filename.str().c_str()); 

// Output to file . Output seems like "I am 0 from 24. hostname" 
file << "I am " << rank << " from " << size << ". " << hostname << std::endl; 

file.close(); 

MPI_Finalize(); 

return 0; 
} 

我openmpi_intel-1.4.2編譯它,使用COMAND

mpicxx -Wall test.cc -o test 

然後我排隊此程序腳本:

#!/bin/bash 

#PBS -N test 
#PBS -l select=8:ncpus=6:mpiprocs=6 
#PBS -l walltime=00:01:30 
#PBS -m n 
#PBS -e stderr.txt 
#PBS -o stdout.txt 

cd $PBS_O_WORKDIR 
echo "I run on node: `uname -n`" 
echo "My working directory is: $PBS_O_WORKDIR" 
echo "Assigned to me nodes are:" 
cat $PBS_NODEFILE 

mpirun -hostfile $PBS_NODEFILE ./test 

我希望這樣的結果:

1. New directory "Res" to be created 

2. 8*6 different files (res_0, res_1, res_2, ...) to be written to the Res dir 

但是隻有res_ *文件來自第一個節點被寫入(res_ {0..5}),而其餘的不是。

什麼問題?

謝謝!

+1

是否所有節點都可以訪問相同的文件位置? – dbeer

+0

@dbeer可以正確。想象一下,每個節點都有一個名爲'/ scratch'的不同卷。新的文件夾'Res'創建在進程0的節點上,但不在其他節點上。因此,'file(filename.str()。c_str());'因爲沒有這樣的文件或目錄'而失敗。你可以使用['ios :: fail()'](http://www.cplusplus.com/reference/ios/ios/fail/)像http://stackoverflow.com/questions/5835848/when-will- ofstreamopen-fail?或者使用像http://codereview.stackexchange.com/questions/57829/better-option-than-errno-for-file-io-error-handling這樣的異常來檢查? – francis

+0

你好。服務器主人傷心的問題是及時需要創建文件。該程序在第一次使用「w」文件時工作非常緩慢,因此檢查0節點是否已創建文件夾並等待該代碼行完成至關重要。他舉了一個例子,首次裝入java需要大約10分鐘,而下一次裝載需要大約1分鐘。 –

回答

1

好吧,讓我們假設你運行在所有計算節點上的文件系統上。情況就是這樣,對嗎? 那麼我的代碼片斷中看到的主要問題是,所有進程都會同時聲明目錄,然後嘗試創建該目錄(如果它不存在)。我不確定真正發生了什麼,但我確信這不是最聰明的想法。

由於本質上你想要的是對目錄進行系列完整性檢查和/或在需要時創建它,爲什麼不只是讓MPI進程0級呢?

這將使你是這樣的:

if (rank == 0) { // Only master manages the directory creation 
    int rc = stat(dir, &buf); 
    ... // sanity check goes here and directory creation as well 
    // calling MPI_Abort() in case of failure seems also a good idea 
} 
// all other processes wait here 
MPI_Barrier(MPI_COMM_WORLD); 
// now we know the directory exists and is accessible 
// let's do our stuff 

莫非這對你的工作?