4
1
mirror of https://github.com/pfloos/quack synced 2024-12-22 12:23:50 +01:00

olympe: compil pyscf interface with ifort

This commit is contained in:
Abdallah Ammar 2024-08-27 20:13:10 +02:00
parent d8daed6ad4
commit bfc165fc5f
7 changed files with 128 additions and 52 deletions

5
.gitignore vendored
View File

@ -1,3 +1,8 @@
*.o *.o
*. *.
*.so *.so
*.mod
*.slurm
__pycache__
int/
.ninja_deps

24
config/env.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/env
CURRENT_HOSTNAME=$(hostname)
echo "Current machine: $CURRENT_HOSTNAME"
export QUACK_ROOT=/users/p18005/ammar/tmpdir/QuAcK
case $CURRENT_HOSTNAME in
*turpan*)
;;
*olympe*)
module purge
module load python/3.9.5
module load intel/18.2.199
export PATH=$PATH:/users/p18005/ammar/qp2/bin
export LD_LIBRARY_PATH=/usr/local/miniconda/4.9.2/envs/python-3.9.5/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$QUACK_ROOT/lib:$LD_LIBRARY_PATH
export PYTHONPATH=$QUACK_ROOT/src/pyscf:$PYTHONPATH
;;
*)
echo "Unknown hostname: $CURRENT_HOSTNAME. No modules loaded."
;;
esac

View File

@ -1,5 +1,7 @@
program QuAcK program QuAcK
use pyscf_module
implicit none implicit none
include 'parameters.h' include 'parameters.h'
@ -68,6 +70,27 @@ program QuAcK
logical :: dotest,doRtest,doUtest,doGtest logical :: dotest,doRtest,doUtest,doGtest
! test pyscf interface
character(len = 50) :: xyz, input_basis, unit_type
integer :: charge, multiplicity, cartesian
integer :: natoms, nalpha, nbeta
xyz = '/users/p18005/ammar/tmpdir/QuAcK/mol/H2O.xyz' // c_null_char
input_basis = 'sto-3g' // c_null_char
unit_type = 'Angstrom' // c_null_char
charge = 0
multiplicity = 1
cartesian = 0
call call_mol_prop(xyz, input_basis, charge, multiplicity, unit_type, cartesian, &
natoms, nalpha, nbeta, Enuc)
print *, "Number of atoms:", natoms
print *, "Number of alpha electrons:", nalpha
print *, "Number of beta electrons:", nbeta
print *, "Nuclear energy:", Enuc
stop
!-------------! !-------------!
! Hello World ! ! Hello World !
!-------------! !-------------!
@ -130,7 +153,8 @@ program QuAcK
! nBas = number of basis functions (see below) ! ! nBas = number of basis functions (see below) !
!------------------------------------------------! !------------------------------------------------!
call read_molecule(nNuc,nO,nC,nR) call read_molecule(nNuc, nO, nC, nR)
allocate(ZNuc(nNuc),rNuc(nNuc,ncart)) allocate(ZNuc(nNuc),rNuc(nNuc,ncart))
! Read geometry ! Read geometry

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os import os
import sys import sys
import subprocess
DEBUG=False DEBUG=False
try: try:
@ -46,7 +48,7 @@ FIX_ORDER_OF_LIBS=-Wl,--start-group
compile_ifort_linux = """ compile_ifort_linux = """
FC = ifort -mkl=parallel -qopenmp FC = ifort -mkl=parallel -qopenmp
AR = ar crs AR = ar crs
FFLAGS = -I$IDIR -g -Ofast -traceback FFLAGS = -I$IDIR -module $IDIR -g -Ofast -traceback
CC = icc CC = icc
CXX = icpc CXX = icpc
LAPACK= LAPACK=
@ -79,7 +81,7 @@ FIX_ORDER_OF_LIBS=-Wl,--start-group
compile_olympe = """ compile_olympe = """
FC = ifort -mkl=parallel -qopenmp FC = ifort -mkl=parallel -qopenmp
AR = ar crs AR = ar crs
FFLAGS = -I$IDIR -Ofast -traceback -xCORE-AVX512 FFLAGS = -I$IDIR -module $IDIR -Ofast -traceback -xCORE-AVX512
CC = icc CC = icc
CXX = icpc CXX = icpc
LAPACK= LAPACK=
@ -119,13 +121,25 @@ rule fc
""" """
rule_build_so = """ rule_cctoso = """
rule build_so rule cctoso
command = $AR $out $in command = $CC $CFLAGS $PYINC $in -o $out $LDFLAGS $PYLDF
description = Linking $out
""" """
def rule_cctoso_flags():
PYTHON_VERSION = "{}.{}".format(sys.version_info.major, sys.version_info.minor)
PYINC = subprocess.run(['python{}-config'.format(PYTHON_VERSION), '--includes'], stdout=subprocess.PIPE, text=True)
PYLDF = subprocess.run(['python{}-config'.format(PYTHON_VERSION), '--ldflags'], stdout=subprocess.PIPE, text=True)
return """
LDFLAGS = -shared -fPIC -L$LDIR -Wl,-rpath=$LDIR
PYINC = {}
PYLDF = {} -lpython{}
""".format(PYINC.stdout.strip(), PYLDF.stdout.strip(), PYTHON_VERSION)
rule_build_lib = """ rule_build_lib = """
rule build_lib rule build_lib
command = $AR $out $in command = $AR $out $in
@ -137,7 +151,7 @@ rule_build_exe = """
LIBS = {0} $LAPACK $STDCXX LIBS = {0} $LAPACK $STDCXX
rule build_exe rule build_exe
command = $FC $FIX_ORDER_OF_LIBS $in $LIBS -o $out command = $FC $FFLAGS $FIX_ORDER_OF_LIBS $PYINC $in $LIBS -o $out -L$LDIR -lpyscf_wrapper $PYLDF
pool = console pool = console
description = Linking $out description = Linking $out
@ -156,11 +170,12 @@ rule git_clone
""" """
build_in_so_dir = "\n".join([ build_in_py_dir = "\n".join([
header, header,
compiler, compiler,
rule_cctoso_flags(),
rule_cctoso,
rule_fortran, rule_fortran,
rule_build_so,
]) ])
build_in_lib_dir = "\n".join([ build_in_lib_dir = "\n".join([
@ -174,6 +189,7 @@ build_in_lib_dir = "\n".join([
build_in_exe_dir = "\n".join([ build_in_exe_dir = "\n".join([
header, header,
compiler, compiler,
rule_cctoso_flags(),
rule_fortran, rule_fortran,
rule_build_exe, rule_build_exe,
]) ])
@ -193,40 +209,14 @@ lib_dirs = list(filter(lambda x: os.path.isdir(x) and \
def create_makefile_in_pydir(directory): def create_makefile_in_pydir(directory):
PYTHON_VERSION = "{}.{}".format(sys.version_info.major, sys.version_info.minor)
CC = "gcc"
CCFLAGS = "$(shell python$(PYTHON_VERSION)-config --includes)"
LDFLAGS = "-shared -fPIC -L$(LDIR) -Wl,-rpath=$(LDIR) $(shell python$(PYTHON_VERSION)-config --ldflags)"
lib_pydir = "lib{}_wrapper.so".format(directory) lib_pydir = "lib{}_wrapper.so".format(directory)
c_pydir = "{}_wrapper.c".format(directory) c_pydir = "{}_wrapper.c".format(directory)
with open(os.path.join(directory, "build.ninja"), "w") as f:
f.write(build_in_py_dir)
f.write("build $LDIR/{}: cctoso {}\n\n".format(lib_pydir, c_pydir))
f.write("build {}_module.o: fc {}_module.f90\n".format(directory, directory))
with open(os.path.join(directory, "Makefile"), "w") as f:
f.write("# This file was automatically generated. Do not modify this file.\n\n")
f.write("IDIR = {}/include\n".format(QUACK_ROOT))
f.write("LDIR = {}/lib\n".format(QUACK_ROOT))
f.write("BDIR = {}/bin\n".format(QUACK_ROOT))
f.write("SDIR = {}/src\n\n".format(QUACK_ROOT))
f.write("CC = gcc\n")
f.write("PYTHON_VERSION = {}\n".format(PYTHON_VERSION))
f.write("CCFLAGS = {}\n".format(CCFLAGS))
f.write("LDFLAGS = {}\n\n".format(LDFLAGS))
f.write("TARGETS = $(LDIR)/{} {}_module.o\n\n".format(lib_pydir, directory))
f.write("all: $(TARGETS)\n\n")
f.write("$(LDIR)/{}: {}\n".format(lib_pydir, c_pydir))
f.write("\t$(CC) $(CCFLAGS) {} -o $(LDIR)/{} $(LDFLAGS)\n\n".format(c_pydir, lib_pydir))
f.write("{}_module.o: {}_module.f90\n".format(directory, directory))
f.write("\tgfortran -c {}_module.f90 -o {}_module.o -J.\n\n".format(directory, directory))
f.write(".PHONY: clean\n")
f.write("clean:\n")
f.write("\trm -f ../../lib/{} *.mod *.o\n\n".format(lib_pydir))
def create_ninja_in_libdir(directory): def create_ninja_in_libdir(directory):
@ -244,8 +234,8 @@ def create_ninja_in_libdir(directory):
obj_file = write_rule(f, filename, suffix) obj_file = write_rule(f, filename, suffix)
objects.append(obj_file) objects.append(obj_file)
objects = " ".join(objects) objects = " ".join(objects)
f.write("build $LDIR/lib{}.a: build_lib {}\n".format(directory, objects)) f.write("build $LDIR/{}.a: build_lib {}\n".format(directory, objects))
f.write("default $LDIR/lib{}.a\n".format(directory)) f.write("default $LDIR/{}.a\n".format(directory))
def create_ninja_in_exedir(directory): def create_ninja_in_exedir(directory):
@ -273,6 +263,8 @@ def create_ninja_in_exedir(directory):
def create_main_ninja(): def create_main_ninja():
libs = " ".join([ "$LDIR/{0}.a".format(x) for x in lib_dirs]) + " "+LIBS libs = " ".join([ "$LDIR/{0}.a".format(x) for x in lib_dirs]) + " "+LIBS
for py_dir in py_dirs:
libs += "$LDIR/lib{0}_wrapper.so".format(py_dir)
with open("build.ninja","w") as f: with open("build.ninja","w") as f:
f.write(build_main) f.write(build_main)
f.write(""" f.write("""
@ -290,6 +282,8 @@ rule build_lib
sources = [ "$SDIR/{0}/{1}".format(exe_dir,x) for x in os.listdir(exe_dir) ] sources = [ "$SDIR/{0}/{1}".format(exe_dir,x) for x in os.listdir(exe_dir) ]
sources = filter(lambda x: x.endswith(".f") or x.endswith(".f90"), sources) sources = filter(lambda x: x.endswith(".f") or x.endswith(".f90"), sources)
sources = " ".join(sources) sources = " ".join(sources)
for py_dir in py_dirs:
sources += " $SDIR/{0}/{0}_wrapper.c $SDIR/{0}/{0}_module.f90".format(py_dir)
f.write("build $BDIR/{0}: build_exe {1} {2}\n".format(exe_dir,libs,sources)) f.write("build $BDIR/{0}: build_exe {1} {2}\n".format(exe_dir,libs,sources))
f.write(" dir = {0} \n".format(exe_dir) ) f.write(" dir = {0} \n".format(exe_dir) )
@ -298,6 +292,10 @@ rule build_lib
sources = filter(lambda x: x.endswith(".f") or x.endswith(".f90"), sources) sources = filter(lambda x: x.endswith(".f") or x.endswith(".f90"), sources)
sources = " ".join(sources) sources = " ".join(sources)
f.write("build $LDIR/{0}.a: build_lib {1} \n dir = $SDIR/{0}\n".format(libname, sources)) f.write("build $LDIR/{0}.a: build_lib {1} \n dir = $SDIR/{0}\n".format(libname, sources))
for py_dir in py_dirs:
f.write("build $LDIR/lib{0}_wrapper.so: build_lib $SDIR/{0}/{0}_wrapper.c $SDIR/{0}/{0}_module.f90 \n dir = $SDIR/{0}\n".format(py_dir))
f.write("build all: phony $BDIR/QuAcK\n") f.write("build all: phony $BDIR/QuAcK\n")
f.write("default all\n") f.write("default all\n")
@ -318,6 +316,7 @@ debug:
def main(): def main():
for py_dir in py_dirs: for py_dir in py_dirs:
create_makefile_in_pydir(py_dir) create_makefile_in_pydir(py_dir)
create_makefile(py_dir)
for lib_dir in lib_dirs: for lib_dir in lib_dirs:
create_ninja_in_libdir(lib_dir) create_ninja_in_libdir(lib_dir)

View File

@ -1,11 +1,14 @@
import warnings
warnings.filterwarnings("ignore", category=UserWarning, module="numpy.core.getlimits")
import numpy as np import numpy as np
from pyscf import gto from pyscf import gto
def read_xyz(xyz): def read_xyz(xyz):
f = open(xyz + '.xyz', 'r') f = open(xyz, 'r')
lines = f.read().splitlines() lines = f.read().splitlines()

View File

@ -1,5 +1,8 @@
#include <Python.h> #include <Python.h>
#include <stdio.h> #include <stdio.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>
void call_mol_prop(const char *xyz, const char *input_basis, int charge, int multiplicity, void call_mol_prop(const char *xyz, const char *input_basis, int charge, int multiplicity,
@ -13,12 +16,27 @@ void call_mol_prop(const char *xyz, const char *input_basis, int charge, int mul
// Initialize the Python interpreter // Initialize the Python interpreter
Py_Initialize(); Py_Initialize();
printf("Python version: %s\n", Py_GetVersion()); //printf("Python version: %s\n", Py_GetVersion());
//printf("xyz: %s\n", xyz);
//printf("input_basis: %s\n", input_basis);
//printf("charge: %d\n", charge);
//printf("multiplicity: %d\n", multiplicity);
//printf("unit: %s\n", unit);
//printf("cartesian: %d\n", cartesian);
PyRun_SimpleString("import sys"); char exe_path[PATH_MAX];
PyRun_SimpleString("sys.path.append('.')"); ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
if (len != -1) {
// Import the Python module exe_path[len] = '\0'; // Null-terminate the string
dirname(exe_path); // Get directory part
char sys_path_command[PATH_MAX + 30];
snprintf(sys_path_command, sizeof(sys_path_command), "sys.path.append('%s')", exe_path);
PyRun_SimpleString("import sys");
PyRun_SimpleString(sys_path_command);
} else {
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('.')");
}
pName = PyUnicode_DecodeFSDefault("pyscf_module"); pName = PyUnicode_DecodeFSDefault("pyscf_module");
pModule = PyImport_Import(pName); pModule = PyImport_Import(pName);
Py_XDECREF(pName); Py_XDECREF(pName);

View File

@ -8,16 +8,19 @@ program test_python_call
integer :: natoms, nalpha, nbeta integer :: natoms, nalpha, nbeta
double precision :: Enuc double precision :: Enuc
xyz = "../../mol/H2O" xyz = '/users/p18005/ammar/tmpdir/QuAcK/mol/H2O.xyz' // C_NULL_CHAR
input_basis = "sto-3g" input_basis = 'sto-3g' // C_NULL_CHAR
charge = 0 charge = 0
multiplicity = 1 multiplicity = 1
unit_type = "Angstrom" unit_type = 'Angstrom' // C_NULL_CHAR
cartesian = 0 cartesian = 0
call call_mol_prop(trim(adjustl(xyz)), trim(adjustl(input_basis)), charge, multiplicity, trim(adjustl(unit_type)), cartesian, & call call_mol_prop(xyz, input_basis, charge, multiplicity, unit_type, cartesian, &
natoms, nalpha, nbeta, Enuc) natoms, nalpha, nbeta, Enuc)
!call call_mol_prop(trim(adjustl(xyz)), trim(adjustl(input_basis)), charge, multiplicity, trim(adjustl(unit_type)), cartesian, &
! natoms, nalpha, nbeta, Enuc)
print *, "Number of atoms:", natoms print *, "Number of atoms:", natoms
print *, "Number of alpha electrons:", nalpha print *, "Number of alpha electrons:", nalpha
print *, "Number of beta electrons:", nbeta print *, "Number of beta electrons:", nbeta