Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Commit

Permalink
Address CR suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
larroy committed Feb 14, 2019
1 parent 2f07dbb commit f09ed43
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 71 deletions.
55 changes: 15 additions & 40 deletions docs/api/python/libinfo/libinfo.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,47 +12,22 @@ The libinfo functionality allows to check for compile-time features supported by

```
In [1]: import mxnet as mx
...: import mxnet.runtime
...: fs = mx.runtime.Features()
In [2]: import mxnet.runtime
In [3]: mxnet.runtime.is_enabled('DEBUG')
Out[3]: True
In [4]: mxnet.runtime.is_enabled('CUDA')
Out[4]: False
In [5]: mx.runtime.libinfo_features()
Out[5]:
[✔ CUDA,
✔ CUDNN,
✔ NCCL,
✔ CUDA_RTC,
✔ TENSORRT,
✖ CPU_SSE,
✖ CPU_SSE2,
✖ CPU_SSE3,
✖ CPU_SSE4_1,
✖ CPU_SSE4_2,
✔ CPU_SSE4A,
✖ CPU_AVX,
✔ CPU_AVX2,
✔ OPENMP,
✔ SSE,
✖ F16C,
✔ JEMALLOC,
✖ BLAS_OPEN,
✔ BLAS_ATLAS,
✔ BLAS_MKL,
✔ BLAS_APPLE,
✔ LAPACK,
✔ MKLDNN,
✖ OPENCV,
✔ CAFFE,
✔ PROFILER,
✔ DIST_KVSTORE,
✔ CXX14,
✔ SIGNAL_HANDLER,
✖ DEBUG]
In [2]: fs
Out[2]: [✖ CUDA, ✖ CUDNN, ✖ NCCL, ✖ CUDA_RTC, ✖ TENSORRT, ✔ CPU_SSE, ✔ CPU_SSE2, ✔ CPU_SSE3, ✔ CPU_SSE4_1, ✔ CPU_SSE4_2, ✖ CPU_SSE4A, ✔ CPU_AVX, ✖ CPU_AVX2, ✖ OPENMP, ✖ SSE, ✔ F16C, ✖ JEMALLOC, ✔ BLAS_OPEN, ✖ BLAS_ATLAS, ✖ BLAS_MKL, ✖ BLAS_APPLE, ✔ LAPACK, ✖ MKLDNN, ✔ OPENCV, ✖ CAFFE, ✖ PROFILER, ✖ DIST_KVSTORE, ✖ CXX14, ✔ SIGNAL_HANDLER, ✔ DEBUG]
In [3]: fs['CUDA'].enabled
Out[3]: False
In [4]: fs.is_enabled('CPU_SSE')
Out[4]: True
In [5]: fs.is_enabled('CUDA')
Out[5]: False
In [6]:
```


Expand Down
49 changes: 30 additions & 19 deletions python/mxnet/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@

import ctypes
from .base import _LIB, check_call
import collections

class LibFeature(ctypes.Structure):
class Feature(ctypes.Structure):
"""
Compile time feature description
"""
Expand All @@ -44,33 +45,43 @@ def __repr__(self):
else:
return "✖ {}".format(self.name)

def libinfo_features():
def feature_list():
"""
Check the library for compile-time features. The list of features are maintained in libinfo.h and libinfo.cc
Returns
-------
:return: list of class LibFeature indicating which features are available and enabled
"""
lib_features = ctypes.POINTER(LibFeature)()
lib_features_c_array = ctypes.POINTER(Feature)()
lib_features_size = ctypes.c_size_t()
check_call(_LIB.MXLibInfoFeatures(ctypes.byref(lib_features), ctypes.byref(lib_features_size)))
feature_list = [lib_features[i] for i in range(lib_features_size.value)]
return feature_list
check_call(_LIB.MXLibInfoFeatures(ctypes.byref(lib_features_c_array), ctypes.byref(lib_features_size)))
features = [lib_features_c_array[i] for i in range(lib_features_size.value)]
return features

def is_enabled(tocheck):
class Features(collections.OrderedDict):
"""
Check for a particular feature by name
OrderedDict of name to Feature
"""
def __init__(self):
super().__init__([(f.name, f) for f in feature_list()])

Parameters
----------
:param x: str The name of a valid feature as string for example 'CUDA'
def __repr__(self):
return str(list(self.values()))

Returns
-------
:return: bool True if it's enabled, False if it's disabled, RuntimeError if the feature is not known
"""
feature_dict = {f.name: f.enabled for f in libinfo_features()}
if tocheck not in feature_dict:
raise RuntimeError("Feature '{}' is unknown, known features are: {}".format(tocheck, list(feature_dict.keys())))
return feature_dict[tocheck]
def is_enabled(self, feature_name):
"""
Check for a particular feature by name
Parameters
----------
:param x: str The name of a valid feature as string for example 'CUDA'
Returns
-------
:return: bool True if it's enabled, False if it's disabled, RuntimeError if the feature is not known
"""
feature_name = feature_name.upper()
if feature_name not in self:
raise RuntimeError("Feature '{}' is unknown, known features are: {}".format(feature_name, list(self.keys())))
return self[feature_name].enabled
23 changes: 11 additions & 12 deletions tests/python/unittest/test_runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,24 @@
from mxnet.base import MXNetError
from nose.tools import *

def test_libinfo_features():
features = libinfo_features()
print("Lib features: ")
for f in features:
print(f.name, f.enabled, f.index)
ok_(type(features) is list)
ok_(len(features) > 0)
def test_features():
features = Features()
print(features)
ok_('CUDA' in features)
ok_(len(features) >= 30)

def test_is_enabled():
features = libinfo_features()
features = Features()
for f in features:
if f.enabled:
ok_(is_enabled(f.name))
if features[f].enabled:
ok_(features.is_enabled(f))
else:
ok_(not is_enabled(f.name))
ok_(not features.is_enabled(f))

@raises(RuntimeError)
def test_is_enabled_not_existing():
is_enabled('this girl is on fire')
features = Features()
features.is_enabled('this girl is on fire')


if __name__ == "__main__":
Expand Down

0 comments on commit f09ed43

Please sign in to comment.