|
EpetraExt
Development
|
00001 /* 00002 //@HEADER 00003 // *********************************************************************** 00004 // 00005 // EpetraExt: Epetra Extended - Linear Algebra Services Package 00006 // Copyright (2011) Sandia Corporation 00007 // 00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00009 // the U.S. Government retains certain rights in this software. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00039 // 00040 // *********************************************************************** 00041 //@HEADER 00042 */ 00043 00044 #include "EpetraExt_ConfigDefs.h" 00045 00046 00047 #ifdef HAVE_MPI 00048 00049 00050 #include "EpetraExt_RestrictedMultiVectorWrapper.h" 00051 #include "Epetra_MpiComm.h" 00052 #include "Epetra_BlockMap.h" 00053 #include "Epetra_MultiVector.h" 00054 00055 00056 namespace EpetraExt { 00057 00058 00059 RestrictedMultiVectorWrapper::RestrictedMultiVectorWrapper() 00060 : proc_is_active(true), 00061 subcomm_is_set(false), 00062 MPI_SubComm_(MPI_COMM_NULL), 00063 RestrictedComm_(0), 00064 ResMap_(0), 00065 input_mv_(), 00066 restricted_mv_() 00067 {} 00068 00069 00070 RestrictedMultiVectorWrapper::~RestrictedMultiVectorWrapper() { 00071 delete ResMap_; 00072 delete RestrictedComm_; 00073 } 00074 00075 00076 int RestrictedMultiVectorWrapper::SetMPISubComm(MPI_Comm MPI_SubComm){ 00077 if(!subcomm_is_set){ 00078 MPI_SubComm_=MPI_SubComm; delete RestrictedComm_; subcomm_is_set=true; 00079 return 0; 00080 } 00081 else return -1; 00082 } 00083 00084 00085 int 00086 RestrictedMultiVectorWrapper:: 00087 restrict_comm (Teuchos::RCP<Epetra_MultiVector> input_mv) 00088 { 00089 using Teuchos::rcp; 00090 input_mv_ = input_mv; 00091 00092 // Extract the input MV's communicator and Map. 00093 const Epetra_MpiComm *InComm = 00094 dynamic_cast<const Epetra_MpiComm*> (& (input_mv_->Comm ())); 00095 const Epetra_BlockMap *InMap = 00096 dynamic_cast<const Epetra_BlockMap*> (& (input_mv_->Map ())); 00097 00098 if (! InComm || ! InMap) { 00099 return -1; // At least one dynamic cast failed. 00100 } 00101 00102 if (! subcomm_is_set) { 00103 /* Build the Split Communicators, If Needed */ 00104 int color; 00105 if (InMap->NumMyElements()) { 00106 color = 1; 00107 } 00108 else { 00109 color = MPI_UNDEFINED; 00110 } 00111 const int err = 00112 MPI_Comm_split (InComm->Comm(), color, InComm->MyPID(), &MPI_SubComm_); 00113 if (err != MPI_SUCCESS) { 00114 return -2; 00115 } 00116 } 00117 else { 00118 /* Sanity check user-provided subcomm - drop an error if the MPISubComm 00119 does not include a processor with data. */ 00120 if (input_mv->MyLength() && MPI_SubComm_ == MPI_COMM_NULL) { 00121 return -2; 00122 } 00123 } 00124 00125 /* Mark active processors */ 00126 if (MPI_SubComm_ == MPI_COMM_NULL) { 00127 proc_is_active = false; 00128 } 00129 else { 00130 proc_is_active = true; 00131 } 00132 00133 if (proc_is_active) { 00134 00135 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES 00136 if(InMap->GlobalIndicesInt()) { 00137 int Nrows = InMap->NumGlobalElements (); 00138 RestrictedComm_ = new Epetra_MpiComm (MPI_SubComm_); 00139 00140 // Build the restricted Maps 00141 ResMap_ = new Epetra_BlockMap (Nrows, InMap->NumMyElements(), 00142 InMap->MyGlobalElements(), 00143 InMap->ElementSizeList(), 00144 InMap->IndexBase(), *RestrictedComm_); 00145 } 00146 else 00147 #endif 00148 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES 00149 if(InMap->GlobalIndicesLongLong()) { 00150 long long Nrows = InMap->NumGlobalElements64 (); 00151 RestrictedComm_ = new Epetra_MpiComm (MPI_SubComm_); 00152 00153 // Build the restricted Maps 00154 ResMap_ = new Epetra_BlockMap (Nrows, InMap->NumMyElements(), 00155 InMap->MyGlobalElements64(), 00156 InMap->ElementSizeList(), 00157 InMap->IndexBase64(), *RestrictedComm_); 00158 } 00159 else 00160 #endif 00161 throw "EpetraExt::RestrictedMultiVectorWrapper::restrict_comm ERROR: GlobalIndices type unknown"; 00162 00163 // Allocate the restricted matrix 00164 double *A; 00165 int LDA; 00166 input_mv_->ExtractView (&A,&LDA); 00167 restricted_mv_ = rcp (new Epetra_MultiVector (View, *ResMap_, A, LDA, 00168 input_mv_->NumVectors ())); 00169 } 00170 return (0); // Success! 00171 }/*end restrict_comm*/ 00172 00173 } 00174 00175 #endif
1.7.6.1