Commit d86860d3 authored by Kirill Terekhov's avatar Kirill Terekhov

fix MPI_Isend/MPI_Irecv tag may be larger then maximum allowed; more memory...

fix MPI_Isend/MPI_Irecv tag may be larger then maximum allowed; more memory optimizations in multilevel solver
parent ebd8a2e0
......@@ -22,6 +22,8 @@
#include <omp.h>
#endif
#define PACK_ARRAY
//TODO
// 1. change to uniform size_type instead of size_t, make it INMOST_DATA_ENUM_TYPE
/*
......
......@@ -155,6 +155,7 @@ namespace INMOST
class Row
{
public:
#pragma pack(push,r1,4)
/// Entry of the sparse matrix row.
typedef struct entry_s
{
......@@ -166,6 +167,7 @@ namespace INMOST
//entry_s(const entry_s& b) : first(b.first), second(b.second) {}
entry_s() : first(ENUMUNDEF), second(0.0) {}
} entry;
#pragma pack(pop,r1)
/// Assemble an entry of entry_s type.
/// @param ind Index.
/// @param val Value.
......
......@@ -485,6 +485,15 @@ namespace INMOST
else
#endif
{
int max_tag = 32767;
int flag = 0;
int * p_max_tag;
#if defined(USE_MPI2)
MPI_Comm_get_attr(comm,MPI_TAG_UB,&p_max_tag,&flag);
#else //USE_MPI2
MPI_Attr_get(comm,MPI_TAG_UB,&p_max_tag,&flag);
#endif //USE_MPI2
if( flag ) max_tag = *p_max_tag;
std::string file_contents;
std::string local_data(out.str());
std::vector<MPI_Request> requests;
......@@ -504,7 +513,7 @@ namespace INMOST
{
MPI_Request req;
chunk = std::min(static_cast<INMOST_DATA_BIG_ENUM_TYPE>(INT_MAX),datasizes[k] - shift);
REPORT_MPI(ierr = MPI_Irecv(&file_contents[offset+shift], (INMOST_MPI_SIZE)chunk,MPI_CHAR,k, k*1000 + it, GetCommunicator(), &req) );
REPORT_MPI(ierr = MPI_Irecv(&file_contents[offset+shift], (INMOST_MPI_SIZE)chunk,MPI_CHAR,k, (k*1000 + it)%max_tag, GetCommunicator(), &req) );
if( ierr != MPI_SUCCESS ) REPORT_MPI(MPI_Abort(GetCommunicator(),__LINE__));
requests.push_back(req);
shift += chunk;
......@@ -524,7 +533,7 @@ namespace INMOST
{
MPI_Request req;
chunk = std::min(static_cast<INMOST_DATA_BIG_ENUM_TYPE>(INT_MAX),datasize - shift);
REPORT_MPI(ierr = MPI_Isend(&local_data[shift],(INMOST_MPI_SIZE)chunk,MPI_CHAR, 0, GetProcessorRank()*1000 + it, GetCommunicator(), &req) );
REPORT_MPI(ierr = MPI_Isend(&local_data[shift],(INMOST_MPI_SIZE)chunk,MPI_CHAR, 0, (GetProcessorRank()*1000 + it)%max_tag, GetCommunicator(), &req) );
if( ierr != MPI_SUCCESS ) REPORT_MPI(MPI_Abort(GetCommunicator(),__LINE__));
requests.push_back(req);
shift += chunk;
......@@ -752,6 +761,15 @@ namespace INMOST
REPORT_STR("strategy 0");
int ierr;
int max_tag = 32767;
int flag = 0;
int * p_max_tag;
#if defined(USE_MPI2)
MPI_Comm_get_attr(comm,MPI_TAG_UB,&p_max_tag,&flag);
#else //USE_MPI2
MPI_Attr_get(comm,MPI_TAG_UB,&p_max_tag,&flag);
#endif //USE_MPI2
if( flag ) max_tag = *p_max_tag;
std::vector<char> buffer, local_buffer;
INMOST_DATA_BIG_ENUM_TYPE recvsize;
......@@ -850,7 +868,7 @@ namespace INMOST
{
MPI_Request req;
chunk = std::min(static_cast<INMOST_DATA_BIG_ENUM_TYPE>(INT_MAX),recvsizes[k] - shift);
REPORT_MPI(ierr = MPI_Isend(&buffer[offset+shift],(INMOST_MPI_SIZE)chunk,MPI_CHAR, k, k*1000 + it, GetCommunicator(), &req) );
REPORT_MPI(ierr = MPI_Isend(&buffer[offset+shift],(INMOST_MPI_SIZE)chunk,MPI_CHAR, k, (k*1000 + it)%max_tag, GetCommunicator(), &req) );
if( ierr != MPI_SUCCESS ) REPORT_MPI(MPI_Abort(GetCommunicator(),__LINE__));
requests.push_back(req);
shift += chunk;
......@@ -879,7 +897,7 @@ namespace INMOST
{
MPI_Request req;
chunk = std::min(static_cast<INMOST_DATA_BIG_ENUM_TYPE>(INT_MAX),recvsize - shift);
REPORT_MPI(ierr = MPI_Irecv(&local_buffer[shift], (INMOST_MPI_SIZE)chunk,MPI_CHAR, 0, GetProcessorRank()*1000 + it, GetCommunicator(), &req) );
REPORT_MPI(ierr = MPI_Irecv(&local_buffer[shift], (INMOST_MPI_SIZE)chunk,MPI_CHAR, 0, (GetProcessorRank()*1000 + it)%max_tag, GetCommunicator(), &req) );
if( ierr != MPI_SUCCESS ) REPORT_MPI(MPI_Abort(GetCommunicator(),__LINE__));
requests.push_back(req);
shift += chunk;
......
......@@ -174,6 +174,15 @@ namespace INMOST
global_to_proc[k + 1] = global_overlap[2 * k + 1];
}
MPI_Status stat;
int max_tag = 32767;
int flag = 0;
int * p_max_tag;
#if defined(USE_MPI2)
MPI_Comm_get_attr(comm,MPI_TAG_UB,&p_max_tag,&flag);
#else //USE_MPI2
MPI_Attr_get(comm,MPI_TAG_UB,&p_max_tag,&flag);
#endif //USE_MPI2
if( flag ) max_tag = *p_max_tag;
INMOST_DATA_ENUM_TYPE ext_pos = local_matrix_end;
//may replace std::map here
//small_hash<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE, HASH_TABLE_SIZE> global_to_local;
......@@ -267,8 +276,8 @@ namespace INMOST
for (INMOST_DATA_ENUM_TYPE k = 0; k < vector_exchange_recv[0]; k++) //send rows that i want to receive
{
total_recv += vector_exchange_recv[j + 1];
GUARD_MPI(MPI_Isend(&vector_exchange_recv[j + 1], 1, INMOST_MPI_DATA_ENUM_TYPE, vector_exchange_recv[j], size + vector_exchange_recv[j], comm, &requests[k])); //send number of rows
GUARD_MPI(MPI_Isend(&vector_exchange_recv[j + 2], vector_exchange_recv[j + 1], INMOST_MPI_DATA_ENUM_TYPE, vector_exchange_recv[j], 2 * size + vector_exchange_recv[j], comm, &requests[k + vector_exchange_recv[0]])); //send row positions
GUARD_MPI(MPI_Isend(&vector_exchange_recv[j + 1], 1, INMOST_MPI_DATA_ENUM_TYPE, vector_exchange_recv[j], (size + vector_exchange_recv[j])%max_tag, comm, &requests[k])); //send number of rows
GUARD_MPI(MPI_Isend(&vector_exchange_recv[j + 2], vector_exchange_recv[j + 1], INMOST_MPI_DATA_ENUM_TYPE, vector_exchange_recv[j], (2 * size + vector_exchange_recv[j])%max_tag, comm, &requests[k + vector_exchange_recv[0]])); //send row positions
j += vector_exchange_recv[j + 1] + 2;
}
......@@ -280,11 +289,11 @@ namespace INMOST
k < incoming[size * 2 + rank]; k++) //receive rows that others want from me
{
INMOST_DATA_ENUM_TYPE msgsize;
GUARD_MPI(MPI_Recv(&msgsize, 1, INMOST_MPI_DATA_ENUM_TYPE, MPI_ANY_SOURCE, size + rank, comm, &stat)); //recv number of rows
GUARD_MPI(MPI_Recv(&msgsize, 1, INMOST_MPI_DATA_ENUM_TYPE, MPI_ANY_SOURCE, (size + rank)%max_tag, comm, &stat)); //recv number of rows
vector_exchange_send[j++] = stat.MPI_SOURCE;
vector_exchange_send[j++] = msgsize;
//std::cout << GetRank() << " MPI_Irecv size " << msgsize << " rank " << stat.MPI_SOURCE << " tag " << 2*size+rank << __FILE__ << ":" << __LINE__ << std::endl;
GUARD_MPI(MPI_Irecv(&vector_exchange_send[j], msgsize, INMOST_MPI_DATA_ENUM_TYPE, stat.MPI_SOURCE,2 * size + rank, comm, &requests[2 * vector_exchange_recv[0] + k])); //recv rows
GUARD_MPI(MPI_Irecv(&vector_exchange_send[j], msgsize, INMOST_MPI_DATA_ENUM_TYPE, stat.MPI_SOURCE,(2 * size + rank)%max_tag, comm, &requests[2 * vector_exchange_recv[0] + k])); //recv rows
j += msgsize;
total_send += msgsize;
vector_exchange_send[0]++;
......@@ -374,7 +383,7 @@ namespace INMOST
INMOST_DATA_ENUM_TYPE j = 1, q = 0, f = 0, total_rows_send = 0, total_rows_recv = 0;
for (INMOST_DATA_ENUM_TYPE k = 0; k < vector_exchange_recv[0]; k++) //recv sizes of rows
{
GUARD_MPI(MPI_Irecv(&recv_row_sizes[q], vector_exchange_recv[j + 1], INMOST_MPI_DATA_ENUM_TYPE, vector_exchange_recv[j], 3 * size + vector_exchange_recv[j], comm,&requests[k]));
GUARD_MPI(MPI_Irecv(&recv_row_sizes[q], vector_exchange_recv[j + 1], INMOST_MPI_DATA_ENUM_TYPE, vector_exchange_recv[j], (3 * size + vector_exchange_recv[j])%max_tag, comm,&requests[k]));
q += vector_exchange_recv[j + 1];
j += vector_exchange_recv[j + 1] + 2;
}
......@@ -388,7 +397,7 @@ namespace INMOST
send_row_sizes[q + r] = m[vector_exchange_send[j + 2 + r]].Size();
total_rows_send += m[vector_exchange_send[j + 2 + r]].Size();
}
GUARD_MPI(MPI_Isend(&send_row_sizes[q], vector_exchange_send[j + 1], INMOST_MPI_DATA_ENUM_TYPE,vector_exchange_send[j], 3 * size + rank, comm, &requests[vector_exchange_recv[0] + k])); //recv rows
GUARD_MPI(MPI_Isend(&send_row_sizes[q], vector_exchange_send[j + 1], INMOST_MPI_DATA_ENUM_TYPE,vector_exchange_send[j], (3 * size + rank)%max_tag, comm, &requests[vector_exchange_recv[0] + k])); //recv rows
//remember processor numbers here
q += vector_exchange_send[j + 1];
j += vector_exchange_send[j + 1] + 2;
......@@ -426,7 +435,7 @@ namespace INMOST
INMOST_DATA_ENUM_TYPE local_size = 0;
for (INMOST_DATA_ENUM_TYPE r = 0; r < vector_exchange_recv[j + 1]; r++)
local_size += recv_row_sizes[q + r];
GUARD_MPI(MPI_Irecv(&recv_row_data[f], local_size, Sparse::GetRowEntryType(), vector_exchange_recv[j], 4 * size + vector_exchange_recv[j], comm, &requests[k]));
GUARD_MPI(MPI_Irecv(&recv_row_data[f], local_size, Sparse::GetRowEntryType(), vector_exchange_recv[j], (4 * size + vector_exchange_recv[j])%max_tag, comm, &requests[k]));
q += vector_exchange_recv[j + 1];
j += vector_exchange_recv[j + 1] + 2;
f += local_size;
......@@ -439,7 +448,7 @@ namespace INMOST
INMOST_DATA_ENUM_TYPE local_size = 0;
for (INMOST_DATA_ENUM_TYPE r = 0; r < vector_exchange_send[j + 1]; r++)
local_size += send_row_sizes[q + r];
GUARD_MPI( MPI_Isend(&send_row_data[f], local_size, Sparse::GetRowEntryType(), vector_exchange_send[j],4 * size + rank, comm, &requests[k + vector_exchange_recv[0]]));
GUARD_MPI( MPI_Isend(&send_row_data[f], local_size, Sparse::GetRowEntryType(), vector_exchange_send[j],(4 * size + rank)%max_tag, comm, &requests[k + vector_exchange_recv[0]]));
q += vector_exchange_send[j + 1];
j += vector_exchange_send[j + 1] + 2;
f += local_size;
......@@ -644,6 +653,15 @@ namespace INMOST
{
//std::cout << __FUNCTION__ << " start" << std::endl;
#if defined(USE_MPI)
int max_tag = 32767;
int flag = 0;
int * p_max_tag;
#if defined(USE_MPI2)
MPI_Comm_get_attr(comm,MPI_TAG_UB,&p_max_tag,&flag);
#else //USE_MPI2
MPI_Attr_get(comm,MPI_TAG_UB,&p_max_tag,&flag);
#endif //USE_MPI2
if( flag ) max_tag = *p_max_tag;
if (GetSize() == 1) return;
#if defined(USE_OMP)
#pragma omp single
......@@ -656,7 +674,7 @@ namespace INMOST
for (i = 0; i < vector_exchange_recv[0]; i++)
{
//std::cout << GetRank() << " MPI_Irecv size " << vector_exchange_recv[j+1] << " dest " << vector_exchange_recv[j] << " tag " << vector_exchange_recv[j]*size+rank << std::endl;
GUARD_MPI(MPI_Irecv(&recv_storage[l], vector_exchange_recv[j + 1], INMOST_MPI_DATA_REAL_TYPE, vector_exchange_recv[j], vector_exchange_recv[j] * size + rank, comm, &recv_requests[i]));
GUARD_MPI(MPI_Irecv(&recv_storage[l], vector_exchange_recv[j + 1], INMOST_MPI_DATA_REAL_TYPE, vector_exchange_recv[j], (vector_exchange_recv[j] * size + rank)%max_tag, comm, &recv_requests[i]));
l += vector_exchange_recv[j + 1];
j += vector_exchange_recv[j + 1] + 2;
}
......@@ -666,7 +684,7 @@ namespace INMOST
//std::cout << GetRank() << " MPI_Isend size " << vector_exchange_send[j+1] << " dest " << vector_exchange_send[j] << " tag " << rank*size+vector_exchange_send[j] << std::endl;
for (k = 0; k < vector_exchange_send[j + 1]; k++)
send_storage[l + k] = x[vector_exchange_send[k + j + 2]];
GUARD_MPI(MPI_Isend(&send_storage[l], vector_exchange_send[j + 1], INMOST_MPI_DATA_REAL_TYPE, vector_exchange_send[j], rank * size + vector_exchange_send[j], comm, &send_requests[i]));
GUARD_MPI(MPI_Isend(&send_storage[l], vector_exchange_send[j + 1], INMOST_MPI_DATA_REAL_TYPE, vector_exchange_send[j], (rank * size + vector_exchange_send[j])%max_tag, comm, &send_requests[i]));
l += vector_exchange_send[j + 1];
j += vector_exchange_send[j + 1] + 2;
}
......@@ -698,6 +716,15 @@ namespace INMOST
//std::cout << __FUNCTION__ << " start" << std::endl;
#if defined(USE_MPI)
if (GetSize() == 1) return;
int max_tag = 32767;
int flag = 0;
int * p_max_tag;
#if defined(USE_MPI2)
MPI_Comm_get_attr(comm,MPI_TAG_UB,&p_max_tag,&flag);
#else //USE_MPI2
MPI_Attr_get(comm,MPI_TAG_UB,&p_max_tag,&flag);
#endif //USE_MPI2
if( flag ) max_tag = *p_max_tag;
#if defined(USE_OMP)
#pragma omp single
#endif
......@@ -710,7 +737,7 @@ namespace INMOST
{
//std::cout << GetRank() << " MPI_Irecv size " << vector_exchange_send[j+1] << " dest " << vector_exchange_send[j] << " tag " << vector_exchange_send[j]*size+rank << std::endl;
GUARD_MPI(MPI_Irecv(&send_storage[l], vector_exchange_send[j + 1], INMOST_MPI_DATA_REAL_TYPE,
vector_exchange_send[j], vector_exchange_send[j] * size + rank, comm,
vector_exchange_send[j], (vector_exchange_send[j] * size + rank)%max_tag, comm,
&send_requests[i]));
l += vector_exchange_send[j + 1];
j += vector_exchange_send[j + 1] + 2;
......@@ -722,7 +749,7 @@ namespace INMOST
recv_storage[l + k] = x[vector_exchange_recv[k + j + 2]];
//std::cout << GetRank() << " MPI_Isend size " << vector_exchange_recv[j+1] << " dest " << vector_exchange_recv[j] << " tag " << rank*size+vector_exchange_recv[j] << std::endl;
GUARD_MPI(MPI_Isend(&recv_storage[l], vector_exchange_recv[j + 1], INMOST_MPI_DATA_REAL_TYPE,
vector_exchange_recv[j], rank * size + vector_exchange_recv[j], comm,
vector_exchange_recv[j], (rank * size + vector_exchange_recv[j])%max_tag, comm,
&recv_requests[i]));
l += vector_exchange_recv[j + 1];
j += vector_exchange_recv[j + 1] + 2;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -832,6 +832,15 @@ namespace INMOST
std::vector<MPI_Request> requests;
int ierr = MPI_Gather(&sendsize,1,INMOST_MPI_DATA_BIG_ENUM_TYPE,&recvsize[0],1,INMOST_MPI_DATA_BIG_ENUM_TYPE,0,GetCommunicator());
if( ierr != MPI_SUCCESS ) MPI_Abort(GetCommunicator(),__LINE__);
int max_tag = 32767;
int flag = 0;
int * p_max_tag;
#if defined(USE_MPI2)
MPI_Comm_get_attr(comm,MPI_TAG_UB,&p_max_tag,&flag);
#else //USE_MPI2
MPI_Attr_get(comm,MPI_TAG_UB,&p_max_tag,&flag);
#endif //USE_MPI2
if( flag ) max_tag = *p_max_tag;
if( rank == 0 )
{
INMOST_DATA_BIG_ENUM_TYPE sizesum = recvsize[0];
......@@ -848,7 +857,7 @@ namespace INMOST
{
MPI_Request req;
chunk = std::min(static_cast<INMOST_DATA_BIG_ENUM_TYPE>(INT_MAX),recvsize[k] - shift);
ierr = MPI_Irecv(&senddata[offset+shift],chunk,MPI_CHAR,k, k*1000 + it, GetCommunicator(), &req);
ierr = MPI_Irecv(&senddata[offset+shift],chunk,MPI_CHAR,k, (k*1000 + it)%max_tag, GetCommunicator(), &req);
if( ierr != MPI_SUCCESS ) MPI_Abort(GetCommunicator(),__LINE__);
requests.push_back(req);
shift += chunk;
......@@ -868,7 +877,7 @@ namespace INMOST
{
MPI_Request req;
chunk = std::min(static_cast<INMOST_DATA_BIG_ENUM_TYPE>(INT_MAX),sendsize - shift);
ierr = MPI_Isend(&senddata[shift],chunk,MPI_CHAR, 0, rank*1000 + it, GetCommunicator(), &req);
ierr = MPI_Isend(&senddata[shift],chunk,MPI_CHAR, 0, (rank*1000 + it)%max_tag, GetCommunicator(), &req);
if( ierr != MPI_SUCCESS ) MPI_Abort(GetCommunicator(),__LINE__);
requests.push_back(req);
shift += chunk;
......@@ -1195,6 +1204,15 @@ namespace INMOST
std::vector<MPI_Request> requests;
int ierr = MPI_Gather(&sendsize,1,INMOST_MPI_DATA_BIG_ENUM_TYPE,&recvsize[0],1,INMOST_MPI_DATA_BIG_ENUM_TYPE,0,GetCommunicator());
if( ierr != MPI_SUCCESS ) MPI_Abort(GetCommunicator(),__LINE__);
int max_tag = 32767;
int flag = 0;
int * p_max_tag;
#if defined(USE_MPI2)
MPI_Comm_get_attr(comm,MPI_TAG_UB,&p_max_tag,&flag);
#else //USE_MPI2
MPI_Attr_get(comm,MPI_TAG_UB,&p_max_tag,&flag);
#endif //USE_MPI2
if( flag ) max_tag = *p_max_tag;
if( rank == 0 )
{
INMOST_DATA_BIG_ENUM_TYPE sizesum = recvsize[0];
......@@ -1211,7 +1229,7 @@ namespace INMOST
{
MPI_Request req;
chunk = std::min(static_cast<INMOST_DATA_BIG_ENUM_TYPE>(INT_MAX),recvsize[k] - shift);
ierr = MPI_Irecv(&senddata[offset+shift],chunk,MPI_CHAR,k, k*1000 + it, GetCommunicator(), &req);
ierr = MPI_Irecv(&senddata[offset+shift],chunk,MPI_CHAR,k, (k*1000 + it)%max_tag, GetCommunicator(), &req);
if( ierr != MPI_SUCCESS ) MPI_Abort(GetCommunicator(),__LINE__);
requests.push_back(req);
shift += chunk;
......@@ -1231,7 +1249,7 @@ namespace INMOST
{
MPI_Request req;
chunk = std::min(static_cast<INMOST_DATA_BIG_ENUM_TYPE>(INT_MAX),sendsize - shift);
ierr = MPI_Isend(&senddata[shift],chunk,MPI_CHAR, 0, rank*1000 + it, GetCommunicator(), &req);
ierr = MPI_Isend(&senddata[shift],chunk,MPI_CHAR, 0, (rank*1000 + it)%max_tag, GetCommunicator(), &req);
if( ierr != MPI_SUCCESS ) MPI_Abort(GetCommunicator(),__LINE__);
requests.push_back(req);
shift += chunk;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment