Monday July 27, 2015
This problem challenges you to create a hybrid MPI+OpenMP model of princes, princesses, frogs, and witches.
The model in this problem is based on Shodor's "Kiss a Frog" model (http://shodor.org/talks/ncsi/vensim/kissafrog.html). You may find it helpful to reference that model as you solve the problem.

This challenge problem is also similar to seven previous "Hybrid Parallel" challenge problems, and you may find it helpful to reference those as you solve the problem:
http://hpcuniversity.org/students/weeklyChallenge/88/
http://hpcuniversity.org/students/weeklyChallenge/87/
http://hpcuniversity.org/students/weeklyChallenge/86/
http://hpcuniversity.org/students/weeklyChallenge/85/
http://hpcuniversity.org/students/weeklyChallenge/83/
http://hpcuniversity.org/students/weeklyChallenge/82/
http://hpcuniversity.org/students/weeklyChallenge/81/

Your task is to implement a hybrid MPI+OpenMP parallel program, wherein each MPI process spawns OpenMP threads. The threads are each responsible for running a simulation with different parameters. The parameters are determined by MPI and OpenMP variables (via MPI_Comm_rank(), MPI_Comm_size(), omp_get_thread_num(), and omp_get_num_threads()), as follows:

if omp_num_threads = 1 and mpi_size = 1, witch_density = 0.
Otherwise, witch_density = 0.5 * (mpi_rank * omp_num_threads + omp_thread_num) / (mpi_size * omp_num_threads - 1).

The other parameters in the model are constant for all threads:
INITIAL_FROGS = 5
INITIAL_PRINCES = 10
INITIAL_SLEEPING_BEAUTIES = 5
INITIAL_PRINCESSES = 10
INITIAL_TIME = 0
FINAL_TIME = 100
TIME_STEP = 1

At each current_time_step from START_TIME through END_TIME, incrementing by TIME_STEP, each OpenMP thread performs the following calculations:

frogs{new} = frogs{old} + TIME_STEP * (whacked{old} - kissed_by_a_princess{old})

princes{new} = princes{old} + TIME_STEP * (kissed_by_a_princess{old} - whacked{old})

sleeping_beauties{new} = sleeping_beauties{old} + TIME_STEP * (poisoned{old} - kissed_by_a_prince{old})

princesses{new} = princesses{old} + TIME_STEP * (kissed_by_a_prince{old} - poisoned{old})

whacked{new} = 0.2 * witch_density * princes{new}

kissed_by_a_princess{new} = 0.05 * princesses{new} * frogs{new}

poisoned{new} = witch_density * princesses{new}

kissed_by_a_prince{new} = 0.01 * sleeping_beauties{new} * princes{new}

At the end of the simulation, the thread stores the final amounts of frogs, princes, sleeping beauties, and princesses in 4 arrays, one for each quantity. The arrays are shared by all threads and indexed omp_thread_num. Thus, each MPI process will have 4 arrays that contain all of its threads' final amounts.

Each MPI process is responsible for sending its final data to the MPI process rank 0, who is responsible for printing the results in the following format:

X1 A1 B1 C1 D1
X2 A2 B2 C2 D2
...
where X is witch_density, A is the final amount of frogs, B is the final amount of princes, C is the final amount of sleeping_beauties, and D is the final amount of princesses. This list of results should be ordered first by mpi_rank and then by omp_thread_num.

Assume that the populations of frogs, princes, sleeping_beauties, and princesses can contain fractional values.

A sample output file for a working program running with 17 MPI processes and 3 OpenMP threads is provided in the "Hybrid Parallel 'Kiss a Frog' sample output" file below.
Show solution
Challenge Resources:
©1994-2020   |   Shodor   |   Privacy Policy   |   NSDL   |   XSEDE   |   Blue Waters   |   ACM SIGHPC   |   feedback  |   facebook   |   twitter   |   rss   |   youtube   |   XSEDE Code of Conduct   |   Not Logged In. Login