uwhpsc-2016 / homework2_solution

Solution to Homework #2
0 stars 2 forks source link

Homework #2 - Solution

Homework #2 will test you on writing C code. In this assignment we will write several basic linear algebra routines as well as some basic linear system solvers. We will use these solvers in future assignments. This is the first assignment which will test your code for performance. This document is long but please read carefully as it explains very thoroughly what to do and how to do it.

Repository layout:

Compiling and Testing

The makefile for this homework assignment has been provided for you. It will compile the source code located in src/ and create a shared object library in the directory lib named libhomework2.so.

Run,

$ make lib

to create lib/libhomework2.so. This library must exist in order for the Python wrappers to work. As a shortcut, running

$ make test

will perform

$ make lib
$ python test_homework2.py

Assignment

Provide the definitions for the following functions. The functions that return by reference do so with a variable (in all cases, an array) named out. All vectors are represented by arrays and all matrices are represented by long arrays. That is, an M-by-N matirx A is represented by an array of length MN.

In include/linalg.h and src/linalg.c:

In include/solvers.h and src/solvers.c:

1) Tests - 60%

Your implementations will be run through the following test suite:

For the following tests, let A be an n-by-n 5-diagonal matrix consisting of "5" along the main diagonal and "-1" on the (-2),(-1),(+1), and (+2) off-diagonals and the vector b be the vector [0, 1, 2, ..., n-1]. Additionally, use an initial guess (x0, in the previous hw) of all zeros.

2) Report - 20%

Produce a PDF document named report.pdf in the directory report of the repository. Please write your name and UW NetID (e.g. "cswiercz", not your student ID number) at the top of the document. The report should contain responses to the following questions:

  1. What is the computational complexity of solve_lower_triangular and solve_upper_triangular as a function of the matrix size n? That is, using big-oh notation list how much time / how many operations it takes to solve a triangular system if the input matrix L or U is N-by-N. Please read this article on time complexity if you need a refresher on the topic. Your response should contain an argument for your result! Listing the complexity without any description will result in zero points.

  2. Copy the code you wrote for solve_upper_triangular and paste it into a markdown cell. You can format the cell to display code nicely using like so:

    
    # The contents of In [1] formatted as "Markdown":
    
    The code I used for `solve_upper_triangular` is:
    
    ```c
    int gauss_seidel(double* out, ...)
    {
     // my code
    }
    ```
    
    (Explanation of my code.)
    
    

    See the example notebook Scratch.nb for a demonstrations. Answer the following questions about your implementation:

    • Does this function have a contiguous memory access pattern?
    • Assuming the cache create a copy of memory at and after a requested / particular location do you think solve_upper_triangular has any inefficiencies? Why or why not?
  3. Just as in 2. above, copy the code you wrote for gauss_seidel and paste it into a markdown cell with nice code formatting. Answer the following questions about your implemenation:

    • What are the memory requirements as a function of n, the system size? You do not need to calculate the number of bytes but at least give a description like "n-squared doubles for storing the matrix, n doubles for storing the right-hand side, etc."
    • What parts of your code have contiguous access patterns?
    • What parts do not have contiguous access patterns? Any thoughts on how to improve this, if possible?

3) Documentation - 10%

Provide documentation for the function prototypes listed in include/linalg.h and include/solvers.h following the formatting described in the Grading document. The format must match the following layout,


  /*
      my_function

      (description of function)

      Parameters
      ----------
      arg1 : parameter type
          (Description of parameter)
      arg2 : parameter type,
          (Description of parameter)

      Returns
      -------
      argument or variable_name : output type
          (Description of output)
      arg2 : type, return by reference
          (Description of output)
  */
  double my_function(int arg1, double* arg2);

Write this documentation above the function prototype defined in the header files, not in the source files. Example documentation for vec_add has already been provided to you.

4) Performance - 10%

Your implementation of gauss_seidel will be tested for performance. Failure to produce a working implementation of gauss_seidel will result in a zero on the performance evaluation. See the Grading document for more information on how the performance grading is done.