source: CIVL/examples/pthread/mpithreads_threads.cvl@ 37bfb99

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

Updated examples and pthread.cvh

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

  • Property mode set to 100644
File size: 4.9 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#include "pthread.cvh"
24#include <civlc.h>
25#include <stdio.h>
26#include <stdlib.h>
27
28/*
29The following structure contains the necessary information to allow the
30function "dotprod" to access its input data and place its output into
31the structure. This structure is unchanged from the sequential version.
32*/
33
34typedef struct
35 {
36 double *a;
37 double *b;
38 double sum;
39 int veclen;
40 } DOTDATA;
41
42/* Define globally accessible variables and a mutex */
43
44$input int MAXTHRDS;
45$input int VECLEN;
46DOTDATA dotstr;
47pthread_t callThd[MAXTHRDS];
48pthread_mutex_t mutexsum;
49
50/*
51The function dotprod is activated when the thread is created. As before,
52all input to this routine is obtained from a structure of type DOTDATA and
53all output from this function is written into this structure. The benefit
54of this approach is apparent for the multi-threaded program: when a thread
55is created we pass a single argument to the activated function - typically
56this argument is a thread number. All the other information required by the
57function is accessed from the globally accessible structure.
58*/
59
60void *dotprod(void *arg)
61{
62
63 /* Define and use local variables for convenience */
64
65 int i, start, end, len ;
66 long offset;
67 double mysum, *x, *y;
68 offset = (long)*arg;
69
70 len = dotstr.veclen;
71 start = offset*len;
72 end = start + len;
73 x = dotstr.a;
74 y = dotstr.b;
75
76 /*
77 Perform the dot product and assign result to the appropriate variable in
78 the structure.
79 */
80
81 mysum = 0;
82 for (i=start; i<end ; i++)
83 {
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",
93 arg, mysum, dotstr.sum); // Removed l from %ld
94 dotstr.sum += mysum;
95 pthread_mutex_unlock (&mutexsum);
96
97 pthread_exit(NULL, false, NULL, 0);
98}
99
100/*
101The main program creates threads which do all the work and then print out
102result upon completion. Before creating the threads, the input data is
103created. Since all threads update a shared structure, we need a mutex for
104mutual exclusion. The main thread needs to wait for all threads to complete,
105it waits for each one of the threads. We specify a thread attribute value
106that allow the main thread to join with the threads it creates. Note also
107that we free up handles when they are no longer needed.
108*/
109
110int main (void)
111{
112long t[MAXTHRDS];
113long i;
114double *a, *b;
115void *status;
116pthread_attr_t attr;
117
118/* Assign storage and initialize values */
119a = (double*) malloc (MAXTHRDS*VECLEN*sizeof(double));
120b = (double*) malloc (MAXTHRDS*VECLEN*sizeof(double));
121
122for (i=0; i<VECLEN*MAXTHRDS; i++) {
123 a[i]=1;
124 b[i]=a[i];
125 }
126
127dotstr.veclen = VECLEN;
128dotstr.a = a;
129dotstr.b = b;
130dotstr.sum=0;
131
132pthread_mutex_init(&mutexsum, NULL);
133
134/* Create threads to perform the dotproduct */
135pthread_attr_init(&attr);
136pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
137
138for(i=0;i<MAXTHRDS;i++) {
139 /* Each thread works on a different set of data.
140 The offset is specified by 'i'. The size of
141 the data for each thread is indicated by VECLEN.
142 */
143 t[i] = i;
144 pthread_create( &callThd[i], &attr, dotprod, (void *)&t[i]);
145 }
146
147pthread_attr_destroy(&attr);
148
149/* Wait on the other threads */
150for(i=0;i<MAXTHRDS;i++) {
151 pthread_join( callThd[i], &status);
152 }
153
154/* After joining, print out the results and cleanup */
155printf ("Done. Threaded version: sum = %f \n", dotstr.sum);
156free (a);
157free (b);
158pthread_mutex_destroy(&mutexsum);
159pthread_exit(NULL, true, NULL, 0);
160return 0;
161}
162
163
Note: See TracBrowser for help on using the repository browser.