\documentclass[twocolumn]{article}
% \documentclass{article}

\setlength{\oddsidemargin}{-0.5in}
\setlength{\evensidemargin}{-0.5in}
\setlength{\topmargin}{0.0in}
\setlength{\headheight}{0in}
\setlength{\headsep}{0in}
\setlength{\textwidth}{7.0in}
\setlength{\textheight}{9.5in}
\setlength{\parindent}{0in}
\setlength{\parskip}{0.05in}
\setlength{\columnseprule}{0.3pt}

\setlength\columnsep{25pt}

\usepackage{fancyvrb}
\usepackage{relsize}
\usepackage{hyperref}

\usepackage{listings}
\usepackage{amsmath}

\begin{document}

\lstset{xleftmargin=5mm,framexleftmargin=10mm,basicstyle=\footnotesize}

Name: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_

Directions: MAKE SURE TO COPY YOUR ANSWERS TO A SEPARATE SHEET FOR SENDING
ME AN ELECTRONIC COPY LATER.

{\bf 1.} (60) The code below uses R Snow to implement a bucket sort
similar to the OMP one in Sec.\ 1.4.2.6.  See the comments at the
beginning of the code.  Fill in the blanks.

\begin{lstlisting}
# bucket sort with sampling; sort vector x 
# on cluster cls; data assumed to be fairly
# uniformly distributed between a and b,
# exclusive; return value is sorted x

bsort <- function(cls,x,a,b) {
   ncls <- length(cls)
   intwidth <- (b - a) / ncls
   # ship needed objects to workers
   clusterExport(cls, ________  // blank (a) 
      envir=environment())
   # have all workers set their ID
   clusterApply(cls, 
      ________ )  // blank (b) 
   # have all workers set their intervals
   clusterEvalQ(cls, ________ ) // blank (c) 
   # sort locally at workers
   sortedchunks <- 
      clusterEvalQ(cls, 
         ________ )  // blank (d) 
   # wrap up
   ________  // blank (e)
}

setmyid <- function(i) {
   myid <<-  i
}

setmyinterval <- function() {
   mylow <<- a + (myid-1) * intwidth
   myhigh <<- a + myid * intwidth
}

sortmine <- function() {
   myx <-  ________  // blank (f)
   sort(myx)
}
\end{lstlisting}

{\bf 2.} Fill in the blanks with terms from our course.  

\begin{itemize}

\item [(a)] (10) The term used for a parallel application that presents no
coding challenge, due to being easily parallelizable, it is called
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_.

\item [(b)] (10) When we are worried whether a certain parallel algorithm
will work well on very large hardware (e.g. many cores), we ask whether
it is 
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_.

\item [(c)] (10) Associating each thread with a specific core is
called
\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_. 

\end{itemize}

{\bf 3.} (10) Consider a {\it ring network}.  Here the nodes are arranged
in a circle, with serial links connecting successive nodes.  When a node
receives a packet, it checks whether this node is the intended
destination.  If so, it accepts the packet, but if not, it forwards to
the next node.  Packets can be transmitted simultaneously on the various
links.  Packet motion is one direction, so counterclockwise.
There is a processing delay at each node.  Which is true of the
following when an extra node is added?

\begin{itemize}

\item [(i)] Both latency and bandwidth will increase.

\item [(ii)] Latency will increase but bandwidth will decrease.

\item [(iii)] Latency will decrease but bandwidth will increase.

\item [(iv)] Both latency and bandwidth will decrease.

\end{itemize}

\onecolumn

\newpage

{\bf Solutions:}

{\bf 1.}

\begin{lstlisting}
# bucket sort with sampling; sort vector x 
# on cluster cls; data assumed to be 
# fairly uniformly distributed between 
# a and b, exclusive; return value is sorted x

bsort <- function(cls,x,a,b) {
   ncls <- length(cls)
   intwidth <- (b - a) / ncls
   # ship needed objects to workers
   clusterExport(cls,
      c("x","a","b","intwidth",
      "setmyid","setmyinterval","sortmine"),
      envir=environment())
   # have all workers set their ID
   clusterApply(cls,1:ncls,setmyid)
   # have all workers set their intervals
   clusterEvalQ(cls,setmyinterval())
   # sort locally at workers
   sortedchunks <- clusterEvalQ(cls,sortmine())
   # wrap up
   Reduce(c,sortedchunks)
}

setmyid <- function(i) {
   myid <<-  i
}

setmyinterval <- function() {
   mylow <<- a + (myid-1) * intwidth
   myhigh <<- a + myid * intwidth
}

sortmine <- function() {
   myx <- x[x > mylow & x <= myhigh]
   sort(myx)
}
\end{lstlisting}

{\bf 2a.} embarrassingly parallel

{\bf 2b.} scalable

{\bf 2c.} processor affinity

{\bf 3.} (i)

\end{document}


