source: CIVL/examples/pthread/mpithreads_threads.cvl@ 42e5d6e

1.23 2.0 main test-branch
Last change on this file since 42e5d6e was 6fe2cd9, checked in by John Edenhofner <johneden@…>, 12 years ago

Almost done

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@1040 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*****************************************************************************
2* SOURCE: This is a translation of a Pthread program from the Lawrence Livermore
3* Computing Center POSIX Threads Programming Exercise at:
4* https://computing.llnl.gov/tutorials/pthreads/exercise.html
5* FILE: mpithreads_threads.cvl
6* DESCRIPTION:
7* This simple program illustrates the use of Pthreads in a program obtained
8* by modifying a serial code that performs a dot product. It is the second
9* of four codes used to show the progression from a serial program to a
10* hybrid MPI/Pthreads program. The other relevant codes are:
11* - mpithreads_serial.c - The serial version
12* - mpithreads_mpi.c - A distributed memory programming model with MPI
13* - mpithreads_both.c - A hybrid model that utilizes both MPI and
14* Pthreads to execute on systems that are comprised of clusters
15* of SMP's.
16* The main data is made available to all threads through a globally
17* accessible structure. Each thread works on a different part of the
18* data. The main thread waits for all the threads to complete their
19* computations, and then it prints the resulting sum.
20* Command line execution:
21* civl verify -inputMAXTHRDS=8 -inputVECLEN=100 mpithreads_thread.cvl
22******************************************************************************/
23
24#include "pthread.cvh"
25#include <civlc.h>
26#include <stdio.h>
27#include <stdlib.h>
28
29/*
30The following structure contains the necessary information to allow the
31function "dotprod" to access its input data and place its output into
32the structure. This structure is unchanged from the sequential version.
33*/
34
35typedef struct
36{
37 double *a;
38 double *b;
39 double sum;
40 int veclen;
41} DOTDATA;
42
43/* Define globally accessible variables and a mutex */
44
45$input int MAXTHRDS;
46$input int VECLEN;
47DOTDATA dotstr;
48pthread_t callThd[MAXTHRDS];
49pthread_mutex_t mutexsum;
50
51/*
52The function dotprod is activated when the thread is created. As before,
53all input to this routine is obtained from a structure of type DOTDATA and
54all output from this function is written into this structure. The benefit
55of this approach is apparent for the multi-threaded program: when a thread
56is created we pass a single argument to the activated function - typically
57this argument is a thread number. All the other information required by the
58function is accessed from the globally accessible structure.
59*/
60
61void *dotprod(void *arg)
62{
63
64 /* Define and use local variables for convenience */
65
66 int i, start, end, len ;
67 long offset;
68 double mysum, *x, *y;
69 offset = (long)*arg; // Dereference rather than direct conv
70
71 len = dotstr.veclen;
72 start = offset*len;
73 end = start + len;
74 x = dotstr.a;
75 y = dotstr.b;
76
77 /*
78 Perform the dot product and assign result to the appropriate variable in
79 the structure.
80 */
81
82 mysum = 0;
83 for (i=start; i<end ; i++){
84 mysum += (x[i] * y[i]);
85 }
86
87 /*
88 Lock a mutex prior to updating the value in the shared structure, and
89 unlock it upon updating.
90 */
91 pthread_mutex_lock (&mutexsum);
92 printf("Thread %d adding partial sum of %f to global sum of %f\n", arg, mysum, dotstr.sum); // Removed l from %ld
93 dotstr.sum += mysum;
94 pthread_mutex_unlock (&mutexsum);
95
96 pthread_exit(NULL, false, NULL, 0); //Different parameters
97}
98
99/*
100The main program creates threads which do all the work and then print out
101result upon completion. Before creating the threads, the input data is
102created. Since all threads update a shared structure, we need a mutex for
103mutual exclusion. The main thread needs to wait for all threads to complete,
104it waits for each one of the threads. We specify a thread attribute value
105that allow the main thread to join with the threads it creates. Note also
106that we free up handles when they are no longer needed.
107*/
108
109int main (void)
110{
111 long t[MAXTHRDS];
112 long i;
113 double *a, *b;
114 void *status;
115 pthread_attr_t attr;
116
117 /* Assign storage and initialize values */
118 a = (double*) malloc (MAXTHRDS*VECLEN*sizeof(double));
119 b = (double*) malloc (MAXTHRDS*VECLEN*sizeof(double));
120
121 for (i=0; i<VECLEN*MAXTHRDS; i++) {
122 a[i]=1;
123 b[i]=a[i];
124 }
125
126 dotstr.veclen = VECLEN;
127 dotstr.a = a;
128 dotstr.b = b;
129 dotstr.sum=0;
130
131 pthread_mutex_init(&mutexsum, NULL);
132
133 /* Create threads to perform the dotproduct */
134 pthread_attr_init(&attr);
135 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
136
137 for(i=0;i<MAXTHRDS;i++) {
138 /* Each thread works on a different set of data.
139 The offset is specified by 'i'. The size of
140 the data for each thread is indicated by VECLEN.
141 */
142 //Add values into array and use address so that each value is unique as int to void * conversion is not supported
143 t[i] = i;
144 pthread_create( &callThd[i], &attr, dotprod, (void *)&t[i]);
145 }
146
147 pthread_attr_destroy(&attr);
148
149 /* Wait on the other threads */
150 for(i=0;i<MAXTHRDS;i++) {
151 pthread_join( callThd[i], &status);
152 }
153
154 /* After joining, print out the results and cleanup */
155 printf ("Done. Threaded version: sum = %f \n", dotstr.sum);
156 free (a);
157 free (b);
158 pthread_mutex_destroy(&mutexsum);
159 pthread_exit(NULL, true, NULL, 0); //Different parameters
160 return 0;
161}
Note: See TracBrowser for help on using the repository browser.