Programming Massively Parallel Processors: A Hands-on Approach