From 0bddca2e356a99b97cd6fa79cf968a893324f917 Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Sun, 13 Dec 2015 15:23:29 -0500 Subject: [PATCH 1/8] Updating README.md to reflect post install options --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e07d32a94..753f31a16 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,8 @@ cd path/to/arrayfire-python python setup.py install ``` +**Post Installation** + Please follow [these instructions](https://github.com/arrayfire/arrayfire-python/wiki) to ensure the arrayfire-python can find the arrayfire libraries. ## Acknowledgements From 81308e9d92b0a4494fabd58b526f39e694a16853 Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Sun, 13 Dec 2015 15:29:48 -0500 Subject: [PATCH 2/8] Updating install instructions from master to devel --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 753f31a16..f3576d179 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ pip install arrayfire **Install the development version:** ``` -pip install git+git://github.com/arrayfire/arrayfire.git@master +pip install git+git://github.com/arrayfire/arrayfire.git@devel ``` **Installing offline** From c5f174fa9684836af2197da4dac016deb3ade1d7 Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 14 Dec 2015 14:15:04 -0500 Subject: [PATCH 3/8] Updating the error message when arrayfire libraries isn't found - Emits the link to the wiki page which discusses the environment variables --- arrayfire/library.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arrayfire/library.py b/arrayfire/library.py index 0b499304b..5b6b808cd 100644 --- a/arrayfire/library.py +++ b/arrayfire/library.py @@ -376,7 +376,8 @@ def __init__(self): pass if (self.__name is None): - raise RuntimeError("Could not load any ArrayFire libraries") + raise RuntimeError("Could not load any ArrayFire libraries.\n" + + "Please look at https://github.com/arrayfire/arrayfire-python/wiki for more information.") def get_id(self, name): return self.__backend_name_map[name] From ad6f76ea6177d72e96d3679852a878e378289c69 Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 14 Dec 2015 16:49:15 -0500 Subject: [PATCH 4/8] Adding default search paths --- arrayfire/library.py | 129 +++++++++++++++++++++++++++++++++---------- 1 file changed, 101 insertions(+), 28 deletions(-) diff --git a/arrayfire/library.py b/arrayfire/library.py index 5b6b808cd..4854d9334 100644 --- a/arrayfire/library.py +++ b/arrayfire/library.py @@ -315,31 +315,85 @@ class BACKEND(_Enum): CUDA = _Enum_Type(2) OPENCL = _Enum_Type(4) -class _clibrary(object): +def _setup(): + import platform + import os + + platform_name = platform.system() + + try: + AF_SEARCH_PATH = os.environ['AF_PATH'] + except: + AF_SEARCH_PATH = None + pass + + try: + CUDA_PATH = os.environ['CUDA_PATH'] + except: + CUDA_PATH= None + pass + + CUDA_EXISTS = False + + assert(len(platform_name) >= 3) + if platform_name == 'Windows' or platform_name[:3] == 'CYG': + + ## Windows specific setup + pre = '' + post = '.dll' + if platform_name == "Windows": + ''' + Supressing crashes caused by missing dlls + http://stackoverflow.com/questions/8347266/missing-dll-print-message-instead-of-launching-a-popup + https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx + ''' + ct.windll.kernel32.SetErrorMode(0x0001 | 0x0002) + + if AF_SEARCH_PATH is None: + AF_SEARCH_PATH="C:/Program Files/ArrayFire/v3/" + + if CUDA_PATH is not None: + CUDA_EXISTS = os.path.isdir(CUDA_PATH + '/bin') and os.path.isdir(CUDA_PATH + '/nvvm/bin/') + + elif platform_name == 'Darwin': + + ## OSX specific setup + pre = 'lib' + post = '.dylib' + + if AF_SEARCH_PATH is None: + AF_SEARCH_PATH='/usr/local/' + + if CUDA_PATH is None: + CUDA_PATH='/usr/local/cuda/' + + CUDA_EXISTS = os.path.isdir(CUDA_PATH + '/lib') and os.path.isdir(CUDA_PATH + '/nvvm/lib') - def __libname(self, name): - platform_name = platform.system() - assert(len(platform_name) >= 3) - - libname = 'libaf' + name - if platform_name == 'Linux': - libname += '.so' - elif platform_name == 'Darwin': - libname += '.dylib' - elif platform_name == "Windows" or platform_name[:3] == "CYG": - libname += '.dll' - libname = libname[3:] # remove 'lib' - if platform_name == "Windows": - ''' - Supressing crashes caused by missing dlls - http://stackoverflow.com/questions/8347266/missing-dll-print-message-instead-of-launching-a-popup - https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx - ''' - ct.windll.kernel32.SetErrorMode(0x0001 | 0x0002); + elif platform_name == 'Linux': + pre = 'lib' + post = '.so' + + if AF_SEARCH_PATH is None: + AF_SEARCH_PATH='/opt/arrayfire-3/' + + if CUDA_PATH is None: + CUDA_PATH='/usr/local/cuda/' + + if platform.architecture()[0][:2] == 64: + CUDA_EXISTS = os.path.isdir(CUDA_PATH + '/lib64') and os.path.isdir(CUDA_PATH + '/nvvm/lib64') else: - raise OSError(platform_name + ' not supported') + CUDA_EXISTS = os.path.isdir(CUDA_PATH + '/lib') and os.path.isdir(CUDA_PATH + '/nvvm/lib') + else: + raise OSError(platform_name + ' not supported') - return libname + return pre, post, AF_SEARCH_PATH, CUDA_EXISTS + +class _clibrary(object): + + def __libname(self, name, head='af'): + libname = self.__pre + head + name + self.__post + libname_full = self.AF_SEARCH_PATH + '/lib/' + libname + return (libname, libname_full) def set_unsafe(self, name): lib = self.__clibs[name] @@ -348,6 +402,15 @@ def set_unsafe(self, name): self.__name = name def __init__(self): + + more_info_str = "Please look at https://github.com/arrayfire/arrayfire-python/wiki for more information." + + pre, post, AF_SEARCH_PATH, CUDA_EXISTS = _setup() + + self.__pre = pre + self.__post = post + self.AF_SEARCH_PATH = AF_SEARCH_PATH + self.__name = None self.__clibs = {'cuda' : None, @@ -365,19 +428,29 @@ def __init__(self): 'cuda' : 2, 'opencl' : 4} - # Iterate in reverse order of preference - for name in ('cpu', 'opencl', 'cuda', ''): + # Try to pre-load forge library if it exists + libnames = self.__libname('forge', '') + for libname in libnames: try: - libname = self.__libname(name) ct.cdll.LoadLibrary(libname) - self.__clibs[name] = ct.CDLL(libname) - self.__name = name except: pass + # Iterate in reverse order of preference + for name in ('cpu', 'opencl', 'cuda', ''): + libnames = self.__libname(name) + for libname in libnames: + try: + ct.cdll.LoadLibrary(libname) + self.__clibs[name] = ct.CDLL(libname) + self.__name = name + break; + except: + pass + if (self.__name is None): raise RuntimeError("Could not load any ArrayFire libraries.\n" + - "Please look at https://github.com/arrayfire/arrayfire-python/wiki for more information.") + more_info_str) def get_id(self, name): return self.__backend_name_map[name] From c5fbdda627d6fd863ef2205373221f3d65b120dc Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 14 Dec 2015 17:58:34 -0500 Subject: [PATCH 5/8] Fixing bug in get_version() --- arrayfire/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arrayfire/util.py b/arrayfire/util.py index 361cadbfd..a20002cd6 100644 --- a/arrayfire/util.py +++ b/arrayfire/util.py @@ -79,7 +79,7 @@ def get_version(): minor=ct.c_int(0) patch=ct.c_int(0) safe_call(backend.get().af_get_version(ct.pointer(major), ct.pointer(minor), ct.pointer(patch))) - return major,minor,patch + return major.value,minor.value,patch.value to_dtype = {'f' : Dtype.f32, 'd' : Dtype.f64, From 1b46eb67ac3d5ee9367fc2bc680f5f70511b1282 Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 14 Dec 2015 17:58:57 -0500 Subject: [PATCH 6/8] Adding af.info_str() function that mimics af.info() - Currently uses information from af.device_info() - This will be replaced when upstream adds native function --- arrayfire/device.py | 51 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/arrayfire/device.py b/arrayfire/device.py index ff2eb88b9..f84404f07 100644 --- a/arrayfire/device.py +++ b/arrayfire/device.py @@ -11,7 +11,7 @@ """ from .library import * -from .util import (safe_call, to_str) +from .util import (safe_call, to_str, get_version) def init(): """ @@ -82,6 +82,55 @@ def set_device(num): """ safe_call(backend.get().af_set_device(num)) +def info_str(verbose = False): + """ + Returns information about the following as a string: + - ArrayFire version number. + - The number of devices available. + - The names of the devices. + - The current device being used. + """ + import platform + res_str = 'ArrayFire' + + major, minor, patch = get_version() + dev_info = device_info() + backend_str = dev_info['backend'] + + res_str += ' v' + str(major) + '.' + str(minor) + '.' + str(patch) + res_str += ' (' + backend_str + ' ' + platform.architecture()[0] + ')\n' + + num_devices = get_device_count() + curr_device_id = get_device() + + for n in range(num_devices): + # To suppress warnings on CPU + if (n != curr_device_id): + set_device(n) + + if (n == curr_device_id): + res_str += '[%d] ' % n + else: + res_str += '-%d- ' % n + + dev_info = device_info() + + if (backend_str.lower() == 'opencl'): + res_str += dev_info['toolkit'] + + res_str += ': ' + dev_info['device'] + + if (backend_str.lower() != 'cpu'): + res_str += ' (Compute ' + dev_info['compute'] + ')' + + res_str += '\n' + + # To suppress warnings on CPU + if (curr_device_id != get_device()): + set_device(curr_device_id) + + return res_str + def is_dbl_supported(device=None): """ Check if double precision is supported on specified device. From 89da7543c1f7b278fe379fb658d693d2d09972a9 Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 14 Dec 2015 18:17:29 -0500 Subject: [PATCH 7/8] Fixing an issue with set_device in tests --- tests/simple/device.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/simple/device.py b/tests/simple/device.py index 40c6026e8..98a2b710a 100644 --- a/tests/simple/device.py +++ b/tests/simple/device.py @@ -19,8 +19,8 @@ def simple_device(verbose=False): print_func(af.is_dbl_supported()) af.sync() - dev = af.get_device() - print_func(dev) + curr_dev = af.get_device() + print_func(curr_dev) for k in range(af.get_device_count()): af.set_device(k) dev = af.get_device() @@ -38,7 +38,7 @@ def simple_device(verbose=False): assert(mem_info['alloc']['buffers'] == 1 + mem_info_old['alloc']['buffers']) assert(mem_info[ 'lock']['buffers'] == 1 + mem_info_old[ 'lock']['buffers']) - af.set_device(dev) + af.set_device(curr_dev) a = af.randu(10,10) display_func(a) From 36fd392d3ca1dc7e3cdd520a6fa4b0603db4106b Mon Sep 17 00:00:00 2001 From: Pavan Yalamanchili Date: Mon, 14 Dec 2015 18:26:43 -0500 Subject: [PATCH 8/8] Updating CHANGELOG and the version number --- CHANGELOG.md | 13 +++++++++++++ setup.py | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53d13ab59..e446bc598 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +### v3.2.20151214 +- Bug fixes: + - `get_version()` now returns ints instead of `c_int` + - Fixed bug in `tests/simple/device.py` + +- The module now looks at additional paths when loading ArrayFire libraries. + - Link to the wiki is provided when `ctypes.cdll.LoadLibrary` fails. + +- New function: + - `info_str()` returns information similar to `info()` as a string. + +- Updated README.md with latest instructions + ### v3.2.20151211 - Feature parity with ArrayFire 3.2 libs - New computer vision functions: `sift`, `gloh`, `homography` diff --git a/setup.py b/setup.py index 277dd76cf..6b7ee9a5e 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ author="Pavan Yalamanchili", author_email="pavan@arrayfire.com", name="arrayfire", - version="3.2.20151211", + version="3.2.20151214", description="Python bindings for ArrayFire", license="BSD", url="http://arrayfire.com",