singe_npp/pipeline/
signal.rs1mod binary;
2mod conversion;
3mod copy;
4mod fill;
5mod filtering;
6mod normalize;
7mod operations;
8mod scaled_constant;
9mod statistics;
10mod statistics_error_methods;
11mod statistics_extremum_methods;
12mod statistics_methods;
13mod statistics_output_methods;
14mod unary;
15
16use singe_cuda::memory::DeviceMemory;
17
18use crate::{
19 context::StreamContext,
20 error::Result,
21 pipeline::{SignalAllocator, Workspace, memory_context::validate_device_memory_stream_context},
22 signal::{
23 memory::Signal,
24 view::{SignalView, SignalViewMut},
25 },
26};
27
28pub use copy::CopySignal;
29pub use statistics::{SignalIndexedValue, SignalMeanStandardDeviation, SignalMinMax};
30
31#[derive(Debug)]
32#[non_exhaustive]
33pub enum SignalBacking<'a, T> {
34 Borrowed(SignalView<'a, T>),
35 Owned(Signal<T>),
36}
37
38pub struct SignalPipeline<'a, T> {
39 stream_context: &'a StreamContext,
40 workspace: &'a mut Workspace,
41 backing: SignalBacking<'a, T>,
42}
43
44impl<'a, T> SignalPipeline<'a, T>
45where
46 T: Copy,
47{
48 pub fn create(
49 stream_context: &'a StreamContext,
50 workspace: &'a mut Workspace,
51 len: usize,
52 ) -> Result<Self>
53 where
54 Workspace: SignalAllocator<T>,
55 {
56 let signal = workspace.signal::<T>(len)?;
57 Ok(Self::from_owned(stream_context, workspace, signal))
58 }
59
60 pub fn from_view(
61 stream_context: &'a StreamContext,
62 workspace: &'a mut Workspace,
63 source: SignalView<'a, T>,
64 ) -> Self {
65 Self {
66 stream_context,
67 workspace,
68 backing: SignalBacking::Borrowed(source),
69 }
70 }
71
72 pub fn from_owned(
73 stream_context: &'a StreamContext,
74 workspace: &'a mut Workspace,
75 signal: Signal<T>,
76 ) -> Self {
77 Self {
78 stream_context,
79 workspace,
80 backing: SignalBacking::Owned(signal),
81 }
82 }
83
84 pub fn from_memory(
85 stream_context: &'a StreamContext,
86 workspace: &'a mut Workspace,
87 memory: &'a DeviceMemory<T>,
88 len: usize,
89 ) -> Result<Self> {
90 validate_device_memory_stream_context(stream_context, memory)?;
91 Ok(Self::from_view(
92 stream_context,
93 workspace,
94 SignalView::from_memory(memory, len)?,
95 ))
96 }
97
98 pub const fn len(&self) -> usize {
99 match &self.backing {
100 SignalBacking::Borrowed(view) => view.len(),
101 SignalBacking::Owned(signal) => signal.len(),
102 }
103 }
104
105 pub const fn is_empty(&self) -> bool {
106 self.len() == 0
107 }
108
109 pub const fn is_owned(&self) -> bool {
110 matches!(self.backing, SignalBacking::Owned(_))
111 }
112
113 fn view(&self) -> Result<SignalView<'_, T>> {
114 match &self.backing {
115 SignalBacking::Borrowed(view) => Ok(*view),
116 SignalBacking::Owned(signal) => signal.view(),
117 }
118 }
119
120 pub fn into_backing(self) -> SignalBacking<'a, T> {
121 self.backing
122 }
123}
124
125impl<'a, T> SignalPipeline<'a, T>
126where
127 T: Copy,
128 Workspace: SignalAllocator<T>,
129 Self: CopySignal<T>,
130{
131 pub fn finish(self) -> Result<Signal<T>> {
132 match self.backing {
133 SignalBacking::Owned(signal) => Ok(signal),
134 SignalBacking::Borrowed(source) => {
135 let mut destination = self.workspace.signal::<T>(source.len())?;
136 let mut destination_view = destination.view_mut()?;
137 <Self as CopySignal<T>>::copy(self.stream_context, &source, &mut destination_view)?;
138 Ok(destination)
139 }
140 }
141 }
142}
143
144impl<'a, T> SignalPipeline<'a, T>
145where
146 T: Copy,
147 Self: CopySignal<T>,
148{
149 pub fn copy_into(
150 stream_context: &StreamContext,
151 source: &SignalView<'_, T>,
152 destination: &mut SignalViewMut<'_, T>,
153 ) -> Result<()> {
154 <Self as CopySignal<T>>::copy(stream_context, source, destination)
155 }
156}