Skip to content

Commit 2050c9e

Browse files
committed
initial checkin of conda recipe. a hard-coded path in build.sh so can't immediately be run, in general
1 parent 88615cc commit 2050c9e

File tree

4 files changed

+310
-0
lines changed

4 files changed

+310
-0
lines changed

conda-recipe/psi4/build.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
source /theoryfs2/common/software/intel2015/bin/compilervars.sh intel64
2+
export TLIBC=/theoryfs2/ds/cdsgroup/psi4-compile/psi4cmake/psi4/glibc2.12rpm
3+
4+
mkdir build
5+
cd build
6+
cmake \
7+
-DCMAKE_C_COMPILER=icc \
8+
-DCMAKE_CXX_COMPILER=icpc \
9+
-DCMAKE_Fortran_COMPILER=ifort \
10+
-DPYTHON_INTERPRETER=${PYTHON} \
11+
-DLIBINT_OPT_AM=5 \
12+
-DENABLE_STATIC_LINKING=ON \
13+
-DENABLE_XHOST=OFF \
14+
-DCMAKE_BUILD_TYPE=release \
15+
-DLIBC_INTERJECT="-L${TLIBC}/usr/lib64 ${TLIBC}/lib64/libpthread.so.0 ${TLIBC}/lib64/libc.so.6" \
16+
-DCMAKE_INSTALL_PREFIX=${PREFIX} \
17+
${SRC_DIR}
18+
make -j3 # -j${CPU_COUNT}
19+
make install
20+

conda-recipe/psi4/meta.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package:
2+
name: psi4
3+
version: 0.0.10
4+
5+
source:
6+
path: ../../
7+
# git_url: ../../
8+
# git_url: git@github.com:psi4/psi4public.git
9+
10+
build:
11+
number: 2 [linux]
12+
binary_relocation: true
13+
binary_has_prefix_files:
14+
- bin/psi4
15+
has_prefix_files:
16+
- share/psi/scripts/setenv.py
17+
18+
requirements:
19+
build:
20+
- cmake [linux]
21+
- python
22+
run:
23+
- python
24+
25+
test:
26+
commands:
27+
- psi4 --help
28+
29+
about:
30+
home: http://www.psicode.org
31+
license: GNU General Public License v2 or later (GPLv2+)
32+
summary: "open-source quantum chemistry"
33+

conda-recipe/psi4/post-link.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
set +x off
2+
echo " Thank you for installing psi4. It is recommended that you run script"
3+
echo " >>> ${PREFIX}/share/psi/scripts/setenv.py"
4+
echo " to configure the runtime environment. Additional resources can be found at"
5+
echo " Website: www.psicode.org"
6+
echo " GitHub: https://github.com/psi4/psi4public/wiki"
7+
echo " Manual: bit.ly/psi4manual"

lib/scripts/setenv.py

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
#!/usr/bin/env python
2+
from __future__ import print_function
3+
import os
4+
import re
5+
import sys
6+
import platform
7+
import subprocess
8+
import collections
9+
10+
# [LAB, 6 Mar 2015]
11+
# This script can be run with *prefix* variable set to install directory
12+
# (a /bin/psi4 should be present) and used to assess the runtime
13+
# environment, particularly the following. Designed to be run after
14+
# download of binary distribution where conda will adjust *prefix*
15+
# variable properly.
16+
# * set PSI_SCRATCH
17+
# * set PSIPATH
18+
# * set psi4 in PATH
19+
# * check linked libraries all found
20+
# * for binary distributions
21+
# * check libc compatibility
22+
# * check right libpython linked
23+
24+
prefix = '/opt/anaconda1anaconda2anaconda3'
25+
envarray = collections.OrderedDict()
26+
# PYTHONPATH
27+
# PYTHONHOME
28+
29+
30+
def which(program, envvar='PATH', startswith=False):
31+
"""Thanks, http://stackoverflow.com/a/377028"""
32+
import os
33+
34+
def is_exe(fpath):
35+
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
36+
37+
fpath, fname = os.path.split(program)
38+
if fpath:
39+
if is_exe(program):
40+
return program
41+
else:
42+
for path in os.environ[envvar].split(os.pathsep):
43+
path = path.strip('"')
44+
exe_file = os.path.join(path, program)
45+
if is_exe(exe_file):
46+
return exe_file
47+
48+
return None
49+
50+
if platform.system() == 'Linux':
51+
52+
# <<< inspect libc >>>
53+
libcdist, builtlibc = platform.libc_ver(executable=prefix + '/bin/psi4')
54+
builtver = tuple(builtlibc.split('.'))
55+
ans = subprocess.Popen('ldd --version', shell=True, stdout=subprocess.PIPE).stdout.read()
56+
sysver = tuple(ans.split('\n')[0].split()[-1].split('.'))
57+
print('\n System libc is version %s, and conda psi4 requires libc version %s or higher' %
58+
('.'.join(sysver), '.'.join(builtver)), end='')
59+
if (int(sysver[0]) < int(builtver[0])) or (int(sysver[1]) < int(builtver[1])):
60+
print('\n ERROR: incompatible libc (%s < %s), no simple remedy.' % ('.'.join(sysver), '.'.join(builtver)))
61+
sys.exit()
62+
else:
63+
print(' .... GOOD')
64+
65+
# <<< inspect psi4 library linkage >>>
66+
quitafterstep = False
67+
ans = subprocess.Popen('ldd %s' % (prefix + '/bin/psi4'), shell=True, stdout=subprocess.PIPE).stdout.read()
68+
libraries = {}
69+
for line in ans.splitlines():
70+
match = re.match(r'\t(.*) => (.*) \(0x', line)
71+
ack = re.match(r'\t(.*) => not found', line)
72+
if match:
73+
libraries[match.group(1)] = match.group(2)
74+
if ack:
75+
libraries[ack.group(1)] = None
76+
print('\n Library dependencies of conda psi4 in current environment:\n%s' % (ans))
77+
78+
for name, fl in libraries.iteritems():
79+
#print('%30s %s' % (name, fl))
80+
if fl is None:
81+
print(' ERROR: needed library %s not found. no advice at this time.' % (name))
82+
quitafterstep = True
83+
if name.startswith('libpython'):
84+
if 'conda' in fl:
85+
print(' {} in conda distribution .... GOOD'.format(fl))
86+
else:
87+
print(' {} in system distribution .... FIXABLE'.format(fl))
88+
89+
if quitafterstep:
90+
print('\n Your conda psi4 installation not expected to work.')
91+
sys.exit()
92+
93+
# <<< inspect ld_library_path >>>
94+
print("""
95+
Psi4 uses Python to drive C++ code. This means that the executable was
96+
linked against a python library at conda-build time, and psi4 finds a
97+
python library and uses the python interpreter at runtime. For compatibility,
98+
the executable must find the *conda* libpython at runtime rather than
99+
any system libpython. Creating a conda environment containing python and
100+
psi4 sets up the optimal conditions for library resolving. However, the
101+
environment variable LD_LIBRARY_PATH has precedence over the conda
102+
environment settings so that a libpython in a LD_LIBRARY_PATH directory
103+
will likely cause psi4 to fail. Below scans your LD_LIBRARY_PATH for any
104+
potentially meddlesome directories and suggests a safe truncated
105+
LD_LIBRARY_PATH. Only you understand the delicate balance of entries in
106+
this variable and runtimes requirements of all your programs, so you're
107+
free to seek another solution.""")
108+
temp = []
109+
ans = os.getenv('LD_LIBRARY_PATH', None)
110+
if ans is None:
111+
print(' Environment variable LD_LIBRARY_PATH is {} .... GOOD'.format(ans))
112+
envarray['LD_LIBRARY_PATH'] = ''
113+
else:
114+
print(' Environment variable LD_LIBRARY_PATH contains:')
115+
ans = [os.path.abspath(os.path.expandvars(os.path.expanduser(p))) for p in ans.split(os.pathsep)]
116+
for dpath in ans:
117+
print(' {}'.format(dpath), end='')
118+
try:
119+
meddlesome = [fl for fl in os.listdir(dpath) if os.path.isfile(os.path.join(dpath, fl)) and fl.startswith('libpython')]
120+
except OSError:
121+
print(' .... FIXABLE')
122+
print(' directory does not exist so discarding.')
123+
else:
124+
if meddlesome:
125+
print(' .... FIXABLE')
126+
print(' directory contains interfering {} so discarding.'.format(meddlesome[0]))
127+
else:
128+
print(' .... GOOD')
129+
temp.append(dpath)
130+
131+
print(' Environment variable LD_LIBRARY_PATH contains:')
132+
envarray['LD_LIBRARY_PATH'] = ':'.join(temp)
133+
print(' {} .... GOOD'.format(envarray['LD_LIBRARY_PATH']))
134+
135+
# <<< inspect psi_scratch >>>
136+
print("""
137+
Quantum chemistry software writes many temporary files of large size.
138+
The environment variable PSI_SCRATCH controls where these files go.
139+
You must have write permissions to this location. If at *all* possible,
140+
this location should be a local, not NFS-mounted, disk.""")
141+
user_obedient = False
142+
while not user_obedient:
143+
ans = os.getenv('PSI_SCRATCH', None)
144+
print(' Environment variable PSI_SCRATCH is %s' % (ans), end='')
145+
if ans is not None and os.access(ans, os.W_OK | os.X_OK):
146+
print(' .... GOOD')
147+
user_obedient = True
148+
else:
149+
print(' .... FIXABLE')
150+
if ans is not None and not os.access(ans, os.W_OK | os.X_OK):
151+
print(' Path %s is not existant/writeable .... FIXABLE' % (ans))
152+
print(' NOTE: if this is just a fixable permissions problem: cancel script, adjust permissions, re-run script.')
153+
temp = raw_input(' TASK: specify a scratch directory.\n PSI_SCRATCH [/tmp] = ').strip()
154+
if temp == '':
155+
temp = '/tmp'
156+
trial = os.path.abspath(os.path.expandvars(os.path.expanduser(temp)))
157+
os.environ['PSI_SCRATCH'] = trial
158+
envarray['PSI_SCRATCH'] = ans
159+
160+
# <<< inspect psipath and path >>>
161+
print("""
162+
Psi4 can use certain files outside its library for basis sets, efp
163+
fragments, interfaced executables, etc. The environment variable
164+
PSIPATH is a colon-separated list of directories to search for
165+
these files, akin to PATH for executables.""")
166+
ans = os.getenv('PSIPATH', None)
167+
envarray['PSIPATH'] = '' if ans is None else ans
168+
print(' Environment variable PSIPATH is {} .... GOOD'.format(ans))
169+
for exe in ['dftd3', 'dmrcc', 'xcfour']:
170+
if ans is None:
171+
exeinpath = which(exe)
172+
if exeinpath is not None:
173+
temp = os.path.dirname(exeinpath)
174+
print(' Executable {} found in PATH so adding {} to PSIPATH .... GOOD'.format(exe, temp))
175+
envarray['PSIPATH'] += ':' + temp
176+
else:
177+
exeinpsipath = which(exe, envvar='PSIPATH')
178+
if exeinpsipath is None:
179+
exeinpath = which(exe)
180+
if exeinpath is not None:
181+
temp = os.path.dirname(exeinpath)
182+
print(' Executable {} found in PATH so adding {} to PSIPATH .... GOOD'.format(exe, temp))
183+
envarray['PSIPATH'] += ':' + temp
184+
else:
185+
print(' Executable {} found in PSIPATH .... GOOD'.format(exe))
186+
temp = raw_input(' TASK: specify additional paths for auxiliary items (colon separated).\n PSIPATH [empty] += ').strip()
187+
envarray['PSIPATH'] += ':' + temp
188+
print(' Environment variable PSIPATH is %s .... GOOD' % (envarray['PSIPATH']))
189+
190+
# <<< inspect path to psi4 >>>
191+
print()
192+
psi4inpath = which('psi4')
193+
if psi4inpath is None:
194+
print(' Psi4 executable not in PATH .... FIXABLE')
195+
envarray['PATH'] = prefix + '/bin:' + os.getenv('PATH', '')
196+
else:
197+
temp = os.path.dirname(psi4inpath)
198+
if temp != (prefix + '/bin'):
199+
print(' Wrong psi4 executable in PATH .... FIXABLE')
200+
envarray['PATH'] = prefix + '/bin:' + os.getenv('PATH', '')
201+
else:
202+
print(' Psi4 executable in PATH .... GOOD')
203+
envarray['PSIDATADIR'] = prefix + '/share/psi'
204+
205+
# <<< write out environment files >>>
206+
print("""
207+
The runtime environment changes from this script are written to files
208+
"psi4setup.sh" and "psi4setup.csh" for bash- and csh-type shells,
209+
respectively. These files are echoed below.""")
210+
setup = prefix + '/share/psi/scripts/psi4setup.sh'
211+
with open(setup, 'w') as handle:
212+
for ev, val in envarray.iteritems():
213+
handle.write("""export {}={}\n""".format(ev.upper(), val))
214+
print("""\n bash-prompt>>> source {}""".format(setup))
215+
os.system('cat {}'.format(setup, 'sh'))
216+
setup = prefix + '/share/psi/scripts/psi4setup.csh'
217+
with open(setup, 'w') as handle:
218+
for ev, val in envarray.iteritems():
219+
handle.write("""setenv {} {}\n""".format(ev.upper(), val))
220+
print("""\n csh-prompt>>> source {}""".format(setup))
221+
os.system('cat {}'.format(setup))
222+
with open('setenvtest.in', 'w') as handle:
223+
handle.write("""
224+
# Any line starting with the # character is a comment line
225+
#! Sample HF/cc-pVDZ H2O computation
226+
227+
memory 250 mb
228+
229+
molecule h2o {
230+
O
231+
H 1 0.96
232+
H 1 0.96 2 104.5
233+
}
234+
235+
set basis cc-pVDZ
236+
energy('scf')
237+
238+
compare_values(-76.0266327341067125, get_variable('SCF TOTAL ENERGY'), 6, 'SCF energy') #TEST
239+
240+
""")
241+
242+
# <<< test the environment >>>
243+
lenv = os.environ.copy()
244+
for ev, val in envarray.iteritems():
245+
lenv[ev.upper()] = val
246+
print("""
247+
Your shell environment has not been changed by this script. A psi4 test
248+
job will be run under the environment conditions suggested by this script.""")
249+
ans = subprocess.Popen('psi4 setenvtest.in'.format(prefix), shell=True, stdout=subprocess.PIPE, env=lenv).stdout.read()
250+
print(ans)

0 commit comments

Comments
 (0)