Programming Lab #1 (CSE 160, Fall 2013)
Parallel Merge Sort
Due Monday 10/14/13 at 6PM


Changelog

Date Description
02-Oct-13 Original posting
07-Oct-13 Clarification about function signatures
08-Oct-13 Corrected path name for assigning $PUB on Bang
11-Oct-13 Clarification about # threads being a power of two
11-Oct-13 Constraint on -g parameter to avoid some corner cases
12-Oct-13 Documentation for -w and -r options


The Assignment

Your assignment is to implement the merge sort algorithm, discussed in class, to run on multiple cores with multithreading. You'll use C++11 threads to parallelize the code. You've been provided with serial code, written in C++, and an executable reference implementation to assess performance goals. (There are two, one for each course platform. Code compiled on Bang won't run on Ieng6, and vice verse).

Using your implementation, you'll conduct experiments, on the Bang cluster, to assess scalability and load balancing tradeoffs. Do your development on Ieng6 if Bang becomes too heavily loaded. In the spirit of friendly competition, post your performance results to the A1 Moodle forum.

The assignment includes a brief report, and the requirements for your report are described at the end of this writeup.

Instructions for setting up your environment on Bang and for submitting jobs are described HERE.

The provided starter code and accessing the code repository

We've provided you with starter code that implements the serial algorithm. We've also provided a reference binary that supports multithreading so you can assess performance. This code has been installed in an SVN repository that resides on Bang.

To use the svn repository, take the following 3 steps.

  1. Check out the provided code from within your home directory on Ieng6. You'll need a password, which will be sent to you after you've filled out the request Google form provided on Moodle. your_AD is your active directory password.
    svn co --username your_AD svn://ccom-bang-login.ucsd.edu/SVN/A1/Provided
    

    When working on Bang, you'll check out the code differently:
    svn co --username your_AD svn://localhost/SVN/A1/Provided
    
  2. Next, check out your development repository directory (Your group ID will also be mailed to you after you have completed the Google form):
    svn co svn://ccom-bang-login.ucsd.edu/SVN/A1/Turnin/YOUR_GROUP_ID Turnin
    
  3. Add the provided code to your development repository. This task will be performed only once and can be done by one team member.
    cp Provided/* Turnin
    cd ./Turnin
    svn add *
    svn commit -m "import the provided code"
    

So you don't have inconsistent copies different machines, make sure that you keep your repository up to date before you log out or interrupt a login session. You can check on the status of your files with the svn status command. Commit any file with the 'M' tag (modified but not committed).

Familiarize yourself with the various modules. For example, the command line parser in cmdLine.cpp explains the options needed to run the code. You will be making changes to use one file: MergeSort.cpp. To ensure that your program is correctly graded, do not rely on any changes you have made to any other provided source code files; we will substitute fresh copies when we grade your assignment. Also, don't change the signature of the function DC_MergeSort() to any of the functions defined in MergeSort.cpp as our tester code is designed to use the signature in the provided code.

To build your code, use the provided Makefile, which sets up the appropriate flags for the compiler via an included "arch" file located in $(PUB)/Arch/arch.gnu-4.7_c++11. PUB is should be defined in ~/.bash_profile on ieng6 as


export PUB= /home/linux/ieng6/cs160f/public

and on Bang as

export PUB=/share/class/public/cse160-fa13

The Makefile produces a target called msort.

Important: Do not change the name of this target. You may add additional source files if you wish, but don't change the names of the any of the provided files.

You may override certain settings, such as compiler optimization, by redefining macros in your Makefile. Within the Makefile, we have provided a commented out line that, if uncommented, will redefine the optimization level. This may come in handy if you want to debug your code using gdb. But don't forget to comment this line out when collecting your timings our your code will run more slowly with optimization turned off.

To assist you in your code development, we've set up the Makefile to enable you to build the code in various ways. For example, if you want to compile for the gdb debugger, specify "gdb=1" on the make command line, e.g.

make gdb=1

The other options are self-explanatory. Don't forget to do a make clean before rebuilding the code. Otherwise, you may get anomalous behavior.


Command line options

The code has various capabilities, which are controlled via command line flags explained in cmdLine.cpp. For example the following invocation

./msort -n 67108864 -s 1380501542 -g 262144 -s 1380501542

will run a problem of size 67108864 (64 Meg) keys on 2 threads. It will terminate the recursion when the input size drops below 262144 keys (256K). Lastly, a random number seed is specified via the -s flag. See below in the discussion of Testing your code.

The inputs provided with randomly distributed inputs (the default) are large numbers, and can be hard to distinguish from one another when debugging. To this end, there are two options, -r and -w to specify best case and worst case inputs, respectively. These options play no role in how we grade your assignment and are intended to help you with testing, as the keys start from 0 and are generally much smaller than the keys specified with random distribution (the default).


Assignment Checklist

  1. Write code in MergeSort.cpp to implement the multithreaded version of the Merge Sort algorithm. You should first parallelize the recursive calls to merge. Once you have that working, then implement the parallel merge algorithm discussed in class. Take care when passing reference arguments to the thread function, since you'll need to use the ref() specifier to pass the arguments correctly.
    1. Programming.
      1. Add code to spawn and join the threads.
      2. Implement a callback thread function that will be called when you spawn threads. Be sure that you spawn no more than the number of threads (NT) specified on the command line via the -t option.
      3. thread::join() will be sufficient to handle synchronization, and no other form of synchronization is required.
    2. Conduct a strong scaling study, using the default parameters defined in the provided code. Vary the number of threads from 1 to 8, in powers of two. Be sure to use the same random seed on all your timing runs using the -s option (explained below). If you have time, let the program pick the random seed for each run and report, for each value of the number of threads (NT), the average timer over ten runs.
    3. You’ll note that performance may be only slightly sensitive to the -g value. However, when g=n on more than 1 thread, the code suddenly slows down. Why is this the case? Try to pick a -g value that minimizes the running time; you may need a different value of -g for each value of the number of threads -t. Behavior may or may not change with parallel merging turned on.
    4. Report and comment on performance. This requirement is described below under Document your work in a well-written report.

Taking timings

Use the batch queues on Bang to collect timings. This is explained in the document Getting Started with Bang, which references the document Running jobs on the Bang Cluster.

Do NOT run interactively on Bang's front end as a class of over 100 students will overload the machine (see instructions provided in the Bang document). But you may find it more convenient to collect your measurements by running non-interactively.

We've provided you with a batch script that provides the appropriate commands for running batch jobs. You need only change the commands you wish to run, and also add your email address if you want to be notified when your job completes. Take timings with the provided timer code (it uses gettimeofday()). Take at least 3 timings for each combination of parameters, and report the minimum timing. Shut off any debugging output when you collect timings results. as doing so could affect your observations.

Testing your code

The code will verify that the list has been sorted. Make sure that the code runs correctly for all timing tests you perform. Since the input keys are distributed randomly, each run will use a different input, which can invalidate performance comparisons on different numbers of processors, unless we have a way of generating the same random number sequence when required will. The provided code enables you to can meet this requirement using the -s flag. This flag starts the random number sequence from a known place so that you can reproduce the input from run to run. The code always outputs the random seed, so the first time you run, note the seed so that you can then specify it in subsequent runs when needed.

We will grade your assignment on bang. Be sure to do your final testing on that machine, to avoid any surprises at turnin time.

We will test your code's correctness and performance. Note that, in the interest of avoiding some messy corner cases for uninteresting values of the -g parameter, we won’t for values of the -g parameter that are smaller than 4. We will test against the public input described here, plus other inputs that will not be made public. Be sure to test against various combinations of the -n, -t, and -g parameters. However, use care in choosing these parameters so that no runs lasts for more than 10 or 20 seconds. To save time, we suggest that you start with the default values for the -n and -g command line parameters and vary by a factor of four--up and down. Your code need only handle the case where the -n and -t parameters are integer powers of two.

Running on a compute node

Request an interactive compute node via the qlogin command. Once you've been granted your node, you'll see the following output, though your job number and assigned node number will differ:

Your job 239 ("QLOGIN") has been submitted
waiting for interactive job to be scheduled ...
Your interactive job 239 has been successfully scheduled.
Establishing builtin session to host compute-0-26.local ...

You are now running in a shell and have exclusive access, for 30 minutes, to a compute node with 8 cores. Since Bang has 32 nodes, at most 32 users can be accommodated. If there are no more available nodes, move to ieng6.

Wait until you receive a command prompt. You will now be running in a new shell, within your $HOME directory. You may run commands on the compute node, edit and compile code, but you won't be able to submit non-interactive jobs. Since SVN won't work on the compute nodes, when tuning the performance of your code, it will be convenient if you have 2 windows: one on the front end for editing and compiling, the other for running the code.

As a courtesy to other users, exit the interactive session when no longer needed.


Things you should turn in

  1. Document your work in a well-written, one to two page report, including plots, which presents your results, analyzes them, and offers insight. Your report should briefly discuss any performance bottlenecks of the implementation. If you improved performance of your code in a sequence of steps, be sure to document this in your svn log, which we'll consider an Appendix to your report. We will be looking at the log, and will deduct points if we can't see your thought processes. If you like, summarize the information in a list or a table in your report. If necessary, provide pseudo code to illustrate the concepts Do not include full code listings in your writeup as these will be in your turnin.

    Negative results are also valid and especially valued if you can document them, with the underlying causes, or best guesses if the causes are not clear.

    Take care in how you plot your data, only plotting what's necessary to get your points across, and choosing log and linear plots carefully. You must also include any plotted data in tabular form. Tabular data may be included electronically (in your turnin) as a spreadsheet or other document called, e.g. Data.xlsx, Data.txt.

    Cite any written works or software as appropriate in the text of the report. Citations should include any software you used that was written by someone else, or that was written by you for purposes other than this class.

  2. Turnin. Your turnin will consist of two parts.

    1. Hard copy of your report. Hand in a hard copy by the deadline, placing it in Jing or Yashodhan's 's student mailbox on the 2nd floor of EBU3B. The paper and electronic versions of the report should be identical. When there are any questions about turnin time, the latest timestamp of all files in your turnin establishes the turnin time. We won't collect files included in your repository after the deadline.

    2. Electronic turnin. Our tester will check out your code from your private Turnin repository, but any files that it checks out won't have a timestamp that is later than the deadline. Be sure that your svn repository is up to date. If you get stuck at the end, we can always roll back your code when grading it, though this may delay the grading of your assignment and result in a small 5% penalty.

      In addition to source code files, your electronic turnin must include a Makefile so that we can build and test your code.

      Your turnin must also include the following important documents. These documents are required as the grading process which not complete without them. Empty forms, or forms not properly filled out, will result in a 10% penalty being assessed, in addition to holding up the grading process.

      1. A completed team self-evaluation called teameval.txt, that discusses the division of labor and other aspects of how you worked together as a team. A copy of the form is included in the provided code.
      2. A file named DECLARATION, that you sign electronically, stating that the work was your own, and that you did not violate the Academic Integrity policies in effect for the course. The DECLARATION file is also included with the provided code. Make changes to your login ID(s) and the date only. Don't change anything else.


Don't wait until the last minute to complete the assignment. The batch queue can become full, the machine unresponsive, so be sure to get results early on. Be sure you are familiar with svn, and commit code frequently.


Grading

We will use a script to measure your code's performance and test for correctness. We will also look at code since some correctness errors cannot be tested automatically. Except for MergeSort.cpp, our tester will use fresh copies of all code files, so only changes to the MergeSort file will affect your grade. Any changes you have made to other files will not affect your grade.

Your grade will based on results obtained from your code, and documentation. Documentation includes the report, comments in the code, and svn log entries. The grade for the code will depend on two factors: performance and correctness. The grade for your documentation will be based on clear explanations, and in the case of the report, insight into the results and presentation of experimental data. Remember: the report is brief so you need not go into long explanations. Focus on what's important. When you commit files with svn, be sure to add brief, but descriptive comments, suitable for understanding your development process. If you aren't sure, be sure to ask us.

To get full credit on the programming portion of the assignment, your code must

  1. Be correct.
  2. Run not less than 10% slower than the provided reference, for each combination of input size and number of threads.
  3. Employ parallelism in the Merge phase (there is a -p command line mode to specify parallel merge).


References to C++11 and to C++11 threading


Copyright © 2013 Scott B. Baden   [Wed Oct 2 10:43:03 PDT 2013]