The second edition of An Introduction to Parallel Programming is an elementary introduction to programming parallel systems with MPI, Pthreads, and OpenMP. However, this edition also includes an introduction to programming GPUs using CUDA. The book should be used by students and professionals with some knowledge of programming conventional, single-processor systems, but who have little or no experience programming multiprocessor systems.
Here's an archive of the source code that's discussed in the book.
Lecture notes, and other companion materials are in preparation. They will be posted as soon as they become available. In the meantime, the materials for the first edition may be helpful. Links are available here.
Please see errata here.