Skip to content

Commit

Permalink
fix Issue #481, ASSET tries to use a backend that is not present in t…
Browse files Browse the repository at this point in the history
…he 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 <[email protected]>
  • Loading branch information
Moritz-Alexander-Kern and Cristiano Köhler authored May 20, 2022
1 parent 6ed3cb3 commit 0df4581
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 3 deletions.
6 changes: 4 additions & 2 deletions elephant/asset/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@

import elephant.conversion as conv
from elephant import spike_train_surrogates
from elephant.utils import get_cuda_capability_major
from elephant.utils import get_cuda_capability_major, get_opencl_capability

try:
from mpi4py import MPI
Expand Down Expand Up @@ -513,9 +513,11 @@ def _choose_backend(self):
use_cuda = int(os.getenv("ELEPHANT_USE_CUDA", '1'))
use_opencl = int(os.getenv("ELEPHANT_USE_OPENCL", '1'))
cuda_detected = get_cuda_capability_major() != 0
opencl_detected = get_opencl_capability()

if use_cuda and cuda_detected:
return self.pycuda
if use_opencl:
if use_opencl and opencl_detected:
return self.pyopencl
return self.cpu

Expand Down
35 changes: 34 additions & 1 deletion elephant/test/test_asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

try:
import pyopencl
HAVE_PYOPENCL = True
HAVE_PYOPENCL = asset.get_opencl_capability()
except ImportError:
HAVE_PYOPENCL = False

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

# regression test Issue #481
# see: https://github.com/NeuralEnsemble/elephant/issues/481
def test_asset_choose_backend_opencl(self):
class TestClassBackend(asset._GPUBackend):

def __init__(self):
super().__init__()
self.backend = self._choose_backend()

def cpu(self):
return "cpu"

def pycuda(self):
return "cuda"

def pyopencl(self):
return "opencl"

# check which backend is chosen if environment variable for opencl
# is not set
os.environ.pop('ELEPHANT_USE_OPENCL', None)
# create object of TestClass
backend_obj = TestClassBackend()

if HAVE_PYOPENCL:
self.assertEqual(backend_obj.backend(), 'opencl')
else:
# if environment variable is not set and no module pyopencl or
# device is found: choose cpu backend
self.assertEqual(backend_obj.backend(), 'cpu')

os.environ['ELEPHANT_USE_OPENCL'] = '0'


@unittest.skipUnless(HAVE_SKLEARN, 'requires sklearn')
class TestJSFUniformOrderStat3D(unittest.TestCase):
Expand Down
22 changes: 22 additions & 0 deletions elephant/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,3 +340,25 @@ def get_cuda_capability_major():
ctypes.byref(cc_minor),
device)
return cc_major.value


def get_opencl_capability():
"""
Return a list of available OpenCL devices.
Returns
-------
bool
True: if openCL platform detected and at least one device is found,
False: if OpenCL is not found or if no OpenCL devices are found
"""
try:
import pyopencl
platforms = pyopencl.get_platforms()

if len(platforms) == 0:
return False
# len(platforms) is > 0, if it is not == 0
return True
except ImportError:
return False

0 comments on commit 0df4581

Please sign in to comment.