1 |
commit: fde06e299589c2abc82df5768773fb3d3cc0befd |
2 |
Author: Alessandro Barbieri <lssndrbarbieri <AT> gmail <DOT> com> |
3 |
AuthorDate: Sun Dec 27 11:20:02 2020 +0000 |
4 |
Commit: Alessandro Barbieri <lssndrbarbieri <AT> gmail <DOT> com> |
5 |
CommitDate: Sun Dec 27 11:20:02 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/proj/guru.git/commit/?id=fde06e29 |
7 |
|
8 |
sys-cluster/dlb: fix python installation |
9 |
|
10 |
thanks @telans |
11 |
|
12 |
Package-Manager: Portage-3.0.12, Repoman-3.0.2 |
13 |
Signed-off-by: Alessandro Barbieri <lssndrbarbieri <AT> gmail.com> |
14 |
|
15 |
sys-cluster/dlb/dlb-2.1-r1.ebuild | 73 +++++++ |
16 |
sys-cluster/dlb/files/dlb-2.1-pygen-python3.patch | 222 ++++++++++++++++++++++ |
17 |
2 files changed, 295 insertions(+) |
18 |
|
19 |
diff --git a/sys-cluster/dlb/dlb-2.1-r1.ebuild b/sys-cluster/dlb/dlb-2.1-r1.ebuild |
20 |
new file mode 100644 |
21 |
index 00000000..456d8c19 |
22 |
--- /dev/null |
23 |
+++ b/sys-cluster/dlb/dlb-2.1-r1.ebuild |
24 |
@@ -0,0 +1,73 @@ |
25 |
+# Copyright 1999-2020 Gentoo Authors |
26 |
+# Distributed under the terms of the GNU General Public License v2 |
27 |
+ |
28 |
+EAPI=7 |
29 |
+ |
30 |
+PYTHON_COMPAT=( python3_{7..9} ) |
31 |
+PYTHON_REQ_USE="tk" |
32 |
+ |
33 |
+inherit autotools python-single-r1 |
34 |
+ |
35 |
+DESCRIPTION="Dynamically react to application imbalance by modifying the number of resources" |
36 |
+HOMEPAGE="https://github.com/bsc-pm/dlb" |
37 |
+SRC_URI="https://github.com/bsc-pm/dlb/archive/v${PV}.tar.gz -> ${P}.tar.gz" |
38 |
+ |
39 |
+LICENSE="LGPL-3" |
40 |
+SLOT="0" |
41 |
+KEYWORDS="~amd64" |
42 |
+IUSE="hwloc instrumentation mpi openmp" |
43 |
+ |
44 |
+DEPEND=" |
45 |
+ hwloc? ( sys-apps/hwloc ) |
46 |
+ mpi? ( virtual/mpi ) |
47 |
+" |
48 |
+#instrumentation ( sys-cluster/extrae ) |
49 |
+RDEPEND=" |
50 |
+ ${DEPEND} |
51 |
+ dev-lang/tk |
52 |
+ $(python_gen_cond_dep 'dev-python/matplotlib[tk,${PYTHON_USEDEP}]') |
53 |
+" |
54 |
+ |
55 |
+PATCHES=( "${FILESDIR}/${P}-pygen-python3.patch" ) |
56 |
+ |
57 |
+src_prepare() { |
58 |
+ default |
59 |
+ sed -e "s|chmod +x \$(|chmod +x ${ED}/\$(|g" -i Makefile.am || die |
60 |
+ |
61 |
+ # Python3 fixes |
62 |
+ sed -e "s/Tkinter/tkinter/" \ |
63 |
+ -e "s/import ttk/from tkinter import ttk/" \ |
64 |
+ -e "s/import tkMessageBox/from tkinter import messagebox/" \ |
65 |
+ -e "s/tkMessageBox/messagebox/g" \ |
66 |
+ -i scripts/viewer/dlb_cpu_usage.in || die |
67 |
+ |
68 |
+ sed -e "s/Tkinter/tkinter/" \ |
69 |
+ -e "s/import ttk/from tkinter import ttk/" \ |
70 |
+ -e "s/, NavigationToolbar2TkAgg//" \ |
71 |
+ -e "/FigureCanvasTkAgg$/a from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT" \ |
72 |
+ -e "s/NavigationToolbar2TkAgg/NavigationToolbar2QT/g" \ |
73 |
+ -i scripts/viewer/dlb_viewer.py.in || die |
74 |
+ |
75 |
+ sed -e "s|lib/|$(get_libdir)/|" -i scripts/viewer/dlb_wrapper.py || die |
76 |
+ sed -e "s|Tkinter|tkinter|" -i scripts/viewer/progressmeter.py || die |
77 |
+ |
78 |
+ eautoreconf |
79 |
+} |
80 |
+ |
81 |
+src_configure() { |
82 |
+ local myconf=( |
83 |
+ --disable-static |
84 |
+ --enable-shared |
85 |
+ --with-pic |
86 |
+ $(use_enable instrumentation) |
87 |
+ $(use_enable openmp) |
88 |
+ $(use_with hwloc) |
89 |
+ $(use_with mpi) |
90 |
+ ) |
91 |
+ econf "${myconf[@]}" |
92 |
+} |
93 |
+ |
94 |
+src_install() { |
95 |
+ default |
96 |
+ find "${D}" -name '*.la' -delete || die |
97 |
+} |
98 |
|
99 |
diff --git a/sys-cluster/dlb/files/dlb-2.1-pygen-python3.patch b/sys-cluster/dlb/files/dlb-2.1-pygen-python3.patch |
100 |
new file mode 100644 |
101 |
index 00000000..4b345d85 |
102 |
--- /dev/null |
103 |
+++ b/sys-cluster/dlb/files/dlb-2.1-pygen-python3.patch |
104 |
@@ -0,0 +1,222 @@ |
105 |
+From 62597a9b65bc51759568278561e415717e1e6ed4 Mon Sep 17 00:00:00 2001 |
106 |
+From: Victor Lopez <victor.lopez@×××.es> |
107 |
+Date: Tue, 17 Nov 2020 15:24:14 +0100 |
108 |
+Subject: [PATCH] Run pygen script with either python2 or python3 |
109 |
+ |
110 |
+--- |
111 |
+ Makefile.am | 7 +- |
112 |
+ configure.ac | 2 + |
113 |
+ scripts/pygen.py3 | 166 ++++++++++++++++++++++++++++++++++++++++++++++ |
114 |
+ 3 files changed, 174 insertions(+), 1 deletion(-) |
115 |
+ create mode 100755 scripts/pygen.py3 |
116 |
+ |
117 |
+diff --git a/Makefile.am b/Makefile.am |
118 |
+index 7d575e7..b274011 100644 |
119 |
+--- a/Makefile.am |
120 |
++++ b/Makefile.am |
121 |
+@@ -83,7 +83,11 @@ nodist_include_HEADERS = src/LB_MPI/MPI_interface.h \ |
122 |
+ #******************************************************************************** |
123 |
+ # Built Sources |
124 |
+ #******************************************************************************** |
125 |
+-MPI_GENERATOR = $(top_srcdir)/scripts/pygen.py |
126 |
++if PYTHON3 |
127 |
++MPI_GENERATOR = $(PYTHON) $(top_srcdir)/scripts/pygen.py3 |
128 |
++else |
129 |
++MPI_GENERATOR = $(PYTHON) $(top_srcdir)/scripts/pygen.py |
130 |
++endif |
131 |
+ MPICALLS_DB = $(top_srcdir)/src/LB_MPI/mpicalls.json |
132 |
+ EXTRA_DIST += src/LB_MPI/mpicalls.json |
133 |
+ |
134 |
+@@ -739,6 +743,7 @@ EXTRA_DIST += \ |
135 |
+ scripts/run_with_dlb.sh.in \ |
136 |
+ scripts/dlb.spec \ |
137 |
+ scripts/pygen.py \ |
138 |
++ scripts/pygen.py3 \ |
139 |
+ scripts/viewer/dlb_cpu_usage.in \ |
140 |
+ scripts/viewer/dlb_viewer.py.in \ |
141 |
+ $(DEBIAN_EXTRA) \ |
142 |
+diff --git a/configure.ac b/configure.ac |
143 |
+index 2200d23..8a587b9 100644 |
144 |
+--- a/configure.ac |
145 |
++++ b/configure.ac |
146 |
+@@ -235,6 +235,8 @@ AC_SUBST([INSTR_DEBUG_CPPFLAGS]) |
147 |
+ AM_PATH_PYTHON |
148 |
+ AX_COMPARE_VERSION([$PYTHON_VERSION], [ge], [2.7], [lit=yes], [lit=no]) |
149 |
+ AM_CONDITIONAL([LIT_SUPPORT], [test "x$lit" = xyes]) |
150 |
++AX_COMPARE_VERSION([$PYTHON_VERSION], [ge], [3.0], [python3=yes], [python3=no]) |
151 |
++AM_CONDITIONAL([PYTHON3], [test "x$python3" = xyes]) |
152 |
+ |
153 |
+ # check for OpenMP availability |
154 |
+ AC_OPENMP |
155 |
+diff --git a/scripts/pygen.py3 b/scripts/pygen.py3 |
156 |
+new file mode 100755 |
157 |
+index 0000000..9748d96 |
158 |
+--- /dev/null |
159 |
++++ b/scripts/pygen.py3 |
160 |
+@@ -0,0 +1,166 @@ |
161 |
++#!/usr/bin/env python3 |
162 |
++ |
163 |
++import sys |
164 |
++import getopt |
165 |
++import json |
166 |
++import re |
167 |
++ |
168 |
++class MPIFile: |
169 |
++ _filename = None |
170 |
++ _mpi_calls = None |
171 |
++ |
172 |
++ def __init__(self, inputfile, outputfile, calls=[]): |
173 |
++ self._in_filename = inputfile |
174 |
++ self._out_filename = outputfile |
175 |
++ self._mpi_calls = calls |
176 |
++ |
177 |
++ def parse(self): |
178 |
++ with open(self._in_filename, 'r') as in_f: |
179 |
++ with open(self._out_filename, 'w+') as out_f: |
180 |
++ pragma_scope = False |
181 |
++ pragma_block = '' |
182 |
++ condition = 'True' |
183 |
++ for line in in_f: |
184 |
++ if pragma_scope: |
185 |
++ if '#pragma pygen end' in line: |
186 |
++ pragma_scope = False |
187 |
++ parsed = self._parse_block(pragma_block, condition) |
188 |
++ out_f.write(parsed) |
189 |
++ else: |
190 |
++ pragma_block += line |
191 |
++ else: |
192 |
++ if '#pragma pygen start' in line: |
193 |
++ pragma_scope = True |
194 |
++ pragma_block = '' |
195 |
++ condition = self._parse_condition(line) |
196 |
++ elif line != '': |
197 |
++ out_f.write(line) |
198 |
++ |
199 |
++ def _parse_condition(self, line): |
200 |
++ try: |
201 |
++ match = re.match(r"#pragma pygen start where\((?P<condition>.*)\)", line) |
202 |
++ condition_str = match.group('condition') |
203 |
++ |
204 |
++ # Type: "string" in key |
205 |
++ match = re.match(r'(?P<string>"[A-Za-z0-9_\./\\-]+") in (?P<key>[A-Za-z0-9_]+)', condition_str) |
206 |
++ if match: |
207 |
++ return '{string} in func[\'{key}\']'.format( |
208 |
++ string = match.group('string'), |
209 |
++ key = match.group('key')) |
210 |
++ |
211 |
++ # Type: "string" not in key |
212 |
++ match = re.match(r'(?P<string>"[A-Za-z0-9_\./\\-]+") not in (?P<key>[A-Za-z0-9_]+)', condition_str) |
213 |
++ if match: |
214 |
++ return '{string} not in func[\'{key}\']'.format( |
215 |
++ string = match.group('string'), |
216 |
++ key = match.group('key')) |
217 |
++ |
218 |
++ except AttributeError: |
219 |
++ # If some regexp fail, just ignore everything else and return |
220 |
++ pass |
221 |
++ |
222 |
++ return 'True' |
223 |
++ |
224 |
++ |
225 |
++ def _parse_block(self, block, condition): |
226 |
++ if not isinstance(condition, str) or not condition: |
227 |
++ condition = 'True' |
228 |
++ |
229 |
++ parsed = '' |
230 |
++ for func in self._mpi_calls: |
231 |
++ if func['enabled'] and eval(condition): |
232 |
++ parsed += block.format( |
233 |
++ MPI_NAME = func['name'], |
234 |
++ MPI_LCASE = func['name'].lower(), |
235 |
++ C_PARAMS = func['cpar'], |
236 |
++ F_PARAMS = func['fpar'], |
237 |
++ C_ARG_LIST = func['c_args'], |
238 |
++ F_ARG_LIST = func['f_args'], |
239 |
++ TAGS = func['tags'], |
240 |
++ MPI_KEYNAME = func['name'][4:], |
241 |
++ BEFORE_FUNC = func['before'], |
242 |
++ AFTER_FUNC = func['after'] |
243 |
++ ) |
244 |
++ return parsed |
245 |
++ |
246 |
++ |
247 |
++def enrich(mpi_calls): |
248 |
++ last_word = re.compile(r'(\w+)(\[\])?\Z') |
249 |
++ for func in mpi_calls: |
250 |
++ # C: Parse arg list: "int argc, char *argv[]" -> "argc, argv" |
251 |
++ c_args = [] |
252 |
++ if func['cpar'] != 'void': |
253 |
++ for arg in func['cpar'].split(','): |
254 |
++ try: |
255 |
++ c_args.append(last_word.search(arg).group(1)) |
256 |
++ except AttributeError: |
257 |
++ print('Error parsing function ' + func['name']) |
258 |
++ raise |
259 |
++ func['c_args'] = ', '.join(c_args) |
260 |
++ # Fortran: Parse arg list: "MPI_Fint *comm, MPI_Fint *ierror" -> "comm, ierror" |
261 |
++ f_args = [] |
262 |
++ if func['fpar'] != '': |
263 |
++ for arg in func['fpar'].split(','): |
264 |
++ try: |
265 |
++ f_args.append(last_word.search(arg).group(1)) |
266 |
++ except AttributeError: |
267 |
++ print('Error parsing function ' + func['name']) |
268 |
++ raise |
269 |
++ func['f_args'] = ', '.join(f_args) |
270 |
++ |
271 |
++ # Set tag _Unknown if not defined |
272 |
++ func.setdefault('tags', '_Unknown') |
273 |
++ if func['tags'] == '': |
274 |
++ func['tags'] = '_Unknown' |
275 |
++ |
276 |
++ # Set before and after funtions |
277 |
++ if 'MPI_Init' in func['name']: |
278 |
++ func['before'] = 'before_init()' |
279 |
++ func['after'] = 'after_init()' |
280 |
++ elif 'MPI_Finalize' in func['name']: |
281 |
++ func['before'] = 'before_finalize()' |
282 |
++ func['after'] = 'after_finalize()' |
283 |
++ else: |
284 |
++ func['before'] = 'before_mpi({0}, 0, 0)'.format(func['name'].replace('MPI_', '')) |
285 |
++ func['after'] = 'after_mpi({0})'.format(func['name'].replace('MPI_', '')) |
286 |
++ |
287 |
++ # Set flag enabled if not defined |
288 |
++ func.setdefault('enabled', True) |
289 |
++ |
290 |
++ func.setdefault('info', '') |
291 |
++ |
292 |
++def main(argv): |
293 |
++ inputfile = '' |
294 |
++ outputfile = '' |
295 |
++ jsonfile = '' |
296 |
++ try: |
297 |
++ opts, args = getopt.getopt(argv[1:],'hi:o:j:',['ifile=','ofile=','json=']) |
298 |
++ except getopt.GetoptError: |
299 |
++ print(argv[0], ' -i <inputfile> -o <outputfile> -j <jsonfile>') |
300 |
++ sys.exit(2) |
301 |
++ for opt, arg in opts: |
302 |
++ if opt == '-h': |
303 |
++ print(argv[0], ' -i <inputfile> -o <outputfile> -j <jsonfile>') |
304 |
++ sys.exit() |
305 |
++ elif opt in ('-i', '--ifile'): |
306 |
++ inputfile = arg |
307 |
++ elif opt in ('-o', '--ofile'): |
308 |
++ outputfile = arg |
309 |
++ elif opt in ('-j', '--json'): |
310 |
++ jsonfile = arg |
311 |
++ |
312 |
++ if inputfile == '' or outputfile == '' or jsonfile == '': |
313 |
++ print(argv[0], ' -i <inputfile> -o <outputfile> -j <jsonfile>') |
314 |
++ sys.exit() |
315 |
++ |
316 |
++ # Read JSON file |
317 |
++ with open(jsonfile, 'r') as json_data: |
318 |
++ mpi_calls = json.load(json_data)['mpi_calls'] |
319 |
++ enrich(mpi_calls) |
320 |
++ |
321 |
++ # Parse input file |
322 |
++ mpi_intercept_c = MPIFile(inputfile, outputfile, mpi_calls) |
323 |
++ mpi_intercept_c.parse() |
324 |
++ |
325 |
++if __name__ == '__main__': |
326 |
++ main(sys.argv) |