Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additions to CREGEN, --ohess rruntype #263

Merged
merged 2 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
246 changes: 179 additions & 67 deletions src/algos/ConfSolv.F90
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,18 @@ module ConfSolv_module
!> ConfSolv teardown instruction
logical :: cs_teardown = .false.
!> Keeping track of setup. Has it been called already?
logical :: cs_setup = .false.
logical :: cs_setup = .false.

!> ConfSolv parameter location
character(len=:),allocatable :: cs_param
!> ConfSolv solvent & smiles
character(len=:),allocatable :: cs_solvent
character(len=:),allocatable :: cs_solvfile
character(len=:),allocatable :: cs_smiles

!> n_threshold_mols
integer :: cs_n_threshold_mols = 1

!========================================================================================!
!========================================================================================!
contains !> MODULE PROCEDURES START HERE
Expand Down Expand Up @@ -96,9 +100,36 @@ subroutine cs_shutdown(io)
call kill(cs_pid,9,io)
deallocate (cs_pid)
end if
call cs_shutdown2(io)

end subroutine cs_shutdown

!=================================================!
subroutine cs_shutdown2(io)
use iomod
implicit none
integer,intent(out) :: io
integer :: ich,ro,pids
character(len=100) :: str
character(len=50) :: str2
call command('lsof confsolv.out > tmpcs 2>/dev/null',io)

open(newunit=ich,file='tmpcs')
do
read(ich,'(a)',iostat=ro) str
if(ro < 0 ) exit
!write(*,*) trim(str)
read(str,*,iostat=ro) str2,pids
if(ro == 0)then
! write(*,*) pids
call kill(pids,9,io)
endif
enddo
close(ich)

call remove('tmpcs')
end subroutine cs_shutdown2

!=================================================!

subroutine cs_deploy()
Expand All @@ -108,31 +139,31 @@ subroutine cs_deploy()
character(len=50) :: atmp
logical :: ex

if(.not.allocated(cs_bin)) cs_bin = 'confsolvserver'
call remove('confsolv.out')
if (.not.allocated(cs_bin)) cs_bin = 'confsolvserver'
!call remove('confsolv.out')
call remove('config_template.toml')

job = 'nohup '//trim(cs_bin)//' -l '//'> confsolv.out 2>/dev/null'//' &'

write(stdout,'(2x,a,a)') 'Hosting command: ',trim(job)
write (stdout,'(2x,a,a)') 'Hosting command: ',trim(job)
call command(job,io)

if(io /= 0) error stop '**ERROR** failed to host ConfSolv server'
if (io /= 0) error stop '**ERROR** failed to host ConfSolv server'
!call sleep(3)
do
do
call sleep(1)
inquire(file='config_template.toml',exist=ex)
if(ex) exit
enddo
inquire (file='config_template.toml',exist=ex)
if (ex) exit
end do

!> read port and pid
open(newunit=ich,file='confsolv.out')
read(ich,*) atmp,cs_pid
read(ich,*) atmp,cs_port
close(ich)
open (newunit=ich,file='confsolv.out')
read (ich,*) atmp,cs_pid
read (ich,*) atmp,cs_port
close (ich)
cs_teardown = .true.
cs_setup = .false.
write(stdout,'(2x,2(a,i0))') 'ConfSolv server will be running at http://localhost:',cs_port,' with PID ',cs_pid
write (stdout,'(2x,2(a,i0))') 'ConfSolv server will be running at http://localhost:',cs_port,' with PID ',cs_pid
end subroutine cs_deploy

!=================================================!
Expand All @@ -152,11 +183,15 @@ subroutine cs_write_config(ensname,threads)
if (allocated(cs_param)) then
call wrtoml(ich,'model_path',cs_param)
end if

call wrtoml(ich,'xyz_file',trim(atmp)//'/'//trim(ensname))
call wrtoml(ich,'solvent_file',trim(atmp)//'/'//'crest_solvents.csv')
if (allocated(cs_solvfile)) then
call wrtoml(ich,'solvent_file',trim(atmp)//'/'//cs_solvfile)
else
call wrtoml(ich,'solvent_file',trim(atmp)//'/'//'crest_solvents.csv')
end if

call wrtoml_int(ich,'n_threshold_mols',1)
call wrtoml_int(ich,'n_threshold_mols',cs_n_threshold_mols)
close (ich)
contains
subroutine wrtoml(ch,key,val)
Expand Down Expand Up @@ -314,13 +349,69 @@ subroutine cs_write_solvent_csv(solvent,smiles,ch)
case ('urea')
write (ich,'(a,",",a)') solvent,'NC(=O)N'
case default
write(stderr,'(2a)') '**ERROR** failed to find matching solvent SMILES for: ',solvent
write (stderr,'(2a)') '**ERROR** failed to find matching solvent SMILES for: ',solvent
error stop
end select
end if
close (ich)
end subroutine cs_write_solvent_csv

!========================================================================================!

subroutine confsolv_select_gsoln(nall,ncol,data,gsoln,mapping)
!************************************************
!* From the matrix of ΔΔGsoln, select the best
!* for each conformer and document which solvent
!* that corresponds to
!************************************************
implicit none
integer,intent(in) :: nall,ncol
real(wp),intent(in) :: data(ncol,nall)
real(wp),intent(out) :: gsoln(nall)
integer,intent(out) :: mapping(nall)
integer :: i,j,k,l,mink
real(wp) :: dum
mapping(:) = 0
gsoln(:) = huge(dum)
if (ncol < 3) then
!>--- ConfSolv should put out at least 3 csv columns. The first two are just IDs
write (stderr,'(a)') '**ERROR** dimension mismatch in ConfSolv data processing'
error stop
end if
do i = 1,nall
do j = 3,ncol
k = j-2
if (data(j,i) < gsoln(i)) then
mink = k
gsoln(i) = data(j,i)
end if
end do
mapping(i) = mink
end do
end subroutine confsolv_select_gsoln


subroutine confsolv_dump_gsoln(nall,ncol,gsoln,mapping,headers)
!****************************************************
!* Dump the selected ΔΔGsoln, and the corresponding
!* solvent for each conformer
!****************************************************
implicit none
integer,intent(in) :: nall,ncol
real(wp),intent(in) :: gsoln(nall)
integer,intent(in) :: mapping(nall)
character(len=*),intent(in) :: headers(ncol)
integer :: i,j,k,l,mink,ich
real(wp) :: dum
open(newunit=ich,file='confsolv.dat')
do i = 1,nall
k = mapping(i)+2
write(ich,'(f15.8,1x,a)') gsoln(i),trim(headers(k))
end do
close(ich)
end subroutine confsolv_dump_gsoln


!========================================================================================!
!========================================================================================!
end module ConfSolv_module
Expand All @@ -338,7 +429,7 @@ subroutine confsolv_request(ensname,nall,ncpus,gsoln,io)
!* nall - number of structures in ensemble
!* ncpus - number on cores to run on
!* gsoln - ΔΔGsoln for each structure
!* io - exit status
!* io - exit status
!***********************************************
use crest_parameters
use crest_data
Expand All @@ -359,103 +450,124 @@ subroutine confsolv_request(ensname,nall,ncpus,gsoln,io)
logical :: pr,wr
character(len=:),allocatable :: job
real(wp),allocatable :: column(:)
real(wp),allocatable :: data(:,:)
integer,allocatable :: mapping(:)
character(len=:),allocatable :: headers(:)
integer :: ncol,nrow
real(wp) :: avg

io = 0
gsoln(:) = 0.0_wp

!>--- setup
if (allocated(cs_pid).and.allocated(cs_port)) then
!> user-provided PID and port (no automatic teardown)
!> user-provided PID and port (no automatic teardown)
write (stdout,'(2x,a,i0,a,i0)') 'Looking for ConfSolv server (PID: ',cs_pid,') running at '//&
& 'http://localhost:',cs_port
!cs_teardown = .false.
!cs_teardown = .false.
else
!> fallback: automatic host (not recommended)
allocate(cs_pid,cs_port)
call cs_deploy()
!> fallback: automatic host (not recommended)
allocate (cs_pid,cs_port)
call cs_deploy()
end if
if (allocated(cs_param)) then
write (stdout,'(2x,a,/,3x,a)') 'pyTorch checkpoint files located at ',cs_param
else
write (stderr,*) '**ERROR** cannot run ConfSolv without defining checkpoint file location!'
error stop
end if
if (allocated(cs_solvent).and.allocated(cs_smiles)) then
write (stdout,'(2x,a,a,3a)') 'Requested ΔΔGsoln for ',cs_solvent,' (SMILES: ',trim(cs_smiles),')'
call cs_write_solvent_csv(cs_solvent,smiles=cs_smiles)
else if(allocated(cs_solvent))then
write (stdout,'(2x,a,a,a)') 'Requested ΔΔGsoln for ',cs_solvent,' (trying to find SMILES ...)'
call cs_write_solvent_csv(cs_solvent)
!> pass the user-defined solvents-csv, or do a single solvent
if (allocated(cs_solvfile)) then
write (stdout,'(2x,a,a)') 'Requested ΔΔGsoln for solvents in ',cs_solvfile
else
if (allocated(cs_solvent).and.allocated(cs_smiles)) then
write (stdout,'(2x,a,a,3a)') 'Requested ΔΔGsoln for ',cs_solvent,' (SMILES: ',trim(cs_smiles),')'
call cs_write_solvent_csv(cs_solvent,smiles=cs_smiles)
else if (allocated(cs_solvent)) then
write (stdout,'(2x,a,a,a)') 'Requested ΔΔGsoln for ',cs_solvent,' (trying to find SMILES ...)'
call cs_write_solvent_csv(cs_solvent)
end if
end if
write (stdout,'(2x,a,a)') 'Processing ensemble file ',trim(ensname)

!>---- creating the request configuration
write (stdout,'(2x,a)',advance='no') 'Writing config.toml file ...'
flush(stdout)
flush (stdout)
call cs_write_config(ensname,ncpus)
write(stdout,*) 'done.'

write (stdout,*) 'done.'

job = ''
job = trim(job)//' '//cs_bin//' -c config.toml'
!>----- this should only be called once:
if(.not.cs_setup)then
write(stdout,'(2x,a)',advance='no') 'Instructing ConfSolv model setup ...'
flush(stdout)
if (.not.cs_setup) then
write (stdout,'(2x,a)',advance='no') 'Instructing ConfSolv model setup ...'
flush (stdout)
call command(trim(job)//' -s >> confsolv.out 2>/dev/null',io)
if(io/=0)then
write(stdout,*)
write(stderr,'(a)')"**ERROR** failed request to ConfSolv server"
if (io /= 0) then
write (stdout,*)
write (stderr,'(a)') "**ERROR** failed request to ConfSolv server"
call cs_shutdown(io)
error stop
endif
end if
cs_setup = .true.
write(stdout,*) 'done.'
endif
write (stdout,*) 'done.'
end if

!>---- and then the actual evaluation
call remove('confsolv.csv')
call remove('confsolv_uncertainty.csv')
write(stdout,'(2x,a)',advance='no') 'Evaluation of ConfSolv D-MPNN ...'
flush(stdout)
write (stdout,'(2x,a)',advance='no') 'Evaluation of ConfSolv D-MPNN ...'
flush (stdout)
call command(trim(job)//' -r >> confsolv.out 2>/dev/null',io)
write(stdout,*) 'done.'
if(io/=0)then
write(stdout,*)
write(stderr,'(a)')"**ERROR** failed request to ConfSolv server"
write (stdout,*) 'done.'
if (io /= 0) then
write (stdout,*)
write (stderr,'(a)') "**ERROR** failed request to ConfSolv server"
call cs_shutdown(io)
error stop
endif
end if

!>--- read ΔΔGsoln
write(stdout,'(2x,a)',advance='no') 'Reading confsolv.csv ...'
flush(stdout)
call parse_csv_column_real('confsolv.csv',cs_solvent,column)
write(stdout,*) 'done.'
if(size(column,1) == nall)then
gsoln(:) = column(:)
write (stdout,'(2x,a)',advance='no') 'Reading confsolv.csv ...'
flush (stdout)
call parse_csv_allcolumns('confsolv.csv',data,cols=ncol,rows=nrow)
write (stdout,*) 'done.'
if (nrow == nall) then
allocate(mapping(nall))
call confsolv_select_gsoln(nall,ncol,data,gsoln,mapping)
call parse_csv_file_row('confsolv.csv',1,headers)
call confsolv_dump_gsoln(nall,ncol,gsoln,mapping,headers)
else
write(stdout,'(a)') '**ERROR** dimension mismatch in confsolv_request'
write (stdout,'(a)') '**ERROR** dimension mismatch in confsolv_request'
call cs_shutdown(io)
error stop
endif
end if

!>--- read uncertainty
write(stdout,'(2x,a)',advance='no') 'Reading confsolv_uncertainty.csv ...'
flush(stdout)
call parse_csv_column_real('confsolv_uncertainty.csv',cs_solvent,column)
write(stdout,*) 'done.'
if(size(column,1) == nall)then
avg = sum(column(:))/real(nall,wp)
write(stdout,'(2x,a,f25.15)') 'Average uncertainty of ConfSolv prediction:',avg
write (stdout,'(2x,a)',advance='no') 'Reading confsolv_uncertainty.csv ...'
flush (stdout)
call parse_csv_allcolumns('confsolv_uncertainty.csv',data)
write (stdout,*) 'done.'
if (size(data,2) == nall) then
avg = 0.0_wp
do i=1,nall
k=mapping(i) + 2
avg=avg+data(k,i)
enddo
avg = avg / real(nall,wp)
write (stdout,'(2x,a,f25.15)') 'Average uncertainty of ConfSolv prediction:',avg
else
write(stdout,'(a)') '**ERROR** dimension mismatch in confsolv_request'
write (stdout,'(a)') '**ERROR** dimension mismatch in confsolv_request'
call cs_shutdown(io)
error stop
endif
end if

if(allocated(column)) deallocate(column)
!call cs_shutdown2(i)

if (allocated(headers)) deallocate(headers)
if (allocated(data)) deallocate(data)
if (allocated(mapping)) deallocate(mapping)
if (allocated(column)) deallocate (column)
return
end subroutine confsolv_request

Expand Down
9 changes: 9 additions & 0 deletions src/algos/optimization.f90
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ subroutine crest_optimization(env,tim)
deallocate (grad)
!========================================================================================!
call tim%stop(14)

!========================================================================================!
!>--- append numerical hessian calculation
if( io == 0 .and. env%crest_ohess )then
call env%ref%load(molnew) !> load the optimized geometry
call crest_numhess(env,tim) !> run the numerical hessian
endif

!========================================================================================!
return
end subroutine crest_optimization

Expand Down
Loading
Loading