Clay Breshears

Dr. Dobb's Bloggers

Life and Death in the Game of Life with MPI

August 14, 2013

In this post, I will finish up my description of how to compute each generation of cells on the grid.

For this article, I will finish up my description of how to compute each generation of cells on the grid. I'm using the row-major division of the grid into subgrids that are assigned to a separate process. Each process knows its own rank number and the rank numbers of the (up to) two neighboring subgrids.

When dealing with domain decomposition solutions within a distributed-memory arena, the subgrids are usually padded with a number of ghost cells along rows and columns where needed. This allows the local computation to hold the corresponding cells from another process and compute with them as if they are part of the local subgrid. This overlap of grid cells has the caveat of needing to communicate any changes to those ghost cells to the process that is actually in charge of the original grid locations.

In my list-based version of Game of Life, I don't need border cells around the Map grid since there is no need to figure out how many live cells are surrounding a border grid cell. The number of neighbors is held in the numNeighbors grid. On the other hand, when a cell is born or dies on the border of the local Map subgrid, that change will affect the neighbor counts of cells in another process. One obvious implementation for my distributed version will be to keep ghost cell subarrays of neighbor count changes corresponding to cells across all process subgrid borders that are generated in the AddNeighbors() and SubtractNeighbors() functions. Once those functions have finished, the ghost cells are exchanged and, upon receipt of a message, the local neighbor counts are updated and any cells along the local border that meet the birth or death criteria will be added to the maylive or maydie. These two lists, as you'll recall, are then processed in the Vivify() and Kill() functions to complete the processing of a simulation generation.

This is all well and good and takes less code than the words I've used above to describe how it works. Rather than show off that code, though, I want to show off a version that takes a slightly different approach. It's not a better approach necessarily (the one just described above is straightforward and simple to understand), just one that utilizes an interesting feature of the MPI library: derived data types. To enable this method, I've chosen to return to the original syntax of the programmer implementation of my List data structure.

The Vivify() and Kill() functions are pretty much as before. That is, they take the current neighbor counts and the grid cells in the maylive and maydie lists, respectively, and birth new cells or kill dead cells before adding the grid coordinates to the appropriate local list that will then be processed by AddNeighbors() and SubtractNeighbors() in the next generation computation.

The interesting part of this distributed computation is the computations for AddNeighbors() and SubtractNeighbors(). As I mentioned above, these are the functions that take the lists of newly born and newly dead cells and adjusts the neighbor counts of numNeighbors. What makes these two functions interesting is the fact that the neighbor counts to be updated can be across the logical subgrid border and part of another process's memory. To illustrate my solution, I'm just going to deal with AddNeighbors(). The changes in that function will have corresponding equivalents in SubtractNeighbors(). Here is my code for AddNeighbors():

newlive list have been processed, the call to SendToNeighbor() moves the data contained in the lists to the neighboring processes.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!