mod cpu_tensor;
mod gpu_tensor;
use blocking::block_on;
pub use cpu_tensor::*;
pub use gpu_tensor::*;
pub mod traits;
use std::collections::VecDeque;
use std::fmt::{Debug, Formatter};
pub use traits::*;
pub mod prelude;
pub struct Tensor {
actual_tensor: GpuTensor,
}
impl Debug for Tensor {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.actual_tensor.fmt(f)
}
}
pub struct TensorView<'a> {
actual_tensor: GpuTensorView<'a>,
}
impl <'a> Debug for TensorView<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
block_on(self.actual_tensor.to_cpu()).fmt(f)
}
}
impl<'a> TensorView<'a> {
pub async fn make_contiguous_async(&self) -> Tensor {
Tensor{
actual_tensor: self.actual_tensor.contiguous().await
}
}
pub fn make_contiguous(&self) -> Tensor {
block_on(self.make_contiguous_async())
}
pub async fn compare_async(&self, other: &Self) -> bool {
self.actual_tensor.eq(&other.actual_tensor).await
}
pub fn compare(&self, other: &Self) -> bool {
block_on(self.actual_tensor.eq(&other.actual_tensor))
}
pub fn shape(&self) -> &VecDeque<usize> {
self.actual_tensor.shape()
}
pub fn strides(&self) -> &VecDeque<usize> {
self.actual_tensor.strides()
}
pub async fn to_cpu_async(&self) -> CpuTensor {
self.actual_tensor.to_cpu().await
}
pub fn to_cpu(&self) -> CpuTensor {
block_on(self.to_cpu_async())
}
}
impl Clone for Tensor {
fn clone(&self) -> Self {
Self {
actual_tensor: blocking::block_on(self.actual_tensor.clone()),
}
}
}
impl Tensor {
pub fn empty() -> Self {
Tensor {
actual_tensor: GpuTensor::from(vec![], vec![])
}
}
pub fn from_data_1d(vec: Vec<f32>) -> Self {
assert!(!vec.is_empty(), "Data cant be empty!");
Tensor {
actual_tensor: GpuTensor::from_data_1d(vec),
}
}
pub fn from_data_and_shape(vec: Vec<f32>, shape: Vec<usize>) -> Self {
assert!(!vec.is_empty(), "Data cant be empty!");
assert!(!shape.is_empty(), "Shape cant be empty!");
Tensor {
actual_tensor: GpuTensor::from(vec, shape),
}
}
pub fn zeros(shape: Vec<usize>) -> Self {
block_on(Tensor::zeros_async(shape))
}
pub async fn zeros_async(shape: Vec<usize>) -> Self {
assert!(!shape.is_empty(), "Shape cant be empty!");
Self {
actual_tensor: GpuTensor::new_filled(shape, 0.).await,
}
}
pub fn rand(shape: Vec<usize>) -> Self {
Self {
actual_tensor: CpuTensor::rand(shape).to_gpu(),
}
}
pub fn zeros_like(other: &Self) -> Self {
Self::zeros(Vec::from(other.shape().clone()))
}
pub async fn zeros_like_async(other: &Self) -> Self {
Self::zeros_async(Vec::from(other.shape().clone())).await
}
pub fn clone(&self) -> Self {
Self {
actual_tensor: block_on(self.actual_tensor.clone()),
}
}
pub async fn clone_async(&self) -> Self {
Self {
actual_tensor: self.actual_tensor.clone().await,
}
}
pub fn shape(&self) -> &VecDeque<usize> {
self.actual_tensor.shape()
}
pub fn strides(&self) -> &VecDeque<usize> {
self.actual_tensor.strides()
}
pub fn fill_with(&mut self, value: f32) {
block_on(self.actual_tensor.fill_with(value));
}
pub async fn fill_with_async(&mut self, value: f32) {
self.actual_tensor.fill_with(value).await;
}
pub async fn matmul_async(&mut self, other: &Self) -> Self {
Self {
actual_tensor: self.actual_tensor.matmul(&other.actual_tensor).await,
}
}
pub fn matmul(&self, other: &Self) -> Self {
Self {
actual_tensor: block_on(self.actual_tensor.matmul(&other.actual_tensor)),
}
}
pub async fn relu_async(&self, leakage: f32) -> Self {
Self {
actual_tensor: self.actual_tensor.leaky_relu(leakage).await,
}
}
pub fn relu(&self, leakage: f32) -> Self {
Self {
actual_tensor: block_on(self.actual_tensor.leaky_relu(leakage)),
}
}
pub async fn compare_async(&self, other: &Self) -> bool {
self.actual_tensor
.view()
.eq(&other.actual_tensor.view())
.await
}
pub fn compare(&self, other: &Self) -> bool {
block_on(self.actual_tensor.view().eq(&other.actual_tensor.view()))
}
pub async fn to_cpu_async(&self) -> CpuTensor {
self.actual_tensor.to_cpu().await
}
pub fn to_cpu(&self) -> CpuTensor {
block_on(self.actual_tensor.to_cpu())
}
pub fn slice<'a, T: Into<SliceRangeInfo>>(&'a self, indices: Vec<T>) -> TensorView<'a> {
TensorView {
actual_tensor: self.actual_tensor.slice(indices),
}
}
pub async fn assign_async<T: Into<SliceRangeInfo>>(&mut self, indices: Vec<T>, value: f32) {
self.actual_tensor.assign(indices, value).await;
}
pub fn assign<T: Into<SliceRangeInfo>>(&mut self, indices: Vec<T>, value: f32) {
block_on(self.actual_tensor.assign(indices, value));
}
pub async fn transpose_async(&self) -> Tensor {
Tensor{
actual_tensor:self.actual_tensor.transpose().await
}
}
pub fn transpose(&self) -> Tensor {
block_on(self.transpose_async())
}
pub fn reshape(&mut self, new_shape: Vec<usize>) {
self.actual_tensor.reshape(new_shape);
}
}