Skip to content

Feature/vector algorithms #5

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

Merged
merged 2 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ Arrayfire python C library wrapper
- [ ] Signal Processing
- [x] Statistics
- [ ] Unified API Functions
- [ ] Vector Algorithms
- [x] Vector Algorithms
18 changes: 0 additions & 18 deletions arrayfire_wrapper/defines.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import ctypes
import platform
from dataclasses import dataclass
from enum import Enum
from typing import Type


Expand Down Expand Up @@ -48,20 +47,3 @@ def __repr__(self) -> str:
def c_array(self): # type: ignore[no-untyped-def]
c_shape = CDimT * 4 # ctypes.c_int | ctypes.c_longlong * 4
return c_shape(CDimT(self.x1), CDimT(self.x2), CDimT(self.x3), CDimT(self.x4))


class Moment(Enum):
M00 = 1
M01 = 2
M10 = 4
M11 = 8
FIRST_ORDER = M00 | M01 | M10 | M11


class PointerSource(Enum):
"""
Source of the pointer.
"""

device = 0 # gpu
host = 1 # cpu
105 changes: 101 additions & 4 deletions arrayfire_wrapper/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,101 @@

from .mathematical_functions.trigonometric_functions import acos, asin, atan, atan2, cos, sin, tan

# Vector Algorithms

__all__ += [
"accum",
"scan",
"scan_by_key",
"where",
]

from .vector_algorithms.inclusive_scan_operations import accum, scan, scan_by_key, where

__all__ += [
"diff1",
"diff2",
"gradient",
]

from .vector_algorithms.numerical_differentiation import diff1, diff2, gradient

__all__ += [
"all_true",
"all_true_all",
"all_true_by_key",
"any_true",
"any_true_all",
"any_true_by_key",
"count",
"count_all",
"count_by_key",
"imax",
"imax_all",
"imin",
"imin_all",
"max",
"max_all",
"max_by_key",
"max_ragged",
"min",
"min_all",
"product",
"product_all",
"product_nan",
"product_nan_all",
"sum",
"sum_all",
"sum_nan",
"sum_nan_all",
]

from .vector_algorithms.reduction_operations import (
all_true,
all_true_all,
all_true_by_key,
any_true,
any_true_all,
any_true_by_key,
count,
count_all,
count_by_key,
imax,
imax_all,
imin,
imin_all,
max,
max_all,
max_by_key,
max_ragged,
min,
min_all,
product,
product_all,
product_nan,
product_nan_all,
sum,
sum_all,
sum_nan,
sum_nan_all,
)

__all__ += [
"set_intersect",
"set_union",
"set_unique",
]

from .vector_algorithms.set_operations import set_intersect, set_union, set_unique

__all__ += [
"sort",
"sort_by_key",
"sort_index",
]

from .vector_algorithms.sort_operations import sort, sort_by_key, sort_index

# Functions to Work with Internal Array Layout

__all__ += [
Expand All @@ -403,8 +498,6 @@
# Statistics

__all__ += [
"TopK",
"VarianceBias",
"corrcoef",
"cov",
"mean",
Expand All @@ -423,8 +516,6 @@
]

from .statistics import (
TopK,
VarianceBias,
corrcoef,
cov,
mean,
Expand All @@ -441,3 +532,9 @@
var_all_weighted,
var_weighted,
)

# Constants

__all__ += ["BinaryOperator", "Moment", "Pad", "PointerSource", "TopK", "VarianceBias"]

from ._constants import BinaryOperator, Moment, Pad, PointerSource, TopK, VarianceBias
77 changes: 77 additions & 0 deletions arrayfire_wrapper/lib/_constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from enum import Enum


class BinaryOperator(Enum): # Binary Operators
ADD = 0
MUL = 1
MIN = 2
MAX = 3


class ErrorCodes(Enum): # Error Values
NONE = 0

# 100-199 Errors in environment
NO_MEM = 101
DRIVER = 102
RUNTIME = 103

# 200-299 Errors in input parameters
INVALID_ARRAY = 201
ARG = 202
SIZE = 203
TYPE = 204
DIFF_TYPE = 205
BATCH = 207
DEVICE = 208

# 300-399 Errors for missing software features
NOT_SUPPORTED = 301
NOT_CONFIGURED = 302
NONFREE = 303

# 400-499 Errors for missing hardware features
NO_DBL = 401
NO_GFX = 402
NO_HALF = 403

# 500-599 Errors specific to the heterogeneous API
LOAD_LIB = 501
LOAD_SYM = 502
ARR_BKND_MISMATCH = 503

# 900-999 Errors from upstream libraries and runtimes
INTERNAL = 998
UNKNOWN = 999


class Moment(Enum): # Image moments types
M00 = 1
M01 = 2
M10 = 4
M11 = 8
FIRST_ORDER = M00 | M01 | M10 | M11


class Pad(Enum): # Edge padding types
ZERO = 0
SYM = 1
CLAMP_TO_EDGE = 2
PERIODIC = 3


class PointerSource(Enum):
device = 0 # gpu
host = 1 # cpu


class TopK(Enum): # Top-K ordering
DEFAULT = 0
MIN = 1
MAX = 2


class VarianceBias(Enum): # Variance Bias types
DEFAULT = 0
SAMPLE = 1
POPULATION = 2
8 changes: 2 additions & 6 deletions arrayfire_wrapper/lib/_error_handler.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import ctypes
from enum import Enum

from arrayfire_wrapper._backend import _backend
from arrayfire_wrapper.defines import CDimT
from arrayfire_wrapper.dtypes import to_str


class _ErrorCodes(Enum):
none = 0
from arrayfire_wrapper.lib._constants import ErrorCodes


def safe_call(c_err: int) -> None:
if c_err == _ErrorCodes.none.value:
if c_err == ErrorCodes.NONE.value:
return

err_str = ctypes.c_char_p(0)
Expand Down
4 changes: 2 additions & 2 deletions arrayfire_wrapper/lib/_utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@


def binary_op(c_func: Callable, lhs: AFArray, rhs: AFArray, /) -> AFArray:
out = AFArray(0)
out = AFArray.create_null_pointer()
safe_call(c_func(ctypes.pointer(out), lhs, rhs, bcast_var.get()))
return out


def unary_op(c_func: Callable, arr: AFArray, /) -> AFArray:
out = AFArray(0)
out = AFArray.create_null_pointer()
safe_call(c_func(ctypes.pointer(out), arr))
return out
3 changes: 2 additions & 1 deletion arrayfire_wrapper/lib/array_layout.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import ctypes

from arrayfire_wrapper._backend import _backend
from arrayfire_wrapper.defines import AFArray, ArrayBuffer, CDimT, CShape, CType, PointerSource
from arrayfire_wrapper.defines import AFArray, ArrayBuffer, CDimT, CShape, CType
from arrayfire_wrapper.dtypes import Dtype
from arrayfire_wrapper.lib._constants import PointerSource
from arrayfire_wrapper.lib._error_handler import safe_call


Expand Down
17 changes: 17 additions & 0 deletions arrayfire_wrapper/lib/image_processing/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import ctypes

from arrayfire_wrapper._backend import _backend
from arrayfire_wrapper.defines import AFArray, CDimT
from arrayfire_wrapper.lib._constants import Pad
from arrayfire_wrapper.lib._error_handler import safe_call


def maxfilt(arr: AFArray, wind_lenght: int, wind_width: int, edge_pad: Pad) -> AFArray:
"""
source: https://arrayfire.org/docs/group__image__func__maxfilt.htm#ga97e07bf5f5c58752d23d1772586b71f4
"""
out = AFArray.create_null_pointer()
safe_call(
_backend.clib.af_maxfilt(ctypes.pointer(out), arr, CDimT(wind_lenght), CDimT(wind_width), edge_pad.value)
)
return out
3 changes: 2 additions & 1 deletion arrayfire_wrapper/lib/image_processing/image_moments.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import ctypes

from arrayfire_wrapper._backend import _backend
from arrayfire_wrapper.defines import AFArray, Moment
from arrayfire_wrapper.defines import AFArray
from arrayfire_wrapper.lib._constants import Moment
from arrayfire_wrapper.lib._error_handler import safe_call


Expand Down
14 changes: 1 addition & 13 deletions arrayfire_wrapper/lib/statistics.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
import ctypes
from enum import Enum

from arrayfire_wrapper._backend import _backend
from arrayfire_wrapper.defines import AFArray
from arrayfire_wrapper.lib._constants import TopK, VarianceBias
from arrayfire_wrapper.lib._error_handler import safe_call


class VarianceBias(Enum):
DEFAULT = 0
SAMPLE = 1
POPULATION = 2


class TopK(Enum):
DEFAULT = 0
MIN = 1
MAX = 2


def corrcoef(x: AFArray, y: AFArray, /) -> complex:
"""
source: https://arrayfire.org/docs/group__stat__func__corrcoef.htm#ga26b894c86731234136bfe1342453d8a7
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import ctypes

from arrayfire_wrapper._backend import _backend
from arrayfire_wrapper.defines import AFArray
from arrayfire_wrapper.lib._constants import BinaryOperator
from arrayfire_wrapper.lib._error_handler import safe_call


def accum(arr: AFArray, dim: int, /) -> AFArray:
"""
source: https://arrayfire.org/docs/group__scan__func__accum.htm#ga50d499e844e0b63e338cb3ea50439629
"""
out = AFArray.create_null_pointer()
safe_call(_backend.clib.af_accum(ctypes.pointer(out), arr, ctypes.c_int(dim)))
return out


def scan(arr: AFArray, dim: int, op: BinaryOperator, inclusive_scan: bool, /) -> AFArray:
"""
source: https://arrayfire.org/docs/group__scan__func__scan.htm#ga1c864e22826f61bec2e9b6c61aa93fce
"""
out = AFArray.create_null_pointer()
safe_call(_backend.clib.af_scan(ctypes.pointer(out), arr, dim, op.value, inclusive_scan))
return out


def scan_by_key(key: AFArray, arr: AFArray, dim: int, op: BinaryOperator, inclusive_scan: bool, /) -> AFArray:
"""
source: https://arrayfire.org/docs/group__scan__func__scanbykey.htm#gaaae150e0f197782782f45340d137b027
"""
out = AFArray.create_null_pointer()
safe_call(_backend.clib.af_scan(ctypes.pointer(out), key, arr, dim, op.value, inclusive_scan))
return out


def where(arr: AFArray, /) -> AFArray:
"""
source: https://arrayfire.org/docs/group__scan__func__where.htm#gafda59a3d25d35238592dd09907be9d07
"""
out = AFArray.create_null_pointer()
safe_call(_backend.clib.af_where(ctypes.pointer(out), arr))
return out
Loading