修訂 | 3a1f18414278129978ce26051ad754e6cb01fb3c (tree) |
---|---|
時間 | 2013-06-18 20:39:10 |
作者 | Mikiya Fujii <mikiya.fujii@gmai...> |
Commiter | Mikiya Fujii |
Mndo::CalcCISMatrix is MPI-parallelized. #31588
git-svn-id: https://svn.sourceforge.jp/svnroot/molds/branches/mpi-cis@1367 1136aad2-a195-0410-b898-f5ea1d11b9d8
@@ -731,21 +731,23 @@ double Mndo::GetMolecularIntegralElement(int moI, int moJ, int moK, int moL, | ||
731 | 731 | void Mndo::CalcCISMatrix(double** matrixCIS) const{ |
732 | 732 | this->OutputLog(this->messageStartCalcCISMatrix); |
733 | 733 | double ompStartTime = omp_get_wtime(); |
734 | + boost::mpi::communicator* world = MolDS_mpi::MpiProcess::GetInstance()->GetCommunicator(); | |
734 | 735 | |
735 | - stringstream ompErrors; | |
736 | -#pragma omp parallel for schedule(auto) | |
737 | 736 | for(int k=0; k<this->matrixCISdimension; k++){ |
738 | - try{ | |
739 | - // single excitation from I-th (occupied)MO to A-th (virtual)MO | |
740 | - int moI = this->GetActiveOccIndex(*this->molecule, k); | |
741 | - int moA = this->GetActiveVirIndex(*this->molecule, k); | |
737 | + // single excitation from I-th (occupied)MO to A-th (virtual)MO | |
738 | + int moI = this->GetActiveOccIndex(*this->molecule, k); | |
739 | + int moA = this->GetActiveVirIndex(*this->molecule, k); | |
740 | + if(k%world->size() != world->rank()){continue;} | |
742 | 741 | |
743 | - for(int l=k; l<this->matrixCISdimension; l++){ | |
742 | + stringstream ompErrors; | |
743 | +#pragma omp parallel for schedule(auto) | |
744 | + for(int l=k; l<this->matrixCISdimension; l++){ | |
745 | + try{ | |
744 | 746 | // single excitation from J-th (occupied)MO to B-th (virtual)MO |
745 | 747 | int moJ = this->GetActiveOccIndex(*this->molecule, l); |
746 | 748 | int moB = this->GetActiveVirIndex(*this->molecule, l); |
747 | 749 | double value=0.0; |
748 | - | |
750 | + | |
749 | 751 | // Fast algorith, but this is not easy to read. |
750 | 752 | // Slow algorithm is alos written below. |
751 | 753 | for(int A=0; A<molecule->GetNumberAtoms(); A++){ |
@@ -865,13 +867,13 @@ void Mndo::CalcCISMatrix(double** matrixCIS) const{ | ||
865 | 867 | } |
866 | 868 | } |
867 | 869 | // End of the fast algorith. |
868 | - | |
870 | + | |
869 | 871 | /* |
870 | 872 | // Slow algorith, but this is easy to read. Fast altorithm is also written above. |
871 | 873 | value = 2.0*this->GetMolecularIntegralElement(moA, moI, moJ, moB, |
872 | - this->molecule, this->fockMatrix, NULL) | |
874 | + *this->molecule, this->fockMatrix, NULL) | |
873 | 875 | -this->GetMolecularIntegralElement(moA, moB, moI, moJ, |
874 | - this->molecule, this->fockMatrix, NULL); | |
876 | + *this->molecule, this->fockMatrix, NULL); | |
875 | 877 | // End of the slow algorith. |
876 | 878 | */ |
877 | 879 | // Diagonal term |
@@ -879,17 +881,38 @@ void Mndo::CalcCISMatrix(double** matrixCIS) const{ | ||
879 | 881 | value += this->energiesMO[moA] - this->energiesMO[moI]; |
880 | 882 | } |
881 | 883 | matrixCIS[k][l] = value; |
884 | + } | |
885 | + catch(MolDSException ex){ | |
886 | +#pragma omp critical | |
887 | + ompErrors << ex.what() << endl ; | |
882 | 888 | } |
889 | + }// end of l-loop | |
890 | + // Exception throwing for omp-region | |
891 | + if(!ompErrors.str().empty()){ | |
892 | + throw MolDSException(ompErrors.str()); | |
883 | 893 | } |
884 | - catch(MolDSException ex){ | |
885 | -#pragma omp critical | |
886 | - ompErrors << ex.what() << endl ; | |
894 | + } // end of k-loop | |
895 | + | |
896 | + // communication to collect all matrix data on rank 0 | |
897 | + if(world->rank() == 0){ | |
898 | + // receive the matrix data from other ranks | |
899 | + for(int k=0; k<this->matrixCISdimension; k++){ | |
900 | + if(k%world->size() == 0){continue;} | |
901 | + int source = k%world->size(); | |
902 | + int tag = k; | |
903 | + world->recv(source, tag, matrixCIS[k], this->matrixCISdimension); | |
887 | 904 | } |
888 | 905 | } |
889 | - // Exception throwing for omp-region | |
890 | - if(!ompErrors.str().empty()){ | |
891 | - throw MolDSException(ompErrors.str()); | |
906 | + else{ | |
907 | + // send the matrix data to rank-0 | |
908 | + for(int k=0; k<this->matrixCISdimension; k++){ | |
909 | + if(k%world->size() != world->rank()){continue;} | |
910 | + int dest = 0; | |
911 | + int tag = k; | |
912 | + world->send(dest, tag, matrixCIS[k], this->matrixCISdimension); | |
913 | + } | |
892 | 914 | } |
915 | + | |
893 | 916 | double ompEndTime = omp_get_wtime(); |
894 | 917 | this->OutputLog(boost::format("%s%lf%s\n%s") % this->messageOmpElapsedTimeCalcCISMarix.c_str() |
895 | 918 | % (ompEndTime - ompStartTime) |