Skip to content

Commit 0df4581

Browse files
Moritz-Alexander-KernCristiano Köhler
and
Cristiano Köhler
authored
fix Issue #481, ASSET tries to use a backend that is not present in the environment (#485)
* added coverage to MPI runner, removed MPI from pip added function get_opencl_capability() to utils, to detect openCL devices * updated docstring, changed return logic * added unittest, regression Issue #481 Co-authored-by: Cristiano Köhler <c.koehler@fz-juelich.de>
1 parent 6ed3cb3 commit 0df4581

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

elephant/asset/asset.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136

137137
import elephant.conversion as conv
138138
from elephant import spike_train_surrogates
139-
from elephant.utils import get_cuda_capability_major
139+
from elephant.utils import get_cuda_capability_major, get_opencl_capability
140140

141141
try:
142142
from mpi4py import MPI
@@ -513,9 +513,11 @@ def _choose_backend(self):
513513
use_cuda = int(os.getenv("ELEPHANT_USE_CUDA", '1'))
514514
use_opencl = int(os.getenv("ELEPHANT_USE_OPENCL", '1'))
515515
cuda_detected = get_cuda_capability_major() != 0
516+
opencl_detected = get_opencl_capability()
517+
516518
if use_cuda and cuda_detected:
517519
return self.pycuda
518-
if use_opencl:
520+
if use_opencl and opencl_detected:
519521
return self.pyopencl
520522
return self.cpu
521523

elephant/test/test_asset.py

+34-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
try:
3535
import pyopencl
36-
HAVE_PYOPENCL = True
36+
HAVE_PYOPENCL = asset.get_opencl_capability()
3737
except ImportError:
3838
HAVE_PYOPENCL = False
3939

@@ -393,6 +393,39 @@ def test_intersection_matrix(self):
393393
spiketrains_i=[st1, st2], bin_size=bin_size,
394394
t_stop_j=5 * pq.ms)
395395

396+
# regression test Issue #481
397+
# see: https://github.com/NeuralEnsemble/elephant/issues/481
398+
def test_asset_choose_backend_opencl(self):
399+
class TestClassBackend(asset._GPUBackend):
400+
401+
def __init__(self):
402+
super().__init__()
403+
self.backend = self._choose_backend()
404+
405+
def cpu(self):
406+
return "cpu"
407+
408+
def pycuda(self):
409+
return "cuda"
410+
411+
def pyopencl(self):
412+
return "opencl"
413+
414+
# check which backend is chosen if environment variable for opencl
415+
# is not set
416+
os.environ.pop('ELEPHANT_USE_OPENCL', None)
417+
# create object of TestClass
418+
backend_obj = TestClassBackend()
419+
420+
if HAVE_PYOPENCL:
421+
self.assertEqual(backend_obj.backend(), 'opencl')
422+
else:
423+
# if environment variable is not set and no module pyopencl or
424+
# device is found: choose cpu backend
425+
self.assertEqual(backend_obj.backend(), 'cpu')
426+
427+
os.environ['ELEPHANT_USE_OPENCL'] = '0'
428+
396429

397430
@unittest.skipUnless(HAVE_SKLEARN, 'requires sklearn')
398431
class TestJSFUniformOrderStat3D(unittest.TestCase):

elephant/utils.py

+22
Original file line numberDiff line numberDiff line change
@@ -340,3 +340,25 @@ def get_cuda_capability_major():
340340
ctypes.byref(cc_minor),
341341
device)
342342
return cc_major.value
343+
344+
345+
def get_opencl_capability():
346+
"""
347+
Return a list of available OpenCL devices.
348+
349+
Returns
350+
-------
351+
bool
352+
True: if openCL platform detected and at least one device is found,
353+
False: if OpenCL is not found or if no OpenCL devices are found
354+
"""
355+
try:
356+
import pyopencl
357+
platforms = pyopencl.get_platforms()
358+
359+
if len(platforms) == 0:
360+
return False
361+
# len(platforms) is > 0, if it is not == 0
362+
return True
363+
except ImportError:
364+
return False

0 commit comments

Comments
 (0)