********>Bugfix 30 Author: Ross Walker Date: 1/27/2007 Programs: Sander Description: Numerous minor bug fixes that may cause problems such as segfaults or file open errors on some systems depending on the compiler being used. Specific Fixes include: 1) Workaround for some dodgy Intel compiler that can cause a QMMM MPI hang at printing kvector distribution in mdout file. 2) Fix QMMM PIMD MPI_Gather error in parallel. 3) Fix bad format statement in bad iqmatoms error message. 4) REMD simulations may report error on opening mdout. 5) Gas phase simulations may segfault in parallel. 6) REMD simulations may have problems reading the command line. Fix: apply the following patch to src/sander/qmmm_module.f src/sander/qm_ewald.f src/sander/mdfil.f src/sander/nonbond_list.f src/sander/sander.f src/sander/mexit.f ------------------------------------------------------------------------------ *** qm_ewald.f 2006-04-03 16:35:55.000000000 -0700 --- qm_ewald.f 2007-01-27 23:28:30.000000000 -0800 *************** *** 58,69 **** !Local integer :: kx,ky,kz,ksy,ksz,ksq ! integer :: mpi_division, mpi_totkq_count integer :: ier #ifdef MPI - #include "parallel.h" #include "mpif.h" ! integer :: i, istatus, istartend(2) #endif !Calculate the total number of kspace vectors --- 58,71 ---- !Local integer :: kx,ky,kz,ksy,ksz,ksq ! integer :: mpi_division integer :: ier #ifdef MPI #include "mpif.h" ! integer :: i, istartend(2) ! !PART OF WORKAROUND FOR BUGGY INTEL COMPILER ! integer, allocatable, dimension(:) :: gather_array ! #endif !Calculate the total number of kspace vectors *************** *** 89,137 **** end do !Now we need to allocate enough memory for the kvectors and the kvector exponential tables. ! if (totkq > 0) then ! mpi_division = (totkq + (qmmm_mpi%numthreads-1))/qmmm_mpi%numthreads ! qmmm_mpi%kvec_end = min(mpi_division*(qmmm_mpi%mytaskid+1),totkq) ! qmmm_mpi%kvec_start = min(mpi_division*qmmm_mpi%mytaskid+1,totkq+1) ! qmmm_mpi%totkq_count = qmmm_mpi%kvec_end-qmmm_mpi%kvec_start+1 #ifdef MPI ! if (qmmm_mpi%master) then ! write (6,'(/a)') '|QMMM: KVector division among threads:' ! write (6,'(a)') '|QMMM: Start End Count' ! !Already know my own. ! write(6,'(a,i8,a,i8,a,i8,a)') & ! '|QMMM: Thread( 0): ',qmmm_mpi%kvec_start,'->',qmmm_mpi%kvec_end, & ! ' (',qmmm_mpi%kvec_end-qmmm_mpi%kvec_start+1,')' ! do i = 1, sandersize-1 ! call mpi_recv(istartend,2,mpi_integer,i,0,commsander,istatus,ier) ! write(6,'(a,i4,a,i8,a,i8,a,i8,a)') & ! '|QMMM: Thread(',i,'): ',istartend(1),'->',istartend(2), & ! ' (',istartend(2)-istartend(1)+1,')' ! end do ! else ! !Send a message to the master with our counts in. ! istartend(1) = qmmm_mpi%kvec_start ! istartend(2) = qmmm_mpi%kvec_end ! call mpi_send(istartend,2,mpi_integer,0,0,commsander,ier) ! end if ! #endif ! !Ultimately we only need to allocate these as the number of kvectors this cpu does. ! allocate ( qmewald%kvec(qmmm_mpi%totkq_count),stat=ier ) ! REQUIRE(ier == 0) ! allocate ( qmewald%dkvec(3,qmmm_mpi%totkq_count),stat=ier ) REQUIRE(ier == 0) ! allocate ( qmewald%dmkv(3,qmmm_mpi%totkq_count),stat=ier ) REQUIRE(ier == 0) ! if (.not. qmmm_nml%qm_pme) then ! allocate ( qmewald%ktable(6,natom,qmmm_mpi%totkq_count), stat=ier ) ! REQUIRE(ier == 0) ! end if ! allocate ( qmewald%qmktable(6,nquant+nlink,qmmm_mpi%totkq_count), stat=ier ) REQUIRE(ier == 0) - else - call sander_bomb('qm_ewald_setup','INVALID NUMBER OF K VECTORS','Need totkq > 0') end if return --- 91,166 ---- end do !Now we need to allocate enough memory for the kvectors and the kvector exponential tables. ! if (totkq == 0) then ! call sander_bomb('qm_ewald_setup','INVALID NUMBER OF K VECTORS','Need totkq > 0') ! end if ! ! mpi_division = (totkq + (qmmm_mpi%numthreads-1))/qmmm_mpi%numthreads ! qmmm_mpi%kvec_end = min(mpi_division*(qmmm_mpi%mytaskid+1),totkq) ! qmmm_mpi%kvec_start = min(mpi_division*qmmm_mpi%mytaskid+1,totkq+1) ! qmmm_mpi%totkq_count = qmmm_mpi%kvec_end-qmmm_mpi%kvec_start+1 ! #ifdef MPI ! if (qmmm_mpi%master) then ! write (6,'(/a)') '|QMMM: KVector division among threads:' ! write (6,'(a)') '|QMMM: Start End Count' ! ! !The FOLLOWING CODE SHOULD WORK FINE BUT THE INTEL COMPILER SEEMS TO MISCOMPILE ! !THE i=1,iminus loop DUE TO A COMPILER BUG. SO I HAVE WRITTEN A WORK AROUND BELOW. ! ! !Already know my own. ! ! write(6,'(a,i8,a,i8,a,i8,a)') & ! ! '|QMMM: Thread( 0): ',qmmm_mpi%kvec_start,'->',qmmm_mpi%kvec_end, & ! ! ' (',qmmm_mpi%kvec_end-qmmm_mpi%kvec_start+1,')' ! ! iminus = qmmm_mpi%numthreads-1 ! ! do i = 1, iminus ! ! call mpi_recv(istartend,2,mpi_integer,i,i,qmmm_mpi%commqmmm,istatus,ier) ! ! write(6,'(a,i4,a,i8,a,i8,a,i8,a)') & ! ! '|QMMM: Thread(',i,'): ',istartend(1),'->',istartend(2), & ! ! ' (',istartend(2)-istartend(1)+1,')' ! ! end do ! ! else ! ! !Send a message to the master with our counts in. ! ! istartend(1) = qmmm_mpi%kvec_start ! ! istartend(2) = qmmm_mpi%kvec_end ! ! call mpi_ssend(istartend,2,mpi_integer,0,qmmm_mpi%mytaskid,qmmm_mpi%commqmmm,ier) ! ! end if ! !WORKAROUND FOR BUGGY INTEL COMPILER ! end if ! if (qmmm_mpi%commqmmm_master) then ! allocate( gather_array(2*qmmm_mpi%numthreads), stat=ier) REQUIRE(ier == 0) ! end if ! istartend(1) = qmmm_mpi%kvec_start ! istartend(2) = qmmm_mpi%kvec_end ! call mpi_gather(istartend, 2, MPI_INTEGER, gather_array, 2, MPI_INTEGER, 0, qmmm_mpi%commqmmm, ier) ! if (qmmm_mpi%master) then ! do i = 1, qmmm_mpi%numthreads ! write(6,'(a,i4,a,i8,a,i8,a,i8,a)') & ! '|QMMM: Thread(',i-1,'): ',gather_array(2*i-1),'->',gather_array(2*i), & ! ' (',gather_array(2*i)-gather_array(2*i-1)+1,')' ! end do ! end if ! if (qmmm_mpi%commqmmm_master) then ! deallocate( gather_array, stat=ier) REQUIRE(ier == 0) ! end if ! ! #endif ! !We only allocate these as the number of kvectors this cpu does since totkq_count is ! !qmmm_mpi%kvec_end-qmmm_mpi%kvec_start+1 ! allocate ( qmewald%kvec(qmmm_mpi%totkq_count),stat=ier ) ! REQUIRE(ier == 0) ! allocate ( qmewald%dkvec(3,qmmm_mpi%totkq_count),stat=ier ) ! REQUIRE(ier == 0) ! allocate ( qmewald%dmkv(3,qmmm_mpi%totkq_count),stat=ier ) ! REQUIRE(ier == 0) ! if (.not. qmmm_nml%qm_pme) then ! allocate ( qmewald%ktable(6,natom,qmmm_mpi%totkq_count), stat=ier ) REQUIRE(ier == 0) end if + allocate ( qmewald%qmktable(6,nquant+nlink,qmmm_mpi%totkq_count), stat=ier ) + REQUIRE(ier == 0) return *** qmmm_module.f 2006-04-03 16:35:55.000000000 -0700 --- qmmm_module.f 2007-01-27 23:28:33.000000000 -0800 *************** *** 1794,1800 **** ! Sanity check 1, ensure nquant isn't bigger than natom (it can't be) if ((nquant < 1) .OR. (nquant > natom)) then write (6,'(" QM ATOM VALIDATION: nquant has a value of ",i8)') nquant ! write (6,'(" which is bigger than natom of ",i8,". Need 0 < nquant <= natom.")i') natom call sander_bomb('validate_qm_atoms','nquant illegal', 'Need 0 < nquant <= natom') end if --- 1794,1800 ---- ! Sanity check 1, ensure nquant isn't bigger than natom (it can't be) if ((nquant < 1) .OR. (nquant > natom)) then write (6,'(" QM ATOM VALIDATION: nquant has a value of ",i8)') nquant ! write (6,'(" which is bigger than natom of ",i8,". Need 0 < nquant <= natom.")') natom call sander_bomb('validate_qm_atoms','nquant illegal', 'Need 0 < nquant <= natom') end if *** mdfil.f 2006-04-03 16:35:55.000000000 -0700 --- mdfil.f 2007-01-27 23:28:16.000000000 -0800 *************** *** 290,305 **** if (numgroup > 1 .and. groups(1:1) /= ' ') then ia = 0 ! istart = 0 iend = len(groupbuffer) ! do while (istart < iend) if ( groupbuffer(istart:istart) == ' ' ) then istart = istart + 1 else is = istart ie = istart ! do while ( ie < iend .and. & groupbuffer(ie:ie) /= ' ' ) ie = ie + 1 end do --- 290,305 ---- if (numgroup > 1 .and. groups(1:1) /= ' ') then ia = 0 ! istart = 1 iend = len(groupbuffer) ! do while (istart <= iend) if ( groupbuffer(istart:istart) == ' ' ) then istart = istart + 1 else is = istart ie = istart ! do while ( ie <= iend .and. & groupbuffer(ie:ie) /= ' ' ) ie = ie + 1 end do *************** *** 341,347 **** istart = 1 iend = len(groupbuffer) ! do while (istart < iend) if ( groupbuffer(istart:istart) == ' ' ) then istart = istart + 1 --- 341,347 ---- istart = 1 iend = len(groupbuffer) ! do while (istart <= iend) if ( groupbuffer(istart:istart) == ' ' ) then istart = istart + 1 *************** *** 349,355 **** is = istart ie = istart ! do while ( ie < iend .and. & groupbuffer(ie:ie) /= ' ' ) ie = ie + 1 end do --- 349,355 ---- is = istart ie = istart ! do while ( ie <= iend .and. & groupbuffer(ie:ie) /= ' ' ) ie = ie + 1 end do *** mexit.f 2006-04-03 16:35:55.000000000 -0700 --- mexit.f 2007-01-27 23:28:21.000000000 -0800 *************** *** 28,34 **** end if #endif ! if (output_unit > 0) then close(unit=output_unit) end if --- 28,34 ---- end if #endif ! if (output_unit > 0 .and. status /= 0) then close(unit=output_unit) end if *** nonbond_list.f 2006-04-03 16:35:55.000000000 -0700 --- nonbond_list.f 2007-01-27 23:28:25.000000000 -0800 *************** *** 2091,2103 **** ! ---- in the right order if(periodic == 0)then do i=1,natom ! j = bckptr(i) ! imagcrds(1,i) = crd(1,j) ! imagcrds(2,i) = crd(2,j) ! imagcrds(3,i) = crd(3,j) ! imagcrds(1,i) = crd(1,j)+xbox0 ! imagcrds(2,i) = crd(2,j)+ybox0 ! imagcrds(3,i) = crd(3,j)+zbox0 end do return end if --- 2091,2102 ---- ! ---- in the right order if(periodic == 0)then do i=1,natom ! if (mygrdlist(i) == 1) then ! j = bckptr(i) ! imagcrds(1,i) = crd(1,j)+xbox0 ! imagcrds(2,i) = crd(2,j)+ybox0 ! imagcrds(3,i) = crd(3,j)+zbox0 ! end if end do return end if *** sander.f 2006-04-03 16:35:55.000000000 -0700 --- sander.f 2007-01-27 23:28:39.000000000 -0800 *************** *** 1004,1009 **** --- 1004,1011 ---- if( ntb>0 .and. ifbox==1 .and. ew_type==0 .and. mpoltype==0 ) & call deallocate_m1m2m3() call AMOEBA_deallocate + + if (master) close(6) return ------------------------------------------------------------------------------ Temporary Workarounds: None