xref: /openbsd-src/gnu/gcc/libgomp/testsuite/libgomp.c/omp_matvec.c (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert /******************************************************************************
2*404b540aSrobert * OpenMP Example - Matrix-vector multiplication - C/C++ Version
3*404b540aSrobert * FILE: omp_matvec.c
4*404b540aSrobert * DESCRIPTION:
5*404b540aSrobert *   This example multiplies all row i elements of matrix A with vector
6*404b540aSrobert *   element b(i) and stores the summed products in vector c(i).  A total is
7*404b540aSrobert *   maintained for the entire matrix.  Performed by using the OpenMP loop
8*404b540aSrobert *   work-sharing construct.  The update of the shared global total is
9*404b540aSrobert *   serialized by using the OpenMP critical directive.
10*404b540aSrobert * SOURCE: Blaise Barney  5/99
11*404b540aSrobert * LAST REVISED:
12*404b540aSrobert ******************************************************************************/
13*404b540aSrobert 
14*404b540aSrobert #include <omp.h>
15*404b540aSrobert #include <stdio.h>
16*404b540aSrobert #define SIZE 10
17*404b540aSrobert 
18*404b540aSrobert 
main()19*404b540aSrobert main ()
20*404b540aSrobert {
21*404b540aSrobert 
22*404b540aSrobert float A[SIZE][SIZE], b[SIZE], c[SIZE], total;
23*404b540aSrobert int i, j, tid;
24*404b540aSrobert 
25*404b540aSrobert /* Initializations */
26*404b540aSrobert total = 0.0;
27*404b540aSrobert for (i=0; i < SIZE; i++)
28*404b540aSrobert   {
29*404b540aSrobert   for (j=0; j < SIZE; j++)
30*404b540aSrobert     A[i][j] = (j+1) * 1.0;
31*404b540aSrobert   b[i] = 1.0 * (i+1);
32*404b540aSrobert   c[i] = 0.0;
33*404b540aSrobert   }
34*404b540aSrobert printf("\nStarting values of matrix A and vector b:\n");
35*404b540aSrobert for (i=0; i < SIZE; i++)
36*404b540aSrobert   {
37*404b540aSrobert   printf("  A[%d]= ",i);
38*404b540aSrobert   for (j=0; j < SIZE; j++)
39*404b540aSrobert     printf("%.1f ",A[i][j]);
40*404b540aSrobert   printf("  b[%d]= %.1f\n",i,b[i]);
41*404b540aSrobert   }
42*404b540aSrobert printf("\nResults by thread/row:\n");
43*404b540aSrobert 
44*404b540aSrobert /* Create a team of threads and scope variables */
45*404b540aSrobert #pragma omp parallel shared(A,b,c,total) private(tid,i)
46*404b540aSrobert   {
47*404b540aSrobert   tid = omp_get_thread_num();
48*404b540aSrobert 
49*404b540aSrobert /* Loop work-sharing construct - distribute rows of matrix */
50*404b540aSrobert #pragma omp for private(j)
51*404b540aSrobert   for (i=0; i < SIZE; i++)
52*404b540aSrobert     {
53*404b540aSrobert     for (j=0; j < SIZE; j++)
54*404b540aSrobert       c[i] += (A[i][j] * b[i]);
55*404b540aSrobert 
56*404b540aSrobert     /* Update and display of running total must be serialized */
57*404b540aSrobert     #pragma omp critical
58*404b540aSrobert       {
59*404b540aSrobert       total = total + c[i];
60*404b540aSrobert       printf("  thread %d did row %d\t c[%d]=%.2f\t",tid,i,i,c[i]);
61*404b540aSrobert       printf("Running total= %.2f\n",total);
62*404b540aSrobert       }
63*404b540aSrobert 
64*404b540aSrobert     }   /* end of parallel i loop */
65*404b540aSrobert 
66*404b540aSrobert   } /* end of parallel construct */
67*404b540aSrobert 
68*404b540aSrobert printf("\nMatrix-vector total - sum of all c[] = %.2f\n\n",total);
69*404b540aSrobert 
70*404b540aSrobert   return 0;
71*404b540aSrobert }
72*404b540aSrobert 
73