Commits (2)
include share/make/share.mk
include share/make/tex.mk
TEXI2PDFFLAGS += --shell-escape
all: slides.pdf
${RM} slides.pdf* tmp*
title = {An Image Processing Library in Modern {C++}: Getting
Simplicity and Efficiency with Generic Programming},
author = {Micha\"el Roynard and Edwin Carlinet and Thierry G\'eraud},
booktitle = {Proceedings of the 2nd Workshop on Reproducible Research
in Pattern Recognition (RRPR)},
year = {2018},
abstract = {As there are as many clients as many usages of an Image
Processing library, each one may expect different services
from it. Some clients may look for efficient and
production-quality algorithms, some may look for a large
tool set, while others may look for extensibility and
genericity to inter-operate with their own code base... but
in most cases, they want a simple-to-use and stable
product. For a C++ Image Processing library designer, it is
difficult to conciliate genericity, efficiency and
simplicity at the same time. Modern C++ (post 2011) brings
new features for library developers that will help
designing a software solution combining those three points.
In this paper, we develop a method using these facilities
to abstract the library components and augment the
genericity of the algorithms. Furthermore, this method is
not specific to image processing; it can be applied to any
C++ scientific library.}
author = {Wenzel Jakob and Jason Rhinelander and Dean Moldovan},
year = {2017},
note = {https://github.com/pybind/pybind11},
title = {pybind11 -- Seamless operability between C++11 and Python}
author={Niebler, Eric},
title={Boost, a modern C++ library},
author={Niebler, Eric},
author = {Travis Oliphant},
title = {{NumPy}: A guide to {NumPy}},
year = {2006--},
howpublished = {USA: Trelgol Publishing},
url = "http://www.numpy.org/",
@InProceedings{ levillain.14.ciarp,
author = {Roland Levillain and Thierry G\'eraud and Laurent Najman
and Edwin Carlinet},
title = {Practical Genericity: Writing Image Processing Algorithms
Both Reusable and Efficient},
booktitle = {Progress in Pattern Recognition, Image Analysis, Computer
Vision, and Applications -- Proceedings of the 19th
Iberoamerican Congress on Pattern Recognition (CIARP)},
address = {Puerto Vallarta, Mexico},
month = nov,
year = {2014},
pages = {70--79},
editor = {Eduardo Bayro and Edwin Hancock},
publisher = {Springer-Verlag},
series = {Lecture Notes in Computer Science},
volume = {8827},
lrdeprojects = {Olena},
abstract = {An important topic for the image processing and pattern
recognition community is the construction of open source
and efficient libraries. An increasing number of software
frameworks are said to be generic: they allow users to
write reusable algorithms compatible with many input image
types. However, this design choice is often made at the
expense of performance. We present an approach to preserve
efficiency in a generic image processing framework, by
leveraging data types features. Variants of generic
algorithms taking advantage of image types properties can
be defined, offering an adjustable trade-off between
genericity and efficiency. Our experiments show that these
generic optimizations can match dedicated code in terms of
execution times, and even sometimes perform better than
routines optimized by hand. Digital Topology software
should reflect the generality of the underlying
mathematics: mapping the latter to the former requires
genericity. By designing generic solutions, one can
effectively reuse digital topology data structures and
algorithms. We propose an image processing framework
focused on the Generic Programming paradigm in which an
algorithm on the paper can be turned into a single code,
written once and usable with various input types. This
approach enables users to design and implement new methods
at a lower cost, try cross-domain experiments and help
generalize results.},
keywords = {Generic Programming, Image Processing, Performance,
lrdepaper = {http://www.lrde.epita.fr/dload/papers/levillain.14.ciarp.pdf},
lrdeslides = {http://www.lrde.epita.fr/dload/papers/levillain.14.ciarp.slides.pdf},
lrdenewsdate = {2014-09-10}
This source diff could not be displayed because it is too large. You can view the blob instead.
\date[02-07-2019]{General Presentation}
\author{Célian \textsc{Gossec}}
\title[The static-dynamic bridge]{Binding a high-performance C++ image processing library to Python}
\institute[LRDE]{LRDE\\Laboratoire de Recherche et Développement de l'EPITA}
\begin{frame} % Situation 1
\frametitle{The situation}
\structure{Our starting point.} Milena, an image processing library built around
\emph{genericity and performances} written in C++
\footnote{\tiny Practical Genericity : Writing Image Processing Algorithms Both Reusable and Efficient.
R. Levillain et al., \textit{ICPR'14}.}
\footnote{\tiny An Image Processing Library in Modern C++: Getting Simplicity and Efficiency with Generic Programming.
M. Roynard, E. Carlinet, T. Géraud, \textit{RRPR'18}.}
& \tiny image 2D & \tiny graph & \tiny mesh \\
\tiny in: & \fbox{\includegraphics[width=.15\linewidth]{figs/geninput-000b}} &
\fbox{\includegraphics[width=.15\linewidth]{figs/geninput-001b}} &
\fbox{\includegraphics[width=.15\linewidth]{figs/geninput-002b}} \\
\tiny out: & \fbox{\includegraphics[width=.15\linewidth]{figs/genoutput-000}} &
\fbox{\includegraphics[width=.15\linewidth]{figs/genoutput-001b}} &
\fbox{\includegraphics[width=.15\linewidth]{figs/genoutput-002b}} \\
\structure{Our objective.} Make the library easier to use.\\[2pt]
\begin{frame} % Situation 2
\structure{The means.} Bind Olena to Python.
\structure{The problems we face.}
\item Calling \textit{static} code (C++ templates) from a \textit{dynamic}
environment (Python) \\
\item Getting a compatibility with Numpy
\footnote{\tiny Numpy: a guide to Numpy. Oliphant, T. (2006)}
\begin{frame} % Possibilities
\frametitle{The different possibilites.}
\item Just-in-time compiling
\item Type generalization
\item Type erasure
\item Dynamic dispatching
\begin{tabular}{llll} & Speed & Genericity & Portability \\
JIT & \includegraphics[width=1.1cm]{figs/checkmark.png} & \includegraphics[width=1.1cm]{figs/checkmark.png} & \includegraphics[width=1.1cm]{figs/crossmark.png} \\
Type erasure & \includegraphics[width=1.1cm]{figs/crossmark.png} & \includegraphics[width=1.1cm]{figs/checkmark.png} & \includegraphics[width=1.1cm]{figs/checkmark.png} \\
Type generalization & \includegraphics[width=1.1cm]{figs/checkmark.png} & \includegraphics[width=1.1cm]{figs/crossmark.png} & \includegraphics[width=1.1cm]{figs/checkmark.png} \\
Dynamic dispatch & \includegraphics[width=1.1cm]{figs/crossmark.png} & \includegraphics[width=1.1cm]{figs/checkmark.png} & \includegraphics[width=1.1cm]{figs/checkmark.png}
\begin{frame} % Objective: hybrid approach
\frametitle{Our objective: using a hybrid approach.}
Providing a type erased interface that can be used with Pybind
\footnote{\tiny pybind11 -- Seamless operability between C++11 and Python}
but also \ldots \\
that can be converted back to a specific type to use predetermined, concrete type
\tikzset{land/.style={draw}, obj/.style={draw,fill=red!20}};
\node[obj] [] (imvoid) {\tiny image2d<>};
\node[obj] [below = 0.5cm of imvoid] (imT) {\tiny image2d<T>};
\node[obj] [right = 5.5cm of imT] (stretch) {\tiny stretch(image2d<T>)};
\node[obj] [above = .5cm of stretch] (stretchv) {\tiny stretch(image2d<>)};
\draw[->,thick] (stretchv) -- (stretch) node[midway,right] {\tiny dyn.
\draw[->,thick] (imT) -- (imvoid) node[midway,above] {};
\draw[->,thick] (imvoid) -- (stretchv) node[midway, above] {\tiny Type erased
images call stretch<>};
\draw[->,thick] (imT) -- (stretch) node[midway, above] {\tiny Concrete type
images can call the faster stretch<T>};
\begin{frame} % The first steps
\frametitle{The first steps taken}
\item Creation of a class to extract type information from templates to
instanciate a type erased interface.
\item Reimplementation of a fragment of the \textit{ndimage} Pylene class:
\item Binding the \textit{image2d} class to Python
\item Usage of the Pybind \textit{buffer\_protocol} to create a numpy-
compatible binding
\begin{frame}[fragile] % Early results
\frametitle{The results at this point}
>>> import milena, numpy as np
>>> arr = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3]],
dtype = 'int8') # Note how we precise the type
>>> img = milena.image2d(arr)
initialized a non-templated image
>>> res = milena.stretch(img)
initialized a templated img
>>> print(np.array(res))
[[0.00787402 0.00787402 0.00787402]
[0.01574803 0.01574803 0.01574803]
[0.02362205 0.02362205 0.02362205]]
\small{N.B: At this point, \textit{image2d<T>} has been type erased and
\textit{image2d<void>} exists, but our only way to call stretch is to use dynamic
dispatching on the type erased image so we can call stretch on a 'concrete' image. \\
The stretch function could not work with type erased images, having the following
\begin{minted}[fontsize=\tiny, escapeinside=||]{c++}
image2d<float> stretch(const image2d<T>& src)
auto res = image2d<float>(src.width(),
|\colorbox{yellow}{auto}| span = src|\colorbox{yellow}{.values();}|
std::transform(span.begin(), span.end(),
[](T val) -> float
return static_cast<float>(val)
/ |\colorbox{yellow}{std::numeric\_limits<T>::max();}|
return res;
\begin{frame} % The next steps
\frametitle{The next steps}
Making the \textit{stretch} algorithm compatible with the \textit{image2d<>} type.
\item Implementing a \textit{value\_set} class, to hold numeric related functions
\item Implementing an \textit{any\_span} class: a type erased container to use
.values() on the \textit{image2d<>} class that would work like the range-v3
\footnote{\tiny Range-v3. Niebler, E. (2014)} library.
\item Working on type safety through
\begin{frame} %Biblio
\nocite{levillain.14.ciarp, roynard.18.rrpr, pybind11, niebler1999boost,
niebler1999boost, numpy}
\begin{frame} %Questions