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

Tests migration to tch #195

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
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
27 changes: 26 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,27 @@ jobs:
fi
shell: bash

- name: Download and install libtorch
run: |
import requests
import zipfile
import os

version = '2.3.0' # default version
with open('requirements.txt') as f:
for line in f:
if 'torch==' in line:
version = line.split('==')[1].strip()
break
response = requests.get(f'https://download.pytorch.org/libtorch/cpu/libtorch-macos-arm64-{version}.zip')
Copy link
Author

Choose a reason for hiding this comment

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

I think an arm64 version of 2.3.0 torch exists as a Python wheel but if you need to download the zip.
This one worked for me for (x86 at least):
wget https://download.pytorch.org/libtorch/cpu/libtorch-shared-with-deps-2.3.0%2Bcpu.zip

Copy link
Collaborator

Choose a reason for hiding this comment

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

@AmineDiro Still being a pain 😡

Copy link
Author

@AmineDiro AmineDiro May 15, 2024

Choose a reason for hiding this comment

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

Ok I think I see the issue (finally got access to the runner output). Setting environment variables in Python I think will not set it in the environment across steps.
I also see in output that we successfully install torch==2.3.0 using pip so I think we can use already installed version without need to download it.

I added the env variable in 87e37ef hope this works

Copy link
Collaborator

Choose a reason for hiding this comment

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

image

Seems tricky, I can look into it later 🫡

Copy link
Author

Choose a reason for hiding this comment

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

Ohh I see that's the DYLIB export 👍🏼

with open('libtorch.zip', 'wb') as f:
f.write(response.content)
with zipfile.ZipFile('libtorch.zip', 'r') as zip_ref:
zip_ref.extractall()
os.environ['LIBTORCH'] = os.path.join(os.getcwd(), f'libtorch')
Copy link
Author

@AmineDiro AmineDiro May 15, 2024

Choose a reason for hiding this comment

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

If the running is MACOS maybe we should add :
export DYLD_LIBRARY_PATH=$LIBTORCH/lib:$DYLD_LIBRARY_PATH. This fixed linking issues for me

os.environ['DYLD_LIBRARY_PATH'] = os.path.join(os.getcwd(), f'libtorch')
shell: python

- uses: FedericoCarboni/setup-ffmpeg@v3
if: matrix.os != 'macos-14'

Expand All @@ -145,9 +166,13 @@ jobs:

- name: run tests
shell: bash
env:
LIBTORCH_USE_PYTORCH: 1
SITE_PACKAGES: $(python -c "import site; print(site.getsitepackages()[0])")
DYLD_LIBRARY_PATH: ${{ env.SITE_PACKAGES }}/torch/lib:$DYLD_LIBRARY_PATH
run: |
set -e
cargo nextest run -j 1 --no-fail-fast --features=ci,pyo3
cargo nextest run -j 1 --no-fail-fast --features=ci,pyo3,testing

- name: Set up WebDriver for Ubuntu
if: matrix.os == 'ubuntu-22.04'
Expand Down
22 changes: 22 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ If that looks like this, you are good to go 🎉

### Step 3: Run Tests

#### PYO3 tests

Finally, run the tests for the package using Cargo:

```sh
Expand All @@ -143,6 +145,26 @@ To run the `PyO3` tests, add the `pyo3` flag:
cargo test --features pyo3
```

#### `tch` tests

`tch` based tests are ran behind the `testing` feature. You need to first have the PyTorch library (libtorch) in v2.3.0 to be available on your system. Follow the [official `tch` for more details](https://github.com/LaurentMazare/tch-rs/tree/main?tab=readme-ov-file). We'll use the libtorch library installed in the python envionment:

```sh
export LIBTORCH_USE_PYTORCH=1
```

You can now run tests:

```sh
cargo test --features testing
```

**NOTE**: If you're having compilation issue with MacOS. You can add the `libtorch` lib to your environment :

```sh
export DYLD_LIBRARY_PATH=$PWD/venv/lib/python3.10/site-packages/torch/lib:$DYLD_LIBRARY_PATH
```

### Step 5: Run WASM Tests

To run WASM tests (e.g., the whisper test) run:
Expand Down
17 changes: 11 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ members = [
"crates/ratchet-web",
"crates/ratchet-loader",
"crates/ratchet-models",
"crates/ratchet-nn",
"crates/ratchet-hub",
"crates/ratchet-nn",
"crates/ratchet-hub",
"crates/ratchet-cli",
]
resolver = "2"
Expand All @@ -18,26 +18,30 @@ debug-assertions = true
[profile.release]
panic = 'abort'
lto = "fat"
codegen-units = 1
codegen-units = 1

[profile.profiling]
inherits = "release"
debug = 2

[workspace.dependencies]
wgpu = { version = "0.20", features = ["fragile-send-sync-non-atomic-wasm"] }
bytemuck = { version = "1.14.0", features=["wasm_simd", "aarch64_simd", "extern_crate_alloc"] }
bytemuck = { version = "1.14.0", features = [
"wasm_simd",
"aarch64_simd",
"extern_crate_alloc",
] }
num-traits = "0.2.17"
half = { version = "2.3.1", features = ["num-traits", "bytemuck"] }
derive-new = "0.6.0"
log = "0.4.20"
thiserror = "1.0.56"
byteorder = "1.5.0"
npyz = { version = "0.8.3"}
npyz = { version = "0.8.3" }
hf-hub = "0.3.2"
serde = "1.0"
anyhow = "1.0.79"
tokenizers = "0.19.1"
tokenizers = "0.19.1"

js-sys = "0.3.64"
wasm-bindgen = "0.2.91"
Expand Down Expand Up @@ -90,3 +94,4 @@ wasm-bindgen-futures = "0.4.41"
web-sys = "0.3.64"
web-time = "1.0.0"
futures-intrusive = "0.5.0"
tch = "0.16.0"
9 changes: 5 additions & 4 deletions crates/ratchet-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ default = ["rand", "testing"]
gpu-profiling = ["dep:tabled", "dep:itertools"]
rand = ["dep:rand", "dep:rand_distr"]
plotting = ["dep:dot3", "dep:tempfile"]
testing = ["dep:npyz", "dep:ndarray"]
testing = ["dep:npyz", "dep:ndarray","dep:tch"]
pyo3 = ["dep:pyo3", "dep:numpy", "dep:regex"]

[build-dependencies]
Expand All @@ -31,7 +31,7 @@ num-traits = { workspace = true }
log = { workspace = true }
thiserror = { workspace = true }
serde = { workspace = true, features = ["derive"] }
anyhow.workspace = true
anyhow.workspace = true

rustc-hash = { workspace = true }
slotmap = { workspace = true }
Expand All @@ -55,12 +55,13 @@ tempfile = { workspace = true, optional = true }
tabled = { workspace = true, optional = true }
itertools = { workspace = true, optional = true }

pyo3 = { workspace = true, features = ["auto-initialize"], optional = true }
pyo3 = { workspace = true, features = ["auto-initialize"], optional = true }
regex = { workspace = true, optional = true }
numpy = { workspace = true, optional = true }
tch = {workspace =true, optional=true}

[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen.workspace = true
wasm-bindgen.workspace = true
futures-intrusive.workspace = true

async-trait = "0.1.77"
Expand Down
17 changes: 10 additions & 7 deletions crates/ratchet-core/src/dtype/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub enum DType {
I32,
U32,
GGUF(gguf::GGUFDType),
I64,
}

impl DType {
Expand Down Expand Up @@ -52,6 +53,7 @@ impl DType {
DType::I32 => 4,
DType::U32 => 4,
DType::GGUF(g) => g.size_of(),
DType::I64 => 8,
}
}

Expand Down Expand Up @@ -111,7 +113,7 @@ pub trait TensorDType:
fn one() -> Self;
}

macro_rules! map_type {
macro_rules! tensor_dt {
($t:ty, $v:ident) => {
impl TensorDType for $t {
fn dt() -> DType {
Expand All @@ -125,7 +127,7 @@ macro_rules! map_type {
};
}

macro_rules! map_half_type {
macro_rules! tensor_half_dt {
($t:ty, $v:ident) => {
impl TensorDType for $t {
fn dt() -> DType {
Expand All @@ -139,11 +141,12 @@ macro_rules! map_half_type {
};
}

map_type!(f32, F32);
map_type!(i32, I32);
map_type!(u32, U32);
map_half_type!(f16, F16);
map_half_type!(bf16, BF16);
tensor_dt!(f32, F32);
tensor_dt!(i32, I32);
tensor_dt!(u32, U32);
tensor_dt!(i64, I64);
tensor_half_dt!(f16, F16);
tensor_half_dt!(bf16, BF16);

//Handy trait for WebGPU buffer alignment
pub trait Align {
Expand Down
6 changes: 6 additions & 0 deletions crates/ratchet-core/src/gpu/buffer_allocator/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ pub struct BufferAllocator {
pool: RwLock<BufferPool>,
}

impl Default for BufferAllocator {
fn default() -> Self {
Self::new()
}
}

impl BufferAllocator {
pub fn new() -> Self {
Self {
Expand Down
6 changes: 6 additions & 0 deletions crates/ratchet-core/src/gpu/pools/bind_group_layout_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ pub struct BindGroupLayoutPool {
StaticResourcePool<BindGroupLayoutHandle, BindGroupLayoutDescriptor, wgpu::BindGroupLayout>,
}

impl Default for BindGroupLayoutPool {
fn default() -> Self {
Self::new()
}
}

impl BindGroupLayoutPool {
pub fn new() -> Self {
Self {
Expand Down
6 changes: 6 additions & 0 deletions crates/ratchet-core/src/gpu/pools/bind_group_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ pub struct BindGroupPool {
inner: DynamicResourcePool<GpuBindGroupHandle, BindGroupDescriptor, wgpu::BindGroup>,
}

impl Default for BindGroupPool {
fn default() -> Self {
Self::new()
}
}

impl BindGroupPool {
pub fn new() -> Self {
Self {
Expand Down
6 changes: 6 additions & 0 deletions crates/ratchet-core/src/gpu/pools/buffer_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ pub struct BufferPool {
inner: DynamicResourcePool<GpuBufferHandle, BufferDescriptor, RawGPUBuffer>,
}

impl Default for BufferPool {
fn default() -> Self {
Self::new()
}
}

impl BufferPool {
pub fn new() -> Self {
Self {
Expand Down
6 changes: 6 additions & 0 deletions crates/ratchet-core/src/gpu/pools/pipeline_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ pub struct ComputePipelinePool {
StaticResourcePool<ComputePipelineHandle, ComputePipelineDescriptor, wgpu::ComputePipeline>,
}

impl Default for ComputePipelinePool {
fn default() -> Self {
Self::new()
}
}

impl ComputePipelinePool {
pub fn new() -> Self {
Self {
Expand Down
23 changes: 11 additions & 12 deletions crates/ratchet-core/src/ops/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ impl MetaOperation for Binary {
}
}

#[cfg(all(test, feature = "pyo3"))]
#[cfg(all(test, feature = "testing"))]
mod tests {
use crate::{test_util::run_py_prg, BinaryOp, Device, DeviceRequest, Shape, Tensor};
use crate::{BinaryOp, Device, DeviceRequest, Shape, Tensor};
use test_strategy::{proptest, Arbitrary};

thread_local! {
Expand All @@ -168,16 +168,15 @@ mod tests {
}

fn ground_truth(a: &Tensor, b: &Tensor, op: &BinaryOp) -> anyhow::Result<Tensor> {
let kn = op.kernel_name();
let prg = format!(
r#"
import torch
def {}(a, b):
return torch.{}(torch.from_numpy(a), torch.from_numpy(b)).numpy()
"#,
kn, kn
);
run_py_prg(prg.to_string(), &[a, b], &[])
let a = a.to_tch::<f32>()?;
let b = b.to_tch::<f32>()?;
let result = match op {
BinaryOp::Add => a.f_add(&b)?,
BinaryOp::Sub => a.f_sub(&b)?,
BinaryOp::Mul => a.f_mul(&b)?,
BinaryOp::Div => a.f_div(&b)?,
};
Tensor::try_from(result)
}

fn run_binary_trial(prob: BinaryProblem) -> anyhow::Result<()> {
Expand Down
30 changes: 10 additions & 20 deletions crates/ratchet-core/src/ops/concat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ impl MetaOperation for Concat {

#[cfg(all(test, feature = "pyo3"))]
mod tests {
use crate::{rvec, shape, test_util::run_py_prg, Device, DeviceRequest, Tensor};
use crate::{rvec, shape, Device, DeviceRequest, Tensor};
use tch::Tensor as TchTensor;

thread_local! {
static GPU_DEVICE: Device = Device::request_device(DeviceRequest::GPU).unwrap();
Expand All @@ -157,22 +158,13 @@ mod tests {
dim: usize,
}

fn ground_truth(to_cat: &[&Tensor], args: &str) -> anyhow::Result<Tensor> {
let prg = format!(
r#"
import torch
import numpy as np
def permute(t0, t1, t2, t3, t4):
t0 = torch.from_numpy(t0)
t1 = torch.from_numpy(t1)
t2 = torch.from_numpy(t2)
t3 = torch.from_numpy(t3)
t4 = torch.from_numpy(t4)
return np.ascontiguousarray(torch.cat((t0, t1, t2, t3, t4), dim={}).numpy())
"#,
args
);
run_py_prg(prg.to_string(), to_cat, &[])
fn ground_truth(to_cat: &[&Tensor], dim: i64) -> anyhow::Result<Tensor> {
let tch_tensors = to_cat
.iter()
.map(|x| x.to_tch::<f32>())
.collect::<Result<Vec<_>, _>>()?;

Tensor::try_from(TchTensor::cat(&tch_tensors, dim))
}

fn run_concat_trial(prob: ConcatProblem) -> anyhow::Result<()> {
Expand All @@ -185,9 +177,7 @@ def permute(t0, t1, t2, t3, t4):
dim,
} = prob;
let device = GPU_DEVICE.with(|d| d.clone());

let arg_str = format!("{}", dim);
let ground = ground_truth(&[&t0, &t1, &t2, &t3, &t4], arg_str.as_str())?;
let ground = ground_truth(&[&t0, &t1, &t2, &t3, &t4], dim as _)?;

t0 = t0.to(&device)?;
t1 = t1.to(&device)?;
Expand Down
Loading
Loading