diff --git a/pystencils/boundaries/boundaryhandling.py b/pystencils/boundaries/boundaryhandling.py index d258de4b3e5e7d5b85c69d0910ea384b77ecd110..e19e24ecb1d5cd5e59a53796fc7ae7f0c9aa30fc 100644 --- a/pystencils/boundaries/boundaryhandling.py +++ b/pystencils/boundaries/boundaryhandling.py @@ -87,8 +87,26 @@ class BoundaryHandling: fi = flag_interface self.flag_interface = fi if fi is not None else FlagInterface(data_handling, name + "Flags") - gpu = self._target == 'gpu' - data_handling.add_custom_class(self._index_array_name, self.IndexFieldBlockData, cpu=True, gpu=gpu) + gpu = self._target in self._data_handling._GPU_LIKE_TARGETS + class_ = self.IndexFieldBlockData + if self._target == 'opencl': + def opencl_to_device(gpu_version, cpu_version): + from pyopencl import array + gpu_version = gpu_version.boundary_object_to_index_list + cpu_version = cpu_version.boundary_object_to_index_list + for obj, cpu_arr in cpu_version.items(): + if obj not in gpu_version or gpu_version[obj].shape != cpu_arr.shape: + from pystencils.opencl.opencljit import get_global_cl_queue + + queue = self._data_handling._opencl_queue or get_global_cl_queue() + gpu_version[obj] = array.to_device(queue, cpu_arr) + else: + gpu_version[obj].set(cpu_arr) + + class_ = type('opencl_class', (self.IndexFieldBlockData,), { + 'to_gpu': opencl_to_device + }) + data_handling.add_custom_class(self._index_array_name, class_, cpu=True, gpu=gpu) @property def data_handling(self): @@ -204,7 +222,7 @@ class BoundaryHandling: if self._dirty: self.prepare() - for b in self._data_handling.iterate(gpu=self._target == 'gpu'): + for b in self._data_handling.iterate(gpu=self._target in self._data_handling._GPU_LIKE_TARGETS): for b_obj, idx_arr in b[self._index_array_name].boundary_object_to_index_list.items(): kwargs[self._field_name] = b[self._field_name] kwargs['indexField'] = idx_arr @@ -219,7 +237,7 @@ class BoundaryHandling: if self._dirty: self.prepare() - for b in self._data_handling.iterate(gpu=self._target == 'gpu'): + for b in self._data_handling.iterate(gpu=self._target in self._data_handling._GPU_LIKE_TARGETS): for b_obj, idx_arr in b[self._index_array_name].boundary_object_to_index_list.items(): arguments = kwargs.copy() arguments[self._field_name] = b[self._field_name] @@ -302,7 +320,7 @@ class BoundaryHandling: def _boundary_data_initialization(self, boundary_obj, boundary_data_setter, **kwargs): if boundary_obj.additional_data_init_callback: boundary_obj.additional_data_init_callback(boundary_data_setter, **kwargs) - if self._target == 'gpu': + if self._target in self._data_handling._GPU_LIKE_TARGETS: self._data_handling.to_gpu(self._index_array_name) class BoundaryInfo(object): diff --git a/pystencils/datahandling/datahandling_interface.py b/pystencils/datahandling/datahandling_interface.py index ba960edc17b2e3409dc465c257e23d9e9394dc5c..af1a6ba1fc9d003042063023aa1ede5fc08665db 100644 --- a/pystencils/datahandling/datahandling_interface.py +++ b/pystencils/datahandling/datahandling_interface.py @@ -16,6 +16,9 @@ class DataHandling(ABC): 'gather' function that has collects (parts of the) distributed data on a single process. """ + _GPU_LIKE_TARGETS = ['gpu', 'opencl'] + _GPU_LIKE_BACKENDS = ['gpucuda', 'opencl'] + # ---------------------------- Adding and accessing data ----------------------------------------------------------- @property diff --git a/pystencils/datahandling/serial_datahandling.py b/pystencils/datahandling/serial_datahandling.py index 10c18d3731e5ac9b4e5003c79a7740bcba060caa..ea708ae2bb1759d5a9766b278afa2dd7c235f2da 100644 --- a/pystencils/datahandling/serial_datahandling.py +++ b/pystencils/datahandling/serial_datahandling.py @@ -16,9 +16,6 @@ from pystencils.utils import DotDict class SerialDataHandling(DataHandling): - _GPU_LIKE_TARGETS = ['gpu', 'opencl'] - _GPU_LIKE_BACKENDS = ['gpucuda', 'opencl'] - def __init__(self, domain_size: Sequence[int], default_ghost_layers: int = 1,