Gentoo Archives: gentoo-commits

From: Alessandro Barbieri <lssndrbarbieri@×××××.com>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/proj/guru:dev commit in: sys-cluster/dlb/, sys-cluster/dlb/files/
Date: Sun, 27 Dec 2020 11:34:25
Message-Id: 1609068002.fde06e299589c2abc82df5768773fb3d3cc0befd.Alessandro-Barbieri@gentoo
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)