Commits

Anonymous committed 6c95473

parallel_article: codes for the article on parallel computing

  • Participants
  • Parent commits 97c54e0

Comments (0)

Files changed (25)

File parallel_article/README

+The source code in this directory are meant to be used as resources for the article 
+"Parallel Programming in C and Python" to be published in Linux Journal tentatively in May, 2012.
+(http://echorand.me/writings/)

File parallel_article/README~

+The source code in this directory are meant to be used as resources for the article 
+"C/C++ Scientific Programming Libraries and Tools" to be published in Linux Journal tentatively in May, 2012.
+(http://echorand.me/writings/)

File parallel_article/openmp/mp_for

Binary file added.

File parallel_article/openmp/omp_for_eval

Binary file added.

File parallel_article/openmp/omp_for_eval.c

+/*Listing 2: omp_for_eval.c*/
+/* Work Sharing construct
+https://computing.llnl.gov/tutorials/openMP/#DO
+
+Distributes an array of elements across threads, where each
+element is passed as a parameter to a function to be evaluated
+
+*/
+
+#include <omp.h>
+#include <stdio.h>
+#define N 100000
+#define CHUNKSIZE 100
+/* dummy function*/
+float myfun(float a)
+{
+  return a*a;
+}
+
+int main (int argc, char **argv)  
+{
+
+  int i, chunk,tid;
+  float a[N], b[N];
+
+  for (i=0; i < N; i++)
+    a[i] = i * 1.0;
+
+
+  /* Get the number of processors */
+  printf("Number of processors available:: %d\n",omp_get_num_procs());
+
+  /* Set the chunk size*/
+  chunk = CHUNKSIZE;
+
+  /* Set the number of threads to the number of processors*/
+  omp_set_num_threads(omp_get_num_procs());
+  
+#pragma omp parallel shared(a,b,chunk) private(i)
+  {
+    
+#pragma omp for schedule(dynamic,chunk)
+    for (i=0; i< N; i++)
+      {
+	b[i] = myfun(a[i]);
+      }
+  }  /* end of parallel section */
+
+  printf("For evaluation completed, the result has been stored in array B\n");
+
+  return 0;  
+}

File parallel_article/openmp/ompdemo

Binary file added.

File parallel_article/openmp/ompdemo.c

+/*Listing 1: ompdemo.c*/
+
+#include <stdio.h>
+#include <omp.h>
+
+int main (int argc, char **argv)  {
+
+  int nthreads, tid, i;
+
+  /* Get the number of processors */
+  printf("Number of processors available:: %d\n",omp_get_num_procs());
+
+  /* Set the number of threads to the number of processors*/
+  omp_set_num_threads(omp_get_num_procs());
+
+  /* Fork a team of threads with each thread having a private tid variable */
+#pragma omp parallel  private(tid) 
+  {
+    /* Obtain and print thread id */
+    tid = omp_get_thread_num();
+    printf("Hello World from thread = %d\n", tid);
+    
+    /* Only master thread does this */
+    if (tid == 0) 
+      {
+	nthreads = omp_get_num_threads();
+	printf("Number of threads = %d\n", nthreads);
+      }
+  }  /* All threads join master thread and terminate */
+
+  return 0;  
+}

File parallel_article/openmp/pi.c

+/* Program to compute Pi using Monte Carlo methods */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#define SEED 35791246
+
+main(int argc, char* argv)
+{
+  int niter=0;
+  double x,y;
+  int i,count=0; /* # of points in the 1st quadrant of unit circle */
+  double z;
+  double pi;
+
+  printf("Enter the number of iterations used to estimate pi: ");
+  scanf("%d",&niter);
+
+  /* initialize random numbers */
+  srand(SEED);
+  count=0;
+  for ( i=0; i<niter; i++) {
+    x = (double)rand()/RAND_MAX;
+    y = (double)rand()/RAND_MAX;
+    z = x*x+y*y;
+    if (z<=1) count++;
+  }
+  pi=(double)count/niter*4;
+  printf("# of trials= %d , estimate of pi is %g \n",niter,pi);
+}

File parallel_article/openmp/pi_openmp

Binary file added.

File parallel_article/openmp/pi_openmp.c

+/*Listing 3: pi_openmp.c*/
+
+/* Program to compute Pi using Monte Carlo method:
+(http://math.fullerton.edu/mathews/n2003/montecarlopimod.html)
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+/* Returns the value of count with niter iterations*/
+int part_count(int niter)
+{
+  int i, count=0;
+  float x,y,z;
+
+  for ( i=0; i<niter; i++) 
+    {
+      x = (double)rand()/RAND_MAX;
+      y = (double)rand()/RAND_MAX;
+      z = x*x+y*y;
+      if (z<=1) count++;
+    }
+
+  return count;
+}
+
+
+int main(int argc, char* argv)
+{
+  int niter=0,chunk;
+  double x,y;
+  int i,count=0; /* # of points in the 1st quadrant of unit circle */
+  double z;
+  double pi;
+
+  /* Get the number of processors */
+  printf("Number of processors available:: %d\n",omp_get_num_procs());
+
+  printf("Enter the number of iterations used to estimate pi (multiple of %d please): ",omp_get_num_procs());
+  scanf("%d",&niter);
+
+
+  /* Set the number of threads to the number of processors*/
+  omp_set_num_threads(omp_get_num_procs());
+  chunk = niter/omp_get_num_procs();
+  
+#pragma omp parallel shared(chunk) reduction(+:count)
+  {
+    count = part_count(chunk);
+  }    
+
+  pi=(double)count/niter*4;
+  printf("# of iterations = %d , estimate of pi is %g \n",niter,pi);
+
+  return 0;
+}

File parallel_article/picloud/demo.py

+import numpy 
+
+def sort_num(num): 
+    sort_num = numpy.sort(num) 
+    return sort_num

File parallel_article/picloud/demo.py~

Empty file added.

File parallel_article/picloud/mapdemo.py

+import numpy
+
+def vol_cylinder(r,h):
+    return numpy.pi*r*r*h

File parallel_article/picloud/mapdemo.py~

Empty file added.

File parallel_article/py_multiprocessing/mp_pool.py~

+''' listing xx: mp_queue.py
+Queue: http://docs.python.org/library/multiprocessing.html#pipes-and-queues
+
+Demonstrates the usage of Queue to share data between processes
+Spilts up a large array into chunks and calculates the partial
+dot products
+'''
+
+import multiprocessing
+from multiprocessing import Process, Queue
+from numpy import *
+
+# dot product of the partial data chunks
+def add(chunk1,chunk2,product):
+    a = chunk1.get()
+    b = chunk2.get()
+    
+    prod = a*b
+    product.put(sum(prod))
+
+if __name__ == '__main__':
+    a = Queue()
+    b = Queue()
+    product=Queue()
+
+    #size of the arrays
+    num_el = 100000
+
+    # Create two arrays
+    a = linspace(0,100,num_el);
+    b = linspace(0,1,num_el);
+
+    # get the number of CPU's
+    np = multiprocessing.cpu_count()
+    print 'You have {0:1d} CPUs'.format(np)
+
+    # chunk size
+    if num_el%np != 0:
+        print "The current chunking mechanism will not work"
+        exit
+    else:
+        chunk = num_el/np
+
+    # Create the processes
+    p_list=[]
+    for i in range(1,np+1):
+
+        # A pair of queues per process for the two arrays
+        aq = Queue()
+        bq = Queue()
+
+        # push the chunks into the queue
+        aq.put(a[(i-1)*chunk:i*chunk])
+        bq.put(b[(i-1)*chunk:i*chunk])
+
+        # create the process
+        p = Process(target=add, args=(aq,bq,product,))
+        p.start()
+        p.join()
+ 
+    # collect the individual sums
+    items=[]
+    for i in range(product.qsize()):
+        items.append(product.get())
+    
+    # final product: sum of individual products
+    print "Dot product:: ",sum(items)

File parallel_article/py_multiprocessing/mp_queue.py

+''' listing 5: mp_queue.py
+Queue: http://docs.python.org/library/multiprocessing.html#pipes-and-queues
+
+Demonstrates the usage of Queue to share data between processes
+Spilts up a large array into chunks and calculates the partial
+dot products
+'''
+
+import multiprocessing
+from multiprocessing import Process, Queue
+from numpy import *
+
+# dot product of the partial data chunks
+def add(chunk1,chunk2,product):
+    a = chunk1.get()
+    b = chunk2.get()
+    
+    prod = a*b
+    product.put(sum(prod))
+
+if __name__ == '__main__':
+
+    #size of the arrays
+    num_el = 100000
+
+    # Create two arrays
+    a = linspace(0,100,num_el);
+    b = linspace(0,1,num_el);
+
+    # get the number of CPU's and assign it as the number of
+    # processes to create
+    np = multiprocessing.cpu_count()
+    print 'You have {0:1d} CPUs'.format(np)
+
+    # chunk size
+    if num_el%np != 0:
+        print "The current chunking mechanism will not work"
+        exit
+    else:
+        chunk = num_el/np
+
+    # Create the processes
+    p_list=[]
+
+    # Create the Queue which will have the partial products
+    product=Queue()
+
+    for i in range(1,np+1):
+
+        # A pair of queues per process for the two arrays
+        aq = Queue()
+        bq = Queue()
+
+        # push the chunks into the queue
+        aq.put(a[(i-1)*chunk:i*chunk])
+        bq.put(b[(i-1)*chunk:i*chunk])
+
+        # create the process
+        p = Process(target=add, args=(aq,bq,product))
+        p.start()
+        p.join()
+ 
+    # collect the individual sums
+    items=[]
+    for i in range(product.qsize()):
+        items.append(product.get())
+    
+    # final product: sum of individual products
+    print "Dot product:: ",sum(items)

File parallel_article/py_multiprocessing/mp_queue.py~

+''' listing xx: mp_queue.py
+Queue: http://docs.python.org/library/multiprocessing.html#pipes-and-queues
+
+Demonstrates the usage of Queue to share data between processes
+Spilts up a large array into chunks and calculates the partial
+dot products
+'''
+
+import multiprocessing
+from multiprocessing import Process, Queue
+from numpy import *
+
+# dot product of the partial data chunks
+def add(chunk1,chunk2,product):
+    a = chunk1.get()
+    b = chunk2.get()
+    
+    prod = a*b
+    product.put(sum(prod))
+
+if __name__ == '__main__':
+    a = Queue()
+    b = Queue()
+    product=Queue()
+
+    #size of the arrays
+    num_el = 100000
+
+    # Create two arrays
+    a = linspace(0,100,num_el);
+    b = linspace(0,1,num_el);
+
+    # get the number of CPU's
+    np = multiprocessing.cpu_count()
+    print 'You have {0:1d} CPUs'.format(np)
+
+    # chunk size
+    if num_el%np != 0:
+        print "The current chunking mechanism will not work"
+        exit
+    else:
+        chunk = num_el/np
+
+    # Create the processes
+    p_list=[]
+    for i in range(1,np+1):
+
+        # A pair of queues per process for the two arrays
+        aq = Queue()
+        bq = Queue()
+
+        # push the chunks into the queue
+        aq.put(a[(i-1)*chunk:i*chunk])
+        bq.put(b[(i-1)*chunk:i*chunk])
+
+        # create the process
+        p = Process(target=add, args=(aq,bq,product,))
+        p.start()
+        p.join()
+ 
+    # collect the individual sums
+    items=[]
+    for i in range(product.qsize()):
+        items.append(product.get())
+    
+    # final product: sum of individual products
+    print "Dot product:: ",sum(items)

File parallel_article/py_multiprocessing/mpdemo.py

+''' listing 4: mpdemo.py
+Create number of processes using the multiprocessing module
+'''
+
+import multiprocessing
+from multiprocessing import Process
+
+# dummy function
+def f(id):
+    #This is a dummy function taking a parameter
+    return
+
+if __name__ == '__main__':
+
+    # get the number of CPU's
+    np = multiprocessing.cpu_count()
+    print 'You have {0:1d} CPUs'.format(np)
+
+    # Create the processes
+    p_list=[]
+    for i in range(1,np+1):
+        p = Process(target=f, name='Process'+str(i), args=(i,))
+        p_list.append(p)
+        print 'Process:: ', p.name,
+        p.start()
+        print 'Was assigned PID:: ', p.pid
+
+    # Wait for all the processes to finish
+    for p in p_list:
+        p.join()

File parallel_article/py_multiprocessing/mpdemo.py~

+''' listing xx: mpdemo.py
+Create number of processes using the multiprocessing module
+'''
+
+import multiprocessing
+from multiprocessing import Process
+
+# dummy function
+def f(id):
+    #This is a dummy function taking a parameter
+    return
+
+if __name__ == '__main__':
+
+    # get the number of CPU's
+    np = multiprocessing.cpu_count()
+    print 'You have {0:1d} CPUs'.format(np)
+
+    # Create the processes
+    p_list=[]
+    for i in range(1,np+1):
+        p = Process(target=f, name='Process'+str(i), args=(i,))
+        p_list.append(p)
+        print 'Process:: ', p.name,
+        p.start()
+        print 'Was assigned PID:: ', p.pid
+
+    # Wait for all the processes to finish
+    for p in p_list:
+        p.join()

File parallel_article/py_multiprocessing/mpdemo_shared.py

+''' listing xx: mpdemo-shared.py
+Create number of processes using the multiprocessing module
+and sharing a variable
+'''
+
+import multiprocessing
+from multiprocessing import Process, Value
+
+# dummy function
+def f(count):
+    #This is a dummy function taking a parameter
+    count.value=count.value+1
+    return
+
+if __name__ == '__main__':
+
+    # get the number of CPU's
+    np = multiprocessing.cpu_count()
+    print 'You have {0:1d} CPUs'.format(np)
+
+    # Shared integer variable (process safe)
+    count=Value('i',0)
+
+    # Create the processes
+    p_list=[]
+    for i in range(1,np+1):
+        p = Process(target=f, name='Process'+str(i), args=(count,))
+        p_list.append(p)
+        print 'Process:: ', p.name,
+        p.start()
+        print 'Was assigned PID:: ', p.pid
+
+    # Wait for all the processes to finish
+    for p in p_list:
+        p.join()
+
+    print count.value

File parallel_article/py_multiprocessing/mpdemo_shared.py~

+''' listing xx: mpdemo.py
+Create number of processes using the multiprocessing module
+'''
+
+import multiprocessing
+from multiprocessing import Process
+
+# dummy function
+def f(id):
+    #This is a dummy function taking a parameter
+    return
+
+if __name__ == '__main__':
+
+    # get the number of CPU's
+    np = multiprocessing.cpu_count()
+    print 'You have {0:1d} CPUs'.format(np)
+
+    # Create the processes
+    p_list=[]
+    for i in range(1,np+1):
+        p = Process(target=f, name='Process'+str(i), args=(i,))
+        p_list.append(p)
+        print 'Process:: ', p.name,
+        p.start()
+        print 'Was assigned PID:: ', p.pid
+
+    # Wait for all the processes to finish
+    for p in p_list:
+        p.join()

File parallel_article/py_multiprocessing/pi_mp.py

+''' listing 6: pi_mp.py
+
+Multiprocessing based code to estimate the value of PI
+using monte carlo sampling 
+Ref: http://math.fullerton.edu/mathews/n2003/montecarlopimod.html
+Uses workers: 
+http://docs.python.org/library/multiprocessing.html#module-multiprocessing.pool
+'''
+
+import random
+import multiprocessing
+from multiprocessing import Pool
+
+
+#caculate the number of points in the unit circle
+#out of n points
+def monte_carlo_pi_part(n):
+    
+    count = 0
+    for i in range(n):
+        x=random.random()
+        y=random.random()
+        
+        # if it is within the unit circle
+        if x*x + y*y <= 1:
+            count=count+1
+        
+    #return
+    return count
+
+
+if __name__=='__main__':
+    
+    np = multiprocessing.cpu_count()
+    print 'You have {0:1d} CPUs'.format(np)
+
+    # Nummber of points to use for the Pi estimation
+    n = 10000000
+    
+    # iterable with a list of points to generate in each worker
+    # each worker process gets n/np number of points to calculate Pi from
+
+    part_count=[n/np for i in range(np)]
+
+    #Create the worker pool
+    # http://docs.python.org/library/multiprocessing.html#module-multiprocessing.pool
+    pool = Pool(processes=np)   
+
+    # parallel map
+    count=pool.map(monte_carlo_pi_part, part_count)
+
+    print "Esitmated value of Pi:: ", sum(count)/(n*1.0)*4     

File parallel_article/py_multiprocessing/pi_mp.py~

+''' Multiprocessing based code to estimate the value of PI
+using monte carlo sampling
+Ref: http://math.fullerton.edu/mathews/n2003/montecarlopimod.html
+Uses workers: 
+http://docs.python.org/library/multiprocessing.html#module-multiprocessing.pool
+'''
+
+import random
+import multiprocessing
+from multiprocessing import Pool
+
+
+#caculate the number of points in the unit circle
+#out of n points
+def monte_carlo_pi_part(n):
+    
+    count = 0
+    for i in range(n):
+        x=random.random()
+        y=random.random()
+        
+        # if it is within the unit circle
+        if x*x + y*y <= 1:
+            count=count+1
+        
+    #return
+    return count
+
+
+if __name__=='__main__':
+    
+    np = multiprocessing.cpu_count()
+    print 'You have {0:1d} CPUs'.format(np)
+
+    # Nummber of points to use for the Pi estimation
+    n = 10000000
+    
+    # iterable with a list of points to generate in each worker
+    # each worker process gets n/np number of points to calculate Pi from
+    part_count=[n/np for i in range(np)]
+
+    #Create the worker pool
+    # http://docs.python.org/library/multiprocessing.html#module-multiprocessing.pool
+    pool = Pool(processes=np)   
+
+    # parallel map
+    count=pool.map(monte_carlo_pi_part, part_count)
+
+    print "Esitmated value of Pi:: ", sum(count)/(n*1.0)*4     
+

File parallel_article/py_multiprocessing/pi_serial.py

+''' Serial code to estimate the value of PI
+using monte carlo sampling'''
+
+import random
+
+
+def monte_carlo_pi(n):
+
+    count=0
+    for i in range(n):
+        x=random.random()
+        y=random.random()
+        
+        # if it is within the unit circle
+        if x*x + y*y <= 1:
+            count=count+1
+        
+    #return
+    return count/(n*1.0)*4
+
+
+if __name__=='__main__':
+    print monte_carlo_pi(10000000)
+        
+

File parallel_article/py_multiprocessing/pi_serial.py~

+''' Serial code to estimate the value of PI
+using monte carlo sampling'''
+
+import random
+
+
+def monte_carlo_pi(n):
+
+    count=0
+    for i in range(n):
+        x=random.random()
+        y=random.random()
+        
+        # if it is within the unit circle
+        if x*x + y*y <= 1:
+            count=count+1
+        
+    #return
+    return count/(n*1.0)*4
+
+
+if __name__=='__main__':
+    print monte_carlo_pi(1000000)
+        
+