Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

signed 8-bit integer support #3507

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion CMakeLists.txt
Expand Up @@ -15,7 +15,7 @@ include(CheckLanguage)
include(CMakeModules/AF_vcpkg_options.cmake)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
project(ArrayFire VERSION 3.9.0 LANGUAGES C CXX)
project(ArrayFire VERSION 3.10.0 LANGUAGES C CXX)

include(AFconfigure_deps_vars)
include(AFBuildConfigurations)
Expand Down
10 changes: 5 additions & 5 deletions docs/details/algorithm.dox
Expand Up @@ -22,7 +22,7 @@ Input Type | Output Type
--------------------|---------------------
f32, f64, c32, c64 | same as input
s32, s64, u32, u64 | same as input
s16 | s32
s16, s8 | s32
u16, u8, b8 | u32

\copydoc batch_detail_algo
Expand Down Expand Up @@ -54,7 +54,7 @@ Input Type | Output Type
--------------------|---------------------
f32, f64, c32, c64 | same as input
s32, s64, u32, u64 | same as input
s16 | s32
s16, s8 | s32
u16, u8, b8 | u32
f16 | f32

Expand All @@ -76,7 +76,7 @@ Input Type | Output Type
--------------------|---------------------
f32, f64, c32, c64 | same as input
s32, u32, s64, u64 | same as input
s16 | s32
s16, s8 | s32
u16, u8, b8 | u32

\copydoc batch_detail_algo
Expand Down Expand Up @@ -108,7 +108,7 @@ Input Type | Output Type
--------------------|---------------------
f32, f64, c32, c64 | same as input
s32, u32, s64, u64 | same as input
s16 | s32
s16, s8 | s32
u16, u8, b8 | u32
f16 | f32

Expand Down Expand Up @@ -340,7 +340,7 @@ Input Type | Output Type
--------------------|---------------------
f32, f64, c32, c64 | same as input
s32, s64, u32, u64 | same as input
s16 | s32
s16, s8 | s32
u16, u8, b8 | u32

\copydoc batch_detail_algo
Expand Down
2 changes: 2 additions & 0 deletions docs/details/image.dox
Expand Up @@ -1007,6 +1007,7 @@ Iterative deconvolution function excepts \ref af::array of the following types o
- \ref f32
- \ref s16
- \ref u16
- \ref s8
- \ref u8

\note The type of output \ref af::array from deconvolution will be double if
Expand Down Expand Up @@ -1044,6 +1045,7 @@ Inverse deconvolution function excepts \ref af::array of the following types onl
- \ref f32
- \ref s16
- \ref u16
- \ref s8
- \ref u8

\note The type of output \ref af::array from deconvolution will be double
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/README.md
Expand Up @@ -52,7 +52,7 @@ vectors, matrices, volumes, and

It supports common [data types](\ref gettingstarted_datatypes), including
single and double precision floating point values, complex numbers, booleans,
and 32-bit signed and unsigned integers.
and 8/16/32-bit signed and unsigned integers.

#### Extending ArrayFire

Expand Down
3 changes: 2 additions & 1 deletion docs/pages/getting_started.md
Expand Up @@ -28,7 +28,8 @@ can represent one of many different [basic data types](\ref af_dtype):
* [b8](\ref b8) 8-bit boolean values (`bool`)
* [s32](\ref s32) 32-bit signed integer (`int`)
* [u32](\ref u32) 32-bit unsigned integer (`unsigned`)
* [u8](\ref u8) 8-bit unsigned values (`unsigned char`)
* [s8](\ref s8) 8-bit signed integer (`signed char`)
* [u8](\ref u8) 8-bit unsigned integer (`unsigned char`)
* [s64](\ref s64) 64-bit signed integer (`intl`)
* [u64](\ref u64) 64-bit unsigned integer (`uintl`)
* [s16](\ref s16) 16-bit signed integer (`short`)
Expand Down
31 changes: 16 additions & 15 deletions include/af/arith.h
Expand Up @@ -904,21 +904,22 @@ extern "C" {
be performed by ArrayFire. The following table shows which casts will
be optimized out. outer -> inner -> outer

| inner-> | f32 | f64 | c32 | c64 | s32 | u32 | u8 | b8 | s64 | u64 | s16 | u16 | f16 |
|---------|-----|-----|-----|-----|-----|-----|----|----|-----|-----|-----|-----|-----|
| f32 | x | x | x | x | | | | | | | | | x |
| f64 | x | x | x | x | | | | | | | | | x |
| c32 | x | x | x | x | | | | | | | | | x |
| c64 | x | x | x | x | | | | | | | | | x |
| s32 | x | x | x | x | x | x | | | x | x | | | x |
| u32 | x | x | x | x | x | x | | | x | x | | | x |
| u8 | x | x | x | x | x | x | x | x | x | x | x | x | x |
| b8 | x | x | x | x | x | x | x | x | x | x | x | x | x |
| s64 | x | x | x | x | | | | | x | x | | | x |
| u64 | x | x | x | x | | | | | x | x | | | x |
| s16 | x | x | x | x | x | x | | | x | x | x | x | x |
| u16 | x | x | x | x | x | x | | | x | x | x | x | x |
| f16 | x | x | x | x | | | | | | | | | x |
| inner-> | f32 | f64 | c32 | c64 | s32 | u32 | s8 | u8 | b8 | s64 | u64 | s16 | u16 | f16 |
|---------|-----|-----|-----|-----|-----|-----|----|----|----|-----|-----|-----|-----|-----|
| f32 | x | x | x | x | | | | | | | | | | x |
| f64 | x | x | x | x | | | | | | | | | | x |
| c32 | x | x | x | x | | | | | | | | | | x |
| c64 | x | x | x | x | | | | | | | | | | x |
| s32 | x | x | x | x | x | x | | | | x | x | | | x |
| u32 | x | x | x | x | x | x | | | | x | x | | | x |
| s8 | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
| u8 | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
| b8 | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
| s64 | x | x | x | x | | | | | | x | x | | | x |
| u64 | x | x | x | x | | | | | | x | x | | | x |
| s16 | x | x | x | x | x | x | | | | x | x | x | x | x |
| u16 | x | x | x | x | x | x | | | | x | x | x | x | x |
| f16 | x | x | x | x | | | | | | | | | | x |

If you want to avoid this behavior use, af_eval after the first cast
operation. This will ensure that the cast operation is performed on the
Expand Down
113 changes: 76 additions & 37 deletions include/af/array.h
Expand Up @@ -71,7 +71,7 @@ namespace af
operator array() const;
operator array();

#define ASSIGN(OP) \
#define ASSIGN_(OP) \
array_proxy& operator OP(const array_proxy &a); \
array_proxy& operator OP(const array &a); \
array_proxy& operator OP(const double &a); \
Expand All @@ -88,25 +88,35 @@ namespace af
array_proxy& operator OP(const long long &a); \
array_proxy& operator OP(const unsigned long long &a);

ASSIGN(=)
ASSIGN(+=)
ASSIGN(-=)
ASSIGN(*=)
ASSIGN(/=)
#undef ASSIGN

#if AF_API_VERSION >= 32
#define ASSIGN(OP) \
#define ASSIGN_32(OP) \
array_proxy& operator OP(const short &a); \
array_proxy& operator OP(const unsigned short &a);
#else
#define ASSIGN_32(OP)
#endif

#if AF_API_VERSION >= 310
#define ASSIGN_310(OP) \
array_proxy& operator OP(const signed char &a);
#else
#define ASSIGN_310(OP)
#endif

#define ASSIGN(OP) \
ASSIGN_(OP) \
ASSIGN_32(OP) \
ASSIGN_310(OP)

ASSIGN(=)
ASSIGN(+=)
ASSIGN(-=)
ASSIGN(*=)
ASSIGN(/=)
#undef ASSIGN
#endif
#undef ASSIGN_
#undef ASSIGN_32
#undef ASSIGN_310

// af::array member functions. same behavior as those below
af_array get();
Expand Down Expand Up @@ -761,8 +771,8 @@ namespace af
bool isfloating() const;

/**
\brief Returns true if the array type is \ref u8, \ref b8, \ref s32
\ref u32, \ref s64, \ref u64, \ref s16, \ref u16
\brief Returns true if the array type is \ref s8, \ref u8, \ref b8,
\ref s32, \ref u32, \ref s64, \ref u64, \ref s16, \ref u16
*/
bool isinteger() const;

Expand Down Expand Up @@ -946,27 +956,28 @@ namespace af

/// \brief Casts the array into another data type
///
/// \note Consecitive casting operations may be may be optimized out if
/// \note Consecutive casting operations may be optimized out if
/// the original type of the af::array is the same as the final type.
/// For example if the original type is f64 which is then cast to f32
/// and then back to f64, then the cast to f32 will be skipped and that
/// operation will *NOT* be performed by ArrayFire. The following table
/// shows which casts will be optimized out. outer -> inner -> outer
/// | inner-> | f32 | f64 | c32 | c64 | s32 | u32 | u8 | b8 | s64 | u64 | s16 | u16 | f16 |
/// |---------|-----|-----|-----|-----|-----|-----|----|----|-----|-----|-----|-----|-----|
/// | f32 | x | x | x | x | | | | | | | | | x |
/// | f64 | x | x | x | x | | | | | | | | | x |
/// | c32 | x | x | x | x | | | | | | | | | x |
/// | c64 | x | x | x | x | | | | | | | | | x |
/// | s32 | x | x | x | x | x | x | | | x | x | | | x |
/// | u32 | x | x | x | x | x | x | | | x | x | | | x |
/// | u8 | x | x | x | x | x | x | x | x | x | x | x | x | x |
/// | b8 | x | x | x | x | x | x | x | x | x | x | x | x | x |
/// | s64 | x | x | x | x | | | | | x | x | | | x |
/// | u64 | x | x | x | x | | | | | x | x | | | x |
/// | s16 | x | x | x | x | x | x | | | x | x | x | x | x |
/// | u16 | x | x | x | x | x | x | | | x | x | x | x | x |
/// | f16 | x | x | x | x | | | | | | | | | x |
/// | inner-> | f32 | f64 | c32 | c64 | s32 | u32 | s8 | u8 | b8 | s64 | u64 | s16 | u16 | f16 |
/// |---------|-----|-----|-----|-----|-----|-----|----|----|----|-----|-----|-----|-----|-----|
/// | f32 | x | x | x | x | | | | | | | | | | x |
/// | f64 | x | x | x | x | | | | | | | | | | x |
/// | c32 | x | x | x | x | | | | | | | | | | x |
/// | c64 | x | x | x | x | | | | | | | | | | x |
/// | s32 | x | x | x | x | x | x | | | | x | x | | | x |
/// | u32 | x | x | x | x | x | x | | | | x | x | | | x |
/// | s8 | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
/// | u8 | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
/// | b8 | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
/// | s64 | x | x | x | x | | | | | | x | x | | | x |
/// | u64 | x | x | x | x | | | | | | x | x | | | x |
/// | s16 | x | x | x | x | x | x | | | | x | x | x | x | x |
/// | u16 | x | x | x | x | x | x | | | | x | x | x | x | x |
/// | f16 | x | x | x | x | | | | | | | | | | x |
/// If you want to avoid this behavior use af_eval after the first cast
/// operation. This will ensure that the cast operation is performed on
/// the af::array
Expand Down Expand Up @@ -1003,17 +1014,25 @@ namespace af
array& OP2(const long long &val); /**< \copydoc OP2##(const array &) */ \
array& OP2(const unsigned long long &val);


#if AF_API_VERSION >= 32
#define ASSIGN(OP) \
ASSIGN_(OP) \
array& OP(const short &val); /**< \copydoc OP##(const array &) */ \
array& OP(const unsigned short &val);
#define ASSIGN_32(OP) \
array& OP(const short &val); /**< \copydoc OP##(const array &) */ \
array& OP(const unsigned short &val);
#else
#define ASSIGN_32(OP)
#endif

#if AF_API_VERSION >= 310
#define ASSIGN_310(OP) \
array& OP(const signed char &val); /**< \copydoc OP##(const array &) */
#else
#define ASSIGN(OP) ASSIGN_(OP)
#define ASSIGN_310(OP)
#endif

#define ASSIGN(OP) \
ASSIGN_(OP) \
ASSIGN_32(OP) \
ASSIGN_310(OP)

/// \ingroup array_mem_operator_eq
/// @{
Expand Down Expand Up @@ -1079,6 +1098,8 @@ namespace af

#undef ASSIGN
#undef ASSIGN_
#undef ASSIGN_32
#undef ASSIGN_310

///
/// \brief Negates the values of the array
Expand Down Expand Up @@ -1167,17 +1188,29 @@ namespace af
AFAPI array OP (const array& lhs, const cdouble& rhs);

#if AF_API_VERSION >= 32
#define BIN_OP(OP) \
BIN_OP_(OP) \
#define BIN_OP_32(OP) \
AFAPI array OP (const short& lhs, const array& rhs); /**< \copydoc OP##(const array&, const array&) */ \
AFAPI array OP (const unsigned short& lhs, const array& rhs); /**< \copydoc OP##(const array&, const array&) */ \
AFAPI array OP (const array& lhs, const short& rhs); /**< \copydoc OP##(const array&, const array&) */ \
AFAPI array OP (const array& lhs, const unsigned short& rhs);

#else
#define BIN_OP(OP) BIN_OP_(OP)
#define BIN_OP_32(OP)
#endif

#if AF_API_VERSION >= 310
#define BIN_OP_310(OP) \
AFAPI array OP (const signed char& lhs, const array& rhs); /**< \copydoc OP##(const array&, const array&) */ \
AFAPI array OP (const array& lhs, const signed char& rhs); /**< \copydoc OP##(const array&, const array&) */
#else
#define BIN_OP_310(OP)
#endif

#define BIN_OP(OP) \
BIN_OP_(OP) \
BIN_OP_32(OP) \
BIN_OP_310(OP)

/// \ingroup arith_func_add
/// @{
/// \brief Adds two arrays or an array and a value.
Expand Down Expand Up @@ -1371,6 +1404,8 @@ namespace af

#undef BIN_OP
#undef BIN_OP_
#undef BIN_OP_32
#undef BIN_OP_310

/// \ingroup arith_func_bitand
/// @{
Expand All @@ -1393,6 +1428,7 @@ namespace af
AFAPI array operator&(const array& lhs, const long long& rhs);
AFAPI array operator&(const array& lhs, const long& rhs);
AFAPI array operator&(const array& lhs, const short& rhs);
AFAPI array operator&(const array& lhs, const signed char& rhs);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the bitwise and logical AND operators need to be protected by the ifdefs? None of the other types have guards.

AFAPI array operator&(const array& lhs, const unsigned char& rhs);
AFAPI array operator&(const array& lhs, const unsigned long long& rhs);
AFAPI array operator&(const array& lhs, const unsigned long& rhs);
Expand All @@ -1408,6 +1444,7 @@ namespace af
AFAPI array operator&(const long long& lhs, const array& rhs);
AFAPI array operator&(const long& lhs, const array& rhs);
AFAPI array operator&(const short& lhs, const array& rhs);
AFAPI array operator&(const signed char& lhs, const array& rhs);
AFAPI array operator&(const unsigned char& lhs, const array& rhs);
AFAPI array operator&(const unsigned long long& lhs, const array& rhs);
AFAPI array operator&(const unsigned long& lhs, const array& rhs);
Expand Down Expand Up @@ -1436,6 +1473,7 @@ namespace af
AFAPI array operator&&(const array& lhs, const long long& rhs);
AFAPI array operator&&(const array& lhs, const long& rhs);
AFAPI array operator&&(const array& lhs, const short& rhs);
AFAPI array operator&&(const array& lhs, const signed char& rhs);
AFAPI array operator&&(const array& lhs, const unsigned char& rhs);
AFAPI array operator&&(const array& lhs, const unsigned long long& rhs);
AFAPI array operator&&(const array& lhs, const unsigned long& rhs);
Expand All @@ -1451,6 +1489,7 @@ namespace af
AFAPI array operator&&(const long long& lhs, const array& rhs);
AFAPI array operator&&(const long& lhs, const array& rhs);
AFAPI array operator&&(const short& lhs, const array& rhs);
AFAPI array operator&&(const signed char& lhs, const array& rhs);
AFAPI array operator&&(const unsigned char& lhs, const array& rhs);
AFAPI array operator&&(const unsigned long long& lhs, const array& rhs);
AFAPI array operator&&(const unsigned long& lhs, const array& rhs);
Expand Down
3 changes: 3 additions & 0 deletions include/af/defines.h
Expand Up @@ -227,6 +227,9 @@ typedef enum {
#if AF_API_VERSION >= 37
, f16 ///< 16-bit floating point value
#endif
#if AF_API_VERSION >= 310
, s8 ///< 8-bit signed integral values
#endif
} af_dtype;

typedef enum {
Expand Down
12 changes: 12 additions & 0 deletions include/af/traits.hpp
Expand Up @@ -175,6 +175,18 @@ struct dtype_traits<half> {
static const char* getName() { return "half"; }
};
#endif

#if AF_API_VERSION >= 310
template<>
struct dtype_traits<signed char> {
enum {
af_type = s8 ,
ctype = f32
};
typedef signed char base_type;
static const char* getName() { return "schar"; }
};
#endif
}

#endif
1 change: 1 addition & 0 deletions src/api/c/anisotropic_diffusion.cpp
Expand Up @@ -90,6 +90,7 @@ af_err af_anisotropic_diffusion(af_array* out, const af_array in,
case u32:
case s16:
case u16:
case s8:
case u8:
output = diffusion<float>(input, dt, K, iterations, F, eq);
break;
Expand Down