From 193ac6378a37ad8fb7382bb3113f4484cc757ff2 Mon Sep 17 00:00:00 2001 From: Matt Wala Date: Sat, 20 May 2017 18:26:05 -0500 Subject: [PATCH 1/4] _UniqueVarNameGenerator: Fix O(n**2) behavior by keeping track of the array prefixes as they are aded to the set. Closes #25 on gitlab Depends on inducer/pytools!2 on gitlab --- loopy/kernel/__init__.py | 51 +++++++++++++++++++++++++--------------- test/test_loopy.py | 14 +++++++++++ 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/loopy/kernel/__init__.py b/loopy/kernel/__init__.py index 324f7da1a..da15967c6 100644 --- a/loopy/kernel/__init__.py +++ b/loopy/kernel/__init__.py @@ -44,33 +44,46 @@ from loopy.diagnostic import CannotBranchDomainTree, LoopyError # {{{ unique var names -def _is_var_name_conflicting_with_longer(name_a, name_b): - # Array dimensions implemented as separate arrays generate - # names by appending '_s'. Make sure that no - # conflicts can arise from these names. +class _UniqueVarNameGenerator(UniqueNameGenerator): - # Only deal with the case of b longer than a. - if not name_b.startswith(name_a): - return False + def __init__(self, existing_names=set(), forced_prefix=""): + super(_UniqueVarNameGenerator, self).__init__(existing_names, forced_prefix) + array_prefix_pattern = re.compile("(.*)_s[0-9]+$") - return re.match("^%s_s[0-9]+" % re.escape(name_b), name_a) is not None + array_prefixes = set() + for name in existing_names: + match = array_prefix_pattern.match(name) + if match is None: + continue + array_prefixes.add(match.group(1)) -def _is_var_name_conflicting(name_a, name_b): - if name_a == name_b: - return True + self.array_prefixes = array_prefixes + self.array_prefix_pattern = array_prefix_pattern - return ( - _is_var_name_conflicting_with_longer(name_a, name_b) - or _is_var_name_conflicting_with_longer(name_b, name_a)) + def _name_added(self, name): + match = self.array_prefix_pattern.match(name) + if match is None: + return + self.array_prefixes.add(match.group(1)) -class _UniqueVarNameGenerator(UniqueNameGenerator): def is_name_conflicting(self, name): - from pytools import any - return any( - _is_var_name_conflicting(name, other_name) - for other_name in self.existing_names) + if name in self.existing_names: + return True + + # Array dimensions implemented as separate arrays generate + # names by appending '_s'. Make sure that no + # conflicts can arise from these names. + + if name in self.array_prefixes: + return True + + match = self.array_prefix_pattern.match(name) + if match is None: + return False + + return match.group(1) in self.existing_names # }}} diff --git a/test/test_loopy.py b/test/test_loopy.py index 4bb6a2726..77fd49e07 100644 --- a/test/test_loopy.py +++ b/test/test_loopy.py @@ -2231,6 +2231,20 @@ def test_struct_assignment(ctx_factory): knl(queue, N=200) +def test_kernel_var_name_generator(): + knl = lp.make_kernel( + "{[i]: 0 <= i <= 10}", + """ + <>a = 0 + <>b_s0 = 0 + """) + + vng = knl.get_var_name_generator() + + assert vng("a_s0") != "a_s0" + assert vng("b") != "b" + + if __name__ == "__main__": if len(sys.argv) > 1: exec(sys.argv[1]) -- GitLab From fe456132076fa82b638650923f99bd9a5706223a Mon Sep 17 00:00:00 2001 From: Matt Wala Date: Sat, 20 May 2017 18:36:59 -0500 Subject: [PATCH 2/4] UniqueVarNameGenerator: Add a brief explanatory comment. --- loopy/kernel/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/loopy/kernel/__init__.py b/loopy/kernel/__init__.py index da15967c6..174b6c43a 100644 --- a/loopy/kernel/__init__.py +++ b/loopy/kernel/__init__.py @@ -76,6 +76,9 @@ class _UniqueVarNameGenerator(UniqueNameGenerator): # names by appending '_s'. Make sure that no # conflicts can arise from these names. + # Case 1: a_s0 is already a name, we are trying to insert a + # Case 2: a is already a name, we are trying to insert a_s0 + if name in self.array_prefixes: return True -- GitLab From 006901ab086127a53fdec82d73529a8fea813d47 Mon Sep 17 00:00:00 2001 From: Matt Wala Date: Sat, 20 May 2017 18:57:22 -0500 Subject: [PATCH 3/4] [ci skip] array_prefixes -> conflicting_array_prefixes --- loopy/kernel/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/loopy/kernel/__init__.py b/loopy/kernel/__init__.py index 174b6c43a..e8c846fbc 100644 --- a/loopy/kernel/__init__.py +++ b/loopy/kernel/__init__.py @@ -58,7 +58,7 @@ class _UniqueVarNameGenerator(UniqueNameGenerator): array_prefixes.add(match.group(1)) - self.array_prefixes = array_prefixes + self.conflicting_array_prefixes = array_prefixes self.array_prefix_pattern = array_prefix_pattern def _name_added(self, name): @@ -66,7 +66,7 @@ class _UniqueVarNameGenerator(UniqueNameGenerator): if match is None: return - self.array_prefixes.add(match.group(1)) + self.conflicting_array_prefixes.add(match.group(1)) def is_name_conflicting(self, name): if name in self.existing_names: @@ -76,10 +76,10 @@ class _UniqueVarNameGenerator(UniqueNameGenerator): # names by appending '_s'. Make sure that no # conflicts can arise from these names. - # Case 1: a_s0 is already a name, we are trying to insert a - # Case 2: a is already a name, we are trying to insert a_s0 + # Case 1: a_s0 is already a name; we are trying to insert a + # Case 2: a is already a name; we are trying to insert a_s0 - if name in self.array_prefixes: + if name in self.conflicting_array_prefixes: return True match = self.array_prefix_pattern.match(name) -- GitLab From 2ca2360f69244c017942c7fcd6b7670de6e9c825 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Wed, 24 May 2017 17:41:41 -0700 Subject: [PATCH 4/4] Bump pytools dep for #25 and !111 on Gitlab --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a941eecd2..150cb1cc4 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,7 @@ setup(name="loo.py", ], install_requires=[ - "pytools>=2016.2.6", + "pytools>=2017.1", "pymbolic>=2016.2", "genpy>=2016.1.2", "cgen>=2016.1", -- GitLab