From 25766fe44e31b69621ec7ca060e65638c47fbe76 Mon Sep 17 00:00:00 2001 From: CoprDistGit Date: Wed, 10 May 2023 05:40:32 +0000 Subject: automatic import of python-backends --- .gitignore | 1 + python-backends.spec | 1704 ++++++++++++++++++++++++++++++++++++++++++++++++++ sources | 1 + 3 files changed, 1706 insertions(+) create mode 100644 python-backends.spec create mode 100644 sources diff --git a/.gitignore b/.gitignore index e69de29..228e473 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +/backends-1.5.3.tar.gz diff --git a/python-backends.spec b/python-backends.spec new file mode 100644 index 0000000..7bfc422 --- /dev/null +++ b/python-backends.spec @@ -0,0 +1,1704 @@ +%global _empty_manifest_terminate_build 0 +Name: python-backends +Version: 1.5.3 +Release: 1 +Summary: A generic interface for linear algebra backends +License: MIT +URL: https://github.com/wesselb/lab +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/dd/ba/25945208f25a1382b421dfa8b6915d3b7886fe843ad9ba86908ec3a99419/backends-1.5.3.tar.gz +BuildArch: noarch + + +%description +# [LAB](http://github.com/wesselb/lab) + +[![CI](https://github.com/wesselb/lab/workflows/CI/badge.svg?branch=master)](https://github.com/wesselb/lab/actions?query=workflow%3ACI) +[![Coverage Status](https://coveralls.io/repos/github/wesselb/lab/badge.svg?branch=master&service=github)](https://coveralls.io/github/wesselb/lab?branch=master) +[![Latest Docs](https://img.shields.io/badge/docs-latest-blue.svg)](https://wesselb.github.io/lab) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) + +A generic interface for linear algebra backends: code it once, run it on any +backend + +* [Requirements and Installation](#requirements-and-installation) +* [Basic Usage](#basic-usage) +* [List of Types](#list-of-types) + - [General](#general) + - [NumPy](#numpy) + - [AutoGrad](#autograd) + - [TensorFlow](#tensorflow) + - [PyTorch](#pytorch) + - [JAX](#jax) +* [List of Methods](#list-of-methods) + - [Constants](#constants) + - [Generic](#generic) + - [Linear Algebra](#linear-algebra) + - [Random](#random) + - [Shaping](#shaping) +* [Devices](#devices) +* [Lazy Shapes](#lazy-shapes) +* [Random Numbers](#random-numbers) +* [Control Flow Cache](#control-flow-cache) + +## Requirements and Installation + +See [the instructions here](https://gist.github.com/wesselb/4b44bf87f3789425f96e26c4308d0adc). +Then simply + +``` +pip install backends +``` + +## Basic Usage + +The basic use case for the package is to write code that automatically +determines the backend to use depending on the types of its arguments. + +Example: + +```python +import lab as B +import lab.autograd # Load the AutoGrad extension. +import lab.torch # Load the PyTorch extension. +import lab.tensorflow # Load the TensorFlow extension. +import lab.jax # Load the JAX extension. + + +def objective(matrix): + outer_product = B.matmul(matrix, matrix, tr_b=True) + return B.mean(outer_product) +``` + +The AutoGrad, PyTorch, TensorFlow, and JAX extensions are not loaded automatically to +not enforce a dependency on all three frameworks. +An extension can alternatively be loaded via `import lab.autograd as B`. + +Run it with NumPy and AutoGrad: + +```python +>>> import autograd.numpy as np + +>>> objective(B.randn(np.float64, 2, 2)) +0.15772589216756833 + +>>> grad(objective)(B.randn(np.float64, 2, 2)) +array([[ 0.23519042, -1.06282928], + [ 0.23519042, -1.06282928]]) +``` + +Run it with TensorFlow: +```python +>>> import tensorflow as tf + +>>> objective(B.randn(tf.float64, 2, 2)) + +``` + +Run it with PyTorch: +```python +>>> import torch + +>>> objective(B.randn(torch.float64, 2, 2)) +tensor(1.9557, dtype=torch.float64) +``` + +Run it with JAX: +```python +>>> import jax + +>>> import jax.numpy as jnp + +>>> jax.jit(objective)(B.randn(jnp.float32, 2, 2)) +DeviceArray(0.3109299, dtype=float32) + +>>> jax.jit(jax.grad(objective))(B.randn(jnp.float32, 2, 2)) +DeviceArray([[ 0.2525182, -1.26065 ], + [ 0.2525182, -1.26065 ]], dtype=float32) +``` + +## List of Types + +This section lists all available types, which can be used to check types of +objects or extend functions. + +### General + +``` +Int # Integers +Float # Floating-point numbers +Complex # Complex numbers +Bool # Booleans +Number # Numbers +Numeric # Numerical objects, including booleans +DType # Data type +Framework # Anything accepted by supported frameworks +Device # Any device type +``` + +### NumPy + +``` +NPNumeric +NPDType +NPRandomState + +NP # Anything NumPy +``` + +### AutoGrad + +``` +AGNumeric +AGDType +AGRandomState + +AG # Anything AutoGrad +``` + +### TensorFlow + +``` +TFNumeric +TFDType +TFRandomState +TFDevice + +TF # Anything TensorFlow +``` + + +### PyTorch + +``` +TorchNumeric +TorchDType +TorchDevice +TorchRandomState + +Torch # Anything PyTorch +``` + + +### JAX + +``` +JAXNumeric +JAXDType +JAXDevice +JAXRandomState + +JAX # Anything JAX +``` + + +## List of Methods +This section lists all available constants and methods. + +* + Arguments *must* be given as arguments and keyword arguments *must* be + given as keyword arguments. + For example, `sum(tensor, axis=1)` is valid, but `sum(tensor, 1)` is not. + +* The names of arguments are indicative of their function: + - `a`, `b`, and `c` indicate general tensors. + - + `dtype` indicates a data type. E.g, `np.float32` or `tf.float64`; and + `rand(np.float32)` creates a NumPy random number, whereas + `rand(tf.float64)` creates a TensorFlow random number. + Data types are always given as the first argument. + - + `shape` indicates a shape. + The dimensions of a shape are always given as separate arguments to + the function. + E.g., `reshape(tensor, 2, 2)` is valid, but `reshape(tensor, (2, 2))` + is not. + - + `axis` indicates an axis over which the function may perform its action. + An axis is always given as a keyword argument. + - + `device` refers to a device on which a tensor can placed, which can + either be a framework-specific type or a string, e.g. `"cpu"`. + - + `ref` indicates a *reference tensor* from which properties, like its + shape and data type, will be used. E.g., `zeros(tensor)` creates a + tensor full of zeros of the same shape and data type as `tensor`. + +See the documentation for more detailed descriptions of each function. + +### Special Variables +``` +default_dtype # Default data type. +epsilon # Magnitude of diagonal to regularise matrices with. +cholesky_retry_factor # Retry the Cholesky, increasing `epsilon` by a factor at most this. +``` + +### Constants +``` +nan +pi +log_2_pi +``` + +### Data Types +``` +dtype(a) +dtype_float(dtype) +dtype_float(a) +dtype_int(dtype) +dtype_int(a) + +promote_dtypes(*dtype) +issubdtype(dtype1, dtype2) +``` + +### Generic +``` +isabstract(a) +jit(f, **kw_args) + +isnan(a) +real(a) +imag(a) + +device(a) +on_device(device) +on_device(a) +set_global_device(device) +to_active_device(a) + +zeros(dtype, *shape) +zeros(*shape) +zeros(ref) + +ones(dtype, *shape) +ones(*shape) +ones(ref) + +zero(dtype) +zero(*refs) + +one(dtype) +one(*refs) + +eye(dtype, *shape) +eye(*shape) +eye(ref) + +linspace(dtype, a, b, num) +linspace(a, b, num) + +range(dtype, start, stop, step) +range(dtype, stop) +range(dtype, start, stop) +range(start, stop, step) +range(start, stop) +range(stop) + +cast(dtype, a) + +identity(a) +round(a) +floor(a) +ceil(a) +negative(a) +abs(a) +sign(a) +sqrt(a) +exp(a) +log(a) +log1p(a) +sin(a) +arcsin(a) +cos(a) +arccos(a) +tan(a) +arctan(a) +tanh(a) +arctanh(a) +loggamma(a) +logbeta(a) +erf(a) +sigmoid(a) +softplus(a) +relu(a) + +add(a, b) +subtract(a, b) +multiply(a, b) +divide(a, b) +power(a, b) +minimum(a, b) +maximum(a, b) +leaky_relu(a, alpha) + +softmax(a, axis=None) + +min(a, axis=None, squeeze=True) +max(a, axis=None, squeeze=True) +sum(a, axis=None, squeeze=True) +prod(a, axis=None, squeeze=True) +mean(a, axis=None, squeeze=True) +std(a, axis=None, squeeze=True) +logsumexp(a, axis=None, squeeze=True) +all(a, axis=None, squeeze=True) +any(a, axis=None, squeeze=True) + +nansum(a, axis=None, squeeze=True) +nanprod(a, axis=None, squeeze=True) +nanmean(a, axis=None, squeeze=True) +nanstd(a, axis=None, squeeze=True) + +argmin(a, axis=None) +argmax(a, axis=None) + +lt(a, b) +le(a, b) +gt(a, b) +ge(a, b) +eq(a, b) +ne(a, b) + +bvn_cdf(a, b, c) + +cond(condition, f_true, f_false, xs**) +where(condition, a, b) +scan(f, xs, *init_state) + +sort(a, axis=-1, descending=False) +argsort(a, axis=-1, descending=False) +quantile(a, q, axis=None) + +to_numpy(a) +jit_to_numpy(a) # Caches results for `B.jit`. +``` + +### Linear Algebra +``` +transpose(a, perm=None) (alias: t, T) +matmul(a, b, tr_a=False, tr_b=False) (alias: mm, dot) +einsum(equation, *elements) +trace(a, axis1=0, axis2=1) +kron(a, b) +svd(a, compute_uv=True) +eig(a, compute_eigvecs=True) +solve(a, b) +inv(a) +pinv(a) +det(a) +logdet(a) +expm(a) +logm(a) +cholesky(a) (alias: chol) + +cholesky_solve(a, b) (alias: cholsolve) +triangular_solve(a, b, lower_a=True) (alias: trisolve) +toeplitz_solve(a, b, c) (alias: toepsolve) +toeplitz_solve(a, c) + +outer(a, b) +reg(a, diag=None, clip=True) + +pw_dists2(a, b) +pw_dists2(a) +pw_dists(a, b) +pw_dists(a) + +ew_dists2(a, b) +ew_dists2(a) +ew_dists(a, b) +ew_dists(a) + +pw_sums2(a, b) +pw_sums2(a) +pw_sums(a, b) +pw_sums(a) + +ew_sums2(a, b) +ew_sums2(a) +ew_sums(a, b) +ew_sums(a) +``` + +### Random +``` +set_random_seed(seed) +create_random_state(dtype, seed=0) +global_random_state(dtype) +global_random_state(a) +set_global_random_state(state) + +rand(state, dtype, *shape) +rand(dtype, *shape) +rand(*shape) +rand(state, ref) +rand(ref) + +randn(state, dtype, *shape) +randn(dtype, *shape) +randn(*shape) +randn(state, ref) +randn(ref) + +randcat(state, p, *shape) +randcat(p, *shape) + +choice(state, a, *shape, p=None) +choice(a, *shape, p=None) + +randint(state, dtype, *shape, lower=0, upper) +randint(dtype, *shape, lower=0, upper) +randint(*shape, lower=0, upper) +randint(state, ref, lower=0, upper) +randint(ref, lower=0, upper) + +randperm(state, dtype, n) +randperm(dtype, n) +randperm(n) + +randgamma(state, dtype, *shape, alpha, scale) +randgamma(dtype, *shape, alpha, scale) +randgamma(*shape, alpha, scale) +randgamma(state, ref, *, alpha, scale) +randgamma(ref, *, alpha, scale) + +randbeta(state, dtype, *shape, alpha, beta) +randbeta(dtype, *shape, alpha, beta) +randbeta(*shape, alpha, beta) +randbeta(state, ref, *, alpha, beta) +randbeta(ref, *, alpha, beta) +``` + +### Shaping +``` +shape(a, *dims) +rank(a) +length(a) (alias: size) +is_scalar(a) +expand_dims(a, axis=0, times=1) +squeeze(a, axis=None) +uprank(a, rank=2) +downrank(a, rank=2, preserve=False) +broadcast_to(a, *shape) + +diag(a) +diag_extract(a) +diag_construct(a) +flatten(a) +vec_to_tril(a, offset=0) +tril_to_vec(a, offset=0) +stack(*elements, axis=0) +unstack(a, axis=0, squeeze=True) +reshape(a, *shape) +concat(*elements, axis=0) +concat2d(*rows) +tile(a, *repeats) +take(a, indices_or_mask, axis=0) +submatrix(a, indices_or_mask) +``` + +## Devices +You can get the device of a tensor with `B.device(a)`, +and you can execute a computation on a device by entering `B.on_device(device)` +as a context: + +```python +with B.on_device("gpu:0"): + a = B.randn(tf.float32, 2, 2) + b = B.randn(tf.float32, 2, 2) + c = a @ b +``` + +Within such a context, a tensor that is not on the active device can be moved to the +active device with `B.to_active_device(a)`. + +You can also globally set the active device with `B.set_global_device("gpu:0")`. + +## Lazy Shapes +If a function is evaluated abstractly, then elements of the shape of a tensor, e.g. +`B.shape(a)[0]`, may also be tensors, which can break dispatch. +By entering `B.lazy_shapes()`, shapes and elements of shapes will be wrapped in a custom +type to fix this issue. + +```python +with B.lazy_shapes(): + a = B.eye(2) + print(type(B.shape(a))) + # + print(type(B.shape(a)[0])) + # +``` + +## Random Numbers +If you call a random number generator without providing a random state, e.g. +`B.randn(np.float32, 2)`, the global random state from the corresponding +backend is used. +For JAX, since there is no global random state, LAB provides a JAX global +random state accessible through `B.jax_global_random_state` once `lab.jax` +is loaded. + +If you do not want to use a global random state but rather explicitly maintain +one, you can create a random state with `B.create_random_state` and then +pass this as the first argument to the random number generators. +The random number generators will then return a tuple containing the updated +random state and the random result. + +```python +# Create random state. +state = B.create_random_state(tf.float32, seed=0) + +# Generate two random arrays. +state, x = B.randn(state, tf.float32, 2) +state, y = B.randn(state, tf.float32, 2) +``` + + +## Control Flow Cache +Coming soon! + + +%package -n python3-backends +Summary: A generic interface for linear algebra backends +Provides: python-backends +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-backends +# [LAB](http://github.com/wesselb/lab) + +[![CI](https://github.com/wesselb/lab/workflows/CI/badge.svg?branch=master)](https://github.com/wesselb/lab/actions?query=workflow%3ACI) +[![Coverage Status](https://coveralls.io/repos/github/wesselb/lab/badge.svg?branch=master&service=github)](https://coveralls.io/github/wesselb/lab?branch=master) +[![Latest Docs](https://img.shields.io/badge/docs-latest-blue.svg)](https://wesselb.github.io/lab) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) + +A generic interface for linear algebra backends: code it once, run it on any +backend + +* [Requirements and Installation](#requirements-and-installation) +* [Basic Usage](#basic-usage) +* [List of Types](#list-of-types) + - [General](#general) + - [NumPy](#numpy) + - [AutoGrad](#autograd) + - [TensorFlow](#tensorflow) + - [PyTorch](#pytorch) + - [JAX](#jax) +* [List of Methods](#list-of-methods) + - [Constants](#constants) + - [Generic](#generic) + - [Linear Algebra](#linear-algebra) + - [Random](#random) + - [Shaping](#shaping) +* [Devices](#devices) +* [Lazy Shapes](#lazy-shapes) +* [Random Numbers](#random-numbers) +* [Control Flow Cache](#control-flow-cache) + +## Requirements and Installation + +See [the instructions here](https://gist.github.com/wesselb/4b44bf87f3789425f96e26c4308d0adc). +Then simply + +``` +pip install backends +``` + +## Basic Usage + +The basic use case for the package is to write code that automatically +determines the backend to use depending on the types of its arguments. + +Example: + +```python +import lab as B +import lab.autograd # Load the AutoGrad extension. +import lab.torch # Load the PyTorch extension. +import lab.tensorflow # Load the TensorFlow extension. +import lab.jax # Load the JAX extension. + + +def objective(matrix): + outer_product = B.matmul(matrix, matrix, tr_b=True) + return B.mean(outer_product) +``` + +The AutoGrad, PyTorch, TensorFlow, and JAX extensions are not loaded automatically to +not enforce a dependency on all three frameworks. +An extension can alternatively be loaded via `import lab.autograd as B`. + +Run it with NumPy and AutoGrad: + +```python +>>> import autograd.numpy as np + +>>> objective(B.randn(np.float64, 2, 2)) +0.15772589216756833 + +>>> grad(objective)(B.randn(np.float64, 2, 2)) +array([[ 0.23519042, -1.06282928], + [ 0.23519042, -1.06282928]]) +``` + +Run it with TensorFlow: +```python +>>> import tensorflow as tf + +>>> objective(B.randn(tf.float64, 2, 2)) + +``` + +Run it with PyTorch: +```python +>>> import torch + +>>> objective(B.randn(torch.float64, 2, 2)) +tensor(1.9557, dtype=torch.float64) +``` + +Run it with JAX: +```python +>>> import jax + +>>> import jax.numpy as jnp + +>>> jax.jit(objective)(B.randn(jnp.float32, 2, 2)) +DeviceArray(0.3109299, dtype=float32) + +>>> jax.jit(jax.grad(objective))(B.randn(jnp.float32, 2, 2)) +DeviceArray([[ 0.2525182, -1.26065 ], + [ 0.2525182, -1.26065 ]], dtype=float32) +``` + +## List of Types + +This section lists all available types, which can be used to check types of +objects or extend functions. + +### General + +``` +Int # Integers +Float # Floating-point numbers +Complex # Complex numbers +Bool # Booleans +Number # Numbers +Numeric # Numerical objects, including booleans +DType # Data type +Framework # Anything accepted by supported frameworks +Device # Any device type +``` + +### NumPy + +``` +NPNumeric +NPDType +NPRandomState + +NP # Anything NumPy +``` + +### AutoGrad + +``` +AGNumeric +AGDType +AGRandomState + +AG # Anything AutoGrad +``` + +### TensorFlow + +``` +TFNumeric +TFDType +TFRandomState +TFDevice + +TF # Anything TensorFlow +``` + + +### PyTorch + +``` +TorchNumeric +TorchDType +TorchDevice +TorchRandomState + +Torch # Anything PyTorch +``` + + +### JAX + +``` +JAXNumeric +JAXDType +JAXDevice +JAXRandomState + +JAX # Anything JAX +``` + + +## List of Methods +This section lists all available constants and methods. + +* + Arguments *must* be given as arguments and keyword arguments *must* be + given as keyword arguments. + For example, `sum(tensor, axis=1)` is valid, but `sum(tensor, 1)` is not. + +* The names of arguments are indicative of their function: + - `a`, `b`, and `c` indicate general tensors. + - + `dtype` indicates a data type. E.g, `np.float32` or `tf.float64`; and + `rand(np.float32)` creates a NumPy random number, whereas + `rand(tf.float64)` creates a TensorFlow random number. + Data types are always given as the first argument. + - + `shape` indicates a shape. + The dimensions of a shape are always given as separate arguments to + the function. + E.g., `reshape(tensor, 2, 2)` is valid, but `reshape(tensor, (2, 2))` + is not. + - + `axis` indicates an axis over which the function may perform its action. + An axis is always given as a keyword argument. + - + `device` refers to a device on which a tensor can placed, which can + either be a framework-specific type or a string, e.g. `"cpu"`. + - + `ref` indicates a *reference tensor* from which properties, like its + shape and data type, will be used. E.g., `zeros(tensor)` creates a + tensor full of zeros of the same shape and data type as `tensor`. + +See the documentation for more detailed descriptions of each function. + +### Special Variables +``` +default_dtype # Default data type. +epsilon # Magnitude of diagonal to regularise matrices with. +cholesky_retry_factor # Retry the Cholesky, increasing `epsilon` by a factor at most this. +``` + +### Constants +``` +nan +pi +log_2_pi +``` + +### Data Types +``` +dtype(a) +dtype_float(dtype) +dtype_float(a) +dtype_int(dtype) +dtype_int(a) + +promote_dtypes(*dtype) +issubdtype(dtype1, dtype2) +``` + +### Generic +``` +isabstract(a) +jit(f, **kw_args) + +isnan(a) +real(a) +imag(a) + +device(a) +on_device(device) +on_device(a) +set_global_device(device) +to_active_device(a) + +zeros(dtype, *shape) +zeros(*shape) +zeros(ref) + +ones(dtype, *shape) +ones(*shape) +ones(ref) + +zero(dtype) +zero(*refs) + +one(dtype) +one(*refs) + +eye(dtype, *shape) +eye(*shape) +eye(ref) + +linspace(dtype, a, b, num) +linspace(a, b, num) + +range(dtype, start, stop, step) +range(dtype, stop) +range(dtype, start, stop) +range(start, stop, step) +range(start, stop) +range(stop) + +cast(dtype, a) + +identity(a) +round(a) +floor(a) +ceil(a) +negative(a) +abs(a) +sign(a) +sqrt(a) +exp(a) +log(a) +log1p(a) +sin(a) +arcsin(a) +cos(a) +arccos(a) +tan(a) +arctan(a) +tanh(a) +arctanh(a) +loggamma(a) +logbeta(a) +erf(a) +sigmoid(a) +softplus(a) +relu(a) + +add(a, b) +subtract(a, b) +multiply(a, b) +divide(a, b) +power(a, b) +minimum(a, b) +maximum(a, b) +leaky_relu(a, alpha) + +softmax(a, axis=None) + +min(a, axis=None, squeeze=True) +max(a, axis=None, squeeze=True) +sum(a, axis=None, squeeze=True) +prod(a, axis=None, squeeze=True) +mean(a, axis=None, squeeze=True) +std(a, axis=None, squeeze=True) +logsumexp(a, axis=None, squeeze=True) +all(a, axis=None, squeeze=True) +any(a, axis=None, squeeze=True) + +nansum(a, axis=None, squeeze=True) +nanprod(a, axis=None, squeeze=True) +nanmean(a, axis=None, squeeze=True) +nanstd(a, axis=None, squeeze=True) + +argmin(a, axis=None) +argmax(a, axis=None) + +lt(a, b) +le(a, b) +gt(a, b) +ge(a, b) +eq(a, b) +ne(a, b) + +bvn_cdf(a, b, c) + +cond(condition, f_true, f_false, xs**) +where(condition, a, b) +scan(f, xs, *init_state) + +sort(a, axis=-1, descending=False) +argsort(a, axis=-1, descending=False) +quantile(a, q, axis=None) + +to_numpy(a) +jit_to_numpy(a) # Caches results for `B.jit`. +``` + +### Linear Algebra +``` +transpose(a, perm=None) (alias: t, T) +matmul(a, b, tr_a=False, tr_b=False) (alias: mm, dot) +einsum(equation, *elements) +trace(a, axis1=0, axis2=1) +kron(a, b) +svd(a, compute_uv=True) +eig(a, compute_eigvecs=True) +solve(a, b) +inv(a) +pinv(a) +det(a) +logdet(a) +expm(a) +logm(a) +cholesky(a) (alias: chol) + +cholesky_solve(a, b) (alias: cholsolve) +triangular_solve(a, b, lower_a=True) (alias: trisolve) +toeplitz_solve(a, b, c) (alias: toepsolve) +toeplitz_solve(a, c) + +outer(a, b) +reg(a, diag=None, clip=True) + +pw_dists2(a, b) +pw_dists2(a) +pw_dists(a, b) +pw_dists(a) + +ew_dists2(a, b) +ew_dists2(a) +ew_dists(a, b) +ew_dists(a) + +pw_sums2(a, b) +pw_sums2(a) +pw_sums(a, b) +pw_sums(a) + +ew_sums2(a, b) +ew_sums2(a) +ew_sums(a, b) +ew_sums(a) +``` + +### Random +``` +set_random_seed(seed) +create_random_state(dtype, seed=0) +global_random_state(dtype) +global_random_state(a) +set_global_random_state(state) + +rand(state, dtype, *shape) +rand(dtype, *shape) +rand(*shape) +rand(state, ref) +rand(ref) + +randn(state, dtype, *shape) +randn(dtype, *shape) +randn(*shape) +randn(state, ref) +randn(ref) + +randcat(state, p, *shape) +randcat(p, *shape) + +choice(state, a, *shape, p=None) +choice(a, *shape, p=None) + +randint(state, dtype, *shape, lower=0, upper) +randint(dtype, *shape, lower=0, upper) +randint(*shape, lower=0, upper) +randint(state, ref, lower=0, upper) +randint(ref, lower=0, upper) + +randperm(state, dtype, n) +randperm(dtype, n) +randperm(n) + +randgamma(state, dtype, *shape, alpha, scale) +randgamma(dtype, *shape, alpha, scale) +randgamma(*shape, alpha, scale) +randgamma(state, ref, *, alpha, scale) +randgamma(ref, *, alpha, scale) + +randbeta(state, dtype, *shape, alpha, beta) +randbeta(dtype, *shape, alpha, beta) +randbeta(*shape, alpha, beta) +randbeta(state, ref, *, alpha, beta) +randbeta(ref, *, alpha, beta) +``` + +### Shaping +``` +shape(a, *dims) +rank(a) +length(a) (alias: size) +is_scalar(a) +expand_dims(a, axis=0, times=1) +squeeze(a, axis=None) +uprank(a, rank=2) +downrank(a, rank=2, preserve=False) +broadcast_to(a, *shape) + +diag(a) +diag_extract(a) +diag_construct(a) +flatten(a) +vec_to_tril(a, offset=0) +tril_to_vec(a, offset=0) +stack(*elements, axis=0) +unstack(a, axis=0, squeeze=True) +reshape(a, *shape) +concat(*elements, axis=0) +concat2d(*rows) +tile(a, *repeats) +take(a, indices_or_mask, axis=0) +submatrix(a, indices_or_mask) +``` + +## Devices +You can get the device of a tensor with `B.device(a)`, +and you can execute a computation on a device by entering `B.on_device(device)` +as a context: + +```python +with B.on_device("gpu:0"): + a = B.randn(tf.float32, 2, 2) + b = B.randn(tf.float32, 2, 2) + c = a @ b +``` + +Within such a context, a tensor that is not on the active device can be moved to the +active device with `B.to_active_device(a)`. + +You can also globally set the active device with `B.set_global_device("gpu:0")`. + +## Lazy Shapes +If a function is evaluated abstractly, then elements of the shape of a tensor, e.g. +`B.shape(a)[0]`, may also be tensors, which can break dispatch. +By entering `B.lazy_shapes()`, shapes and elements of shapes will be wrapped in a custom +type to fix this issue. + +```python +with B.lazy_shapes(): + a = B.eye(2) + print(type(B.shape(a))) + # + print(type(B.shape(a)[0])) + # +``` + +## Random Numbers +If you call a random number generator without providing a random state, e.g. +`B.randn(np.float32, 2)`, the global random state from the corresponding +backend is used. +For JAX, since there is no global random state, LAB provides a JAX global +random state accessible through `B.jax_global_random_state` once `lab.jax` +is loaded. + +If you do not want to use a global random state but rather explicitly maintain +one, you can create a random state with `B.create_random_state` and then +pass this as the first argument to the random number generators. +The random number generators will then return a tuple containing the updated +random state and the random result. + +```python +# Create random state. +state = B.create_random_state(tf.float32, seed=0) + +# Generate two random arrays. +state, x = B.randn(state, tf.float32, 2) +state, y = B.randn(state, tf.float32, 2) +``` + + +## Control Flow Cache +Coming soon! + + +%package help +Summary: Development documents and examples for backends +Provides: python3-backends-doc +%description help +# [LAB](http://github.com/wesselb/lab) + +[![CI](https://github.com/wesselb/lab/workflows/CI/badge.svg?branch=master)](https://github.com/wesselb/lab/actions?query=workflow%3ACI) +[![Coverage Status](https://coveralls.io/repos/github/wesselb/lab/badge.svg?branch=master&service=github)](https://coveralls.io/github/wesselb/lab?branch=master) +[![Latest Docs](https://img.shields.io/badge/docs-latest-blue.svg)](https://wesselb.github.io/lab) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) + +A generic interface for linear algebra backends: code it once, run it on any +backend + +* [Requirements and Installation](#requirements-and-installation) +* [Basic Usage](#basic-usage) +* [List of Types](#list-of-types) + - [General](#general) + - [NumPy](#numpy) + - [AutoGrad](#autograd) + - [TensorFlow](#tensorflow) + - [PyTorch](#pytorch) + - [JAX](#jax) +* [List of Methods](#list-of-methods) + - [Constants](#constants) + - [Generic](#generic) + - [Linear Algebra](#linear-algebra) + - [Random](#random) + - [Shaping](#shaping) +* [Devices](#devices) +* [Lazy Shapes](#lazy-shapes) +* [Random Numbers](#random-numbers) +* [Control Flow Cache](#control-flow-cache) + +## Requirements and Installation + +See [the instructions here](https://gist.github.com/wesselb/4b44bf87f3789425f96e26c4308d0adc). +Then simply + +``` +pip install backends +``` + +## Basic Usage + +The basic use case for the package is to write code that automatically +determines the backend to use depending on the types of its arguments. + +Example: + +```python +import lab as B +import lab.autograd # Load the AutoGrad extension. +import lab.torch # Load the PyTorch extension. +import lab.tensorflow # Load the TensorFlow extension. +import lab.jax # Load the JAX extension. + + +def objective(matrix): + outer_product = B.matmul(matrix, matrix, tr_b=True) + return B.mean(outer_product) +``` + +The AutoGrad, PyTorch, TensorFlow, and JAX extensions are not loaded automatically to +not enforce a dependency on all three frameworks. +An extension can alternatively be loaded via `import lab.autograd as B`. + +Run it with NumPy and AutoGrad: + +```python +>>> import autograd.numpy as np + +>>> objective(B.randn(np.float64, 2, 2)) +0.15772589216756833 + +>>> grad(objective)(B.randn(np.float64, 2, 2)) +array([[ 0.23519042, -1.06282928], + [ 0.23519042, -1.06282928]]) +``` + +Run it with TensorFlow: +```python +>>> import tensorflow as tf + +>>> objective(B.randn(tf.float64, 2, 2)) + +``` + +Run it with PyTorch: +```python +>>> import torch + +>>> objective(B.randn(torch.float64, 2, 2)) +tensor(1.9557, dtype=torch.float64) +``` + +Run it with JAX: +```python +>>> import jax + +>>> import jax.numpy as jnp + +>>> jax.jit(objective)(B.randn(jnp.float32, 2, 2)) +DeviceArray(0.3109299, dtype=float32) + +>>> jax.jit(jax.grad(objective))(B.randn(jnp.float32, 2, 2)) +DeviceArray([[ 0.2525182, -1.26065 ], + [ 0.2525182, -1.26065 ]], dtype=float32) +``` + +## List of Types + +This section lists all available types, which can be used to check types of +objects or extend functions. + +### General + +``` +Int # Integers +Float # Floating-point numbers +Complex # Complex numbers +Bool # Booleans +Number # Numbers +Numeric # Numerical objects, including booleans +DType # Data type +Framework # Anything accepted by supported frameworks +Device # Any device type +``` + +### NumPy + +``` +NPNumeric +NPDType +NPRandomState + +NP # Anything NumPy +``` + +### AutoGrad + +``` +AGNumeric +AGDType +AGRandomState + +AG # Anything AutoGrad +``` + +### TensorFlow + +``` +TFNumeric +TFDType +TFRandomState +TFDevice + +TF # Anything TensorFlow +``` + + +### PyTorch + +``` +TorchNumeric +TorchDType +TorchDevice +TorchRandomState + +Torch # Anything PyTorch +``` + + +### JAX + +``` +JAXNumeric +JAXDType +JAXDevice +JAXRandomState + +JAX # Anything JAX +``` + + +## List of Methods +This section lists all available constants and methods. + +* + Arguments *must* be given as arguments and keyword arguments *must* be + given as keyword arguments. + For example, `sum(tensor, axis=1)` is valid, but `sum(tensor, 1)` is not. + +* The names of arguments are indicative of their function: + - `a`, `b`, and `c` indicate general tensors. + - + `dtype` indicates a data type. E.g, `np.float32` or `tf.float64`; and + `rand(np.float32)` creates a NumPy random number, whereas + `rand(tf.float64)` creates a TensorFlow random number. + Data types are always given as the first argument. + - + `shape` indicates a shape. + The dimensions of a shape are always given as separate arguments to + the function. + E.g., `reshape(tensor, 2, 2)` is valid, but `reshape(tensor, (2, 2))` + is not. + - + `axis` indicates an axis over which the function may perform its action. + An axis is always given as a keyword argument. + - + `device` refers to a device on which a tensor can placed, which can + either be a framework-specific type or a string, e.g. `"cpu"`. + - + `ref` indicates a *reference tensor* from which properties, like its + shape and data type, will be used. E.g., `zeros(tensor)` creates a + tensor full of zeros of the same shape and data type as `tensor`. + +See the documentation for more detailed descriptions of each function. + +### Special Variables +``` +default_dtype # Default data type. +epsilon # Magnitude of diagonal to regularise matrices with. +cholesky_retry_factor # Retry the Cholesky, increasing `epsilon` by a factor at most this. +``` + +### Constants +``` +nan +pi +log_2_pi +``` + +### Data Types +``` +dtype(a) +dtype_float(dtype) +dtype_float(a) +dtype_int(dtype) +dtype_int(a) + +promote_dtypes(*dtype) +issubdtype(dtype1, dtype2) +``` + +### Generic +``` +isabstract(a) +jit(f, **kw_args) + +isnan(a) +real(a) +imag(a) + +device(a) +on_device(device) +on_device(a) +set_global_device(device) +to_active_device(a) + +zeros(dtype, *shape) +zeros(*shape) +zeros(ref) + +ones(dtype, *shape) +ones(*shape) +ones(ref) + +zero(dtype) +zero(*refs) + +one(dtype) +one(*refs) + +eye(dtype, *shape) +eye(*shape) +eye(ref) + +linspace(dtype, a, b, num) +linspace(a, b, num) + +range(dtype, start, stop, step) +range(dtype, stop) +range(dtype, start, stop) +range(start, stop, step) +range(start, stop) +range(stop) + +cast(dtype, a) + +identity(a) +round(a) +floor(a) +ceil(a) +negative(a) +abs(a) +sign(a) +sqrt(a) +exp(a) +log(a) +log1p(a) +sin(a) +arcsin(a) +cos(a) +arccos(a) +tan(a) +arctan(a) +tanh(a) +arctanh(a) +loggamma(a) +logbeta(a) +erf(a) +sigmoid(a) +softplus(a) +relu(a) + +add(a, b) +subtract(a, b) +multiply(a, b) +divide(a, b) +power(a, b) +minimum(a, b) +maximum(a, b) +leaky_relu(a, alpha) + +softmax(a, axis=None) + +min(a, axis=None, squeeze=True) +max(a, axis=None, squeeze=True) +sum(a, axis=None, squeeze=True) +prod(a, axis=None, squeeze=True) +mean(a, axis=None, squeeze=True) +std(a, axis=None, squeeze=True) +logsumexp(a, axis=None, squeeze=True) +all(a, axis=None, squeeze=True) +any(a, axis=None, squeeze=True) + +nansum(a, axis=None, squeeze=True) +nanprod(a, axis=None, squeeze=True) +nanmean(a, axis=None, squeeze=True) +nanstd(a, axis=None, squeeze=True) + +argmin(a, axis=None) +argmax(a, axis=None) + +lt(a, b) +le(a, b) +gt(a, b) +ge(a, b) +eq(a, b) +ne(a, b) + +bvn_cdf(a, b, c) + +cond(condition, f_true, f_false, xs**) +where(condition, a, b) +scan(f, xs, *init_state) + +sort(a, axis=-1, descending=False) +argsort(a, axis=-1, descending=False) +quantile(a, q, axis=None) + +to_numpy(a) +jit_to_numpy(a) # Caches results for `B.jit`. +``` + +### Linear Algebra +``` +transpose(a, perm=None) (alias: t, T) +matmul(a, b, tr_a=False, tr_b=False) (alias: mm, dot) +einsum(equation, *elements) +trace(a, axis1=0, axis2=1) +kron(a, b) +svd(a, compute_uv=True) +eig(a, compute_eigvecs=True) +solve(a, b) +inv(a) +pinv(a) +det(a) +logdet(a) +expm(a) +logm(a) +cholesky(a) (alias: chol) + +cholesky_solve(a, b) (alias: cholsolve) +triangular_solve(a, b, lower_a=True) (alias: trisolve) +toeplitz_solve(a, b, c) (alias: toepsolve) +toeplitz_solve(a, c) + +outer(a, b) +reg(a, diag=None, clip=True) + +pw_dists2(a, b) +pw_dists2(a) +pw_dists(a, b) +pw_dists(a) + +ew_dists2(a, b) +ew_dists2(a) +ew_dists(a, b) +ew_dists(a) + +pw_sums2(a, b) +pw_sums2(a) +pw_sums(a, b) +pw_sums(a) + +ew_sums2(a, b) +ew_sums2(a) +ew_sums(a, b) +ew_sums(a) +``` + +### Random +``` +set_random_seed(seed) +create_random_state(dtype, seed=0) +global_random_state(dtype) +global_random_state(a) +set_global_random_state(state) + +rand(state, dtype, *shape) +rand(dtype, *shape) +rand(*shape) +rand(state, ref) +rand(ref) + +randn(state, dtype, *shape) +randn(dtype, *shape) +randn(*shape) +randn(state, ref) +randn(ref) + +randcat(state, p, *shape) +randcat(p, *shape) + +choice(state, a, *shape, p=None) +choice(a, *shape, p=None) + +randint(state, dtype, *shape, lower=0, upper) +randint(dtype, *shape, lower=0, upper) +randint(*shape, lower=0, upper) +randint(state, ref, lower=0, upper) +randint(ref, lower=0, upper) + +randperm(state, dtype, n) +randperm(dtype, n) +randperm(n) + +randgamma(state, dtype, *shape, alpha, scale) +randgamma(dtype, *shape, alpha, scale) +randgamma(*shape, alpha, scale) +randgamma(state, ref, *, alpha, scale) +randgamma(ref, *, alpha, scale) + +randbeta(state, dtype, *shape, alpha, beta) +randbeta(dtype, *shape, alpha, beta) +randbeta(*shape, alpha, beta) +randbeta(state, ref, *, alpha, beta) +randbeta(ref, *, alpha, beta) +``` + +### Shaping +``` +shape(a, *dims) +rank(a) +length(a) (alias: size) +is_scalar(a) +expand_dims(a, axis=0, times=1) +squeeze(a, axis=None) +uprank(a, rank=2) +downrank(a, rank=2, preserve=False) +broadcast_to(a, *shape) + +diag(a) +diag_extract(a) +diag_construct(a) +flatten(a) +vec_to_tril(a, offset=0) +tril_to_vec(a, offset=0) +stack(*elements, axis=0) +unstack(a, axis=0, squeeze=True) +reshape(a, *shape) +concat(*elements, axis=0) +concat2d(*rows) +tile(a, *repeats) +take(a, indices_or_mask, axis=0) +submatrix(a, indices_or_mask) +``` + +## Devices +You can get the device of a tensor with `B.device(a)`, +and you can execute a computation on a device by entering `B.on_device(device)` +as a context: + +```python +with B.on_device("gpu:0"): + a = B.randn(tf.float32, 2, 2) + b = B.randn(tf.float32, 2, 2) + c = a @ b +``` + +Within such a context, a tensor that is not on the active device can be moved to the +active device with `B.to_active_device(a)`. + +You can also globally set the active device with `B.set_global_device("gpu:0")`. + +## Lazy Shapes +If a function is evaluated abstractly, then elements of the shape of a tensor, e.g. +`B.shape(a)[0]`, may also be tensors, which can break dispatch. +By entering `B.lazy_shapes()`, shapes and elements of shapes will be wrapped in a custom +type to fix this issue. + +```python +with B.lazy_shapes(): + a = B.eye(2) + print(type(B.shape(a))) + # + print(type(B.shape(a)[0])) + # +``` + +## Random Numbers +If you call a random number generator without providing a random state, e.g. +`B.randn(np.float32, 2)`, the global random state from the corresponding +backend is used. +For JAX, since there is no global random state, LAB provides a JAX global +random state accessible through `B.jax_global_random_state` once `lab.jax` +is loaded. + +If you do not want to use a global random state but rather explicitly maintain +one, you can create a random state with `B.create_random_state` and then +pass this as the first argument to the random number generators. +The random number generators will then return a tuple containing the updated +random state and the random result. + +```python +# Create random state. +state = B.create_random_state(tf.float32, seed=0) + +# Generate two random arrays. +state, x = B.randn(state, tf.float32, 2) +state, y = B.randn(state, tf.float32, 2) +``` + + +## Control Flow Cache +Coming soon! + + +%prep +%autosetup -n backends-1.5.3 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-backends -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Wed May 10 2023 Python_Bot - 1.5.3-1 +- Package Spec generated diff --git a/sources b/sources new file mode 100644 index 0000000..7c4f3a4 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +31a761f1d9642e2a7fca58e9b327ee13 backends-1.5.3.tar.gz -- cgit v1.2.3