[arrayfire] 11/248: Initial commit for heterogenous api for ArrayFire backends
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Tue Nov 17 15:53:49 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to branch dfsg-clean
in repository arrayfire.
commit 857a6b4b796a15cfa575f38e5505c9eac870c244
Author: pradeep <pradeep at arrayfire.com>
Date: Tue Aug 25 16:52:36 2015 -0400
Initial commit for heterogenous api for ArrayFire backends
---
CMakeLists.txt | 7 ++++
hapi_examples/CMakeLists.txt | 13 +++++++
hapi_examples/test.cpp | 67 +++++++++++++++++++++++++++++++++++
include/af/defines.h | 12 +++++++
include/af/hapi.h | 21 +++++++++++
src/api/hapi/CMakeLists.txt | 39 +++++++++++++++++++++
src/api/hapi/data.cpp | 62 +++++++++++++++++++++++++++++++++
src/api/hapi/device.cpp | 43 +++++++++++++++++++++++
src/api/hapi/print.cpp | 29 ++++++++++++++++
src/api/hapi/symbol_manager.cpp | 77 +++++++++++++++++++++++++++++++++++++++++
src/api/hapi/symbol_manager.hpp | 64 ++++++++++++++++++++++++++++++++++
11 files changed, 434 insertions(+)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ef2a80a..7ba8e38 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,6 +35,8 @@ OPTION(BUILD_SIFT "Build ArrayFire nonfree algorithms" OFF)
MARK_AS_ADVANCED(BUILD_SIFT)
+OPTION(BUILD_HETEROGENOUS_API "Build Heterogeneous ArrayFire API" ON)
+
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
@@ -168,6 +170,11 @@ IF(${BUILD_OPENCL})
ADD_SUBDIRECTORY(src/backend/opencl)
ENDIF()
+IF(${BUILD_HETEROGENOUS_API})
+ ADD_SUBDIRECTORY(src/api/hapi)
+ ADD_SUBDIRECTORY(hapi_examples)
+ENDIF()
+
IF(${BUILD_DOCS})
ADD_SUBDIRECTORY(docs)
ENDIF()
diff --git a/hapi_examples/CMakeLists.txt b/hapi_examples/CMakeLists.txt
new file mode 100644
index 0000000..b7e7aea
--- /dev/null
+++ b/hapi_examples/CMakeLists.txt
@@ -0,0 +1,13 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+PROJECT(arrayfire-hapi-examples)
+
+ADD_DEFINITIONS(-std=c++11)
+
+IF(NOT TARGET af)
+ FIND_PACKAGE(ArrayFire REQUIRED)
+ INCLUDE_DIRECTORIES(${ArrayFire_INCLUDE_DIRS})
+ENDIF()
+
+ADD_EXECUTABLE(hapi_test test.cpp)
+
+TARGET_LINK_LIBRARIES(hapi_test af dl)
diff --git a/hapi_examples/test.cpp b/hapi_examples/test.cpp
new file mode 100644
index 0000000..a7ee36c
--- /dev/null
+++ b/hapi_examples/test.cpp
@@ -0,0 +1,67 @@
+/*******************************************************
+ * Copyright (c) 2015, ArrayFire
+ * All rights reserved.
+ *
+ * This file is distributed under 3-clause BSD license.
+ * The complete license agreement can be obtained at:
+ * http://arrayfire.com/licenses/BSD-3-Clause
+ ********************************************************/
+
+#include <arrayfire.h>
+#include <af/hapi.h>
+#include <cstdio>
+#include <cstdlib>
+#include <vector>
+#include <algorithm>
+
+using namespace af;
+
+std::vector<float> input(100);
+
+
+// Generate a random number between 0 and 1
+// return a uniform number in [0,1].
+double unifRand()
+{
+ return rand() / double(RAND_MAX);
+}
+
+void testBackend()
+{
+ af_info();
+
+ dim_t dims[] = {10, 10, 1, 1};
+
+ af_array A = 0;
+ af_array B = 0;
+
+ af_create_array(&A, &(input.front()), 4, dims, af_dtype::f32);
+ af_print_array(A);
+
+ af_constant(&B, 0.5, 4, dims, af_dtype::f32);
+ af_print_array(B);
+
+ af_release_array(A);
+ af_release_array(B);
+}
+
+int main(int argc, char *argv[])
+{
+ std::generate(input.begin(), input.end(), unifRand);
+
+ af_set_backend(AF_BACKEND_CPU);
+ testBackend();
+
+ af_set_backend(AF_BACKEND_OPENCL);
+ testBackend();
+
+ #ifdef WIN32 // pause in Windows
+ if (!(argc == 2 && argv[1][0] == '-')) {
+ printf("hit [enter]...");
+ fflush(stdout);
+ getchar();
+ }
+ #endif
+
+ return 0;
+}
diff --git a/include/af/defines.h b/include/af/defines.h
index 8587ef3..bc53cff 100644
--- a/include/af/defines.h
+++ b/include/af/defines.h
@@ -149,6 +149,11 @@ typedef enum {
/// not support graphics
///
AF_ERR_NO_GFX = 402,
+
+ // 500-599 Errors specific to heterogenous API
+ AF_ERR_LOAD_LIB = 501,
+ AF_ERR_SYM_LOAD = 502,
+
// 900-999 Errors from upstream libraries and runtimes
///
@@ -316,6 +321,12 @@ typedef enum {
AF_FIF_RAW = 34 ///< FreeImage Enum for RAW Camera Image File
} af_image_format;
+typedef enum {
+ AF_BACKEND_CPU,
+ AF_BACKEND_CUDA,
+ AF_BACKEND_OPENCL
+} af_backend;
+
// Below enum is purely added for example purposes
// it doesn't and shoudn't be used anywhere in the
// code. No Guarantee's provided if it is used.
@@ -342,6 +353,7 @@ namespace af
typedef af_norm_type normType;
typedef af_ycc_std YCCStd;
typedef af_image_format imageFormat;
+ typedef af_backend Backend;
}
#endif
diff --git a/include/af/hapi.h b/include/af/hapi.h
new file mode 100644
index 0000000..f6185a7
--- /dev/null
+++ b/include/af/hapi.h
@@ -0,0 +1,21 @@
+/*******************************************************
+ * Copyright (c) 2014, ArrayFire
+ * All rights reserved.
+ *
+ * This file is distributed under 3-clause BSD license.
+ * The complete license agreement can be obtained at:
+ * http://arrayfire.com/licenses/BSD-3-Clause
+ ********************************************************/
+
+#pragma once
+#include <af/defines.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+AFAPI af_err af_set_backend(const af_backend bknd);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/api/hapi/CMakeLists.txt b/src/api/hapi/CMakeLists.txt
new file mode 100644
index 0000000..23f7c8a
--- /dev/null
+++ b/src/api/hapi/CMakeLists.txt
@@ -0,0 +1,39 @@
+
+FILE(GLOB hapi_headers
+ "*.hpp"
+ "*.h")
+
+FILE(GLOB hapi_sources
+ "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
+
+ADD_LIBRARY(af SHARED
+ ${hapi_headers}
+ ${hapi_sources})
+
+IF(${BUILD_CPU})
+ ADD_DEPENDENCIES(af afcpu)
+ENDIF()
+
+IF(${BUILD_CUDA})
+ ADD_DEPENDENCIES(af afcuda)
+ENDIF()
+
+IF(${BUILD_OPENCL})
+ ADD_DEPENDENCIES(af afopencl)
+ENDIF()
+
+SET_TARGET_PROPERTIES(af PROPERTIES
+ VERSION "${AF_VERSION}"
+ SOVERSION "${AF_VERSION_MAJOR}")
+
+INSTALL(TARGETS af EXPORT AF DESTINATION "${AF_INSTALL_LIB_DIR}"
+ COMPONENT libraries)
+
+IF(APPLE)
+ INSTALL(SCRIPT "${CMAKE_MODULE_PATH}/osx_install/InstallTool.cmake")
+ENDIF(APPLE)
+
+EXPORT(TARGETS af FILE ArrayFireHAPI.cmake)
+INSTALL(EXPORT AF DESTINATION "${AF_INSTALL_CMAKE_DIR}"
+ COMPONENT cmake
+ FILE ArrayFireHAPI.cmake)
diff --git a/src/api/hapi/data.cpp b/src/api/hapi/data.cpp
new file mode 100644
index 0000000..cc042ef
--- /dev/null
+++ b/src/api/hapi/data.cpp
@@ -0,0 +1,62 @@
+/*******************************************************
+ * Copyright (c) 2014, ArrayFire
+ * All rights reserved.
+ *
+ * This file is distributed under 3-clause BSD license.
+ * The complete license agreement can be obtained at:
+ * http://arrayfire.com/licenses/BSD-3-Clause
+ ********************************************************/
+
+#include <af/array.h>
+#include <af/data.h>
+#include <functional>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <iostream>
+#include "symbol_manager.hpp"
+
+af_err af_create_array(af_array *result, const void * const data,
+ const unsigned ndims, const dim_t * const dims,
+ const af_dtype type)
+{
+ af_err errCode = AF_SUCCESS;
+ try {
+ AFSymbolManager& symbolManager = AFSymbolManager::getInstance();
+ errCode = symbolManager.call("af_create_array", result, data, ndims, dims, type);
+ } catch(std::logic_error &e) {
+ // FIXME: remove std::cerr
+ std::cerr<<e.what()<<std::endl;
+ errCode = AF_ERR_SYM_LOAD;
+ }
+ return errCode;
+}
+
+af_err af_constant(af_array *result, const double value,
+ const unsigned ndims, const dim_t * const dims,
+ const af_dtype type)
+{
+ af_err errCode = AF_SUCCESS;
+ try {
+ AFSymbolManager& symbolManager = AFSymbolManager::getInstance();
+ errCode = symbolManager.call("af_constant", result, value, ndims, dims, type);
+ } catch(std::logic_error &e) {
+ // FIXME: remove std::cerr
+ std::cerr<<e.what()<<std::endl;
+ errCode = AF_ERR_SYM_LOAD;
+ }
+ return errCode;
+}
+
+af_err af_release_array(af_array arr)
+{
+ af_err errCode = AF_SUCCESS;
+ try {
+ AFSymbolManager& symbolManager = AFSymbolManager::getInstance();
+ errCode = symbolManager.call("af_release_array", arr);
+ } catch(std::logic_error &e) {
+ // FIXME: remove std::cerr
+ std::cerr<<e.what()<<std::endl;
+ errCode = AF_ERR_SYM_LOAD;
+ }
+ return errCode;
+}
diff --git a/src/api/hapi/device.cpp b/src/api/hapi/device.cpp
new file mode 100644
index 0000000..dc4de07
--- /dev/null
+++ b/src/api/hapi/device.cpp
@@ -0,0 +1,43 @@
+/*******************************************************
+ * Copyright (c) 2015, ArrayFire
+ * All rights reserved.
+ *
+ * This file is distributed under 3-clause BSD license.
+ * The complete license agreement can be obtained at:
+ * http://arrayfire.com/licenses/BSD-3-Clause
+ ********************************************************/
+
+#include <af/hapi.h>
+#include <af/device.h>
+#include <functional>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <iostream>
+#include "symbol_manager.hpp"
+
+af_err af_set_backend(const af_backend bknd)
+{
+ af_err errCode = AF_SUCCESS;
+ try {
+ AFSymbolManager::getInstance().setBackend(bknd);
+ } catch(std::logic_error &e) {
+ // FIXME: remove std::cerr
+ std::cerr<<e.what()<<std::endl;
+ errCode = AF_ERR_LOAD_LIB;
+ }
+ return errCode;
+}
+
+af_err af_info()
+{
+ af_err errCode = AF_SUCCESS;
+ try {
+ AFSymbolManager& symbolManager = AFSymbolManager::getInstance();
+ errCode = symbolManager.call("af_info");
+ } catch(std::logic_error &e) {
+ // FIXME: remove std::cerr
+ std::cerr<<e.what()<<std::endl;
+ errCode = AF_ERR_SYM_LOAD;
+ }
+ return errCode;
+}
diff --git a/src/api/hapi/print.cpp b/src/api/hapi/print.cpp
new file mode 100644
index 0000000..3eb28cd
--- /dev/null
+++ b/src/api/hapi/print.cpp
@@ -0,0 +1,29 @@
+/*******************************************************
+ * Copyright (c) 2014, ArrayFire
+ * All rights reserved.
+ *
+ * This file is distributed under 3-clause BSD license.
+ * The complete license agreement can be obtained at:
+ * http://arrayfire.com/licenses/BSD-3-Clause
+ ********************************************************/
+
+#include <af/util.h>
+#include <functional>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <iostream>
+#include "symbol_manager.hpp"
+
+af_err af_print_array(const af_array arr)
+{
+ af_err errCode = AF_SUCCESS;
+ try {
+ AFSymbolManager& symbolManager = AFSymbolManager::getInstance();
+ errCode = symbolManager.call("af_print_array", arr);
+ } catch(std::logic_error &e) {
+ // FIXME: remove std::cerr
+ std::cerr<<e.what()<<std::endl;
+ errCode = AF_ERR_SYM_LOAD;
+ }
+ return errCode;
+}
diff --git a/src/api/hapi/symbol_manager.cpp b/src/api/hapi/symbol_manager.cpp
new file mode 100644
index 0000000..ce5bf18
--- /dev/null
+++ b/src/api/hapi/symbol_manager.cpp
@@ -0,0 +1,77 @@
+/*******************************************************
+ * Copyright (c) 2014, ArrayFire
+ * All rights reserved.
+ *
+ * This file is distributed under 3-clause BSD license.
+ * The complete license agreement can be obtained at:
+ * http://arrayfire.com/licenses/BSD-3-Clause
+ ********************************************************/
+
+#include "symbol_manager.hpp"
+
+AFSymbolManager& AFSymbolManager::getInstance()
+{
+ static AFSymbolManager symbolManager;
+ return symbolManager;
+}
+
+AFSymbolManager::AFSymbolManager()
+ : isCPULoaded(false), isCUDALoaded(false), isOCLLoaded(false)
+{
+ cpuHandle = dlopen("libafcpu.so", RTLD_LAZY);
+ if (cpuHandle) {
+ isCPULoaded = true;
+ activeHandle = cpuHandle;
+ }
+ cudaHandle = dlopen("libafcuda.so", RTLD_LAZY);
+ if (cudaHandle) {
+ isCUDALoaded = true;
+ activeHandle = cudaHandle;
+ }
+ oclHandle = dlopen("libafopencl.so", RTLD_LAZY);
+ if (oclHandle) {
+ isOCLLoaded = true;
+ activeHandle = oclHandle;
+ }
+}
+
+AFSymbolManager::~AFSymbolManager()
+{
+ if (isCPULoaded) {
+ dlclose(cpuHandle);
+ isCPULoaded = false;
+ }
+ if (isCUDALoaded) {
+ dlclose(cudaHandle);
+ isCUDALoaded = false;
+ }
+ if (isOCLLoaded) {
+ dlclose(oclHandle);
+ isOCLLoaded = false;
+ }
+}
+
+void AFSymbolManager::setBackend(af::Backend bknd)
+{
+ activeBknd = bknd;
+ switch (activeBknd) {
+ case af::Backend::AF_BACKEND_CPU:
+ if(isCPULoaded)
+ activeHandle = cpuHandle;
+ else
+ throw std::logic_error("can't load afcpu library");
+ break;
+ case af::Backend::AF_BACKEND_CUDA:
+ if(isCUDALoaded)
+ activeHandle = cudaHandle;
+ else
+ throw std::logic_error("can't load afcuda library");
+ break;
+ case af::Backend::AF_BACKEND_OPENCL:
+ if(isOCLLoaded)
+ activeHandle = oclHandle;
+ else
+ throw std::logic_error("can't load afopencl library");
+ break;
+ }
+}
diff --git a/src/api/hapi/symbol_manager.hpp b/src/api/hapi/symbol_manager.hpp
new file mode 100644
index 0000000..eea8f38
--- /dev/null
+++ b/src/api/hapi/symbol_manager.hpp
@@ -0,0 +1,64 @@
+/*******************************************************
+ * Copyright (c) 2014, ArrayFire
+ * All rights reserved.
+ *
+ * This file is distributed under 3-clause BSD license.
+ * The complete license agreement can be obtained at:
+ * http://arrayfire.com/licenses/BSD-3-Clause
+ ********************************************************/
+
+#include <af/defines.h>
+#include <functional>
+#include <string>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+class AFSymbolManager {
+ public:
+ static AFSymbolManager& getInstance();
+
+ ~AFSymbolManager();
+
+ void setBackend(af::Backend bnkd);
+
+ template<typename... CalleeArgs>
+ af_err call(const char* symbolName, CalleeArgs... args) {
+ using std::string;
+ using std::logic_error;
+
+ void* const handle = dlsym(activeHandle, symbolName);
+
+ if (!handle) {
+ char* const error = dlerror();
+ if (error) {
+ throw logic_error("can't find symbol: "+string(symbolName)+" - "+error);
+ }
+ }
+
+ std::function<af_err (CalleeArgs...)> callee = reinterpret_cast<af_err (*)(CalleeArgs...)>(handle);
+
+ return callee(args...);
+ }
+
+ protected:
+ AFSymbolManager();
+
+ // Following two declarations are required to
+ // avoid copying accidental copy/assignment
+ // of instance returned by getInstance to other
+ // variables
+ AFSymbolManager(AFSymbolManager const&);
+ void operator=(AFSymbolManager const&);
+
+ private:
+ bool isCPULoaded;
+ bool isCUDALoaded;
+ bool isOCLLoaded;
+
+ void* cpuHandle;
+ void* cudaHandle;
+ void* oclHandle;
+
+ af::Backend activeBknd;
+ void* activeHandle;
+};
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/arrayfire.git
More information about the debian-science-commits
mailing list