├── Chapter01
├── __pycache__
│ └── do_something.cpython-35.pyc
├── classes.py
├── dir.py
├── do_something.py
├── file.py
├── flow.py
├── lists.py
├── multiprocessing_test.py
├── multithreading_test.py
├── serial_test.py
├── test.txt
└── thread_and_processes.py
├── Chapter02
├── Barrier.py
├── Condition.py
├── Event.py
├── MyThreadClass.py
├── MyThreadClass_lock.py
├── MyThreadClass_lock_2.py
├── Rlock.py
├── Semaphore.py
├── Thread_definition.py
├── Thread_determine.py
├── Thread_name_and_processes.py
└── Threading_with_queue.py
├── Chapter03
├── __pycache__
│ └── myFunc.cpython-35.pyc
├── communicating_with_pipe.py
├── communicating_with_queue.py
├── killing_processes.py
├── myFunc.py
├── naming_processes.py
├── process_in_subclass.py
├── process_pool.py
├── processes_barrier.py
├── run_background_processes.py
├── run_background_processes_no_daemons.py
├── spawning_processes.py
└── spawning_processes_namespace.py
├── Chapter04
├── alltoall.py
├── broadcast.py
├── deadLockProblems.py
├── gather.py
├── helloworld_MPI.py
├── pointToPointCommunication.py
├── reduction.py
├── scatter.py
└── virtualTopology.py
├── Chapter05
├── asyncio_and_futures.py
├── asyncio_coroutine.py
├── asyncio_event_loop.py
├── asyncio_task_manipulation.py
└── concurrent_futures_pooling.py
├── Chapter06
├── Celery
│ ├── addTask.py
│ └── addTask_main.py
├── Pyro4
│ ├── First Example
│ │ ├── pyro_client.py
│ │ └── pyro_server.py
│ └── Second Example
│ │ ├── __pycache__
│ │ └── chainTopology.cpython-35.pyc
│ │ ├── chainTopology.py
│ │ ├── client_chain.py
│ │ ├── desktop.ini
│ │ ├── server_chain_1.py
│ │ ├── server_chain_2.py
│ │ └── server_chain_3.py
└── socket
│ ├── addTask.py
│ ├── addTask_main.py
│ ├── client.py
│ ├── client2.py
│ ├── mytext.txt
│ ├── received.txt
│ ├── server.py
│ └── server2.py
├── Chapter07
└── codes
│ └── how to containerize a Python application
│ ├── Dockerfile
│ ├── dockerize.py
│ └── requirements.txt
├── Chapter08
├── Numba
│ ├── matMulNumba.py
│ ├── numba_cuda_detection.py
│ └── reduceNumba.py
├── PyCUDA
│ ├── dealingWithPycuda.py
│ ├── heterogenousPycuda.py
│ └── memManagementPycuda.py
└── PyOpenCL
│ ├── __pycache__
│ └── deviceInfoPyopencl.cpython-37.pyc
│ ├── deviceInfoPyopencl.py
│ ├── elementwisePyopencl.py
│ ├── testApplicationPyopencl.py
│ └── vectorSumPyopencl.py
├── Chapter09
└── codes chapter 9 debug and test
│ ├── __pycache__
│ ├── testset.cpython-36.pyc
│ └── testset1.cpython-36.pyc
│ ├── nosetest.py
│ ├── pdb
│ ├── __pycache__
│ │ └── pdb_test.cpython-35.pyc
│ ├── inside_code_to_debug_pdb.py
│ ├── pdb_test.py
│ ├── postmortem.py
│ ├── unittest_fail.py
│ └── using_python_interpreter_pdb.py
│ ├── rpdb_code_example.py
│ ├── simplicisticTest.py
│ ├── testset.py
│ ├── testset1.py
│ ├── unittest_exception.py
│ ├── unittest_truth.py
│ └── winpdb_reborn_code_example.py
├── LICENSE
└── README.md
/Chapter01/__pycache__/do_something.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Python-Parallel-Programming-Cookbook-Second-Edition/a10f0b2ba69995a6a8697e68ae0b53a20f4c04c7/Chapter01/__pycache__/do_something.cpython-35.pyc
--------------------------------------------------------------------------------
/Chapter01/classes.py:
--------------------------------------------------------------------------------
1 | class Myclass:
2 | common = 10
3 | def __init__ (self):
4 | self.myvariable = 3
5 | def myfunction (self, arg1, arg2):
6 | return self.myvariable
7 |
8 | instance = Myclass()
9 | print("instance.myfunction(1, 2)" , instance.myfunction(1, 2))
10 |
11 | instance2 = Myclass()
12 | print("instance.common ",instance.common)
13 | print("instance2.common ",instance2.common)
14 |
15 | Myclass.common = 30
16 |
17 | print("instance.common ", instance.common)
18 |
19 | print("instance2.common ", instance2.common)
20 |
21 | instance.common = 10
22 | print("instance.common ", instance.common)
23 |
24 | print("instance2.common " , instance2.common)
25 | Myclass.common = 50
26 |
27 | print("instance.common ", instance.common)
28 | print("instance2.common " , instance2.common)
29 |
30 | class AnotherClass (Myclass):
31 | # The "self" argument is passed automatically
32 | # and refers to the class's instance, so you can set
33 | # instance variables as above, but from within the class.
34 | def __init__ (self, arg1):
35 | self.myvariable = 3
36 | print (arg1)
37 |
38 | instance = AnotherClass ("hello")
39 | print("instance.myfunction (1, 2) " , instance.myfunction (1, 2))
40 |
41 | instance.test = 10
42 | print("instance.test " , instance.test)
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/Chapter01/dir.py:
--------------------------------------------------------------------------------
1 | # In this program,
2 | # we check if the number is positive or
3 | # negative or zero and
4 | # display an appropriate message
5 |
6 | num = 1
7 |
8 | # Try these two variations as well:
9 | # num = 0
10 | # num = -4.5
11 |
12 | if num > 0:
13 | print("Positive number")
14 | elif num == 0:
15 | print("Zero")
16 | else:
17 | print("Negative number")
18 |
19 |
20 |
21 | # Program to find the sum of all numbers stored in a list
22 |
23 | # List of numbers
24 | numbers = [6, 6, 3, 8, -3, 2, 5, 44, 12]
25 |
26 | # variable to store the sum
27 | sum = 0
28 |
29 | # iterate over the list
30 | for val in numbers:
31 | sum = sum+val
32 |
33 | # Output: The sum is 48
34 | print("The sum is", sum)
35 |
36 |
--------------------------------------------------------------------------------
/Chapter01/do_something.py:
--------------------------------------------------------------------------------
1 | import random
2 |
3 | def do_something(count,out_list):
4 | for i in range(count):
5 | out_list.append(random.random())
6 |
7 |
--------------------------------------------------------------------------------
/Chapter01/file.py:
--------------------------------------------------------------------------------
1 | f = open ('test.txt', 'w')
2 | f.write ('first line of file \n')
3 |
4 | f.write ('second line of file \n')
5 |
6 | f.close()
7 | f = open ('test.txt')
8 | content = f.read()
9 | print (content)
10 |
11 | f.close()
12 |
--------------------------------------------------------------------------------
/Chapter01/flow.py:
--------------------------------------------------------------------------------
1 |
2 | # IF
3 |
4 | # In this program, we check if the number is positive or negative or zero and
5 | # display an appropriate message
6 |
7 | num = 1
8 | if num > 0:
9 | print("Positive number")
10 | elif num == 0:
11 | print("Zero")
12 | else:
13 | print("Negative number")
14 |
15 |
16 | # FOR
17 | # Program to find the sum of all numbers stored in a list
18 | numbers = [6, 6, 3, 8, -3, 2, 5, 44, 12]
19 | sum = 0
20 | for val in numbers:
21 | sum = sum+val
22 |
23 | # Output: The sum is 48
24 | print("The sum is", sum)
25 |
26 |
27 | #WHILE
28 | # Program to add natural numbers upto sum = 1+2+3+...+n
29 |
30 | n = 10
31 | # initialize sum and counter
32 | sum = 0
33 | i = 1
34 | while i <= n:
35 | sum = sum + i
36 | i = i+1 # update counter
37 |
38 | # print the sum
39 | print("The sum is", sum)
40 |
41 |
--------------------------------------------------------------------------------
/Chapter01/lists.py:
--------------------------------------------------------------------------------
1 | example = [1, ["another", "list"], ("a", "tuple")]
2 | example
3 | mylist = ["element 1", 2, 3.14]
4 | mylist
5 | mylist[0] = "yet element 1"
6 | print(mylist[0])
7 | mylist[-1] = 3.15
8 | print (mylist[-1])
9 | mydict = {"Key 1": "value 1", 2: 3, "pi": 3.14}
10 | print(mydict)
11 | mydict["pi"] = 3.15
12 | print(mydict["pi"])
13 | mytuple = (1, 2, 3)
14 | print(mytuple)
15 | myfunc = len
16 | print (myfunc(mylist))
17 |
--------------------------------------------------------------------------------
/Chapter01/multiprocessing_test.py:
--------------------------------------------------------------------------------
1 | from do_something import *
2 | import time
3 | import multiprocessing
4 |
5 |
6 | if __name__ == "__main__":
7 | start_time = time.time()
8 | size = 10000000
9 | procs = 10
10 | jobs = []
11 | for i in range(0, procs):
12 | out_list = list()
13 | process = multiprocessing.Process\
14 | (target=do_something,args=(size,out_list))
15 | jobs.append(process)
16 |
17 | for j in jobs:
18 | j.start()
19 |
20 | for j in jobs:
21 | j.join()
22 |
23 | print ("List processing complete.")
24 | end_time = time.time()
25 | print("multiprocesses time=", end_time - start_time)
26 |
--------------------------------------------------------------------------------
/Chapter01/multithreading_test.py:
--------------------------------------------------------------------------------
1 | from do_something import *
2 | import time
3 | import threading
4 |
5 | if __name__ == "__main__":
6 | start_time = time.time()
7 | size = 10000000
8 | threads = 10
9 | jobs = []
10 | for i in range(0, threads):
11 | out_list = list()
12 | thread = threading.Thread(target=do_something(size, out_list))
13 | jobs.append(thread)
14 | for j in jobs:
15 | j.start()
16 |
17 |
18 | for j in jobs:
19 | j.join()
20 |
21 | print ("List processing complete.")
22 | end_time = time.time()
23 | print("multithreading time=", end_time - start_time)
24 |
25 |
--------------------------------------------------------------------------------
/Chapter01/serial_test.py:
--------------------------------------------------------------------------------
1 | import time
2 | from do_something import *
3 |
4 | if __name__ == "__main__":
5 | start_time = time.time()
6 | size = 10000000
7 | n_exec = 10
8 | for i in range(0, n_exec):
9 | out_list = list()
10 | do_something(size, out_list)
11 |
12 |
13 | print ("List processing complete.")
14 | end_time = time.time()
15 | print("serial time=", end_time - start_time)
16 |
--------------------------------------------------------------------------------
/Chapter01/test.txt:
--------------------------------------------------------------------------------
1 | first line of file
2 | second line of file
3 |
--------------------------------------------------------------------------------
/Chapter01/thread_and_processes.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 | import threading
4 | import multiprocessing
5 | import random
6 |
7 | NUM_WORKERS = 10
8 | size = 10000000
9 | out_list = list()
10 |
11 | def do_something(count, out_list):
12 | for i in range(count):
13 | out_list.append(random.random())
14 | """
15 | #Serial
16 | start_time = time.time()
17 | for _ in range(NUM_WORKERS):
18 | do_something(size,out_list)
19 | end_time = time.time()
20 | print("Serial time=", end_time - start_time)
21 | """
22 |
23 | #MultiThreading
24 | start_time = time.time()
25 | jobs = []
26 | for i in range(0, NUM_WORKERS):
27 | thread = threading.Thread(target=do_something(size, out_list))
28 | jobs.append(thread)
29 | for j in jobs:
30 | j.start()
31 |
32 | for j in jobs:
33 | j.join()
34 |
35 | print ("List processing complete.")
36 | end_time = time.time()
37 | print("threading time=", end_time - start_time)
38 |
39 |
40 | #MultiProcesses
41 | start_time = time.time()
42 | jobs = []
43 | for i in range(0, NUM_WORKERS):
44 | process = multiprocessing.Process\
45 | (target=do_something,args=(size,out_list))
46 | jobs.append(process)
47 |
48 | for j in jobs:
49 | j.start()
50 |
51 | for j in jobs:
52 | j.join()
53 |
54 | print ("List processing complete.")
55 | end_time = time.time()
56 | print("processes time=", end_time - start_time)
57 |
--------------------------------------------------------------------------------
/Chapter02/Barrier.py:
--------------------------------------------------------------------------------
1 | from random import randrange
2 | from threading import Barrier, Thread
3 | from time import ctime, sleep
4 |
5 | num_runners = 3
6 | finish_line = Barrier(num_runners)
7 | runners = ['Huey', 'Dewey', 'Louie']
8 |
9 | def runner():
10 | name = runners.pop()
11 | sleep(randrange(2, 5))
12 | print('%s reached the barrier at: %s \n' % (name, ctime()))
13 | finish_line.wait()
14 |
15 | def main():
16 | threads = []
17 | print('START RACE!!!!')
18 | for i in range(num_runners):
19 | threads.append(Thread(target=runner))
20 | threads[-1].start()
21 | for thread in threads:
22 | thread.join()
23 | print('Race over!')
24 |
25 | if __name__ == "__main__":
26 | main()
27 |
--------------------------------------------------------------------------------
/Chapter02/Condition.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import threading
3 | import time
4 |
5 | LOG_FORMAT = '%(asctime)s %(threadName)-17s %(levelname)-8s %(message)s'
6 | logging.basicConfig(level=logging.INFO, format=LOG_FORMAT)
7 |
8 | items = []
9 | condition = threading.Condition()
10 |
11 |
12 | class Consumer(threading.Thread):
13 | def __init__(self, *args, **kwargs):
14 | super().__init__(*args, **kwargs)
15 |
16 | def consume(self):
17 |
18 | with condition:
19 |
20 | if len(items) == 0:
21 | logging.info('no items to consume')
22 | condition.wait()
23 |
24 | items.pop()
25 | logging.info('consumed 1 item')
26 |
27 | condition.notify()
28 |
29 | def run(self):
30 | for i in range(20):
31 | time.sleep(2)
32 | self.consume()
33 |
34 |
35 | class Producer(threading.Thread):
36 | def __init__(self, *args, **kwargs):
37 | super().__init__(*args, **kwargs)
38 |
39 | def produce(self):
40 |
41 | with condition:
42 |
43 | if len(items) == 10:
44 | logging.info('items produced {}. Stopped'.format(len(items)))
45 | condition.wait()
46 |
47 | items.append(1)
48 | logging.info('total items {}'.format(len(items)))
49 |
50 | condition.notify()
51 |
52 | def run(self):
53 | for i in range(20):
54 | time.sleep(0.5)
55 | self.produce()
56 |
57 |
58 | def main():
59 | producer = Producer(name='Producer')
60 | consumer = Consumer(name='Consumer')
61 |
62 | producer.start()
63 | consumer.start()
64 |
65 | producer.join()
66 | consumer.join()
67 |
68 |
69 | if __name__ == "__main__":
70 | main()
71 |
--------------------------------------------------------------------------------
/Chapter02/Event.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import threading
3 | import time
4 | import random
5 |
6 | LOG_FORMAT = '%(asctime)s %(threadName)-17s %(levelname)-8s %(message)s'
7 | logging.basicConfig(level=logging.INFO, format=LOG_FORMAT)
8 |
9 | items = []
10 | event = threading.Event()
11 |
12 |
13 | class Consumer(threading.Thread):
14 | def __init__(self, *args, **kwargs):
15 | super().__init__(*args, **kwargs)
16 |
17 | def run(self):
18 | while True:
19 | time.sleep(2)
20 | event.wait()
21 | item = items.pop()
22 | logging.info('Consumer notify: {} popped by {}'\
23 | .format(item, self.name))
24 |
25 | class Producer(threading.Thread):
26 | def __init__(self, *args, **kwargs):
27 | super().__init__(*args, **kwargs)
28 |
29 | def run(self):
30 | for i in range(5):
31 | time.sleep(2)
32 | item = random.randint(0, 100)
33 | items.append(item)
34 | logging.info('Producer notify: item {} appended by {}'\
35 | .format(item, self.name))
36 | event.set()
37 | event.clear()
38 |
39 | if __name__ == "__main__":
40 | t1 = Producer()
41 | t2 = Consumer()
42 |
43 | t1.start()
44 | t2.start()
45 |
46 | t1.join()
47 | t2.join()
48 |
--------------------------------------------------------------------------------
/Chapter02/MyThreadClass.py:
--------------------------------------------------------------------------------
1 | import time
2 | import os
3 | from random import randint
4 | from threading import Thread
5 |
6 | class MyThreadClass (Thread):
7 | def __init__(self, name, duration):
8 | Thread.__init__(self)
9 | self.name = name
10 | self.duration = duration
11 | def run(self):
12 | print ("---> " + self.name + \
13 | " running, belonging to process ID "\
14 | + str(os.getpid()) + "\n")
15 | time.sleep(self.duration)
16 | print ("---> " + self.name + " over\n")
17 |
18 |
19 | def main():
20 | start_time = time.time()
21 |
22 | # Thread Creation
23 | thread1 = MyThreadClass("Thread#1 ", randint(1,10))
24 | thread2 = MyThreadClass("Thread#2 ", randint(1,10))
25 | thread3 = MyThreadClass("Thread#3 ", randint(1,10))
26 | thread4 = MyThreadClass("Thread#4 ", randint(1,10))
27 | thread5 = MyThreadClass("Thread#5 ", randint(1,10))
28 | thread6 = MyThreadClass("Thread#6 ", randint(1,10))
29 | thread7 = MyThreadClass("Thread#7 ", randint(1,10))
30 | thread8 = MyThreadClass("Thread#8 ", randint(1,10))
31 | thread9 = MyThreadClass("Thread#9 ", randint(1,10))
32 |
33 | # Thread Running
34 | thread1.start()
35 | thread2.start()
36 | thread3.start()
37 | thread4.start()
38 | thread5.start()
39 | thread6.start()
40 | thread7.start()
41 | thread8.start()
42 | thread9.start()
43 |
44 | # Thread joining
45 | thread1.join()
46 | thread2.join()
47 | thread3.join()
48 | thread4.join()
49 | thread5.join()
50 | thread6.join()
51 | thread7.join()
52 | thread8.join()
53 | thread9.join()
54 |
55 | # End
56 | print("End")
57 |
58 | #Execution Time
59 | print("--- %s seconds ---" % (time.time() - start_time))
60 |
61 |
62 | if __name__ == "__main__":
63 | main()
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/Chapter02/MyThreadClass_lock.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 | import os
4 | from threading import Thread
5 | from random import randint
6 |
7 | # Lock Definition
8 | threadLock = threading.Lock()
9 |
10 | class MyThreadClass (Thread):
11 | def __init__(self, name, duration):
12 | Thread.__init__(self)
13 | self.name = name
14 | self.duration = duration
15 | def run(self):
16 | #Acquire the Lock
17 | threadLock.acquire()
18 | print ("---> " + self.name + \
19 | " running, belonging to process ID "\
20 | + str(os.getpid()) + "\n")
21 | time.sleep(self.duration)
22 | print ("---> " + self.name + " over\n")
23 | #Release the Lock
24 | threadLock.release()
25 |
26 |
27 | def main():
28 | start_time = time.time()
29 | # Thread Creation
30 | thread1 = MyThreadClass("Thread#1 ", randint(1,10))
31 | thread2 = MyThreadClass("Thread#2 ", randint(1,10))
32 | thread3 = MyThreadClass("Thread#3 ", randint(1,10))
33 | thread4 = MyThreadClass("Thread#4 ", randint(1,10))
34 | thread5 = MyThreadClass("Thread#5 ", randint(1,10))
35 | thread6 = MyThreadClass("Thread#6 ", randint(1,10))
36 | thread7 = MyThreadClass("Thread#7 ", randint(1,10))
37 | thread8 = MyThreadClass("Thread#8 ", randint(1,10))
38 | thread9 = MyThreadClass("Thread#9 ", randint(1,10))
39 |
40 | # Thread Running
41 | thread1.start()
42 | thread2.start()
43 | thread3.start()
44 | thread4.start()
45 | thread5.start()
46 | thread6.start()
47 | thread7.start()
48 | thread8.start()
49 | thread9.start()
50 |
51 | # Thread joining
52 | thread1.join()
53 | thread2.join()
54 | thread3.join()
55 | thread4.join()
56 | thread5.join()
57 | thread6.join()
58 | thread7.join()
59 | thread8.join()
60 | thread9.join()
61 |
62 | # End
63 | print("End")
64 |
65 | #Execution Time
66 | print("--- %s seconds ---" % (time.time() - start_time))
67 |
68 |
69 | if __name__ == "__main__":
70 | main()
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/Chapter02/MyThreadClass_lock_2.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 | import os
4 | from threading import Thread
5 | from random import randint
6 |
7 | # Lock Definition
8 | threadLock = threading.Lock()
9 |
10 | class MyThreadClass (Thread):
11 | def __init__(self, name, duration):
12 | Thread.__init__(self)
13 | self.name = name
14 | self.duration = duration
15 | def run(self):
16 | #Acquire the Lock
17 | threadLock.acquire()
18 | print ("---> " + self.name + \
19 | " running, belonging to process ID "\
20 | + str(os.getpid()) + "\n")
21 | threadLock.release()
22 | time.sleep(self.duration)
23 | print ("---> " + self.name + " over\n")
24 | #Release the Lock
25 |
26 |
27 | def main():
28 | start_time = time.time()
29 |
30 | # Thread Creation
31 | thread1 = MyThreadClass("Thread#1 ", randint(1,10))
32 | thread2 = MyThreadClass("Thread#2 ", randint(1,10))
33 | thread3 = MyThreadClass("Thread#3 ", randint(1,10))
34 | thread4 = MyThreadClass("Thread#4 ", randint(1,10))
35 | thread5 = MyThreadClass("Thread#5 ", randint(1,10))
36 | thread6 = MyThreadClass("Thread#6 ", randint(1,10))
37 | thread7 = MyThreadClass("Thread#7 ", randint(1,10))
38 | thread8 = MyThreadClass("Thread#8 ", randint(1,10))
39 | thread9 = MyThreadClass("Thread#9 ", randint(1,10))
40 |
41 | # Thread Running
42 | thread1.start()
43 | thread2.start()
44 | thread3.start()
45 | thread4.start()
46 | thread5.start()
47 | thread6.start()
48 | thread7.start()
49 | thread8.start()
50 | thread9.start()
51 |
52 | # Thread joining
53 | thread1.join()
54 | thread2.join()
55 | thread3.join()
56 | thread4.join()
57 | thread5.join()
58 | thread6.join()
59 | thread7.join()
60 | thread8.join()
61 | thread9.join()
62 |
63 | # End
64 | print("End")
65 |
66 | #Execution Time
67 | print("--- %s seconds ---" % (time.time() - start_time))
68 |
69 |
70 | if __name__ == "__main__":
71 | main()
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/Chapter02/Rlock.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 | import random
4 |
5 |
6 | class Box:
7 | def __init__(self):
8 | self.lock = threading.RLock()
9 | self.total_items = 0
10 |
11 | def execute(self, value):
12 | with self.lock:
13 | self.total_items += value
14 |
15 | def add(self):
16 | with self.lock:
17 | self.execute(1)
18 |
19 | def remove(self):
20 | with self.lock:
21 | self.execute(-1)
22 |
23 | def adder(box, items):
24 | print("N° {} items to ADD \n".format(items))
25 | while items:
26 | box.add()
27 | time.sleep(1)
28 | items -= 1
29 | print("ADDED one item -->{} item to ADD \n".format(items))
30 |
31 |
32 |
33 | def remover(box, items):
34 | print("N° {} items to REMOVE \n".format(items))
35 | while items:
36 | box.remove()
37 | time.sleep(1)
38 | items -= 1
39 | print("REMOVED one item -->{} item to REMOVE \n".format(items))
40 |
41 |
42 | def main():
43 | items = 10
44 | box = Box()
45 |
46 | t1 = threading.Thread(target=adder, \
47 | args=(box, random.randint(10,20)))
48 | t2 = threading.Thread(target=remover, \
49 | args=(box, random.randint(1,10)))
50 |
51 | t1.start()
52 | t2.start()
53 |
54 |
55 | t1.join()
56 | t2.join()
57 |
58 |
59 | if __name__ == "__main__":
60 | main()
61 |
--------------------------------------------------------------------------------
/Chapter02/Semaphore.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import threading
3 | import time
4 | import random
5 |
6 | LOG_FORMAT = '%(asctime)s %(threadName)-17s %(levelname)-8s %(message)s'
7 | logging.basicConfig(level=logging.INFO, format=LOG_FORMAT)
8 |
9 |
10 | semaphore = threading.Semaphore(0)
11 | item = 0
12 |
13 |
14 | def consumer():
15 | logging.info('Consumer is waiting')
16 | semaphore.acquire()
17 | logging.info('Consumer notify: item number {}'.format(item))
18 |
19 |
20 | def producer():
21 | global item
22 | time.sleep(3)
23 | item = random.randint(0, 1000)
24 | logging.info('Producer notify: item number {}'.format(item))
25 | semaphore.release()
26 |
27 |
28 | def main():
29 | for i in range(10):
30 | t1 = threading.Thread(target=consumer)
31 | t2 = threading.Thread(target=producer)
32 |
33 | t1.start()
34 | t2.start()
35 |
36 | t1.join()
37 | t2.join()
38 |
39 |
40 | if __name__ == "__main__":
41 | main()
42 |
--------------------------------------------------------------------------------
/Chapter02/Thread_definition.py:
--------------------------------------------------------------------------------
1 | import threading
2 |
3 |
4 | def my_func(thread_number):
5 | return print('my_func called by thread N°{}'.format(thread_number))
6 |
7 |
8 | def main():
9 | threads = []
10 | for i in range(10):
11 | t = threading.Thread(target=my_func, args=(i,))
12 | threads.append(t)
13 | t.start()
14 | t.join()
15 |
16 | if __name__ == "__main__":
17 | main()
18 |
--------------------------------------------------------------------------------
/Chapter02/Thread_determine.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import time
3 |
4 | def function_A():
5 | print (threading.currentThread().getName()+str('--> starting \n'))
6 | time.sleep(2)
7 | print (threading.currentThread().getName()+str( '--> exiting \n'))
8 | return
9 |
10 | def function_B():
11 | print (threading.currentThread().getName()+str('--> starting \n'))
12 | time.sleep(2)
13 | print (threading.currentThread().getName()+str( '--> exiting \n'))
14 | return
15 |
16 | def function_C():
17 | print (threading.currentThread().getName()+str('--> starting \n'))
18 | time.sleep(2)
19 | print (threading.currentThread().getName()+str( '--> exiting \n'))
20 | return
21 |
22 |
23 | if __name__ == "__main__":
24 |
25 | t1 = threading.Thread(name='function_A', target=function_A)
26 | t2 = threading.Thread(name='function_B', target=function_B)
27 | t3 = threading.Thread(name='function_C',target=function_C)
28 |
29 | t1.start()
30 | t2.start()
31 | t3.start()
32 |
33 | t1.join()
34 | t2.join()
35 | t3.join()
36 |
--------------------------------------------------------------------------------
/Chapter02/Thread_name_and_processes.py:
--------------------------------------------------------------------------------
1 | from threading import Thread
2 | import time
3 | import os
4 |
5 | class MyThreadClass (Thread):
6 | def __init__(self, name):
7 | Thread.__init__(self)
8 | self.name = name
9 |
10 | def run(self):
11 | print("ID of process running {}".format(self.name)) #, " is {} \n".format(os.getpid()))
12 |
13 | def main():
14 | from random import randint
15 | # Thread Creation
16 | thread1 = MyThreadClass("Thread#1 ")
17 | thread2 = MyThreadClass("Thread#2 ")
18 |
19 | # Thread Running
20 | thread1.start()
21 | thread2.start()
22 |
23 |
24 | # Thread joining
25 | thread1.join()
26 | thread2.join()
27 |
28 | # End
29 | print("End")
30 |
31 |
32 | if __name__ == "__main__":
33 | main()
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/Chapter02/Threading_with_queue.py:
--------------------------------------------------------------------------------
1 | """"Thread synchronisation with queue"""
2 |
3 | from threading import Thread
4 | from queue import Queue
5 | import time
6 | import random
7 |
8 |
9 | class Producer(Thread):
10 |
11 | def __init__(self, queue):
12 | Thread.__init__(self)
13 | self.queue = queue
14 |
15 | def run(self):
16 | for i in range(5):
17 | item = random.randint(0, 256)
18 | self.queue.put(item)
19 | print('Producer notify : item N°%d appended to queue by %s\n'\
20 | % (item, self.name))
21 | time.sleep(1)
22 |
23 |
24 | class Consumer(Thread):
25 |
26 | def __init__(self, queue):
27 | Thread.__init__(self)
28 | self.queue = queue
29 |
30 | def run(self):
31 | while True:
32 | item = self.queue.get()
33 | print('Consumer notify : %d popped from queue by %s'\
34 | % (item, self.name))
35 | self.queue.task_done()
36 |
37 | if __name__ == '__main__':
38 | queue = Queue()
39 |
40 | t1 = Producer(queue)
41 | t2 = Consumer(queue)
42 | t3 = Consumer(queue)
43 | t4 = Consumer(queue)
44 |
45 | t1.start()
46 | t2.start()
47 | t3.start()
48 | t4.start()
49 |
50 | t1.join()
51 | t2.join()
52 | t3.join()
53 | t4.join()
54 |
--------------------------------------------------------------------------------
/Chapter03/__pycache__/myFunc.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Python-Parallel-Programming-Cookbook-Second-Edition/a10f0b2ba69995a6a8697e68ae0b53a20f4c04c7/Chapter03/__pycache__/myFunc.cpython-35.pyc
--------------------------------------------------------------------------------
/Chapter03/communicating_with_pipe.py:
--------------------------------------------------------------------------------
1 | ##Using Pipes with multiprocessing – Chapter 3: Process Based Parallelism
2 |
3 | import multiprocessing
4 |
5 |
6 | def create_items(pipe):
7 | output_pipe, _ = pipe
8 | for item in range(10):
9 | output_pipe.send(item)
10 | output_pipe.close()
11 |
12 | def multiply_items(pipe_1, pipe_2):
13 | close, input_pipe = pipe_1
14 | close.close()
15 | output_pipe, _ = pipe_2
16 | try:
17 | while True:
18 | item = input_pipe.recv()
19 | output_pipe.send(item * item)
20 | except EOFError:
21 | output_pipe.close()
22 |
23 |
24 | if __name__== '__main__':
25 |
26 | #First process pipe with numbers from 0 to 9
27 | pipe_1 = multiprocessing.Pipe(True)
28 | process_pipe_1 = \
29 | multiprocessing.Process\
30 | (target=create_items, args=(pipe_1,))
31 | process_pipe_1.start()
32 |
33 | #second pipe,
34 | pipe_2 = multiprocessing.Pipe(True)
35 | process_pipe_2 = \
36 | multiprocessing.Process\
37 | (target=multiply_items, args=(pipe_1, pipe_2,))
38 | process_pipe_2.start()
39 |
40 | pipe_1[0].close()
41 | pipe_2[0].close()
42 |
43 | try:
44 | while True:
45 |
46 | print (pipe_2[1].recv())
47 | except EOFError:
48 | print ("End")
49 |
--------------------------------------------------------------------------------
/Chapter03/communicating_with_queue.py:
--------------------------------------------------------------------------------
1 | import multiprocessing
2 | import random
3 | import time
4 |
5 | class producer(multiprocessing.Process):
6 | def __init__(self, queue):
7 | multiprocessing.Process.__init__(self)
8 | self.queue = queue
9 |
10 | def run(self) :
11 | for i in range(10):
12 | item = random.randint(0, 256)
13 | self.queue.put(item)
14 | print ("Process Producer : item %d appended to queue %s"\
15 | % (item,self.name))
16 | time.sleep(1)
17 | print ("The size of queue is %s"\
18 | % self.queue.qsize())
19 |
20 | class consumer(multiprocessing.Process):
21 | def __init__(self, queue):
22 | multiprocessing.Process.__init__(self)
23 | self.queue = queue
24 |
25 | def run(self):
26 | while True:
27 | if (self.queue.empty()):
28 | print("the queue is empty")
29 | break
30 | else :
31 | time.sleep(2)
32 | item = self.queue.get()
33 | print ('Process Consumer : item %d popped \
34 | from by %s \n'\
35 | % (item, self.name))
36 | time.sleep(1)
37 |
38 |
39 | if __name__ == '__main__':
40 | queue = multiprocessing.Queue()
41 | process_producer = producer(queue)
42 | process_consumer = consumer(queue)
43 | process_producer.start()
44 | process_consumer.start()
45 | process_producer.join()
46 | process_consumer.join()
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Chapter03/killing_processes.py:
--------------------------------------------------------------------------------
1 | import multiprocessing
2 | import time
3 |
4 | def foo():
5 | print ('Starting function')
6 | for i in range(0,10):
7 | print('-->%d\n' %i)
8 | time.sleep(1)
9 | print ('Finished function')
10 |
11 | if __name__ == '__main__':
12 | p = multiprocessing.Process(target=foo)
13 | print ('Process before execution:', p, p.is_alive())
14 | p.start()
15 | print ('Process running:', p, p.is_alive())
16 | p.terminate()
17 | print ('Process terminated:', p, p.is_alive())
18 | p.join()
19 | print ('Process joined:', p, p.is_alive())
20 | print ('Process exit code:', p.exitcode)
21 |
--------------------------------------------------------------------------------
/Chapter03/myFunc.py:
--------------------------------------------------------------------------------
1 | def myFunc(i):
2 | print ('calling myFunc from process n°: %s' %i)
3 | for j in range (0,i):
4 | print('output from myFunc is :%s' %j)
5 | return
6 |
--------------------------------------------------------------------------------
/Chapter03/naming_processes.py:
--------------------------------------------------------------------------------
1 | import multiprocessing
2 | import time
3 |
4 | def myFunc():
5 | name = multiprocessing.current_process().name
6 | print ("Starting process name = %s \n" %name)
7 | time.sleep(3)
8 | print ("Exiting process name = %s \n" %name)
9 |
10 | if __name__ == '__main__':
11 | process_with_name = multiprocessing.Process\
12 | (name='myFunc process',\
13 | target=myFunc)
14 |
15 | #process_with_name.daemon = True
16 |
17 | process_with_default_name = multiprocessing.Process\
18 | (target=myFunc)
19 |
20 | process_with_name.start()
21 | process_with_default_name.start()
22 |
23 | process_with_name.join()
24 | process_with_default_name.join()
25 |
26 |
--------------------------------------------------------------------------------
/Chapter03/process_in_subclass.py:
--------------------------------------------------------------------------------
1 | import multiprocessing
2 |
3 | class MyProcess(multiprocessing.Process):
4 |
5 | def run(self):
6 | print ('called run method in %s' %self.name)
7 | return
8 |
9 | if __name__ == '__main__':
10 | for i in range(10):
11 | process = MyProcess()
12 | process.start()
13 | process.join()
14 |
15 |
--------------------------------------------------------------------------------
/Chapter03/process_pool.py:
--------------------------------------------------------------------------------
1 | #Using a Process Pool – Chapter 3: Process Based Parallelism
2 | import multiprocessing
3 |
4 | def function_square(data):
5 | result = data*data
6 | return result
7 |
8 |
9 | if __name__ == '__main__':
10 | inputs = list(range(0,100))
11 | pool = multiprocessing.Pool(processes=4)
12 | pool_outputs = pool.map(function_square, inputs)
13 |
14 | pool.close()
15 | pool.join()
16 | print ('Pool :', pool_outputs)
17 |
--------------------------------------------------------------------------------
/Chapter03/processes_barrier.py:
--------------------------------------------------------------------------------
1 | import multiprocessing
2 | from multiprocessing import Barrier, Lock, Process
3 | from time import time
4 | from datetime import datetime
5 |
6 |
7 | def test_with_barrier(synchronizer, serializer):
8 | name = multiprocessing.current_process().name
9 | synchronizer.wait()
10 | now = time()
11 | with serializer:
12 | print("process %s ----> %s" \
13 | %(name,datetime.fromtimestamp(now)))
14 |
15 | def test_without_barrier():
16 | name = multiprocessing.current_process().name
17 | now = time()
18 | print("process %s ----> %s" \
19 | %(name ,datetime.fromtimestamp(now)))
20 |
21 | if __name__ == '__main__':
22 | synchronizer = Barrier(2)
23 | serializer = Lock()
24 | Process(name='p1 - test_with_barrier'\
25 | ,target=test_with_barrier,\
26 | args=(synchronizer,serializer)).start()
27 | Process(name='p2 - test_with_barrier'\
28 | ,target=test_with_barrier,\
29 | args=(synchronizer,serializer)).start()
30 | Process(name='p3 - test_without_barrier'\
31 | ,target=test_without_barrier).start()
32 | Process(name='p4 - test_without_barrier'\
33 | ,target=test_without_barrier).start()
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Chapter03/run_background_processes.py:
--------------------------------------------------------------------------------
1 | import multiprocessing
2 | import time
3 |
4 | def foo():
5 | name = multiprocessing.current_process().name
6 | print ("Starting %s \n" %name)
7 | if name == 'background_process':
8 | for i in range(0,5):
9 | print('---> %d \n' %i)
10 | time.sleep(1)
11 | else:
12 | for i in range(5,10):
13 | print('---> %d \n' %i)
14 | time.sleep(1)
15 | print ("Exiting %s \n" %name)
16 |
17 |
18 | if __name__ == '__main__':
19 | background_process = multiprocessing.Process\
20 | (name='background_process',\
21 | target=foo)
22 | background_process.daemon = True
23 |
24 | NO_background_process = multiprocessing.Process\
25 | (name='NO_background_process',\
26 | target=foo)
27 |
28 | NO_background_process.daemon = False
29 |
30 | background_process.start()
31 | NO_background_process.start()
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Chapter03/run_background_processes_no_daemons.py:
--------------------------------------------------------------------------------
1 | import multiprocessing
2 | import time
3 |
4 | def foo():
5 | name = multiprocessing.current_process().name
6 | print ("Starting %s \n" %name)
7 | if name == 'background_process':
8 | for i in range(0,5):
9 | print('---> %d \n' %i)
10 | time.sleep(1)
11 | else:
12 | for i in range(5,10):
13 | print('---> %d \n' %i)
14 | time.sleep(1)
15 | print ("Exiting %s \n" %name)
16 |
17 |
18 | if __name__ == '__main__':
19 | background_process = multiprocessing.Process\
20 | (name='background_process',\
21 | target=foo)
22 | background_process.daemon = False
23 |
24 | NO_background_process = multiprocessing.Process\
25 | (name='NO_background_process',\
26 | target=foo)
27 |
28 | NO_background_process.daemon = False
29 |
30 | background_process.start()
31 | NO_background_process.start()
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Chapter03/spawning_processes.py:
--------------------------------------------------------------------------------
1 | #Spawn a Process – Chapter 3: Process Based Parallelism
2 | import multiprocessing
3 |
4 | def myFunc(i):
5 | print ('calling myFunc from process n°: %s' %i)
6 | for j in range (0,i):
7 | print('output from myFunc is :%s' %j)
8 | return
9 |
10 | if __name__ == '__main__':
11 | for i in range(6):
12 | process = multiprocessing.Process(target=myFunc, args=(i,))
13 | process.start()
14 | process.join()
15 |
16 |
--------------------------------------------------------------------------------
/Chapter03/spawning_processes_namespace.py:
--------------------------------------------------------------------------------
1 | import multiprocessing
2 | from myFunc import myFunc
3 |
4 | if __name__ == '__main__':
5 | for i in range(6):
6 | process = multiprocessing.Process(target=myFunc, args=(i,))
7 | process.start()
8 | process.join()
9 |
10 |
--------------------------------------------------------------------------------
/Chapter04/alltoall.py:
--------------------------------------------------------------------------------
1 | from mpi4py import MPI
2 | import numpy
3 |
4 | comm = MPI.COMM_WORLD
5 | size = comm.Get_size()
6 | rank = comm.Get_rank()
7 |
8 |
9 | senddata = (rank+1)*numpy.arange(size,dtype=int)
10 | recvdata = numpy.empty(size,dtype=int)
11 | comm.Alltoall(senddata,recvdata)
12 |
13 |
14 | print(" process %s sending %s receiving %s"\
15 | %(rank , senddata , recvdata))
16 |
--------------------------------------------------------------------------------
/Chapter04/broadcast.py:
--------------------------------------------------------------------------------
1 | from mpi4py import MPI
2 |
3 | comm = MPI.COMM_WORLD
4 | rank = comm.Get_rank()
5 |
6 | if rank == 0:
7 | variable_to_share = 100
8 |
9 | else:
10 | variable_to_share = None
11 |
12 | variable_to_share = comm.bcast(variable_to_share, root=0)
13 | print("process = %d" %rank + " variable shared = %d " %variable_to_share)
14 |
--------------------------------------------------------------------------------
/Chapter04/deadLockProblems.py:
--------------------------------------------------------------------------------
1 | from mpi4py import MPI
2 |
3 | comm=MPI.COMM_WORLD
4 | rank = comm.rank
5 | print("my rank is %i" % (rank))
6 |
7 | if rank==1:
8 | data_send= "a"
9 | destination_process = 5
10 | source_process = 5
11 |
12 | data_received=comm.recv(source=source_process)
13 | comm.send(data_send,dest=destination_process)
14 |
15 | print ("sending data %s " %data_send + \
16 | "to process %d" %destination_process)
17 | print ("data received is = %s" %data_received)
18 |
19 |
20 |
21 | if rank==5:
22 | data_send= "b"
23 | destination_process = 1
24 | source_process = 1
25 |
26 | comm.send(data_send,dest=destination_process)
27 | data_received=comm.recv(source=source_process)
28 |
29 |
30 | print ("sending data %s :" %data_send + \
31 | "to process %d" %destination_process)
32 | print ("data received is = %s" %data_received)
33 |
34 |
--------------------------------------------------------------------------------
/Chapter04/gather.py:
--------------------------------------------------------------------------------
1 | from mpi4py import MPI
2 |
3 | comm = MPI.COMM_WORLD
4 | size = comm.Get_size()
5 | rank = comm.Get_rank()
6 | data = (rank+1)**2
7 |
8 | data = comm.gather(data, root=0)
9 | if rank == 0:
10 | print ("rank = %s " %rank +\
11 | "...receiving data to other process")
12 | for i in range(1,size):
13 |
14 | value = data[i]
15 | print(" process %s receiving %s from process %s"\
16 | %(rank , value , i))
17 |
18 |
--------------------------------------------------------------------------------
/Chapter04/helloworld_MPI.py:
--------------------------------------------------------------------------------
1 | #hello.py
2 | from mpi4py import MPI
3 | comm = MPI.COMM_WORLD
4 | rank = comm.Get_rank()
5 | print ("hello world from process ", rank)
6 |
--------------------------------------------------------------------------------
/Chapter04/pointToPointCommunication.py:
--------------------------------------------------------------------------------
1 | from mpi4py import MPI
2 |
3 | comm=MPI.COMM_WORLD
4 | rank = comm.rank
5 | print("my rank is : " , rank)
6 |
7 | if rank==0:
8 | data= 10000000
9 | destination_process = 4
10 | comm.send(data,dest=destination_process)
11 | print ("sending data %s " %data +\
12 | "to process %d" %destination_process)
13 |
14 | if rank==1:
15 | destination_process = 8
16 | data= "hello"
17 | comm.send(data,dest=destination_process)
18 | print ("sending data %s :" %data + \
19 | "to process %d" %destination_process)
20 |
21 |
22 | if rank==4:
23 | data=comm.recv(source=0)
24 | print ("data received is = %s" %data)
25 |
26 |
27 | if rank==8:
28 | data1=comm.recv(source=1)
29 | print ("data1 received is = %s" %data1)
30 |
--------------------------------------------------------------------------------
/Chapter04/reduction.py:
--------------------------------------------------------------------------------
1 | import numpy
2 | from mpi4py import MPI
3 | comm = MPI.COMM_WORLD
4 | size = comm.size
5 | rank = comm.rank
6 |
7 |
8 | array_size = 10
9 | recvdata = numpy.zeros(array_size,dtype=numpy.int)
10 | senddata = (rank+1)*numpy.arange(array_size,dtype=numpy.int)
11 |
12 | print(" process %s sending %s " %(rank , senddata))
13 |
14 |
15 | comm.Reduce(senddata,recvdata,root=0,op=MPI.SUM)
16 | print ('on task',rank,'after Reduce: data = ',recvdata)
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Chapter04/scatter.py:
--------------------------------------------------------------------------------
1 | from mpi4py import MPI
2 |
3 | comm = MPI.COMM_WORLD
4 | rank = comm.Get_rank()
5 |
6 | if rank == 0:
7 | array_to_share = [1, 2, 3, 4 ,5 ,6 ,7, 8 ,9 ,10]
8 |
9 | else:
10 | array_to_share = None
11 |
12 | recvbuf = comm.scatter(array_to_share, root=0)
13 | print("process = %d" % rank + " variable shared = %d " % recvbuf )
14 |
--------------------------------------------------------------------------------
/Chapter04/virtualTopology.py:
--------------------------------------------------------------------------------
1 | from mpi4py import MPI
2 | import numpy as np
3 |
4 | UP = 0
5 | DOWN = 1
6 | LEFT = 2
7 | RIGHT = 3
8 | neighbour_processes = [0,0,0,0]
9 | if __name__ == "__main__":
10 | comm = MPI.COMM_WORLD
11 | rank = comm.rank
12 | size = comm.size
13 |
14 | grid_row = int(np.floor(np.sqrt(comm.size)))
15 | grid_column = comm.size // grid_row
16 |
17 |
18 | if grid_row*grid_column > size:
19 | grid_column -= 1
20 | if grid_row*grid_column > size:
21 | grid_row -= 1
22 |
23 | if (rank == 0) :
24 | print("Building a %d x %d grid topology:"\
25 | % (grid_row, grid_column) )
26 |
27 |
28 | cartesian_communicator = \
29 | comm.Create_cart( \
30 | (grid_row, grid_column), \
31 | periods=(True, True), reorder=True)
32 | my_mpi_row, my_mpi_col = \
33 | cartesian_communicator.Get_coords\
34 | ( cartesian_communicator.rank )
35 |
36 |
37 | neighbour_processes[UP], neighbour_processes[DOWN]\
38 | = cartesian_communicator.Shift(0, 1)
39 | neighbour_processes[LEFT], \
40 | neighbour_processes[RIGHT] = \
41 | cartesian_communicator.Shift(1, 1)
42 | print ("Process = %s \
43 | row = %s \
44 | column = %s \n----> \nneighbour_processes[UP] = %s\n\
45 | neighbour_processes[DOWN] = %s\n\
46 | neighbour_processes[LEFT] =%s\nneighbour_processes[RIGHT]=%s\n" \
47 | %(rank, my_mpi_row, \
48 | my_mpi_col,neighbour_processes[UP], \
49 | neighbour_processes[DOWN], \
50 | neighbour_processes[LEFT] , \
51 | neighbour_processes[RIGHT]))
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/Chapter05/asyncio_and_futures.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import sys
3 |
4 |
5 | @asyncio.coroutine
6 | def first_coroutine(future, num):
7 | count = 0
8 | for i in range(1, num + 1):
9 | count += 1
10 | yield from asyncio.sleep(4)
11 | future.set_result('First coroutine (sum of N ints) result = %s' % count)
12 |
13 |
14 | @asyncio.coroutine
15 | def second_coroutine(future, num):
16 | count = 1
17 | for i in range(2, num + 1):
18 | count *= i
19 | yield from asyncio.sleep(4)
20 | future.set_result('Second coroutine (factorial) result = %s' % count)
21 |
22 |
23 | def got_result(future):
24 | print(future.result())
25 |
26 | if __name__ == '__main__':
27 | num1 = int(sys.argv[1])
28 | num2 = int(sys.argv[2])
29 |
30 | loop = asyncio.get_event_loop()
31 | future1 = asyncio.Future()
32 | future2 = asyncio.Future()
33 |
34 | tasks = [first_coroutine(future1, num1),
35 | second_coroutine(future2, num2)]
36 |
37 | future1.add_done_callback(got_result)
38 | future2.add_done_callback(got_result)
39 |
40 | loop.run_until_complete(asyncio.wait(tasks))
41 | loop.close()
42 |
--------------------------------------------------------------------------------
/Chapter05/asyncio_coroutine.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import time
3 | from random import randint
4 |
5 |
6 | @asyncio.coroutine
7 | def start_state():
8 | print('Start State called\n')
9 | input_value = randint(0, 1)
10 | time.sleep(1)
11 |
12 | if input_value == 0:
13 | result = yield from state2(input_value)
14 | else:
15 | result = yield from state1(input_value)
16 |
17 | print('Resume of the Transition : \nStart State calling ' + result)
18 |
19 |
20 | @asyncio.coroutine
21 | def state1(transition_value):
22 | output_value = 'State 1 with transition value = %s\n' % transition_value
23 | input_value = randint(0, 1)
24 | time.sleep(1)
25 |
26 | print('...evaluating...')
27 | if input_value == 0:
28 | result = yield from state3(input_value)
29 | else:
30 | result = yield from state2(input_value)
31 |
32 | return output_value + 'State 1 calling %s' % result
33 |
34 |
35 | @asyncio.coroutine
36 | def state2(transition_value):
37 | output_value = 'State 2 with transition value = %s\n' % transition_value
38 | input_value = randint(0, 1)
39 | time.sleep(1)
40 |
41 | print('...evaluating...')
42 | if input_value == 0:
43 | result = yield from state1(input_value)
44 | else:
45 | result = yield from state3(input_value)
46 |
47 | return output_value + 'State 2 calling %s' % result
48 |
49 |
50 | @asyncio.coroutine
51 | def state3(transition_value):
52 | output_value = 'State 3 with transition value = %s\n' % transition_value
53 | input_value = randint(0, 1)
54 | time.sleep(1)
55 |
56 | print('...evaluating...')
57 | if input_value == 0:
58 | result = yield from state1(input_value)
59 | else:
60 | result = yield from end_state(input_value)
61 |
62 | return output_value + 'State 3 calling %s' % result
63 |
64 |
65 | @asyncio.coroutine
66 | def end_state(transition_value):
67 | output_value = 'End State with transition value = %s\n' % transition_value
68 | print('...stop computation...')
69 | return output_value
70 |
71 |
72 | if __name__ == '__main__':
73 | print('Finite State Machine simulation with Asyncio Coroutine')
74 | loop = asyncio.get_event_loop()
75 | loop.run_until_complete(start_state())
76 |
--------------------------------------------------------------------------------
/Chapter05/asyncio_event_loop.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import time
3 | import random
4 |
5 | def task_A(end_time, loop):
6 | print ("task_A called")
7 | time.sleep(random.randint(0, 5))
8 | if (loop.time() + 1.0) < end_time:
9 | loop.call_later(1, task_B, end_time, loop)
10 | else:
11 | loop.stop()
12 |
13 | def task_B(end_time, loop):
14 | print ("task_B called ")
15 | time.sleep(random.randint(0, 5))
16 | if (loop.time() + 1.0) < end_time:
17 | loop.call_later(1, task_C, end_time, loop)
18 | else:
19 | loop.stop()
20 |
21 | def task_C(end_time, loop):
22 | print ("task_C called")
23 | time.sleep(random.randint(0, 5))
24 | if (loop.time() + 1.0) < end_time:
25 | loop.call_later(1, task_A, end_time, loop)
26 | else:
27 | loop.stop()
28 |
29 |
30 | loop = asyncio.get_event_loop()
31 | end_loop = loop.time() + 60
32 | loop.call_soon(task_A, end_loop, loop)
33 | loop.run_forever()
34 | loop.close()
35 |
36 |
--------------------------------------------------------------------------------
/Chapter05/asyncio_task_manipulation.py:
--------------------------------------------------------------------------------
1 | """Asyncio using Asyncio.Task to execute three math functions in parallel"""
2 |
3 | import asyncio
4 |
5 |
6 | @asyncio.coroutine
7 | def factorial(number):
8 | fact = 1
9 | for i in range(2, number + 1):
10 | print('Asyncio.Task: Compute factorial(%s)' % i)
11 | yield from asyncio.sleep(1)
12 | fact *= i
13 | print('Asyncio.Task - factorial(%s) = %s' % (number, fact))
14 |
15 |
16 | @asyncio.coroutine
17 | def fibonacci(number):
18 | a, b = 0, 1
19 | for i in range(number):
20 | print('Asyncio.Task: Compute fibonacci(%s)' % i)
21 | yield from asyncio.sleep(1)
22 | a, b = b, a + b
23 | print('Asyncio.Task - fibonacci(%s) = %s' % (number, a))
24 |
25 |
26 | @asyncio.coroutine
27 | def binomial_coefficient(n, k):
28 | result = 1
29 | for i in range(1, k + 1):
30 | result = result*(n - i + 1)/i
31 | print('Asyncio.Task: Compute binomial_coefficient(%s)' % i)
32 | yield from asyncio.sleep(1)
33 | print('Asyncio.Task - binomial_coefficient(%s, %s) = %s' % (n, k, result))
34 |
35 |
36 | if __name__ == '__main__':
37 | task_list = [asyncio.Task(factorial(10)),
38 | asyncio.Task(fibonacci(10)),
39 | asyncio.Task(binomial_coefficient(20, 10))]
40 | loop = asyncio.get_event_loop()
41 | loop.run_until_complete(asyncio.wait(task_list))
42 | loop.close()
43 |
--------------------------------------------------------------------------------
/Chapter05/concurrent_futures_pooling.py:
--------------------------------------------------------------------------------
1 | import concurrent.futures
2 | import time
3 |
4 | number_list = list(range(1, 11))
5 |
6 |
7 | def count(number):
8 | for i in range(0,10000000):
9 | i += 1
10 | return i*number
11 |
12 |
13 | def evaluate(item):
14 | result_item = count(item)
15 | print('Item %s, result %s' % (item, result_item))
16 |
17 | if __name__ == '__main__':
18 | # Sequential Execution
19 | start_time = time.clock()
20 | for item in number_list:
21 | evaluate(item)
22 | print('Sequential Execution in %s seconds' % (time.clock() - start_time))
23 |
24 |
25 | # Thread Pool Execution
26 | start_time = time.clock()
27 | with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
28 | for item in number_list:
29 | executor.submit(evaluate, item)
30 | print('Thread Pool Execution in %s seconds' % (time.clock() - start_time))
31 |
32 |
33 | # Process Pool Execution
34 | start_time = time.clock()
35 | with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
36 | for item in number_list:
37 | executor.submit(evaluate, item)
38 | print('Process Pool Execution in %s seconds' % (time.clock() - start_time))
39 |
--------------------------------------------------------------------------------
/Chapter06/Celery/addTask.py:
--------------------------------------------------------------------------------
1 | ###
2 | ## addTask.py :Executing a simple task
3 | ###
4 |
5 | from celery import Celery
6 |
7 | app = Celery('addTask',broker='amqp://guest@localhost//')
8 |
9 | @app.task
10 | def add(x, y):
11 | return x + y
12 |
13 |
--------------------------------------------------------------------------------
/Chapter06/Celery/addTask_main.py:
--------------------------------------------------------------------------------
1 | ###
2 | #addTask.py : RUN the AddTask example with
3 | ###
4 |
5 | import addTask
6 |
7 | if __name__ == '__main__':
8 | result = addTask.add.delay(5,5)
9 |
10 |
--------------------------------------------------------------------------------
/Chapter06/Pyro4/First Example/pyro_client.py:
--------------------------------------------------------------------------------
1 | import Pyro4
2 |
3 | #uri = input("insert the PYRO4 server URI (help : PYRONAME:server) ").strip()
4 | name = input("What is your name? ").strip()
5 | # use name server object lookup uri shortcut
6 | server = Pyro4.Proxy("PYRONAME:server")
7 | print(server.welcomeMessage(name))
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Chapter06/Pyro4/First Example/pyro_server.py:
--------------------------------------------------------------------------------
1 | import Pyro4
2 |
3 | class Server(object):
4 | @Pyro4.expose
5 | def welcomeMessage(self, name):
6 | return ("Hi welcome " + str (name))
7 |
8 | def startServer():
9 | server = Server()
10 | # make a Pyro daemon
11 | daemon = Pyro4.Daemon()
12 | # locate the name server running
13 | ns = Pyro4.locateNS()
14 | # register the server as a Pyro object
15 | uri = daemon.register(server)
16 | # register the object with a name in the name server
17 | ns.register("server", uri)
18 | # print the uri so we can use it in the client later
19 | print("Ready. Object uri =", uri)
20 | # start the event loop of the server to wait for calls
21 | daemon.requestLoop()
22 |
23 | if __name__ == "__main__":
24 | startServer()
25 |
26 |
--------------------------------------------------------------------------------
/Chapter06/Pyro4/Second Example/__pycache__/chainTopology.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Python-Parallel-Programming-Cookbook-Second-Edition/a10f0b2ba69995a6a8697e68ae0b53a20f4c04c7/Chapter06/Pyro4/Second Example/__pycache__/chainTopology.cpython-35.pyc
--------------------------------------------------------------------------------
/Chapter06/Pyro4/Second Example/chainTopology.py:
--------------------------------------------------------------------------------
1 | import Pyro4
2 |
3 | @Pyro4.expose
4 | class Chain(object):
5 | def __init__(self, name, current_server):
6 | self.name = name
7 | self.current_serverName = current_server
8 | self.current_server = None
9 |
10 | def process(self, message):
11 | if self.current_server is None:
12 | self.current_server = Pyro4.core.Proxy("PYRONAME:example.chainTopology." + self.current_serverName)
13 | if self.name in message:
14 | print("Back at %s; the chain is closed!" % self.name)
15 | return ["complete at " + self.name]
16 | else:
17 | print("%s forwarding the message to the object %s" % (self.name, self.current_serverName))
18 | message.append(self.name)
19 | result = self.current_server.process(message)
20 | result.insert(0, "passed on from " + self.name)
21 | return result
22 |
--------------------------------------------------------------------------------
/Chapter06/Pyro4/Second Example/client_chain.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | import Pyro4
3 |
4 | obj = Pyro4.core.Proxy("PYRONAME:example.chainTopology.1")
5 | print("Result=%s" % obj.process(["hello"]))
6 |
--------------------------------------------------------------------------------
/Chapter06/Pyro4/Second Example/desktop.ini:
--------------------------------------------------------------------------------
1 | [LocalizedFileNames]
2 | Command Prompt.lnk=@%SystemRoot%\system32\shell32.dll,-22022
3 |
--------------------------------------------------------------------------------
/Chapter06/Pyro4/Second Example/server_chain_1.py:
--------------------------------------------------------------------------------
1 | import Pyro4
2 | import chainTopology
3 |
4 | current_server = "1"
5 | next_server = "2"
6 |
7 | servername = "example.chainTopology." + current_server
8 |
9 | daemon = Pyro4.core.Daemon()
10 | obj = chainTopology.Chain(current_server, next_server)
11 | uri = daemon.register(obj)
12 | ns = Pyro4.locateNS()
13 | ns.register(servername, uri)
14 |
15 | # enter the service loop.
16 |
17 | print("server_%s started " % current_server)
18 | daemon.requestLoop()
19 |
--------------------------------------------------------------------------------
/Chapter06/Pyro4/Second Example/server_chain_2.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | import Pyro4
3 | import chainTopology
4 |
5 | current_server = "2"
6 | next_server = "3"
7 |
8 | servername = "example.chainTopology." + current_server
9 |
10 | daemon = Pyro4.core.Daemon()
11 | obj = chainTopology.Chain(current_server,next_server)
12 | uri = daemon.register(obj)
13 | ns = Pyro4.locateNS()
14 | ns.register(servername, uri)
15 |
16 | # enter the service loop.
17 | print("server_%s started " % current_server)
18 | daemon.requestLoop()
19 |
--------------------------------------------------------------------------------
/Chapter06/Pyro4/Second Example/server_chain_3.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function
2 | import Pyro4
3 | import chainTopology
4 |
5 | current_server = "3"
6 | next_server = "1"
7 |
8 | servername = "example.chainTopology." + current_server
9 |
10 | daemon = Pyro4.core.Daemon()
11 | obj = chainTopology.Chain(current_server, next_server)
12 | uri = daemon.register(obj)
13 | ns = Pyro4.locateNS()
14 | ns.register(servername, uri)
15 |
16 | # enter the service loop.
17 | print("server_%s started " % current_server)
18 | daemon.requestLoop()
19 |
--------------------------------------------------------------------------------
/Chapter06/socket/addTask.py:
--------------------------------------------------------------------------------
1 | from celery import Celery
2 |
3 | app = Celery('tasks', broker='pyamqp://guest@localhost//')
4 |
5 | @app.task
6 | def add(x, y):
7 | return x + y
8 |
--------------------------------------------------------------------------------
/Chapter06/socket/addTask_main.py:
--------------------------------------------------------------------------------
1 | from addTask import add
2 |
3 |
4 | if __name__ == '__main__':
5 | add.delay(5, 5)
6 |
7 |
--------------------------------------------------------------------------------
/Chapter06/socket/client.py:
--------------------------------------------------------------------------------
1 | # client .py
2 | import socket
3 |
4 | # create a socket object
5 | s =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
6 | # get local machine name
7 | host=socket.gethostname()
8 | port=9999
9 | # connection to hostname on the port .
10 | s.connect((host,port))
11 | # Receive no more than 1024 bytes
12 | tm=s.recv(1024)
13 | s.close()
14 | print ("Time connection server:%s"%tm.decode('ascii'))
15 |
--------------------------------------------------------------------------------
/Chapter06/socket/client2.py:
--------------------------------------------------------------------------------
1 | import socket
2 | s =socket.socket()
3 | host=socket.gethostname()
4 | port=60000
5 | s.connect((host,port))
6 | s.send('HelloServer!'.encode())
7 | with open('received.txt','wb') as f:
8 | print ('file opened')
9 | while True :
10 | print ('receiving data...')
11 | data=s.recv(1024)
12 | if not data:
13 | break
14 | print ('Data=>',data.decode())
15 | # write data to a file
16 | f.write(data)
17 | f.close()
18 | print ('Successfully get the file')
19 | s.close()
20 | print ('connection closed')
21 |
--------------------------------------------------------------------------------
/Chapter06/socket/mytext.txt:
--------------------------------------------------------------------------------
1 | hello!!!
--------------------------------------------------------------------------------
/Chapter06/socket/received.txt:
--------------------------------------------------------------------------------
1 | hello!!!->Thankyouforconnecting
--------------------------------------------------------------------------------
/Chapter06/socket/server.py:
--------------------------------------------------------------------------------
1 | # server .py
2 | import socket
3 | import time
4 |
5 | # create a socket object
6 | serversocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
7 | # get local machine name
8 | host=socket.gethostname()
9 | port=9999
10 | # bind to the port
11 | serversocket.bind((host,port))
12 | # queue up to 5 requests
13 | serversocket.listen(5)
14 | # establish a connection
15 | while True:
16 | clientsocket,addr=serversocket.accept()
17 | print ("Connected with[addr],[port]%s"%str(addr))
18 | currentTime=time.ctime(time.time())+"\r\n"
19 | clientsocket.send(currentTime.encode('ascii'))
20 | clientsocket.close()
21 |
--------------------------------------------------------------------------------
/Chapter06/socket/server2.py:
--------------------------------------------------------------------------------
1 | # server .py
2 |
3 | import socket
4 | port=60000
5 | s =socket.socket()
6 | host=socket.gethostname()
7 | s.bind((host,port))
8 | s.listen(15)
9 | print('Server listening....')
10 | while True :
11 | conn,addr=s.accept()
12 | print ('Got connection from',addr)
13 | data=conn.recv(1024)
14 | print ('Server received',repr(data.decode()))
15 | filename='mytext.txt'
16 | f =open(filename,'rb')
17 | l =f.read(1024)
18 | while (l):
19 | conn.send(l)
20 | print ('Sent',repr(l.decode()))
21 | l =f.read(1024)
22 | f.close()
23 | print ('Donesending')
24 | conn.send('->Thank you for connecting'.encode())
25 | conn.close()
26 |
--------------------------------------------------------------------------------
/Chapter07/codes/how to containerize a Python application/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:alpine3.7
2 | COPY . /app
3 | WORKDIR /app
4 | RUN pip install -r requirements.txt
5 | EXPOSE 5000
6 | CMD python ./dockerize.py
--------------------------------------------------------------------------------
/Chapter07/codes/how to containerize a Python application/dockerize.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | from flask import Flask
4 | app = Flask(__name__)
5 | @app.route("/")
6 | def hello():
7 | return "Hello World!"
8 | if __name__ == "__main__":
9 | app.run(host="0.0.0.0", port=int("5000"), debug=True)
--------------------------------------------------------------------------------
/Chapter07/codes/how to containerize a Python application/requirements.txt:
--------------------------------------------------------------------------------
1 | flask
--------------------------------------------------------------------------------
/Chapter08/Numba/matMulNumba.py:
--------------------------------------------------------------------------------
1 | from numba import guvectorize
2 | import numpy as np
3 |
4 | @guvectorize(['void(int64[:,:], int64[:,:], int64[:,:])'],
5 | '(m,n),(n,p)->(m,p)')
6 | def matmul(A, B, C):
7 | m, n = A.shape
8 | n, p = B.shape
9 | for i in range(m):
10 | for j in range(p):
11 | C[i, j] = 0
12 | for k in range(n):
13 | C[i, j] += A[i, k] * B[k, j]
14 |
15 | dim = 10
16 | A = np.random.randint(dim,size=(dim, dim))
17 | B = np.random.randint(dim,size=(dim, dim))
18 |
19 |
20 | C = matmul(A, B)
21 | print("INPUT MATRIX A")
22 | print(":\n%s" % A)
23 | print("INPUT MATRIX B")
24 | print(":\n%s" % B)
25 | print("RESULT MATRIX C = A*B")
26 | print(":\n%s" % C)
27 |
--------------------------------------------------------------------------------
/Chapter08/Numba/numba_cuda_detection.py:
--------------------------------------------------------------------------------
1 | import numba.cuda.api
2 | import numba.cuda.cudadrv.libs
3 |
4 | numba.cuda.cudadrv.libs.test()
5 | numba.cuda.api.detect()
--------------------------------------------------------------------------------
/Chapter08/Numba/reduceNumba.py:
--------------------------------------------------------------------------------
1 | import numpy
2 | from numba import cuda
3 |
4 |
5 | A = (numpy.arange(10000, dtype=numpy.int64)) + 1
6 | print("vector to reduce = ", A)
7 |
8 | @cuda.reduce
9 | def sum_reduce(a, b):
10 | return a + b
11 |
12 | got = sum_reduce(A)
13 | print("result = " , got)
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Chapter08/PyCUDA/dealingWithPycuda.py:
--------------------------------------------------------------------------------
1 | import pycuda.driver as drv
2 | drv.init()
3 | print ("%d device(s) found." % drv.Device.count())
4 | for ordinal in range(drv.Device.count()):
5 | dev = drv.Device(ordinal)
6 | print ("Device #%d: %s" % (ordinal, dev.name()))
7 | print (" Compute Capability: %d.%d" % dev.compute_capability())
8 | print (" Total Memory: %s KB" % (dev.total_memory()//(1024)))
9 |
10 |
--------------------------------------------------------------------------------
/Chapter08/PyCUDA/heterogenousPycuda.py:
--------------------------------------------------------------------------------
1 | import pycuda.driver as cuda
2 | import pycuda.autoinit
3 | from pycuda.compiler import SourceModule
4 |
5 | import numpy
6 |
7 | a = numpy.random.randn(5,5)
8 | a = a.astype(numpy.float32)
9 |
10 | a_gpu = cuda.mem_alloc(a.nbytes)
11 | cuda.memcpy_htod(a_gpu, a)
12 |
13 | mod = SourceModule("""
14 | __global__ void doubles_matrix(float *a)
15 | {
16 | int idx = threadIdx.x + threadIdx.y*4;
17 | a[idx] *= 2;
18 | }
19 | """)
20 |
21 | func = mod.get_function("doubles_matrix")
22 | func(a_gpu, block=(5,5,1))
23 |
24 | a_doubled = numpy.empty_like(a)
25 | cuda.memcpy_dtoh(a_doubled, a_gpu)
26 | print ("ORIGINAL MATRIX")
27 | print (a)
28 | print ("DOUBLED MATRIX AFTER PyCUDA EXECUTION")
29 | print (a_doubled)
30 |
31 |
--------------------------------------------------------------------------------
/Chapter08/PyCUDA/memManagementPycuda.py:
--------------------------------------------------------------------------------
1 | import pycuda.driver as CUDA
2 | import pycuda.autoinit
3 | from pycuda.compiler import SourceModule
4 | import numpy as np
5 | from pycuda import driver, compiler, gpuarray, tools
6 |
7 | kernel_code_template = """
8 | __global__ void MatrixMulKernel(float *a, float *b, float *c)
9 | {
10 | int tx = threadIdx.x;
11 | int ty = threadIdx.y;
12 | float Pvalue = 0;
13 | for (int k = 0; k < %(MATRIX_SIZE)s; ++k) {
14 | float Aelement = a[ty * %(MATRIX_SIZE)s + k];
15 | float Belement = b[k * %(MATRIX_SIZE)s + tx];
16 | Pvalue += Aelement * Belement;
17 | }
18 |
19 | c[ty * %(MATRIX_SIZE)s + tx] = Pvalue;
20 | }
21 | """
22 |
23 | MATRIX_SIZE = 5
24 |
25 | a_cpu = np.random.randn(MATRIX_SIZE, MATRIX_SIZE).astype(np.float32)
26 | b_cpu = np.random.randn(MATRIX_SIZE, MATRIX_SIZE).astype(np.float32)
27 |
28 | c_cpu = np.dot(a_cpu, b_cpu)
29 |
30 | a_gpu = gpuarray.to_gpu(a_cpu)
31 | b_gpu = gpuarray.to_gpu(b_cpu)
32 |
33 | c_gpu = gpuarray.empty((MATRIX_SIZE, MATRIX_SIZE), np.float32)
34 |
35 | kernel_code = kernel_code_template % {
36 | 'MATRIX_SIZE': MATRIX_SIZE
37 | }
38 |
39 | mod = compiler.SourceModule(kernel_code)
40 |
41 | matrixmul = mod.get_function("MatrixMulKernel")
42 |
43 | matrixmul(
44 | a_gpu, b_gpu,
45 | c_gpu,
46 | block = (MATRIX_SIZE, MATRIX_SIZE, 1),
47 | )
48 |
49 | # print the results
50 | print ("-" * 80)
51 | print ("Matrix A (GPU):")
52 | print (a_gpu.get())
53 |
54 | print ("-" * 80)
55 | print ("Matrix B (GPU):")
56 | print (b_gpu.get())
57 |
58 | print ("-" * 80)
59 | print ("Matrix C (GPU):")
60 | print (c_gpu.get())
61 |
62 | print ("-" * 80)
63 | print ("CPU-GPU difference:")
64 | print (c_cpu - c_gpu.get())
65 |
66 | np.allclose(c_cpu, c_gpu.get())
67 |
68 |
--------------------------------------------------------------------------------
/Chapter08/PyOpenCL/__pycache__/deviceInfoPyopencl.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Python-Parallel-Programming-Cookbook-Second-Edition/a10f0b2ba69995a6a8697e68ae0b53a20f4c04c7/Chapter08/PyOpenCL/__pycache__/deviceInfoPyopencl.cpython-37.pyc
--------------------------------------------------------------------------------
/Chapter08/PyOpenCL/deviceInfoPyopencl.py:
--------------------------------------------------------------------------------
1 | import pyopencl as cl
2 |
3 |
4 | def print_device_info() :
5 | print('\n' + '=' * 60 + '\nOpenCL Platforms and Devices')
6 | for platform in cl.get_platforms():
7 | print('=' * 60)
8 | print('Platform - Name: ' + platform.name)
9 | print('Platform - Vendor: ' + platform.vendor)
10 | print('Platform - Version: ' + platform.version)
11 | print('Platform - Profile: ' + platform.profile)
12 |
13 | for device in platform.get_devices():
14 | print(' ' + '-' * 56)
15 | print(' Device - Name: ' \
16 | + device.name)
17 | print(' Device - Type: ' \
18 | + cl.device_type.to_string(device.type))
19 | print(' Device - Max Clock Speed: {0} Mhz'\
20 | .format(device.max_clock_frequency))
21 | print(' Device - Compute Units: {0}'\
22 | .format(device.max_compute_units))
23 | print(' Device - Local Memory: {0:.0f} KB'\
24 | .format(device.local_mem_size/1024.0))
25 | print(' Device - Constant Memory: {0:.0f} KB'\
26 | .format(device.max_constant_buffer_size/1024.0))
27 | print(' Device - Global Memory: {0:.0f} GB'\
28 | .format(device.global_mem_size/1073741824.0))
29 | print(' Device - Max Buffer/Image Size: {0:.0f} MB'\
30 | .format(device.max_mem_alloc_size/1048576.0))
31 | print(' Device - Max Work Group Size: {0:.0f}'\
32 | .format(device.max_work_group_size))
33 | print('\n')
34 |
35 | if __name__ == "__main__":
36 | print_device_info()
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Chapter08/PyOpenCL/elementwisePyopencl.py:
--------------------------------------------------------------------------------
1 | import pyopencl as cl
2 | import pyopencl.array as cl_array
3 | import numpy as np
4 |
5 | context = cl.create_some_context() # Initialize the Context
6 | queue = cl.CommandQueue(context) # Instantiate a Queue
7 |
8 | vector_dimension = 100
9 | vector_a = cl_array.to_device(queue, np.random.randint(vector_dimension, size=vector_dimension))
10 | vector_b = cl_array.to_device(queue, np.random.randint(vector_dimension, size=vector_dimension))
11 | result_vector = cl_array.empty_like(vector_a)
12 |
13 | elementwiseSum = cl.elementwise.ElementwiseKernel(context, "int *a, int *b, int *c", "c[i] = a[i] + b[i]", "sum")
14 | elementwiseSum(vector_a, vector_b, result_vector)
15 |
16 | print ("PyOpenCL ELEMENTWISE SUM OF TWO VECTORS")
17 | print ("VECTOR LENGTH = %s" %vector_dimension)
18 | print ("INPUT VECTOR A")
19 | print (vector_a)
20 | print ("INPUT VECTOR B")
21 | print (vector_b)
22 | print ("OUTPUT VECTOR RESULT A + B ")
23 | print (result_vector)
24 |
--------------------------------------------------------------------------------
/Chapter08/PyOpenCL/testApplicationPyopencl.py:
--------------------------------------------------------------------------------
1 | from time import time # Import time tools
2 |
3 | import pyopencl as cl
4 | import numpy as np
5 | import deviceInfoPyopencl as device_info
6 | import numpy.linalg as la
7 |
8 | #input vectors
9 | a = np.random.rand(10000).astype(np.float32)
10 | b = np.random.rand(10000).astype(np.float32)
11 |
12 | def test_cpu_vector_sum(a, b):
13 | c_cpu = np.empty_like(a)
14 | cpu_start_time = time()
15 | for i in range(10000):
16 | for j in range(10000):
17 | c_cpu[i] = a[i] + b[i]
18 | cpu_end_time = time()
19 | print("CPU Time: {0} s".format(cpu_end_time - cpu_start_time))
20 | return c_cpu
21 |
22 | def test_gpu_vector_sum(a, b):
23 | #define the PyOpenCL Context
24 | platform = cl.get_platforms()[0]
25 | device = platform.get_devices()[0]
26 | context = cl.Context([device])
27 | queue = cl.CommandQueue(context, \
28 | properties=cl.command_queue_properties.PROFILING_ENABLE)
29 | #prepare the data structure
30 | a_buffer = cl.Buffer\
31 | (context, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=a)
32 | b_buffer = cl.Buffer\
33 | (context, cl.mem_flags.READ_ONLY | cl.mem_flags.COPY_HOST_PTR, hostbuf=b)
34 | c_buffer = cl.Buffer\
35 | (context, cl.mem_flags.WRITE_ONLY, b.nbytes)
36 | program = cl.Program(context, """
37 | __kernel void sum(__global const float *a, __global const float *b, __global float *c)
38 | {
39 | int i = get_global_id(0);
40 | int j;
41 | for(j = 0; j < 10000; j++)
42 | {
43 | c[i] = a[i] + b[i];
44 | }
45 | }""").build()
46 | #start the gpu test
47 | gpu_start_time = time()
48 | event = program.sum(queue, a.shape, None, a_buffer, b_buffer, c_buffer)
49 | event.wait()
50 | elapsed = 1e-9*(event.profile.end - event.profile.start)
51 | print("GPU Kernel evaluation Time: {0} s".format(elapsed))
52 | c_gpu = np.empty_like(a)
53 | cl._enqueue_read_buffer(queue, c_buffer, c_gpu).wait()
54 | gpu_end_time = time()
55 | print("GPU Time: {0} s".format(gpu_end_time - gpu_start_time))
56 | return c_gpu
57 |
58 | #start the test
59 | if __name__ == "__main__":
60 | #print the device info
61 | device_info.print_device_info()
62 | #call the test on the cpu
63 | cpu_result = test_cpu_vector_sum(a, b)
64 | #call the test on the gpu
65 | gpu_result = test_gpu_vector_sum(a, b)
66 | assert (la.norm(cpu_result - gpu_result)) < 1e-5
67 |
68 |
--------------------------------------------------------------------------------
/Chapter08/PyOpenCL/vectorSumPyopencl.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import pyopencl as cl
3 | import numpy.linalg as la
4 |
5 | vector_dimension = 100
6 |
7 | vector_a = np.random.randint(vector_dimension, size=vector_dimension)
8 | vector_b = np.random.randint(vector_dimension, size=vector_dimension)
9 |
10 | platform = cl.get_platforms()[0]
11 | device = platform.get_devices()[0]
12 | context = cl.Context([device])
13 | queue = cl.CommandQueue(context)
14 |
15 | mf = cl.mem_flags
16 | a_g = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=vector_a)
17 | b_g = cl.Buffer(context, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=vector_b)
18 |
19 |
20 | program = cl.Program(context, """
21 | __kernel void vectorSum(__global const int *a_g, __global const int *b_g, __global int *res_g) {
22 | int gid = get_global_id(0);
23 | res_g[gid] = a_g[gid] + b_g[gid];
24 | }
25 | """).build()
26 |
27 | res_g = cl.Buffer(context, mf.WRITE_ONLY, vector_a.nbytes)
28 |
29 | program.vectorSum(queue, vector_a.shape, None, a_g, b_g, res_g)
30 |
31 | res_np = np.empty_like(vector_a)
32 | cl.enqueue_copy(queue, res_np, res_g)
33 |
34 | print ("PyOPENCL SUM OF TWO VECTORS")
35 | print ("Platform Selected = %s" %platform.name )
36 | print ("Device Selected = %s" %device.name)
37 | print ("VECTOR LENGTH = %s" %vector_dimension)
38 | print ("INPUT VECTOR A")
39 | print (vector_a)
40 | print ("INPUT VECTOR B")
41 | print (vector_b)
42 | print ("OUTPUT VECTOR RESULT A + B ")
43 | print (res_np)
44 |
45 | assert(la.norm(res_np - (vector_a + vector_b))) < 1e-5
46 |
47 |
48 |
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/__pycache__/testset.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Python-Parallel-Programming-Cookbook-Second-Edition/a10f0b2ba69995a6a8697e68ae0b53a20f4c04c7/Chapter09/codes chapter 9 debug and test/__pycache__/testset.cpython-36.pyc
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/__pycache__/testset1.cpython-36.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Python-Parallel-Programming-Cookbook-Second-Edition/a10f0b2ba69995a6a8697e68ae0b53a20f4c04c7/Chapter09/codes chapter 9 debug and test/__pycache__/testset1.cpython-36.pyc
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/nosetest.py:
--------------------------------------------------------------------------------
1 | from math import *
2 | import nose
3 |
4 |
5 | def add(num1, num2):
6 | assert type(num1) == int or type(num1) == float
7 | assert type(num2) == int or type(num2) == float
8 | return num1 + num2
9 |
10 | def divide(numerator, denominator):
11 | return numerator / denominator
12 |
13 | def test_add_integers():
14 | assert add(5, 3) == 8
15 |
16 | def test_add_integers_zero():
17 | assert add(3, 0) == 3
18 |
19 | def test_add_floats():
20 | assert add(1.5, 2.5) == 4
21 |
22 | def test_add_strings():
23 | nose.tools.assert_raises(AssertionError, add, 'paul', 'carol')
24 |
25 | def test_divide_integers_even():
26 | assert divide(2, 10) == 0.2
27 |
28 | def test_divide_integers_repetant():
29 | nose.tools.assert_almost_equal(divide(1, 3), 0.33333333, 7)
30 |
31 | if __name__ == '__main__':
32 | nose.run()
33 |
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/pdb/__pycache__/pdb_test.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PacktPublishing/Python-Parallel-Programming-Cookbook-Second-Edition/a10f0b2ba69995a6a8697e68ae0b53a20f4c04c7/Chapter09/codes chapter 9 debug and test/pdb/__pycache__/pdb_test.cpython-35.pyc
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/pdb/inside_code_to_debug_pdb.py:
--------------------------------------------------------------------------------
1 | import pdb
2 |
3 | class Pdb_test(object):
4 |
5 | def __init__(self, parameter):
6 | self.counter = parameter
7 |
8 | def go(self):
9 | for j in range(self.counter):
10 | pdb.set_trace()
11 | print ("--->",j)
12 | return
13 |
14 | if __name__ == '__main__':
15 | Pdb_test(10).go()
16 |
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/pdb/pdb_test.py:
--------------------------------------------------------------------------------
1 | class Pdb_test(object):
2 | def __init__(self, parameter):
3 | self.counter = parameter
4 |
5 | def go(self):
6 | for j in range(self.counter):
7 | print ("--->",j)
8 | return
9 |
10 | if __name__ == '__main__':
11 | Pdb_test(10).go()
12 |
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/pdb/postmortem.py:
--------------------------------------------------------------------------------
1 | import pdb
2 | pdb.pm()
3 |
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/pdb/unittest_fail.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | class OutcomesTest(unittest.TestCase):
4 | def testPass(self):
5 | return
6 | def testFail(self):
7 | self.failIf(True)
8 | def testError(self):
9 | raise RuntimeError('test error!')
10 |
11 | if __name__ == '__main__':
12 | unittest.main()
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/pdb/using_python_interpreter_pdb.py:
--------------------------------------------------------------------------------
1 | import pdb_test
2 | import pdb
3 |
4 | pdb.run('pdb_test.Pdb_test(10).go()')
5 |
6 |
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/rpdb_code_example.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import rpdb
3 |
4 | #debugger = rpdb.Rpdb(port=4444)
5 | rpdb.Rpdb().set_trace()
6 |
7 | def my_func(thread_number):
8 | return print('my_func called by thread N°{}'.format(thread_number))
9 |
10 | def main():
11 | threads = []
12 | for i in range(10):
13 | t = threading.Thread(target=my_func, args=(i,))
14 | threads.append(t)
15 | t.start()
16 | t.join()
17 |
18 | if __name__ == "__main__":
19 |
20 | main()
21 |
22 |
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/simplicisticTest.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | class SimplisticTest(unittest.TestCase):
4 |
5 | def test(self):
6 | self.assertTrue(True)
7 |
8 | if __name__ == '__main__':
9 | unittest.main()
10 |
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/testset.py:
--------------------------------------------------------------------------------
1 | #testset.py
2 | from nose.tools import eq_
3 | import unittest
4 |
5 |
6 | class TestSuite:
7 | def test_mult(self):
8 | eq_(2*2,4)
9 |
10 | def ignored(self):
11 | eq_(2*2,3)
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/testset1.py:
--------------------------------------------------------------------------------
1 | #testset.py
2 | from nose.tools import eq_
3 | import unittest
4 |
5 |
6 | def test_sum():
7 | eq_(2+2,4)
8 |
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/unittest_exception.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | def raises_error(*args, **kwds):
4 | print (args, kwds)
5 | raise ValueError\
6 | ('Valore non valido:'+ str(args)+ str(kwds))
7 |
8 | class ExceptionTest(unittest.TestCase):
9 | def testTrapLocally(self):
10 | try:
11 | raises_error('a', b='c')
12 | except ValueError:
13 | pass
14 | else:
15 | self.fail('Non si vede ValueError')
16 |
17 | def testFailUnlessRaises(self):
18 | self.assertRaises\
19 | (ValueError, raises_error, 'a', b='c')
20 |
21 | if __name__ == '__main__':
22 | unittest.main()
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/unittest_truth.py:
--------------------------------------------------------------------------------
1 | import unittest
2 |
3 | class TruthTest(unittest.TestCase):
4 |
5 | def testFailUnless(self):
6 | self.failUnless(True)
7 | def testAssertTrue(self):
8 | self.assertTrue(True)
9 | def testFailIf(self):
10 | self.assertFalse(False)
11 | def testAssertFalse(self):
12 | self.assertFalse(False)
13 | if __name__ == '__main__':
14 | unittest.main()
--------------------------------------------------------------------------------
/Chapter09/codes chapter 9 debug and test/winpdb_reborn_code_example.py:
--------------------------------------------------------------------------------
1 | import time
2 | import os
3 | from random import randint
4 | from threading import Thread
5 |
6 | class MyThreadClass (Thread):
7 | def __init__(self, name, duration):
8 | Thread.__init__(self)
9 | self.name = name
10 | self.duration = duration
11 | def run(self):
12 | print ("---> " + self.name + \
13 | " running, belonging to process ID "\
14 | + str(os.getpid()) + "\n")
15 | time.sleep(self.duration)
16 | print ("---> " + self.name + " over\n")
17 |
18 |
19 | def main():
20 | start_time = time.time()
21 |
22 | # Thread Creation
23 | thread1 = MyThreadClass("Thread#1 ", randint(1,10))
24 | thread2 = MyThreadClass("Thread#2 ", randint(1,10))
25 | thread3 = MyThreadClass("Thread#3 ", randint(1,10))
26 |
27 | # Thread Running
28 | thread1.start()
29 | thread2.start()
30 | thread3.start()
31 |
32 | # Thread joining
33 | thread1.join()
34 | thread2.join()
35 | thread3.join()
36 |
37 | # End
38 | print("End")
39 |
40 | #Execution Time
41 | print("--- %s seconds ---" % (time.time() - start_time))
42 |
43 |
44 | if __name__ == "__main__":
45 | main()
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Packt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Python Parallel Programming Cookbook - Second Edition
2 |
3 |
4 |
5 | This is the code repository for [Python Parallel Programming Cookbook - Second Edition ](https://www.packtpub.com/programming/python-parallel-programming-cookbook?utm_source=github&utm_medium=repository&utm_campaign=9781789533736), published by Packt.
6 |
7 | **Over 70 recipes to solve challenges in multithreading and distributed system with Python 3**
8 |
9 | ## What is this book about?
10 | Nowadays, it has become extremely important for programmers to understand the link between the software and the parallel nature of their hardware so that their programs run efficiently on computer architectures. Applications based on parallel programming are fast, robust, and easily scalable.
11 |
12 |
13 | This book covers the following exciting features:
14 | * Synchronize multiple threads and processes to manage parallel tasks
15 | * Use message passing techniques to establish communication between processes to build parallel applications
16 | * Program your own GPU cards to address complex problems
17 | * Manage computing entities to execute distributed computational task
18 | * Write efficient programs by adopting the event-driven programming model
19 | * Explore cloud technology with Django and Google App Engine
20 | * Apply parallel programming techniques that can lead to performance improvements
21 |
22 | If you feel this book is for you, get your [copy](https://www.amazon.com/dp/1789533732) today!
23 |
24 |
26 |
27 | ## Instructions and Navigations
28 | All of the code is organized into folders. For example, Chapter02.
29 |
30 | The code will look like the following:
31 | ```
32 | class Pdb_test(object):
33 | def __init__(self, parameter):
34 | self.counter = parameter
35 | ```
36 |
37 | **Following is what you need for this book:**
38 | The Python Parallel Programming Cookbook is for software developers who are well-versed with Python and want to use parallel programming techniques to write powerful and efficient code. This book will help you master the basics and the advanced of parallel computing.
39 |
40 | With the following software and hardware list you can run all code files present in the book (Chapter 01-09).
41 | ### Software and Hardware List
42 | | No | Software required | OS required |
43 | | -------- | ------------------------------------ | ----------------------------------- |
44 | | 1 | Python 3.7 | Any |
45 |
46 |
47 | We also provide a PDF file that has color images of the screenshots/diagrams used in this book. [Click here to download it](https://static.packt-cdn.com/downloads/9781789533736_ColorImages.pdf).
48 |
49 | ### Related products
50 | * Mastering GUI Programming with Python [[Packt]](https://www.packtpub.com/in/application-development/mastering-gui-programming-python?utm_source=github&utm_medium=repository&utm_campaign=9781789612905) [[Amazon]](https://www.amazon.com/dp/178961290X)
51 |
52 | * Expert Python Programming - Third Edition [[Packt]](https://www.packtpub.com/in/application-development/expert-python-programming-third-edition?utm_source=github&utm_medium=repository&utm_campaign=9781789808896) [[Amazon]](https://www.amazon.com/dp/1789808898)
53 |
54 | ## Get to Know the Author
55 | **Giancarlo Zaccone**
56 | Giancarlo Zaccone has over fifteen years' experience of managing research projects in the scientific and industrial domains. He is a software and systems engineer at the European Space Agency (ESTEC), where he mainly deals with the cybersecurity of satellite navigation systems.
57 |
58 | Giancarlo holds a master's degree in physics and an advanced master's degree in scientific computing.
59 |
60 | Giancarlo has already authored the following titles, available from Packt: Python Parallel Programming Cookbook (First Edition), Getting Started with TensorFlow, Deep Learning with TensorFlow (First Edition), and Deep Learning with TensorFlow (Second Edition).
61 |
62 | ## Other books by the authors
63 | [Python Parallel Programming Cookbook ](https://www.packtpub.com/application-development/python-parallel-programming-cookbook?utm_source=github&utm_medium=repository&utm_campaign=9781785289583)
64 |
65 | ### Suggestions and Feedback
66 | [Click here](https://docs.google.com/forms/d/e/1FAIpQLSdy7dATC6QmEL81FIUuymZ0Wy9vH1jHkvpY57OiMeKGqib_Ow/viewform) if you have any feedback or suggestions.
67 |
68 |
--------------------------------------------------------------------------------