Commit efb0bb4a authored by Dmitry Bagaev's avatar Dmitry Bagaev

CLion code style reformat

parent 9705cf97
set(SOURCE
${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/Solver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/SolverFactory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/sparse.cpp
)
${SOURCE}
${CMAKE_CURRENT_SOURCE_DIR}/Solver.cpp
${CMAKE_CURRENT_SOURCE_DIR}/SolverFactory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/sparse.cpp
)
set(HEADER
${HEADER}
${CMAKE_CURRENT_SOURCE_DIR}/SolverFactory.h
)
${HEADER}
${CMAKE_CURRENT_SOURCE_DIR}/SolverFactory.h
)
add_subdirectory(solver_inner)
if(USE_SOLVER_PETSC)
add_subdirectory(solver_petsc)
endif()
if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_mtiluc2.hpp" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_mtiluc2.cpp" )
set(SOLVER_DEFINITIONS ${SOLVER_DEFINITIONS} -DHAVE_SOLVER_MPTILUC2)
set(HAVE_SOLVER_MPTILUC2 TRUE PARENT_SCOPE)
list(APPEND HEADER ${CMAKE_CURRENT_SOURCE_DIR}/solver_mtiluc2.hpp)
list(APPEND SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/solver_mtiluc2.cpp)
else()
set(HAVE_SOLVER_MPTILUC2 FALSE PARENT_SCOPE)
endif()
if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_mtilu2.hpp" )
set(SOLVER_DEFINITIONS ${SOLVER_DEFINITIONS} -DHAVE_SOLVER_MPTILU2)
set(HAVE_SOLVER_MPTILU2 TRUE PARENT_SCOPE)
list(APPEND HEADER ${CMAKE_CURRENT_SOURCE_DIR}/solver_mtilu2.hpp)
list(APPEND SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/solver_mtilu2.cpp)
else()
set(HAVE_SOLVER_MPTILU2 FALSE PARENT_SCOPE)
endif()
if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_fcbiilu2.h" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_fcbiilu2.cpp" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/fcbiilu2.cpp" )
set(SOLVER_DEFINITIONS ${SOLVER_DEFINITIONS} -DHAVE_SOLVER_FCBIILU2)
set(HAVE_SOLVER_FCBIILU2 TRUE PARENT_SCOPE)
list(APPEND HEADER ${CMAKE_CURRENT_SOURCE_DIR}/solver_fcbiilu2.h)
list(APPEND SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/solver_fcbiilu2.cpp ${CMAKE_CURRENT_SOURCE_DIR}/fcbiilu2.cpp)
else()
set(HAVE_SOLVER_FCBIILU2 FALSE)
endif()
if (USE_SOLVER_PETSC)
add_subdirectory(solver_petsc)
endif ()
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_mtiluc2.hpp" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_mtiluc2.cpp")
set(SOLVER_DEFINITIONS ${SOLVER_DEFINITIONS} -DHAVE_SOLVER_MPTILUC2)
set(HAVE_SOLVER_MPTILUC2 TRUE PARENT_SCOPE)
list(APPEND HEADER ${CMAKE_CURRENT_SOURCE_DIR}/solver_mtiluc2.hpp)
list(APPEND SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/solver_mtiluc2.cpp)
else ()
set(HAVE_SOLVER_MPTILUC2 FALSE PARENT_SCOPE)
endif ()
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_mtilu2.hpp")
set(SOLVER_DEFINITIONS ${SOLVER_DEFINITIONS} -DHAVE_SOLVER_MPTILU2)
set(HAVE_SOLVER_MPTILU2 TRUE PARENT_SCOPE)
list(APPEND HEADER ${CMAKE_CURRENT_SOURCE_DIR}/solver_mtilu2.hpp)
list(APPEND SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/solver_mtilu2.cpp)
else ()
set(HAVE_SOLVER_MPTILU2 FALSE PARENT_SCOPE)
endif ()
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_fcbiilu2.h" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_fcbiilu2.cpp" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/fcbiilu2.cpp")
set(SOLVER_DEFINITIONS ${SOLVER_DEFINITIONS} -DHAVE_SOLVER_FCBIILU2)
set(HAVE_SOLVER_FCBIILU2 TRUE PARENT_SCOPE)
list(APPEND HEADER ${CMAKE_CURRENT_SOURCE_DIR}/solver_fcbiilu2.h)
list(APPEND SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/solver_fcbiilu2.cpp ${CMAKE_CURRENT_SOURCE_DIR}/fcbiilu2.cpp)
else ()
set(HAVE_SOLVER_FCBIILU2 FALSE)
endif ()
if (USE_MPI)
if( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_k3biilu2.h" AND EXISTS
"${CMAKE_CURRENT_SOURCE_DIR}/solver_k3biilu2.cpp" AND EXISTS
"${CMAKE_CURRENT_SOURCE_DIR}/k3d.h" AND EXISTS
"${CMAKE_CURRENT_SOURCE_DIR}/k3d.cpp" )
set(SOLVER_DEFINITIONS ${SOLVER_DEFINITIONS} -DHAVE_SOLVER_K3BIILU2)
set(HAVE_SOLVER_K3BIILU2 TRUE PARENT_SCOPE)
list(APPEND HEADER ${CMAKE_CURRENT_SOURCE_DIR}/solver_k3biilu2.h ${CMAKE_CURRENT_SOURCE_DIR}/k3d.h)
list(APPEND SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/solver_k3biilu2.cpp ${CMAKE_CURRENT_SOURCE_DIR}/k3d.cpp)
else()
set(HAVE_SOLVER_K3BIILU2 FALSE PARENT_SCOPE)
endif()
endif()
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/solver_k3biilu2.h" AND EXISTS
"${CMAKE_CURRENT_SOURCE_DIR}/solver_k3biilu2.cpp" AND EXISTS
"${CMAKE_CURRENT_SOURCE_DIR}/k3d.h" AND EXISTS
"${CMAKE_CURRENT_SOURCE_DIR}/k3d.cpp")
set(SOLVER_DEFINITIONS ${SOLVER_DEFINITIONS} -DHAVE_SOLVER_K3BIILU2)
set(HAVE_SOLVER_K3BIILU2 TRUE PARENT_SCOPE)
list(APPEND HEADER ${CMAKE_CURRENT_SOURCE_DIR}/solver_k3biilu2.h ${CMAKE_CURRENT_SOURCE_DIR}/k3d.h)
list(APPEND SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/solver_k3biilu2.cpp ${CMAKE_CURRENT_SOURCE_DIR}/k3d.cpp)
else ()
set(HAVE_SOLVER_K3BIILU2 FALSE PARENT_SCOPE)
endif ()
endif ()
set(HEADER ${HEADER} PARENT_SCOPE)
......
......@@ -41,6 +41,5 @@ namespace INMOST {
}
}
......@@ -6,17 +6,20 @@
namespace INMOST {
struct SolverBaseFactory {
virtual SolverInterface* create() = 0;
virtual SolverInterface* copy(const SolverInterface* other) = 0;
virtual SolverInterface *create() = 0;
virtual SolverInterface *copy(const SolverInterface *other) = 0;
virtual ~SolverBaseFactory() {};
};
template <class C> struct SolverCreateFactory : SolverBaseFactory {
template<class C>
struct SolverCreateFactory : SolverBaseFactory {
SolverInterface *create() {
return new C;
};
SolverInterface *copy(const SolverInterface* other) {
SolverInterface *copy(const SolverInterface *other) {
return new C(other);
};
};
......@@ -25,12 +28,17 @@ namespace INMOST {
private:
static std::map<std::string, SolverBaseFactory *> solvers;
public:
template<class T> static void registerSolver(std::string name) {
template<class T>
static void registerSolver(std::string name) {
solvers.insert(std::make_pair(name, new SolverCreateFactory<T>));
};
static SolverInterface *getSolver(std::string name);
static SolverInterface *copySolver(const SolverInterface *other);
static std::vector<std::string> getAvailableSolvers();
static bool isSolverAvailable(std::string name);
};
......
......@@ -5,7 +5,9 @@
#include "solver_inner/solver_ilu2/SolverILU2.h"
#if defined(USE_SOLVER_PETSC)
#include "solver_petsc/SolverPETSc.h"
#include "solver_petsc/SolverPETSc.h"
#endif
namespace INMOST {
......@@ -34,8 +36,8 @@ namespace INMOST {
solver->Initialize(argc, argv, solverDatabasePath.c_str(), prefix);
}
Solver& Solver::operator=(const Solver& other) {
if( this != &other ) {
Solver &Solver::operator=(const Solver &other) {
if (this != &other) {
this->solver->SetCommunicator(other.solver->GetCommunicator());
this->prefix = other.prefix;
this->solver->Assign(other.solver);
......@@ -63,8 +65,8 @@ namespace INMOST {
int ierr = 0;
MPI_Initialized(&flag);
if (!flag) {
ierr = MPI_Init(argc,argv);
if( ierr != MPI_SUCCESS ) {
ierr = MPI_Init(argc, argv);
if (ierr != MPI_SUCCESS) {
std::cout << __FILE__ << ":" << __LINE__ << "problem in MPI_Init" << std::endl;
}
}
......@@ -81,13 +83,13 @@ namespace INMOST {
void Solver::Finalize() {
Sparse::DestroyRowEntryType();
#if defined(USE_MPI)
{
int flag = 0;
MPI_Finalized(&flag);
if( !flag ) {
MPI_Finalize();
{
int flag = 0;
MPI_Finalized(&flag);
if (!flag) {
MPI_Finalize();
}
}
}
#endif
Solver::is_finalized = true;
Solver::is_initialized = false;
......@@ -101,25 +103,27 @@ namespace INMOST {
return is_finalized;
}
void Solver::SetMatrix(Sparse::Matrix & A, bool ModifiedPattern, bool OldPreconditioner) {
void Solver::SetMatrix(Sparse::Matrix &A, bool ModifiedPattern, bool OldPreconditioner) {
solver->SetMatrix(A, ModifiedPattern, OldPreconditioner);
}
bool Solver::Solve(INMOST::Sparse::Vector & RHS, INMOST::Sparse::Vector & SOL) {
if( !solver->isMatrixSet()) throw MatrixNotSetInSolver;
if( RHS.GetCommunicator() != solver->GetCommunicator() || SOL.GetCommunicator() != solver->GetCommunicator()) throw DifferentCommunicatorInSolver;
INMOST_DATA_ENUM_TYPE vbeg,vend;
RHS.GetInterval(vbeg,vend);
bool Solver::Solve(INMOST::Sparse::Vector &RHS, INMOST::Sparse::Vector &SOL) {
if (!solver->isMatrixSet()) throw MatrixNotSetInSolver;
if (RHS.GetCommunicator() != solver->GetCommunicator() ||
SOL.GetCommunicator() != solver->GetCommunicator())
throw DifferentCommunicatorInSolver;
INMOST_DATA_ENUM_TYPE vbeg, vend;
RHS.GetInterval(vbeg, vend);
if (RHS.Size() != SOL.Size()) {
if (SOL.Size() == 0) {
SOL.SetInterval(vbeg,vend);
for(Sparse::Vector::iterator ri = SOL.Begin(); ri != SOL.End(); ++ri) *ri = 0.0;
SOL.SetInterval(vbeg, vend);
for (Sparse::Vector::iterator ri = SOL.Begin(); ri != SOL.End(); ++ri) *ri = 0.0;
} else throw InconsistentSizesInSolver;
}
return solver->Solve(RHS, SOL);
}
bool Solver::Clear() {
bool Solver::Clear() {
return solver->Clear();
}
......@@ -158,25 +162,25 @@ namespace INMOST {
std::string Solver::parseDatabase(std::string solverName) {
const char *name = solverName.c_str();
if( database != NULL ) {
FILE * f = fopen(database, "r");
if (database != NULL) {
FILE *f = fopen(database, "r");
if (f != NULL) {
char str[4096];
while( !feof(f) && fgets(str,4096,f)) {
while (!feof(f) && fgets(str, 4096, f)) {
int k = 0, l;
for(k = 0; k < (int)strlen(str); ++k) {
if( str[k] == ':' ) break;
for (k = 0; k < (int) strlen(str); ++k) {
if (str[k] == ':') break;
}
if( k == strlen(str) ) continue; //invalid line
for(l = 0; l < k; ++l) str[l] = tolower(str[l]);
l = (int)strlen(str)-1; // Right-trim string
while(l > 0 && isspace(str[l]) ) --l;
str[l+1] = 0;
l = k+1;
while(l < (int)strlen(str) && isspace(str[l]) ) ++l;
if( l == strlen(str) ) continue; //skip empty entry
if( !strncmp(str, name, k) ) {
return std::string(str+l);
if (k == strlen(str)) continue; //invalid line
for (l = 0; l < k; ++l) str[l] = tolower(str[l]);
l = (int) strlen(str) - 1; // Right-trim string
while (l > 0 && isspace(str[l])) --l;
str[l + 1] = 0;
l = k + 1;
while (l < (int) strlen(str) && isspace(str[l])) ++l;
if (l == strlen(str)) continue; //skip empty entry
if (!strncmp(str, name, k)) {
return std::string(str + l);
}
}
fclose(f);
......@@ -185,37 +189,35 @@ namespace INMOST {
return std::string("");
}
int comparator(const void * pa, const void *pb)
{
INMOST_DATA_ENUM_TYPE * a = (INMOST_DATA_ENUM_TYPE *)pa, * b = (INMOST_DATA_ENUM_TYPE *)pb;
int comparator(const void *pa, const void *pb) {
INMOST_DATA_ENUM_TYPE *a = (INMOST_DATA_ENUM_TYPE *) pa, *b = (INMOST_DATA_ENUM_TYPE *) pb;
return a[0] - b[0];
}
INMOST_DATA_ENUM_TYPE binary_search_pairs(INMOST_DATA_ENUM_TYPE * link, INMOST_DATA_ENUM_TYPE size, INMOST_DATA_ENUM_TYPE find)
{
INMOST_DATA_ENUM_TYPE binary_search_pairs(INMOST_DATA_ENUM_TYPE *link, INMOST_DATA_ENUM_TYPE size,
INMOST_DATA_ENUM_TYPE find) {
INMOST_DATA_ENUM_TYPE rcur = size >> 1, lcur = 0, mid, chk;
while( rcur >= lcur )
{
mid = lcur + ((rcur-lcur) >> 1);
while (rcur >= lcur) {
mid = lcur + ((rcur - lcur) >> 1);
chk = mid << 1;
if( link[chk] < find ) lcur = mid+1;
else if( link[chk] > find ) rcur = mid-1;
if (link[chk] < find) lcur = mid + 1;
else if (link[chk] > find) rcur = mid - 1;
else return chk;
}
return size;
}
void Solver::OrderInfo::Integrate(INMOST_DATA_REAL_TYPE * inout, INMOST_DATA_ENUM_TYPE num) const
{
void Solver::OrderInfo::Integrate(INMOST_DATA_REAL_TYPE *inout, INMOST_DATA_ENUM_TYPE num) const {
#if defined(USE_MPI)
if( GetSize() == 1 ) return;
if (GetSize() == 1) return;
#if defined(USE_OMP)
#pragma omp single
#endif
{
int ierr = 0;
dynarray<INMOST_DATA_REAL_TYPE,1024> temp(num);
memcpy(temp.data(),inout,sizeof(INMOST_DATA_REAL_TYPE)*num);
GUARD_MPI(MPI_Allreduce(temp.data(),inout,num,INMOST_MPI_DATA_REAL_TYPE,MPI_SUM,comm));
dynarray<INMOST_DATA_REAL_TYPE, 1024> temp(num);
memcpy(temp.data(), inout, sizeof(INMOST_DATA_REAL_TYPE) * num);
GUARD_MPI(MPI_Allreduce(temp.data(), inout, num, INMOST_MPI_DATA_REAL_TYPE, MPI_SUM, comm));
}
#else
(void) inout;
......@@ -223,26 +225,24 @@ namespace INMOST {
#endif
}
void Solver::OrderInfo::PrepareMatrix(Sparse::Matrix & m, INMOST_DATA_ENUM_TYPE overlap)
{
void Solver::OrderInfo::PrepareMatrix(Sparse::Matrix &m, INMOST_DATA_ENUM_TYPE overlap) {
have_matrix = true;
m.isParallel() = true;
INMOST_DATA_ENUM_TYPE two[2];
INMOST_DATA_ENUM_TYPE mbeg,mend;
INMOST_DATA_ENUM_TYPE two[2];
INMOST_DATA_ENUM_TYPE mbeg, mend;
int initial_rank;
#if defined(USE_MPI)
int ierr = 0;
if( comm != INMOST_MPI_COMM_WORLD )
{
if (comm != INMOST_MPI_COMM_WORLD) {
MPI_Comm_free(&comm);
comm = INMOST_MPI_COMM_WORLD;
}
if( m.GetCommunicator() == INMOST_MPI_COMM_WORLD )
if (m.GetCommunicator() == INMOST_MPI_COMM_WORLD)
comm = INMOST_MPI_COMM_WORLD;
else MPI_Comm_dup(m.GetCommunicator(), &comm);
MPI_Comm_rank(comm,&rank);
MPI_Comm_size(comm,&size);
MPI_Comm_rank(comm, &rank);
MPI_Comm_size(comm, &size);
#else
(void) overlap;
rank = 0;
......@@ -250,16 +250,17 @@ namespace INMOST {
#endif
initial_rank = rank;
//std::vector<MPI_Request> requests;
global_overlap.resize(size*2);
global_to_proc.resize(size+1);
m.GetInterval(mbeg,mend);
global_overlap.resize(size * 2);
global_to_proc.resize(size + 1);
m.GetInterval(mbeg, mend);
global_to_proc[0] = 0;
initial_matrix_begin = mbeg;
initial_matrix_end = mend;
two[0] = mbeg;
two[1] = mend;
#if defined(USE_MPI)
GUARD_MPI(MPI_Allgather(two,2,INMOST_MPI_DATA_ENUM_TYPE,&global_overlap[0],2,INMOST_MPI_DATA_ENUM_TYPE,comm));
GUARD_MPI(MPI_Allgather(two, 2, INMOST_MPI_DATA_ENUM_TYPE, &global_overlap[0], 2, INMOST_MPI_DATA_ENUM_TYPE,
comm));
#else
local_vector_begin = initial_matrix_begin = local_matrix_begin = global_overlap[0] = mbeg;
local_vector_end = initial_matrix_end = local_matrix_end = global_overlap[1] = mend;
......@@ -270,195 +271,191 @@ namespace INMOST {
{
//starts of local indexes should appear in asscending order
bool reorder = false;
for(int k = 0; k < size-1; k++)
if( global_overlap[2*k] > global_overlap[2*(k+1)] )
{
for (int k = 0; k < size - 1; k++)
if (global_overlap[2 * k] > global_overlap[2 * (k + 1)]) {
reorder = true;
break;
}
if( reorder )
{
storage_type temp(size*2);
if (reorder) {
storage_type temp(size * 2);
//assemble array that includes rank
for(int k = 0; k < size; ++k)
{
temp[2*k+0] = global_overlap[2*k];
temp[2*k+1] = k;
for (int k = 0; k < size; ++k) {
temp[2 * k + 0] = global_overlap[2 * k];
temp[2 * k + 1] = k;
}
//sort array
qsort(&temp[0],size,sizeof(INMOST_DATA_ENUM_TYPE)*2,comparator);
qsort(&temp[0], size, sizeof(INMOST_DATA_ENUM_TYPE) * 2, comparator);
//create new group
MPI_Group oldg, newg;
MPI_Comm newcomm;
std::vector<int> ranks(size);
for(int k = 0; k < size; ++k)
ranks[k] = temp[2*k+1];
GUARD_MPI(MPI_Comm_group(comm,&oldg));
GUARD_MPI(MPI_Group_incl(oldg,size,&ranks[0],&newg));
GUARD_MPI(MPI_Comm_create(comm,newg,&newcomm));
if( comm != INMOST_MPI_COMM_WORLD )
{
for (int k = 0; k < size; ++k)
ranks[k] = temp[2 * k + 1];
GUARD_MPI(MPI_Comm_group(comm, &oldg));
GUARD_MPI(MPI_Group_incl(oldg, size, &ranks[0], &newg));
GUARD_MPI(MPI_Comm_create(comm, newg, &newcomm));
if (comm != INMOST_MPI_COMM_WORLD) {
GUARD_MPI(MPI_Comm_free(&comm));
}
comm = newcomm;
//compute new rank
MPI_Comm_rank(comm,&rank);
MPI_Comm_rank(comm, &rank);
//sort array pairs, so we don't need to exchange them again
qsort(&global_overlap[0],size,sizeof(INMOST_DATA_ENUM_TYPE)*2,comparator);
qsort(&global_overlap[0], size, sizeof(INMOST_DATA_ENUM_TYPE) * 2, comparator);
}
//now check that there are no overlaps of local indexes
//every mend must be equal to every mbeg
reorder = false;
for(int k = 0; k < size-1; k++)
if( global_overlap[2*k+1] != global_overlap[2*(k+1)] )
{
for (int k = 0; k < size - 1; k++)
if (global_overlap[2 * k + 1] != global_overlap[2 * (k + 1)]) {
//check that end is strictly greater then begin
if( global_overlap[2*k+1] < global_overlap[2*(k+1)] )
{
if( initial_rank == 0 )
{
if (global_overlap[2 * k + 1] < global_overlap[2 * (k + 1)]) {
if (initial_rank == 0) {
std::cout << __FILE__ << ":" << __LINE__ << " Matrix index intervals are not complete:";
std::cout << " processor " << k+0 << " interval " << global_overlap[2*(k+0)] << ":" << global_overlap[2*(k+0)+1];
std::cout << " processor " << k+1 << " interval " << global_overlap[2*(k+1)] << ":" << global_overlap[2*(k+1)+1];
std::cout << " processor " << k + 0 << " interval " << global_overlap[2 * (k + 0)] << ":"
<< global_overlap[2 * (k + 0) + 1];
std::cout << " processor " << k + 1 << " interval " << global_overlap[2 * (k + 1)] << ":"
<< global_overlap[2 * (k + 1) + 1];
std::cout << std::endl;
MPI_Abort(comm,-1000);
MPI_Abort(comm, -1000);
}
}
reorder = true;
}
if( reorder )
{
if (reorder) {
storage_type old_overlap(global_overlap);
//move local bounds to get non-overlapping regions
for(int k = 0; k < size-1; k++)
while( global_overlap[2*k+1] > global_overlap[2*(k+1)] )
{
for (int k = 0; k < size - 1; k++)
while (global_overlap[2 * k + 1] > global_overlap[2 * (k + 1)]) {
//move bounds to equalize sizes
if( global_overlap[2*k+1] - global_overlap[2*k] < global_overlap[2*(k+1)+1] - global_overlap[2*(k+1)] )
global_overlap[2*k+1]--; //move right bound of the current processor to left
if (global_overlap[2 * k + 1] - global_overlap[2 * k] <
global_overlap[2 * (k + 1) + 1] - global_overlap[2 * (k + 1)])
global_overlap[2 * k + 1]--; //move right bound of the current processor to left
else
global_overlap[2*(k+1)]++; //move left bound of the next processor to right
global_overlap[2 * (k + 1)]++; //move left bound of the next processor to right
}
//TODO: if we need to merge overlapping parts of the matrices - do it here
}
local_matrix_begin = global_overlap[2*rank+0];
local_matrix_end = global_overlap[2*rank+1];
for(int k = 0; k < size; k++)
global_to_proc[k+1] = global_overlap[2*k+1];
local_matrix_begin = global_overlap[2 * rank + 0];
local_matrix_end = global_overlap[2 * rank + 1];
for (int k = 0; k < size; k++)
global_to_proc[k + 1] = global_overlap[2 * k + 1];
}
MPI_Status stat;
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;
std::vector< std::pair<INMOST_DATA_ENUM_TYPE,INMOST_DATA_ENUM_TYPE> > current_global_to_local;
std::vector< Sparse::Row::entry > send_row_data, recv_row_data;
std::vector< INMOST_DATA_ENUM_TYPE > send_row_sizes, recv_row_sizes;
std::vector<INMOST_DATA_ENUM_TYPE> incoming(4*size);
small_hash<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE, HASH_TABLE_SIZE> global_to_local;
std::vector<std::pair<INMOST_DATA_ENUM_TYPE, INMOST_DATA_ENUM_TYPE> > current_global_to_local;
std::vector<Sparse::Row::entry> send_row_data, recv_row_data;
std::vector<INMOST_DATA_ENUM_TYPE> send_row_sizes, recv_row_sizes;
std::vector<INMOST_DATA_ENUM_TYPE> incoming(4 * size);
std::vector<MPI_Request> requests;
INMOST_DATA_ENUM_TYPE total_send = 0, total_recv = 0;
INMOST_DATA_ENUM_TYPE local_start = local_matrix_begin, local_end = local_matrix_end;
for(INMOST_DATA_ENUM_TYPE it = 0; it < overlap+1; it++)
{
for (INMOST_DATA_ENUM_TYPE it = 0; it < overlap + 1; it++) {
total_send = 0, total_recv = 0;
current_global_to_local.clear();
for(INMOST_DATA_ENUM_TYPE k = local_start; k < local_end; ++k)
{
Sparse::Row & r = m[k];
for (INMOST_DATA_ENUM_TYPE k = local_start; k < local_end; ++k) {
Sparse::Row &r = m[k];
INMOST_DATA_ENUM_TYPE jend = r.Size(), ind;
for(INMOST_DATA_ENUM_TYPE j = 0; j < jend; ++j)
{
for (INMOST_DATA_ENUM_TYPE j = 0; j < jend; ++j) {
ind = r.GetIndex(j);
if( ind < local_matrix_begin || ind >= local_matrix_end)
{
INMOST_DATA_ENUM_TYPE & recv_pos = global_to_local[ind];
if( recv_pos == 0 ) //this number was not assigned yet
if (ind < local_matrix_begin || ind >= local_matrix_end) {
INMOST_DATA_ENUM_TYPE &recv_pos = global_to_local[ind];
if (recv_pos == 0) //this number was not assigned yet
{
recv_pos = ext_pos++;
if( it < overlap ) current_global_to_local.push_back(std::make_pair(ind,recv_pos));
if (it < overlap) current_global_to_local.push_back(std::make_pair(ind, recv_pos));
}
}
}
}
if( it == overlap )
if (it == overlap)
current_global_to_local = global_to_local.serialize();
std::sort(current_global_to_local.begin(),current_global_to_local.end());
std::sort(current_global_to_local.begin(), current_global_to_local.end());
//if( !current_global_to_local.empty() )
{
//check all the indexes that comes from other processors
//for every processor we need arrays:
// processor -> (array of index positions where to receive))
// processor -> (array of index positions from where to send)
memset(&incoming[0],0,sizeof(INMOST_DATA_ENUM_TYPE)*size*2);
memset(&incoming[0], 0, sizeof(INMOST_DATA_ENUM_TYPE) * size * 2);
vector_exchange_recv.clear();
vector_exchange_recv.push_back(0);
if( !current_global_to_local.empty() )
{
INMOST_DATA_ENUM_TYPE proc_beg = GetProcessor(current_global_to_local.begin()->first), proc_end = GetProcessor(current_global_to_local.rbegin()->first)+1;
if (!current_global_to_local.empty()) {
INMOST_DATA_ENUM_TYPE proc_beg = GetProcessor(current_global_to_local.begin()->first), proc_end =
GetProcessor(current_global_to_local.rbegin()->first) + 1;
INMOST_DATA_ENUM_TYPE current_ind = 0;
for(INMOST_DATA_ENUM_TYPE proc = proc_beg; proc < proc_end; proc++)
{
for (INMOST_DATA_ENUM_TYPE proc = proc_beg; proc < proc_end; proc++) {
bool first = true;
INMOST_DATA_ENUM_TYPE numind = static_cast<INMOST_DATA_ENUM_TYPE>(vector_exchange_recv.size() + 1);
while( current_ind < current_global_to_local.size() && current_global_to_local[current_ind].first < global_to_proc[proc+1] )
{
INMOST_DATA_ENUM_TYPE numind = static_cast<INMOST_DATA_ENUM_TYPE>(vector_exchange_recv.size() +
1);
while (current_ind < current_global_to_local.size() &&
current_global_to_local[current_ind].first < global_to_proc[proc + 1]) {
INMOST_DATA_ENUM_TYPE k = current_global_to_local[current_ind].first;
if( first )
{
if (first) {
vector_exchange_recv.push_back(proc);
vector_exchange_recv.push_back(1);
vector_exchange_recv.push_back(k);
first = false;
}
else
{
} else {
vector_exchange_recv[numind]++;
vector_exchange_recv.push_back(k);
}
current_ind++;
}
if( !first )
{
if (!first) {
incoming[proc]++;
incoming[proc+size] += vector_exchange_recv[numind];
incoming[proc + size] += vector_exchange_recv[numind];
vector_exchange_recv[0]++;
}
}
}
GUARD_MPI(MPI_Allreduce(&incoming[0],&incoming[2*size],size*2,INMOST_MPI_DATA_ENUM_TYPE,MPI_SUM,comm));
GUARD_MPI(MPI_Allreduce(&incoming[0], &incoming[2 * size], size * 2, INMOST_MPI_DATA_ENUM_TYPE, MPI_SUM,
comm));
//std::cout << GetRank() << " MPI_Allreduce " << __FILE__ << ":" << __LINE__ << " incoming " << incoming[size*2+rank] << " size " << incoming[size*3+rank] << std::endl;
//prepare array that helps exchanging vector values
requests.resize(2*vector_exchange_recv[0] + incoming[size*2+rank]);
requests.resize(2 * vector_exchange_recv[0] + incoming[size * 2 + rank]);
INMOST_DATA_ENUM_TYPE j = 1;
for(INMOST_DATA_ENUM_TYPE k = 0; k < vector_exchange_recv[0]; k++) //send rows that i want to receive
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
j += vector_exchange_recv[j+1] + 2;
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
j += vector_exchange_recv[j + 1] + 2;
}
recv_row_sizes.resize(incoming[size*3+rank]);
vector_exchange_send.resize(1+incoming[size*2+rank]*2+incoming[size*3+rank]);
recv_row_sizes.resize(incoming[size * 3 + rank]);
vector_exchange_send.resize(1 + incoming[size * 2 + rank] * 2 + incoming[size * 3 + rank]);
vector_exchange_send[0] = 0;
j = 1;