Skip to content

Commit eb38994

Browse files
authored
Add GitHub Actions CI (#5)
* chore: add ci pipeline * Use actions-rs toolchain for CI * Fix formatting and lint errors
1 parent 0255443 commit eb38994

File tree

12 files changed

+174
-78
lines changed

12 files changed

+174
-78
lines changed

.github/workflows/ci.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v3
15+
- uses: actions-rs/toolchain@v1
16+
with:
17+
toolchain: stable
18+
profile: minimal
19+
components: rustfmt, clippy
20+
- name: Format
21+
run: cargo fmt --all -- --check
22+
- name: Lint
23+
run: cargo clippy --workspace --all-targets -- -D warnings
24+
- name: Test
25+
run: cargo test --workspace --all-targets

crates/phantom-core/src/backend/cpu_backend.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
use crate::storage::StorageError;
12
use crate::storage::{BinaryOperation, UnaryOperation};
23
use crate::{index::StridedIndex, DType, Shape};
3-
use crate::storage::StorageError;
44

55
#[derive(Debug, Clone)]
66
pub enum CPUStorage {
@@ -94,7 +94,11 @@ impl CPUStorage {
9494
}
9595
}
9696

97-
pub(crate) fn transpose(&self, shape: &Shape, stride: &[usize]) -> std::result::Result<Self, StorageError> {
97+
pub(crate) fn transpose(
98+
&self,
99+
shape: &Shape,
100+
stride: &[usize],
101+
) -> std::result::Result<Self, StorageError> {
98102
let (rows, cols) = match shape.rank_two() {
99103
Ok(rc) => rc,
100104
Err(_) => {

crates/phantom-core/src/backprop.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use crate::tensor::{Tensor, TensorID};
2-
use crate::{Operation};
31
use crate::tensor::TensorError;
2+
use crate::tensor::{Tensor, TensorID};
3+
use crate::Operation;
44

55
#[derive(Debug)]
66
pub enum BackpropError {

crates/phantom-core/src/device.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::backend::cpu_backend::CPUStorage;
2-
use crate::{storage::Storage, DType, Shape};
32
use crate::shape::ShapeError;
3+
use crate::{storage::Storage, DType, Shape};
44

55
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
66
pub enum Device {

crates/phantom-core/src/index.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,7 @@ impl<'a> Iterator for StridedIndex<'a> {
3131
type Item = usize;
3232

3333
fn next(&mut self) -> Option<Self::Item> {
34-
let storage_index = match self.next_index {
35-
None => return None,
36-
Some(storage_index) => storage_index,
37-
};
34+
let storage_index = self.next_index?;
3835
let mut updated = false;
3936
for (multi_i, max_i) in self.multi_index.iter_mut().zip(self.dims.iter()).rev() {
4037
let next_i = *multi_i + 1;

crates/phantom-core/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ mod storage;
99
mod tensor;
1010

1111
pub use backend::cpu_backend::CPUStorage;
12+
pub use backprop::BackpropError;
1213
pub use device::Device;
13-
pub use dtype::{DType, WithDType};
1414
pub use dtype::DTypeError;
15+
pub use dtype::{DType, WithDType};
1516
pub use index::StridedIndex;
1617
pub use operation::Operation;
1718
pub use shape::Shape;
1819
pub use shape::ShapeError;
1920
pub use storage::Storage;
2021
pub use storage::StorageError;
2122
pub use tensor::{Tensor, TensorError, TensorID};
22-
pub use backprop::BackpropError;

crates/phantom-core/src/shape.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1-
21
#[derive(Debug)]
32
pub enum ShapeError {
4-
UnexpectedRank { expected: usize, actual: usize, shape: Shape },
3+
UnexpectedRank {
4+
expected: usize,
5+
actual: usize,
6+
shape: Shape,
7+
},
58
}
69

710
impl std::fmt::Display for ShapeError {
811
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
912
match self {
10-
ShapeError::UnexpectedRank { expected, actual, .. } => {
11-
write!(f, "unexpected rank, expected: {}, actual: {}", expected, actual)
13+
ShapeError::UnexpectedRank {
14+
expected, actual, ..
15+
} => {
16+
write!(
17+
f,
18+
"unexpected rank, expected: {}, actual: {}",
19+
expected, actual
20+
)
1221
}
1322
}
1423
}

crates/phantom-core/src/storage.rs

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,46 @@ use crate::{DType, Device, Shape};
33

44
#[derive(Debug)]
55
pub enum StorageError {
6-
BinaryOperationDeviceMismatch { lhs: Device, rhs: Device, op: &'static str },
7-
BinaryOperationDTypeMismatch { lhs: DType, rhs: DType, op: &'static str },
8-
BinaryOperationShapeMismatch { lhs: Shape, rhs: Shape, op: &'static str },
6+
BinaryOperationDeviceMismatch {
7+
lhs: Device,
8+
rhs: Device,
9+
op: &'static str,
10+
},
11+
BinaryOperationDTypeMismatch {
12+
lhs: DType,
13+
rhs: DType,
14+
op: &'static str,
15+
},
16+
BinaryOperationShapeMismatch {
17+
lhs: Shape,
18+
rhs: Shape,
19+
op: &'static str,
20+
},
921
}
1022

1123
impl std::fmt::Display for StorageError {
1224
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1325
match self {
1426
StorageError::BinaryOperationDeviceMismatch { lhs, rhs, op } => {
15-
write!(f, "unexpected device in {}, lhs: {:?}, rhs: {:?}", op, lhs, rhs)
27+
write!(
28+
f,
29+
"unexpected device in {}, lhs: {:?}, rhs: {:?}",
30+
op, lhs, rhs
31+
)
1632
}
1733
StorageError::BinaryOperationDTypeMismatch { lhs, rhs, op } => {
18-
write!(f, "unexpected dtype in {}, lhs: {:?}, rhs: {:?}", op, lhs, rhs)
34+
write!(
35+
f,
36+
"unexpected dtype in {}, lhs: {:?}, rhs: {:?}",
37+
op, lhs, rhs
38+
)
1939
}
2040
StorageError::BinaryOperationShapeMismatch { lhs, rhs, op } => {
21-
write!(f, "unexpected shape in {}, lhs: {:?}, rhs: {:?}", op, lhs, rhs)
41+
write!(
42+
f,
43+
"unexpected shape in {}, lhs: {:?}, rhs: {:?}",
44+
op, lhs, rhs
45+
)
2246
}
2347
}
2448
}
@@ -139,7 +163,11 @@ impl Storage {
139163
}
140164
}
141165

142-
pub(crate) fn matches_device(&self, rhs: &Self, op: &'static str) -> std::result::Result<(), StorageError> {
166+
pub(crate) fn matches_device(
167+
&self,
168+
rhs: &Self,
169+
op: &'static str,
170+
) -> std::result::Result<(), StorageError> {
143171
let lhs = self.device();
144172
let rhs = rhs.device();
145173

@@ -150,7 +178,11 @@ impl Storage {
150178
}
151179
}
152180

153-
pub(crate) fn matches_dtype(&self, rhs: &Self, op: &'static str) -> std::result::Result<(), StorageError> {
181+
pub(crate) fn matches_dtype(
182+
&self,
183+
rhs: &Self,
184+
op: &'static str,
185+
) -> std::result::Result<(), StorageError> {
154186
let lhs = self.dtype();
155187
let rhs = rhs.dtype();
156188

@@ -161,7 +193,11 @@ impl Storage {
161193
}
162194
}
163195

164-
fn unary_operation<T: UnaryOperation>(&self, shape: &Shape, stride: &[usize]) -> std::result::Result<Self, StorageError> {
196+
fn unary_operation<T: UnaryOperation>(
197+
&self,
198+
shape: &Shape,
199+
stride: &[usize],
200+
) -> std::result::Result<Self, StorageError> {
165201
match self {
166202
Storage::CPU(storage) => {
167203
let storage = storage.unary_impl::<T>(shape, stride)?;
@@ -245,19 +281,35 @@ impl Storage {
245281
}
246282
}
247283

248-
pub(crate) fn sqr(&self, shape: &Shape, stride: &[usize]) -> std::result::Result<Self, StorageError> {
284+
pub(crate) fn sqr(
285+
&self,
286+
shape: &Shape,
287+
stride: &[usize],
288+
) -> std::result::Result<Self, StorageError> {
249289
self.unary_operation::<Sqr>(shape, stride)
250290
}
251291

252-
pub(crate) fn sqrt(&self, shape: &Shape, stride: &[usize]) -> std::result::Result<Self, StorageError> {
292+
pub(crate) fn sqrt(
293+
&self,
294+
shape: &Shape,
295+
stride: &[usize],
296+
) -> std::result::Result<Self, StorageError> {
253297
self.unary_operation::<Sqrt>(shape, stride)
254298
}
255299

256-
pub(crate) fn neg(&self, shape: &Shape, stride: &[usize]) -> std::result::Result<Self, StorageError> {
300+
pub(crate) fn neg(
301+
&self,
302+
shape: &Shape,
303+
stride: &[usize],
304+
) -> std::result::Result<Self, StorageError> {
257305
self.unary_operation::<Neg>(shape, stride)
258306
}
259307

260-
pub(crate) fn transpose(&self, shape: &Shape, stride: &[usize]) -> std::result::Result<Self, StorageError> {
308+
pub(crate) fn transpose(
309+
&self,
310+
shape: &Shape,
311+
stride: &[usize],
312+
) -> std::result::Result<Self, StorageError> {
261313
match self {
262314
Storage::CPU(storage) => {
263315
let storage = storage.transpose(shape, stride)?;

crates/phantom-core/src/tensor.rs

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ use std::sync::atomic::{AtomicUsize, Ordering};
22
use std::sync::Arc;
33

44
use crate::device::{Device, NDArray};
5+
use crate::dtype::DTypeError;
56
use crate::index::StridedIndex;
7+
use crate::shape::ShapeError;
68
use crate::storage::Storage;
9+
use crate::storage::StorageError;
710
use crate::WithDType;
811
use crate::{DType, Operation, Shape};
9-
use crate::dtype::DTypeError;
10-
use crate::shape::ShapeError;
11-
use crate::storage::StorageError;
1212

1313
#[derive(Debug)]
1414
pub enum TensorError {
@@ -131,7 +131,11 @@ macro_rules! unary_operation {
131131
}
132132

133133
impl Tensor {
134-
pub(crate) fn new_impl<A: NDArray>(array: A, device: Device, variable: bool) -> std::result::Result<Self, TensorError> {
134+
pub(crate) fn new_impl<A: NDArray>(
135+
array: A,
136+
device: Device,
137+
variable: bool,
138+
) -> std::result::Result<Self, TensorError> {
135139
let shape: Shape = array.shape()?;
136140
let storage: Storage = device.tensor(array);
137141
let stride: Vec<usize> = shape.stride_contiguous();
@@ -475,7 +479,9 @@ impl Tensor {
475479
/// assert_eq!(a.to_vector_rank_two::<f32>()?, &[[0., 1.], [2., 3.], [4., 5.]]);
476480
/// # Ok::<(), Box<dyn std::error::Error>>(())
477481
/// ```
478-
pub fn to_vector_rank_two<S: WithDType>(&self) -> std::result::Result<Vec<Vec<S>>, TensorError> {
482+
pub fn to_vector_rank_two<S: WithDType>(
483+
&self,
484+
) -> std::result::Result<Vec<Vec<S>>, TensorError> {
479485
let (dim_one, dim_two) = self.shape().rank_two()?;
480486
match &self.storage {
481487
Storage::CPU(storage) => {
@@ -510,11 +516,13 @@ impl Tensor {
510516
let rhs = rhs.shape();
511517

512518
if lhs != rhs {
513-
Err(TensorError::Storage(StorageError::BinaryOperationShapeMismatch {
514-
lhs: lhs.clone(),
515-
rhs: rhs.clone(),
516-
op: operation,
517-
}))
519+
Err(TensorError::Storage(
520+
StorageError::BinaryOperationShapeMismatch {
521+
lhs: lhs.clone(),
522+
rhs: rhs.clone(),
523+
op: operation,
524+
},
525+
))
518526
} else {
519527
Ok(lhs)
520528
}
@@ -596,29 +604,39 @@ impl Tensor {
596604
if self.rank() != 2 || rhs.rank() != 2 {
597605
return Err(TensorError::Shape(ShapeError::UnexpectedRank {
598606
expected: 2,
599-
actual: if self.rank() != 2 { self.rank() } else { rhs.rank() },
600-
shape: if self.rank() != 2 { self.shape().clone() } else { rhs.shape().clone() },
607+
actual: if self.rank() != 2 {
608+
self.rank()
609+
} else {
610+
rhs.rank()
611+
},
612+
shape: if self.rank() != 2 {
613+
self.shape().clone()
614+
} else {
615+
rhs.shape().clone()
616+
},
601617
}));
602618
}
603619
let (m, k) = self.shape().rank_two()?;
604620
let (k_rhs, n) = rhs.shape().rank_two()?;
605621
if k != k_rhs {
606-
return Err(TensorError::Storage(StorageError::BinaryOperationShapeMismatch {
607-
lhs: self.shape().clone(),
608-
rhs: rhs.shape().clone(),
609-
op: "matmul",
610-
}));
622+
return Err(TensorError::Storage(
623+
StorageError::BinaryOperationShapeMismatch {
624+
lhs: self.shape().clone(),
625+
rhs: rhs.shape().clone(),
626+
op: "matmul",
627+
},
628+
));
611629
}
612630
let storage = self
613631
.storage
614632
.matmul(
615-
&rhs.storage,
616-
(m, k),
617-
self.stride(),
618-
(k_rhs, n),
619-
rhs.stride(),
620-
)
621-
.map_err(TensorError::from)?;
633+
&rhs.storage,
634+
(m, k),
635+
self.stride(),
636+
(k_rhs, n),
637+
rhs.stride(),
638+
)
639+
.map_err(TensorError::from)?;
622640
let shape = Shape::from((m, n));
623641
let t = Tensor_ {
624642
id: TensorID::new(),
@@ -651,15 +669,19 @@ macro_rules! binary_trait {
651669
}
652670
}
653671

654-
impl<B: std::borrow::Borrow<Tensor>> std::ops::$trait<std::result::Result<B, TensorError>> for Tensor {
672+
impl<B: std::borrow::Borrow<Tensor>> std::ops::$trait<std::result::Result<B, TensorError>>
673+
for Tensor
674+
{
655675
type Output = std::result::Result<Tensor, TensorError>;
656676

657677
fn $fn1(self, rhs: std::result::Result<B, TensorError>) -> Self::Output {
658678
Tensor::$fn1(&self, rhs?.borrow())
659679
}
660680
}
661681

662-
impl<B: std::borrow::Borrow<Tensor>> std::ops::$trait<std::result::Result<B, TensorError>> for &Tensor {
682+
impl<B: std::borrow::Borrow<Tensor>> std::ops::$trait<std::result::Result<B, TensorError>>
683+
for &Tensor
684+
{
663685
type Output = std::result::Result<Tensor, TensorError>;
664686

665687
fn $fn1(self, rhs: std::result::Result<B, TensorError>) -> Self::Output {

crates/phantom-layers/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
pub mod linear;
22

33
pub use linear::Linear;
4-

0 commit comments

Comments
 (0)