6

I am trying to create a custom algorithm environment for CUDA kernel code that runs on the GPU, but have little experience with custom LaTeX. It should have a separate counter, be referenced as Kernel X by the cleveref package, and possibly show up in the list of algorithms as a kernel somehow to distinguish it from regular algorithms.

The following is my M(-kinda-)WE. It gets counters working, but not references. Also I am unable to properly include the placement specifiers in the kernel environment.

\documentclass[11pt]{article}
\usepackage{algorithm}
\usepackage{algorithmicx}
\usepackage{hyperref}
\usepackage[nameinlink, noabbrev]{cleveref}
\usepackage{float}

% Custom reference command
\newcommand{\sref}[1]{\textbf{\cref{#1}}}
\newcommand{\Sref}[1]{\textbf{\Cref{#1}}}

\newcounter{kernel}
\newcounter{temp}

\newenvironment{kernel}[1][ps]{%
    \setcounter{temp}{\value{algorithm}}%
    \setcounter{algorithm}{\value{kernel}}%
    \refstepcounter{kernel}%
    \begin{algorithm}[#1]%
    \floatname{algorithm}{Kernel}%
} {\end{algorithm}\setcounter{algorithm}{\value{temp}}}

\floatname{kernel}{Kernel}
\crefname{kernel}{kernel}{kernels}
\Crefname{kernel}{Kernel}{Kernels}

\begin{document}
\begin{algorithm}[htb!]
    \caption{Some really cool algorithm}
    \label{alg:algorithm1}

    \begin{algorithmic}
        \State $x \gets 1$
    \end{algorithmic}
\end{algorithm}

\begin{kernel}[htb!]
    \caption{Some other really cool algorithm}
    \label{alg:algorithm2}

    \begin{algorithmic}
        \State $y \gets 2$
    \end{algorithmic}
\end{kernel}

\begin{algorithm}[htb!]
    \caption{Another one...}
    \label{alg:algorithm3}

    \begin{algorithmic}
        \State $w \gets 3$
    \end{algorithmic}
\end{algorithm}

\begin{kernel}[htb!]
    \caption{The last one, I promise}
    \label{alg:algorithm4}

    \begin{algorithmic}
        \State $w \gets 4$
    \end{algorithmic}
\end{kernel}

As implied in~\ref{alg:algorithm1} aka~\autoref{alg:algorithm1} aka~\nameref{alg:algorithm1} aka~\cref{alg:algorithm1} aka~\sref{alg:algorithm1} it is really cool. The same goes for
~\ref{alg:algorithm2} aka~\autoref{alg:algorithm2} aka~\nameref{alg:algorithm2} aka~\cref{alg:algorithm2} aka~\sref{alg:algorithm2}.

\end{document}

Most of the examples I found here where either concerned with the algorithm2e package or didn't do quite what I wanted.

EDIT: I succeeded in passing the placement specifiers to the algorithm environment, but they seem to be ignored, so I am probably still doing something wrong.

1 Answer 1

4

The \label command saves the index of counter that was last used in the \refstepcounter command. As the \caption command always calls \refstepcounter{algorithm}, the \label is always associated with the algorithm counter and hence cleveref prints Algorithm instead of Kernel.

The easiest solution I can think of is just calling \label before calling \caption.

However this does not give you two separate lists of the captions. So its actually much easier to define a new floating environment to hold the algorithm.

\documentclass[11pt]{article}
\usepackage{algorithm}
\usepackage{algorithmicx}
\usepackage{hyperref}
\usepackage[nameinlink, noabbrev]{cleveref}
\usepackage{float}

% Custom reference command
\newcommand{\sref}[1]{\textbf{\cref{#1}}}
\newcommand{\Sref}[1]{\textbf{\Cref{#1}}}

% define a new float, with style `ruled`
\floatstyle{ruled}
\newfloat{kernel}{htbp}{lok}
\floatname{kernel}{Kernel}

\crefname{kernel}{kernel}{kernels}
\Crefname{kernel}{Kernel}{Kernels}

\begin{document}

\begin{algorithm}[htb!]
    \caption{Some really cool algorithm}
    \label{alg:algorithm1}

    \begin{algorithmic}
        \State $x \gets 1$
    \end{algorithmic}
\end{algorithm}

\begin{kernel}[htb!]
    \caption{Some other really cool algorithm}
    \label{alg:algorithm2}

    \begin{algorithmic}
        \State $y \gets 2$
    \end{algorithmic}
\end{kernel}

\begin{algorithm}[htb!]
    \caption{Another one...}
    \label{alg:algorithm3}

    \begin{algorithmic}
        \State $w \gets 3$
    \end{algorithmic}
\end{algorithm}

\begin{kernel}[htb!]
    \caption{The last one, I promise}
    \label{alg:algorithm4}

    \begin{algorithmic}
        \State $w \gets 4$
    \end{algorithmic}
\end{kernel}

As implied in~\ref{alg:algorithm1} aka~\autoref{alg:algorithm1}
aka~\nameref{alg:algorithm1} aka~\cref{alg:algorithm1} aka~\sref{alg:algorithm1}
it is really cool. The same goes for
~\ref{alg:algorithm2} aka~\autoref{alg:algorithm2}
aka~\nameref{alg:algorithm2} aka~\cref{alg:algorithm2} aka~\sref{alg:algorithm2}.

\listof{kernel}{List Of Kernels}

\listof{algorithm}{List Of Algorithms}

\end{document}

Output

1
  • 1
    Thanks, that's a great solution! I think my lack of knowledge about the inner workings of \label had me stumped here.
    – NordCoder
    Commented Apr 20, 2015 at 12:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .