Exercises
Exercise 1
Write a multiprocessing program that computes the sum of the cubes of the numbers from 1.0 to 1000.0 by increments of 0.1
Exercise 2
We are going to find the maximum of a 3-d surface by “brute force” evaluation of x, y, z values. This is a method of optimization that has become increasingly popular since it is easily parallelizable. The surface is defined by the following rules:
$$ \mu_1 = \sqrt{2} $$ $$ \mu_2 = \sqrt{\pi} $$ $$ \sigma_1=3.1 $$ $$\sigma_2=1.4 $$ $$ a=(x-\mu_1)^2 \div (2 \sig_1^2) $$ $$ b=(x-\mu_2)^2 \div (2 \sig_2^2) $$ $$ z_1=0.1 \sin(x) \sin(xy) $$ $$ z_2=\exp(-(a+b)) \div (\sig_1 \sig_2 \sqrt(2\pi) $$ $$ z=z_1+z_2 $$
The surface is defined over the ranges $$ −10\pi \le x \le 10\pi $$ $$ −10\pi \le y \le 10\pi $$
Generate a list of N random values for each of x and y over the above range. For testing you can use N=800000. Be sure to measure the time.
Hints: use Numpy. Look up numpy.random.uniform(arglist) to find out how to generate the values. Another hint: for best performance use the numpy built-in array_split to divide an array among the processes.
Print the final value of the maximum you found. If you have time, you can go back and figure out how to return the corresponding x and y values as well.
Add the timing routines to compare the parallel and serial times.
Example solution
Contents of mp_findmax.py
import multiprocessing as mp
import time
import numpy as np
import os
def surface(coords):
"""This is the main processing function."""
x,y=coords
mu1=np.sqrt(2.0)
mu2=np.sqrt(np.pi)
sig1=3.1
sig2=1.4
z1=0.1*np.sin(x)*np.sin(x*y)
a=(x-mu1)**2/(2*sig1**2)
b=(y-mu2)**2/(2*sig2**2)
z2=np.exp(-(a+b))/(sig1*sig2*np.sqrt(2.0*np.pi))
z=z1+z2
return z.max()
if __name__ == '__main__':
ncpus=int(os.getenv('NUM_PROCS'))
nsamps=4000000
# Define the parameters to test
xlo=-10.*np.pi; xhi=10.*np.pi
ylo=-10.*np.pi; yhi=10.*np.pi
xyvals=np.random.uniform(xlo,xhi,size=(2,nsamps))
coords=np.array_split(xyvals,ncpus,axis=1)
pool = mp.Pool(processes=ncpus)
tic=time.time ()
results = np.asarray(pool.map(surface, coords))
print("Result is "+str(results.max()))
toc=time.time ()
print("Parallel time on "+str(ncpus)+" cores:"+str(round(toc-tic,4)))
pool.close(); pool.join()
tic=time.time()
results=np.asarray(list(map(surface,coords)))
print("Result is "+str(results.max()))
toc=time.time()
print("Serial time:"+str(round(toc-tic,4)))
Download mp_findmax.py file