Nearly all contemporary high-performance systems rely on heterogeneous computation. As a result, scientific application developers are increasingly pushed to explore heterogeneous programming approaches. In this project, we discuss the long history of heterogeneous computing and analyze the evolution of heterogeneous programming approaches, from distributed systems to grid computing to accelerator-based supercomputers.