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. Commented Apr 20, 2015 at 12:52

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.