[arrayfire] 220/248: Added array/backend checks to unified backend

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Tue Nov 17 15:54:29 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 efd5c0259868dd346c832768256ede22703b8b64
Author: Shehzan Mohammed <shehzan at arrayfire.com>
Date:   Tue Nov 10 12:18:09 2015 -0500

    Added array/backend checks to unified backend
    
    * Checks whether all input arrays are for the active backend
    * Throws error 503 for mismatch
---
 include/af/defines.h               |  1 +
 src/api/unified/algorithm.cpp      | 13 +++++++++++++
 src/api/unified/arith.cpp          |  3 +++
 src/api/unified/array.cpp          | 12 ++++++++++++
 src/api/unified/blas.cpp           |  4 ++++
 src/api/unified/data.cpp           | 18 ++++++++++++++++++
 src/api/unified/device.cpp         |  9 ++++++---
 src/api/unified/graphics.cpp       |  5 +++++
 src/api/unified/image.cpp          | 33 +++++++++++++++++++++++++++++++++
 src/api/unified/index.cpp          |  5 +++++
 src/api/unified/lapack.cpp         | 14 ++++++++++++++
 src/api/unified/signal.cpp         | 18 ++++++++++++++++++
 src/api/unified/statistics.cpp     | 14 ++++++++++++++
 src/api/unified/symbol_manager.cpp | 25 ++++++++++++++++++++++++-
 src/api/unified/symbol_manager.hpp | 38 ++++++++++++++++++++++++++++++++++----
 src/api/unified/util.cpp           |  5 +++++
 src/api/unified/vision.cpp         | 10 ++++++++++
 17 files changed, 219 insertions(+), 8 deletions(-)

diff --git a/include/af/defines.h b/include/af/defines.h
index dc36a27..911779c 100644
--- a/include/af/defines.h
+++ b/include/af/defines.h
@@ -153,6 +153,7 @@ typedef enum {
     // 500-599 Errors specific to heterogenous API
     AF_ERR_LOAD_LIB       = 501,
     AF_ERR_LOAD_SYM       = 502,
+    AF_ERR_ARR_BKND_MISMATCH    = 503,
 
     // 900-999 Errors from upstream libraries and runtimes
 
diff --git a/src/api/unified/algorithm.cpp b/src/api/unified/algorithm.cpp
index 97f3b5e..934b7ae 100644
--- a/src/api/unified/algorithm.cpp
+++ b/src/api/unified/algorithm.cpp
@@ -14,6 +14,7 @@
 #define ALGO_HAPI_DEF(af_func) \
 af_err af_func(af_array* out, const af_array in, const int dim) \
 { \
+    CHECK_ARRAYS(in); \
     return CALL(out, in, dim); \
 }
 
@@ -33,6 +34,7 @@ ALGO_HAPI_DEF(af_diff2)
 #define ALGO_HAPI_DEF(af_func_nan) \
 af_err af_func_nan(af_array* out, const af_array in, const int dim, const double nanval) \
 { \
+    CHECK_ARRAYS(in); \
     return CALL(out, in, dim, nanval); \
 }
 
@@ -44,6 +46,7 @@ ALGO_HAPI_DEF(af_product_nan)
 #define ALGO_HAPI_DEF(af_func_all) \
 af_err af_func_all(double *real, double *imag, const af_array in) \
 { \
+    CHECK_ARRAYS(in); \
     return CALL(real, imag, in);\
 }
 
@@ -60,6 +63,7 @@ ALGO_HAPI_DEF(af_count_all)
 #define ALGO_HAPI_DEF(af_func_nan_all) \
 af_err af_func_nan_all(double *real, double *imag, const af_array in, const double nanval) \
 { \
+    CHECK_ARRAYS(in); \
     return CALL(real, imag, in, nanval);\
 }
 
@@ -72,6 +76,7 @@ ALGO_HAPI_DEF(af_product_nan_all)
 #define ALGO_HAPI_DEF(af_ifunc) \
 af_err af_ifunc(af_array* out, af_array *idx, const af_array in, const int dim) \
 { \
+    CHECK_ARRAYS(in); \
     return CALL(out, idx, in, dim); \
 }
 
@@ -83,6 +88,7 @@ ALGO_HAPI_DEF(af_imax)
 #define ALGO_HAPI_DEF(af_ifunc_all) \
 af_err af_ifunc_all(double *real, double *imag, unsigned *idx, const af_array in) \
 { \
+    CHECK_ARRAYS(in); \
     return CALL(real, imag, idx, in);\
 }
 
@@ -94,17 +100,20 @@ ALGO_HAPI_DEF(af_imax_all)
 
 af_err af_where(af_array *idx, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(idx, in);
 }
 
 af_err af_sort(af_array *out, const af_array in, const unsigned dim, const bool isAscending)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, dim, isAscending);
 }
 
 af_err af_sort_index(af_array *out, af_array *indices, const af_array in,
                      const unsigned dim, const bool isAscending)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, indices, in, dim, isAscending);
 }
 
@@ -112,11 +121,13 @@ af_err af_sort_by_key(af_array *out_keys, af_array *out_values,
                       const af_array keys, const af_array values,
                       const unsigned dim, const bool isAscending)
 {
+    CHECK_ARRAYS(keys, values);
     return CALL(out_keys, out_values, keys, values, dim, isAscending);
 }
 
 af_err af_set_unique(af_array *out, const af_array in, const bool is_sorted)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, is_sorted);
 }
 
@@ -124,6 +135,7 @@ af_err af_set_union(af_array *out,
                     const af_array first, const af_array second,
                     const bool is_unique)
 {
+    CHECK_ARRAYS(first, second);
     return CALL(out, first, second, is_unique);
 }
 
@@ -131,5 +143,6 @@ af_err af_set_intersect(af_array *out,
                         const af_array first, const af_array second,
                         const bool is_unique)
 {
+    CHECK_ARRAYS(first, second);
     return CALL(out, first, second, is_unique);
 }
diff --git a/src/api/unified/arith.cpp b/src/api/unified/arith.cpp
index a4d3f30..c811500 100644
--- a/src/api/unified/arith.cpp
+++ b/src/api/unified/arith.cpp
@@ -14,6 +14,7 @@
 #define BINARY_HAPI_DEF(af_func) \
 af_err af_func(af_array* out, const af_array lhs, const af_array rhs, const bool batchMode) \
 { \
+    CHECK_ARRAYS(lhs, rhs); \
     return CALL(out, lhs, rhs, batchMode); \
 }
 
@@ -46,12 +47,14 @@ BINARY_HAPI_DEF(af_hypot)
 
 af_err af_cast(af_array *out, const af_array in, const af_dtype type)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, type);
 }
 
 #define UNARY_HAPI_DEF(af_func) \
 af_err af_func(af_array* out, const af_array in) \
 { \
+    CHECK_ARRAYS(in); \
     return CALL(out, in); \
 }
 
diff --git a/src/api/unified/array.cpp b/src/api/unified/array.cpp
index 020a2e3..59158ca 100644
--- a/src/api/unified/array.cpp
+++ b/src/api/unified/array.cpp
@@ -22,62 +22,74 @@ af_err af_create_handle(af_array *arr, const unsigned ndims, const dim_t * const
 
 af_err af_copy_array(af_array *arr, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(arr, in);
 }
 
 af_err af_write_array(af_array arr, const void *data, const size_t bytes, af_source src)
 {
+    CHECK_ARRAYS(arr);
     return CALL(arr, data, bytes, src);
 }
 
 af_err af_get_data_ptr(void *data, const af_array arr)
 {
+    CHECK_ARRAYS(arr);
     return CALL(data, arr);
 }
 
 af_err af_release_array(af_array arr)
 {
+    CHECK_ARRAYS(arr);
     return CALL(arr);
 }
 
 af_err af_retain_array(af_array *out, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in);
 }
 
 af_err af_get_data_ref_count(int *use_count, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(use_count, in);
 }
 
 af_err af_eval(af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(in);
 }
 
 af_err af_get_elements(dim_t *elems, const af_array arr)
 {
+    CHECK_ARRAYS(arr);
     return CALL(elems, arr);
 }
 
 af_err af_get_type(af_dtype *type, const af_array arr)
 {
+    CHECK_ARRAYS(arr);
     return CALL(type, arr);
 }
 
 af_err af_get_dims(dim_t *d0, dim_t *d1, dim_t *d2, dim_t *d3, const af_array arr)
 {
+    CHECK_ARRAYS(arr);
     return CALL(d0, d1, d2, d3, arr);
 }
 
 af_err af_get_numdims(unsigned *result, const af_array arr)
 {
+    CHECK_ARRAYS(arr);
     return CALL(result, arr);
 }
 
 #define ARRAY_HAPI_DEF(af_func) \
 af_err af_func(bool *result, const af_array arr)\
 {\
+    CHECK_ARRAYS(arr); \
     return CALL(result, arr);\
 }
 
diff --git a/src/api/unified/blas.cpp b/src/api/unified/blas.cpp
index 8080f05..547e3ac 100644
--- a/src/api/unified/blas.cpp
+++ b/src/api/unified/blas.cpp
@@ -14,6 +14,7 @@ af_err af_matmul( af_array *out ,
         const af_array lhs, const af_array rhs,
         const af_mat_prop optLhs, const af_mat_prop optRhs)
 {
+    CHECK_ARRAYS(lhs, rhs);
     return CALL(out, lhs, rhs, optLhs, optRhs);
 }
 
@@ -22,15 +23,18 @@ af_err af_dot(    af_array *out,
         const af_array lhs, const af_array rhs,
         const af_mat_prop optLhs, const af_mat_prop optRhs)
 {
+    CHECK_ARRAYS(lhs, rhs);
     return CALL(out, lhs, rhs, optLhs, optRhs);
 }
 
 af_err af_transpose(af_array *out, af_array in, const bool conjugate)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, conjugate);
 }
 
 af_err af_transpose_inplace(af_array in, const bool conjugate)
 {
+    CHECK_ARRAYS(in);
     return CALL(in, conjugate);
 }
diff --git a/src/api/unified/data.cpp b/src/api/unified/data.cpp
index 3543246..236b11f 100644
--- a/src/api/unified/data.cpp
+++ b/src/api/unified/data.cpp
@@ -76,87 +76,105 @@ af_err af_identity(af_array *out, const unsigned ndims, const dim_t * const dims
 
 af_err af_diag_create(af_array *out, const af_array in, const int num)
 {
+    CHECK_ARRAYS(in)
     return CALL(out, in, num);
 }
 
 af_err af_diag_extract(af_array *out, const af_array in, const int num)
 {
+    CHECK_ARRAYS(in)
     return CALL(out, in, num);
 }
 
 af_err af_join(af_array *out, const int dim, const af_array first, const af_array second)
 {
+    CHECK_ARRAYS(first, second)
     return CALL(out, dim, first, second);
 }
 
 af_err af_join_many(af_array *out, const int dim, const unsigned n_arrays, const af_array *inputs)
 {
+    for(unsigned i = 0; i < n_arrays; i++)
+        CHECK_ARRAYS(inputs[i]);
     return CALL(out, dim, n_arrays, inputs);
 }
 
 af_err af_tile(af_array *out, const af_array in,
         const unsigned x, const unsigned y, const unsigned z, const unsigned w)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, x, y, z, w);
 }
 
 af_err af_reorder(af_array *out, const af_array in,
         const unsigned x, const unsigned y, const unsigned z, const unsigned w)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, x, y, z, w);
 }
 
 af_err af_shift(af_array *out, const af_array in, const int x, const int y, const int z, const int w)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, x, y, z, w);
 }
 
 af_err af_moddims(af_array *out, const af_array in, const unsigned ndims, const dim_t * const dims)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, ndims, dims);
 }
 
 af_err af_flat(af_array *out, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in);
 }
 
 af_err af_flip(af_array *out, const af_array in, const unsigned dim)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, dim);
 }
 
 af_err af_lower(af_array *out, const af_array in, bool is_unit_diag)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, is_unit_diag);
 }
 
 af_err af_upper(af_array *out, const af_array in, bool is_unit_diag)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, is_unit_diag);
 }
 
 af_err af_select(af_array *out, const af_array cond, const af_array a, const af_array b)
 {
+    CHECK_ARRAYS(cond, a, b);
     return CALL(out, cond, a, b);
 }
 
 af_err af_select_scalar_r(af_array *out, const af_array cond, const af_array a, const double b)
 {
+    CHECK_ARRAYS(cond, a);
     return CALL(out, cond, a, b);
 }
 
 af_err af_select_scalar_l(af_array *out, const af_array cond, const double a, const af_array b)
 {
+    CHECK_ARRAYS(cond, b);
     return CALL(out, cond, a, b);
 }
 
 af_err af_replace(af_array a, const af_array cond, const af_array b)
 {
+    CHECK_ARRAYS(a, cond, b);
     return CALL(a, cond, b);
 }
 
 af_err af_replace_scalar(af_array a, const af_array cond, const double b)
 {
+    CHECK_ARRAYS(a, cond);
     return CALL(a, cond, b);
 }
diff --git a/src/api/unified/device.cpp b/src/api/unified/device.cpp
index dccb2e8..a9affa5 100644
--- a/src/api/unified/device.cpp
+++ b/src/api/unified/device.cpp
@@ -13,18 +13,18 @@
 
 af_err af_set_backend(const af_backend bknd)
 {
-    return AFSymbolManager::getInstance().setBackend(bknd);
+    return unified::AFSymbolManager::getInstance().setBackend(bknd);
 }
 
 af_err af_get_backend_count(unsigned* num_backends)
 {
-    *num_backends = AFSymbolManager::getInstance().getBackendCount();
+    *num_backends = unified::AFSymbolManager::getInstance().getBackendCount();
     return AF_SUCCESS;
 }
 
 af_err af_get_available_backends(int* result)
 {
-    *result = AFSymbolManager::getInstance().getAvailableBackends();
+    *result = unified::AFSymbolManager::getInstance().getAvailableBackends();
     return AF_SUCCESS;
 }
 
@@ -116,15 +116,18 @@ af_err af_get_mem_step_size(size_t *step_bytes)
 
 af_err af_lock_device_ptr(const af_array arr)
 {
+    CHECK_ARRAYS(arr);
     return CALL(arr);
 }
 
 af_err af_unlock_device_ptr(const af_array arr)
 {
+    CHECK_ARRAYS(arr);
     return CALL(arr);
 }
 
 af_err af_get_device_ptr(void **ptr, const af_array arr)
 {
+    CHECK_ARRAYS(arr);
     return CALL(ptr, arr);
 }
diff --git a/src/api/unified/graphics.cpp b/src/api/unified/graphics.cpp
index ca74f02..81076f2 100644
--- a/src/api/unified/graphics.cpp
+++ b/src/api/unified/graphics.cpp
@@ -34,26 +34,31 @@ af_err af_set_size(const af_window wind, const unsigned w, const unsigned h)
 
 af_err af_draw_image(const af_window wind, const af_array in, const af_cell* const props)
 {
+    CHECK_ARRAYS(in);
     return CALL(wind, in, props);
 }
 
 af_err af_draw_plot(const af_window wind, const af_array X, const af_array Y, const af_cell* const props)
 {
+    CHECK_ARRAYS(X, Y);
     return CALL(wind, X, Y, props);
 }
 
 af_err af_draw_plot3(const af_window wind, const af_array P, const af_cell* const props)
 {
+    CHECK_ARRAYS(P);
     return CALL(wind, P, props);
 }
 
 af_err af_draw_hist(const af_window wind, const af_array X, const double minval, const double maxval, const af_cell* const props)
 {
+    CHECK_ARRAYS(X);
     return CALL(wind, X, minval, maxval, props);
 }
 
 af_err af_draw_surface(const af_window wind, const af_array xVals, const af_array yVals, const af_array S, const af_cell* const props)
 {
+    CHECK_ARRAYS(xVals, yVals, S);
     return CALL(wind, xVals, yVals, S, props);
 }
 
diff --git a/src/api/unified/image.cpp b/src/api/unified/image.cpp
index d3c4d07..d0f9aa6 100644
--- a/src/api/unified/image.cpp
+++ b/src/api/unified/image.cpp
@@ -13,6 +13,7 @@
 
 af_err af_gradient(af_array *dx, af_array *dy, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(dx, dy, in);
 }
 
@@ -23,6 +24,7 @@ af_err af_load_image(af_array *out, const char* filename, const bool isColor)
 
 af_err af_save_image(const char* filename, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(filename, in);
 }
 
@@ -33,6 +35,7 @@ af_err af_load_image_memory(af_array *out, const void* ptr)
 
 af_err af_save_image_memory(void** ptr, const af_array in, const af_image_format format)
 {
+    CHECK_ARRAYS(in);
     return CALL(ptr, in, format);
 }
 
@@ -48,11 +51,13 @@ af_err af_load_image_native(af_array *out, const char* filename)
 
 af_err af_save_image_native(const char* filename, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(filename, in);
 }
 
 af_err af_resize(af_array *out, const af_array in, const dim_t odim0, const dim_t odim1, const af_interp_type method)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, odim0, odim1, method);
 }
 
@@ -60,24 +65,28 @@ af_err af_transform(af_array *out, const af_array in, const af_array transform,
         const dim_t odim0, const dim_t odim1,
         const af_interp_type method, const bool inverse)
 {
+    CHECK_ARRAYS(in, transform);
     return CALL(out, in, transform, odim0, odim1, method, inverse);
 }
 
 af_err af_rotate(af_array *out, const af_array in, const float theta,
         const bool crop, const af_interp_type method)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, theta, crop, method);
 }
 
 af_err af_translate(af_array *out, const af_array in, const float trans0, const float trans1,
         const dim_t odim0, const dim_t odim1, const af_interp_type method)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, trans0, trans1, odim0, odim1, method);
 }
 
 af_err af_scale(af_array *out, const af_array in, const float scale0, const float scale1,
         const dim_t odim0, const dim_t odim1, const af_interp_type method)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, scale0, scale1, odim0, odim1, method);
 }
 
@@ -85,81 +94,97 @@ af_err af_skew(af_array *out, const af_array in, const float skew0, const float
         const dim_t odim0, const dim_t odim1, const af_interp_type method,
         const bool inverse)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, skew0, skew1, odim0, odim1, method, inverse);
 }
 
 af_err af_histogram(af_array *out, const af_array in, const unsigned nbins, const double minval, const double maxval)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, nbins, minval, maxval);
 }
 
 af_err af_dilate(af_array *out, const af_array in, const af_array mask)
 {
+    CHECK_ARRAYS(in, mask);
     return CALL(out, in, mask);
 }
 
 af_err af_dilate3(af_array *out, const af_array in, const af_array mask)
 {
+    CHECK_ARRAYS(in, mask);
     return CALL(out, in, mask);
 }
 
 af_err af_erode(af_array *out, const af_array in, const af_array mask)
 {
+    CHECK_ARRAYS(in, mask);
     return CALL(out, in, mask);
 }
 
 af_err af_erode3(af_array *out, const af_array in, const af_array mask)
 {
+    CHECK_ARRAYS(in, mask);
     return CALL(out, in, mask);
 }
 
 af_err af_bilateral(af_array *out, const af_array in, const float spatial_sigma, const float chromatic_sigma, const bool isColor)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, spatial_sigma, chromatic_sigma, isColor);
 }
 
 af_err af_mean_shift(af_array *out, const af_array in, const float spatial_sigma, const float chromatic_sigma, const unsigned iter, const bool is_color)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, spatial_sigma, chromatic_sigma, iter, is_color);
 }
 
 af_err af_medfilt(af_array *out, const af_array in, const dim_t wind_length, const dim_t wind_width, const af_border_type edge_pad)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, wind_length, wind_width, edge_pad);
 }
 
 af_err af_minfilt(af_array *out, const af_array in, const dim_t wind_length, const dim_t wind_width, const af_border_type edge_pad)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, wind_length, wind_width, edge_pad);
 }
 
 af_err af_maxfilt(af_array *out, const af_array in, const dim_t wind_length, const dim_t wind_width, const af_border_type edge_pad)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, wind_length, wind_width, edge_pad);
 }
 
 af_err af_regions(af_array *out, const af_array in, const af_connectivity connectivity, const af_dtype ty)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, connectivity, ty);
 }
 
 af_err af_sobel_operator(af_array *dx, af_array *dy, const af_array img, const unsigned ker_size)
 {
+    CHECK_ARRAYS(img);
     return CALL(dx, dy, img, ker_size);
 }
 
 af_err af_rgb2gray(af_array* out, const af_array in, const float rPercent, const float gPercent, const float bPercent)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, rPercent, gPercent, bPercent);
 }
 
 af_err af_gray2rgb(af_array* out, const af_array in, const float rFactor, const float gFactor, const float bFactor)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, rFactor, gFactor, bFactor);
 }
 
 af_err af_hist_equal(af_array *out, const af_array in, const af_array hist)
 {
+    CHECK_ARRAYS(in, hist);
     return CALL(out, in, hist);
 }
 
@@ -172,16 +197,19 @@ af_err af_gaussian_kernel(af_array *out,
 
 af_err af_hsv2rgb(af_array* out, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in);
 }
 
 af_err af_rgb2hsv(af_array* out, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in);
 }
 
 af_err af_color_space(af_array *out, const af_array image, const af_cspace_t to, const af_cspace_t from)
 {
+    CHECK_ARRAYS(image);
     return CALL(out, image, to, from);
 }
 
@@ -189,6 +217,7 @@ af_err af_unwrap(af_array *out, const af_array in, const dim_t wx, const dim_t w
         const dim_t sx, const dim_t sy, const dim_t px, const dim_t py,
         const bool is_column)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, wx, wy, sx, sy, px, py, is_column);
 }
 
@@ -200,20 +229,24 @@ af_err af_wrap(af_array *out,
         const dim_t px, const dim_t py,
         const bool is_column)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, ox, oy, wx, wy, sx, sy, px, py, is_column);
 }
 
 af_err af_sat(af_array *out, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in);
 }
 
 af_err af_ycbcr2rgb(af_array* out, const af_array in, const af_ycc_std standard)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, standard);
 }
 
 af_err af_rgb2ycbcr(af_array* out, const af_array in, const af_ycc_std standard)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, standard);
 }
diff --git a/src/api/unified/index.cpp b/src/api/unified/index.cpp
index 36c671e..0927dd8 100644
--- a/src/api/unified/index.cpp
+++ b/src/api/unified/index.cpp
@@ -15,6 +15,7 @@ af_err af_index(  af_array *out,
         const af_array in,
         const unsigned ndims, const af_seq* const index)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, ndims, index);
 }
 
@@ -22,6 +23,7 @@ af_err af_lookup( af_array *out,
         const af_array in, const af_array indices,
         const unsigned dim)
 {
+    CHECK_ARRAYS(in, indices);
     return CALL(out, in, indices, dim);
 }
 
@@ -30,6 +32,7 @@ af_err af_assign_seq( af_array *out,
         const unsigned ndims, const af_seq* const indices,
         const af_array rhs)
 {
+    CHECK_ARRAYS(lhs, rhs);
     return CALL(out, lhs, ndims, indices, rhs);
 }
 
@@ -37,6 +40,7 @@ af_err af_index_gen(  af_array *out,
         const af_array in,
         const dim_t ndims, const af_index_t* indices)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, ndims, indices);
 }
 
@@ -45,5 +49,6 @@ af_err af_assign_gen( af_array *out,
         const dim_t ndims, const af_index_t* indices,
         const af_array rhs)
 {
+    CHECK_ARRAYS(lhs, rhs);
     return CALL(out, lhs, ndims, indices, rhs);
 }
diff --git a/src/api/unified/lapack.cpp b/src/api/unified/lapack.cpp
index f60009c..b2364ac 100644
--- a/src/api/unified/lapack.cpp
+++ b/src/api/unified/lapack.cpp
@@ -13,72 +13,86 @@
 
 af_err af_svd(af_array *u, af_array *s, af_array *vt, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(u, s, vt, in);
 }
 
 af_err af_svd_inplace(af_array *u, af_array *s, af_array *vt, af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(u, s, vt, in);
 }
 
 af_err af_lu(af_array *lower, af_array *upper, af_array *pivot, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(lower, upper, pivot, in);
 }
 
 af_err af_lu_inplace(af_array *pivot, af_array in, const bool is_lapack_piv)
 {
+    CHECK_ARRAYS(in);
     return CALL(pivot, in, is_lapack_piv);
 }
 
 af_err af_qr(af_array *q, af_array *r, af_array *tau, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(q, r, tau, in);
 }
 
 af_err af_qr_inplace(af_array *tau, af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(tau, in);
 }
 
 af_err af_cholesky(af_array *out, int *info, const af_array in, const bool is_upper)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, info, in, is_upper);
 }
 
 af_err af_cholesky_inplace(int *info, af_array in, const bool is_upper)
 {
+    CHECK_ARRAYS(in);
     return CALL(info, in, is_upper);
 }
 
 af_err af_solve(af_array *x, const af_array a, const af_array b,
         const af_mat_prop options)
 {
+    CHECK_ARRAYS(a, b);
     return CALL(x, a, b, options);
 }
 
 af_err af_solve_lu(af_array *x, const af_array a, const af_array piv,
         const af_array b, const af_mat_prop options)
 {
+    CHECK_ARRAYS(a, piv, b);
     return CALL(x, a, piv, b, options);
 }
 
 af_err af_inverse(af_array *out, const af_array in, const af_mat_prop options)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, options);
 }
 
 af_err af_rank(unsigned *rank, const af_array in, const double tol)
 {
+    CHECK_ARRAYS(in);
     return CALL(rank, in, tol);
 }
 
 af_err af_det(double *det_real, double *det_imag, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(det_real, det_imag, in);
 }
 
 af_err af_norm(double *out, const af_array in, const af_norm_type type, const double p, const double q)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, type, p, q);
 }
diff --git a/src/api/unified/signal.cpp b/src/api/unified/signal.cpp
index 46ab5f3..138a0d6 100644
--- a/src/api/unified/signal.cpp
+++ b/src/api/unified/signal.cpp
@@ -13,17 +13,20 @@
 
 af_err af_approx1(af_array *out, const af_array in, const af_array pos, const af_interp_type method, const float offGrid)
 {
+    CHECK_ARRAYS(in, pos);
     return CALL(out, in, pos, method, offGrid);
 }
 
 af_err af_approx2(af_array *out, const af_array in, const af_array pos0, const af_array pos1, const af_interp_type method, const float offGrid)
 {
+    CHECK_ARRAYS(in, pos0, pos1);
     return CALL(out, in, pos0, pos1, method, offGrid);
 }
 
 #define FFT_HAPI_DEF(af_func)\
 af_err af_func(af_array in, const double norm_factor)\
 {\
+    CHECK_ARRAYS(in); \
     return CALL(in, norm_factor);\
 }
 
@@ -36,52 +39,62 @@ FFT_HAPI_DEF(af_ifft3_inplace)
 
 af_err af_fft(af_array *out, const af_array in, const double norm_factor, const dim_t odim0)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, norm_factor, odim0);
 }
 
 af_err af_fft2(af_array *out, const af_array in, const double norm_factor, const dim_t odim0, const dim_t odim1)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, norm_factor, odim0, odim1);
 }
 
 af_err af_fft3(af_array *out, const af_array in, const double norm_factor, const dim_t odim0, const dim_t odim1, const dim_t odim2)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, norm_factor, odim0, odim1, odim2);
 }
 
 af_err af_ifft(af_array *out, const af_array in, const double norm_factor, const dim_t odim0)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, norm_factor, odim0);
 }
 
 af_err af_ifft2(af_array *out, const af_array in, const double norm_factor, const dim_t odim0, const dim_t odim1)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, norm_factor, odim0, odim1);
 }
 
 af_err af_ifft3(af_array *out, const af_array in, const double norm_factor, const dim_t odim0, const dim_t odim1, const dim_t odim2)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, norm_factor, odim0, odim1, odim2);
 }
 
 af_err af_fft_r2c (af_array *out, const af_array in, const double norm_factor, const dim_t pad0)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, norm_factor, pad0);
 }
 
 af_err af_fft2_r2c(af_array *out, const af_array in, const double norm_factor, const dim_t pad0, const dim_t pad1)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, norm_factor, pad0, pad1);
 }
 
 af_err af_fft3_r2c(af_array *out, const af_array in, const double norm_factor, const dim_t pad0, const dim_t pad1, const dim_t pad2)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, norm_factor, pad0, pad1, pad2);
 }
 
 #define FFTC2R_HAPI_DEF(af_func)\
 af_err af_func(af_array *out, const af_array in, const double norm_factor, const bool is_odd)\
 {\
+    CHECK_ARRAYS(in); \
     return CALL(out, in, norm_factor, is_odd);\
 }
 
@@ -92,6 +105,7 @@ FFTC2R_HAPI_DEF(af_fft3_c2r)
 #define CONV_HAPI_DEF(af_func)\
 af_err af_func(af_array *out, const af_array signal, const af_array filter, const af_conv_mode mode, af_conv_domain domain)\
 {\
+    CHECK_ARRAYS(signal, filter); \
     return CALL(out, signal, filter, mode, domain);\
 }
 
@@ -102,6 +116,7 @@ CONV_HAPI_DEF(af_convolve3)
 #define FFT_CONV_HAPI_DEF(af_func)\
 af_err af_func(af_array *out, const af_array signal, const af_array filter, const af_conv_mode mode)\
 {\
+    CHECK_ARRAYS(signal, filter); \
     return CALL(out, signal, filter, mode);\
 }
 
@@ -111,15 +126,18 @@ FFT_CONV_HAPI_DEF(af_fft_convolve3)
 
 af_err af_convolve2_sep(af_array *out, const af_array col_filter, const af_array row_filter, const af_array signal, const af_conv_mode mode)
 {
+    CHECK_ARRAYS(col_filter, row_filter, signal);
     return CALL(out, col_filter, row_filter, signal, mode);
 }
 
 af_err af_fir(af_array *y, const af_array b, const af_array x)
 {
+    CHECK_ARRAYS(b, x);
     return CALL(y, b, x);
 }
 
 af_err af_iir(af_array *y, const af_array b, const af_array a, const af_array x)
 {
+    CHECK_ARRAYS(b, a, x);
     return CALL(y, b, a, x);
 }
diff --git a/src/api/unified/statistics.cpp b/src/api/unified/statistics.cpp
index 18705f6..9f72674 100644
--- a/src/api/unified/statistics.cpp
+++ b/src/api/unified/statistics.cpp
@@ -13,70 +13,84 @@
 
 af_err af_mean(af_array *out, const af_array in, const dim_t dim)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, dim);
 }
 
 af_err af_mean_weighted(af_array *out, const af_array in, const af_array weights, const dim_t dim)
 {
+    CHECK_ARRAYS(in, weights);
     return CALL(out, in, weights, dim);
 }
 
 af_err af_var(af_array *out, const af_array in, const bool isbiased, const dim_t dim)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, isbiased, dim);
 }
 
 af_err af_var_weighted(af_array *out, const af_array in, const af_array weights, const dim_t dim)
 {
+    CHECK_ARRAYS(in, weights);
     return CALL(out, in, weights, dim);
 }
 
 af_err af_stdev(af_array *out, const af_array in, const dim_t dim)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, dim);
 }
 
 af_err af_cov(af_array* out, const af_array X, const af_array Y, const bool isbiased)
 {
+    CHECK_ARRAYS(X, Y);
     return CALL(out, X, Y, isbiased);
 }
 
 af_err af_median(af_array* out, const af_array in, const dim_t dim)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, dim);
 }
 
 af_err af_mean_all(double *real, double *imag, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(real, imag, in);
 }
 
 af_err af_mean_all_weighted(double *real, double *imag, const af_array in, const af_array weights)
 {
+    CHECK_ARRAYS(in, weights);
     return CALL(real, imag, in, weights);
 }
 
 af_err af_var_all(double *realVal, double *imagVal, const af_array in, const bool isbiased)
 {
+    CHECK_ARRAYS(in);
     return CALL(realVal, imagVal, in, isbiased);
 }
 
 af_err af_var_all_weighted(double *realVal, double *imagVal, const af_array in, const af_array weights)
 {
+    CHECK_ARRAYS(in, weights);
     return CALL(realVal, imagVal, in, weights);
 }
 
 af_err af_stdev_all(double *real, double *imag, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(real, imag, in);
 }
 
 af_err af_median_all(double *realVal, double *imagVal, const af_array in)
 {
+    CHECK_ARRAYS(in);
     return CALL(realVal, imagVal, in);
 }
 
 af_err af_corrcoef(double *realVal, double *imagVal, const af_array X, const af_array Y)
 {
+    CHECK_ARRAYS(X, Y);
     return CALL(realVal, imagVal, X, Y);
 }
diff --git a/src/api/unified/symbol_manager.cpp b/src/api/unified/symbol_manager.cpp
index 0f1219b..c29908a 100644
--- a/src/api/unified/symbol_manager.cpp
+++ b/src/api/unified/symbol_manager.cpp
@@ -15,6 +15,9 @@
 using std::string;
 using std::replace;
 
+namespace unified
+{
+
 static const string LIB_AF_BKND_NAME[NUM_BACKENDS] = {"cpu", "cuda", "opencl"};
 #if defined(OS_WIN)
 static const string LIB_AF_BKND_PREFIX = "af";
@@ -144,6 +147,7 @@ AFSymbolManager::AFSymbolManager()
         bkndHandles[backend] = openDynLibrary(backend);
         if (bkndHandles[backend]) {
             activeHandle = bkndHandles[backend];
+            activeBackend = (af_backend)order[i];
             numBackends++;
             backendsAvailable += order[i];
         }
@@ -152,6 +156,7 @@ AFSymbolManager::AFSymbolManager()
     // inorder to use it in ::setBackend when
     // the user passes AF_BACKEND_DEFAULT
     defaultHandle = activeHandle;
+    defaultBackend = activeBackend;
 }
 
 AFSymbolManager::~AFSymbolManager()
@@ -178,15 +183,33 @@ af_err AFSymbolManager::setBackend(af::Backend bknd)
     if (bknd==AF_BACKEND_DEFAULT) {
         if (defaultHandle) {
             activeHandle = defaultHandle;
+            activeBackend = defaultBackend;
             return AF_SUCCESS;
         } else
             return AF_ERR_LOAD_LIB;
     }
-    unsigned idx = bknd - 1;
+    int idx = bknd >> 1;    // Convert 1, 2, 4 -> 0, 1, 2
     if(bkndHandles[idx]) {
         activeHandle = bkndHandles[idx];
+        activeBackend = bknd;
         return AF_SUCCESS;
     } else {
         return AF_ERR_LOAD_LIB;
     }
 }
+
+bool checkArray(af_backend activeBackend, af_array a)
+{
+    // Convert af_array into int to retrieve the backend info.
+    // See ArrayInfo.hpp for more
+    int* a_ = reinterpret_cast<int*>(a);
+    return (*a_ >> 3) == activeBackend;
+}
+
+bool checkArrays(af_backend activeBackend)
+{
+    // Dummy
+    return true;
+}
+
+} // namespace unified
diff --git a/src/api/unified/symbol_manager.hpp b/src/api/unified/symbol_manager.hpp
index 94a2b38..f4cf913 100644
--- a/src/api/unified/symbol_manager.hpp
+++ b/src/api/unified/symbol_manager.hpp
@@ -6,6 +6,7 @@
  * The complete license agreement can be obtained at:
  * http://arrayfire.com/licenses/BSD-3-Clause
  ********************************************************/
+#pragma once
 
 #include <af/defines.h>
 #include <string>
@@ -18,6 +19,9 @@ typedef HMODULE LibHandle;
 typedef void* LibHandle;
 #endif
 
+namespace unified
+{
+
 const int NUM_BACKENDS = 3;
 const int NUM_ENV_VARS = 2;
 
@@ -33,6 +37,8 @@ class AFSymbolManager {
 
         af_err setBackend(af::Backend bnkd);
 
+        af::Backend getActiveBackend() { return activeBackend; }
+
         template<typename... CalleeArgs>
         af_err call(const char* symbolName, CalleeArgs... args) {
             if (!activeHandle)
@@ -47,6 +53,7 @@ class AFSymbolManager {
             if (!funcHandle) {
                 return AF_ERR_LOAD_SYM;
             }
+
             return funcHandle(args...);
         }
 
@@ -61,18 +68,41 @@ class AFSymbolManager {
         void operator=(AFSymbolManager const&);
 
     private:
+
         LibHandle bkndHandles[NUM_BACKENDS];
 
         LibHandle activeHandle;
         LibHandle defaultHandle;
         unsigned numBackends;
         int backendsAvailable;
+        af_backend activeBackend;
+        af_backend defaultBackend;
 };
 
+// Helper functions to ensure all the input arrays are on the active backend
+bool checkArray(af_backend activeBackend, af_array a);
+bool checkArrays(af_backend activeBackend);
+
+template<typename T, typename... Args>
+bool checkArrays(af_backend activeBackend, T a, Args... arg)
+{
+    return checkArray(activeBackend, a) && checkArrays(activeBackend, arg...);
+}
+
+} // namespace unified
+
+// Macro to check af_array as inputs. The arguments to this macro should be
+// only input af_arrays. Not outputs or other types.
+#define CHECK_ARRAYS(...) do {                                                              \
+    af_backend backendId = unified::AFSymbolManager::getInstance().getActiveBackend();      \
+    if(!unified::checkArrays(backendId, __VA_ARGS__))                                       \
+        return AF_ERR_ARR_BKND_MISMATCH;                                                    \
+} while(0);
+
 #if defined(OS_WIN)
-#define CALL(...) AFSymbolManager::getInstance().call(__FUNCTION__, __VA_ARGS__)
-#define CALL_NO_PARAMS() AFSymbolManager::getInstance().call(__FUNCTION__)
+#define CALL(...) unified::AFSymbolManager::getInstance().call(__FUNCTION__, __VA_ARGS__)
+#define CALL_NO_PARAMS() unified::AFSymbolManager::getInstance().call(__FUNCTION__)
 #else
-#define CALL(...) AFSymbolManager::getInstance().call(__func__, __VA_ARGS__)
-#define CALL_NO_PARAMS() AFSymbolManager::getInstance().call(__func__)
+#define CALL(...) unified::AFSymbolManager::getInstance().call(__func__, __VA_ARGS__)
+#define CALL_NO_PARAMS() unified::AFSymbolManager::getInstance().call(__func__)
 #endif
diff --git a/src/api/unified/util.cpp b/src/api/unified/util.cpp
index f98b79f..155c4f8 100644
--- a/src/api/unified/util.cpp
+++ b/src/api/unified/util.cpp
@@ -13,16 +13,19 @@
 
 af_err af_print_array(af_array arr)
 {
+    CHECK_ARRAYS(arr);
     return CALL(arr);
 }
 
 af_err af_print_array_gen(const char *exp, const af_array arr, const int precision)
 {
+    CHECK_ARRAYS(arr);
     return CALL(exp, arr, precision);
 }
 
 af_err af_save_array(int *index, const char* key, const af_array arr, const char *filename, const bool append)
 {
+    CHECK_ARRAYS(arr);
     return CALL(index, key, arr, filename, append);
 }
 
@@ -44,11 +47,13 @@ af_err af_read_array_key_check(int *index, const char *filename, const char* key
 af_err af_array_to_string(char **output, const char *exp, const af_array arr,
         const int precision, const bool transpose)
 {
+    CHECK_ARRAYS(arr);
     return CALL(output, exp, arr, precision, transpose);
 }
 
 af_err af_example_function(af_array* out, const af_array in, const af_someenum_t param)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, param);
 }
 
diff --git a/src/api/unified/vision.cpp b/src/api/unified/vision.cpp
index db1cfdb..1f71740 100644
--- a/src/api/unified/vision.cpp
+++ b/src/api/unified/vision.cpp
@@ -13,26 +13,31 @@
 
 af_err af_fast(af_features *out, const af_array in, const float thr, const unsigned arc_length, const bool non_max, const float feature_ratio, const unsigned edge)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, thr, arc_length, non_max, feature_ratio, edge);
 }
 
 af_err af_harris(af_features *out, const af_array in, const unsigned max_corners, const float min_response, const float sigma, const unsigned block_size, const float k_thr)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, max_corners, min_response, sigma, block_size, k_thr);
 }
 
 af_err af_orb(af_features *feat, af_array *desc, const af_array in, const float fast_thr, const unsigned max_feat, const float scl_fctr, const unsigned levels, const bool blur_img)
 {
+    CHECK_ARRAYS(in);
     return CALL(feat, desc, in, fast_thr, max_feat, scl_fctr, levels, blur_img);
 }
 
 af_err af_sift(af_features *feat, af_array *desc, const af_array in, const unsigned n_layers, const float contrast_thr, const float edge_thr, const float init_sigma, const bool double_input, const float intensity_scale, const float feature_ratio)
 {
+    CHECK_ARRAYS(in);
     return CALL(feat, desc, in, n_layers, contrast_thr, edge_thr, init_sigma, double_input, intensity_scale, feature_ratio);
 }
 
 af_err af_gloh(af_features *feat, af_array *desc, const af_array in, const unsigned n_layers, const float contrast_thr, const float edge_thr, const float init_sigma, const bool double_input, const float intensity_scale, const float feature_ratio)
 {
+    CHECK_ARRAYS(in);
     return CALL(feat, desc, in, n_layers, contrast_thr, edge_thr, init_sigma, double_input, intensity_scale, feature_ratio);
 }
 
@@ -40,6 +45,7 @@ af_err af_hamming_matcher(af_array* idx, af_array* dist,
         const af_array query, const af_array train,
         const dim_t dist_dim, const unsigned n_dist)
 {
+    CHECK_ARRAYS(query, train);
     return CALL(idx, dist, query, train, dist_dim, n_dist);
 }
 
@@ -48,21 +54,25 @@ af_err af_nearest_neighbour(af_array* idx, af_array* dist,
         const dim_t dist_dim, const unsigned n_dist,
         const af_match_type dist_type)
 {
+    CHECK_ARRAYS(query, train);
     return CALL(idx, dist, query, train, dist_dim, n_dist, dist_type);
 }
 
 af_err af_match_template(af_array *out, const af_array search_img, const af_array template_img, const af_match_type m_type)
 {
+    CHECK_ARRAYS(search_img, template_img);
     return CALL(out, search_img, template_img, m_type);
 }
 
 af_err af_susan(af_features* out, const af_array in, const unsigned radius, const float diff_thr, const float geom_thr,
         const float feature_ratio, const unsigned edge)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, radius, diff_thr, geom_thr, feature_ratio, edge);
 }
 
 af_err af_dog(af_array *out, const af_array in, const int radius1, const int radius2)
 {
+    CHECK_ARRAYS(in);
     return CALL(out, in, radius1, radius2);
 }

-- 
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