-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathsetup.py
More file actions
143 lines (116 loc) · 4.13 KB
/
Copy pathsetup.py
File metadata and controls
143 lines (116 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
from glob import glob
import os
import sys
import subprocess
from setuptools import setup
import tempfile
from pybind11.setup_helpers import Pybind11Extension, build_ext
try:
from distutils.errors import CCompilerError
except ImportError:
from setuptools._distutils.errors import CCompilerError
__version__ = "4.0.3"
def __read__(file_name):
return open(os.path.join(os.path.dirname(__file__), file_name)).read()
#Try to find Homebrew's libomp on macOS
def get_homebrew_libomp_prefix():
try:
result = subprocess.run(
["brew", "--prefix", "libomp"],
capture_output=True, text=True, timeout=10)
if result.returncode == 0:
prefix = result.stdout.strip()
if os.path.isdir(prefix):
return prefix
except (FileNotFoundError, subprocess.TimeoutExpired):
pass
return None
#Custom build class that provides additional checks for OpenMP
class custom_build_ext(build_ext):
#Compile a test program to determine if C++ compiler supports OpenMP
def check_openmp_support(self):
os.makedirs(self.build_temp, exist_ok=True)
#Determine platform-specific OpenMP flags
if sys.platform == "darwin":
libomp_prefix = get_homebrew_libomp_prefix()
if libomp_prefix:
print("Found Homebrew libomp at: " + libomp_prefix)
self._omp_compile_flags = [
"-Xclang", "-fopenmp",
"-I" + libomp_prefix + "/include"]
self._omp_link_flags = [
"-L" + libomp_prefix + "/lib",
"-Wl,-rpath," + libomp_prefix + "/lib",
"-lomp"]
else:
print("Homebrew libomp not found, OpenMP will be disabled")
return False
else:
self._omp_compile_flags = ["-fopenmp"]
self._omp_link_flags = ["-fopenmp"]
with tempfile.NamedTemporaryFile(mode='w',
dir=self.build_temp,
prefix='openmptest',
suffix='.cpp') as srcfile:
print("Checking if compiler supports OpenMP")
srcfile.write("""
#include <omp.h>
int omp_test()
{
#pragma omp parallel for
for (int i=0; i<5; ++i);
return omp_get_num_threads();
}
""")
srcfile.flush()
try:
objects = self.compiler.compile([srcfile.name],
extra_postargs=self._omp_compile_flags,
output_dir="/")
except CCompilerError:
print("Compiler does not support OpenMP")
return False
else:
print("Enabling OpenMP support")
for o in objects:
os.remove(o)
return True
#Add OpenMP compiler and linker flags if necessary
def build_extensions(self):
use_openmp = self.check_openmp_support()
if use_openmp:
for ext in self.extensions:
if not ext.extra_compile_args:
ext.extra_compile_args = []
ext.extra_compile_args.extend(self._omp_compile_flags)
if not ext.extra_link_args:
ext.extra_link_args = []
ext.extra_link_args.extend(self._omp_link_flags)
#Call the build function from the parent class
build_ext.build_extensions(self)
ext_modules = [
Pybind11Extension(
"pyfastchem",
sorted(glob("fastchem_src/*.cpp") +
glob("fastchem_src/elements/*.cpp") +
glob("fastchem_src/gas_phase/*.cpp") +
glob("fastchem_src/condensed_phase/*.cpp") +
glob("python/fastchem_python_wrapper.cpp")),
define_macros = [('_SETUP_PY', '1')],
cxx_std = 17,
language ='c++',
),
]
setup(
name = "pyfastchem",
python_requires = ">=3.10",
description = "FastChem, an ultra-fast equilibrium chemistry",
long_description=__read__('README.md'),
long_description_content_type="text/markdown",
author = "Daniel Kitzmann, Joachim Stock, Brett Morris",
license = "GPL 3.0",
url = "https://github.com/NewStrangeWorlds/FastChem",
version = __version__,
ext_modules = ext_modules,
cmdclass = {"build_ext": custom_build_ext}
)