# Naive Dot Product Example

Phil Merkey

## Introduction

In this demo program we compute the dot product of two vectors `x`

and `y`

.
We use `upc_forall`

to compute partial sums and then use a `upc_lock`

to
protect the part where we reduce the individual partial sums to the total
dot product.

The other part of the demo is to show difference between the
blocked and cyclic distribution.
The arrays `x_cyc`

and `y_cyc`

are declared with block size 1
and arrays `x_blk`

and `y_blk`

are declared with ` [*`

]]
block size. This can't change the results, but it does change the
partial sums collected by each thread.

<dotproduct.c>=
//dotproduct.c -- simple dot product
//Intro: upc_forall, locks, cyclic vs blocked
#include <stdio.h>
#include <upc.h>
#define NperTHREAD 100
#define SIZE (NperTHREAD * THREADS)
#define BLOCK NperTHREAD
shared float dot_cyc, dot_blk;
shared float x_cyc[SIZE], y_cyc[SIZE];
shared [*] float x_blk[SIZE], y_blk[SIZE];
upc_lock_t *dotlock;
main ()
{
int i;
float mydot;
dotlock = upc_all_lock_alloc();
upc_lock_init( dotlock );
if(MYTHREAD == 0)
dot_blk = dot_cyc = 0.0;
upc_barrier(0);
// "affinity" is an int so it is (i mod THREADS)
upc_forall( i=0; i< SIZE; i++; i ){
x_cyc[i] = (float) i;
y_cyc[i] = x_cyc[i];
x_blk[i] = (float) i;
y_blk[i] = x_blk[i];
}
upc_barrier(1);
mydot = 0.0;
// "affinity" is found from affinity of x_cyc[i]
upc_forall( i=0; i< SIZE; i++; &x_cyc[i] )
mydot += x_cyc[i] * y_cyc[i];
printf ("Process %2d holds %g (cyclic)\n", MYTHREAD, mydot);
upc_lock(dotlock);
dot_cyc = dot_cyc + mydot;
upc_unlock(dotlock);
upc_barrier(2);
if( MYTHREAD == 0 )
printf("Total (cyclic) is %g\n", dot_cyc);
upc_barrier(3);
mydot = 0.0;
// "affinity" is found from affinity of x[i]
upc_forall( i=0; i< SIZE; i++; &x_blk[i] )
mydot += x_blk[i] * y_blk[i];
printf ("Process %2d holds %g (blocked)\n", MYTHREAD, mydot);
upc_lock(dotlock);
dot_blk = dot_blk + mydot;
upc_unlock(dotlock);
upc_barrier(2);
if( MYTHREAD == 0 )
printf("Total (blocked) is %g\n", dot_blk);
}