From 86a6112e8fe8745eaa6f71c6a185cd64e8ec2bb5 Mon Sep 17 00:00:00 2001 From: Markus Holzer <markus.holzer@fau.de> Date: Sun, 2 Jun 2024 17:15:15 +0200 Subject: [PATCH] Fuse thread safety check with existing check --- src/pystencils/config.py | 11 +++-------- src/pystencils/kernel_contrains_check.py | 5 +++-- src/pystencils/kernelcreation.py | 6 ------ 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/pystencils/config.py b/src/pystencils/config.py index fafc34178..dec9df8ba 100644 --- a/src/pystencils/config.py +++ b/src/pystencils/config.py @@ -135,14 +135,9 @@ class CreateKernelConfig: """ skip_independence_check: bool = False """ - Don't check that loop iterations are independent. This is needed e.g. for - periodicity kernel, that access the field outside the iteration bounds. Use with care! - """ - check_thread_safety: bool = True - """ - Assignments are considered thread safe if read and writes only target the same locations. If this is not the case, - multithreaded optimisations will fail. The thread safety check can be deactivated to use e.g. GPUs anyway. - Use with care! + By default the assignment list is checked for read/write independence. This means fields are only written at + locations where they are read. Doing so guarantees thread safety. In some cases e.g. for + periodicity kernel, this can not be assured and does the check needs to be deactivated. Use with care! """ class DataTypeFactory: diff --git a/src/pystencils/kernel_contrains_check.py b/src/pystencils/kernel_contrains_check.py index b72e084a3..f33434a0e 100644 --- a/src/pystencils/kernel_contrains_check.py +++ b/src/pystencils/kernel_contrains_check.py @@ -43,7 +43,6 @@ class KernelConstraintsCheck: self.fields_read = set() self.check_independence_condition = check_independence_condition self.check_double_write_condition = check_double_write_condition - self.thread_safe = True def visit(self, obj): if isinstance(obj, (AssignmentCollection, NodeCollection)): @@ -117,7 +116,9 @@ class KernelConstraintsCheck: if fai in self.field_reads: reads = tuple(self.field_reads[fai]) if len(reads) > 1 or lhs.offsets != reads[0]: - self.thread_safe = False + if self.check_independence_condition: + raise ValueError(f"Field {lhs.field.name} is written at different location than it was read. " + f"This means the resulting kernel would not be thread safe") elif isinstance(lhs, sp.Symbol): if self.scopes.is_defined_locally(lhs): raise ValueError(f"Assignments not in SSA form, multiple assignments to {lhs.name}") diff --git a/src/pystencils/kernelcreation.py b/src/pystencils/kernelcreation.py index 8dd7b90fc..59986e8d8 100644 --- a/src/pystencils/kernelcreation.py +++ b/src/pystencils/kernelcreation.py @@ -130,12 +130,6 @@ def create_domain_kernel(assignments: NodeCollection, *, config: CreateKernelCon check_double_write_condition=not config.allow_double_writes) check.visit(assignments) - if not check.thread_safe and config.check_thread_safety: - base = "Assignments are not thread safe because data is read and written on different locations." - if config.cpu_openmp: - raise ValueError(f"{base} OpenMP optimisation is not permitted in this scenario.") - if config.target == Target.GPU: - raise ValueError(f"{base} GPU target is not permitted in this case, only CPU target with single thread") assignments.bound_fields = check.fields_written assignments.rhs_fields = check.fields_read -- GitLab