Skip to content

Commit

Permalink
add old setenv.py script
Browse files Browse the repository at this point in the history
  • Loading branch information
loriab committed Nov 26, 2018
1 parent 5d118ed commit 68a02be
Show file tree
Hide file tree
Showing 2 changed files with 281 additions and 0 deletions.
2 changes: 2 additions & 0 deletions scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
false negatives.
- `autofy.py` Replaces the type on the left-hand side of a `std::make_shared` call with `auto`.
The regex was fine-tuned using [regex101.com](https://regex101.com/)

- `examine_psi4_conda_env.py` was once in `GH/psi4/psi4:psi4/share/psi4/scripts/setenv.py` to test the environment after a conda install. It has some nice snippets for examining shell and libs but was mainly to convince the core devs that conda was sane. That mission was accomplished and script no longer maintained, so removing from main repo.
279 changes: 279 additions & 0 deletions scripts/examine_psi4_conda_env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
#!/usr/bin/env python

#
# @BEGIN LICENSE
#
# Psi4: an open-source quantum chemistry software package
#
# Copyright (c) 2007-2018 The Psi4 Developers.
#
# The copyrights for code used from other parties are included in
# the corresponding files.
#
# This file is part of Psi4.
#
# Psi4 is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, version 3.
#
# Psi4 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with Psi4; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# @END LICENSE
#

from __future__ import print_function
import os
import re
import sys
import platform
import subprocess
import collections

# [LAB, 6 Mar 2015]
# This script can be run with *prefix* variable set to install directory
# (a /bin/psi4 should be present) and used to assess the runtime
# environment, particularly the following. Designed to be run after
# download of binary distribution where conda will adjust *prefix*
# variable properly.
# * set PSI_SCRATCH
# * set PSIPATH
# * set psi4 in PATH
# * check linked libraries all found
# * for binary distributions
# * check libc compatibility
# * check right libpython linked

prefix = '/opt/anaconda1anaconda2anaconda3'
envarray = collections.OrderedDict()
# PYTHONPATH
# PYTHONHOME


def which(program, envvar='PATH', startswith=False):
"""Thanks, http://stackoverflow.com/a/377028"""
import os

def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
for path in os.environ[envvar].split(os.pathsep):
path = path.strip('"')
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file

return None

if platform.system() == 'Linux':

# <<< inspect libc >>>
libcdist, builtlibc = platform.libc_ver(executable=prefix + '/bin/psi4')
builtver = tuple(builtlibc.split('.'))
ans = subprocess.Popen('ldd --version', shell=True, stdout=subprocess.PIPE).stdout.read()
sysver = tuple(ans.split('\n')[0].split()[-1].split('.'))
print('\n System libc is version %s, and conda psi4 requires libc version %s or higher' %
('.'.join(sysver), '.'.join(builtver)), end='')
if (int(sysver[0]) < int(builtver[0])) or (int(sysver[1]) < int(builtver[1])):
print('\n ERROR: incompatible libc (%s < %s), no simple remedy.' % ('.'.join(sysver), '.'.join(builtver)))
sys.exit()
else:
print(' .... GOOD')

# <<< inspect psi4 library linkage >>>
quitafterstep = False
ans = subprocess.Popen('ldd %s' % (prefix + '/bin/psi4'), shell=True, stdout=subprocess.PIPE).stdout.read()
libraries = {}
for line in ans.splitlines():
match = re.match(r'\t(.*) => (.*) \(0x', line)
ack = re.match(r'\t(.*) => not found', line)
if match:
libraries[match.group(1)] = match.group(2)
if ack:
libraries[ack.group(1)] = None
print('\n Library dependencies of conda psi4 in current environment:\n%s' % (ans))

for name, fl in libraries.items():
#print('%30s %s' % (name, fl))
if fl is None:
print(' ERROR: needed library %s not found. no advice at this time.' % (name))
quitafterstep = True
if name.startswith('libpython'):
if 'conda' in fl:
print(' {} in conda distribution .... GOOD'.format(fl))
else:
print(' {} in system distribution .... FIXABLE'.format(fl))

if quitafterstep:
print('\n Your conda psi4 installation not expected to work.')
sys.exit()

# <<< inspect ld_library_path >>>
print("""
Psi4 uses Python to drive C++ code. This means that the executable was
linked against a python library at conda-build time, and psi4 finds a
python library and uses the python interpreter at runtime. For compatibility,
the executable must find the *conda* libpython at runtime rather than
any system libpython. Creating a conda environment containing python and
psi4 sets up the optimal conditions for library resolving. However, the
environment variable LD_LIBRARY_PATH has precedence over the conda
environment settings so that a libpython in a LD_LIBRARY_PATH directory
will likely cause psi4 to fail. Below scans your LD_LIBRARY_PATH for any
potentially meddlesome directories and suggests a safe truncated
LD_LIBRARY_PATH. Only you understand the delicate balance of entries in
this variable and runtimes requirements of all your programs, so you're
free to seek another solution.""")
temp = []
ans = os.getenv('LD_LIBRARY_PATH', None)
if ans is None:
print(' Environment variable LD_LIBRARY_PATH is {} .... GOOD'.format(ans))
envarray['LD_LIBRARY_PATH'] = ''
else:
print(' Environment variable LD_LIBRARY_PATH contains:')
ans = [os.path.abspath(os.path.expandvars(os.path.expanduser(p))) for p in ans.split(os.pathsep)]
for dpath in ans:
print(' {}'.format(dpath), end='')
try:
meddlesome = [fl for fl in os.listdir(dpath) if os.path.isfile(os.path.join(dpath, fl)) and fl.startswith('libpython')]
except OSError:
print(' .... FIXABLE')
print(' directory does not exist so discarding.')
else:
if meddlesome:
print(' .... FIXABLE')
print(' directory contains interfering {} so discarding.'.format(meddlesome[0]))
else:
print(' .... GOOD')
temp.append(dpath)

print(' Environment variable LD_LIBRARY_PATH contains:')
envarray['LD_LIBRARY_PATH'] = ':'.join(temp)
print(' {} .... GOOD'.format(envarray['LD_LIBRARY_PATH']))

# <<< inspect psi_scratch >>>
print("""
Quantum chemistry software writes many temporary files of large size.
The environment variable PSI_SCRATCH controls where these files go.
You must have write permissions to this location. If at *all* possible,
this location should be a local, not NFS-mounted, disk.""")
user_obedient = False
while not user_obedient:
ans = os.getenv('PSI_SCRATCH', None)
print(' Environment variable PSI_SCRATCH is %s' % (ans), end='')
if ans is not None and os.access(ans, os.W_OK | os.X_OK):
print(' .... GOOD')
user_obedient = True
else:
print(' .... FIXABLE')
if ans is not None and not os.access(ans, os.W_OK | os.X_OK):
print(' Path %s is not existant/writeable .... FIXABLE' % (ans))
print(' NOTE: if this is just a fixable permissions problem: cancel script, adjust permissions, re-run script.')
temp = raw_input(' TASK: specify a scratch directory.\n PSI_SCRATCH [/tmp] = ').strip()
if temp == '':
temp = '/tmp'
trial = os.path.abspath(os.path.expandvars(os.path.expanduser(temp)))
os.environ['PSI_SCRATCH'] = trial
envarray['PSI_SCRATCH'] = ans

# <<< inspect psipath and path >>>
print("""
Psi4 can use certain files outside its library for basis sets, efp
fragments, interfaced executables, etc. The environment variable
PSIPATH is a colon-separated list of directories to search for
these files, akin to PATH for executables.""")
ans = os.getenv('PSIPATH', None)
envarray['PSIPATH'] = '' if ans is None else ans
print(' Environment variable PSIPATH is {} .... GOOD'.format(ans))
for exe in ['dftd3', 'dmrcc', 'xcfour']:
if ans is None:
exeinpath = which(exe)
if exeinpath is not None:
temp = os.path.dirname(exeinpath)
print(' Executable {} found in PATH so adding {} to PSIPATH .... GOOD'.format(exe, temp))
envarray['PSIPATH'] += ':' + temp
else:
exeinpsipath = which(exe, envvar='PSIPATH')
if exeinpsipath is None:
exeinpath = which(exe)
if exeinpath is not None:
temp = os.path.dirname(exeinpath)
print(' Executable {} found in PATH so adding {} to PSIPATH .... GOOD'.format(exe, temp))
envarray['PSIPATH'] += ':' + temp
else:
print(' Executable {} found in PSIPATH .... GOOD'.format(exe))
temp = raw_input(' TASK: specify additional paths for auxiliary items (colon separated).\n PSIPATH [empty] += ').strip()
envarray['PSIPATH'] += ':' + temp
print(' Environment variable PSIPATH is %s .... GOOD' % (envarray['PSIPATH']))

# <<< inspect path to psi4 >>>
print()
psi4inpath = which('psi4')
if psi4inpath is None:
print(' Psi4 executable not in PATH .... FIXABLE')
envarray['PATH'] = prefix + '/bin:' + os.getenv('PATH', '')
else:
temp = os.path.dirname(psi4inpath)
if temp != (prefix + '/bin'):
print(' Wrong psi4 executable in PATH .... FIXABLE')
envarray['PATH'] = prefix + '/bin:' + os.getenv('PATH', '')
else:
print(' Psi4 executable in PATH .... GOOD')
envarray['PSIDATADIR'] = prefix + '/share/psi4'

# <<< write out environment files >>>
print("""
The runtime environment changes from this script are written to files
"psi4setup.sh" and "psi4setup.csh" for bash- and csh-type shells,
respectively. These files are echoed below.""")
setup = prefix + '/share/psi/scripts/psi4setup.sh'
with open(setup, 'w') as handle:
for ev, val in envarray.items():
handle.write("""export {}={}\n""".format(ev.upper(), val))
print("""\n bash-prompt>>> source {}""".format(setup))
os.system('cat {}'.format(setup, 'sh'))
setup = prefix + '/share/psi/scripts/psi4setup.csh'
with open(setup, 'w') as handle:
for ev, val in envarray.items():
handle.write("""setenv {} {}\n""".format(ev.upper(), val))
print("""\n csh-prompt>>> source {}""".format(setup))
os.system('cat {}'.format(setup))
with open('setenvtest.in', 'w') as handle:
handle.write("""
# Any line starting with the # character is a comment line
#! Sample HF/cc-pVDZ H2O computation
memory 250 mb
molecule h2o {
O
H 1 0.96
H 1 0.96 2 104.5
}
set basis cc-pVDZ
energy('scf')
compare_values(-76.0266327341067125, get_variable('SCF TOTAL ENERGY'), 6, 'SCF energy') #TEST
""")

# <<< test the environment >>>
lenv = os.environ.copy()
for ev, val in envarray.items():
lenv[ev.upper()] = val
print("""
Your shell environment has not been changed by this script. A psi4 test
job will be run under the environment conditions suggested by this script.""")
ans = subprocess.Popen('psi4 setenvtest.in'.format(prefix), shell=True, stdout=subprocess.PIPE, env=lenv).stdout.read()
print(ans)

0 comments on commit 68a02be

Please sign in to comment.