8 #include <fei_macros.hpp>
10 #include <fei_utils.hpp>
12 #include <fei_ParameterSet.hpp>
13 #include <fei_LogManager.hpp>
14 #include <fei_Matrix_core.hpp>
15 #include <fei_CSRMat.hpp>
16 #include <fei_TemplateUtils.hpp>
17 #include <fei_CommUtils.hpp>
18 #include <fei_impl_utils.hpp>
20 #include <fei_VectorSpace.hpp>
21 #include <snl_fei_PointBlockMap.hpp>
22 #include <fei_MatrixGraph.hpp>
23 #include <snl_fei_Utils.hpp>
25 #include <fei_MatrixTraits.hpp>
26 #include <fei_MatrixTraits_FillableMat.hpp>
29 #define fei_file "fei_Matrix_core.cpp"
30 #include <fei_ErrMacros.hpp>
42 comm_(matrixGraph->getRowSpace()->getCommunicator()),
46 matrixGraph_(matrixGraph),
48 remotelyOwned_last_requested_(NULL),
53 sendRecvProcsNeedUpdated_(true),
54 proc_last_requested_(-1),
55 haveBlockMatrix_(false),
61 if (matrixGraph.
get() == NULL) {
62 throw std::runtime_error(
"fei::Matrix_core constructed with NULL fei::MatrixGraph");
67 if (vecSpace_->initCompleteAlreadyCalled()) {
69 eqnComm_.reset(
new fei::EqnComm(comm_, numLocalEqns, globalOffsets_));
72 eqnComm_.reset(
new fei::EqnComm(comm_, numLocalEqns));
80 globalOffsets_ = eqnComm_->getGlobalOffsets();
82 firstLocalOffset_ = globalOffsets_[localProc_];
83 lastLocalOffset_ = globalOffsets_[localProc_+1]-1;
86 std::map<int,fei::FillableMat*>&
87 fei::Matrix_core::getRemotelyOwnedMatrices()
89 return remotelyOwned_;
93 fei::Matrix_core::putScalar_remotelyOwned(
double scalar)
95 std::map<int,FillableMat*>::iterator
96 it = remotelyOwned_.begin(),
97 it_end = remotelyOwned_.end();
98 for(; it!=it_end; ++it) {
107 globalOffsets_ = eqnComm_->getGlobalOffsets();
108 firstLocalOffset_ = globalOffsets_[localProc_];
109 lastLocalOffset_ = globalOffsets_[localProc_+1]-1;
110 sendRecvProcsNeedUpdated_ =
true;
113 fei::Matrix_core::~Matrix_core()
115 std::map<int,FillableMat*>::iterator
116 it = remotelyOwned_.begin(),
117 it_end = remotelyOwned_.end();
118 for(; it!=it_end; ++it) {
128 param->
getType() : fei::Param::BAD_TYPE;
129 if (ptype == fei::Param::STRING) {
133 param = paramset.
get(
"FEI_OUTPUT_LEVEL");
134 ptype = param != NULL ? param->
getType() : fei::Param::BAD_TYPE;
135 if (ptype == fei::Param::STRING) {
143 void fei::Matrix_core::setName(
const char* name)
145 if (name == NULL)
return;
147 if (name_ == name)
return;
152 int fei::Matrix_core::getOwnerProc(
int globalEqn)
const
154 int len = globalOffsets_.size();
155 if (globalEqn > globalOffsets_[len-1])
return(-1);
157 for(
int p=len-2; p>=0; --p) {
158 if (globalEqn >= globalOffsets_[p]) {
168 rhsVector_ = rhsvector;
171 void fei::Matrix_core::setCommSizes()
178 std::map<int,FillableMat*>::iterator
179 it = remotelyOwned_.begin(),
180 it_end = remotelyOwned_.end();
181 for(; it!=it_end; ++it) {
182 if (it->first == localProc_)
continue;
183 if (it->second != NULL) {
184 if (it->second->getNumRows() == 0) {
188 sendProcs_.push_back(it->first);
197 std::vector<MPI_Request> mpiReqs(recvProcs_.size());
200 std::vector<int> recv_sizes(recvProcs_.size(), 0);
201 for(
size_t i=0; i<recvProcs_.size(); ++i) {
202 MPI_Irecv(&recv_sizes[i], 1, MPI_INT, recvProcs_[i],
203 tag1, comm_, &mpiReqs[i]);
208 send_chars_.resize(sendProcs_.size());
209 recv_chars_.resize(recvProcs_.size());
211 for(
size_t i=0; i<sendProcs_.size(); ++i) {
212 int proc = sendProcs_[i];
214 int num_bytes = fei::impl_utils::num_bytes_FillableMat(*(remotelyOwned_[proc]));
215 send_chars_[i].resize(num_bytes);
216 char* buffer = &(send_chars_[i][0]);
217 fei::impl_utils::pack_FillableMat(*(remotelyOwned_[proc]), buffer);
219 int bsize = send_chars_[i].size();
221 MPI_Send(&bsize, 1, MPI_INT, proc, tag1, comm_);
224 int numRecvProcs = recvProcs_.size();
225 for(
size_t i=0; i<recvProcs_.size(); ++i) {
228 MPI_Waitany(numRecvProcs, &mpiReqs[0], &index, &status);
230 recv_chars_[index].resize(recv_sizes[index]);
233 sendRecvProcsNeedUpdated_ =
false;
237 int fei::Matrix_core::gatherFromOverlap(
bool accumulate)
245 if (sendRecvProcsNeedUpdated_) {
249 std::vector<MPI_Request> mpiReqs(recvProcs_.size());
252 int numRecvProcs = recvProcs_.size();
255 for(
size_t i=0; i<recvProcs_.size(); ++i) {
256 int bsize = recv_chars_[i].size();
258 MPI_Irecv(&(recv_chars_[i][0]), bsize, MPI_CHAR, recvProcs_[i],
259 tag1, comm_, &mpiReqs[i]);
263 for(
size_t i=0; i<sendProcs_.size(); ++i) {
264 int proc = sendProcs_[i];
265 fei::FillableMat* remoteMat = remotelyOwned_[proc];
266 char* buffer = &(send_chars_[i][0]);
267 fei::impl_utils::pack_FillableMat(*remoteMat, buffer);
268 remoteMat->setValues(0.0);
270 MPI_Send(&(send_chars_[i][0]), send_chars_[i].size(), MPI_CHAR, proc, tag1, comm_);
273 for(
size_t ir=0; ir<recvProcs_.size(); ++ir) {
276 MPI_Waitany(numRecvProcs, &mpiReqs[0], &index, &status);
281 for(
size_t ir=0; ir<recvProcs_.size(); ++ir) {
282 size_t len = recv_chars_[ir].size();
283 const char* data = &(recv_chars_[ir][0]);
286 if (all_zeros)
continue;
288 int nrows = recvMat.getNumRows();
290 for(
int i=0; i<nrows; ++i) {
291 int row = recvMat.getGraph().rowNumbers[i];
292 int rowOffset = recvMat.getGraph().rowOffsets[i];
293 int rowLen = recvMat.getGraph().rowOffsets[i+1] - rowOffset;
295 int* indices = &(recvMat.getGraph().packedColumnIndices[rowOffset]);
296 double* vals = &(recvMat.getPackedCoefs()[rowOffset]);
298 if (haveBlockMatrix()) {
299 err = giveToBlockMatrix(1, &row, rowLen, indices, &vals, accumulate);
302 err = giveToUnderlyingMatrix(1, &row, rowLen, indices,
303 &vals, accumulate, FEI_DENSE_ROW);
306 FEI_COUT <<
"fei::Matrix_core::gatherFromOverlap ERROR storing "
307 <<
"values for row=" << row<<
", recv'd from proc " << recvProcs_[i]
320 fei::Matrix_core::copyTransposeToWorkArrays(
int numRows,
int numCols,
321 const double*
const* values,
322 std::vector<double>& work_1D,
323 std::vector<const double*>& work_2D)
327 int arrayLen = numCols*numRows;
328 if ((
int)work_1D.size() != arrayLen) {
329 work_1D.resize(arrayLen);
331 if ((
int)work_2D.size() != numCols) {
332 work_2D.resize(numCols);
335 const double** dataPtr = &work_2D[0];
336 double* data1DPtr = &work_1D[0];
338 for(
int i=0; i<numCols; ++i) {
339 dataPtr[i] = data1DPtr;
341 for(
int j=0; j<numRows; ++j) {
342 data1DPtr[j] = values[j][i];
345 data1DPtr += numRows;
350 int fei::Matrix_core::convertPtToBlk(
int numRows,
362 for(i=0; i<numRows; ++i) {
363 if (pointBlockMap->
getPtEqnInfo(rows[i], blkRows[i], blkRowOffsets[i])!=0){
367 for(i=0; i<numCols; ++i) {
368 if(pointBlockMap->
getPtEqnInfo(cols[i], blkCols[i], blkColOffsets[i])!=0){
376 int fei::Matrix_core::copyPointRowsToBlockRow(
int numPtRows,
378 const double*
const* ptValues,
380 const int* blkColDims,
384 for(
int blki=0; blki<numBlkCols; ++blki) {
385 int blkvalueOffset = 0;
386 double* blkvalues_i = blkValues[blki];
387 for(
int j=0; j<blkColDims[blki]; ++j) {
388 int loc = ptColOffset+j;
389 for(
int i=0; i<numPtRows; ++i) {
390 blkvalues_i[blkvalueOffset++] = ptValues[i][loc];
393 ptColOffset += blkColDims[blki];
401 matrixGraph_ = matrixGraph;
ParamType getType() const
const Param * get(const char *name) const
fei::OutputLevel string_to_output_level(const std::string &str)
bool unpack_CSRMat(const char *buffer_begin, const char *buffer_end, fei::CSRMat &mat)
virtual fei::SharedPtr< fei::VectorSpace > getRowSpace()=0
int mirrorProcs(MPI_Comm comm, std::vector< int > &toProcs, std::vector< int > &fromProcs)
void setOutputLevel(OutputLevel olevel)
void getGlobalIndexOffsets(std::vector< int > &globalOffsets) const
const std::string & getStringValue() const
int localProc(MPI_Comm comm)
static LogManager & getLogManager()
static int setValues(T *mat, double scalar)
int getPtEqnInfo(int ptEqn, int &blkEqn, int &blkOffset)
int numProcs(MPI_Comm comm)