Skip to content

Commit

Permalink
Add C exercice.
Browse files Browse the repository at this point in the history
  • Loading branch information
abergeron committed Oct 29, 2014
1 parent c25390e commit 965e444
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 14 deletions.
33 changes: 33 additions & 0 deletions 08_scalmulc/01_scalmulc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from theano import Op, Apply
from theano.tensor import as_tensor_variable

class DoubleC(Op):
__props__ = ()

def make_node(self, x):
x = as_tensor_variable(x)
if x.ndim != 1:
raise TypeError("DoubleC only works on 1D")
return Apply(self, [x], [x.type()])

def c_code(self, node, name, input_names,
output_names, sub):
return """
Py_XDECREF(%(out)s);
%(out)s = (PyArrayObject *)PyArray_NewLikeArray(
%(inp)s, NPY_ANYORDER, NULL, 0);
if (%(out)s == NULL) {
%(fail)s
}
for (npy_intp i = 0; i < PyArray_DIM(%(inp)s, 0); i++) {
*(dtype_%(out)s *)PyArray_GETPTR1(%(out)s, i) =
(*(dtype_%(inp)s *)PyArray_GETPTR1(%(inp)s, i)) * 2;
}
""" % dict(inp=input_names[0], out=output_names[0],
fail=sub["fail"])

def infer_shape(self, node, input_shapes):
return input_shapes

def grad(self, inputs, output_grads):
return [output_grads[0] * 2]
38 changes: 38 additions & 0 deletions 08_scalmulc/01_scalmulc_soln.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from theano import Op, Apply
from theano.tensor import as_tensor_variable

class ScalMulC(Op):
__props__ = ('scal')

def __init__(self, scal):
if not isinstance(scal, int):
raise TypeError('expected an int')
self.scal = scal

def make_node(self, x):
x = as_tensor_variable(x)
if x.ndim != 1:
raise TypeError("ScalMulC only works on 1D")
return Apply(self, [x], [x.type()])

def c_code(self, node, name, input_names,
output_names, sub):
return """
Py_XDECREF(%(out)s);
%(out)s = (PyArrayObject *)PyArray_NewLikeArray(
%(inp)s, NPY_ANYORDER, NULL, 0);
if (%(out)s == NULL) {
%(fail)s
}
for (npy_intp i = 0; i < PyArray_DIM(%(inp)s, 0); i++) {
*(dtype_%(out)s *)PyArray_GETPTR1(%(out)s, i) =
(*(dtype_%(inp)s *)PyArray_GETPTR1(%(inp)s, i)) * %(scal)d;
}
""" % % dict(inp=input_names[0], out=output_names[0],
fail=sub["fail"], scal=self.scal)

def infer_shape(self, node, input_shapes):
return input_shapes

def grad(self, inputs, output_grads):
return [output_grads[0] * self.scal]
25 changes: 11 additions & 14 deletions advanced.tex
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,12 @@ \section{How to Make an Op (Python)}

\begin{frame}{Exercise: ScalMulOp}
\begin{center}
Work though the "06\_scalmulop" directory now.
It is available at \url{https://github.com/abergeron/ccw_tutorial_theano.git}.
Work though the "06\_scalmulop" directory available at \url{https://github.com/abergeron/ccw_tutorial_theano.git}.
\end{center}
\begin{itemize}
\item Take the \code{DoubleOp} code and make it work with an arbitrary scalar
\item There are more than one solution possible, both have advantages and disadvantages
\end{itemize}
\end{frame}

\begin{frame}{\code{infer_shape}}
Expand Down Expand Up @@ -221,7 +224,7 @@ \section{How to Make an Op (Python)}
\end{frame}

\begin{frame}{Exercice: Add Special Methods to ScalMulOp}
Work through the "07\_scalmulgrad" directory
Work through the "07\_scalmulgrad" directory available at \url{https://github.com/abergeron/ccw_tutorial_theano.git}
\begin{itemize}
\item Take the ScalMulOp class you made and add the \code{infer_shape} and \code{grad} methods to it.
\item Don't forget to make tests for your new class to make sure everything works correctly.
Expand Down Expand Up @@ -277,13 +280,6 @@ \section{How to Make an Op (C)}
\lstinputlisting[linerange={1-27}]{doublec.py}
\end{frame}

\begin{frame}{Exercice: DoubleC}
\begin{itemize}
\item Make a new DoubleC op that only accepts vectors as input using the C code above.
\item Copy and modify the tests for DoubleC. Be sure to check for invalid inputs (matrices).
\end{itemize}
\end{frame}

\begin{frame}{COp}
\lstinputlisting{cop.py}
\end{frame}
Expand Down Expand Up @@ -330,11 +326,12 @@ \section{How to Make an Op (C)}
\end{itemize}
\end{frame}

\begin{frame}{Add C Code to ScalMulOp}
\begin{frame}{Exercice: Add C Code to ScalMulOp}
Work through the "08\_scalmulc" directory available at \url{https://github.com/abergeron/ccw_tutorial_theano.git}.
\begin{itemize}
\item Take the ScalMulOp from before and write C code for it using either approach
\item You can base yourself on the C code for DoubleOp
\item Don't forget to test your new implementation
\item Take the ScalMulOp from before and write C code for it using either approach (only accept vectors).
\item You can base yourself on the C code for DoubleOp.
\item Don't forget to test your new implementation! Be sure to check for invalid inputs (matrices).
\end{itemize}
\end{frame}

Expand Down

0 comments on commit 965e444

Please sign in to comment.