Merge branch 'PolySmooth' into development

This commit is contained in:
sfilippone
2024-07-05 16:50:26 +02:00
118 changed files with 8202 additions and 783 deletions
+4 -4
View File
@@ -22,22 +22,22 @@ MPFOBJS=$(SMPFOBJS) $(DMPFOBJS) $(CMPFOBJS) $(ZMPFOBJS)
MPCOBJS=amg_dslud_interface.o amg_zslud_interface.o
DINNEROBJS= amg_dmlprec_bld.o amg_dfile_prec_descr.o \
DINNEROBJS= amg_dmlprec_bld.o amg_dfile_prec_descr.o amg_dfile_prec_memory_use.o \
amg_d_smoothers_bld.o amg_d_hierarchy_bld.o amg_d_hierarchy_rebld.o \
amg_dmlprec_aply.o \
$(DMPFOBJS) amg_d_extprol_bld.o
SINNEROBJS= amg_smlprec_bld.o amg_sfile_prec_descr.o \
SINNEROBJS= amg_smlprec_bld.o amg_sfile_prec_descr.o amg_sfile_prec_memory_use.o \
amg_s_smoothers_bld.o amg_s_hierarchy_bld.o amg_s_hierarchy_rebld.o \
amg_smlprec_aply.o \
$(SMPFOBJS) amg_s_extprol_bld.o
ZINNEROBJS= amg_zmlprec_bld.o amg_zfile_prec_descr.o \
ZINNEROBJS= amg_zmlprec_bld.o amg_zfile_prec_descr.o amg_zfile_prec_memory_use.o \
amg_z_smoothers_bld.o amg_z_hierarchy_bld.o amg_z_hierarchy_rebld.o \
amg_zmlprec_aply.o \
$(ZMPFOBJS) amg_z_extprol_bld.o
CINNEROBJS= amg_cmlprec_bld.o amg_cfile_prec_descr.o \
CINNEROBJS= amg_cmlprec_bld.o amg_cfile_prec_descr.o amg_cfile_prec_memory_use.o \
amg_c_smoothers_bld.o amg_c_hierarchy_bld.o amg_c_hierarchy_rebld.o \
amg_cmlprec_aply.o \
$(CMPFOBJS) amg_c_extprol_bld.o
+28 -16
View File
@@ -67,12 +67,13 @@ void dMatchBoxPC(MilanLongInt NLVer, MilanLongInt NLEdge,
#endif
#define TIME_TRACKER
#ifdef TIME_TRACKER
double tmr = MPI_Wtime();
#endif
#undef TIME_TRACKER
#ifdef TIME_TRACKER
double tmr = MPI_Wtime();
#endif
#ifdef OPENMP
#if defined(OPENMP)
//fprintf(stderr,"Warning: using buggy OpenMP matching!\n");
dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(NLVer, NLEdge,
verLocPtr, verLocInd, edgeLocWeight,
verDistance, Mate,
@@ -91,11 +92,11 @@ void dMatchBoxPC(MilanLongInt NLVer, MilanLongInt NLEdge,
#endif
#ifdef TIME_TRACKER
tmr = MPI_Wtime() - tmr;
fprintf(stderr, "Elaboration time: %f for %ld nodes\n", tmr, NLVer);
#endif
#ifdef TIME_TRACKER
tmr = MPI_Wtime() - tmr;
fprintf(stderr, "Elaboration time: %f for %ld nodes\n", tmr, NLVer);
#endif
#endif
}
@@ -113,13 +114,24 @@ void sMatchBoxPC(MilanLongInt NLVer, MilanLongInt NLEdge,
fprintf(stderr,"MatchBoxPC: rank %d nlver %ld nledge %ld [ %ld %ld ]\n",
myRank,NLVer, NLEdge,verDistance[0],verDistance[1]);
#endif
#if defined(OPENMP)
//fprintf(stderr,"Warning: using buggy OpenMP matching!\n");
salgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(NLVer, NLEdge,
verLocPtr, verLocInd, edgeLocWeight,
verDistance, Mate,
myRank, numProcs, C_comm,
msgIndSent, msgActualSent, msgPercent,
ph0_time, ph1_time, ph2_time,
ph1_card, ph2_card );
#else
salgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateC(NLVer, NLEdge,
verLocPtr, verLocInd, edgeLocWeight,
verDistance, Mate,
myRank, numProcs, C_comm,
msgIndSent, msgActualSent, msgPercent,
ph0_time, ph1_time, ph2_time,
ph1_card, ph2_card );
verLocPtr, verLocInd, edgeLocWeight,
verDistance, Mate,
myRank, numProcs, C_comm,
msgIndSent, msgActualSent, msgPercent,
ph0_time, ph1_time, ph2_time,
ph1_card, ph2_card );
#endif
#endif
}
+407 -239
View File
@@ -59,7 +59,11 @@
#include <assert.h>
#include <map>
#include <vector>
#ifdef OPENMP
// OpenMP is included and used if and only if the OpenMP version of the matching
// is required
#include "omp.h"
#endif
#include "primitiveDataTypeDefinitions.h"
#include "dataStrStaticQueue.h"
@@ -177,252 +181,416 @@ extern "C"
#define MilanRealMin MINUS_INFINITY
#endif
// Function of find the owner of a ghost vertex using binary search:
MilanInt findOwnerOfGhost(MilanLongInt vtxIndex, MilanLongInt *mVerDistance,
MilanInt myRank, MilanInt numProcs);
/* These functions are only used in the experimental OMP implementation, if that
is disabled there is no reason to actually compile or reference them. */
MilanLongInt firstComputeCandidateMate(MilanLongInt adj1,
MilanLongInt adj2,
MilanLongInt *verLocInd,
MilanReal *edgeLocWeight);
// Function of find the owner of a ghost vertex using binary search:
MilanInt findOwnerOfGhost(MilanLongInt vtxIndex, MilanLongInt *mVerDistance,
MilanInt myRank, MilanInt numProcs);
MilanLongInt firstComputeCandidateMateD(MilanLongInt adj1,
MilanLongInt adj2,
MilanLongInt *verLocInd,
MilanReal *edgeLocWeight);
void queuesTransfer(vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner);
void queuesTransfer(vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner);
bool isAlreadyMatched(MilanLongInt node,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap);
MilanLongInt computeCandidateMateD(MilanLongInt adj1,
MilanLongInt adj2,
MilanReal *edgeLocWeight,
MilanLongInt k,
MilanLongInt *verLocInd,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap);
void initialize(MilanLongInt NLVer, MilanLongInt NLEdge,
MilanLongInt StartIndex, MilanLongInt EndIndex,
MilanLongInt *numGhostEdgesPtr,
MilanLongInt *numGhostVerticesPtr,
MilanLongInt *S,
MilanLongInt *verLocInd,
MilanLongInt *verLocPtr,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
vector<MilanLongInt> &Counter,
vector<MilanLongInt> &verGhostPtr,
vector<MilanLongInt> &verGhostInd,
vector<MilanLongInt> &tempCounter,
vector<MilanLongInt> &GMate,
vector<MilanLongInt> &Message,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
MilanLongInt *&candidateMate,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner);
void clean(MilanLongInt NLVer,
MilanInt myRank,
MilanLongInt MessageIndex,
vector<MPI_Request> &SRequest,
vector<MPI_Status> &SStatus,
MilanInt BufferSize,
MilanLongInt *Buffer,
MilanLongInt msgActual,
MilanLongInt *msgActualSent,
MilanLongInt msgInd,
MilanLongInt *msgIndSent,
MilanLongInt NumMessagesBundled,
MilanReal *msgPercent);
void PARALLEL_COMPUTE_CANDIDATE_MATE_BD(MilanLongInt NLVer,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanInt myRank,
MilanReal *edgeLocWeight,
MilanLongInt *candidateMate);
void PARALLEL_PROCESS_EXPOSED_VERTEX_BD(MilanLongInt NLVer,
MilanLongInt *candidateMate,
MilanLongInt *verLocInd,
MilanLongInt *verLocPtr,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *Mate,
vector<MilanLongInt> &GMate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanReal *edgeLocWeight,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *NumMessagesBundledPtr,
MilanLongInt *SPtr,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner);
void PROCESS_CROSS_EDGE(MilanLongInt *edge,
MilanLongInt *SPtr);
void processMatchedVerticesD(
MilanLongInt NLVer,
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *NumMessagesBundledPtr,
MilanLongInt *SPtr,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
MilanLongInt *candidateMate,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanReal *edgeLocWeight,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner);
void processMatchedVerticesAndSendMessagesD(
MilanLongInt NLVer,
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *NumMessagesBundledPtr,
MilanLongInt *SPtr,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
MilanLongInt *candidateMate,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanReal *edgeLocWeight,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner,
MPI_Comm comm,
MilanLongInt *msgActual,
vector<MilanLongInt> &Message);
void sendBundledMessages(MilanLongInt *numGhostEdgesPtr,
MilanInt *BufferSizePtr,
MilanLongInt *Buffer,
vector<MilanLongInt> &PCumulative,
vector<MilanLongInt> &PMessageBundle,
vector<MilanLongInt> &PSizeInfoMessages,
MilanLongInt *PCounter,
MilanLongInt NumMessagesBundled,
MilanLongInt *msgActualPtr,
MilanLongInt *MessageIndexPtr,
MilanInt numProcs,
MilanInt myRank,
MPI_Comm comm,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MPI_Request> &SRequest,
vector<MPI_Status> &SStatus);
void processMessagesD(
MilanLongInt NLVer,
MilanLongInt *Mate,
MilanLongInt *candidateMate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
vector<MilanLongInt> &GMate,
vector<MilanLongInt> &Counter,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *msgActualPtr,
MilanReal *edgeLocWeight,
MilanLongInt *verDistance,
MilanLongInt *verLocPtr,
MilanLongInt k,
MilanLongInt *verLocInd,
MilanInt numProcs,
MilanInt myRank,
MPI_Comm comm,
vector<MilanLongInt> &Message,
MilanLongInt numGhostEdges,
MilanLongInt u,
MilanLongInt v,
MilanLongInt *SPtr,
vector<MilanLongInt> &U);
void extractUChunk(
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU);
bool isAlreadyMatched(MilanLongInt node,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap);
MilanLongInt firstComputeCandidateMateS(MilanLongInt adj1,
MilanLongInt adj2,
MilanLongInt *verLocInd,
MilanFloat *edgeLocWeight);
MilanLongInt computeCandidateMate(MilanLongInt adj1,
MilanLongInt adj2,
MilanReal *edgeLocWeight,
MilanLongInt k,
MilanLongInt *verLocInd,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap);
MilanLongInt computeCandidateMateS(MilanLongInt adj1,
MilanLongInt adj2,
MilanFloat *edgeLocWeight,
MilanLongInt k,
MilanLongInt *verLocInd,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap);
void PARALLEL_COMPUTE_CANDIDATE_MATE_BS(MilanLongInt NLVer,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanInt myRank,
MilanFloat *edgeLocWeight,
MilanLongInt *candidateMate);
void PARALLEL_PROCESS_EXPOSED_VERTEX_BS(MilanLongInt NLVer,
MilanLongInt *candidateMate,
MilanLongInt *verLocInd,
MilanLongInt *verLocPtr,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *Mate,
vector<MilanLongInt> &GMate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanFloat *edgeLocWeight,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *NumMessagesBundledPtr,
MilanLongInt *SPtr,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner);
void processMatchedVerticesS(
MilanLongInt NLVer,
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *NumMessagesBundledPtr,
MilanLongInt *SPtr,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
MilanLongInt *candidateMate,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanFloat *edgeLocWeight,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner);
void processMatchedVerticesAndSendMessagesS(
MilanLongInt NLVer,
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *NumMessagesBundledPtr,
MilanLongInt *SPtr,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
MilanLongInt *candidateMate,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanFloat *edgeLocWeight,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner,
MPI_Comm comm,
MilanLongInt *msgActual,
vector<MilanLongInt> &Message);
void processMessagesS(
MilanLongInt NLVer,
MilanLongInt *Mate,
MilanLongInt *candidateMate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
vector<MilanLongInt> &GMate,
vector<MilanLongInt> &Counter,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *msgActualPtr,
MilanFloat *edgeLocWeight,
MilanLongInt *verDistance,
MilanLongInt *verLocPtr,
MilanLongInt k,
MilanLongInt *verLocInd,
MilanInt numProcs,
MilanInt myRank,
MPI_Comm comm,
vector<MilanLongInt> &Message,
MilanLongInt numGhostEdges,
MilanLongInt u,
MilanLongInt v,
MilanLongInt *SPtr,
vector<MilanLongInt> &U);
void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
MilanLongInt NLVer, MilanLongInt NLEdge,
MilanLongInt *verLocPtr, MilanLongInt *verLocInd, MilanReal *edgeLocWeight,
MilanLongInt *verDistance,
MilanLongInt *Mate,
MilanInt myRank, MilanInt numProcs, MPI_Comm comm,
MilanLongInt *msgIndSent, MilanLongInt *msgActualSent, MilanReal *msgPercent,
MilanReal *ph0_time, MilanReal *ph1_time, MilanReal *ph2_time,
MilanLongInt *ph1_card, MilanLongInt *ph2_card);
void initialize(MilanLongInt NLVer, MilanLongInt NLEdge,
MilanLongInt StartIndex, MilanLongInt EndIndex,
MilanLongInt *numGhostEdgesPtr,
MilanLongInt *numGhostVerticesPtr,
MilanLongInt *S,
MilanLongInt *verLocInd,
MilanLongInt *verLocPtr,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
vector<MilanLongInt> &Counter,
vector<MilanLongInt> &verGhostPtr,
vector<MilanLongInt> &verGhostInd,
vector<MilanLongInt> &tempCounter,
vector<MilanLongInt> &GMate,
vector<MilanLongInt> &Message,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
MilanLongInt *&candidateMate,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner);
void salgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
MilanLongInt NLVer, MilanLongInt NLEdge,
MilanLongInt *verLocPtr, MilanLongInt *verLocInd, MilanFloat *edgeLocWeight,
MilanLongInt *verDistance,
MilanLongInt *Mate,
MilanInt myRank, MilanInt numProcs, MPI_Comm comm,
MilanLongInt *msgIndSent, MilanLongInt *msgActualSent, MilanReal *msgPercent,
MilanReal *ph0_time, MilanReal *ph1_time, MilanReal *ph2_time,
MilanLongInt *ph1_card, MilanLongInt *ph2_card);
void clean(MilanLongInt NLVer,
MilanInt myRank,
MilanLongInt MessageIndex,
vector<MPI_Request> &SRequest,
vector<MPI_Status> &SStatus,
MilanInt BufferSize,
MilanLongInt *Buffer,
MilanLongInt msgActual,
MilanLongInt *msgActualSent,
MilanLongInt msgInd,
MilanLongInt *msgIndSent,
MilanLongInt NumMessagesBundled,
MilanReal *msgPercent);
void PARALLEL_COMPUTE_CANDIDATE_MATE_B(MilanLongInt NLVer,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanInt myRank,
MilanReal *edgeLocWeight,
MilanLongInt *candidateMate);
void PARALLEL_PROCESS_EXPOSED_VERTEX_B(MilanLongInt NLVer,
MilanLongInt *candidateMate,
MilanLongInt *verLocInd,
MilanLongInt *verLocPtr,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *Mate,
vector<MilanLongInt> &GMate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanReal *edgeLocWeight,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *NumMessagesBundledPtr,
MilanLongInt *SPtr,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner);
void PROCESS_CROSS_EDGE(MilanLongInt *edge,
MilanLongInt *SPtr);
void processMatchedVertices(
MilanLongInt NLVer,
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *NumMessagesBundledPtr,
MilanLongInt *SPtr,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
MilanLongInt *candidateMate,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanReal *edgeLocWeight,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner);
void processMatchedVerticesAndSendMessages(
MilanLongInt NLVer,
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *NumMessagesBundledPtr,
MilanLongInt *SPtr,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
MilanLongInt *candidateMate,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanReal *edgeLocWeight,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner,
MPI_Comm comm,
MilanLongInt *msgActual,
vector<MilanLongInt> &Message);
void sendBundledMessages(MilanLongInt *numGhostEdgesPtr,
MilanInt *BufferSizePtr,
MilanLongInt *Buffer,
vector<MilanLongInt> &PCumulative,
vector<MilanLongInt> &PMessageBundle,
vector<MilanLongInt> &PSizeInfoMessages,
MilanLongInt *PCounter,
MilanLongInt NumMessagesBundled,
MilanLongInt *msgActualPtr,
MilanLongInt *MessageIndexPtr,
MilanInt numProcs,
MilanInt myRank,
MPI_Comm comm,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MPI_Request> &SRequest,
vector<MPI_Status> &SStatus);
void processMessages(
MilanLongInt NLVer,
MilanLongInt *Mate,
MilanLongInt *candidateMate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
vector<MilanLongInt> &GMate,
vector<MilanLongInt> &Counter,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCardPtr,
MilanLongInt *msgIndPtr,
MilanLongInt *msgActualPtr,
MilanReal *edgeLocWeight,
MilanLongInt *verDistance,
MilanLongInt *verLocPtr,
MilanLongInt k,
MilanLongInt *verLocInd,
MilanInt numProcs,
MilanInt myRank,
MPI_Comm comm,
vector<MilanLongInt> &Message,
MilanLongInt numGhostEdges,
MilanLongInt u,
MilanLongInt v,
MilanLongInt *SPtr,
vector<MilanLongInt> &U);
void extractUChunk(
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU);
void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
MilanLongInt NLVer, MilanLongInt NLEdge,
MilanLongInt *verLocPtr, MilanLongInt *verLocInd, MilanReal *edgeLocWeight,
MilanLongInt *verDistance,
MilanLongInt *Mate,
MilanInt myRank, MilanInt numProcs, MPI_Comm comm,
MilanLongInt *msgIndSent, MilanLongInt *msgActualSent, MilanReal *msgPercent,
MilanReal *ph0_time, MilanReal *ph1_time, MilanReal *ph2_time,
MilanLongInt *ph1_card, MilanLongInt *ph2_card);
void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateC(
MilanLongInt NLVer, MilanLongInt NLEdge,
@@ -1303,16 +1303,16 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateC(
// SINGLE PRECISION VERSION
void salgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateC(
MilanLongInt NLVer, MilanLongInt NLEdge,
MilanLongInt* verLocPtr, MilanLongInt* verLocInd,
MilanFloat* edgeLocWeight,
MilanLongInt* verDistance,
MilanLongInt* Mate,
MilanInt myRank, MilanInt numProcs, MPI_Comm comm,
MilanLongInt* msgIndSent, MilanLongInt* msgActualSent,
MilanReal* msgPercent,
MilanReal* ph0_time, MilanReal* ph1_time, MilanReal* ph2_time,
MilanLongInt* ph1_card, MilanLongInt* ph2_card ) {
MilanLongInt NLVer, MilanLongInt NLEdge,
MilanLongInt* verLocPtr, MilanLongInt* verLocInd,
MilanFloat* edgeLocWeight,
MilanLongInt* verDistance,
MilanLongInt* Mate,
MilanInt myRank, MilanInt numProcs, MPI_Comm comm,
MilanLongInt* msgIndSent, MilanLongInt* msgActualSent,
MilanReal* msgPercent,
MilanReal* ph0_time, MilanReal* ph1_time, MilanReal* ph2_time,
MilanLongInt* ph1_card, MilanLongInt* ph2_card ) {
#if !defined(SERIAL_MPI)
#ifdef PRINT_DEBUG_INFO_
cout<<"\n("<<myRank<<")Within algoEdgeApproxDominatingEdgesLinearSearchMessageBundling()"; fflush(stdout);
@@ -1,5 +1,4 @@
#include "MatchBoxPC.h"
#ifdef OPENMP
// ***********************************************************************
//
// MatchboxP: A C++ library for approximate weighted matching
@@ -244,7 +243,7 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
* PARALLEL_COMPUTE_CANDIDATE_MATE_B is now totally parallel.
*/
PARALLEL_COMPUTE_CANDIDATE_MATE_B(NLVer,
PARALLEL_COMPUTE_CANDIDATE_MATE_BD(NLVer,
verLocPtr,
verLocInd,
myRank,
@@ -269,7 +268,7 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
* TODO: Test when it's actually more efficient to execute this code
* in parallel.
*/
PARALLEL_PROCESS_EXPOSED_VERTEX_B(NLVer,
PARALLEL_PROCESS_EXPOSED_VERTEX_BD(NLVer,
candidateMate,
verLocInd,
verLocPtr,
@@ -321,7 +320,7 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
vector<MilanLongInt> UChunkBeingProcessed;
UChunkBeingProcessed.reserve(UCHUNK);
processMatchedVertices(NLVer,
processMatchedVerticesD(NLVer,
UChunkBeingProcessed,
U,
privateU,
@@ -430,7 +429,7 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
/////////////////////////// PROCESS MATCHED VERTICES //////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
processMatchedVerticesAndSendMessages(NLVer,
processMatchedVerticesAndSendMessagesD(NLVer,
UChunkBeingProcessed,
U,
privateU,
@@ -490,8 +489,8 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
///////////////////////////////////////////////////////////////////////////////////
/////////////////////////// PROCESS MESSAGES //////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
processMessages(NLVer,
//startTime = MPI_Wtime();
processMessagesD(NLVer,
Mate,
candidateMate,
Ghost2LocalMap,
@@ -556,6 +555,488 @@ void dalgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
*ph2_card = myCard; // Cardinality at the end of Phase-2
}
// End of algoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMate
void salgoDistEdgeApproxDomEdgesLinearSearchMesgBndlSmallMateCMP(
MilanLongInt NLVer, MilanLongInt NLEdge,
MilanLongInt *verLocPtr, MilanLongInt *verLocInd,
MilanFloat *edgeLocWeight,
MilanLongInt *verDistance,
MilanLongInt *Mate,
MilanInt myRank, MilanInt numProcs, MPI_Comm comm,
MilanLongInt *msgIndSent, MilanLongInt *msgActualSent,
MilanReal *msgPercent,
MilanReal *ph0_time, MilanReal *ph1_time, MilanReal *ph2_time,
MilanLongInt *ph1_card, MilanLongInt *ph2_card)
{
/*
* verDistance: it's a vector long as the number of processors.
* verDistance[i] contains the first node index of the i-th processor
* verDistance[i + 1] contains the last node index of the i-th processor
* NLVer: number of elements in the LocPtr
* NLEdge: number of edges assigned to the current processor
*
* Contains the portion of matrix assigned to the processor in
* Yale notation
* verLocInd: contains the positions on row of the matrix
* verLocPtr: i-th value is the position of the first element on the i-th row and
* i+1-th value is the position of the first element on the i+1-th row
*/
#if !defined(SERIAL_MPI)
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Within algoEdgeApproxDominatingEdgesLinearSearchMessageBundling()";
fflush(stdout);
#endif
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ") verDistance [" ;
for (int i = 0; i < numProcs; i++)
cout << verDistance[i] << "," << verDistance[i+1];
cout << "]\n";
fflush(stdout);
#endif
#ifdef DEBUG_HANG_
if (myRank == 0) {
cout << "\n(" << myRank << ") verDistance [" ;
for (int i = 0; i < numProcs; i++)
cout << verDistance[i] << "," ;
cout << verDistance[numProcs]<< "]\n";
}
fflush(stdout);
#endif
// The starting vertex owned by the current rank
MilanLongInt StartIndex = verDistance[myRank];
// The ending vertex owned by the current rank
MilanLongInt EndIndex = verDistance[myRank + 1] - 1;
MPI_Status computeStatus;
MilanLongInt msgActual = 0, msgInd = 0;
MilanFloat heaviestEdgeWt = 0.0f; // Assumes positive weight
MilanReal startTime, finishTime;
startTime = MPI_Wtime();
// Data structures for sending and receiving messages:
vector<MilanLongInt> Message; // [ u, v, message_type ]
Message.resize(3, -1);
// Data structures for Message Bundling:
// Although up to two messages can be sent along any cross edge,
// only one message will be sent in the initialization phase -
// one of: REQUEST/FAILURE/SUCCESS
vector<MilanLongInt> QLocalVtx, QGhostVtx, QMsgType;
// Changed by Fabio to be an integer, addresses needs to be integers!
vector<MilanInt> QOwner;
MilanLongInt *PCounter = new MilanLongInt[numProcs];
for (int i = 0; i < numProcs; i++)
PCounter[i] = 0;
MilanLongInt NumMessagesBundled = 0;
// TODO when the last computational section will be refactored this could be eliminated
// Changed by Fabio to be an integer, addresses needs to be integers!
MilanInt ghostOwner = 0;
MilanLongInt *candidateMate = nullptr;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")NV: " << NLVer << " Edges: " << NLEdge;
fflush(stdout);
cout << "\n(" << myRank << ")StartIndex: " << StartIndex << " EndIndex: " << EndIndex;
fflush(stdout);
#endif
// Other Variables:
MilanLongInt u = -1, v = -1, w = -1, i = 0;
MilanLongInt k = -1, adj1 = -1, adj2 = -1;
MilanLongInt k1 = -1, adj11 = -1, adj12 = -1;
MilanLongInt myCard = 0;
// Build the Ghost Vertex Set: Vg
// Map each ghost vertex to a local vertex
map<MilanLongInt, MilanLongInt> Ghost2LocalMap;
// Store the edge count for each ghost vertex
vector<MilanLongInt> Counter;
// Number of Ghost vertices
MilanLongInt numGhostVertices = 0, numGhostEdges = 0;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")About to compute Ghost Vertices...";
fflush(stdout);
#endif
#ifdef DEBUG_HANG_
if (myRank == 0)
cout << "\n(" << myRank << ")About to compute Ghost Vertices...";
fflush(stdout);
#endif
// Define Adjacency Lists for Ghost Vertices:
// cout<<"Building Ghost data structures ... \n\n";
vector<MilanLongInt> verGhostPtr, verGhostInd, tempCounter;
// Mate array for ghost vertices:
vector<MilanLongInt> GMate; // Proportional to the number of ghost vertices
MilanLongInt S;
MilanLongInt privateMyCard = 0;
vector<MilanLongInt> PCumulative, PMessageBundle, PSizeInfoMessages;
vector<MPI_Request> SRequest; // Requests that are used for each send message
vector<MPI_Status> SStatus; // Status of sent messages, used in MPI_Wait
MilanLongInt MessageIndex = 0; // Pointer for current message
MilanInt BufferSize;
MilanLongInt *Buffer;
vector<MilanLongInt> privateQLocalVtx, privateQGhostVtx, privateQMsgType;
vector<MilanInt> privateQOwner;
vector<MilanLongInt> U, privateU;
initialize(NLVer, NLEdge, StartIndex,
EndIndex, &numGhostEdges,
&numGhostVertices, &S,
verLocInd, verLocPtr,
Ghost2LocalMap, Counter,
verGhostPtr, verGhostInd,
tempCounter, GMate,
Message, QLocalVtx,
QGhostVtx, QMsgType, QOwner,
candidateMate, U,
privateU,
privateQLocalVtx,
privateQGhostVtx,
privateQMsgType,
privateQOwner);
finishTime = MPI_Wtime();
*ph0_time = finishTime - startTime; // Time taken for Phase-0: Initialization
#ifdef DEBUG_HANG_
cout << myRank << " Finished initialization" << endl;
fflush(stdout);
#endif
startTime = MPI_Wtime();
/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// INITIALIZATION /////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// Compute the Initial Matching Set:
/*
* OMP PARALLEL_COMPUTE_CANDIDATE_MATE_B has been splitted from
* PARALLEL_PROCESS_EXPOSED_VERTEX_B in order to better parallelize
* the two.
* PARALLEL_COMPUTE_CANDIDATE_MATE_B is now totally parallel.
*/
PARALLEL_COMPUTE_CANDIDATE_MATE_BS(NLVer,
verLocPtr,
verLocInd,
myRank,
edgeLocWeight,
candidateMate);
#ifdef DEBUG_HANG_
cout << myRank << " Finished Exposed Vertex" << endl;
fflush(stdout);
#if 0
cout << myRank << " candidateMate after parallelCompute " <<endl;
for (int i=0; i<NLVer; i++) {
cout << candidateMate[i] << " " ;
}
cout << endl;
#endif
#endif
/*
* PARALLEL_PROCESS_EXPOSED_VERTEX_B
* TODO: write comment
*
* TODO: Test when it's actually more efficient to execute this code
* in parallel.
*/
PARALLEL_PROCESS_EXPOSED_VERTEX_BS(NLVer,
candidateMate,
verLocInd,
verLocPtr,
StartIndex,
EndIndex,
Mate,
GMate,
Ghost2LocalMap,
edgeLocWeight,
&myCard,
&msgInd,
&NumMessagesBundled,
&S,
verDistance,
PCounter,
Counter,
myRank,
numProcs,
U,
privateU,
QLocalVtx,
QGhostVtx,
QMsgType,
QOwner,
privateQLocalVtx,
privateQGhostVtx,
privateQMsgType,
privateQOwner);
tempCounter.clear(); // Do not need this any more
#ifdef DEBUG_HANG_
cout << myRank << " Finished Exposed Vertex" << endl;
fflush(stdout);
#if 0
cout << myRank << " Mate after Exposed Vertices " <<endl;
for (int i=0; i<NLVer; i++) {
cout << Mate[i] << " " ;
}
cout << endl;
#endif
#endif
///////////////////////////////////////////////////////////////////////////////////
/////////////////////////// PROCESS MATCHED VERTICES //////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
// TODO what would be the optimal UCHUNK
vector<MilanLongInt> UChunkBeingProcessed;
UChunkBeingProcessed.reserve(UCHUNK);
processMatchedVerticesS(NLVer,
UChunkBeingProcessed,
U,
privateU,
StartIndex,
EndIndex,
&myCard,
&msgInd,
&NumMessagesBundled,
&S,
verLocPtr,
verLocInd,
verDistance,
PCounter,
Counter,
myRank,
numProcs,
candidateMate,
GMate,
Mate,
Ghost2LocalMap,
edgeLocWeight,
QLocalVtx,
QGhostVtx,
QMsgType,
QOwner,
privateQLocalVtx,
privateQGhostVtx,
privateQMsgType,
privateQOwner);
#ifdef DEBUG_HANG_
cout << myRank << " Finished Process Vertices" << endl;
fflush(stdout);
#if 0
cout << myRank << " Mate after Matched Vertices " <<endl;
for (int i=0; i<NLVer; i++) {
cout << Mate[i] << " " ;
}
cout << endl;
#endif
#endif
/////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////// SEND BUNDLED MESSAGES /////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
sendBundledMessages(&numGhostEdges,
&BufferSize,
Buffer,
PCumulative,
PMessageBundle,
PSizeInfoMessages,
PCounter,
NumMessagesBundled,
&msgActual,
&MessageIndex,
numProcs,
myRank,
comm,
QLocalVtx,
QGhostVtx,
QMsgType,
QOwner,
SRequest,
SStatus);
///////////////////////// END OF SEND BUNDLED MESSAGES //////////////////////////////////
finishTime = MPI_Wtime();
*ph1_time = finishTime - startTime; // Time taken for Phase-1
#ifdef DEBUG_HANG_
cout << myRank << " Finished sendBundles" << endl;
fflush(stdout);
#endif
*ph1_card = myCard; // Cardinality at the end of Phase-1
startTime = MPI_Wtime();
/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////// MAIN LOOP //////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
// Main While Loop:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << "=========================************===============================" << endl;
fflush(stdout);
fflush(stdout);
#endif
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Entering While(true) loop..";
fflush(stdout);
#endif
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << "=========================************===============================" << endl;
fflush(stdout);
fflush(stdout);
#endif
while (true) {
#ifdef DEBUG_HANG_
//if (myRank == 0)
cout << "\n(" << myRank << ") Main loop" << endl;
fflush(stdout);
#endif
///////////////////////////////////////////////////////////////////////////////////
/////////////////////////// PROCESS MATCHED VERTICES //////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
processMatchedVerticesAndSendMessagesS(NLVer,
UChunkBeingProcessed,
U,
privateU,
StartIndex,
EndIndex,
&myCard,
&msgInd,
&NumMessagesBundled,
&S,
verLocPtr,
verLocInd,
verDistance,
PCounter,
Counter,
myRank,
numProcs,
candidateMate,
GMate,
Mate,
Ghost2LocalMap,
edgeLocWeight,
QLocalVtx,
QGhostVtx,
QMsgType,
QOwner,
privateQLocalVtx,
privateQGhostVtx,
privateQMsgType,
privateQOwner,
comm,
&msgActual,
Message);
///////////////////////// END OF PROCESS MATCHED VERTICES /////////////////////////
//// BREAK IF NO MESSAGES EXPECTED /////////
#ifdef DEBUG_HANG_
#if 0
cout << myRank << " Mate after ProcessMatchedAndSend phase "<<S <<endl;
for (int i=0; i<NLVer; i++) {
cout << Mate[i] << " " ;
}
cout << endl;
#endif
#endif
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Deciding whether to break: S= " << S << endl;
#endif
if (S == 0) {
#ifdef DEBUG_HANG_
cout << "\n(" << myRank << ") Breaking out" << endl;
fflush(stdout);
#endif
break;
}
///////////////////////////////////////////////////////////////////////////////////
/////////////////////////// PROCESS MESSAGES //////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
processMessagesS(NLVer,
Mate,
candidateMate,
Ghost2LocalMap,
GMate,
Counter,
StartIndex,
EndIndex,
&myCard,
&msgInd,
&msgActual,
edgeLocWeight,
verDistance,
verLocPtr,
k,
verLocInd,
numProcs,
myRank,
comm,
Message,
numGhostEdges,
u,
v,
&S,
U);
///////////////////////// END OF PROCESS MESSAGES /////////////////////////////////
#ifdef DEBUG_HANG_
#if 0
cout << myRank << " Mate after ProcessMessages phase "<<S <<endl;
for (int i=0; i<NLVer; i++) {
cout << Mate[i] << " " ;
}
cout << endl;
#endif
#endif
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Finished Message processing phase: S= " << S;
fflush(stdout);
cout << "\n(" << myRank << ")** SENT : ACTUAL= " << msgActual;
fflush(stdout);
cout << "\n(" << myRank << ")** SENT : INDIVIDUAL= " << msgInd << endl;
fflush(stdout);
#endif
} // End of while (true)
clean(NLVer,
myRank,
MessageIndex,
SRequest,
SStatus,
BufferSize,
Buffer,
msgActual,
msgActualSent,
msgInd,
msgIndSent,
NumMessagesBundled,
msgPercent);
finishTime = MPI_Wtime();
*ph2_time = finishTime - startTime; // Time taken for Phase-2
*ph2_card = myCard; // Cardinality at the end of Phase-2
}
#endif
#endif
@@ -275,7 +275,8 @@ subroutine amg_c_soc1_map_bld(iorder,theta,clean_zeros,a,desc_a,nlaggr,ilaggr,in
disjoint = all(ilaggr(icol(1:ip)) == -(nr+1)).or.(ip==0)
if (disjoint) then
locnaggr(kk) = locnaggr(kk) + 1
itmp = (bnds(kk)-1+locnaggr(kk))*nths+kk
itmp = (bnds(kk)-1+locnaggr(kk)) !be careful about overflow
itmp = itmp*nths+kk
if (itmp < (bnds(kk)-1+locnaggr(kk))) then
!$omp atomic update
info = max(12345678,info)
@@ -309,7 +309,8 @@ subroutine amg_c_soc2_map_bld(iorder,theta,clean_zeros,a,desc_a,nlaggr,ilaggr,in
!
if (disjoint) then
locnaggr(kk) = locnaggr(kk) + 1
itmp = (bnds(kk)-1+locnaggr(kk))*nths+kk
itmp = (bnds(kk)-1+locnaggr(kk)) !be careful about overflow
itmp = itmp*nths+kk
if (itmp < (bnds(kk)-1+locnaggr(kk))) then
!$omp atomic update
info = max(12345678,info)
@@ -275,7 +275,8 @@ subroutine amg_d_soc1_map_bld(iorder,theta,clean_zeros,a,desc_a,nlaggr,ilaggr,in
disjoint = all(ilaggr(icol(1:ip)) == -(nr+1)).or.(ip==0)
if (disjoint) then
locnaggr(kk) = locnaggr(kk) + 1
itmp = (bnds(kk)-1+locnaggr(kk))*nths+kk
itmp = (bnds(kk)-1+locnaggr(kk)) !be careful about overflow
itmp = itmp*nths+kk
if (itmp < (bnds(kk)-1+locnaggr(kk))) then
!$omp atomic update
info = max(12345678,info)
@@ -309,7 +309,8 @@ subroutine amg_d_soc2_map_bld(iorder,theta,clean_zeros,a,desc_a,nlaggr,ilaggr,in
!
if (disjoint) then
locnaggr(kk) = locnaggr(kk) + 1
itmp = (bnds(kk)-1+locnaggr(kk))*nths+kk
itmp = (bnds(kk)-1+locnaggr(kk)) !be careful about overflow
itmp = itmp*nths+kk
if (itmp < (bnds(kk)-1+locnaggr(kk))) then
!$omp atomic update
info = max(12345678,info)
@@ -275,7 +275,8 @@ subroutine amg_s_soc1_map_bld(iorder,theta,clean_zeros,a,desc_a,nlaggr,ilaggr,in
disjoint = all(ilaggr(icol(1:ip)) == -(nr+1)).or.(ip==0)
if (disjoint) then
locnaggr(kk) = locnaggr(kk) + 1
itmp = (bnds(kk)-1+locnaggr(kk))*nths+kk
itmp = (bnds(kk)-1+locnaggr(kk)) !be careful about overflow
itmp = itmp*nths+kk
if (itmp < (bnds(kk)-1+locnaggr(kk))) then
!$omp atomic update
info = max(12345678,info)
@@ -309,7 +309,8 @@ subroutine amg_s_soc2_map_bld(iorder,theta,clean_zeros,a,desc_a,nlaggr,ilaggr,in
!
if (disjoint) then
locnaggr(kk) = locnaggr(kk) + 1
itmp = (bnds(kk)-1+locnaggr(kk))*nths+kk
itmp = (bnds(kk)-1+locnaggr(kk)) !be careful about overflow
itmp = itmp*nths+kk
if (itmp < (bnds(kk)-1+locnaggr(kk))) then
!$omp atomic update
info = max(12345678,info)
@@ -275,7 +275,8 @@ subroutine amg_z_soc1_map_bld(iorder,theta,clean_zeros,a,desc_a,nlaggr,ilaggr,in
disjoint = all(ilaggr(icol(1:ip)) == -(nr+1)).or.(ip==0)
if (disjoint) then
locnaggr(kk) = locnaggr(kk) + 1
itmp = (bnds(kk)-1+locnaggr(kk))*nths+kk
itmp = (bnds(kk)-1+locnaggr(kk)) !be careful about overflow
itmp = itmp*nths+kk
if (itmp < (bnds(kk)-1+locnaggr(kk))) then
!$omp atomic update
info = max(12345678,info)
@@ -309,7 +309,8 @@ subroutine amg_z_soc2_map_bld(iorder,theta,clean_zeros,a,desc_a,nlaggr,ilaggr,in
!
if (disjoint) then
locnaggr(kk) = locnaggr(kk) + 1
itmp = (bnds(kk)-1+locnaggr(kk))*nths+kk
itmp = (bnds(kk)-1+locnaggr(kk)) !be careful about overflow
itmp = itmp*nths+kk
if (itmp < (bnds(kk)-1+locnaggr(kk))) then
!$omp atomic update
info = max(12345678,info)
-1
View File
@@ -1,5 +1,4 @@
#include "MatchBoxPC.h"
// TODO comment
#if !defined(SERIAL_MPI)
@@ -1,5 +1,4 @@
#include "MatchBoxPC.h"
/**
* Execute the research fr the Candidate Mate without controlling if the vertices are already matched.
* Returns the vertices with the highest weight
@@ -9,9 +8,8 @@
* @param edgeLocWeight
* @return
*/
#if !defined(SERIAL_MPI)
MilanLongInt firstComputeCandidateMate(MilanLongInt adj1,
MilanLongInt firstComputeCandidateMateD(MilanLongInt adj1,
MilanLongInt adj2,
MilanLongInt *verLocInd,
MilanReal *edgeLocWeight)
@@ -44,7 +42,7 @@ MilanLongInt firstComputeCandidateMate(MilanLongInt adj1,
* @param Ghost2LocalMap
* @return
*/
MilanLongInt computeCandidateMate(MilanLongInt adj1,
MilanLongInt computeCandidateMateD(MilanLongInt adj1,
MilanLongInt adj2,
MilanReal *edgeLocWeight,
MilanLongInt k,
@@ -62,7 +60,7 @@ MilanLongInt computeCandidateMate(MilanLongInt adj1,
for (k = adj1; k < adj2; k++) {
if (isAlreadyMatched(verLocInd[k], StartIndex, EndIndex, GMate, Mate, Ghost2LocalMap))
continue;
if ((edgeLocWeight[k] > heaviestEdgeWt) ||
((edgeLocWeight[k] == heaviestEdgeWt) && (w < verLocInd[k]))) {
heaviestEdgeWt = edgeLocWeight[k];
@@ -70,7 +68,71 @@ MilanLongInt computeCandidateMate(MilanLongInt adj1,
}
} // End of for loop
// End: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v)
return w;
}
MilanLongInt firstComputeCandidateMateS(MilanLongInt adj1,
MilanLongInt adj2,
MilanLongInt *verLocInd,
MilanFloat *edgeLocWeight)
{
MilanInt w = -1;
MilanFloat heaviestEdgeWt = 0.0f; // Assign the smallest
int finalK;
for (int k = adj1; k < adj2; k++) {
if ((edgeLocWeight[k] > heaviestEdgeWt) ||
((edgeLocWeight[k] == heaviestEdgeWt) && (w < verLocInd[k]))) {
heaviestEdgeWt = edgeLocWeight[k];
w = verLocInd[k];
finalK = k;
}
} // End of for loop
return finalK;
}
/**
* //TODO documentation
* @param adj1
* @param adj2
* @param edgeLocWeight
* @param k
* @param verLocInd
* @param StartIndex
* @param EndIndex
* @param GMate
* @param Mate
* @param Ghost2LocalMap
* @return
*/
MilanLongInt computeCandidateMateS(MilanLongInt adj1,
MilanLongInt adj2,
MilanFloat *edgeLocWeight,
MilanLongInt k,
MilanLongInt *verLocInd,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap)
{
// Start: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v)
MilanInt w = -1;
MilanFloat heaviestEdgeWt = 0.0f; // Assign the smallest Value
for (k = adj1; k < adj2; k++) {
if (isAlreadyMatched(verLocInd[k], StartIndex, EndIndex, GMate, Mate, Ghost2LocalMap))
continue;
if ((edgeLocWeight[k] > heaviestEdgeWt) ||
((edgeLocWeight[k] == heaviestEdgeWt) && (w < verLocInd[k]))) {
heaviestEdgeWt = edgeLocWeight[k];
w = verLocInd[k];
}
} // End of for loop
// End: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v)
return w;
}
#endif
+1 -2
View File
@@ -1,5 +1,4 @@
#include "MatchBoxPC.h"
void extractUChunk(
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
@@ -28,4 +27,4 @@ void extractUChunk(
}
} // End of critical U // End of critical U
}
}
@@ -1,5 +1,4 @@
#include "MatchBoxPC.h"
/// Find the owner of a ghost node:
MilanInt findOwnerOfGhost(MilanLongInt vtxIndex, MilanLongInt *mVerDistance,
MilanInt myRank, MilanInt numProcs)
+1 -2
View File
@@ -1,5 +1,4 @@
#include "MatchBoxPC.h"
void initialize(MilanLongInt NLVer, MilanLongInt NLEdge,
MilanLongInt StartIndex, MilanLongInt EndIndex,
MilanLongInt *numGhostEdges,
@@ -291,7 +290,7 @@ void initialize(MilanLongInt NLVer, MilanLongInt NLEdge,
//new (&U) staticQueue(NLVer + (*numGhostVertices));
U.reserve(NLVer + (*numGhostVertices));
// Initialize the private vectors
// Initialize the private vectors
privateQLocalVtx.reserve(*numGhostVertices);
privateQGhostVtx.reserve(*numGhostVertices);
privateQMsgType.reserve(*numGhostVertices);
+2 -3
View File
@@ -1,5 +1,4 @@
#include "MatchBoxPC.h"
/**
* //TODO documentation
* @param k
@@ -32,7 +31,7 @@ bool isAlreadyMatched(MilanLongInt node,
*/
MilanLongInt val;
if ((node < StartIndex) || (node > EndIndex)) // if ghost vertex
{
{
#pragma omp atomic read
val = GMate[Ghost2LocalMap[node]];
return val >= 0; // Already matched
@@ -43,4 +42,4 @@ bool isAlreadyMatched(MilanLongInt node,
val = Mate[node - StartIndex];
return val >= 0; // Already matched
}
}
@@ -1,7 +1,6 @@
#include "MatchBoxPC.h"
#if !defined(SERIAL_MPI)
void PARALLEL_COMPUTE_CANDIDATE_MATE_B(MilanLongInt NLVer,
void PARALLEL_COMPUTE_CANDIDATE_MATE_BD(MilanLongInt NLVer,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanInt myRank,
@@ -21,7 +20,35 @@ void PARALLEL_COMPUTE_CANDIDATE_MATE_B(MilanLongInt NLVer,
fflush(stdout);
#endif
// Start: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v)
candidateMate[v] = firstComputeCandidateMate(verLocPtr[v], verLocPtr[v + 1], verLocInd, edgeLocWeight);
candidateMate[v] = firstComputeCandidateMateD(verLocPtr[v], verLocPtr[v + 1],
verLocInd, edgeLocWeight);
// End: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v)
}
}
}
void PARALLEL_COMPUTE_CANDIDATE_MATE_BS(MilanLongInt NLVer,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanInt myRank,
MilanFloat *edgeLocWeight,
MilanLongInt *candidateMate)
{
MilanLongInt v = -1;
#pragma omp parallel private(v) default(shared) num_threads(NUM_THREAD)
{
#pragma omp for schedule(static)
for (v = 0; v < NLVer; v++) {
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Processing: " << v + StartIndex << endl;
fflush(stdout);
#endif
// Start: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v)
candidateMate[v] = firstComputeCandidateMateS(verLocPtr[v], verLocPtr[v + 1],
verLocInd, edgeLocWeight);
// End: PARALLEL_COMPUTE_CANDIDATE_MATE_B(v)
}
}
+1 -2
View File
@@ -1,5 +1,4 @@
#include "MatchBoxPC.h"
void PROCESS_CROSS_EDGE(MilanLongInt *edge,
MilanLongInt *S)
{
@@ -21,4 +20,4 @@ void PROCESS_CROSS_EDGE(MilanLongInt *edge,
#endif
// End: PARALLEL_PROCESS_CROSS_EDGE_B
}
}
@@ -1,6 +1,5 @@
#include "MatchBoxPC.h"
#ifdef OPENMP
void PARALLEL_PROCESS_EXPOSED_VERTEX_B(MilanLongInt NLVer,
#include "MatchBoxPC.h"
void PARALLEL_PROCESS_EXPOSED_VERTEX_BD(MilanLongInt NLVer,
MilanLongInt *candidateMate,
MilanLongInt *verLocInd,
MilanLongInt *verLocPtr,
@@ -31,15 +30,16 @@ void PARALLEL_PROCESS_EXPOSED_VERTEX_B(MilanLongInt NLVer,
vector<MilanInt> &privateQOwner)
{
MilanLongInt v = -1, k = -1, w = -1, adj11 = 0, adj12 = 0, k1 = 0;
MilanLongInt v = -1, k = -1, w = -1, adj11 = 0, adj12 = 0, k1 = 0;
MilanInt ghostOwner = 0, option, igw;
#pragma omp parallel private(option, k, w, v, k1, adj11, adj12, ghostOwner) \
firstprivate(privateU, StartIndex, EndIndex, privateQLocalVtx, privateQGhostVtx, privateQMsgType, privateQOwner) \
default(shared) num_threads(NUM_THREAD)
//#pragma omp parallel private(option, k, w, v, k1, adj11, adj12, ghostOwner) \
firstprivate(privateU, StartIndex, EndIndex, privateQLocalVtx, \
privateQGhostVtx, privateQMsgType, privateQOwner) \
default(shared) num_threads(NUM_THREAD)
{
#pragma omp for reduction(+ \
//#pragma omp for reduction(+ \
: PCounter[:numProcs], myCard \
[:1], msgInd \
[:1], NumMessagesBundled \
@@ -66,7 +66,7 @@ void PARALLEL_PROCESS_EXPOSED_VERTEX_B(MilanLongInt NLVer,
#pragma omp critical(Matching)
{
if (isAlreadyMatched(verLocInd[k], StartIndex, EndIndex, GMate, Mate, Ghost2LocalMap)) {
w = computeCandidateMate(verLocPtr[v], verLocPtr[v + 1], edgeLocWeight, 0,
w = computeCandidateMateD(verLocPtr[v], verLocPtr[v + 1], edgeLocWeight, 0,
verLocInd, StartIndex, EndIndex,
GMate, Mate, Ghost2LocalMap);
candidateMate[v] = w;
@@ -181,4 +181,189 @@ void PARALLEL_PROCESS_EXPOSED_VERTEX_B(MilanLongInt NLVer,
} // End of parallel region
}
void PARALLEL_PROCESS_EXPOSED_VERTEX_BS(MilanLongInt NLVer,
MilanLongInt *candidateMate,
MilanLongInt *verLocInd,
MilanLongInt *verLocPtr,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *Mate,
vector<MilanLongInt> &GMate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanFloat *edgeLocWeight,
MilanLongInt *myCard,
MilanLongInt *msgInd,
MilanLongInt *NumMessagesBundled,
MilanLongInt *S,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner)
{
MilanLongInt v = -1, k = -1, w = -1, adj11 = 0, adj12 = 0, k1 = 0;
MilanInt ghostOwner = 0, option, igw;
//#pragma omp parallel private(option, k, w, v, k1, adj11, adj12, ghostOwner) \
firstprivate(privateU, StartIndex, EndIndex, privateQLocalVtx, \
privateQGhostVtx, privateQMsgType, privateQOwner) \
default(shared) num_threads(NUM_THREAD)
{
//#pragma omp for reduction(+ \
: PCounter[:numProcs], myCard \
[:1], msgInd \
[:1], NumMessagesBundled \
[:1]) \
schedule(static)
for (v = 0; v < NLVer; v++) {
option = -1;
// Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
k = candidateMate[v];
candidateMate[v] = verLocInd[k];
w = candidateMate[v];
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Processing: " << v + StartIndex << endl;
fflush(stdout);
#endif
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")" << v + StartIndex << " Points to: " << w;
fflush(stdout);
#endif
// If found a dominating edge:
if (w >= 0) {
#pragma omp critical(Matching)
{
if (isAlreadyMatched(verLocInd[k], StartIndex, EndIndex, GMate, Mate, Ghost2LocalMap)) {
w = computeCandidateMateS(verLocPtr[v], verLocPtr[v + 1], edgeLocWeight, 0,
verLocInd, StartIndex, EndIndex,
GMate, Mate, Ghost2LocalMap);
candidateMate[v] = w;
}
if (w >= 0) {
(*myCard)++;
if ((w < StartIndex) || (w > EndIndex)) { // w is a ghost vertex
option = 2;
if (candidateMate[NLVer + Ghost2LocalMap[w]] == v + StartIndex) {
option = 1;
Mate[v] = w;
GMate[Ghost2LocalMap[w]] = v + StartIndex; // w is a Ghost
} // End of if CandidateMate[w] = v
} // End of if a Ghost Vertex
else { // w is a local vertex
if (candidateMate[w - StartIndex] == (v + StartIndex)) {
option = 3;
Mate[v] = w; // v is local
Mate[w - StartIndex] = v + StartIndex; // w is local
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v + StartIndex << "," << w << ") ";
fflush(stdout);
#endif
} // End of if ( candidateMate[w-StartIndex] == (v+StartIndex) )
} // End of Else
} // End of second if
}
} // End of if(w >=0)
else {
//#pragma omp critical(adjuse)
{
// This piece of code is executed a really small number of times
adj11 = verLocPtr[v];
adj12 = verLocPtr[v + 1];
for (k1 = adj11; k1 < adj12; k1++) {
w = verLocInd[k1];
if ((w < StartIndex) || (w > EndIndex)) { // A ghost
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a failure message: ";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs);
fflush(stdout);
#endif
(*msgInd)++;
(*NumMessagesBundled)++;
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
// assert(ghostOwner != -1);
// assert(ghostOwner != myRank);
#pragma omp atomic
PCounter[ghostOwner]++;
privateQLocalVtx.push_back(v + StartIndex);
privateQGhostVtx.push_back(w);
privateQMsgType.push_back(FAILURE);
privateQOwner.push_back(ghostOwner);
} // End of if(GHOST)
} // End of for loop
}
}
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
switch (option)
{
case -1:
break;
case 1:
privateU.push_back(v + StartIndex);
privateU.push_back(w);
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v + StartIndex << "," << w << ")";
fflush(stdout);
#endif
// Decrement the counter:
PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[w]], S);
case 2:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a request message (291):";
cout << "\n(" << myRank << ")Local is: " << v + StartIndex << " Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs) << endl;
fflush(stdout);
#endif
(*msgInd)++;
(*NumMessagesBundled)++;
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
// assert(ghostOwner != -1);
// assert(ghostOwner != myRank);
#pragma omp atomic
PCounter[ghostOwner]++;
privateQLocalVtx.push_back(v + StartIndex);
privateQGhostVtx.push_back(w);
privateQMsgType.push_back(REQUEST);
privateQOwner.push_back(ghostOwner);
break;
case 3:
default:
privateU.push_back(v + StartIndex);
privateU.push_back(w);
break;
}
} // End of for ( v=0; v < NLVer; v++ )
queuesTransfer(U, privateU, QLocalVtx,
QGhostVtx,
QMsgType, QOwner, privateQLocalVtx,
privateQGhostVtx,
privateQMsgType,
privateQOwner);
} // End of parallel region
}
#endif
@@ -1,7 +1,5 @@
#include "MatchBoxPC.h"
#if !defined(SERIAL_MPI)
void processMatchedVertices(
void processMatchedVerticesD(
MilanLongInt NLVer,
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
@@ -59,29 +57,29 @@ void processMatchedVertices(
{
while (!U.empty()) {
extractUChunk(UChunkBeingProcessed, U, privateU);
for (MilanLongInt u : UChunkBeingProcessed) {
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")u: " << u;
fflush(stdout);
#endif
if ((u >= StartIndex) && (u <= EndIndex)) { // Process Only the Local Vertices
#ifdef COUNT_LOCAL_VERTEX
localVertices++;
#endif
// Get the Adjacency list for u
adj1 = verLocPtr[u - StartIndex]; // Pointer
adj2 = verLocPtr[u - StartIndex + 1];
for (k = adj1; k < adj2; k++) {
option = -1;
v = verLocInd[k];
if ((v >= StartIndex) && (v <= EndIndex)) { // If Local Vertex:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")v: " << v << " c(v)= " << candidateMate[v - StartIndex] << " Mate[v]: " << Mate[v];
fflush(stdout);
@@ -92,62 +90,62 @@ void processMatchedVertices(
if (mateVal < 0) {
#pragma omp critical
{
if (candidateMate[v - StartIndex] == u) {
#pragma omp atomic read
mateVal = Mate[v - StartIndex];
// If the current vertex is pointing to a matched vertex and is not matched
if (mateVal < 0) {
if (candidateMate[v - StartIndex] == u) {
// Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
w = computeCandidateMate(verLocPtr[v - StartIndex],
verLocPtr[v - StartIndex + 1],
edgeLocWeight, 0,
verLocInd,
StartIndex,
EndIndex,
GMate,
Mate,
Ghost2LocalMap);
candidateMate[v - StartIndex] = w;
w = computeCandidateMateD(verLocPtr[v - StartIndex],
verLocPtr[v - StartIndex + 1],
edgeLocWeight, 0,
verLocInd, StartIndex, EndIndex,
GMate, Mate, Ghost2LocalMap);
candidateMate[v - StartIndex] = w;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")" << v << " Points to: " << w;
fflush(stdout);
cout << "\n(" << myRank << ")" << v << " Points to: " << w;
fflush(stdout);
#endif
// If found a dominating edge:
if (w >= 0) {
if ((w < StartIndex) || (w > EndIndex)) { // A ghost
// If found a dominating edge:
if (w >= 0) {
if ((w < StartIndex) || (w > EndIndex)) { // A ghost
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a request message:";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs);
cout << "\n(" << myRank << ")Sending a request message:";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs);
#endif
option = 2;
if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) {
option = 1;
Mate[v - StartIndex] = w; // v is a local vertex
GMate[Ghost2LocalMap[w]] = v; // w is a ghost vertex
} // End of if CandidateMate[w] = v
} // End of if a Ghost Vertex
else { // w is a local vertex
if (candidateMate[w - StartIndex] == v) {
option = 3;
Mate[v - StartIndex] = w; // v is a local vertex
Mate[w - StartIndex] = v; // w is a local vertex
option = 2;
if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) {
option = 1;
Mate[v - StartIndex] = w; // v is a local vertex
GMate[Ghost2LocalMap[w]] = v; // w is a ghost vertex
} // End of if CandidateMate[w] = v
} // End of if a Ghost Vertex
else { // w is a local vertex
if (candidateMate[w - StartIndex] == v) {
option = 3;
Mate[v - StartIndex] = w; // v is a local vertex
Mate[w - StartIndex] = v; // w is a local vertex
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") ";
fflush(stdout);
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") ";
fflush(stdout);
#endif
} // End of if(CandidateMate(w) = v
} // End of Else
} // End of if(w >=0)
else
option = 4; // End of Else: w == -1
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
} // End of If (candidateMate[v-StartIndex] == u
} // End of if(CandidateMate(w) = v
} // End of Else
} // End of if(w >=0)
else
option = 4; // End of Else: w == -1
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
} // End of If (candidateMate[v-StartIndex] == u
}
} // End of task
} // mateval < 0
} // End of if ( (v >= StartIndex) && (v <= EndIndex) ) //If Local Vertex:
else { // Neighbor is a ghost vertex
#pragma omp critical
{
if (candidateMate[NLVer + Ghost2LocalMap[v]] == u)
@@ -156,7 +154,7 @@ void processMatchedVertices(
option = 5; // u is local
} // End of critical
} // End of Else //A Ghost Vertex
switch (option)
{
case -1:
@@ -166,7 +164,7 @@ void processMatchedVertices(
// Found a dominating edge, it is a ghost and candidateMate[NLVer + Ghost2LocalMap[w]] == v
privateU.push_back(v);
privateU.push_back(w);
(*myCard)++;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") ";
@@ -175,15 +173,16 @@ void processMatchedVertices(
// Decrement the counter:
PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[w]], SPtr);
case 2:
// Found a dominating edge, it is a ghost
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
// assert(ghostOwner != -1);
// assert(ghostOwner != myRank);
#pragma omp atomic
PCounter[ghostOwner]++;
(*NumMessagesBundled)++;
(*msgInd)++;
privateQLocalVtx.push_back(v);
privateQGhostVtx.push_back(w);
privateQMsgType.push_back(REQUEST);
@@ -192,7 +191,7 @@ void processMatchedVertices(
case 3:
privateU.push_back(v);
privateU.push_back(w);
(*myCard)++;
break;
case 4:
@@ -202,94 +201,384 @@ void processMatchedVertices(
for (k1 = adj11; k1 < adj12; k1++) {
w = verLocInd[k1];
if ((w < StartIndex) || (w > EndIndex)) { // A ghost
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a failure message: ";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs);
fflush(stdout);
#endif
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
// assert(ghostOwner != -1);
// assert(ghostOwner != myRank);
#pragma omp atomic
PCounter[ghostOwner]++;
(*NumMessagesBundled)++;
(*msgInd)++;
privateQLocalVtx.push_back(v);
privateQGhostVtx.push_back(w);
privateQMsgType.push_back(FAILURE);
privateQOwner.push_back(ghostOwner);
} // End of if(GHOST)
} // End of for loop
break;
case 5:
default:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a success message: ";
cout << "\n(" << myRank << ")Ghost is " << v << " Owner is: " << findOwnerOfGhost(v, verDistance, myRank, numProcs) << "\n";
fflush(stdout);
#endif
ghostOwner = findOwnerOfGhost(v, verDistance, myRank, numProcs);
// assert(ghostOwner != -1);
// assert(ghostOwner != myRank);
(*NumMessagesBundled)++;
PCounter[ghostOwner]++;
(*msgInd)++;
privateQLocalVtx.push_back(u);
privateQGhostVtx.push_back(v);
privateQMsgType.push_back(SUCCESS);
privateQOwner.push_back(ghostOwner);
break;
} // End of switch
} // End of inner for
}
} // End of outer for
queuesTransfer(U, privateU, QLocalVtx,
QGhostVtx,
QMsgType, QOwner, privateQLocalVtx,
privateQGhostVtx,
privateQMsgType,
privateQOwner);
#pragma omp critical(U)
{
U.insert(U.end(), privateU.begin(), privateU.end());
}
privateU.clear();
#pragma omp critical(sendMessageTransfer)
{
QLocalVtx.insert(QLocalVtx.end(), privateQLocalVtx.begin(), privateQLocalVtx.end());
QGhostVtx.insert(QGhostVtx.end(), privateQGhostVtx.begin(), privateQGhostVtx.end());
QMsgType.insert(QMsgType.end(), privateQMsgType.begin(), privateQMsgType.end());
QOwner.insert(QOwner.end(), privateQOwner.begin(), privateQOwner.end());
}
privateU.clear();
privateQLocalVtx.clear();
privateQGhostVtx.clear();
privateQMsgType.clear();
privateQOwner.clear();
} // End of while ( !U.empty() )
#ifdef COUNT_LOCAL_VERTEX
printf("Count local vertexes: %ld for thread %d of processor %d\n",
localVertices,
omp_get_thread_num(),
myRank);
#endif
} // End of parallel region
}
void processMatchedVerticesS(
MilanLongInt NLVer,
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCard,
MilanLongInt *msgInd,
MilanLongInt *NumMessagesBundled,
MilanLongInt *SPtr,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
MilanLongInt *candidateMate,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanFloat *edgeLocWeight,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner)
{
MilanLongInt adj1, adj2, adj11, adj12, k, k1, v = -1, w = -1, ghostOwner;
int option;
MilanLongInt mateVal;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << "=========================************===============================" << endl;
fflush(stdout);
fflush(stdout);
#endif
#ifdef COUNT_LOCAL_VERTEX
MilanLongInt localVertices = 0;
#endif
//#pragma omp parallel private(k, w, v, k1, adj1, adj2, adj11, adj12, ghostOwner, option) \
firstprivate(privateU, StartIndex, EndIndex, privateQLocalVtx, privateQGhostVtx, \
privateQMsgType, privateQOwner, UChunkBeingProcessed) \
default(shared) num_threads(NUM_THREAD) \
reduction(+ \
: msgInd[:1], PCounter \
[:numProcs], myCard \
[:1], NumMessagesBundled \
[:1])
{
while (!U.empty()) {
extractUChunk(UChunkBeingProcessed, U, privateU);
for (MilanLongInt u : UChunkBeingProcessed) {
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")u: " << u;
fflush(stdout);
#endif
if ((u >= StartIndex) && (u <= EndIndex)) { // Process Only the Local Vertices
#ifdef COUNT_LOCAL_VERTEX
localVertices++;
#endif
// Get the Adjacency list for u
adj1 = verLocPtr[u - StartIndex]; // Pointer
adj2 = verLocPtr[u - StartIndex + 1];
for (k = adj1; k < adj2; k++) {
option = -1;
v = verLocInd[k];
if ((v >= StartIndex) && (v <= EndIndex)) { // If Local Vertex:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")v: " << v << " c(v)= " << candidateMate[v - StartIndex] << " Mate[v]: " << Mate[v];
fflush(stdout);
#endif
#pragma omp atomic read
mateVal = Mate[v - StartIndex];
// If the current vertex is pointing to a matched vertex and is not matched
if (mateVal < 0) {
#pragma omp critical
{
#pragma omp atomic read
mateVal = Mate[v - StartIndex];
// If the current vertex is pointing to a matched vertex and is not matched
if (mateVal < 0) {
if (candidateMate[v - StartIndex] == u) {
// Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
w = computeCandidateMateS(verLocPtr[v - StartIndex],
verLocPtr[v - StartIndex + 1],
edgeLocWeight, 0,
verLocInd, StartIndex, EndIndex,
GMate, Mate, Ghost2LocalMap);
candidateMate[v - StartIndex] = w;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")" << v << " Points to: " << w;
fflush(stdout);
#endif
// If found a dominating edge:
if (w >= 0) {
if ((w < StartIndex) || (w > EndIndex)) { // A ghost
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a request message:";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs);
#endif
option = 2;
if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) {
option = 1;
Mate[v - StartIndex] = w; // v is a local vertex
GMate[Ghost2LocalMap[w]] = v; // w is a ghost vertex
} // End of if CandidateMate[w] = v
} // End of if a Ghost Vertex
else { // w is a local vertex
if (candidateMate[w - StartIndex] == v) {
option = 3;
Mate[v - StartIndex] = w; // v is a local vertex
Mate[w - StartIndex] = v; // w is a local vertex
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") ";
fflush(stdout);
#endif
} // End of if(CandidateMate(w) = v
} // End of Else
} // End of if(w >=0)
else
option = 4; // End of Else: w == -1
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
} // End of If (candidateMate[v-StartIndex] == u
}
} // End of task
} // mateval < 0
} // End of if ( (v >= StartIndex) && (v <= EndIndex) ) //If Local Vertex:
else { // Neighbor is a ghost vertex
#pragma omp critical
{
if (candidateMate[NLVer + Ghost2LocalMap[v]] == u)
candidateMate[NLVer + Ghost2LocalMap[v]] = -1;
if (v != Mate[u - StartIndex])
option = 5; // u is local
} // End of critical
} // End of Else //A Ghost Vertex
switch (option)
{
case -1:
// No things to do
break;
case 1:
// Found a dominating edge, it is a ghost and candidateMate[NLVer + Ghost2LocalMap[w]] == v
privateU.push_back(v);
privateU.push_back(w);
(*myCard)++;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") ";
fflush(stdout);
#endif
// Decrement the counter:
PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[w]], SPtr);
case 2:
// Found a dominating edge, it is a ghost
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
// assert(ghostOwner != -1);
// assert(ghostOwner != myRank);
#pragma omp atomic
PCounter[ghostOwner]++;
(*NumMessagesBundled)++;
(*msgInd)++;
privateQLocalVtx.push_back(v);
privateQGhostVtx.push_back(w);
privateQMsgType.push_back(REQUEST);
privateQOwner.push_back(ghostOwner);
break;
case 3:
privateU.push_back(v);
privateU.push_back(w);
(*myCard)++;
break;
case 4:
// Could not find a dominating vertex
adj11 = verLocPtr[v - StartIndex];
adj12 = verLocPtr[v - StartIndex + 1];
for (k1 = adj11; k1 < adj12; k1++) {
w = verLocInd[k1];
if ((w < StartIndex) || (w > EndIndex)) { // A ghost
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a failure message: ";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs);
fflush(stdout);
#endif
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
// assert(ghostOwner != -1);
// assert(ghostOwner != myRank);
#pragma omp atomic
PCounter[ghostOwner]++;
(*NumMessagesBundled)++;
(*msgInd)++;
privateQLocalVtx.push_back(v);
privateQGhostVtx.push_back(w);
privateQMsgType.push_back(FAILURE);
privateQOwner.push_back(ghostOwner);
} // End of if(GHOST)
} // End of for loop
break;
case 5:
default:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a success message: ";
cout << "\n(" << myRank << ")Ghost is " << v << " Owner is: " << findOwnerOfGhost(v, verDistance, myRank, numProcs) << "\n";
fflush(stdout);
#endif
ghostOwner = findOwnerOfGhost(v, verDistance, myRank, numProcs);
// assert(ghostOwner != -1);
// assert(ghostOwner != myRank);
(*NumMessagesBundled)++;
PCounter[ghostOwner]++;
(*msgInd)++;
privateQLocalVtx.push_back(u);
privateQGhostVtx.push_back(v);
privateQMsgType.push_back(SUCCESS);
privateQOwner.push_back(ghostOwner);
break;
} // End of switch
} // End of inner for
}
} // End of outer for
queuesTransfer(U, privateU, QLocalVtx,
QGhostVtx,
QMsgType, QOwner, privateQLocalVtx,
privateQGhostVtx,
privateQMsgType,
privateQOwner);
#pragma omp critical(U)
{
U.insert(U.end(), privateU.begin(), privateU.end());
}
#pragma omp critical(sendMessageTransfer)
{
QLocalVtx.insert(QLocalVtx.end(), privateQLocalVtx.begin(), privateQLocalVtx.end());
QGhostVtx.insert(QGhostVtx.end(), privateQGhostVtx.begin(), privateQGhostVtx.end());
QMsgType.insert(QMsgType.end(), privateQMsgType.begin(), privateQMsgType.end());
QOwner.insert(QOwner.end(), privateQOwner.begin(), privateQOwner.end());
}
privateU.clear();
privateQLocalVtx.clear();
privateQGhostVtx.clear();
privateQMsgType.clear();
privateQOwner.clear();
} // End of while ( !U.empty() )
#ifdef COUNT_LOCAL_VERTEX
printf("Count local vertexes: %ld for thread %d of processor %d\n",
localVertices,
omp_get_thread_num(),
myRank);
#endif
} // End of parallel region
}
@@ -1,7 +1,6 @@
#include "MatchBoxPC.h"
//#define DEBUG_HANG_
#if !defined(SERIAL_MPI)
void processMatchedVerticesAndSendMessages(
void processMatchedVerticesAndSendMessagesD(
MilanLongInt NLVer,
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
@@ -27,6 +26,302 @@ void processMatchedVerticesAndSendMessages(
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
vector<MilanLongInt> &privateQMsgType,
vector<MilanInt> &privateQOwner,
MPI_Comm comm,
MilanLongInt *msgActual,
vector<MilanLongInt> &Message)
{
MilanLongInt initialSize = QLocalVtx.size();
MilanLongInt adj1, adj2, adj11, adj12, k, k1, v = -1, w = -1, ghostOwner;
int option;
MilanLongInt mateVal;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << "=========================************===============================" << endl;
fflush(stdout);
fflush(stdout);
#endif
#ifdef COUNT_LOCAL_VERTEX
MilanLongInt localVertices = 0;
#endif
//#pragma omp parallel private(k, w, v, k1, adj1, adj2, adj11, adj12, ghostOwner, option) \
firstprivate(Message, privateU, StartIndex, EndIndex, privateQLocalVtx, \
privateQGhostVtx, privateQMsgType, privateQOwner, UChunkBeingProcessed) \
default(shared) \
num_threads(NUM_THREAD) \
reduction(+ \
: msgInd[:1], PCounter \
[:numProcs], myCard \
[:1], NumMessagesBundled \
[:1], msgActual \
[:1])
{
while (!U.empty()) {
extractUChunk(UChunkBeingProcessed, U, privateU);
for (MilanLongInt u : UChunkBeingProcessed) {
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")u: " << u;
fflush(stdout);
#endif
if ((u >= StartIndex) && (u <= EndIndex)) { // Process Only the Local Vertices
#ifdef COUNT_LOCAL_VERTEX
localVertices++;
#endif
// Get the Adjacency list for u
adj1 = verLocPtr[u - StartIndex]; // Pointer
adj2 = verLocPtr[u - StartIndex + 1];
for (k = adj1; k < adj2; k++) {
option = -1;
v = verLocInd[k];
if ((v >= StartIndex) && (v <= EndIndex)) { // If Local Vertex:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")v: " << v << " c(v)= " << candidateMate[v - StartIndex] << " Mate[v]: " << Mate[v];
fflush(stdout);
#endif
#pragma omp atomic read
mateVal = Mate[v - StartIndex];
// If the current vertex is pointing to a matched vertex and is not matched
if (mateVal < 0) {
#pragma omp critical
{
#pragma omp atomic read
mateVal = Mate[v - StartIndex];
// If the current vertex is pointing to a matched vertex and is not matched
if (mateVal < 0) {
if (candidateMate[v - StartIndex] == u) {
// Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
w = computeCandidateMateD(verLocPtr[v - StartIndex],
verLocPtr[v - StartIndex + 1],
edgeLocWeight, 0,
verLocInd, StartIndex, EndIndex,
GMate, Mate, Ghost2LocalMap);
candidateMate[v - StartIndex] = w;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")" << v << " Points to: " << w;
fflush(stdout);
#endif
// If found a dominating edge:
if (w >= 0) {
if ((w < StartIndex) || (w > EndIndex)) { // A ghost
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a request message:";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs);
#endif
option = 2;
if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) {
option = 1;
Mate[v - StartIndex] = w; // v is a local vertex
GMate[Ghost2LocalMap[w]] = v; // w is a ghost vertex
} // End of if CandidateMate[w] = v
} // End of if a Ghost Vertex
else { // w is a local vertex
if (candidateMate[w - StartIndex] == v) {
option = 3;
Mate[v - StartIndex] = w; // v is a local vertex
Mate[w - StartIndex] = v; // w is a local vertex
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") ";
fflush(stdout);
#endif
} // End of if(CandidateMate(w) = v
} // End of Else
} // End of if(w >=0)
else
option = 4; // End of Else: w == -1
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
} // End of If (candidateMate[v-StartIndex] == u
}
} // End of task
} // mateval < 0
} // End of if ( (v >= StartIndex) && (v <= EndIndex) ) //If Local Vertex:
else { // Neighbor is a ghost vertex
#pragma omp critical
{
if (candidateMate[NLVer + Ghost2LocalMap[v]] == u)
candidateMate[NLVer + Ghost2LocalMap[v]] = -1;
if (v != Mate[u - StartIndex])
option = 5; // u is local
} // End of critical
} // End of Else //A Ghost Vertex
switch (option)
{
case -1:
// No things to do
break;
case 1:
// Found a dominating edge, it is a ghost and candidateMate[NLVer + Ghost2LocalMap[w]] == v
privateU.push_back(v);
privateU.push_back(w);
(*myCard)++;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") ";
fflush(stdout);
#endif
// Decrement the counter:
PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[w]], SPtr);
case 2:
// Found a dominating edge, it is a ghost
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
// Build the Message Packet:
// Message[0] = v; // LOCAL
// Message[1] = w; // GHOST
// Message[2] = REQUEST; // TYPE
// Send a Request (Asynchronous)
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
(*msgActual)++;
(*msgInd)++;
privateQLocalVtx.push_back(v);
privateQGhostVtx.push_back(w);
privateQMsgType.push_back(REQUEST);
privateQOwner.push_back(ghostOwner);
break;
case 3:
privateU.push_back(v);
privateU.push_back(w);
(*myCard)++;
break;
case 4:
// Could not find a dominating vertex
adj11 = verLocPtr[v - StartIndex];
adj12 = verLocPtr[v - StartIndex + 1];
for (k1 = adj11; k1 < adj12; k1++) {
w = verLocInd[k1];
if ((w < StartIndex) || (w > EndIndex)) { // A ghost
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a failure message: ";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs);
fflush(stdout);
#endif
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
// Build the Message Packet:
// Message[0] = v; // LOCAL
// Message[1] = w; // GHOST
// Message[2] = FAILURE; // TYPE
// Send a Request (Asynchronous)
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
(*msgActual)++;
(*msgInd)++;
privateQLocalVtx.push_back(v);
privateQGhostVtx.push_back(w);
privateQMsgType.push_back(FAILURE);
privateQOwner.push_back(ghostOwner);
} // End of if(GHOST)
} // End of for loop
break;
case 5:
default:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a success message: ";
cout << "\n(" << myRank << ")Ghost is " << v << " Owner is: " << findOwnerOfGhost(v, verDistance, myRank, numProcs) << "\n";
fflush(stdout);
#endif
ghostOwner = findOwnerOfGhost(v, verDistance, myRank, numProcs);
// Build the Message Packet:
// Message[0] = u; // LOCAL
// Message[1] = v; // GHOST
// Message[2] = SUCCESS; // TYPE
// Send a Request (Asynchronous)
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
(*msgActual)++;
(*msgInd)++;
privateQLocalVtx.push_back(u);
privateQGhostVtx.push_back(v);
privateQMsgType.push_back(SUCCESS);
privateQOwner.push_back(ghostOwner);
break;
} // End of switch
} // End of inner for
}
} // End of outer for
queuesTransfer(U, privateU, QLocalVtx,
QGhostVtx,
QMsgType, QOwner, privateQLocalVtx,
privateQGhostVtx,
privateQMsgType,
privateQOwner);
} // End of while ( !U.empty() )
#ifdef COUNT_LOCAL_VERTEX
printf("Count local vertexes: %ld for thread %d of processor %d\n",
localVertices, mp_get_thread_num(), myRank);
#endif
} // End of parallel region
// Send the messages
#ifdef DEBUG_HANG_
cout << myRank<<" Sending: "<<QOwner.size()-initialSize<<" messages" <<endl;
#endif
for (int i = initialSize; i < QOwner.size(); i++) {
Message[0] = QLocalVtx[i];
Message[1] = QGhostVtx[i];
Message[2] = QMsgType[i];
ghostOwner = QOwner[i];
//MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
//cout << myRank<<" Sending to "<<ghostOwner<<endl;
MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
}
#ifdef DEBUG_HANG_
cout << myRank<<" Done sending messages"<<endl;
#endif
}
void processMatchedVerticesAndSendMessagesS(
MilanLongInt NLVer,
vector<MilanLongInt> &UChunkBeingProcessed,
vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCard,
MilanLongInt *msgInd,
MilanLongInt *NumMessagesBundled,
MilanLongInt *SPtr,
MilanLongInt *verLocPtr,
MilanLongInt *verLocInd,
MilanLongInt *verDistance,
MilanLongInt *PCounter,
vector<MilanLongInt> &Counter,
MilanInt myRank,
MilanInt numProcs,
MilanLongInt *candidateMate,
vector<MilanLongInt> &GMate,
MilanLongInt *Mate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
MilanFloat *edgeLocWeight,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MilanLongInt> &privateQLocalVtx,
vector<MilanLongInt> &privateQGhostVtx,
@@ -64,29 +359,28 @@ void processMatchedVerticesAndSendMessages(
{
while (!U.empty()) {
extractUChunk(UChunkBeingProcessed, U, privateU);
for (MilanLongInt u : UChunkBeingProcessed) {
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")u: " << u;
fflush(stdout);
#endif
if ((u >= StartIndex) && (u <= EndIndex)) { // Process Only the Local Vertices
#ifdef COUNT_LOCAL_VERTEX
localVertices++;
#endif
// Get the Adjacency list for u
adj1 = verLocPtr[u - StartIndex]; // Pointer
adj2 = verLocPtr[u - StartIndex + 1];
for (k = adj1; k < adj2; k++) {
option = -1;
v = verLocInd[k];
if ((v >= StartIndex) && (v <= EndIndex)) { // If Local Vertex:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")v: " << v << " c(v)= " << candidateMate[v - StartIndex] << " Mate[v]: " << Mate[v];
fflush(stdout);
@@ -97,63 +391,62 @@ void processMatchedVerticesAndSendMessages(
if (mateVal < 0) {
#pragma omp critical
{
if (candidateMate[v - StartIndex] == u) {
// Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
w = computeCandidateMate(verLocPtr[v - StartIndex],
verLocPtr[v - StartIndex + 1],
edgeLocWeight, 0,
verLocInd,
StartIndex,
EndIndex,
GMate,
Mate,
Ghost2LocalMap);
candidateMate[v - StartIndex] = w;
#pragma omp atomic read
mateVal = Mate[v - StartIndex];
// If the current vertex is pointing to a matched vertex and is not matched
if (mateVal < 0) {
if (candidateMate[v - StartIndex] == u) {
// Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
w = computeCandidateMateS(verLocPtr[v - StartIndex],
verLocPtr[v - StartIndex + 1],
edgeLocWeight, 0,
verLocInd, StartIndex, EndIndex,
GMate, Mate, Ghost2LocalMap);
candidateMate[v - StartIndex] = w;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")" << v << " Points to: " << w;
fflush(stdout);
cout << "\n(" << myRank << ")" << v << " Points to: " << w;
fflush(stdout);
#endif
// If found a dominating edge:
if (w >= 0) {
if ((w < StartIndex) || (w > EndIndex)) { // A ghost
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a request message:";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs);
#endif
option = 2;
// If found a dominating edge:
if (w >= 0) {
if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) {
option = 1;
Mate[v - StartIndex] = w; // v is a local vertex
GMate[Ghost2LocalMap[w]] = v; // w is a ghost vertex
} // End of if CandidateMate[w] = v
} // End of if a Ghost Vertex
else { // w is a local vertex
if (candidateMate[w - StartIndex] == v) {
option = 3;
Mate[v - StartIndex] = w; // v is a local vertex
Mate[w - StartIndex] = v; // w is a local vertex
if ((w < StartIndex) || (w > EndIndex)) { // A ghost
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") ";
fflush(stdout);
cout << "\n(" << myRank << ")Sending a request message:";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs);
#endif
} // End of if(CandidateMate(w) = v
} // End of Else
} // End of if(w >=0)
else
option = 4; // End of Else: w == -1
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
} // End of If (candidateMate[v-StartIndex] == u
option = 2;
if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) {
option = 1;
Mate[v - StartIndex] = w; // v is a local vertex
GMate[Ghost2LocalMap[w]] = v; // w is a ghost vertex
} // End of if CandidateMate[w] = v
} // End of if a Ghost Vertex
else { // w is a local vertex
if (candidateMate[w - StartIndex] == v) {
option = 3;
Mate[v - StartIndex] = w; // v is a local vertex
Mate[w - StartIndex] = v; // w is a local vertex
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") ";
fflush(stdout);
#endif
} // End of if(CandidateMate(w) = v
} // End of Else
} // End of if(w >=0)
else
option = 4; // End of Else: w == -1
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
} // End of If (candidateMate[v-StartIndex] == u
}
} // End of task
} // mateval < 0
} // End of if ( (v >= StartIndex) && (v <= EndIndex) ) //If Local Vertex:
else { // Neighbor is a ghost vertex
#pragma omp critical
{
if (candidateMate[NLVer + Ghost2LocalMap[v]] == u)
@@ -162,7 +455,7 @@ void processMatchedVerticesAndSendMessages(
option = 5; // u is local
} // End of critical
} // End of Else //A Ghost Vertex
switch (option)
{
case -1:
@@ -180,20 +473,20 @@ void processMatchedVerticesAndSendMessages(
// Decrement the counter:
PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[w]], SPtr);
case 2:
// Found a dominating edge, it is a ghost
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
// Build the Message Packet:
// Message[0] = v; // LOCAL
// Message[1] = w; // GHOST
// Message[2] = REQUEST; // TYPE
// Send a Request (Asynchronous)
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
(*msgActual)++;
(*msgInd)++;
privateQLocalVtx.push_back(v);
privateQGhostVtx.push_back(w);
privateQMsgType.push_back(REQUEST);
@@ -211,94 +504,82 @@ void processMatchedVerticesAndSendMessages(
for (k1 = adj11; k1 < adj12; k1++) {
w = verLocInd[k1];
if ((w < StartIndex) || (w > EndIndex)) { // A ghost
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a failure message: ";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs);
fflush(stdout);
#endif
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
// Build the Message Packet:
// Message[0] = v; // LOCAL
// Message[1] = w; // GHOST
// Message[2] = FAILURE; // TYPE
// Send a Request (Asynchronous)
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
(*msgActual)++;
(*msgInd)++;
privateQLocalVtx.push_back(v);
privateQGhostVtx.push_back(w);
privateQMsgType.push_back(FAILURE);
privateQOwner.push_back(ghostOwner);
} // End of if(GHOST)
} // End of for loop
break;
case 5:
default:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a success message: ";
cout << "\n(" << myRank << ")Ghost is " << v << " Owner is: " << findOwnerOfGhost(v, verDistance, myRank, numProcs) << "\n";
fflush(stdout);
#endif
ghostOwner = findOwnerOfGhost(v, verDistance, myRank, numProcs);
// Build the Message Packet:
// Message[0] = u; // LOCAL
// Message[1] = v; // GHOST
// Message[2] = SUCCESS; // TYPE
// Send a Request (Asynchronous)
// MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
(*msgActual)++;
(*msgInd)++;
privateQLocalVtx.push_back(u);
privateQGhostVtx.push_back(v);
privateQMsgType.push_back(SUCCESS);
privateQOwner.push_back(ghostOwner);
break;
} // End of switch
} // End of inner for
}
} // End of outer for
queuesTransfer(U, privateU, QLocalVtx,
QGhostVtx,
QMsgType, QOwner, privateQLocalVtx,
privateQGhostVtx,
privateQMsgType,
privateQOwner);
} // End of while ( !U.empty() )
#ifdef COUNT_LOCAL_VERTEX
printf("Count local vertexes: %ld for thread %d of processor %d\n",
localVertices,
omp_get_thread_num(),
myRank);
localVertices, mp_get_thread_num(), myRank);
#endif
} // End of parallel region
// Send the messages
#ifdef DEBUG_HANG_
cout << myRank<<" Sending: "<<QOwner.size()-initialSize<<" messages" <<endl;
#endif
for (int i = initialSize; i < QOwner.size(); i++) {
Message[0] = QLocalVtx[i];
Message[1] = QGhostVtx[i];
Message[2] = QMsgType[i];
ghostOwner = QOwner[i];
//MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
//cout << myRank<<" Sending to "<<ghostOwner<<endl;
MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
+325 -9
View File
@@ -2,7 +2,7 @@
//#define DEBUG_HANG_
#if !defined(SERIAL_MPI)
void processMessages(
void processMessagesD(
MilanLongInt NLVer,
MilanLongInt *Mate,
MilanLongInt *candidateMate,
@@ -139,12 +139,12 @@ void processMessages(
if (!ReceiveBuffer.empty())
ReceiveBuffer.clear(); // Empty it out first
ReceiveBuffer.resize(bundleSize, -1); // Initialize
ReceiveBuffer[0] = Message[0]; // u
ReceiveBuffer[1] = Message[1]; // v
ReceiveBuffer[2] = Message[2]; // message_type
}
#ifdef DEBUG_GHOST_
if ((v < StartIndex) || (v > EndIndex)) {
cout << "\n(" << myRank << ") From ReceiveBuffer: This should not happen: u= " << u << " v= " << v << " Type= " << message_type << " StartIndex " << StartIndex << " EndIndex " << EndIndex << endl;
@@ -161,7 +161,7 @@ void processMessages(
u = ReceiveBuffer[bundleCounter - 3]; // GHOST
v = ReceiveBuffer[bundleCounter - 2]; // LOCAL
message_type = ReceiveBuffer[bundleCounter - 1]; // TYPE
// CASE I: REQUEST
if (message_type == REQUEST) {
#ifdef PRINT_DEBUG_INFO_
@@ -189,7 +189,7 @@ void processMessages(
cout << "\n(" << myRank << ")MATCH: (" << v << "," << u << ") " << endl;
fflush(stdout);
#endif
PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[u]], S);
} // End of if ( candidateMate[v-StartIndex] == u )e
} // End of if ( Mate[v] == -1 )
@@ -212,8 +212,9 @@ void processMessages(
// Process only if not already matched ( v is local)
if (candidateMate[v - StartIndex] == u) {
// Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
w = computeCandidateMate(verLocPtr[v - StartIndex], verLocPtr[v - StartIndex + 1], edgeLocWeight, k,
verLocInd, StartIndex, EndIndex, GMate, Mate, Ghost2LocalMap);
w = computeCandidateMateD(verLocPtr[v - StartIndex], verLocPtr[v - StartIndex + 1],
edgeLocWeight, k,verLocInd, StartIndex, EndIndex,
GMate, Mate, Ghost2LocalMap);
candidateMate[v - StartIndex] = w;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")" << v << " Points to: " << w << endl;
@@ -250,7 +251,7 @@ void processMessages(
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") " << endl;
fflush(stdout);
#endif
PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[w]], S);
} // End of if CandidateMate[w] = v
} // End of if a Ghost Vertex
@@ -311,7 +312,322 @@ void processMessages(
} // End of else: CASE III
} // End of else: CASE I
}
return;
}
void processMessagesS(
MilanLongInt NLVer,
MilanLongInt *Mate,
MilanLongInt *candidateMate,
map<MilanLongInt, MilanLongInt> &Ghost2LocalMap,
vector<MilanLongInt> &GMate,
vector<MilanLongInt> &Counter,
MilanLongInt StartIndex,
MilanLongInt EndIndex,
MilanLongInt *myCard,
MilanLongInt *msgInd,
MilanLongInt *msgActual,
MilanFloat *edgeLocWeight,
MilanLongInt *verDistance,
MilanLongInt *verLocPtr,
MilanLongInt k,
MilanLongInt *verLocInd,
MilanInt numProcs,
MilanInt myRank,
MPI_Comm comm,
vector<MilanLongInt> &Message,
MilanLongInt numGhostEdges,
MilanLongInt u,
MilanLongInt v,
MilanLongInt *S,
vector<MilanLongInt> &U)
{
//#define PRINT_DEBUG_INFO_
MilanInt Sender;
MPI_Status computeStatus;
MilanLongInt bundleSize, w;
MilanLongInt adj11, adj12, k1;
MilanLongInt ghostOwner;
int error_codeC;
error_codeC = MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);
char error_message[MPI_MAX_ERROR_STRING];
int message_length;
MilanLongInt message_type = 0;
// Buffer to receive bundled messages
// Maximum messages that can be received from any processor is
// twice the edge cut: REQUEST; REQUEST+(FAILURE/SUCCESS)
vector<MilanLongInt> ReceiveBuffer;
try
{
ReceiveBuffer.reserve(numGhostEdges * 2 * 3); // Three integers per cross edge
}
catch (length_error)
{
cout << "Error in function algoDistEdgeApproxDominatingEdgesMessageBundling: \n";
cout << "Not enough memory to allocate the internal variables \n";
exit(1);
}
#ifdef PRINT_DEBUG_INFO_
cout
<< "\n(" << myRank << "=========================************===============================" << endl;
fflush(stdout);
fflush(stdout);
#endif
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")About to begin Message processing phase ... *S=" << *S << endl;
fflush(stdout);
#endif
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << "=========================************===============================" << endl;
fflush(stdout);
fflush(stdout);
#endif
// BLOCKING RECEIVE:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << " Waiting for blocking receive..." << endl;
fflush(stdout);
fflush(stdout);
#endif
//cout << myRank<<" Receiving ...";
error_codeC = MPI_Recv(&Message[0], 3, TypeMap<MilanLongInt>(), MPI_ANY_SOURCE, ComputeTag, comm, &computeStatus);
if (error_codeC != MPI_SUCCESS)
{
MPI_Error_string(error_codeC, error_message, &message_length);
cout << "\n*Error in call to MPI_Receive on Slave: " << error_message << "\n";
fflush(stdout);
}
Sender = computeStatus.MPI_SOURCE;
//cout << " ...from "<<Sender << endl;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Received message from Process " << Sender << " Type= " << Message[2] << endl;
fflush(stdout);
#endif
if (Message[2] == SIZEINFO) {
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Received bundled message from Process " << Sender << " Size= " << Message[0] << endl;
fflush(stdout);
#endif
bundleSize = Message[0]; //#of integers in the message
// Build the Message Buffer:
if (!ReceiveBuffer.empty())
ReceiveBuffer.clear(); // Empty it out first
ReceiveBuffer.resize(bundleSize, -1); // Initialize
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Message Bundle Before: " << endl;
for (int i = 0; i < bundleSize; i++)
cout << ReceiveBuffer[i] << ",";
cout << endl;
fflush(stdout);
#endif
// Receive the message
//cout << myRank<<" Receiving from "<<Sender<<endl;
error_codeC = MPI_Recv(&ReceiveBuffer[0], bundleSize, TypeMap<MilanLongInt>(), Sender, BundleTag, comm, &computeStatus);
if (error_codeC != MPI_SUCCESS) {
MPI_Error_string(error_codeC, error_message, &message_length);
cout << "\n*Error in call to MPI_Receive on processor " << myRank << " Error: " << error_message << "\n";
fflush(stdout);
}
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Message Bundle After: " << endl;
for (int i = 0; i < bundleSize; i++)
cout << ReceiveBuffer[i] << ",";
cout << endl;
fflush(stdout);
#endif
} else { // Just a single message:
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Received regular message from Process " << Sender << " u= " << Message[0] << " v= " << Message[1] << endl;
fflush(stdout);
#endif
// Add the current message to Queue:
bundleSize = 3; //#of integers in the message
// Build the Message Buffer:
if (!ReceiveBuffer.empty())
ReceiveBuffer.clear(); // Empty it out first
ReceiveBuffer.resize(bundleSize, -1); // Initialize
ReceiveBuffer[0] = Message[0]; // u
ReceiveBuffer[1] = Message[1]; // v
ReceiveBuffer[2] = Message[2]; // message_type
}
#ifdef DEBUG_GHOST_
if ((v < StartIndex) || (v > EndIndex)) {
cout << "\n(" << myRank << ") From ReceiveBuffer: This should not happen: u= " << u << " v= " << v << " Type= " << message_type << " StartIndex " << StartIndex << " EndIndex " << EndIndex << endl;
fflush(stdout);
}
#endif
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Processing message: u= " << u << " v= " << v << " Type= " << message_type << endl;
fflush(stdout);
#endif
// Most of the time bundleSize == 3, thus, it's not worth parallelizing thi loop
for (MilanLongInt bundleCounter = 3; bundleCounter < bundleSize + 3; bundleCounter += 3) {
u = ReceiveBuffer[bundleCounter - 3]; // GHOST
v = ReceiveBuffer[bundleCounter - 2]; // LOCAL
message_type = ReceiveBuffer[bundleCounter - 1]; // TYPE
// CASE I: REQUEST
if (message_type == REQUEST) {
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Message type is REQUEST" << endl;
fflush(stdout);
#endif
#ifdef DEBUG_GHOST_
if ((v < 0) || (v < StartIndex) || ((v - StartIndex) > NLVer)) {
cout << "\n(" << myRank << ") case 1 Bad address " << v << " " << StartIndex << " " << v - StartIndex << " " << NLVer << endl;
fflush(stdout);
}
#endif
if (Mate[v - StartIndex] == -1) {
// Process only if not already matched (v is local)
candidateMate[NLVer + Ghost2LocalMap[u]] = v; // Set CandidateMate for the ghost
if (candidateMate[v - StartIndex] == u) {
GMate[Ghost2LocalMap[u]] = v; // u is ghost
Mate[v - StartIndex] = u; // v is local
U.push_back(v);
U.push_back(u);
(*myCard)++;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v << "," << u << ") " << endl;
fflush(stdout);
#endif
PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[u]], S);
} // End of if ( candidateMate[v-StartIndex] == u )e
} // End of if ( Mate[v] == -1 )
} // End of REQUEST
else { // CASE II: SUCCESS
if (message_type == SUCCESS) {
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Message type is SUCCESS" << endl;
fflush(stdout);
#endif
GMate[Ghost2LocalMap[u]] = EndIndex + 1; // Set a Dummy Mate to make sure that we do not (u is a ghost) process it again
PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[u]], S);
#ifdef DEBUG_GHOST_
if ((v < 0) || (v < StartIndex) || ((v - StartIndex) > NLVer)) {
cout << "\n(" << myRank << ") case 2 Bad address " << v << " " << StartIndex << " " << v - StartIndex << " " << NLVer << endl;
fflush(stdout);
}
#endif
if (Mate[v - StartIndex] == -1) {
// Process only if not already matched ( v is local)
if (candidateMate[v - StartIndex] == u) {
// Start: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
w = computeCandidateMateS(verLocPtr[v - StartIndex], verLocPtr[v - StartIndex + 1],
edgeLocWeight, k,verLocInd, StartIndex, EndIndex,
GMate, Mate, Ghost2LocalMap);
candidateMate[v - StartIndex] = w;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")" << v << " Points to: " << w << endl;
fflush(stdout);
#endif
// If found a dominating edge:
if (w >= 0) {
if ((w < StartIndex) || (w > EndIndex)) {
// w is a ghost
// Build the Message Packet:
Message[0] = v; // LOCAL
Message[1] = w; // GHOST
Message[2] = REQUEST; // TYPE
// Send a Request (Asynchronous)
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a request message: ";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs) << endl;
fflush(stdout);
#endif
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
//assert(ghostOwner != -1);
//assert(ghostOwner != myRank);
//cout << myRank<<" Sending to "<<ghostOwner<<endl;
MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
(*msgInd)++;
(*msgActual)++;
if (candidateMate[NLVer + Ghost2LocalMap[w]] == v) {
Mate[v - StartIndex] = w; // v is local
GMate[Ghost2LocalMap[w]] = v; // w is ghost
U.push_back(v);
U.push_back(w);
(*myCard)++;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") " << endl;
fflush(stdout);
#endif
PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[w]], S);
} // End of if CandidateMate[w] = v
} // End of if a Ghost Vertex
else { // w is a local vertex
if (candidateMate[w - StartIndex] == v) {
Mate[v - StartIndex] = w; // v is local
Mate[w - StartIndex] = v; // w is local
// Q.push_back(u);
U.push_back(v);
U.push_back(w);
(*myCard)++;
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")MATCH: (" << v << "," << w << ") " << endl;
fflush(stdout);
#endif
} // End of if(CandidateMate(w) = v
} // End of Else
} // End of if(w >=0)
else { // No dominant edge found
adj11 = verLocPtr[v - StartIndex];
adj12 = verLocPtr[v - StartIndex + 1];
for (k1 = adj11; k1 < adj12; k1++) {
w = verLocInd[k1];
if ((w < StartIndex) || (w > EndIndex)) {
// A ghost
// Build the Message Packet:
Message[0] = v; // LOCAL
Message[1] = w; // GHOST
Message[2] = FAILURE; // TYPE
// Send a Request (Asynchronous)
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Sending a failure message: ";
cout << "\n(" << myRank << ")Ghost is " << w << " Owner is: " << findOwnerOfGhost(w, verDistance, myRank, numProcs) << endl;
fflush(stdout);
#endif
ghostOwner = findOwnerOfGhost(w, verDistance, myRank, numProcs);
//assert(ghostOwner != -1);
//assert(ghostOwner != myRank);
//cout << myRank<<" Sending to "<<ghostOwner<<endl;
MPI_Bsend(&Message[0], 3, TypeMap<MilanLongInt>(), ghostOwner, ComputeTag, comm);
(*msgInd)++;
(*msgActual)++;
} // End of if(GHOST)
} // End of for loop
} // End of Else: w == -1
// End: PARALLEL_PROCESS_EXPOSED_VERTEX_B(v)
} // End of if ( candidateMate[v-StartIndex] == u )
} // End of if ( Mate[v] == -1 )
} // End of if ( message_type == SUCCESS )
else {
// CASE III: FAILURE
#ifdef PRINT_DEBUG_INFO_
cout << "\n(" << myRank << ")Message type is FAILURE" << endl;
fflush(stdout);
#endif
GMate[Ghost2LocalMap[u]] = EndIndex + 1; // Set a Dummy Mate to make sure that we do not (u is a ghost) process this anymore
PROCESS_CROSS_EDGE(&Counter[Ghost2LocalMap[u]], S); // Decrease the counter
} // End of else: CASE III
} // End of else: CASE I
}
return;
}
#endif
@@ -1,5 +1,4 @@
#include "MatchBoxPC.h"
#ifdef OPENMP
void queuesTransfer(vector<MilanLongInt> &U,
vector<MilanLongInt> &privateU,
vector<MilanLongInt> &QLocalVtx,
+21 -22
View File
@@ -1,24 +1,23 @@
#include "MatchBoxPC.h"
#if !defined(SERIAL_MPI)
void sendBundledMessages(MilanLongInt *numGhostEdges,
MilanInt *BufferSize,
MilanLongInt *Buffer,
vector<MilanLongInt> &PCumulative,
vector<MilanLongInt> &PMessageBundle,
vector<MilanLongInt> &PSizeInfoMessages,
MilanLongInt *PCounter,
MilanLongInt NumMessagesBundled,
MilanLongInt *msgActual,
MilanLongInt *msgInd,
MilanInt numProcs,
MilanInt myRank,
MPI_Comm comm,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MPI_Request> &SRequest,
vector<MPI_Status> &SStatus)
MilanInt *BufferSize,
MilanLongInt *Buffer,
vector<MilanLongInt> &PCumulative,
vector<MilanLongInt> &PMessageBundle,
vector<MilanLongInt> &PSizeInfoMessages,
MilanLongInt *PCounter,
MilanLongInt NumMessagesBundled,
MilanLongInt *msgActual,
MilanLongInt *msgInd,
MilanInt numProcs,
MilanInt myRank,
MPI_Comm comm,
vector<MilanLongInt> &QLocalVtx,
vector<MilanLongInt> &QGhostVtx,
vector<MilanLongInt> &QMsgType,
vector<MilanInt> &QOwner,
vector<MPI_Request> &SRequest,
vector<MPI_Status> &SStatus)
{
MilanLongInt myIndex = 0, numMessagesToSend;
@@ -62,7 +61,7 @@ void sendBundledMessages(MilanLongInt *numGhostEdges,
for (i = 0; i < numProcs; i++)
PCumulative[i + 1] = PCumulative[i] + PCounter[i];
}
#pragma omp task depend(inout \
: PCounter)
{
@@ -84,7 +83,7 @@ void sendBundledMessages(MilanLongInt *numGhostEdges,
PCounter[QOwner[i]]++;
}
}
// Send the Bundled Messages: Use ISend
#pragma omp task depend(out \
: SRequest, SStatus)
@@ -101,7 +100,7 @@ void sendBundledMessages(MilanLongInt *numGhostEdges,
exit(1);
}
}
// Send the Messages
#pragma omp task depend(inout \
: SRequest, PSizeInfoMessages, PCumulative) depend(out \
@@ -507,6 +507,71 @@ subroutine amg_c_hierarchy_bld(a,desc_a,prec,info)
return
contains
#if ( __GNUC__ == 13 && __GNUC_MINOR__ == 3)
! gfortran 13.3.0 generates a strange error here with MOLD
! moving to SOURCE but only for this version, since it's heavier
subroutine save_smoothers(level,save1, save2,info)
type(amg_c_onelev_type), intent(inout) :: level
class(amg_c_base_smoother_type), allocatable , intent(inout) :: save1, save2
integer(psb_ipk_), intent(out) :: info
info = 0
if (allocated(save1)) then
call save1%free(info)
if (info == 0) deallocate(save1,stat=info)
if (info /= 0) return
end if
if (allocated(save2)) then
call save2%free(info)
if (info == 0) deallocate(save2,stat=info)
if (info /= 0) return
end if
allocate(save1, source=level%sm,stat=info)
if (info == 0) call level%sm%clone_settings(save1,info)
if ((info == 0).and.allocated(level%sm2a)) then
allocate(save2, source=level%sm2a,stat=info)
if (info == 0) call level%sm2a%clone_settings(save2,info)
end if
return
end subroutine save_smoothers
subroutine restore_smoothers(level,save1, save2,info)
type(amg_c_onelev_type), intent(inout), target :: level
class(amg_c_base_smoother_type), allocatable, intent(inout) :: save1, save2
integer(psb_ipk_), intent(out) :: info
info = 0
if (allocated(level%sm)) then
if (info == 0) call level%sm%free(info)
if (info == 0) deallocate(level%sm,stat=info)
end if
if (allocated(save1)) then
if (info == 0) allocate(level%sm,source=save1,stat=info)
if (info == 0) call save1%clone_settings(level%sm,info)
end if
if (info /= 0) return
if (allocated(level%sm2a)) then
if (info == 0) call level%sm2a%free(info)
if (info == 0) deallocate(level%sm2a,stat=info)
end if
if (allocated(save2)) then
if (info == 0) allocate(level%sm2a,source=save2,stat=info)
if (info == 0) call save2%clone_settings(level%sm2a,info)
if (info == 0) level%sm2 => level%sm2a
else
if (allocated(level%sm)) level%sm2 => level%sm
end if
return
end subroutine restore_smoothers
#else
subroutine save_smoothers(level,save1, save2,info)
type(amg_c_onelev_type), intent(inout) :: level
class(amg_c_base_smoother_type), allocatable , intent(inout) :: save1, save2
@@ -565,5 +630,5 @@ contains
return
end subroutine restore_smoothers
#endif
end subroutine amg_c_hierarchy_bld
+2 -2
View File
@@ -186,8 +186,8 @@ subroutine amg_c_smoothers_bld(a,desc_a,prec,info,amold,vmold,imold)
& ' but it has been changed to distributed.'
end if
case(psb_ilu_n_, psb_ilu_t_,psb_milu_n_)
if (prec%precv(iszv)%sm%sv%get_id() /= psb_ilu_n_) then
case(amg_ilu_n_, amg_ilu_t_,amg_milu_n_)
if (prec%precv(iszv)%sm%sv%get_id() /= amg_ilu_n_) then
write(psb_err_unit,*) &
& 'AMG4PSBLAS: Warning: original coarse solver was requested as ',&
& amg_fact_names(coarse_solve_id)
+18 -18
View File
@@ -485,7 +485,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -499,7 +499,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -522,7 +522,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -530,21 +530,21 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#endif
case('ILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('ILUT')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_t_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_t_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('MILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_milu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_milu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
@@ -559,7 +559,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -582,7 +582,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -606,7 +606,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -714,7 +714,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -727,7 +727,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -750,7 +750,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -758,21 +758,21 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#endif
case('ILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('ILUT')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_t_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_t_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('MILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_milu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_milu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
@@ -787,7 +787,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -810,7 +810,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -834,7 +834,7 @@ subroutine amg_ccprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
+1 -1
View File
@@ -170,7 +170,7 @@ subroutine amg_cfile_prec_descr(prec,info,iout,root, verbosity,prefix)
call prec%precv(1)%sm%descr(info,iout=iout_,prefix=prefix)
nswps = prec%precv(1)%parms%sweeps_pre
end if
write(iout_,*) trim(prefix_), ' Number of sweeps : ',nswps
write(iout_,*) trim(prefix_), ' Number of sweeps/degree : ',nswps
write(iout_,*) trim(prefix_)
else if (nlev > 1) then
+152
View File
@@ -0,0 +1,152 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
! File: amg_dfile_prec_memory_use.f90
!
!
! Subroutine: amg_file_prec_memory_use
! Version: complex
!
! This routine prints a memory_useiption of the preconditioner to the standard
! output or to a file. It must be called after the preconditioner has been
! built by amg_precbld.
!
! Arguments:
! p - type(amg_Tprec_type), input.
! The preconditioner data structure to be printed out.
! info - integer, output.
! error code.
! iout - integer, input, optional.
! The id of the file where the preconditioner description
! will be printed. If iout is not present, then the standard
! output is condidered.
! root - integer, input, optional.
! The id of the process printing the message; -1 acts as a wildcard.
! Default is psb_root_
!
!
!
! verbosity:
! <0: suppress all messages
! 0: normal
! >1: increased details
!
subroutine amg_cfile_prec_memory_use(prec,info,iout,root, verbosity,prefix,global)
use psb_base_mod
use amg_c_prec_mod, amg_protect_name => amg_cfile_prec_memory_use
use amg_c_inner_mod
use amg_c_gs_solver
implicit none
! Arguments
class(amg_cprec_type), intent(in) :: prec
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: iout
integer(psb_ipk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: verbosity
character(len=*), intent(in), optional :: prefix
logical, intent(in), optional :: global
! Local variables
integer(psb_ipk_) :: ilev, nlev, ilmin, nswps
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: me, np
logical :: is_symgs
character(len=20), parameter :: name='amg_file_prec_memory_use'
integer(psb_ipk_) :: iout_, root_, verbosity_
logical :: global_
character(1024) :: prefix_
info = psb_success_
if (present(iout)) then
iout_ = iout
else
iout_ = psb_out_unit
end if
if (iout_ < 0) iout_ = psb_out_unit
if (present(verbosity)) then
verbosity_ = verbosity
else
verbosity_ = 0
end if
if (verbosity_ < 0) goto 9998
ctxt = prec%ctxt
call psb_info(ctxt,me,np)
prefix_ = ""
if (verbosity_ == 0) then
if (present(prefix)) then
prefix_ = prefix
end if
else if (verbosity_ > 0) then
if (present(prefix)) then
write(prefix_,'(a,a,i5,a)') prefix,' from process ',me,': '
else
write(prefix_,'(a,i5,a)') 'Process ',me,': '
end if
end if
if (present(root)) then
root_ = root
else
root_ = psb_root_
end if
if (root_ == -1) root_ = me
if (allocated(prec%precv)) then
if (verbosity_ >=0) then
if (me == root_) then
write(iout_,*)
write(iout_,'(a,1x,a)') trim(prefix_),'Preconditioner memory usage'
end if
nlev = size(prec%precv)
do ilev=1,nlev
call prec%precv(ilev)%memory_use(ilev,nlev,ilmin,info, &
& iout=iout_,verbosity=verbosity_,prefix=trim(prefix_),global=global)
end do
else
write(iout_,*) trim(name), &
& ': Error: no base preconditioner available, something is wrong!'
info = -2
return
endif
end if
9998 continue
end subroutine amg_cfile_prec_memory_use
+1 -1
View File
@@ -98,6 +98,7 @@ subroutine amg_cprecinit(ctxt,prec,ptype,info)
use amg_c_diag_solver
use amg_c_ilu_solver
use amg_c_gs_solver
#if defined(HAVE_SLU_)
use amg_c_slu_solver
#endif
@@ -152,7 +153,6 @@ subroutine amg_cprecinit(ctxt,prec,ptype,info)
if (info /= psb_success_) return
allocate(amg_c_diag_solver_type :: prec%precv(ilev_)%sm%sv, stat=info)
call prec%precv(ilev_)%default()
case ('L1-DIAG','L1-JACOBI','L1_DIAG','L1_JACOBI')
nlev_ = 1
ilev_ = 1
@@ -507,6 +507,71 @@ subroutine amg_d_hierarchy_bld(a,desc_a,prec,info)
return
contains
#if ( __GNUC__ == 13 && __GNUC_MINOR__ == 3)
! gfortran 13.3.0 generates a strange error here with MOLD
! moving to SOURCE but only for this version, since it's heavier
subroutine save_smoothers(level,save1, save2,info)
type(amg_d_onelev_type), intent(inout) :: level
class(amg_d_base_smoother_type), allocatable , intent(inout) :: save1, save2
integer(psb_ipk_), intent(out) :: info
info = 0
if (allocated(save1)) then
call save1%free(info)
if (info == 0) deallocate(save1,stat=info)
if (info /= 0) return
end if
if (allocated(save2)) then
call save2%free(info)
if (info == 0) deallocate(save2,stat=info)
if (info /= 0) return
end if
allocate(save1, source=level%sm,stat=info)
if (info == 0) call level%sm%clone_settings(save1,info)
if ((info == 0).and.allocated(level%sm2a)) then
allocate(save2, source=level%sm2a,stat=info)
if (info == 0) call level%sm2a%clone_settings(save2,info)
end if
return
end subroutine save_smoothers
subroutine restore_smoothers(level,save1, save2,info)
type(amg_d_onelev_type), intent(inout), target :: level
class(amg_d_base_smoother_type), allocatable, intent(inout) :: save1, save2
integer(psb_ipk_), intent(out) :: info
info = 0
if (allocated(level%sm)) then
if (info == 0) call level%sm%free(info)
if (info == 0) deallocate(level%sm,stat=info)
end if
if (allocated(save1)) then
if (info == 0) allocate(level%sm,source=save1,stat=info)
if (info == 0) call save1%clone_settings(level%sm,info)
end if
if (info /= 0) return
if (allocated(level%sm2a)) then
if (info == 0) call level%sm2a%free(info)
if (info == 0) deallocate(level%sm2a,stat=info)
end if
if (allocated(save2)) then
if (info == 0) allocate(level%sm2a,source=save2,stat=info)
if (info == 0) call save2%clone_settings(level%sm2a,info)
if (info == 0) level%sm2 => level%sm2a
else
if (allocated(level%sm)) level%sm2 => level%sm
end if
return
end subroutine restore_smoothers
#else
subroutine save_smoothers(level,save1, save2,info)
type(amg_d_onelev_type), intent(inout) :: level
class(amg_d_base_smoother_type), allocatable , intent(inout) :: save1, save2
@@ -565,5 +630,5 @@ contains
return
end subroutine restore_smoothers
#endif
end subroutine amg_d_hierarchy_bld
+2 -2
View File
@@ -186,8 +186,8 @@ subroutine amg_d_smoothers_bld(a,desc_a,prec,info,amold,vmold,imold)
& ' but it has been changed to distributed.'
end if
case(psb_ilu_n_, psb_ilu_t_,psb_milu_n_)
if (prec%precv(iszv)%sm%sv%get_id() /= psb_ilu_n_) then
case(amg_ilu_n_, amg_ilu_t_,amg_milu_n_)
if (prec%precv(iszv)%sm%sv%get_id() /= amg_ilu_n_) then
write(psb_err_unit,*) &
& 'AMG4PSBLAS: Warning: original coarse solver was requested as ',&
& amg_fact_names(coarse_solve_id)
+18 -18
View File
@@ -499,7 +499,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -515,7 +515,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -538,7 +538,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -546,21 +546,21 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#endif
case('ILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('ILUT')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_t_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_t_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('MILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_milu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_milu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
@@ -575,7 +575,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -605,7 +605,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -643,7 +643,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -753,7 +753,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -768,7 +768,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -791,7 +791,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -799,21 +799,21 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#endif
case('ILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('ILUT')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_t_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_t_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('MILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_milu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_milu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
@@ -828,7 +828,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -858,7 +858,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -896,7 +896,7 @@ subroutine amg_dcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
+1 -1
View File
@@ -170,7 +170,7 @@ subroutine amg_dfile_prec_descr(prec,info,iout,root, verbosity,prefix)
call prec%precv(1)%sm%descr(info,iout=iout_,prefix=prefix)
nswps = prec%precv(1)%parms%sweeps_pre
end if
write(iout_,*) trim(prefix_), ' Number of sweeps : ',nswps
write(iout_,*) trim(prefix_), ' Number of sweeps/degree : ',nswps
write(iout_,*) trim(prefix_)
else if (nlev > 1) then
+152
View File
@@ -0,0 +1,152 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
! File: amg_dfile_prec_memory_use.f90
!
!
! Subroutine: amg_file_prec_memory_use
! Version: real
!
! This routine prints a memory_useiption of the preconditioner to the standard
! output or to a file. It must be called after the preconditioner has been
! built by amg_precbld.
!
! Arguments:
! p - type(amg_Tprec_type), input.
! The preconditioner data structure to be printed out.
! info - integer, output.
! error code.
! iout - integer, input, optional.
! The id of the file where the preconditioner description
! will be printed. If iout is not present, then the standard
! output is condidered.
! root - integer, input, optional.
! The id of the process printing the message; -1 acts as a wildcard.
! Default is psb_root_
!
!
!
! verbosity:
! <0: suppress all messages
! 0: normal
! >1: increased details
!
subroutine amg_dfile_prec_memory_use(prec,info,iout,root, verbosity,prefix,global)
use psb_base_mod
use amg_d_prec_mod, amg_protect_name => amg_dfile_prec_memory_use
use amg_d_inner_mod
use amg_d_gs_solver
implicit none
! Arguments
class(amg_dprec_type), intent(in) :: prec
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: iout
integer(psb_ipk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: verbosity
character(len=*), intent(in), optional :: prefix
logical, intent(in), optional :: global
! Local variables
integer(psb_ipk_) :: ilev, nlev, ilmin, nswps
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: me, np
logical :: is_symgs
character(len=20), parameter :: name='amg_file_prec_memory_use'
integer(psb_ipk_) :: iout_, root_, verbosity_
logical :: global_
character(1024) :: prefix_
info = psb_success_
if (present(iout)) then
iout_ = iout
else
iout_ = psb_out_unit
end if
if (iout_ < 0) iout_ = psb_out_unit
if (present(verbosity)) then
verbosity_ = verbosity
else
verbosity_ = 0
end if
if (verbosity_ < 0) goto 9998
ctxt = prec%ctxt
call psb_info(ctxt,me,np)
prefix_ = ""
if (verbosity_ == 0) then
if (present(prefix)) then
prefix_ = prefix
end if
else if (verbosity_ > 0) then
if (present(prefix)) then
write(prefix_,'(a,a,i5,a)') prefix,' from process ',me,': '
else
write(prefix_,'(a,i5,a)') 'Process ',me,': '
end if
end if
if (present(root)) then
root_ = root
else
root_ = psb_root_
end if
if (root_ == -1) root_ = me
if (allocated(prec%precv)) then
if (verbosity_ >=0) then
if (me == root_) then
write(iout_,*)
write(iout_,'(a,1x,a)') trim(prefix_),'Preconditioner memory usage'
end if
nlev = size(prec%precv)
do ilev=1,nlev
call prec%precv(ilev)%memory_use(ilev,nlev,ilmin,info, &
& iout=iout_,verbosity=verbosity_,prefix=trim(prefix_),global=global)
end do
else
write(iout_,*) trim(name), &
& ': Error: no base preconditioner available, something is wrong!'
info = -2
return
endif
end if
9998 continue
end subroutine amg_dfile_prec_memory_use
+10 -1
View File
@@ -98,6 +98,8 @@ subroutine amg_dprecinit(ctxt,prec,ptype,info)
use amg_d_diag_solver
use amg_d_ilu_solver
use amg_d_gs_solver
use amg_d_poly_smoother
#if defined(HAVE_UMF_)
use amg_d_umf_solver
#endif
@@ -155,7 +157,14 @@ subroutine amg_dprecinit(ctxt,prec,ptype,info)
if (info /= psb_success_) return
allocate(amg_d_diag_solver_type :: prec%precv(ilev_)%sm%sv, stat=info)
call prec%precv(ilev_)%default()
case ('POLY')
nlev_ = 1
ilev_ = 1
allocate(prec%precv(nlev_),stat=info)
allocate(amg_d_poly_smoother_type :: prec%precv(ilev_)%sm, stat=info)
if (info /= psb_success_) return
allocate(amg_d_l1_diag_solver_type :: prec%precv(ilev_)%sm%sv, stat=info)
call prec%precv(ilev_)%default()
case ('L1-DIAG','L1-JACOBI','L1_DIAG','L1_JACOBI')
nlev_ = 1
ilev_ = 1
@@ -507,6 +507,71 @@ subroutine amg_s_hierarchy_bld(a,desc_a,prec,info)
return
contains
#if ( __GNUC__ == 13 && __GNUC_MINOR__ == 3)
! gfortran 13.3.0 generates a strange error here with MOLD
! moving to SOURCE but only for this version, since it's heavier
subroutine save_smoothers(level,save1, save2,info)
type(amg_s_onelev_type), intent(inout) :: level
class(amg_s_base_smoother_type), allocatable , intent(inout) :: save1, save2
integer(psb_ipk_), intent(out) :: info
info = 0
if (allocated(save1)) then
call save1%free(info)
if (info == 0) deallocate(save1,stat=info)
if (info /= 0) return
end if
if (allocated(save2)) then
call save2%free(info)
if (info == 0) deallocate(save2,stat=info)
if (info /= 0) return
end if
allocate(save1, source=level%sm,stat=info)
if (info == 0) call level%sm%clone_settings(save1,info)
if ((info == 0).and.allocated(level%sm2a)) then
allocate(save2, source=level%sm2a,stat=info)
if (info == 0) call level%sm2a%clone_settings(save2,info)
end if
return
end subroutine save_smoothers
subroutine restore_smoothers(level,save1, save2,info)
type(amg_s_onelev_type), intent(inout), target :: level
class(amg_s_base_smoother_type), allocatable, intent(inout) :: save1, save2
integer(psb_ipk_), intent(out) :: info
info = 0
if (allocated(level%sm)) then
if (info == 0) call level%sm%free(info)
if (info == 0) deallocate(level%sm,stat=info)
end if
if (allocated(save1)) then
if (info == 0) allocate(level%sm,source=save1,stat=info)
if (info == 0) call save1%clone_settings(level%sm,info)
end if
if (info /= 0) return
if (allocated(level%sm2a)) then
if (info == 0) call level%sm2a%free(info)
if (info == 0) deallocate(level%sm2a,stat=info)
end if
if (allocated(save2)) then
if (info == 0) allocate(level%sm2a,source=save2,stat=info)
if (info == 0) call save2%clone_settings(level%sm2a,info)
if (info == 0) level%sm2 => level%sm2a
else
if (allocated(level%sm)) level%sm2 => level%sm
end if
return
end subroutine restore_smoothers
#else
subroutine save_smoothers(level,save1, save2,info)
type(amg_s_onelev_type), intent(inout) :: level
class(amg_s_base_smoother_type), allocatable , intent(inout) :: save1, save2
@@ -565,5 +630,5 @@ contains
return
end subroutine restore_smoothers
#endif
end subroutine amg_s_hierarchy_bld
+2 -2
View File
@@ -186,8 +186,8 @@ subroutine amg_s_smoothers_bld(a,desc_a,prec,info,amold,vmold,imold)
& ' but it has been changed to distributed.'
end if
case(psb_ilu_n_, psb_ilu_t_,psb_milu_n_)
if (prec%precv(iszv)%sm%sv%get_id() /= psb_ilu_n_) then
case(amg_ilu_n_, amg_ilu_t_,amg_milu_n_)
if (prec%precv(iszv)%sm%sv%get_id() /= amg_ilu_n_) then
write(psb_err_unit,*) &
& 'AMG4PSBLAS: Warning: original coarse solver was requested as ',&
& amg_fact_names(coarse_solve_id)
+18 -18
View File
@@ -485,7 +485,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -499,7 +499,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -522,7 +522,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -530,21 +530,21 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#endif
case('ILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('ILUT')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_t_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_t_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('MILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_milu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_milu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
@@ -559,7 +559,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -582,7 +582,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -606,7 +606,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -714,7 +714,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -727,7 +727,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -750,7 +750,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -758,21 +758,21 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#endif
case('ILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('ILUT')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_t_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_t_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('MILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_milu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_milu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
@@ -787,7 +787,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -810,7 +810,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -834,7 +834,7 @@ subroutine amg_scprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
+1 -1
View File
@@ -170,7 +170,7 @@ subroutine amg_sfile_prec_descr(prec,info,iout,root, verbosity,prefix)
call prec%precv(1)%sm%descr(info,iout=iout_,prefix=prefix)
nswps = prec%precv(1)%parms%sweeps_pre
end if
write(iout_,*) trim(prefix_), ' Number of sweeps : ',nswps
write(iout_,*) trim(prefix_), ' Number of sweeps/degree : ',nswps
write(iout_,*) trim(prefix_)
else if (nlev > 1) then
+152
View File
@@ -0,0 +1,152 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
! File: amg_dfile_prec_memory_use.f90
!
!
! Subroutine: amg_file_prec_memory_use
! Version: real
!
! This routine prints a memory_useiption of the preconditioner to the standard
! output or to a file. It must be called after the preconditioner has been
! built by amg_precbld.
!
! Arguments:
! p - type(amg_Tprec_type), input.
! The preconditioner data structure to be printed out.
! info - integer, output.
! error code.
! iout - integer, input, optional.
! The id of the file where the preconditioner description
! will be printed. If iout is not present, then the standard
! output is condidered.
! root - integer, input, optional.
! The id of the process printing the message; -1 acts as a wildcard.
! Default is psb_root_
!
!
!
! verbosity:
! <0: suppress all messages
! 0: normal
! >1: increased details
!
subroutine amg_sfile_prec_memory_use(prec,info,iout,root, verbosity,prefix,global)
use psb_base_mod
use amg_s_prec_mod, amg_protect_name => amg_sfile_prec_memory_use
use amg_s_inner_mod
use amg_s_gs_solver
implicit none
! Arguments
class(amg_sprec_type), intent(in) :: prec
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: iout
integer(psb_ipk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: verbosity
character(len=*), intent(in), optional :: prefix
logical, intent(in), optional :: global
! Local variables
integer(psb_ipk_) :: ilev, nlev, ilmin, nswps
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: me, np
logical :: is_symgs
character(len=20), parameter :: name='amg_file_prec_memory_use'
integer(psb_ipk_) :: iout_, root_, verbosity_
logical :: global_
character(1024) :: prefix_
info = psb_success_
if (present(iout)) then
iout_ = iout
else
iout_ = psb_out_unit
end if
if (iout_ < 0) iout_ = psb_out_unit
if (present(verbosity)) then
verbosity_ = verbosity
else
verbosity_ = 0
end if
if (verbosity_ < 0) goto 9998
ctxt = prec%ctxt
call psb_info(ctxt,me,np)
prefix_ = ""
if (verbosity_ == 0) then
if (present(prefix)) then
prefix_ = prefix
end if
else if (verbosity_ > 0) then
if (present(prefix)) then
write(prefix_,'(a,a,i5,a)') prefix,' from process ',me,': '
else
write(prefix_,'(a,i5,a)') 'Process ',me,': '
end if
end if
if (present(root)) then
root_ = root
else
root_ = psb_root_
end if
if (root_ == -1) root_ = me
if (allocated(prec%precv)) then
if (verbosity_ >=0) then
if (me == root_) then
write(iout_,*)
write(iout_,'(a,1x,a)') trim(prefix_),'Preconditioner memory usage'
end if
nlev = size(prec%precv)
do ilev=1,nlev
call prec%precv(ilev)%memory_use(ilev,nlev,ilmin,info, &
& iout=iout_,verbosity=verbosity_,prefix=trim(prefix_),global=global)
end do
else
write(iout_,*) trim(name), &
& ': Error: no base preconditioner available, something is wrong!'
info = -2
return
endif
end if
9998 continue
end subroutine amg_sfile_prec_memory_use
+10 -1
View File
@@ -98,6 +98,8 @@ subroutine amg_sprecinit(ctxt,prec,ptype,info)
use amg_s_diag_solver
use amg_s_ilu_solver
use amg_s_gs_solver
use amg_s_poly_smoother
#if defined(HAVE_SLU_)
use amg_s_slu_solver
#endif
@@ -152,7 +154,14 @@ subroutine amg_sprecinit(ctxt,prec,ptype,info)
if (info /= psb_success_) return
allocate(amg_s_diag_solver_type :: prec%precv(ilev_)%sm%sv, stat=info)
call prec%precv(ilev_)%default()
case ('POLY')
nlev_ = 1
ilev_ = 1
allocate(prec%precv(nlev_),stat=info)
allocate(amg_s_poly_smoother_type :: prec%precv(ilev_)%sm, stat=info)
if (info /= psb_success_) return
allocate(amg_s_l1_diag_solver_type :: prec%precv(ilev_)%sm%sv, stat=info)
call prec%precv(ilev_)%default()
case ('L1-DIAG','L1-JACOBI','L1_DIAG','L1_JACOBI')
nlev_ = 1
ilev_ = 1
@@ -507,6 +507,71 @@ subroutine amg_z_hierarchy_bld(a,desc_a,prec,info)
return
contains
#if ( __GNUC__ == 13 && __GNUC_MINOR__ == 3)
! gfortran 13.3.0 generates a strange error here with MOLD
! moving to SOURCE but only for this version, since it's heavier
subroutine save_smoothers(level,save1, save2,info)
type(amg_z_onelev_type), intent(inout) :: level
class(amg_z_base_smoother_type), allocatable , intent(inout) :: save1, save2
integer(psb_ipk_), intent(out) :: info
info = 0
if (allocated(save1)) then
call save1%free(info)
if (info == 0) deallocate(save1,stat=info)
if (info /= 0) return
end if
if (allocated(save2)) then
call save2%free(info)
if (info == 0) deallocate(save2,stat=info)
if (info /= 0) return
end if
allocate(save1, source=level%sm,stat=info)
if (info == 0) call level%sm%clone_settings(save1,info)
if ((info == 0).and.allocated(level%sm2a)) then
allocate(save2, source=level%sm2a,stat=info)
if (info == 0) call level%sm2a%clone_settings(save2,info)
end if
return
end subroutine save_smoothers
subroutine restore_smoothers(level,save1, save2,info)
type(amg_z_onelev_type), intent(inout), target :: level
class(amg_z_base_smoother_type), allocatable, intent(inout) :: save1, save2
integer(psb_ipk_), intent(out) :: info
info = 0
if (allocated(level%sm)) then
if (info == 0) call level%sm%free(info)
if (info == 0) deallocate(level%sm,stat=info)
end if
if (allocated(save1)) then
if (info == 0) allocate(level%sm,source=save1,stat=info)
if (info == 0) call save1%clone_settings(level%sm,info)
end if
if (info /= 0) return
if (allocated(level%sm2a)) then
if (info == 0) call level%sm2a%free(info)
if (info == 0) deallocate(level%sm2a,stat=info)
end if
if (allocated(save2)) then
if (info == 0) allocate(level%sm2a,source=save2,stat=info)
if (info == 0) call save2%clone_settings(level%sm2a,info)
if (info == 0) level%sm2 => level%sm2a
else
if (allocated(level%sm)) level%sm2 => level%sm
end if
return
end subroutine restore_smoothers
#else
subroutine save_smoothers(level,save1, save2,info)
type(amg_z_onelev_type), intent(inout) :: level
class(amg_z_base_smoother_type), allocatable , intent(inout) :: save1, save2
@@ -565,5 +630,5 @@ contains
return
end subroutine restore_smoothers
#endif
end subroutine amg_z_hierarchy_bld
+2 -2
View File
@@ -186,8 +186,8 @@ subroutine amg_z_smoothers_bld(a,desc_a,prec,info,amold,vmold,imold)
& ' but it has been changed to distributed.'
end if
case(psb_ilu_n_, psb_ilu_t_,psb_milu_n_)
if (prec%precv(iszv)%sm%sv%get_id() /= psb_ilu_n_) then
case(amg_ilu_n_, amg_ilu_t_,amg_milu_n_)
if (prec%precv(iszv)%sm%sv%get_id() /= amg_ilu_n_) then
write(psb_err_unit,*) &
& 'AMG4PSBLAS: Warning: original coarse solver was requested as ',&
& amg_fact_names(coarse_solve_id)
+18 -18
View File
@@ -499,7 +499,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -515,7 +515,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -538,7 +538,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -546,21 +546,21 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#endif
case('ILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('ILUT')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_t_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_t_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('MILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_milu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_milu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
@@ -575,7 +575,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -605,7 +605,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -643,7 +643,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -753,7 +753,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -768,7 +768,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#elif defined(HAVE_MUMPS_)
call p%precv(nlev_)%set('SUB_SOLVE',amg_mumps_,info,pos=pos)
#else
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
#endif
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
@@ -791,7 +791,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -799,21 +799,21 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
#endif
case('ILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('ILUT')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_t_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_t_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
call p%precv(nlev_)%set('COARSE_MAT',amg_repl_mat_,info,pos=pos)
case('MILU')
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_milu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_milu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_repl_mat_)
@@ -828,7 +828,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -858,7 +858,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
@@ -896,7 +896,7 @@ subroutine amg_zcprecsetc(p,what,string,info,ilev,ilmax,pos,idx)
call p%precv(nlev_)%set('COARSE_MAT',amg_distr_mat_,info,pos=pos)
#else
call p%precv(nlev_)%set('SMOOTHER_TYPE',amg_bjac_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',psb_ilu_n_,info,pos=pos)
call p%precv(nlev_)%set('SUB_SOLVE',amg_ilu_n_,info,pos=pos)
if (hier_asb) &
& call amg_warn_coarse_mat(p%precv(nlev_)%parms%get_coarse_mat(),&
& amg_distr_mat_)
+1 -1
View File
@@ -170,7 +170,7 @@ subroutine amg_zfile_prec_descr(prec,info,iout,root, verbosity,prefix)
call prec%precv(1)%sm%descr(info,iout=iout_,prefix=prefix)
nswps = prec%precv(1)%parms%sweeps_pre
end if
write(iout_,*) trim(prefix_), ' Number of sweeps : ',nswps
write(iout_,*) trim(prefix_), ' Number of sweeps/degree : ',nswps
write(iout_,*) trim(prefix_)
else if (nlev > 1) then
+152
View File
@@ -0,0 +1,152 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
! File: amg_dfile_prec_memory_use.f90
!
!
! Subroutine: amg_file_prec_memory_use
! Version: complex
!
! This routine prints a memory_useiption of the preconditioner to the standard
! output or to a file. It must be called after the preconditioner has been
! built by amg_precbld.
!
! Arguments:
! p - type(amg_Tprec_type), input.
! The preconditioner data structure to be printed out.
! info - integer, output.
! error code.
! iout - integer, input, optional.
! The id of the file where the preconditioner description
! will be printed. If iout is not present, then the standard
! output is condidered.
! root - integer, input, optional.
! The id of the process printing the message; -1 acts as a wildcard.
! Default is psb_root_
!
!
!
! verbosity:
! <0: suppress all messages
! 0: normal
! >1: increased details
!
subroutine amg_zfile_prec_memory_use(prec,info,iout,root, verbosity,prefix,global)
use psb_base_mod
use amg_z_prec_mod, amg_protect_name => amg_zfile_prec_memory_use
use amg_z_inner_mod
use amg_z_gs_solver
implicit none
! Arguments
class(amg_zprec_type), intent(in) :: prec
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: iout
integer(psb_ipk_), intent(in), optional :: root
integer(psb_ipk_), intent(in), optional :: verbosity
character(len=*), intent(in), optional :: prefix
logical, intent(in), optional :: global
! Local variables
integer(psb_ipk_) :: ilev, nlev, ilmin, nswps
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: me, np
logical :: is_symgs
character(len=20), parameter :: name='amg_file_prec_memory_use'
integer(psb_ipk_) :: iout_, root_, verbosity_
logical :: global_
character(1024) :: prefix_
info = psb_success_
if (present(iout)) then
iout_ = iout
else
iout_ = psb_out_unit
end if
if (iout_ < 0) iout_ = psb_out_unit
if (present(verbosity)) then
verbosity_ = verbosity
else
verbosity_ = 0
end if
if (verbosity_ < 0) goto 9998
ctxt = prec%ctxt
call psb_info(ctxt,me,np)
prefix_ = ""
if (verbosity_ == 0) then
if (present(prefix)) then
prefix_ = prefix
end if
else if (verbosity_ > 0) then
if (present(prefix)) then
write(prefix_,'(a,a,i5,a)') prefix,' from process ',me,': '
else
write(prefix_,'(a,i5,a)') 'Process ',me,': '
end if
end if
if (present(root)) then
root_ = root
else
root_ = psb_root_
end if
if (root_ == -1) root_ = me
if (allocated(prec%precv)) then
if (verbosity_ >=0) then
if (me == root_) then
write(iout_,*)
write(iout_,'(a,1x,a)') trim(prefix_),'Preconditioner memory usage'
end if
nlev = size(prec%precv)
do ilev=1,nlev
call prec%precv(ilev)%memory_use(ilev,nlev,ilmin,info, &
& iout=iout_,verbosity=verbosity_,prefix=trim(prefix_),global=global)
end do
else
write(iout_,*) trim(name), &
& ': Error: no base preconditioner available, something is wrong!'
info = -2
return
endif
end if
9998 continue
end subroutine amg_zfile_prec_memory_use
+1 -1
View File
@@ -98,6 +98,7 @@ subroutine amg_zprecinit(ctxt,prec,ptype,info)
use amg_z_diag_solver
use amg_z_ilu_solver
use amg_z_gs_solver
#if defined(HAVE_UMF_)
use amg_z_umf_solver
#endif
@@ -155,7 +156,6 @@ subroutine amg_zprecinit(ctxt,prec,ptype,info)
if (info /= psb_success_) return
allocate(amg_z_diag_solver_type :: prec%precv(ilev_)%sm%sv, stat=info)
call prec%precv(ilev_)%default()
case ('L1-DIAG','L1-JACOBI','L1_DIAG','L1_JACOBI')
nlev_ = 1
ilev_ = 1
+4
View File
@@ -15,6 +15,7 @@ amg_c_base_onelev_csetc.o \
amg_c_base_onelev_cseti.o \
amg_c_base_onelev_csetr.o \
amg_c_base_onelev_descr.o \
amg_c_base_onelev_memory_use.o \
amg_c_base_onelev_dump.o \
amg_c_base_onelev_free.o \
amg_c_base_onelev_free_smoothers.o \
@@ -31,6 +32,7 @@ amg_d_base_onelev_csetc.o \
amg_d_base_onelev_cseti.o \
amg_d_base_onelev_csetr.o \
amg_d_base_onelev_descr.o \
amg_d_base_onelev_memory_use.o \
amg_d_base_onelev_dump.o \
amg_d_base_onelev_free.o \
amg_d_base_onelev_free_smoothers.o \
@@ -47,6 +49,7 @@ amg_s_base_onelev_csetc.o \
amg_s_base_onelev_cseti.o \
amg_s_base_onelev_csetr.o \
amg_s_base_onelev_descr.o \
amg_s_base_onelev_memory_use.o \
amg_s_base_onelev_dump.o \
amg_s_base_onelev_free.o \
amg_s_base_onelev_free_smoothers.o \
@@ -63,6 +66,7 @@ amg_z_base_onelev_csetc.o \
amg_z_base_onelev_cseti.o \
amg_z_base_onelev_csetr.o \
amg_z_base_onelev_descr.o \
amg_z_base_onelev_memory_use.o \
amg_z_base_onelev_dump.o \
amg_z_base_onelev_free.o \
amg_z_base_onelev_free_smoothers.o \
@@ -43,7 +43,6 @@ subroutine amg_c_base_onelev_csetc(lv,what,val,info,pos,idx)
use amg_c_dec_aggregator_mod
use amg_c_symdec_aggregator_mod
#if !defined(SERIAL_MPI)
#endif
use amg_c_jac_smoother
use amg_c_as_smoother
use amg_c_diag_solver
@@ -190,16 +189,11 @@ subroutine amg_c_base_onelev_csetc(lv,what,val,info,pos,idx)
case ('NONE','NOPREC','FACT_NONE')
call lv%set(amg_c_id_solver_mold,info,pos=pos)
case ('DIAG')
case ('DIAG','JACOBI')
call lv%set(amg_c_diag_solver_mold,info,pos=pos)
case ('JACOBI')
call lv%set(amg_c_jac_solver_mold,info,pos=pos)
case ('L1-DIAG')
case ('L1-DIAG','L1-JACOBI')
call lv%set(amg_c_l1_diag_solver_mold,info,pos=pos)
case ('L1-JACOBI')
call lv%set(amg_c_l1_jac_solver_mold,info,pos=pos)
case ('GS','FGS','FWGS')
call lv%set(amg_c_gs_solver_mold,info,pos=pos)
@@ -164,7 +164,7 @@ subroutine amg_c_base_onelev_cseti(lv,what,val,info,pos,idx)
case (amg_bwgs_)
call lv%set(amg_c_bwgs_solver_mold,info,pos=pos)
case (psb_ilu_n_,psb_milu_n_,psb_ilu_t_)
case (amg_ilu_n_,amg_milu_n_,amg_ilu_t_)
call lv%set(amg_c_ilu_solver_mold,info,pos=pos)
if (info == 0) then
if ((ipos_==amg_smooth_pre_) .or.(ipos_==amg_smooth_both_)) then
@@ -0,0 +1,150 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
!
! verbosity:
! <0: suppress all messages
! 0: normal
! >1: increased details
!
subroutine amg_c_base_onelev_memory_use(lv,il,nl,ilmin,info,iout,verbosity,prefix,global)
use psb_base_mod
use amg_c_onelev_mod, amg_protect_name => amg_c_base_onelev_memory_use
Implicit None
! Arguments
class(amg_c_onelev_type), intent(in) :: lv
integer(psb_ipk_), intent(in) :: il,nl,ilmin
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: iout
character(len=*), intent(in), optional :: prefix
integer(psb_ipk_), intent(in), optional :: verbosity
logical, intent(in), optional :: global
! Local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: err_act ,me, np
character(len=20), parameter :: name='amg_c_base_onelev_memory_use'
integer(psb_ipk_) :: iout_, verbosity_
logical :: coarse, global_
character(1024) :: prefix_
integer(psb_epk_), allocatable :: sz(:)
call psb_erractionsave(err_act)
ctxt = lv%base_desc%get_ctxt()
call psb_info(ctxt,me,np)
coarse = (il==nl)
if (present(iout)) then
iout_ = iout
else
iout_ = psb_out_unit
end if
if (present(verbosity)) then
verbosity_ = verbosity
else
verbosity_ = 0
end if
if (verbosity_ < 0) goto 9998
if (present(global)) then
global_ = global
else
global_ = .true.
end if
if (present(prefix)) then
prefix_ = prefix
else
prefix_ = ""
end if
if ((me == 0).or.(verbosity_>0)) write(iout_,*) trim(prefix_)
if (global_) then
allocate(sz(6))
sz(:) = 0
sz(1) = lv%base_a%sizeof()
sz(2) = lv%base_desc%sizeof()
if (il >1) sz(3) = lv%linmap%sizeof()
if (allocated(lv%sm)) sz(4) = lv%sm%sizeof()
if (allocated(lv%sm2a)) sz(5) = lv%sm2a%sizeof()
if (allocated(lv%wrk)) sz(6) = lv%wrk%sizeof()
call psb_sum(ctxt,sz)
if (me == 0) then
if (coarse) then
write(iout_,*) trim(prefix_), ' Level ',il,' (coarse)'
else
write(iout_,*) trim(prefix_), ' Level ',il
end if
write(iout_,*) trim(prefix_), ' Matrix:', sz(1)
write(iout_,*) trim(prefix_), ' Descriptor:', sz(2)
if (il >1) write(iout_,*) trim(prefix_), ' Linear map:', sz(3)
if (allocated(lv%sm)) write(iout_,*) trim(prefix_), ' Smoother:', sz(4)
if (allocated(lv%sm2a)) write(iout_,*) trim(prefix_), ' Smoother 2:', sz(5)
if (allocated(lv%wrk)) write(iout_,*) trim(prefix_), ' Workspace:', sz(6)
end if
else
if ((me == 0).or.(verbosity_>0)) then
if (coarse) then
write(iout_,*) trim(prefix_), ' Level ',il,' (coarse)'
else
write(iout_,*) trim(prefix_), ' Level ',il
end if
write(iout_,*) trim(prefix_), ' Matrix:', lv%base_a%sizeof()
write(iout_,*) trim(prefix_), ' Descriptor:', lv%base_desc%sizeof()
if (il >1) write(iout_,*) trim(prefix_), ' Linear map:', lv%linmap%sizeof()
if (allocated(lv%sm)) write(iout_,*) trim(prefix_), ' Smoother:', lv%sm%sizeof()
if (allocated(lv%sm2a)) write(iout_,*) trim(prefix_), ' Smoother 2:', lv%sm2a%sizeof()
if (allocated(lv%wrk)) write(iout_,*) trim(prefix_), ' Workspace:', lv%wrk%sizeof()
end if
endif
9998 continue
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_c_base_onelev_memory_use
@@ -44,7 +44,7 @@ subroutine amg_d_base_onelev_csetc(lv,what,val,info,pos,idx)
use amg_d_symdec_aggregator_mod
#if !defined(SERIAL_MPI)
use amg_d_parmatch_aggregator_mod
#endif
use amg_d_poly_smoother
use amg_d_jac_smoother
use amg_d_as_smoother
use amg_d_diag_solver
@@ -97,6 +97,7 @@ subroutine amg_d_base_onelev_csetc(lv,what,val,info,pos,idx)
type(amg_d_ainv_solver_type) :: amg_d_ainv_solver_mold
type(amg_d_invk_solver_type) :: amg_d_invk_solver_mold
type(amg_d_invt_solver_type) :: amg_d_invt_solver_mold
type(amg_d_poly_smoother_type) :: amg_d_poly_smoother_mold
#if defined(HAVE_UMF_)
type(amg_d_umf_solver_type) :: amg_d_umf_solver_mold
#endif
@@ -158,6 +159,9 @@ subroutine amg_d_base_onelev_csetc(lv,what,val,info,pos,idx)
call lv%set(amg_d_as_smoother_mold,info,pos=pos)
if (info == 0) call lv%set(amg_d_ilu_solver_mold,info,pos=pos)
case ('POLY')
call lv%set(amg_d_poly_smoother_mold,info,pos=pos)
if (info == 0) call lv%set(amg_d_l1_diag_solver_mold,info,pos=pos)
case ('GS','FWGS')
call lv%set(amg_d_jac_smoother_mold,info,pos='pre')
if (info == 0) call lv%set(amg_d_gs_solver_mold,info,pos='pre')
@@ -203,16 +207,11 @@ subroutine amg_d_base_onelev_csetc(lv,what,val,info,pos,idx)
case ('NONE','NOPREC','FACT_NONE')
call lv%set(amg_d_id_solver_mold,info,pos=pos)
case ('DIAG')
case ('DIAG','JACOBI')
call lv%set(amg_d_diag_solver_mold,info,pos=pos)
case ('JACOBI')
call lv%set(amg_d_jac_solver_mold,info,pos=pos)
case ('L1-DIAG')
case ('L1-DIAG','L1-JACOBI')
call lv%set(amg_d_l1_diag_solver_mold,info,pos=pos)
case ('L1-JACOBI')
call lv%set(amg_d_l1_jac_solver_mold,info,pos=pos)
case ('GS','FGS','FWGS')
call lv%set(amg_d_gs_solver_mold,info,pos=pos)
@@ -177,7 +177,7 @@ subroutine amg_d_base_onelev_cseti(lv,what,val,info,pos,idx)
case (amg_bwgs_)
call lv%set(amg_d_bwgs_solver_mold,info,pos=pos)
case (psb_ilu_n_,psb_milu_n_,psb_ilu_t_)
case (amg_ilu_n_,amg_milu_n_,amg_ilu_t_)
call lv%set(amg_d_ilu_solver_mold,info,pos=pos)
if (info == 0) then
if ((ipos_==amg_smooth_pre_) .or.(ipos_==amg_smooth_both_)) then
@@ -0,0 +1,150 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
!
! verbosity:
! <0: suppress all messages
! 0: normal
! >1: increased details
!
subroutine amg_d_base_onelev_memory_use(lv,il,nl,ilmin,info,iout,verbosity,prefix,global)
use psb_base_mod
use amg_d_onelev_mod, amg_protect_name => amg_d_base_onelev_memory_use
Implicit None
! Arguments
class(amg_d_onelev_type), intent(in) :: lv
integer(psb_ipk_), intent(in) :: il,nl,ilmin
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: iout
character(len=*), intent(in), optional :: prefix
integer(psb_ipk_), intent(in), optional :: verbosity
logical, intent(in), optional :: global
! Local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: err_act ,me, np
character(len=20), parameter :: name='amg_d_base_onelev_memory_use'
integer(psb_ipk_) :: iout_, verbosity_
logical :: coarse, global_
character(1024) :: prefix_
integer(psb_epk_), allocatable :: sz(:)
call psb_erractionsave(err_act)
ctxt = lv%base_desc%get_ctxt()
call psb_info(ctxt,me,np)
coarse = (il==nl)
if (present(iout)) then
iout_ = iout
else
iout_ = psb_out_unit
end if
if (present(verbosity)) then
verbosity_ = verbosity
else
verbosity_ = 0
end if
if (verbosity_ < 0) goto 9998
if (present(global)) then
global_ = global
else
global_ = .true.
end if
if (present(prefix)) then
prefix_ = prefix
else
prefix_ = ""
end if
if ((me == 0).or.(verbosity_>0)) write(iout_,*) trim(prefix_)
if (global_) then
allocate(sz(6))
sz(:) = 0
sz(1) = lv%base_a%sizeof()
sz(2) = lv%base_desc%sizeof()
if (il >1) sz(3) = lv%linmap%sizeof()
if (allocated(lv%sm)) sz(4) = lv%sm%sizeof()
if (allocated(lv%sm2a)) sz(5) = lv%sm2a%sizeof()
if (allocated(lv%wrk)) sz(6) = lv%wrk%sizeof()
call psb_sum(ctxt,sz)
if (me == 0) then
if (coarse) then
write(iout_,*) trim(prefix_), ' Level ',il,' (coarse)'
else
write(iout_,*) trim(prefix_), ' Level ',il
end if
write(iout_,*) trim(prefix_), ' Matrix:', sz(1)
write(iout_,*) trim(prefix_), ' Descriptor:', sz(2)
if (il >1) write(iout_,*) trim(prefix_), ' Linear map:', sz(3)
if (allocated(lv%sm)) write(iout_,*) trim(prefix_), ' Smoother:', sz(4)
if (allocated(lv%sm2a)) write(iout_,*) trim(prefix_), ' Smoother 2:', sz(5)
if (allocated(lv%wrk)) write(iout_,*) trim(prefix_), ' Workspace:', sz(6)
end if
else
if ((me == 0).or.(verbosity_>0)) then
if (coarse) then
write(iout_,*) trim(prefix_), ' Level ',il,' (coarse)'
else
write(iout_,*) trim(prefix_), ' Level ',il
end if
write(iout_,*) trim(prefix_), ' Matrix:', lv%base_a%sizeof()
write(iout_,*) trim(prefix_), ' Descriptor:', lv%base_desc%sizeof()
if (il >1) write(iout_,*) trim(prefix_), ' Linear map:', lv%linmap%sizeof()
if (allocated(lv%sm)) write(iout_,*) trim(prefix_), ' Smoother:', lv%sm%sizeof()
if (allocated(lv%sm2a)) write(iout_,*) trim(prefix_), ' Smoother 2:', lv%sm2a%sizeof()
if (allocated(lv%wrk)) write(iout_,*) trim(prefix_), ' Workspace:', lv%wrk%sizeof()
end if
endif
9998 continue
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_d_base_onelev_memory_use
@@ -44,7 +44,7 @@ subroutine amg_s_base_onelev_csetc(lv,what,val,info,pos,idx)
use amg_s_symdec_aggregator_mod
#if !defined(SERIAL_MPI)
use amg_s_parmatch_aggregator_mod
#endif
use amg_s_poly_smoother
use amg_s_jac_smoother
use amg_s_as_smoother
use amg_s_diag_solver
@@ -91,6 +91,7 @@ subroutine amg_s_base_onelev_csetc(lv,what,val,info,pos,idx)
type(amg_s_ainv_solver_type) :: amg_s_ainv_solver_mold
type(amg_s_invk_solver_type) :: amg_s_invk_solver_mold
type(amg_s_invt_solver_type) :: amg_s_invt_solver_mold
type(amg_s_poly_smoother_type) :: amg_s_poly_smoother_mold
#if defined(HAVE_SLU_)
type(amg_s_slu_solver_type) :: amg_s_slu_solver_mold
#endif
@@ -146,6 +147,9 @@ subroutine amg_s_base_onelev_csetc(lv,what,val,info,pos,idx)
call lv%set(amg_s_as_smoother_mold,info,pos=pos)
if (info == 0) call lv%set(amg_s_ilu_solver_mold,info,pos=pos)
case ('POLY')
call lv%set(amg_s_poly_smoother_mold,info,pos=pos)
if (info == 0) call lv%set(amg_s_l1_diag_solver_mold,info,pos=pos)
case ('GS','FWGS')
call lv%set(amg_s_jac_smoother_mold,info,pos='pre')
if (info == 0) call lv%set(amg_s_gs_solver_mold,info,pos='pre')
@@ -191,16 +195,11 @@ subroutine amg_s_base_onelev_csetc(lv,what,val,info,pos,idx)
case ('NONE','NOPREC','FACT_NONE')
call lv%set(amg_s_id_solver_mold,info,pos=pos)
case ('DIAG')
case ('DIAG','JACOBI')
call lv%set(amg_s_diag_solver_mold,info,pos=pos)
case ('JACOBI')
call lv%set(amg_s_jac_solver_mold,info,pos=pos)
case ('L1-DIAG')
case ('L1-DIAG','L1-JACOBI')
call lv%set(amg_s_l1_diag_solver_mold,info,pos=pos)
case ('L1-JACOBI')
call lv%set(amg_s_l1_jac_solver_mold,info,pos=pos)
case ('GS','FGS','FWGS')
call lv%set(amg_s_gs_solver_mold,info,pos=pos)
@@ -165,7 +165,7 @@ subroutine amg_s_base_onelev_cseti(lv,what,val,info,pos,idx)
case (amg_bwgs_)
call lv%set(amg_s_bwgs_solver_mold,info,pos=pos)
case (psb_ilu_n_,psb_milu_n_,psb_ilu_t_)
case (amg_ilu_n_,amg_milu_n_,amg_ilu_t_)
call lv%set(amg_s_ilu_solver_mold,info,pos=pos)
if (info == 0) then
if ((ipos_==amg_smooth_pre_) .or.(ipos_==amg_smooth_both_)) then
@@ -0,0 +1,150 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
!
! verbosity:
! <0: suppress all messages
! 0: normal
! >1: increased details
!
subroutine amg_s_base_onelev_memory_use(lv,il,nl,ilmin,info,iout,verbosity,prefix,global)
use psb_base_mod
use amg_s_onelev_mod, amg_protect_name => amg_s_base_onelev_memory_use
Implicit None
! Arguments
class(amg_s_onelev_type), intent(in) :: lv
integer(psb_ipk_), intent(in) :: il,nl,ilmin
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: iout
character(len=*), intent(in), optional :: prefix
integer(psb_ipk_), intent(in), optional :: verbosity
logical, intent(in), optional :: global
! Local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: err_act ,me, np
character(len=20), parameter :: name='amg_s_base_onelev_memory_use'
integer(psb_ipk_) :: iout_, verbosity_
logical :: coarse, global_
character(1024) :: prefix_
integer(psb_epk_), allocatable :: sz(:)
call psb_erractionsave(err_act)
ctxt = lv%base_desc%get_ctxt()
call psb_info(ctxt,me,np)
coarse = (il==nl)
if (present(iout)) then
iout_ = iout
else
iout_ = psb_out_unit
end if
if (present(verbosity)) then
verbosity_ = verbosity
else
verbosity_ = 0
end if
if (verbosity_ < 0) goto 9998
if (present(global)) then
global_ = global
else
global_ = .true.
end if
if (present(prefix)) then
prefix_ = prefix
else
prefix_ = ""
end if
if ((me == 0).or.(verbosity_>0)) write(iout_,*) trim(prefix_)
if (global_) then
allocate(sz(6))
sz(:) = 0
sz(1) = lv%base_a%sizeof()
sz(2) = lv%base_desc%sizeof()
if (il >1) sz(3) = lv%linmap%sizeof()
if (allocated(lv%sm)) sz(4) = lv%sm%sizeof()
if (allocated(lv%sm2a)) sz(5) = lv%sm2a%sizeof()
if (allocated(lv%wrk)) sz(6) = lv%wrk%sizeof()
call psb_sum(ctxt,sz)
if (me == 0) then
if (coarse) then
write(iout_,*) trim(prefix_), ' Level ',il,' (coarse)'
else
write(iout_,*) trim(prefix_), ' Level ',il
end if
write(iout_,*) trim(prefix_), ' Matrix:', sz(1)
write(iout_,*) trim(prefix_), ' Descriptor:', sz(2)
if (il >1) write(iout_,*) trim(prefix_), ' Linear map:', sz(3)
if (allocated(lv%sm)) write(iout_,*) trim(prefix_), ' Smoother:', sz(4)
if (allocated(lv%sm2a)) write(iout_,*) trim(prefix_), ' Smoother 2:', sz(5)
if (allocated(lv%wrk)) write(iout_,*) trim(prefix_), ' Workspace:', sz(6)
end if
else
if ((me == 0).or.(verbosity_>0)) then
if (coarse) then
write(iout_,*) trim(prefix_), ' Level ',il,' (coarse)'
else
write(iout_,*) trim(prefix_), ' Level ',il
end if
write(iout_,*) trim(prefix_), ' Matrix:', lv%base_a%sizeof()
write(iout_,*) trim(prefix_), ' Descriptor:', lv%base_desc%sizeof()
if (il >1) write(iout_,*) trim(prefix_), ' Linear map:', lv%linmap%sizeof()
if (allocated(lv%sm)) write(iout_,*) trim(prefix_), ' Smoother:', lv%sm%sizeof()
if (allocated(lv%sm2a)) write(iout_,*) trim(prefix_), ' Smoother 2:', lv%sm2a%sizeof()
if (allocated(lv%wrk)) write(iout_,*) trim(prefix_), ' Workspace:', lv%wrk%sizeof()
end if
endif
9998 continue
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_s_base_onelev_memory_use
@@ -43,7 +43,6 @@ subroutine amg_z_base_onelev_csetc(lv,what,val,info,pos,idx)
use amg_z_dec_aggregator_mod
use amg_z_symdec_aggregator_mod
#if !defined(SERIAL_MPI)
#endif
use amg_z_jac_smoother
use amg_z_as_smoother
use amg_z_diag_solver
@@ -202,16 +201,11 @@ subroutine amg_z_base_onelev_csetc(lv,what,val,info,pos,idx)
case ('NONE','NOPREC','FACT_NONE')
call lv%set(amg_z_id_solver_mold,info,pos=pos)
case ('DIAG')
case ('DIAG','JACOBI')
call lv%set(amg_z_diag_solver_mold,info,pos=pos)
case ('JACOBI')
call lv%set(amg_z_jac_solver_mold,info,pos=pos)
case ('L1-DIAG')
case ('L1-DIAG','L1-JACOBI')
call lv%set(amg_z_l1_diag_solver_mold,info,pos=pos)
case ('L1-JACOBI')
call lv%set(amg_z_l1_jac_solver_mold,info,pos=pos)
case ('GS','FGS','FWGS')
call lv%set(amg_z_gs_solver_mold,info,pos=pos)
@@ -176,7 +176,7 @@ subroutine amg_z_base_onelev_cseti(lv,what,val,info,pos,idx)
case (amg_bwgs_)
call lv%set(amg_z_bwgs_solver_mold,info,pos=pos)
case (psb_ilu_n_,psb_milu_n_,psb_ilu_t_)
case (amg_ilu_n_,amg_milu_n_,amg_ilu_t_)
call lv%set(amg_z_ilu_solver_mold,info,pos=pos)
if (info == 0) then
if ((ipos_==amg_smooth_pre_) .or.(ipos_==amg_smooth_both_)) then
@@ -0,0 +1,150 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
!
!
! verbosity:
! <0: suppress all messages
! 0: normal
! >1: increased details
!
subroutine amg_z_base_onelev_memory_use(lv,il,nl,ilmin,info,iout,verbosity,prefix,global)
use psb_base_mod
use amg_z_onelev_mod, amg_protect_name => amg_z_base_onelev_memory_use
Implicit None
! Arguments
class(amg_z_onelev_type), intent(in) :: lv
integer(psb_ipk_), intent(in) :: il,nl,ilmin
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: iout
character(len=*), intent(in), optional :: prefix
integer(psb_ipk_), intent(in), optional :: verbosity
logical, intent(in), optional :: global
! Local variables
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: err_act ,me, np
character(len=20), parameter :: name='amg_z_base_onelev_memory_use'
integer(psb_ipk_) :: iout_, verbosity_
logical :: coarse, global_
character(1024) :: prefix_
integer(psb_epk_), allocatable :: sz(:)
call psb_erractionsave(err_act)
ctxt = lv%base_desc%get_ctxt()
call psb_info(ctxt,me,np)
coarse = (il==nl)
if (present(iout)) then
iout_ = iout
else
iout_ = psb_out_unit
end if
if (present(verbosity)) then
verbosity_ = verbosity
else
verbosity_ = 0
end if
if (verbosity_ < 0) goto 9998
if (present(global)) then
global_ = global
else
global_ = .true.
end if
if (present(prefix)) then
prefix_ = prefix
else
prefix_ = ""
end if
if ((me == 0).or.(verbosity_>0)) write(iout_,*) trim(prefix_)
if (global_) then
allocate(sz(6))
sz(:) = 0
sz(1) = lv%base_a%sizeof()
sz(2) = lv%base_desc%sizeof()
if (il >1) sz(3) = lv%linmap%sizeof()
if (allocated(lv%sm)) sz(4) = lv%sm%sizeof()
if (allocated(lv%sm2a)) sz(5) = lv%sm2a%sizeof()
if (allocated(lv%wrk)) sz(6) = lv%wrk%sizeof()
call psb_sum(ctxt,sz)
if (me == 0) then
if (coarse) then
write(iout_,*) trim(prefix_), ' Level ',il,' (coarse)'
else
write(iout_,*) trim(prefix_), ' Level ',il
end if
write(iout_,*) trim(prefix_), ' Matrix:', sz(1)
write(iout_,*) trim(prefix_), ' Descriptor:', sz(2)
if (il >1) write(iout_,*) trim(prefix_), ' Linear map:', sz(3)
if (allocated(lv%sm)) write(iout_,*) trim(prefix_), ' Smoother:', sz(4)
if (allocated(lv%sm2a)) write(iout_,*) trim(prefix_), ' Smoother 2:', sz(5)
if (allocated(lv%wrk)) write(iout_,*) trim(prefix_), ' Workspace:', sz(6)
end if
else
if ((me == 0).or.(verbosity_>0)) then
if (coarse) then
write(iout_,*) trim(prefix_), ' Level ',il,' (coarse)'
else
write(iout_,*) trim(prefix_), ' Level ',il
end if
write(iout_,*) trim(prefix_), ' Matrix:', lv%base_a%sizeof()
write(iout_,*) trim(prefix_), ' Descriptor:', lv%base_desc%sizeof()
if (il >1) write(iout_,*) trim(prefix_), ' Linear map:', lv%linmap%sizeof()
if (allocated(lv%sm)) write(iout_,*) trim(prefix_), ' Smoother:', lv%sm%sizeof()
if (allocated(lv%sm2a)) write(iout_,*) trim(prefix_), ' Smoother 2:', lv%sm2a%sizeof()
if (allocated(lv%wrk)) write(iout_,*) trim(prefix_), ' Workspace:', lv%wrk%sizeof()
end if
endif
9998 continue
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_z_base_onelev_memory_use
+22
View File
@@ -97,6 +97,17 @@ amg_d_jac_smoother_csetr.o \
amg_d_l1_jac_smoother_bld.o \
amg_d_l1_jac_smoother_descr.o \
amg_d_l1_jac_smoother_clone.o \
amg_d_poly_smoother_apply_vect.o \
amg_d_poly_smoother_bld.o \
amg_d_poly_smoother_cnv.o \
amg_d_poly_smoother_clone.o \
amg_d_poly_smoother_clone_settings.o \
amg_d_poly_smoother_clear_data.o \
amg_d_poly_smoother_descr.o \
amg_d_poly_smoother_dmp.o \
amg_d_poly_smoother_csetc.o \
amg_d_poly_smoother_cseti.o \
amg_d_poly_smoother_csetr.o \
amg_s_as_smoother_apply.o \
amg_s_as_smoother_apply_vect.o \
amg_s_as_smoother_bld.o \
@@ -142,6 +153,17 @@ amg_s_jac_smoother_csetr.o \
amg_s_l1_jac_smoother_bld.o \
amg_s_l1_jac_smoother_descr.o \
amg_s_l1_jac_smoother_clone.o \
amg_s_poly_smoother_apply_vect.o \
amg_s_poly_smoother_bld.o \
amg_s_poly_smoother_cnv.o \
amg_s_poly_smoother_clone.o \
amg_s_poly_smoother_clone_settings.o \
amg_s_poly_smoother_clear_data.o \
amg_s_poly_smoother_descr.o \
amg_s_poly_smoother_dmp.o \
amg_s_poly_smoother_csetc.o \
amg_s_poly_smoother_cseti.o \
amg_s_poly_smoother_csetr.o \
amg_z_as_smoother_apply.o \
amg_z_as_smoother_apply_vect.o \
amg_z_as_smoother_bld.o \
@@ -175,7 +175,7 @@ subroutine amg_c_jac_smoother_apply_vect(alpha,sm,x,beta,y,desc_data,trans,&
if (info /= psb_success_) exit
if ( sm%checkres.and.(mod(i,sm%checkiter) == 0) ) then
call psb_geaxpby(cone,x,czero,r,r,desc_data,info)
call psb_geaxpby(cone,x,czero,r,desc_data,info)
call psb_spmm(-cone,sm%pa,ty,cone,r,desc_data,info)
res = psb_genrm2(r,desc_data,info)
if( sm%printres ) then
@@ -175,7 +175,7 @@ subroutine amg_d_jac_smoother_apply_vect(alpha,sm,x,beta,y,desc_data,trans,&
if (info /= psb_success_) exit
if ( sm%checkres.and.(mod(i,sm%checkiter) == 0) ) then
call psb_geaxpby(done,x,dzero,r,r,desc_data,info)
call psb_geaxpby(done,x,dzero,r,desc_data,info)
call psb_spmm(-done,sm%pa,ty,done,r,desc_data,info)
res = psb_genrm2(r,desc_data,info)
if( sm%printres ) then
@@ -0,0 +1,281 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_d_poly_smoother_apply_vect(alpha,sm,x,beta,y,desc_data,trans,&
& sweeps,work,wv,info,init,initu)
use psb_base_mod
use amg_d_diag_solver
use psb_base_krylov_conv_mod, only : log_conv
use amg_d_poly_smoother, amg_protect_name => amg_d_poly_smoother_apply_vect
implicit none
type(psb_desc_type), intent(in) :: desc_data
class(amg_d_poly_smoother_type), intent(inout) :: sm
type(psb_d_vect_type),intent(inout) :: x
type(psb_d_vect_type),intent(inout) :: y
real(psb_dpk_),intent(in) :: alpha,beta
character(len=1),intent(in) :: trans
integer(psb_ipk_), intent(in) :: sweeps! this is ignored here, the polynomial degree dictates the value
real(psb_dpk_),target, intent(inout) :: work(:)
type(psb_d_vect_type),intent(inout) :: wv(:)
integer(psb_ipk_), intent(out) :: info
character, intent(in), optional :: init
type(psb_d_vect_type),intent(inout), optional :: initu
! Timers
logical, parameter :: do_timings=.true.
integer(psb_ipk_), save :: poly_1=-1, poly_2=-1, poly_3=-1
integer(psb_ipk_), save :: poly_mv=-1, poly_sv=-1, poly_vect=-1
!
integer(psb_ipk_) :: n_row,n_col
type(psb_d_vect_type) :: tx, ty, tz, r
real(psb_dpk_), pointer :: aux(:)
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np, me, i, err_act
character :: trans_, init_
real(psb_dpk_) :: res, resdenum
character(len=20) :: name='d_poly_smoother_apply_v'
call psb_erractionsave(err_act)
info = psb_success_
ctxt = desc_data%get_context()
call psb_info(ctxt,me,np)
if (present(init)) then
init_ = psb_toupper(init)
else
init_='Z'
end if
trans_ = psb_toupper(trans)
select case(trans_)
case('N')
case('T','C')
case default
call psb_errpush(psb_err_iarg_invalid_i_,name)
goto 9999
end select
if (.not.allocated(sm%sv)) then
info = 1121
call psb_errpush(info,name)
goto 9999
end if
if ((do_timings).and.(poly_1==-1)) &
& poly_1 = psb_get_timer_idx("POLY: Chebychev4")
if ((do_timings).and.(poly_2==-1)) &
& poly_2 = psb_get_timer_idx("POLY: OptChebychev4")
if ((do_timings).and.(poly_3==-1)) &
& poly_3 = psb_get_timer_idx("POLY: OptChebychev1")
if ((do_timings).and.(poly_mv==-1)) &
& poly_mv = psb_get_timer_idx("POLY: spMV")
if ((do_timings).and.(poly_vect==-1)) &
& poly_vect = psb_get_timer_idx("POLY: Vectors")
if ((do_timings).and.(poly_sv==-1)) &
& poly_sv = psb_get_timer_idx("POLY: solver")
n_row = desc_data%get_local_rows()
n_col = desc_data%get_local_cols()
if (4*n_col <= size(work)) then
aux => work(:)
else
allocate(aux(4*n_col),stat=info)
if (info /= psb_success_) then
info=psb_err_alloc_request_
call psb_errpush(info,name,&
& i_err=(/4*n_col,izero,izero,izero,izero/),&
& a_err='real(psb_dpk_)')
goto 9999
end if
endif
if (size(wv) < 4) then
info = psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='invalid wv size in smoother_apply')
goto 9999
end if
associate(tx => wv(1), ty => wv(2), tz => wv(3), r => wv(4))
call psb_geaxpby(done,x,dzero,r,desc_data,info)
call tx%zero()
call ty%zero()
call tz%zero()
select case(sm%variant)
case(amg_poly_lottes_)
if (do_timings) call psb_tic(poly_1)
block
real(psb_dpk_) :: cz, cr
! b == x
! x == tx
!
do i=1, sm%pdegree-1
! B r_{k-1}
if (do_timings) call psb_tic(poly_sv)
call sm%sv%apply(done,r,dzero,ty,desc_data,trans_,aux,wv(5:),info,init='Z') ! ty = M^{-1} r
if (do_timings) call psb_toc(poly_sv)
cz = (2*i*done-3)/(2*i*done+done)
cr = (8*i*done-4)/((2*i*done+done)*sm%rho_ba)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz(cr,cz,done,done,ty,tz,tx,desc_data,info) ! zk = cz * zk-1 + cr * rk-1
if (do_timings) call psb_toc(poly_vect)
if (do_timings) call psb_tic(poly_mv)
call psb_spmm(-done,sm%pa,tz,done,r,desc_data,info,work=aux,trans=trans_)
if (do_timings) call psb_toc(poly_mv)
end do
if (do_timings) call psb_tic(poly_sv)
call sm%sv%apply(done,r,dzero,ty,desc_data,trans_,aux,wv(5:),info,init='Z') ! ty = M^{-1} r
if (do_timings) call psb_toc(poly_sv)
cz = (2*sm%pdegree*done-3)/(2*sm%pdegree*done+done)
cr = (8*sm%pdegree*done-4)/((2*sm%pdegree*done+done)*sm%rho_ba)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz(cr,cz,done,done,ty,tz,tx,desc_data,info)
if (do_timings) call psb_toc(poly_vect)
end block
if (do_timings) call psb_toc(poly_1)
case(amg_poly_lottes_beta_)
if (do_timings) call psb_tic(poly_2)
block
real(psb_dpk_) :: cz, cr
! b == x
! x == tx
!
if (allocated(sm%poly_beta)) then
if (size(sm%poly_beta) /= sm%pdegree) deallocate(sm%poly_beta)
end if
if (.not.allocated(sm%poly_beta)) then
call psb_realloc(sm%pdegree,sm%poly_beta,info)
sm%poly_beta(1:sm%pdegree) = amg_d_poly_beta_mat(1:sm%pdegree,sm%pdegree)
end if
do i=1, sm%pdegree-1
! B r_{k-1}
if (do_timings) call psb_tic(poly_sv)
call sm%sv%apply(done,r,dzero,ty,desc_data,trans_,aux,wv(5:),info,init='Z')
if (do_timings) call psb_toc(poly_sv)
cz = (2*i*done-3)/(2*i*done+done)
cr = (8*i*done-4)/((2*i*done+done)*sm%rho_ba)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz(cr,cz,sm%poly_beta(i),done,ty,tz,tx,desc_data,info)
if (do_timings) call psb_toc(poly_vect)
if (do_timings) call psb_tic(poly_mv)
call psb_spmm(-done,sm%pa,tz,done,r,desc_data,info,work=aux,trans=trans_)
if (do_timings) call psb_toc(poly_mv)
end do
call sm%sv%apply(done,r,dzero,ty,desc_data,trans_,aux,wv(5:),info,init='Z')
cz = (2*sm%pdegree*done-3)/(2*sm%pdegree*done+done)
cr = (8*sm%pdegree*done-4)/((2*sm%pdegree*done+done)*sm%rho_ba)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz(cr,cz,sm%poly_beta(sm%pdegree),done,ty,tz,tx,desc_data,info)
if (do_timings) call psb_toc(poly_vect)
end block
if (do_timings) call psb_toc(poly_2)
case(amg_poly_new_)
if (do_timings) call psb_tic(poly_3)
block
real(psb_dpk_) :: sigma, theta, delta, rho_old, rho
! b == x
! x == tx
!
theta = (done+sm%cf_a)/2
delta = (done-sm%cf_a)/2
sigma = theta/delta
rho_old = done/sigma
if (do_timings) call psb_tic(poly_sv)
call sm%sv%apply(done,r,dzero,ty,desc_data,trans_,aux,wv(5:),info,init='Z')
if (do_timings) call psb_toc(poly_sv)
call psb_geaxpby((done/sm%rho_ba),ty,dzero,r,desc_data,info)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz((done/theta),dzero,done,done,r,tz,tx,desc_data,info)
if (do_timings) call psb_toc(poly_vect)
! tz == d
do i=1, sm%pdegree-1
!
!
! r_{k-1} = r_k - (1/rho(BA)) B A d_k
if (do_timings) call psb_tic(poly_mv)
call psb_spmm(done,sm%pa,tz,dzero,ty,desc_data,info,work=aux,trans=trans_)
if (do_timings) call psb_toc(poly_mv)
if (do_timings) call psb_tic(poly_sv)
call sm%sv%apply(-(done/sm%rho_ba),ty,done,r,desc_data,trans_,aux,wv(5:),info,init='Z')
if (do_timings) call psb_toc(poly_sv)
!
! d_{k+1} = (rho rho_old) d_k + 2(rho/delta) r_{k+1}
rho = done/(2*sigma - rho_old)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz((2*rho/delta),(rho*rho_old),done,done,r,tz,tx,desc_data,info)
if (do_timings) call psb_toc(poly_vect)
rho_old = rho
end do
end block
if (do_timings) call psb_toc(poly_3)
case default
info=psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='wrong polynomial variant')
goto 9999
end select
if (info == psb_success_) call psb_geaxpby(alpha,tx,beta,y,desc_data,info)
if (info /= psb_success_) then
info=psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='polynomial smoother')
goto 9999
end if
end associate
if (.not.(4*n_col <= size(work))) then
deallocate(aux)
endif
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_d_poly_smoother_apply_vect
@@ -0,0 +1,179 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_d_poly_smoother_bld(a,desc_a,sm,info,amold,vmold,imold)
use psb_base_mod
use amg_d_diag_solver
use amg_d_l1_diag_solver
use amg_d_poly_coeff_mod
use amg_d_poly_smoother, amg_protect_name => amg_d_poly_smoother_bld
Implicit None
! Arguments
type(psb_dspmat_type), intent(in), target :: a
Type(psb_desc_type), Intent(inout) :: desc_a
class(amg_d_poly_smoother_type), intent(inout) :: sm
integer(psb_ipk_), intent(out) :: info
class(psb_d_base_sparse_mat), intent(in), optional :: amold
class(psb_d_base_vect_type), intent(in), optional :: vmold
class(psb_i_base_vect_type), intent(in), optional :: imold
! Local variables
type(psb_dspmat_type) :: tmpa
integer(psb_ipk_) :: n_row,n_col, nrow_a, nztota, nzeros
type(psb_ctxt_type) :: ctxt
real(psb_dpk_), allocatable :: da(:), dsv(:)
integer(psb_ipk_) :: np, me, i, err_act, debug_unit, debug_level
character(len=20) :: name='d_poly_smoother_bld', ch_err
info=psb_success_
call psb_erractionsave(err_act)
debug_unit = psb_get_debug_unit()
debug_level = psb_get_debug_level()
ctxt = desc_a%get_context()
call psb_info(ctxt, me, np)
if (debug_level >= psb_debug_outer_) &
& write(debug_unit,*) me,' ',trim(name),' start'
n_row = desc_a%get_local_rows()
n_col = desc_a%get_local_cols()
nrow_a = a%get_nrows()
nztota = a%get_nzeros()
select case(sm%variant)
case(amg_poly_lottes_)
! do nothing
case(amg_poly_lottes_beta_)
if ((1<=sm%pdegree).and.(sm%pdegree<=30)) then
call psb_realloc(sm%pdegree,sm%poly_beta,info)
sm%poly_beta(1:sm%pdegree) = amg_d_poly_beta_mat(1:sm%pdegree,sm%pdegree)
else
info = psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='invalid sm%degree for poly_beta')
goto 9999
end if
case(amg_poly_new_)
if ((1<=sm%pdegree).and.(sm%pdegree<=30)) then
!Ok
sm%cf_a = amg_d_poly_a_vect(sm%pdegree)
else
info = psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='invalid sm%degree for poly_a')
goto 9999
end if
case default
info = psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='invalid sm%variant')
goto 9999
end select
sm%pa => a
if (.not.allocated(sm%sv)) then
info = psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='unallocated sm%sv')
goto 9999
end if
call sm%sv%build(a,desc_a,info,amold=amold,vmold=vmold)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,&
& a_err='sv%build')
goto 9999
end if
!!$ if (.false.) then
!!$ select type(ssv => sm%sv)
!!$ class is(amg_d_l1_diag_solver_type)
!!$ da = a%arwsum(info)
!!$ dsv = ssv%dv%get_vect()
!!$ sm%rho_ba = maxval(da(1:n_row)*dsv(1:n_row))
!!$ class default
!!$ write(0,*) 'PolySmoother BUILD: only L1-Jacobi/L1-DIAG for now ',ssv%get_fmt()
!!$ sm%rho_ba = done
!!$ end select
!!$ else
if (sm%rho_ba <= dzero) then
select case(sm%rho_estimate)
case(amg_poly_rho_est_power_)
block
type(psb_d_vect_type) :: tq, tt, tz,wv(2)
real(psb_dpk_) :: znrm, lambda
real(psb_dpk_),allocatable :: work(:)
integer(psb_ipk_) :: i, n_cols
n_cols = desc_a%get_local_cols()
allocate(work(4*n_cols))
call psb_geasb(tz,desc_a,info,mold=vmold,scratch=.true.)
call psb_geasb(tt,desc_a,info,mold=vmold,scratch=.true.)
call psb_geasb(wv(1),desc_a,info,mold=vmold,scratch=.true.)
call psb_geasb(wv(2),desc_a,info,mold=vmold,scratch=.true.)
call psb_geall(tq,desc_a,info)
call tq%set(done)
call psb_geasb(tq,desc_a,info,mold=vmold)
call psb_spmm(done,a,tq,dzero,tt,desc_a,info) !
call sm%sv%apply_v(done,tt,dzero,tz,desc_a,'NoTrans',work,wv,info) ! z_{k+1} = BA q_k
do i=1,sm%rho_estimate_iterations
znrm = psb_genrm2(tz,desc_a,info) ! znrm = |z_k|_2
call psb_geaxpby((done/znrm),tz,dzero,tq,desc_a,info) ! q_k = z_k/znrm
call psb_spmm(done,a,tq,dzero,tt,desc_a,info) ! t_{k+1} = BA q_k
call sm%sv%apply_v(done,tt,dzero,tz,desc_a,'NoTrans',work,wv,info) ! z_{k+1} = B t_{k+1}
lambda = psb_gedot(tq,tz,desc_a,info) ! lambda = q_k^T z_{k+1} = q_k^T BA q_k
!write(0,*) 'BLD: lambda estimate ',i,lambda
end do
sm%rho_ba = lambda
end block
case default
write(0,*) ' Unknown algorithm for RHO(BA) estimate, defaulting to a value of 1.0 '
sm%rho_ba = done
end select
end if
if (debug_level >= psb_debug_outer_) &
& write(debug_unit,*) me,' ',trim(name),' end'
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_d_poly_smoother_bld
@@ -0,0 +1,70 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_d_poly_smoother_clear_data(sm,info)
use psb_base_mod
use amg_d_poly_smoother, amg_protect_name => amg_d_poly_smoother_clear_data
Implicit None
! Arguments
class(amg_d_poly_smoother_type), intent(inout) :: sm
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_) :: err_act
character(len=20) :: name='amg_d_poly_smoother_clear_data'
call psb_erractionsave(err_act)
info = 0
sm%pdegree = 0
if (allocated(sm%poly_beta)) deallocate(sm%poly_beta)
sm%pa => null()
if ((info==0).and.allocated(sm%sv)) then
call sm%sv%clear_data(info)
end if
if (info /= 0) then
info = psb_err_internal_error_
call psb_errpush(info,name)
goto 9999
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_d_poly_smoother_clear_data
@@ -0,0 +1,90 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_d_poly_smoother_clone(sm,smout,info)
use psb_base_mod
use amg_d_poly_smoother, amg_protect_name => amg_d_poly_smoother_clone
Implicit None
! Arguments
class(amg_d_poly_smoother_type), intent(inout) :: sm
class(amg_d_base_smoother_type), allocatable, intent(inout) :: smout
integer(psb_ipk_), intent(out) :: info
! Local variables
integer(psb_ipk_) :: err_act
info=psb_success_
call psb_erractionsave(err_act)
if (allocated(smout)) then
call smout%free(info)
if (info == psb_success_) deallocate(smout, stat=info)
end if
if (info == psb_success_) &
& allocate(amg_d_poly_smoother_type :: smout, stat=info)
if (info /= 0) then
info = psb_err_alloc_dealloc_
goto 9999
end if
select type(smo => smout)
type is (amg_d_poly_smoother_type)
smo%pdegree = sm%pdegree
smo%rho_ba = sm%rho_ba
smo%poly_beta = sm%poly_beta
smo%pa => sm%pa
if ((info==psb_success_).and.(allocated(sm%sv))) then
allocate(smout%sv,mold=sm%sv,stat=info)
if (info == psb_success_) call sm%sv%clone(smo%sv,info)
end if
class default
info = psb_err_internal_error_
end select
if (info /= 0) goto 9999
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_d_poly_smoother_clone
@@ -0,0 +1,102 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! asd on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_d_poly_smoother_clone_settings(sm,smout,info)
use psb_base_mod
use amg_d_poly_smoother, amg_protect_name => amg_d_poly_smoother_clone_settings
Implicit None
! Arguments
class(amg_d_poly_smoother_type), intent(inout) :: sm
class(amg_d_base_smoother_type), intent(inout) :: smout
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_) :: err_act
character(len=20) :: name='d_poly_smoother_clone_settings'
call psb_erractionsave(err_act)
info = psb_success_
select type(smout)
class is(amg_d_poly_smoother_type)
smout%pa => null()
smout%pdegree = sm%pdegree
smout%variant = sm%variant
smout%cf_a = sm%cf_a
smout%rho_ba = sm%rho_ba
smout%rho_estimate = sm%rho_estimate
smout%rho_estimate_iterations = sm%rho_estimate_iterations
smout%poly_beta = sm%poly_beta
if (allocated(smout%sv)) then
if (.not.same_type_as(sm%sv,smout%sv)) then
call smout%sv%free(info)
if (info == 0) deallocate(smout%sv,stat=info)
end if
end if
if (info /= 0) then
info = psb_err_internal_error_
else
if (allocated(smout%sv)) then
if (same_type_as(sm%sv,smout%sv)) then
call sm%sv%clone_settings(smout%sv,info)
else
info = psb_err_internal_error_
end if
else
allocate(smout%sv,mold=sm%sv,stat=info)
if (info == 0) call sm%sv%clone_settings(smout%sv,info)
if (info /= 0) info = psb_err_internal_error_
end if
end if
class default
info = psb_err_internal_error_
end select
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_d_poly_smoother_clone_settings
@@ -0,0 +1,77 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_d_poly_smoother_cnv(sm,info,amold,vmold,imold)
use psb_base_mod
use amg_d_diag_solver
use amg_d_poly_smoother, amg_protect_name => amg_d_poly_smoother_cnv
Implicit None
! Arguments
class(amg_d_poly_smoother_type), intent(inout) :: sm
integer(psb_ipk_), intent(out) :: info
class(psb_d_base_sparse_mat), intent(in), optional :: amold
class(psb_d_base_vect_type), intent(in), optional :: vmold
class(psb_i_base_vect_type), intent(in), optional :: imold
! Local variables
integer(psb_ipk_) :: i, err_act, debug_unit, debug_level
character(len=20) :: name='d_poly_smoother_cnv', ch_err
info=psb_success_
call psb_erractionsave(err_act)
debug_unit = psb_get_debug_unit()
debug_level = psb_get_debug_level()
if (allocated(sm%sv)) &
& call sm%sv%cnv(info,amold=amold,vmold=vmold,imold=imold)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,&
& a_err='solver cnv')
goto 9999
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_d_poly_smoother_cnv
@@ -0,0 +1,76 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_d_poly_smoother_csetc(sm,what,val,info,idx)
use psb_base_mod
use amg_d_poly_smoother, amg_protect_name => amg_d_poly_smoother_csetc
Implicit None
! Arguments
class(amg_d_poly_smoother_type), intent(inout) :: sm
character(len=*), intent(in) :: what
character(len=*), intent(in) :: val
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: idx
integer(psb_ipk_) :: err_act, ival
character(len=20) :: name='d_poly_smoother_csetc'
info = psb_success_
call psb_erractionsave(err_act)
select case(psb_toupper(trim(what)))
case('POLY_VARIANT')
call sm%set(what,amg_stringval(val),info,idx=idx)
case('POLY_RHO_ESTIMATE')
call sm%set(what,amg_stringval(val),info,idx=idx)
case default
call sm%amg_d_base_smoother_type%set(what,val,info,idx=idx)
end select
if (info /= psb_success_) then
info = psb_err_from_subroutine_
call psb_errpush(info, name)
goto 9999
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_d_poly_smoother_csetc
@@ -0,0 +1,92 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_d_poly_smoother_cseti(sm,what,val,info,idx)
use psb_base_mod
use amg_d_poly_smoother, amg_protect_nam => amg_d_poly_smoother_cseti
Implicit None
! Arguments
class(amg_d_poly_smoother_type), intent(inout) :: sm
character(len=*), intent(in) :: what
integer(psb_ipk_), intent(in) :: val
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: idx
integer(psb_ipk_) :: err_act
character(len=20) :: name='d_poly_smoother_cseti'
info = psb_success_
call psb_erractionsave(err_act)
select case(psb_toupper(what))
case('POLY_DEGREE')
sm%pdegree = val
case('POLY_VARIANT')
select case(val)
case(amg_poly_lottes_,amg_poly_lottes_beta_,amg_poly_new_)
sm%variant = val
case default
write(0,*) 'Invalid choice for POLY_VARIANT, defaulting to amg_poly_lottes_',val
sm%variant = amg_poly_lottes_
end select
case('POLY_RHO_ESTIMATE')
select case(val)
case (amg_poly_rho_est_power_)
sm%rho_estimate = val
case default
write(0,*) 'Invalid choice for POLY_RHO_ESTIMATE, defaulting to amg_poly_rho_power'
sm%variant = amg_poly_rho_est_power_
end select
case('POLY_RHO_ESTIMATE_ITERATIONS')
if (val>0) then
sm%rho_estimate_iterations = val
else
write(0,*) 'Invalid choice for POLY_RHO_ESTIMATE_ITERATIONS, defaulting to 20'
sm%variant = 20
end if
case default
call sm%amg_d_base_smoother_type%set(what,val,info,idx=idx)
end select
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_d_poly_smoother_cseti
@@ -0,0 +1,74 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_d_poly_smoother_csetr(sm,what,val,info,idx)
use psb_base_mod
use amg_d_poly_smoother, amg_protect_nam => amg_d_poly_smoother_csetr
Implicit None
! Arguments
class(amg_d_poly_smoother_type), intent(inout) :: sm
character(len=*), intent(in) :: what
real(psb_dpk_), intent(in) :: val
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: idx
integer(psb_ipk_) :: err_act
character(len=20) :: name='d_poly_smoother_csetr'
info = psb_success_
call psb_erractionsave(err_act)
select case(psb_toupper(what))
case('POLY_RHO_BA')
if ((dzero<val).and.(val<=done)) then
sm%rho_ba = val
else
write(0,*) 'Invalid choice for POLY_RHO_BA, defaulting to compute estimate'
sm%rho_ba = -done
end if
case default
call sm%amg_d_base_smoother_type%set(what,val,info,idx=idx)
end select
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_d_poly_smoother_csetr
@@ -0,0 +1,108 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_d_poly_smoother_descr(sm,info,iout,coarse,prefix)
use psb_base_mod
use amg_d_diag_solver
use amg_d_poly_smoother, amg_protect_name => amg_d_poly_smoother_descr
Implicit None
! Arguments
class(amg_d_poly_smoother_type), intent(in) :: sm
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: iout
logical, intent(in), optional :: coarse
character(len=*), intent(in), optional :: prefix
! Local variables
integer(psb_ipk_) :: err_act
character(len=20), parameter :: name='amg_d_poly_smoother_descr'
integer(psb_ipk_) :: iout_
logical :: coarse_
character(1024) :: prefix_
call psb_erractionsave(err_act)
info = psb_success_
if (present(coarse)) then
coarse_ = coarse
else
coarse_ = .false.
end if
if (present(iout)) then
iout_ = iout
else
iout_ = psb_out_unit
endif
if (present(prefix)) then
prefix_ = prefix
else
prefix_ = ""
end if
write(iout_,*) trim(prefix_), ' Polynomial smoother '
select case(sm%variant)
case(amg_poly_lottes_)
write(iout_,*) trim(prefix_), ' variant: ','POLY_LOTTES'
write(iout_,*) trim(prefix_), ' Degree: ',sm%pdegree
write(iout_,*) trim(prefix_), ' rho_ba: ',sm%rho_ba
case(amg_poly_lottes_beta_)
write(iout_,*) trim(prefix_), ' variant: ','POLY_LOTTES_BETA'
write(iout_,*) trim(prefix_), ' Degree: ',sm%pdegree
write(iout_,*) trim(prefix_), ' rho_ba: ',sm%rho_ba
if (allocated(sm%poly_beta)) write(iout_,*) trim(prefix_), ' Coefficients: ',sm%poly_beta(1:sm%pdegree)
case(amg_poly_new_)
write(iout_,*) trim(prefix_), ' variant: ','POLY_NEW'
write(iout_,*) trim(prefix_), ' Degree: ',sm%pdegree
write(iout_,*) trim(prefix_), ' rho_ba: ',sm%rho_ba
write(iout_,*) trim(prefix_), ' Coefficient: ',sm%cf_a
case default
write(iout_,*) trim(prefix_), ' variant: ','UNKNOWN???'
end select
if (allocated(sm%sv)) then
write(iout_,*) trim(prefix_), ' Local solver details:'
call sm%sv%descr(info,iout_,coarse=coarse,prefix=prefix)
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_d_poly_smoother_descr
@@ -0,0 +1,90 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_d_poly_smoother_dmp(sm,desc,level,info,prefix,head,smoother,solver,global_num)
use psb_base_mod
use amg_d_poly_smoother, amg_protect_nam => amg_d_poly_smoother_dmp
implicit none
class(amg_d_poly_smoother_type), intent(in) :: sm
type(psb_desc_type), intent(in) :: desc
integer(psb_ipk_), intent(in) :: level
integer(psb_ipk_), intent(out) :: info
character(len=*), intent(in), optional :: prefix, head
logical, optional, intent(in) :: smoother, solver, global_num
integer(psb_ipk_) :: i, j, il1, iln, lname, lev
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: iam, np
character(len=80) :: prefix_
character(len=120) :: fname ! len should be at least 20 more than
integer(psb_lpk_), allocatable :: iv(:)
logical :: smoother_, global_num_
! len of prefix_
info = 0
if (present(prefix)) then
prefix_ = trim(prefix(1:min(len(prefix),len(prefix_))))
else
prefix_ = "dump_smth_d"
end if
ctxt = desc%get_context()
call psb_info(ctxt,iam,np)
if (present(smoother)) then
smoother_ = smoother
else
smoother_ = .false.
end if
if (present(global_num)) then
global_num_ = global_num
else
global_num_ = .false.
end if
lname = len_trim(prefix_)
fname = trim(prefix_)
write(fname(lname+1:lname+5),'(a,i3.3)') '_poly',iam
lname = lname + 8
! to be completed
! At base level do nothing for the smoother
if (allocated(sm%sv)) &
& call sm%sv%dump(desc,level,info,solver=solver,prefix=prefix,global_num=global_num)
end subroutine amg_d_poly_smoother_dmp
@@ -175,7 +175,7 @@ subroutine amg_s_jac_smoother_apply_vect(alpha,sm,x,beta,y,desc_data,trans,&
if (info /= psb_success_) exit
if ( sm%checkres.and.(mod(i,sm%checkiter) == 0) ) then
call psb_geaxpby(sone,x,szero,r,r,desc_data,info)
call psb_geaxpby(sone,x,szero,r,desc_data,info)
call psb_spmm(-sone,sm%pa,ty,sone,r,desc_data,info)
res = psb_genrm2(r,desc_data,info)
if( sm%printres ) then
@@ -0,0 +1,281 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_s_poly_smoother_apply_vect(alpha,sm,x,beta,y,desc_data,trans,&
& sweeps,work,wv,info,init,initu)
use psb_base_mod
use amg_s_diag_solver
use psb_base_krylov_conv_mod, only : log_conv
use amg_s_poly_smoother, amg_protect_name => amg_s_poly_smoother_apply_vect
implicit none
type(psb_desc_type), intent(in) :: desc_data
class(amg_s_poly_smoother_type), intent(inout) :: sm
type(psb_s_vect_type),intent(inout) :: x
type(psb_s_vect_type),intent(inout) :: y
real(psb_spk_),intent(in) :: alpha,beta
character(len=1),intent(in) :: trans
integer(psb_ipk_), intent(in) :: sweeps! this is ignored here, the polynomial degree dictates the value
real(psb_spk_),target, intent(inout) :: work(:)
type(psb_s_vect_type),intent(inout) :: wv(:)
integer(psb_ipk_), intent(out) :: info
character, intent(in), optional :: init
type(psb_s_vect_type),intent(inout), optional :: initu
! Timers
logical, parameter :: do_timings=.true.
integer(psb_ipk_), save :: poly_1=-1, poly_2=-1, poly_3=-1
integer(psb_ipk_), save :: poly_mv=-1, poly_sv=-1, poly_vect=-1
!
integer(psb_ipk_) :: n_row,n_col
type(psb_s_vect_type) :: tx, ty, tz, r
real(psb_spk_), pointer :: aux(:)
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np, me, i, err_act
character :: trans_, init_
real(psb_spk_) :: res, resdenum
character(len=20) :: name='d_poly_smoother_apply_v'
call psb_erractionsave(err_act)
info = psb_success_
ctxt = desc_data%get_context()
call psb_info(ctxt,me,np)
if (present(init)) then
init_ = psb_toupper(init)
else
init_='Z'
end if
trans_ = psb_toupper(trans)
select case(trans_)
case('N')
case('T','C')
case default
call psb_errpush(psb_err_iarg_invalid_i_,name)
goto 9999
end select
if (.not.allocated(sm%sv)) then
info = 1121
call psb_errpush(info,name)
goto 9999
end if
if ((do_timings).and.(poly_1==-1)) &
& poly_1 = psb_get_timer_idx("POLY: Chebychev4")
if ((do_timings).and.(poly_2==-1)) &
& poly_2 = psb_get_timer_idx("POLY: OptChebychev4")
if ((do_timings).and.(poly_3==-1)) &
& poly_3 = psb_get_timer_idx("POLY: OptChebychev1")
if ((do_timings).and.(poly_mv==-1)) &
& poly_mv = psb_get_timer_idx("POLY: spMV")
if ((do_timings).and.(poly_vect==-1)) &
& poly_vect = psb_get_timer_idx("POLY: Vectors")
if ((do_timings).and.(poly_sv==-1)) &
& poly_sv = psb_get_timer_idx("POLY: solver")
n_row = desc_data%get_local_rows()
n_col = desc_data%get_local_cols()
if (4*n_col <= size(work)) then
aux => work(:)
else
allocate(aux(4*n_col),stat=info)
if (info /= psb_success_) then
info=psb_err_alloc_request_
call psb_errpush(info,name,&
& i_err=(/4*n_col,izero,izero,izero,izero/),&
& a_err='real(psb_spk_)')
goto 9999
end if
endif
if (size(wv) < 4) then
info = psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='invalid wv size in smoother_apply')
goto 9999
end if
associate(tx => wv(1), ty => wv(2), tz => wv(3), r => wv(4))
call psb_geaxpby(sone,x,szero,r,desc_data,info)
call tx%zero()
call ty%zero()
call tz%zero()
select case(sm%variant)
case(amg_poly_lottes_)
if (do_timings) call psb_tic(poly_1)
block
real(psb_spk_) :: cz, cr
! b == x
! x == tx
!
do i=1, sm%pdegree-1
! B r_{k-1}
if (do_timings) call psb_tic(poly_sv)
call sm%sv%apply(sone,r,szero,ty,desc_data,trans_,aux,wv(5:),info,init='Z') ! ty = M^{-1} r
if (do_timings) call psb_toc(poly_sv)
cz = (2*i*sone-3)/(2*i*sone+sone)
cr = (8*i*sone-4)/((2*i*sone+sone)*sm%rho_ba)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz(cr,cz,sone,sone,ty,tz,tx,desc_data,info) ! zk = cz * zk-1 + cr * rk-1
if (do_timings) call psb_toc(poly_vect)
if (do_timings) call psb_tic(poly_mv)
call psb_spmm(-sone,sm%pa,tz,sone,r,desc_data,info,work=aux,trans=trans_)
if (do_timings) call psb_toc(poly_mv)
end do
if (do_timings) call psb_tic(poly_sv)
call sm%sv%apply(sone,r,szero,ty,desc_data,trans_,aux,wv(5:),info,init='Z') ! ty = M^{-1} r
if (do_timings) call psb_toc(poly_sv)
cz = (2*sm%pdegree*sone-3)/(2*sm%pdegree*sone+sone)
cr = (8*sm%pdegree*sone-4)/((2*sm%pdegree*sone+sone)*sm%rho_ba)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz(cr,cz,sone,sone,ty,tz,tx,desc_data,info)
if (do_timings) call psb_toc(poly_vect)
end block
if (do_timings) call psb_toc(poly_1)
case(amg_poly_lottes_beta_)
if (do_timings) call psb_tic(poly_2)
block
real(psb_spk_) :: cz, cr
! b == x
! x == tx
!
if (allocated(sm%poly_beta)) then
if (size(sm%poly_beta) /= sm%pdegree) deallocate(sm%poly_beta)
end if
if (.not.allocated(sm%poly_beta)) then
call psb_realloc(sm%pdegree,sm%poly_beta,info)
sm%poly_beta(1:sm%pdegree) = amg_d_poly_beta_mat(1:sm%pdegree,sm%pdegree)
end if
do i=1, sm%pdegree-1
! B r_{k-1}
if (do_timings) call psb_tic(poly_sv)
call sm%sv%apply(sone,r,szero,ty,desc_data,trans_,aux,wv(5:),info,init='Z')
if (do_timings) call psb_toc(poly_sv)
cz = (2*i*sone-3)/(2*i*sone+sone)
cr = (8*i*sone-4)/((2*i*sone+sone)*sm%rho_ba)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz(cr,cz,sm%poly_beta(i),sone,ty,tz,tx,desc_data,info)
if (do_timings) call psb_toc(poly_vect)
if (do_timings) call psb_tic(poly_mv)
call psb_spmm(-sone,sm%pa,tz,sone,r,desc_data,info,work=aux,trans=trans_)
if (do_timings) call psb_toc(poly_mv)
end do
call sm%sv%apply(sone,r,szero,ty,desc_data,trans_,aux,wv(5:),info,init='Z')
cz = (2*sm%pdegree*sone-3)/(2*sm%pdegree*sone+sone)
cr = (8*sm%pdegree*sone-4)/((2*sm%pdegree*sone+sone)*sm%rho_ba)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz(cr,cz,sm%poly_beta(sm%pdegree),sone,ty,tz,tx,desc_data,info)
if (do_timings) call psb_toc(poly_vect)
end block
if (do_timings) call psb_toc(poly_2)
case(amg_poly_new_)
if (do_timings) call psb_tic(poly_3)
block
real(psb_spk_) :: sigma, theta, delta, rho_old, rho
! b == x
! x == tx
!
theta = (sone+sm%cf_a)/2
delta = (sone-sm%cf_a)/2
sigma = theta/delta
rho_old = sone/sigma
if (do_timings) call psb_tic(poly_sv)
call sm%sv%apply(sone,r,szero,ty,desc_data,trans_,aux,wv(5:),info,init='Z')
if (do_timings) call psb_toc(poly_sv)
call psb_geaxpby((sone/sm%rho_ba),ty,szero,r,desc_data,info)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz((sone/theta),szero,sone,sone,r,tz,tx,desc_data,info)
if (do_timings) call psb_toc(poly_vect)
! tz == d
do i=1, sm%pdegree-1
!
!
! r_{k-1} = r_k - (1/rho(BA)) B A d_k
if (do_timings) call psb_tic(poly_mv)
call psb_spmm(sone,sm%pa,tz,szero,ty,desc_data,info,work=aux,trans=trans_)
if (do_timings) call psb_toc(poly_mv)
if (do_timings) call psb_tic(poly_sv)
call sm%sv%apply(-(sone/sm%rho_ba),ty,sone,r,desc_data,trans_,aux,wv(5:),info,init='Z')
if (do_timings) call psb_toc(poly_sv)
!
! d_{k+1} = (rho rho_old) d_k + 2(rho/delta) r_{k+1}
rho = sone/(2*sigma - rho_old)
if (do_timings) call psb_tic(poly_vect)
call psb_abgdxyz((2*rho/delta),(rho*rho_old),sone,sone,r,tz,tx,desc_data,info)
if (do_timings) call psb_toc(poly_vect)
rho_old = rho
end do
end block
if (do_timings) call psb_toc(poly_3)
case default
info=psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='wrong polynomial variant')
goto 9999
end select
if (info == psb_success_) call psb_geaxpby(alpha,tx,beta,y,desc_data,info)
if (info /= psb_success_) then
info=psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='polynomial smoother')
goto 9999
end if
end associate
if (.not.(4*n_col <= size(work))) then
deallocate(aux)
endif
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_s_poly_smoother_apply_vect
@@ -0,0 +1,179 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_s_poly_smoother_bld(a,desc_a,sm,info,amold,vmold,imold)
use psb_base_mod
use amg_s_diag_solver
use amg_s_l1_diag_solver
use amg_d_poly_coeff_mod
use amg_s_poly_smoother, amg_protect_name => amg_s_poly_smoother_bld
Implicit None
! Arguments
type(psb_sspmat_type), intent(in), target :: a
Type(psb_desc_type), Intent(inout) :: desc_a
class(amg_s_poly_smoother_type), intent(inout) :: sm
integer(psb_ipk_), intent(out) :: info
class(psb_s_base_sparse_mat), intent(in), optional :: amold
class(psb_s_base_vect_type), intent(in), optional :: vmold
class(psb_i_base_vect_type), intent(in), optional :: imold
! Local variables
type(psb_sspmat_type) :: tmpa
integer(psb_ipk_) :: n_row,n_col, nrow_a, nztota, nzeros
type(psb_ctxt_type) :: ctxt
real(psb_spk_), allocatable :: da(:), dsv(:)
integer(psb_ipk_) :: np, me, i, err_act, debug_unit, debug_level
character(len=20) :: name='d_poly_smoother_bld', ch_err
info=psb_success_
call psb_erractionsave(err_act)
debug_unit = psb_get_debug_unit()
debug_level = psb_get_debug_level()
ctxt = desc_a%get_context()
call psb_info(ctxt, me, np)
if (debug_level >= psb_debug_outer_) &
& write(debug_unit,*) me,' ',trim(name),' start'
n_row = desc_a%get_local_rows()
n_col = desc_a%get_local_cols()
nrow_a = a%get_nrows()
nztota = a%get_nzeros()
select case(sm%variant)
case(amg_poly_lottes_)
! do nothing
case(amg_poly_lottes_beta_)
if ((1<=sm%pdegree).and.(sm%pdegree<=30)) then
call psb_realloc(sm%pdegree,sm%poly_beta,info)
sm%poly_beta(1:sm%pdegree) = amg_d_poly_beta_mat(1:sm%pdegree,sm%pdegree)
else
info = psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='invalid sm%degree for poly_beta')
goto 9999
end if
case(amg_poly_new_)
if ((1<=sm%pdegree).and.(sm%pdegree<=30)) then
!Ok
sm%cf_a = amg_d_poly_a_vect(sm%pdegree)
else
info = psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='invalid sm%degree for poly_a')
goto 9999
end if
case default
info = psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='invalid sm%variant')
goto 9999
end select
sm%pa => a
if (.not.allocated(sm%sv)) then
info = psb_err_internal_error_
call psb_errpush(info,name,&
& a_err='unallocated sm%sv')
goto 9999
end if
call sm%sv%build(a,desc_a,info,amold=amold,vmold=vmold)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,&
& a_err='sv%build')
goto 9999
end if
!!$ if (.false.) then
!!$ select type(ssv => sm%sv)
!!$ class is(amg_s_l1_diag_solver_type)
!!$ da = a%arwsum(info)
!!$ dsv = ssv%dv%get_vect()
!!$ sm%rho_ba = maxval(da(1:n_row)*dsv(1:n_row))
!!$ class default
!!$ write(0,*) 'PolySmoother BUILD: only L1-Jacobi/L1-DIAG for now ',ssv%get_fmt()
!!$ sm%rho_ba = sone
!!$ end select
!!$ else
if (sm%rho_ba <= szero) then
select case(sm%rho_estimate)
case(amg_poly_rho_est_power_)
block
type(psb_s_vect_type) :: tq, tt, tz,wv(2)
real(psb_spk_) :: znrm, lambda
real(psb_spk_),allocatable :: work(:)
integer(psb_ipk_) :: i, n_cols
n_cols = desc_a%get_local_cols()
allocate(work(4*n_cols))
call psb_geasb(tz,desc_a,info,mold=vmold,scratch=.true.)
call psb_geasb(tt,desc_a,info,mold=vmold,scratch=.true.)
call psb_geasb(wv(1),desc_a,info,mold=vmold,scratch=.true.)
call psb_geasb(wv(2),desc_a,info,mold=vmold,scratch=.true.)
call psb_geall(tq,desc_a,info)
call tq%set(sone)
call psb_geasb(tq,desc_a,info,mold=vmold)
call psb_spmm(sone,a,tq,szero,tt,desc_a,info) !
call sm%sv%apply_v(sone,tt,szero,tz,desc_a,'NoTrans',work,wv,info) ! z_{k+1} = BA q_k
do i=1,sm%rho_estimate_iterations
znrm = psb_genrm2(tz,desc_a,info) ! znrm = |z_k|_2
call psb_geaxpby((sone/znrm),tz,szero,tq,desc_a,info) ! q_k = z_k/znrm
call psb_spmm(sone,a,tq,szero,tt,desc_a,info) ! t_{k+1} = BA q_k
call sm%sv%apply_v(sone,tt,szero,tz,desc_a,'NoTrans',work,wv,info) ! z_{k+1} = B t_{k+1}
lambda = psb_gedot(tq,tz,desc_a,info) ! lambda = q_k^T z_{k+1} = q_k^T BA q_k
!write(0,*) 'BLD: lambda estimate ',i,lambda
end do
sm%rho_ba = lambda
end block
case default
write(0,*) ' Unknown algorithm for RHO(BA) estimate, defaulting to a value of 1.0 '
sm%rho_ba = sone
end select
end if
if (debug_level >= psb_debug_outer_) &
& write(debug_unit,*) me,' ',trim(name),' end'
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_s_poly_smoother_bld
@@ -0,0 +1,70 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_s_poly_smoother_clear_data(sm,info)
use psb_base_mod
use amg_s_poly_smoother, amg_protect_name => amg_s_poly_smoother_clear_data
Implicit None
! Arguments
class(amg_s_poly_smoother_type), intent(inout) :: sm
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_) :: err_act
character(len=20) :: name='amg_s_poly_smoother_clear_data'
call psb_erractionsave(err_act)
info = 0
sm%pdegree = 0
if (allocated(sm%poly_beta)) deallocate(sm%poly_beta)
sm%pa => null()
if ((info==0).and.allocated(sm%sv)) then
call sm%sv%clear_data(info)
end if
if (info /= 0) then
info = psb_err_internal_error_
call psb_errpush(info,name)
goto 9999
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_s_poly_smoother_clear_data
@@ -0,0 +1,90 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_s_poly_smoother_clone(sm,smout,info)
use psb_base_mod
use amg_s_poly_smoother, amg_protect_name => amg_s_poly_smoother_clone
Implicit None
! Arguments
class(amg_s_poly_smoother_type), intent(inout) :: sm
class(amg_s_base_smoother_type), allocatable, intent(inout) :: smout
integer(psb_ipk_), intent(out) :: info
! Local variables
integer(psb_ipk_) :: err_act
info=psb_success_
call psb_erractionsave(err_act)
if (allocated(smout)) then
call smout%free(info)
if (info == psb_success_) deallocate(smout, stat=info)
end if
if (info == psb_success_) &
& allocate(amg_s_poly_smoother_type :: smout, stat=info)
if (info /= 0) then
info = psb_err_alloc_dealloc_
goto 9999
end if
select type(smo => smout)
type is (amg_s_poly_smoother_type)
smo%pdegree = sm%pdegree
smo%rho_ba = sm%rho_ba
smo%poly_beta = sm%poly_beta
smo%pa => sm%pa
if ((info==psb_success_).and.(allocated(sm%sv))) then
allocate(smout%sv,mold=sm%sv,stat=info)
if (info == psb_success_) call sm%sv%clone(smo%sv,info)
end if
class default
info = psb_err_internal_error_
end select
if (info /= 0) goto 9999
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_s_poly_smoother_clone
@@ -0,0 +1,102 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! asd on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_s_poly_smoother_clone_settings(sm,smout,info)
use psb_base_mod
use amg_s_poly_smoother, amg_protect_name => amg_s_poly_smoother_clone_settings
Implicit None
! Arguments
class(amg_s_poly_smoother_type), intent(inout) :: sm
class(amg_s_base_smoother_type), intent(inout) :: smout
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_) :: err_act
character(len=20) :: name='d_poly_smoother_clone_settings'
call psb_erractionsave(err_act)
info = psb_success_
select type(smout)
class is(amg_s_poly_smoother_type)
smout%pa => null()
smout%pdegree = sm%pdegree
smout%variant = sm%variant
smout%cf_a = sm%cf_a
smout%rho_ba = sm%rho_ba
smout%rho_estimate = sm%rho_estimate
smout%rho_estimate_iterations = sm%rho_estimate_iterations
smout%poly_beta = sm%poly_beta
if (allocated(smout%sv)) then
if (.not.same_type_as(sm%sv,smout%sv)) then
call smout%sv%free(info)
if (info == 0) deallocate(smout%sv,stat=info)
end if
end if
if (info /= 0) then
info = psb_err_internal_error_
else
if (allocated(smout%sv)) then
if (same_type_as(sm%sv,smout%sv)) then
call sm%sv%clone_settings(smout%sv,info)
else
info = psb_err_internal_error_
end if
else
allocate(smout%sv,mold=sm%sv,stat=info)
if (info == 0) call sm%sv%clone_settings(smout%sv,info)
if (info /= 0) info = psb_err_internal_error_
end if
end if
class default
info = psb_err_internal_error_
end select
if (info /= 0) then
call psb_errpush(info,name)
goto 9999
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_s_poly_smoother_clone_settings
@@ -0,0 +1,77 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_s_poly_smoother_cnv(sm,info,amold,vmold,imold)
use psb_base_mod
use amg_s_diag_solver
use amg_s_poly_smoother, amg_protect_name => amg_s_poly_smoother_cnv
Implicit None
! Arguments
class(amg_s_poly_smoother_type), intent(inout) :: sm
integer(psb_ipk_), intent(out) :: info
class(psb_s_base_sparse_mat), intent(in), optional :: amold
class(psb_s_base_vect_type), intent(in), optional :: vmold
class(psb_i_base_vect_type), intent(in), optional :: imold
! Local variables
integer(psb_ipk_) :: i, err_act, debug_unit, debug_level
character(len=20) :: name='d_poly_smoother_cnv', ch_err
info=psb_success_
call psb_erractionsave(err_act)
debug_unit = psb_get_debug_unit()
debug_level = psb_get_debug_level()
if (allocated(sm%sv)) &
& call sm%sv%cnv(info,amold=amold,vmold=vmold,imold=imold)
if (info /= psb_success_) then
call psb_errpush(psb_err_from_subroutine_,name,&
& a_err='solver cnv')
goto 9999
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_s_poly_smoother_cnv
@@ -0,0 +1,76 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_s_poly_smoother_csetc(sm,what,val,info,idx)
use psb_base_mod
use amg_s_poly_smoother, amg_protect_name => amg_s_poly_smoother_csetc
Implicit None
! Arguments
class(amg_s_poly_smoother_type), intent(inout) :: sm
character(len=*), intent(in) :: what
character(len=*), intent(in) :: val
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: idx
integer(psb_ipk_) :: err_act, ival
character(len=20) :: name='d_poly_smoother_csetc'
info = psb_success_
call psb_erractionsave(err_act)
select case(psb_toupper(trim(what)))
case('POLY_VARIANT')
call sm%set(what,amg_stringval(val),info,idx=idx)
case('POLY_RHO_ESTIMATE')
call sm%set(what,amg_stringval(val),info,idx=idx)
case default
call sm%amg_s_base_smoother_type%set(what,val,info,idx=idx)
end select
if (info /= psb_success_) then
info = psb_err_from_subroutine_
call psb_errpush(info, name)
goto 9999
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_s_poly_smoother_csetc
@@ -0,0 +1,92 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_s_poly_smoother_cseti(sm,what,val,info,idx)
use psb_base_mod
use amg_s_poly_smoother, amg_protect_nam => amg_s_poly_smoother_cseti
Implicit None
! Arguments
class(amg_s_poly_smoother_type), intent(inout) :: sm
character(len=*), intent(in) :: what
integer(psb_ipk_), intent(in) :: val
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: idx
integer(psb_ipk_) :: err_act
character(len=20) :: name='d_poly_smoother_cseti'
info = psb_success_
call psb_erractionsave(err_act)
select case(psb_toupper(what))
case('POLY_DEGREE')
sm%pdegree = val
case('POLY_VARIANT')
select case(val)
case(amg_poly_lottes_,amg_poly_lottes_beta_,amg_poly_new_)
sm%variant = val
case default
write(0,*) 'Invalid choice for POLY_VARIANT, defaulting to amg_poly_lottes_',val
sm%variant = amg_poly_lottes_
end select
case('POLY_RHO_ESTIMATE')
select case(val)
case (amg_poly_rho_est_power_)
sm%rho_estimate = val
case default
write(0,*) 'Invalid choice for POLY_RHO_ESTIMATE, defaulting to amg_poly_rho_power'
sm%variant = amg_poly_rho_est_power_
end select
case('POLY_RHO_ESTIMATE_ITERATIONS')
if (val>0) then
sm%rho_estimate_iterations = val
else
write(0,*) 'Invalid choice for POLY_RHO_ESTIMATE_ITERATIONS, defaulting to 20'
sm%variant = 20
end if
case default
call sm%amg_s_base_smoother_type%set(what,val,info,idx=idx)
end select
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_s_poly_smoother_cseti
@@ -0,0 +1,74 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Daniela di Serafino
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_s_poly_smoother_csetr(sm,what,val,info,idx)
use psb_base_mod
use amg_s_poly_smoother, amg_protect_nam => amg_s_poly_smoother_csetr
Implicit None
! Arguments
class(amg_s_poly_smoother_type), intent(inout) :: sm
character(len=*), intent(in) :: what
real(psb_spk_), intent(in) :: val
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: idx
integer(psb_ipk_) :: err_act
character(len=20) :: name='d_poly_smoother_csetr'
info = psb_success_
call psb_erractionsave(err_act)
select case(psb_toupper(what))
case('POLY_RHO_BA')
if ((szero<val).and.(val<=sone)) then
sm%rho_ba = val
else
write(0,*) 'Invalid choice for POLY_RHO_BA, defaulting to compute estimate'
sm%rho_ba = -sone
end if
case default
call sm%amg_s_base_smoother_type%set(what,val,info,idx=idx)
end select
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_s_poly_smoother_csetr
@@ -0,0 +1,108 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_s_poly_smoother_descr(sm,info,iout,coarse,prefix)
use psb_base_mod
use amg_s_diag_solver
use amg_s_poly_smoother, amg_protect_name => amg_s_poly_smoother_descr
Implicit None
! Arguments
class(amg_s_poly_smoother_type), intent(in) :: sm
integer(psb_ipk_), intent(out) :: info
integer(psb_ipk_), intent(in), optional :: iout
logical, intent(in), optional :: coarse
character(len=*), intent(in), optional :: prefix
! Local variables
integer(psb_ipk_) :: err_act
character(len=20), parameter :: name='amg_s_poly_smoother_descr'
integer(psb_ipk_) :: iout_
logical :: coarse_
character(1024) :: prefix_
call psb_erractionsave(err_act)
info = psb_success_
if (present(coarse)) then
coarse_ = coarse
else
coarse_ = .false.
end if
if (present(iout)) then
iout_ = iout
else
iout_ = psb_out_unit
endif
if (present(prefix)) then
prefix_ = prefix
else
prefix_ = ""
end if
write(iout_,*) trim(prefix_), ' Polynomial smoother '
select case(sm%variant)
case(amg_poly_lottes_)
write(iout_,*) trim(prefix_), ' variant: ','POLY_LOTTES'
write(iout_,*) trim(prefix_), ' Degree: ',sm%pdegree
write(iout_,*) trim(prefix_), ' rho_ba: ',sm%rho_ba
case(amg_poly_lottes_beta_)
write(iout_,*) trim(prefix_), ' variant: ','POLY_LOTTES_BETA'
write(iout_,*) trim(prefix_), ' Degree: ',sm%pdegree
write(iout_,*) trim(prefix_), ' rho_ba: ',sm%rho_ba
if (allocated(sm%poly_beta)) write(iout_,*) trim(prefix_), ' Coefficients: ',sm%poly_beta(1:sm%pdegree)
case(amg_poly_new_)
write(iout_,*) trim(prefix_), ' variant: ','POLY_NEW'
write(iout_,*) trim(prefix_), ' Degree: ',sm%pdegree
write(iout_,*) trim(prefix_), ' rho_ba: ',sm%rho_ba
write(iout_,*) trim(prefix_), ' Coefficient: ',sm%cf_a
case default
write(iout_,*) trim(prefix_), ' variant: ','UNKNOWN???'
end select
if (allocated(sm%sv)) then
write(iout_,*) trim(prefix_), ' Local solver details:'
call sm%sv%descr(info,iout_,coarse=coarse,prefix=prefix)
end if
call psb_erractionrestore(err_act)
return
9999 call psb_error_handler(err_act)
return
end subroutine amg_s_poly_smoother_descr
@@ -0,0 +1,90 @@
!
!
! AMG4PSBLAS version 1.0
! Algebraic Multigrid Package
! based on PSBLAS (Parallel Sparse BLAS version 3.7)
!
! (C) Copyright 2021
!
! Salvatore Filippone
! Pasqua D'Ambra
! Fabio Durastante
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions, and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! 3. The name of the AMG4PSBLAS group or the names of its contributors may
! not be used to endorse or promote products derived from this
! software without specific written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
! TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AMG4PSBLAS GROUP OR ITS CONTRIBUTORS
! BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! POSSIBILITY OF SUCH DAMAGE.
!
!
subroutine amg_s_poly_smoother_dmp(sm,desc,level,info,prefix,head,smoother,solver,global_num)
use psb_base_mod
use amg_s_poly_smoother, amg_protect_nam => amg_s_poly_smoother_dmp
implicit none
class(amg_s_poly_smoother_type), intent(in) :: sm
type(psb_desc_type), intent(in) :: desc
integer(psb_ipk_), intent(in) :: level
integer(psb_ipk_), intent(out) :: info
character(len=*), intent(in), optional :: prefix, head
logical, optional, intent(in) :: smoother, solver, global_num
integer(psb_ipk_) :: i, j, il1, iln, lname, lev
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: iam, np
character(len=80) :: prefix_
character(len=120) :: fname ! len should be at least 20 more than
integer(psb_lpk_), allocatable :: iv(:)
logical :: smoother_, global_num_
! len of prefix_
info = 0
if (present(prefix)) then
prefix_ = trim(prefix(1:min(len(prefix),len(prefix_))))
else
prefix_ = "dump_smth_d"
end if
ctxt = desc%get_context()
call psb_info(ctxt,iam,np)
if (present(smoother)) then
smoother_ = smoother
else
smoother_ = .false.
end if
if (present(global_num)) then
global_num_ = global_num
else
global_num_ = .false.
end if
lname = len_trim(prefix_)
fname = trim(prefix_)
write(fname(lname+1:lname+5),'(a,i3.3)') '_poly',iam
lname = lname + 8
! to be completed
! At base level do nothing for the smoother
if (allocated(sm%sv)) &
& call sm%sv%dump(desc,level,info,solver=solver,prefix=prefix,global_num=global_num)
end subroutine amg_s_poly_smoother_dmp
@@ -175,7 +175,7 @@ subroutine amg_z_jac_smoother_apply_vect(alpha,sm,x,beta,y,desc_data,trans,&
if (info /= psb_success_) exit
if ( sm%checkres.and.(mod(i,sm%checkiter) == 0) ) then
call psb_geaxpby(zone,x,zzero,r,r,desc_data,info)
call psb_geaxpby(zone,x,zzero,r,desc_data,info)
call psb_spmm(-zone,sm%pa,ty,zone,r,desc_data,info)
res = psb_genrm2(r,desc_data,info)
if( sm%printres ) then
+22 -8
View File
@@ -52,7 +52,7 @@ subroutine amg_c_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
class(psb_c_base_vect_type), intent(in), optional :: vmold
class(psb_i_base_vect_type), intent(in), optional :: imold
! Local variables
integer(psb_ipk_) :: n_row,n_col, nrow_a, nztota
integer(psb_ipk_) :: n_row,n_col, nrow_a, nztota, psb_fctype
!!$ complex(psb_spk_), pointer :: ww(:), aux(:), tx(:),ty(:)
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np, me, i, err_act, debug_unit, debug_level
@@ -97,10 +97,24 @@ subroutine amg_c_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
goto 9999
endif
select case(sv%fact_type)
case (amg_ilu_n_)
psb_fctype = psb_ilu_n_
case (amg_milu_n_)
psb_fctype = psb_milu_n_
case (amg_ilu_t_)
psb_fctype = psb_ilu_t_
case default
! If we end up here, something was wrong up in the call chain.
info = psb_err_input_value_invalid_i_
call psb_errpush(psb_err_input_value_invalid_i_,name,&
& i_err=(/ithree,sv%fact_type,izero,izero,izero/))
goto 9999
end select
select case(sv%fact_type)
case (psb_ilu_t_)
case (amg_ilu_t_)
!
! ILU(k,t)
!
@@ -124,7 +138,7 @@ subroutine amg_c_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
goto 9999
end if
case(psb_ilu_n_,psb_milu_n_)
case(amg_ilu_n_,amg_milu_n_)
!
! ILU(k) and MILU(k)
!
@@ -140,17 +154,17 @@ subroutine amg_c_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
! There seems to be a problem with the separate implementation of MILU(0),
! contained into psb_ilu0_fact. This must be investigated. For the time being,
! resort to the implementation of MILU(k) with k=0.
if (sv%fact_type == psb_ilu_n_) then
call psb_ilu0_fact(sv%fact_type,a,sv%l,sv%u,&
if (sv%fact_type == amg_ilu_n_) then
call psb_ilu0_fact(psb_fctype,a,sv%l,sv%u,&
& sv%d,info,blck=b)
else
call psb_iluk_fact(sv%fill_in,sv%fact_type,&
call psb_iluk_fact(sv%fill_in,psb_fctype,&
& a,sv%l,sv%u,sv%d,info,blck=b)
endif
case(1:)
! Fill-in >= 1
! The same routine implements both ILU(k) and MILU(k)
call psb_iluk_fact(sv%fill_in,sv%fact_type,&
call psb_iluk_fact(sv%fill_in,psb_fctype,&
& a,sv%l,sv%u,sv%d,info,blck=b)
end select
if (info /= psb_success_) then
+22 -8
View File
@@ -52,7 +52,7 @@ subroutine amg_d_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
class(psb_d_base_vect_type), intent(in), optional :: vmold
class(psb_i_base_vect_type), intent(in), optional :: imold
! Local variables
integer(psb_ipk_) :: n_row,n_col, nrow_a, nztota
integer(psb_ipk_) :: n_row,n_col, nrow_a, nztota, psb_fctype
!!$ real(psb_dpk_), pointer :: ww(:), aux(:), tx(:),ty(:)
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np, me, i, err_act, debug_unit, debug_level
@@ -97,10 +97,24 @@ subroutine amg_d_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
goto 9999
endif
select case(sv%fact_type)
case (amg_ilu_n_)
psb_fctype = psb_ilu_n_
case (amg_milu_n_)
psb_fctype = psb_milu_n_
case (amg_ilu_t_)
psb_fctype = psb_ilu_t_
case default
! If we end up here, something was wrong up in the call chain.
info = psb_err_input_value_invalid_i_
call psb_errpush(psb_err_input_value_invalid_i_,name,&
& i_err=(/ithree,sv%fact_type,izero,izero,izero/))
goto 9999
end select
select case(sv%fact_type)
case (psb_ilu_t_)
case (amg_ilu_t_)
!
! ILU(k,t)
!
@@ -124,7 +138,7 @@ subroutine amg_d_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
goto 9999
end if
case(psb_ilu_n_,psb_milu_n_)
case(amg_ilu_n_,amg_milu_n_)
!
! ILU(k) and MILU(k)
!
@@ -140,17 +154,17 @@ subroutine amg_d_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
! There seems to be a problem with the separate implementation of MILU(0),
! contained into psb_ilu0_fact. This must be investigated. For the time being,
! resort to the implementation of MILU(k) with k=0.
if (sv%fact_type == psb_ilu_n_) then
call psb_ilu0_fact(sv%fact_type,a,sv%l,sv%u,&
if (sv%fact_type == amg_ilu_n_) then
call psb_ilu0_fact(psb_fctype,a,sv%l,sv%u,&
& sv%d,info,blck=b)
else
call psb_iluk_fact(sv%fill_in,sv%fact_type,&
call psb_iluk_fact(sv%fill_in,psb_fctype,&
& a,sv%l,sv%u,sv%d,info,blck=b)
endif
case(1:)
! Fill-in >= 1
! The same routine implements both ILU(k) and MILU(k)
call psb_iluk_fact(sv%fill_in,sv%fact_type,&
call psb_iluk_fact(sv%fill_in,psb_fctype,&
& a,sv%l,sv%u,sv%d,info,blck=b)
end select
if (info /= psb_success_) then
+22 -8
View File
@@ -52,7 +52,7 @@ subroutine amg_s_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
class(psb_s_base_vect_type), intent(in), optional :: vmold
class(psb_i_base_vect_type), intent(in), optional :: imold
! Local variables
integer(psb_ipk_) :: n_row,n_col, nrow_a, nztota
integer(psb_ipk_) :: n_row,n_col, nrow_a, nztota, psb_fctype
!!$ real(psb_spk_), pointer :: ww(:), aux(:), tx(:),ty(:)
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np, me, i, err_act, debug_unit, debug_level
@@ -97,10 +97,24 @@ subroutine amg_s_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
goto 9999
endif
select case(sv%fact_type)
case (amg_ilu_n_)
psb_fctype = psb_ilu_n_
case (amg_milu_n_)
psb_fctype = psb_milu_n_
case (amg_ilu_t_)
psb_fctype = psb_ilu_t_
case default
! If we end up here, something was wrong up in the call chain.
info = psb_err_input_value_invalid_i_
call psb_errpush(psb_err_input_value_invalid_i_,name,&
& i_err=(/ithree,sv%fact_type,izero,izero,izero/))
goto 9999
end select
select case(sv%fact_type)
case (psb_ilu_t_)
case (amg_ilu_t_)
!
! ILU(k,t)
!
@@ -124,7 +138,7 @@ subroutine amg_s_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
goto 9999
end if
case(psb_ilu_n_,psb_milu_n_)
case(amg_ilu_n_,amg_milu_n_)
!
! ILU(k) and MILU(k)
!
@@ -140,17 +154,17 @@ subroutine amg_s_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
! There seems to be a problem with the separate implementation of MILU(0),
! contained into psb_ilu0_fact. This must be investigated. For the time being,
! resort to the implementation of MILU(k) with k=0.
if (sv%fact_type == psb_ilu_n_) then
call psb_ilu0_fact(sv%fact_type,a,sv%l,sv%u,&
if (sv%fact_type == amg_ilu_n_) then
call psb_ilu0_fact(psb_fctype,a,sv%l,sv%u,&
& sv%d,info,blck=b)
else
call psb_iluk_fact(sv%fill_in,sv%fact_type,&
call psb_iluk_fact(sv%fill_in,psb_fctype,&
& a,sv%l,sv%u,sv%d,info,blck=b)
endif
case(1:)
! Fill-in >= 1
! The same routine implements both ILU(k) and MILU(k)
call psb_iluk_fact(sv%fill_in,sv%fact_type,&
call psb_iluk_fact(sv%fill_in,psb_fctype,&
& a,sv%l,sv%u,sv%d,info,blck=b)
end select
if (info /= psb_success_) then
+22 -8
View File
@@ -52,7 +52,7 @@ subroutine amg_z_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
class(psb_z_base_vect_type), intent(in), optional :: vmold
class(psb_i_base_vect_type), intent(in), optional :: imold
! Local variables
integer(psb_ipk_) :: n_row,n_col, nrow_a, nztota
integer(psb_ipk_) :: n_row,n_col, nrow_a, nztota, psb_fctype
!!$ complex(psb_dpk_), pointer :: ww(:), aux(:), tx(:),ty(:)
type(psb_ctxt_type) :: ctxt
integer(psb_ipk_) :: np, me, i, err_act, debug_unit, debug_level
@@ -97,10 +97,24 @@ subroutine amg_z_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
goto 9999
endif
select case(sv%fact_type)
case (amg_ilu_n_)
psb_fctype = psb_ilu_n_
case (amg_milu_n_)
psb_fctype = psb_milu_n_
case (amg_ilu_t_)
psb_fctype = psb_ilu_t_
case default
! If we end up here, something was wrong up in the call chain.
info = psb_err_input_value_invalid_i_
call psb_errpush(psb_err_input_value_invalid_i_,name,&
& i_err=(/ithree,sv%fact_type,izero,izero,izero/))
goto 9999
end select
select case(sv%fact_type)
case (psb_ilu_t_)
case (amg_ilu_t_)
!
! ILU(k,t)
!
@@ -124,7 +138,7 @@ subroutine amg_z_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
goto 9999
end if
case(psb_ilu_n_,psb_milu_n_)
case(amg_ilu_n_,amg_milu_n_)
!
! ILU(k) and MILU(k)
!
@@ -140,17 +154,17 @@ subroutine amg_z_ilu_solver_bld(a,desc_a,sv,info,b,amold,vmold,imold)
! There seems to be a problem with the separate implementation of MILU(0),
! contained into psb_ilu0_fact. This must be investigated. For the time being,
! resort to the implementation of MILU(k) with k=0.
if (sv%fact_type == psb_ilu_n_) then
call psb_ilu0_fact(sv%fact_type,a,sv%l,sv%u,&
if (sv%fact_type == amg_ilu_n_) then
call psb_ilu0_fact(psb_fctype,a,sv%l,sv%u,&
& sv%d,info,blck=b)
else
call psb_iluk_fact(sv%fill_in,sv%fact_type,&
call psb_iluk_fact(sv%fill_in,psb_fctype,&
& a,sv%l,sv%u,sv%d,info,blck=b)
endif
case(1:)
! Fill-in >= 1
! The same routine implements both ILU(k) and MILU(k)
call psb_iluk_fact(sv%fill_in,sv%fact_type,&
call psb_iluk_fact(sv%fill_in,psb_fctype,&
& a,sv%l,sv%u,sv%d,info,blck=b)
end select
if (info /= psb_success_) then