Cardiac Electrophysiology Simulation
with SSE Vector Intrinsics
| Date | Description |
| 25-Feb-16 | Original posting |
| 25-Feb-16 | Clarification about batch script |
| 27-Feb-16 | Fixed typo; failure should be with odd numbers not even. |
In this assignment you'll re-implement the heart electrophysiology simulator from Assignment #3 using SSE intrinsics, and conduct experiments on Bang to assess performance. The assignment includes a brief report, and the requirements for your report are described at the end of this writeup.
Your grade will based on 4 factors: performance attained by your implementation; correctness; well-displayed results; descriptive comments in the code and in your repository.
In the spirit of friendly competition, post your performance results to the HW4 Piazza folder.
☞ Due Friday3/4/16 @ 9PM
‣ ‣ ‣ Required solution files: solve.cpp helper.cpp
This means that these files, containing your solution to the assignment, must be turned in by the deadline.
You may develop your code anywhere, but you must ensure that it compiles and runs correctly on Bang because that’s where we’ll be testing it.
The background for the cardiac simulator is the same as for Assignment #3
In doing this assignment, it's your responsibility to understand the course rules for integrity of scholarship.
All assignments will be turned in using UCSD's GitLab. The turnin procedure is described below in the section "Turning in your assignment". You must follow these steps to get the starter code and to get set up to do assignment 4.
Refer to the link below for instructions on how to obtain the starter code to get started on your assignment
A4 Git Instructions
We've provided you with starter code that implements the Aliev-Panfilov solver as well as an executable so that you may assess performance with a known reference. The provided starter source code is virtually identical to that of the previous assignment, but there are some new instructions, so be sure to look them over. The binary reference is new, since it has been vectorized with SSE intrinsics. You can find this reference in $PUB/HW/A4/apf-sse-ref on Bang. It may be possible to improve on the performance of the reference, since it doesn't include any significant optimizations to conserve memory locality.
All of your changes will made to just two files:
solve.cpp helper.cpp
Solve.cpp contains the solver, helper.cpp provides various helper functions such as storage allocation. (You may therefore change the storage allocation scheme if you wish.) The solver is computationally intensive, and so the focus of vectorization and performance programming effort will be on this routine.
The code and Makefile have been set up to enable you to compile with or without the flags needed to support SSE vector intrinsics. The default is to compile without the intrinsics. To compile with intrinsics, specify following make command line argument to Make:
vec=1
This setting defines the SSE_VEC macro which you can use to enable selected code to be conditionally compiled. To take advantage of this feature in any code you write, follow the convention used in the provided starter code. (The code also prints out a message tell ling you when you are building code with SSE intrinsics).
As with the previous assignments, build your code using the provided Makefile, which sets the appropriate flags for the compiler via the "arch" file located in $(PUB)/Arch/arch.gnu-c++11.generic. The Makefile produces a target called apf. Do not change the name of this target. While you may modify any files not listed above, remember that we will substitute fresh copies when we grade your assignment, so don't really on any custom changes as they will be lost during the grading process.
We have also provided one batch script, batch_job.sh. This script runs the , and you'll need to modify it to run your multithreaded code.
The simulator has various options, controlled via command line arguments (parsed in in cmdLine.cpp), with default values set in apf.cpp. These are the same as in the previous assignment, however, the -t option is not used.
Use the SSE intrinsics discussed in class to nearly double the speed of your code. Note that, the compiler will attempt to vectorize certain code and will succeed in this endeavor, as the optimization is enabled by -O3. However, the quality of the generated code won't match that obtained via hand vectorization with SSE intrinsics.
Although several loops in solver.cpp are amenable to optimization, you should ignore loops that consume insignificant amounts of the application's running time such as initialization. Focus on the remaining code. Your efforts will be much more rewarding if you focus on the PDE and ODE code. Vectorize these two parts one at a time. We have set up a simple vectorization example to help get you started. The code resides in $PUB/Examples/SSE/Vec. However, in the example code the stencils are one dimensional and there are no alignment issues. In the PDE and ODE loops, you'll have two dimensional stencils and array strides are not integral powers of two in length.
Your code will be tested for correctness and performance against
various combinations of the N and niter.
Note that for this assignment,
N will always be an odd even number; the provided reference will get a Segmentation Fault on even odd numbers. This is due to how vectorization is handled on the Bang's Clovertown processor.
Verify that results are independent of whether or not the code was vectorized, for various (legal) values of N.
While you can catch some obvious errors using the graphical output (as in the previous assignment)
a more precise test is to compare two summary quantities reported by the
simulator: the
L2 norm and the L∞ norm, the maximum value (magnitude) of the excitation variable, which are included in the 1 line of performance output.
These are described in the the
Testing part of the writeup for A3.
We will award 10% extra credit if you can run 15% or more faster than the provided reference binary.
This procedure is the same as the previous assignment and is reproduced here:
Git Lab Submission
A3-report-baden-powell.pdf. This report is worth 20% of your grade.
Provide all data in both tabular and graphical form. Plot your data carefully, plotting only what's necessary to get your points across, and choosing log and linear plots carefully. Be sure to provide a caption for each table or plot that describes the experiment you conducted, e.g. "strong scaling."
We encourage you to report negative results which are also valid especially valued if you can document them, with the underlying causes, or best guesses if the causes are not clear. So if results weren't as you expected, let us know why and we may be able to give you some partial credit. Include this discussion on the PDF containing your results.Don't wait until the last minute to attempt a turnin for the first time. Try out the turnin process early on so you are sure that you you are familiar with the process, and that all the required additional files are present.
You will receive 0 points for this assignment if your code does not compile, including cases of non-compilation due to merge conflicts. If you developed your code on another machine you are responsible for properly testing on Bang, else you may lose significant credit, possibly all 10% depending on the circumstances. As mentioned previously, you must ensure that you resolve all of your merge conflicts and that your code compiles and runs correctly IMMEDIATELY BEFORE you push to GitLab.
For this assignment staff will attempt intervene manually to fix problems. However, the policy for such manual intervention is as follows. Staff will change at most 3 lines of code, or you can send us the 3 changes yourself if asked. If such intervention is required we will assess a 10% penalty. This penalty is not severe and is an incentive to make small changes that fix a minor problem so that you can receive credit for all your hard work! Included in this policy are: coding errors, incorrectly naming your GitLab repository, or misspelling the words FINAL SUBMISSION in the commit message.
The only files you should be pushing to GitLab are text files: source code and ASCII test files. Do not push large binaries such as the executables or media files, as doing so could lead to problems such as losing the ability to push to GitLab. Staff will not intervene under these circumstances and you you may be unable to complete your assignment by the deadline. If you commit binaries, you are doing so at your own risk.
There are 25 possible points on the assignment and your grade will depend on 4 factors: performance attained by your code, correctness, well-displayed results (including an explanation if you have negative results) and comments. You must not only put comments inside your code, but every time you commit to your repository. There should be a steady stream of comments that enable us to retrace your development steps. Your performance score will be based on the ability to scale strongly.
We will grade your code on Bang using our own Makefile with the same compilation flags as in the provided in starter code. To get full credit, design, style and comments (including gitlab commit comments) count.
Wikipedia entries on Vectorization and Streaming SIMD Extensions
Automatic Intra-Register Vectorization for the Intel Architecture, A. Bik et al., Int. J. of Parallel Programming, 30(2):65-98 (2002). DOI (Required a UCSD network login)
Q. How can I use the statistics output (L2 and Linfo) to help me debug my code?
A. Your first step after partitioning the data structures and setting up the initial conditions is to make sure you get the statistics reporting to work, so that you will have diagnostic tests enabling you to compare your code with the provided reference. Having done this, you can test that you've set up the initial conditions correctly, and that your solver runs correctly on the local partitions.Q. How can I get assembler output?.
A. Add asm=1 to the make command line as in
make asm=1 solve.oYou'll get two files. Solve.s will contain the assembler. Solve.cpp.lst will contain the assembler and the source code, with the assembler interleaved among the lines of source. This file is easier to read than the raw assembler output, but having said that, the optimizer makes life "interesting." Try turning the optimizer off to (-O0) the first time you try this out.
[Wed Feb 17 18:50:30 PST 2016]