Skip to content

Use pixi to install environment #19

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

Open
wants to merge 4 commits into
base: main
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
31 changes: 31 additions & 0 deletions .github/workflows/pixi_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Tests on GPU

on:
push:
branches:
- main
tags:
- v*.*.*
pull_request: {}

jobs:
test:
runs-on: [ubuntu-latest, gpu]

steps:
- name: Check out the repository
uses: actions/checkout@v4

- name: Install pixi
run: |
curl -fsSL https://pixi.sh/install.sh | bash
echo "$HOME/.pixi/bin" >> $GITHUB_PATH

- name: Show NVIDIA-smi
run: nvidia-smi

- name: install pixi test environment
run: pixi install -e dev

- name: run pytest
run: pixi run -e dev test
4 changes: 4 additions & 0 deletions bigwig_loader/intervals_to_values.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import math
from math import isnan
from pathlib import Path

import cupy as cp
Expand Down Expand Up @@ -120,6 +121,7 @@ def intervals_to_values(
array_start = cp.ascontiguousarray(array_start)
array_end = cp.ascontiguousarray(array_end)
array_value = cp.ascontiguousarray(array_value)
default_value_isnan = isnan(default_value)

cuda_kernel(
(grid_size,),
Expand All @@ -137,6 +139,8 @@ def intervals_to_values(
sequence_length,
max_number_intervals,
window_size,
default_value,
default_value_isnan,
out,
),
)
Expand Down
31 changes: 26 additions & 5 deletions cuda_kernels/intervals_to_values.cu
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <math_constants.h>

extern "C" __global__
void intervals_to_values(
const unsigned int* query_starts,
Expand All @@ -12,6 +14,8 @@ void intervals_to_values(
const int sequence_length,
const int max_number_intervals,
const int window_size,
const float default_value,
const bool default_value_isnan,
float* out
) {

Expand Down Expand Up @@ -49,7 +53,7 @@ void intervals_to_values(
}
} else {

int track_index = i / batch_size;
// int track_index = i / batch_size;

int found_start_index = found_starts[i];
int found_end_index = found_ends[i];
Expand All @@ -59,6 +63,8 @@ void intervals_to_values(
int cursor = found_start_index;
int window_index = 0;
float summation = 0.0f;
int valid_count = 0;


int reduced_dim = sequence_length / window_size;

Expand All @@ -73,19 +79,34 @@ void intervals_to_values(
int end_index = min(interval_end, query_end) - query_start;

if (start_index >= window_end) {
out[i * reduced_dim + window_index] = summation / window_size;
if (default_value_isnan) {
out[i * reduced_dim + window_index] = valid_count > 0 ? summation / valid_count : CUDART_NAN_F;
} else {
summation = summation + (window_size - valid_count) * default_value;
out[i * reduced_dim + window_index] = summation / window_size;
}
summation = 0.0f;
valid_count = 0;
window_index += 1;
continue;
}

int number = min(window_end, end_index) - max(window_start, start_index);

summation += number * track_values[cursor];
if (number > 0) {
summation += number * track_values[cursor];
valid_count += number;
}

if (end_index >= window_end || cursor + 1 >= found_end_index) {
out[i * reduced_dim + window_index] = summation / window_size;
summation = 0.0f;
if (default_value_isnan) {
out[i * reduced_dim + window_index] = valid_count > 0 ? summation / valid_count : CUDART_NAN_F;
} else {
summation = summation + (window_size - valid_count) * default_value;
out[i * reduced_dim + window_index] = summation / window_size;
}
summation = 0.0f;
valid_count = 0;
window_index += 1;
}

Expand Down
1 change: 1 addition & 0 deletions example_data/some_positions.tsv
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
chr center
chr1 45298878
chr18 61036865
chr17 12174372
chr3 65857025
Expand Down
44 changes: 44 additions & 0 deletions pixi.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[workspace]
channels = ["rapidsai", "conda-forge", "nvidia"]
name = "bigwig-loader"
platforms = ["linux-64"]
version = "0.1.0"

[tasks]
test = { cmd = 'pytest -v' }

[dependencies]
python = ">=3.10"
pip = "*"
cython="*"
c-compiler = "*"
kvikio = ">=24.06.00"
cupy = ">=12.0.0"
numpy = ">=1.21"
pandas = "*"

[pypi-dependencies]
torch = "*"
python-dotenv = "*"
pydantic = "*"
pydantic-settings = "*"
pyfaidx = "*"
natsort = "*"
setuptools-scm = "*"
ncls = "*"
bigwig_loader = { path = ".", editable = true }

[feature.test.pypi-dependencies]
pytest = "*"
pytest-sugar = "*"
pytest-cov = "*"
pytest-mock = "*"
pyBigWig = "*"

[feature.dev.pypi-dependencies]
mypy = "*"
pre-commit = "*"

[environments]
test = {features = ["test"]}
dev = {features = ["test", "dev"]}
32 changes: 30 additions & 2 deletions tests/test_against_pybigwig.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ def get_batch(self, chromosomes, starts, ends):


def test_same_output(bigwig_path):
pybigwig_collection = PyBigWigCollection(bigwig_path, first_n_files=2)
collection = BigWigCollection(bigwig_path, first_n_files=2)
pybigwig_collection = PyBigWigCollection(bigwig_path, first_n_files=3)
collection = BigWigCollection(bigwig_path, first_n_files=3)

df = pd.read_csv(config.example_positions, sep="\t")
df = df[df["chr"].isin(collection.get_chromosomes_present_in_all_files())]
Expand All @@ -49,3 +49,31 @@ def test_same_output(bigwig_path):
print(this_batch[pybigwig_batch != this_batch])
print(pybigwig_batch[pybigwig_batch != this_batch])
assert (pybigwig_batch == this_batch).all()


def test_same_output_with_nans(bigwig_path):
pybigwig_collection = PyBigWigCollection(bigwig_path, first_n_files=3)
collection = BigWigCollection(bigwig_path, first_n_files=3)

df = pd.read_csv(config.example_positions, sep="\t")
df = df[df["chr"].isin(collection.get_chromosomes_present_in_all_files())]
chromosomes, starts, ends = (
list(df["chr"]),
list(df["center"] - 1000),
list(df["center"] + 1000),
)

pybigwig_batch = pybigwig_collection.get_batch(chromosomes, starts, ends)

this_batch = collection.get_batch(
chromosomes, starts, ends, default_value=np.nan
).get()
print("PyBigWig:")
print(pybigwig_batch)
print(type(this_batch), "shape:", pybigwig_batch.shape)
print("This Library:")
print(this_batch)
print(type(this_batch), "shape:", this_batch.shape)
print(this_batch[pybigwig_batch != this_batch])
print(pybigwig_batch[pybigwig_batch != this_batch])
assert np.allclose(pybigwig_batch, this_batch, equal_nan=True)
Loading
Loading