我有以下情況:我已經寫了一些簡短的MPI測試代碼,以便找出哪些組合的發送和接收操作在我的代碼中效果最好。C++:奇怪的指針損壞錯誤
該代碼在我自己的計算機上工作得很好(使用8個進程進行測試),但只要我運行一個正在處理的羣集,就會得到一個巨大的錯誤輸出,這是輸出:http://pastebin.com/pXTRSf89
我在我的代碼中做的事情如下:我打電話給我的通信功能100K次,並測量時間。該功能如下所示。我發現,錯誤總是發生在同一次迭代中(大約6K左右)。報告的處理器ID確實會改變。迭代是相同的,即使我使用64個proc而不是8個。問題是:我完全不知道,可能是錯誤的,特別是因爲沒有指針被釋放或分配。
void communicateGrid(int level, real* grid, const Subdomain& subdomain, std::vector<TimeMap>& tm_) {
tm_[level]["CommGrid"].start();
MPI_Status status[2];
MPI_Request request[2];
// x
MPI_Isend(&grid[getIndexInner(level, 1, 1, 1) + innerGridpoints_[level][0] - numOuterGridpoints_[level]], 1, mpiTypes_[level * 4 + 1], subdomain.upperNeighbors[0], 0, MPI_COMM_WORLD, &request[0]);
MPI_Isend(&grid[getIndexInner(level, 1, 1, 1)], 1, mpiTypes_[level * 4 + 1], subdomain.lowerNeighbors[0], 1, MPI_COMM_WORLD, &request[1]);
MPI_Recv(&grid[getIndexInner(level, 1,1,1) + innerGridpoints_[level][0]], 1, mpiTypes_[level * 4 + 1], subdomain.upperNeighbors[0], 1, MPI_COMM_WORLD, &status[0]);
MPI_Recv(&grid[getIndexInner(level, 1,1,1) - numOuterGridpoints_[level]], 1, mpiTypes_[level * 4 + 1], subdomain.lowerNeighbors[0], 0, MPI_COMM_WORLD, &status[1]);
//y
MPI_Isend(&grid[getIndex(level, 0, innerGridpoints_[level][1], 0)], 1, mpiTypes_[level * 4 + 2], subdomain.upperNeighbors[1], 2, MPI_COMM_WORLD, &request[0]);
MPI_Isend(&grid[getIndex(level, 0, numOuterGridpoints_[level], 0)], 1, mpiTypes_[level * 4 + 2], subdomain.lowerNeighbors[1], 3, MPI_COMM_WORLD, &request[1]);
MPI_Recv(&grid[getIndex(level, 0, innerGridpoints_[level][1] + numOuterGridpoints_[level], 0)], 1, mpiTypes_[level * 4 + 2], subdomain.upperNeighbors[1], 3, MPI_COMM_WORLD, &status[0]);
MPI_Recv(grid, 1, mpiTypes_[level * 4 + 2], subdomain.lowerNeighbors[1], 2, MPI_COMM_WORLD, &status[1]);
// z
MPI_Isend(&grid[getIndex(level, 0, 0, innerGridpoints_[level][2])], 1, mpiTypes_[level * 4 + 3], subdomain.upperNeighbors[2], 4, MPI_COMM_WORLD, &request[0]);
MPI_Isend(&grid[getIndex(level, 0, 0, numOuterGridpoints_[level])], 1, mpiTypes_[level * 4 + 3], subdomain.lowerNeighbors[2], 5, MPI_COMM_WORLD, &request[1]);
MPI_Recv(&grid[getIndex(level, 0, 0, numOuterGridpoints_[level] + innerGridpoints_[level][2])], 1, mpiTypes_[level * 4 + 3], subdomain.upperNeighbors[2], 5, MPI_COMM_WORLD, &status[0]);
MPI_Recv(grid, 1, mpiTypes_[level * 4 + 3], subdomain.lowerNeighbors[2], 4, MPI_COMM_WORLD, &status[1]);
tm_[level]["CommGrid"].stop();
}
mpiTypes_的類型是MPI_Datatype *的全局變量,innerGridpoints_和numOuterGridpoints_是全球性的(我知道這是不是一個好的編碼風格,但我把它僅適用於正時)。 我很確定我的數據類型是正確的,因爲他們在另一個通信功能設置中工作(例如Irecv後面跟着發送)。
Final注意:我只是試圖用一個進程來運行它。然後將下面的出錯:
排名0 [週一年04月22 2時11分23秒2013] [c0-0c1s3n0]致命錯誤 PMPI_Isend:內部MPI錯誤!錯誤堆棧:PMPI_Isend(148): MPI_Isend(buf = 0x2aaaab7b531c,count = 1,dtype = USER,dest = 0, tag = 1,MPI_COMM_WORLD,請求= 0x7fffffffb4d4)失敗(未知)(): 內部MPI錯誤! _pmiu_daemon(SIGCHLD):NID 00070] [c0-0c1s3n0] [週一年04月22二點11分23秒2013] PE RANK 0退出信號中止
再次,這僅發生在羣集上,但製作我的機器。
我很高興能夠檢查任何事情或錯誤可能在哪裏! 謝謝
它工作在哪種品牌的CPU上,哪種品牌的CPU不起作用? – Patashu 2013-04-22 00:29:37
我想知道你的指針是否最終會指向它們不應該有的數據塊。當你做'&grid [getIndex(level,0,0,numOuterGridpoints_ [level] + innerGridpoints_ [level] [2])]''這樣的事情時,是否有機會指向一個不是你自己的塊?或者你所調用的函數中是否有內存泄漏......是兩臺機器上的編譯器/庫的完全相同版本嗎? – Floris 2013-04-22 00:32:39
getIndex和getInnerIndex只是內聯索引函數,因爲網格是3d數組,它們應該沒問題。我的電腦是英特爾i5,使用gcc 4.6.0(Mac系統)進行編譯 - 集羣是帶有Opteron CPU的Cray機器。我嘗試過,但標準的PGI編譯器以及gcc(版本4.6.3) – Chris 2013-04-22 00:37:44