Skip to content

Commit

Permalink
initial checkin of conda recipe. a hard-coded path in build.sh so can…
Browse files Browse the repository at this point in the history
…'t immediately be run, in general
  • Loading branch information
loriab committed Mar 7, 2015
1 parent 88615cc commit 2050c9e
Showing 4 changed files with 310 additions and 0 deletions.
20 changes: 20 additions & 0 deletions conda-recipe/psi4/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
source /theoryfs2/common/software/intel2015/bin/compilervars.sh intel64
export TLIBC=/theoryfs2/ds/cdsgroup/psi4-compile/psi4cmake/psi4/glibc2.12rpm

mkdir build
cd build
cmake \
-DCMAKE_C_COMPILER=icc \
-DCMAKE_CXX_COMPILER=icpc \
-DCMAKE_Fortran_COMPILER=ifort \
-DPYTHON_INTERPRETER=${PYTHON} \
-DLIBINT_OPT_AM=5 \
-DENABLE_STATIC_LINKING=ON \
-DENABLE_XHOST=OFF \
-DCMAKE_BUILD_TYPE=release \
-DLIBC_INTERJECT="-L${TLIBC}/usr/lib64 ${TLIBC}/lib64/libpthread.so.0 ${TLIBC}/lib64/libc.so.6" \
-DCMAKE_INSTALL_PREFIX=${PREFIX} \
${SRC_DIR}
make -j3 # -j${CPU_COUNT}
make install

33 changes: 33 additions & 0 deletions conda-recipe/psi4/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package:
name: psi4
version: 0.0.10

source:
path: ../../
# git_url: ../../
# git_url: git@github.com:psi4/psi4public.git

build:
number: 2 [linux]
binary_relocation: true
binary_has_prefix_files:
- bin/psi4
has_prefix_files:
- share/psi/scripts/setenv.py

requirements:
build:
- cmake [linux]
- python
run:
- python

test:
commands:
- psi4 --help

about:
home: http://www.psicode.org
license: GNU General Public License v2 or later (GPLv2+)
summary: "open-source quantum chemistry"

7 changes: 7 additions & 0 deletions conda-recipe/psi4/post-link.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
set +x off
echo " Thank you for installing psi4. It is recommended that you run script"
echo " >>> ${PREFIX}/share/psi/scripts/setenv.py"
echo " to configure the runtime environment. Additional resources can be found at"
echo " Website: www.psicode.org"
echo " GitHub: https://github.com/psi4/psi4public/wiki"
echo " Manual: bit.ly/psi4manual"
250 changes: 250 additions & 0 deletions lib/scripts/setenv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
#!/usr/bin/env python
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.iteritems():
#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/psi'

# <<< 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.iteritems():
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.iteritems():
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.iteritems():
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 2050c9e

Please sign in to comment.