Monday October 27, 2014
This problem challenges you to create a hybrid MPI+OpenMP model of concentration of a drug in the bloodstream.
The model in this problem is based on Shodor's Pharmacology system dynamics model (http://shodor.org/talks/ncsi/vensim/Pharma.html). You may find it helpful to reference that model as you solve the problem.

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

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 the thread's MPI rank and OpenMP thread number, as follows:

doses_per_day = mpi_rank + 1
dosage_per_day = 20000 * (thread_num + 1)
dosage = dosage_per_day / doses_per_day
every_few_hours = 24 / doses_per_day

The other parameters in the model are constant for all threads:
START_TIME = 0
END_TIME = 48
TIME_STEP = 0.25
BLOOD_VOLUME = 4.6
ABSORPTION_RATE_CONSTANT = 0.25
HALF_LIFE = 6
EXCRETION_RATE_CONSTANT = 0.693 / HALF_LIFE
INITIAL_MEDICINE_IN_INTESTINES = 0
INITIAL_PLASMA_LEVEL = 0
MEDICINAL_LEVEL = 800
TOXIC_LEVEL = 1000

At each current_time_step from START_TIME through END_TIME, incrementing by TIME_STEP, each OpenMP thread performs the following calculations:
medicine_in_intestines{new} = medicine_in_intestines{old} + TIME_STEP * (intake{old} - absorption{old})
plasma_level{new} = plasma_level{old} + TIME_STEP * (absorption{old} - excretion{old})
plasma_concentration{new} = plasma_level{new} / BLOOD_VOLUME
If the current_time_step is the next_dose_time_step, intake{new} = dosage / TIME_STEP, next_dose_time{new} = next_dose_time{old} + every_few_hours, and next_dose_time_step{new} = TIME_STEP * round(next_dose_time{new} / TIME_STEP). Otherwise, intake{new} = 0.
absorption{new} = ABSORPTION_RATE_CONSTANT * medicine_in_intestines{new}
excretion{new} = EXCRETION_RATE_CONSTANT * plasma_level{new}

At the end of each time step, the thread increments one of three counters, each of which start at 0 at the beginning of the simulation:
- if the plasma_concentration is < the MEDICINAL_LEVEL, the thread increments a below_medicinal_counter.
- if the plasma_concentration is >= the MEDICINAL_LEVEL and < the TOXIC_LEVEL, the thread increments a between_medicinal_and_toxic_counter.
- if the plasma_concentration is >= the TOXIC_LEVEL, the thread increments an above_toxic_counter.

At the end of the simulation, the thread stores the final value of its counters in 3 arrays, one for each counter, which are shared by all threads and indexed by the thread's OpenMP thread number. Thus, each MPI process will have 3 arrays that contain all of its threads' final counter values.

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 Y1 A1 B1 C1
X2 Y2 A2 B2 C2
...
where X is the doses_per_day, Y is the dosage_per_day, A is the final value of the below_medicinal_counter, B is the final value of the between_medicinal_and_toxic_counter, and C is the final value of the above_toxic_counter. This list of results should be ordered first by MPI rank and then by OpenMP thread number.

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