-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpipeline.tex
163 lines (152 loc) · 4.94 KB
/
pipeline.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
\subsection{Pipelines}
\begin{frame}[t]{Pipeline pattern}
\begin{itemize}
\item A \textgood{pipeline} pattern allows processing a data stream where the
computation may be divided in multiple stages.
\begin{itemize}
\item Each stage processes the data item generated in the previous stage
and passes the produced result to the next stage.
\end{itemize}
\end{itemize}
\vfill
\begin{center}
\begin{tikzpicture}
\tikzset{
label/.style={text centered, text=orange,font=\footnotesize,minimum width=1cm} ,
transform/.style={rectangle,rounded corners,draw=black,fill=green!50,text=white,thick, text centered, font=\tiny, minimum width=0.75cm,minimum height=0.5cm},
item/.style={rectangle,draw=black,fill=orange!70,text=white,thick, text centered, font=\tiny, minimum width=0.75cm},
result/.style={rectangle,draw=black,fill=blue!70,text=white,thick, text centered, font=\tiny, minimum width=0.75cm},
arrow/.style={->,thick,draw=black,font=\tiny},
}
\node[transform] (stage1) {};
\node[transform,right=1cm of stage1] (stage2) {};
\node[transform,right=1cm of stage2] (stage3) {};
\node[transform,right=1cm of stage3] (stage4) {};
%
\path[arrow] (stage1) -- (stage2);
\path[arrow] (stage2) -- (stage3);
\path[arrow] (stage3) -- (stage4);
\end{tikzpicture}
\end{center}
\end{frame}
\begin{frame}[t]{Standalone pipeline}
\begin{itemize}
\item A \textmark{standalone} \textgood{pipeline} is a top-level pipeline.
\begin{itemize}
\item Invoking the pipeline translates into its execution.
\end{itemize}
\vfill\pause
\item Given:
\begin{itemize}
\item A \textgood{generator} $g : \varnothing \mapsto T_1 \cup \varnothing$
\item A sequence of \textgood{transformers} $t_i : T_i \mapsto T_{i+1}$
\end{itemize}
\vfill
\item For every \textmark{non-empty} value generated by $g$, it evaluates:
\begin{itemize}
\item $t_n(t_{n-1}(\ldots t_1(g())))$
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}[t,fragile]{Generators}
\vspace{-1em}
\begin{itemize}
\item A generator $g$ is any callable C++ entity that:
\begin{itemize}
\item Takes no argument.
\item Returns a value of type $T$ that may hold (or not) a value.
\item Null value signals end of stream.
\end{itemize}
\vfill\pause
\item The return value must be any type that:
\begin{itemize}
\item Is copy-constructible or move-constructible.
\begin{lstlisting}
T x = g();
\end{lstlisting}
\pause
\item Is contextually convertible to \cppkey{bool}
\begin{lstlisting}
if (x) { /*...*/ }
if (!x) { /*...*/ }
\end{lstlisting}
\pause
\item Can be derreferenced
\begin{lstlisting}
auto val = *x;
\end{lstlisting}
\end{itemize}
\vfill\pause
\item The standard library offers an excellent candidate \cppid{std::optional<T>}.
\end{itemize}
\end{frame}
\begin{frame}[t,fragile]{Simple pipeline: x -> x*x -> 1/x -> print}
\begin{lstlisting}
template <typename Execution>
void run_pipe(const Execution & ex, int n)
{
grppi::pipeline(ex,
[i=0,max=n] () mutable -> optional<int> {
if (i<max) return i++;
else return {};
},
[](int x) -> double { return x*x; },
[](double x) { return 1/x; },
[](double x) { cout << x << "\n"; }
);
}
\end{lstlisting}
\end{frame}
\begin{frame}[t,fragile]{Nested pipelines}
\begin{itemize}
\item \textgood{Pipelines} may be \textmark{nested}.
\vfill
\item An \textenum{inner pipeline}:
\begin{itemize}
\item Does not take an execution policy.
\item All stages are transformers (no generator).
\item The last stage must also produce values.
\end{itemize}
\vfill
\item The \textgood{inner pipeline} uses the same execution policy than the outer
pipeline.
\end{itemize}
\end{frame}
\begin{frame}[t,fragile]{Nested pipelines: Image processing}
\begin{lstlisting}[escapechar=@]
void process(std::istream & in_file, std::ostream & out_file) {
grppi:parallel_execution_native ex;@\pause@
grppi::pipeline(ex,@\pause@
[&in_file]() -> optional<frame> {
frame f = read_frame(file);
if (!file) return {};
return f;
},@\pause@
pipeline(
[](const frame & f) { return filter(f); },
[](const frame & f) { return gray_scale(f); },
},@\pause@
[&out_file](const frame & f) { write_frame(out_file, f); }
);
}
\end{lstlisting}
\end{frame}
\begin{frame}[t,fragile]{Piecewise pipelines: Image processing}
\vspace{-.5em}
\begin{lstlisting}[escapechar=@]
void process(std::istream & in_file, std::ostream & out_file) {@\pause@
auto reader = [&in_file]() -> optional<frame> {
frame f = read_frame(file);
if (!file) return {};
return f;
};@\pause@
auto transformer = pipeline(
[](const frame & f) { return filter(f); },
[](const frame & f) { return gray_scale(f); },
};@\pause@
auto writer = [&out_file](const frame & f) { write_frame(out_file, f); }@\pause@
grppi:parallel_execution_native ex;
grppi::pipeline(ex, reader, transformer, writer);
}
\end{lstlisting}
\end{frame}