Révision | 748479b4f5705859d117caa2d7c03ee0a26d07c6 (tree) |
---|---|
l'heure | 2013-08-01 10:51:52 |
Auteur | Mikiya Fujii <mikiya.fujii@gmai...> |
Commiter | Mikiya Fujii |
Calculation of force on ground state for MNDO-series is MPI parallelized. #31814
git-svn-id: https://svn.sourceforge.jp/svnroot/molds/trunk@1451 1136aad2-a195-0410-b898-f5ea1d11b9d8
@@ -2267,23 +2267,29 @@ void Mndo::CalcForceExcitedTwoElecPart(double* force, | ||
2267 | 2267 | // electronicStateIndex is index of the electroinc eigen state. |
2268 | 2268 | // "electronicStateIndex = 0" means electronic ground state. |
2269 | 2269 | void Mndo::CalcForce(const vector<int>& elecStates){ |
2270 | + int mpiRank = MolDS_mpi::MpiProcess::GetInstance()->GetRank(); | |
2271 | + int mpiSize = MolDS_mpi::MpiProcess::GetInstance()->GetSize(); | |
2270 | 2272 | this->CheckMatrixForce(elecStates); |
2271 | 2273 | if(this->RequiresExcitedStatesForce(elecStates)){ |
2272 | 2274 | this->CalcEtaMatrixForce(elecStates); |
2273 | 2275 | this->CalcZMatrixForce(elecStates); |
2274 | 2276 | } |
2275 | - stringstream ompErrors; | |
2277 | + | |
2278 | + // this loop is MPI-parallelized | |
2279 | + for(int a=0; a<this->molecule->GetNumberAtoms(); a++){ | |
2280 | + if(a%mpiSize != mpiRank){continue;} | |
2281 | + const Atom& atomA = *molecule->GetAtom(a); | |
2282 | + int firstAOIndexA = atomA.GetFirstAOIndex(); | |
2283 | + int lastAOIndexA = atomA.GetLastAOIndex(); | |
2284 | + stringstream ompErrors; | |
2276 | 2285 | #pragma omp parallel |
2277 | - { | |
2278 | - double***** diatomicTwoElecTwoCore1stDerivs = NULL; | |
2279 | - double*** diatomicOverlapAOs1stDerivs = NULL; | |
2280 | - try{ | |
2281 | - this->MallocTempMatricesCalcForce(&diatomicOverlapAOs1stDerivs, &diatomicTwoElecTwoCore1stDerivs); | |
2286 | + { | |
2287 | + double***** diatomicTwoElecTwoCore1stDerivs = NULL; | |
2288 | + double*** diatomicOverlapAOs1stDerivs = NULL; | |
2289 | + try{ | |
2290 | + this->MallocTempMatricesCalcForce(&diatomicOverlapAOs1stDerivs, &diatomicTwoElecTwoCore1stDerivs); | |
2291 | + | |
2282 | 2292 | #pragma omp for schedule(auto) |
2283 | - for(int a=0; a<this->molecule->GetNumberAtoms(); a++){ | |
2284 | - const Atom& atomA = *molecule->GetAtom(a); | |
2285 | - int firstAOIndexA = atomA.GetFirstAOIndex(); | |
2286 | - int lastAOIndexA = atomA.GetLastAOIndex(); | |
2287 | 2293 | for(int b=0; b<this->molecule->GetNumberAtoms(); b++){ |
2288 | 2294 | if(a == b){continue;} |
2289 | 2295 | const Atom& atomB = *molecule->GetAtom(b); |
@@ -2393,19 +2399,25 @@ void Mndo::CalcForce(const vector<int>& elecStates){ | ||
2393 | 2399 | } |
2394 | 2400 | } |
2395 | 2401 | } // end of excited state force |
2396 | - } // end of for(int b) | |
2397 | - } // end of for(int a) | |
2398 | - } // end of try | |
2399 | - catch(MolDSException ex){ | |
2402 | + } // end of for(int b) with omp parallelization | |
2403 | + | |
2404 | + } // end of try for omp-for | |
2405 | + catch(MolDSException ex){ | |
2400 | 2406 | #pragma omp critical |
2401 | - ex.Serialize(ompErrors); | |
2407 | + ex.Serialize(ompErrors); | |
2408 | + } | |
2409 | + this->FreeTempMatricesCalcForce(&diatomicOverlapAOs1stDerivs, &diatomicTwoElecTwoCore1stDerivs); | |
2410 | + } // end of omp-parallelized region | |
2411 | + // Exception throwing for omp-region | |
2412 | + if(!ompErrors.str().empty()){ | |
2413 | + throw MolDSException::Deserialize(ompErrors); | |
2402 | 2414 | } |
2403 | - this->FreeTempMatricesCalcForce(&diatomicOverlapAOs1stDerivs, &diatomicTwoElecTwoCore1stDerivs); | |
2404 | - } | |
2405 | - // Exception throwing for omp-region | |
2406 | - if(!ompErrors.str().empty()){ | |
2407 | - throw MolDSException::Deserialize(ompErrors); | |
2408 | - } | |
2415 | + }// end of for(int a) with MPI parallelization | |
2416 | + | |
2417 | + // communication to reduce thsi->matrixForce on all node (namely, all_reduce) | |
2418 | + int numTransported = elecStates.size()*this->molecule->GetNumberAtoms()*CartesianType_end; | |
2419 | + MolDS_mpi::MpiProcess::GetInstance()->AllReduce(&this->matrixForce[0][0][0], numTransported, std::plus<double>()); | |
2420 | + | |
2409 | 2421 | } |
2410 | 2422 | |
2411 | 2423 | void Mndo::MallocTempMatricesCalcForce(double**** diatomicOverlapAOs1stDerivs, double****** diatomicTwoElecTwoCore1stDerivs) const{ |
@@ -3731,7 +3731,7 @@ void ZindoS::CalcForce(const vector<int>& elecStates){ | ||
3731 | 3731 | OrbitalType_end, |
3732 | 3732 | OrbitalType_end, |
3733 | 3733 | CartesianType_end); |
3734 | - } //end of parallelized region | |
3734 | + } //end of omp-parallelized region | |
3735 | 3735 | // Exception throwing for omp-region |
3736 | 3736 | if(!ompErrors.str().empty()){ |
3737 | 3737 | throw MolDSException::Deserialize(ompErrors); |