From 5437459fc0d0c2b63aa5865a3e79b1450dfa5636 Mon Sep 17 00:00:00 2001
From: Stephan Seitz <stephan.seitz@fau.de>
Date: Wed, 13 Nov 2019 11:14:14 +0100
Subject: [PATCH] Add pystencils.opencl.autoinit

---
 conftest.py                         | 15 +++++++++------
 pystencils/datahandling/pyopencl.py |  3 ++-
 pystencils/opencl/__init__.py       |  8 ++++++++
 pystencils/opencl/autoinit.py       | 11 +++++++++++
 pystencils/opencl/opencljit.py      |  6 ++++--
 pystencils_tests/test_opencl.py     | 10 +++++-----
 6 files changed, 39 insertions(+), 14 deletions(-)
 create mode 100644 pystencils/opencl/__init__.py
 create mode 100644 pystencils/opencl/autoinit.py

diff --git a/conftest.py b/conftest.py
index d1da0451a..c20bde409 100644
--- a/conftest.py
+++ b/conftest.py
@@ -1,9 +1,14 @@
 import os
-import pytest
-import tempfile
 import runpy
 import sys
 import warnings
+import tempfile
+
+import nbformat
+import pytest
+from nbconvert import PythonExporter
+
+from pystencils.boundaries.createindexlistcython import *  # NOQA
 # Trigger config file reading / creation once - to avoid race conditions when multiple instances are creating it
 # at the same time
 from pystencils.cpu import cpujit
@@ -15,7 +20,6 @@ try:
     pyximport.install(language_level=3)
 except ImportError:
     pass
-from pystencils.boundaries.createindexlistcython import *  # NOQA
 
 
 SCRIPT_FOLDER = os.path.dirname(os.path.realpath(__file__))
@@ -29,7 +33,8 @@ def add_path_to_ignore(path):
     collect_ignore += [os.path.join(SCRIPT_FOLDER, path, f) for f in os.listdir(os.path.join(SCRIPT_FOLDER, path))]
 
 
-collect_ignore = [os.path.join(SCRIPT_FOLDER, "doc", "conf.py")]
+collect_ignore = [os.path.join(SCRIPT_FOLDER, "doc", "conf.py"),
+        os.path.join(SCRIPT_FOLDER, "pystencils", "opencl", "opencl.autoinit")]
 add_path_to_ignore('pystencils_tests/benchmark')
 add_path_to_ignore('_local_tmp')
 
@@ -78,8 +83,6 @@ for root, sub_dirs, files in os.walk('.'):
             collect_ignore.append(f)
 
 
-import nbformat
-from nbconvert import PythonExporter
 
 
 class IPythonMockup:
diff --git a/pystencils/datahandling/pyopencl.py b/pystencils/datahandling/pyopencl.py
index 05470ea9f..7b6f44088 100644
--- a/pystencils/datahandling/pyopencl.py
+++ b/pystencils/datahandling/pyopencl.py
@@ -14,7 +14,8 @@ class PyOpenClArrayHandler:
         if not queue:
             from pystencils.opencl.opencljit import get_global_cl_queue
             queue = get_global_cl_queue()
-        assert queue, "OpenCL queue missing"
+        assert queue, "OpenCL queue missing!\n" \
+            "Use `import pystencils.opencl.autoinit` if you want it to be automatically created"
         self.queue = queue
 
     def zeros(self, shape, dtype=np.float64, order='C'):
diff --git a/pystencils/opencl/__init__.py b/pystencils/opencl/__init__.py
new file mode 100644
index 000000000..e405a2f4e
--- /dev/null
+++ b/pystencils/opencl/__init__.py
@@ -0,0 +1,8 @@
+"""
+
+"""
+
+from pystencils.opencl.opencljit import (
+    clear_global_ctx, init_globally, init_globally_with_context, make_python_function)
+
+__all__ = ['init_globally', 'init_globally_with_context', 'clear_global_ctx', 'make_python_function']
diff --git a/pystencils/opencl/autoinit.py b/pystencils/opencl/autoinit.py
new file mode 100644
index 000000000..f37ddc1cb
--- /dev/null
+++ b/pystencils/opencl/autoinit.py
@@ -0,0 +1,11 @@
+"""
+Automatically initializes OpenCL context using any device.
+
+Use `pystencils.opencl.{init_globally_with_context,init_globally}` if you want to use a specific device.
+"""
+
+from pystencils.opencl import *  # noqa
+from pystencils.opencl.opencljit import *  # noqa
+from pystencils.opencl.opencljit import init_globally
+
+init_globally()
diff --git a/pystencils/opencl/opencljit.py b/pystencils/opencl/opencljit.py
index 939387338..c58f81e9d 100644
--- a/pystencils/opencl/opencljit.py
+++ b/pystencils/opencl/opencljit.py
@@ -65,8 +65,10 @@ def make_python_function(kernel_function_node, opencl_queue, opencl_ctx, argumen
     if not opencl_queue:
         opencl_queue = _global_cl_queue
 
-    assert opencl_ctx, "No valid OpenCL context"
-    assert opencl_queue, "No valid OpenCL queue"
+    assert opencl_ctx, "No valid OpenCL context!\n" \
+        "Use `import pystencils.opencl.autoinit` if you want it to be automatically created"
+    assert opencl_queue, "No valid OpenCL queue!\n" \
+        "Use `import pystencils.opencl.autoinit` if you want it to be automatically created"
 
     if argument_dict is None:
         argument_dict = {}
diff --git a/pystencils_tests/test_opencl.py b/pystencils_tests/test_opencl.py
index 2fce04f4a..ea5b1ecbc 100644
--- a/pystencils_tests/test_opencl.py
+++ b/pystencils_tests/test_opencl.py
@@ -1,11 +1,11 @@
 import numpy as np
 import pytest
+import sympy as sp
 
 import pystencils
-import sympy as sp
 from pystencils.backends.cuda_backend import CudaBackend
 from pystencils.backends.opencl_backend import OpenClBackend
-from pystencils.opencl.opencljit import make_python_function, init_globally, get_global_cl_queue
+from pystencils.opencl.opencljit import get_global_cl_queue, init_globally, make_python_function
 
 try:
     import pyopencl as cl
@@ -235,9 +235,9 @@ def test_without_cuda():
     opencl_kernel(x=x, y=y, z=z)
 
 
-
 @pytest.mark.skipif(not HAS_OPENCL, reason="Test requires pyopencl")
 def test_kernel_creation():
+    global pystencils
     z, y, x = pystencils.fields("z, y, x: [20,30]")
 
     assignments = pystencils.AssignmentCollection({
@@ -246,8 +246,9 @@ def test_kernel_creation():
 
     print(assignments)
 
+    pystencils.opencl.clear_global_ctx()
 
-    init_globally()
+    import pystencils.opencl.autoinit
     ast = pystencils.create_kernel(assignments, target='opencl')
 
     print(ast.backend)
@@ -270,4 +271,3 @@ def test_kernel_creation():
 
     assert opencl_kernel is not None
     opencl_kernel(x=x, y=y, z=z)
-
-- 
GitLab