Functions in UPC

Phil Merkey

Introduction

There are a couple of interesting issues associated with writing functions in UPC. Writing a general purpose library can be quite involved and is beyond the tutorial. Writing functions for yourself, so that your program is more modular and is easier to understand is not so bad.

In the first example each thread calls a function to print helloworld.

<functions1.c>=
// upc_functions.c -- simple example of main calling functions
// Intro: calling upc functions in upc

#include <stdio.h>
#include <upc.h>

print_hello()
{
   printf("From within a function in thread %d of %d\n", 
          MYTHREAD,THREADS);
}

print_from_zero()
{
   if(MYTHREAD==0)
      printf("Hello From thread zero\n");
   else
      printf("Hello From someone else\n");
}

main()
{
  int i;
  upc_forall(i=0; i<THREADS; i++; i){
     printf("Hello A thread %d of %d\n", MYTHREAD,THREADS);
     print_hello();
  }
  upc_forall(i=0; i<THREADS; i++; i){
     printf("Hello B thread %d of %d\n", MYTHREAD,THREADS);
     print_from_zero();
  }
}

Calling standard C function, for example from the math library, requires a little care. This is not really an issue with the function, it is a problem of type. If the function expects a double you can give it shared double just as you can't give it int. Run the following program and then chance the MKERROR macro to generate an error on the next run.

<functions2.c>=
// Intro: Calling C functions

#include <stdio.h>
#include <upc.h>
#include <math.h>

#define MKERROR 0

shared int K[THREADS];

main()
{
  int i; 
  double k,p;

  upc_forall(i=0; i<THREADS; i++; i){
     K[i] = MYTHREAD;
  }

#if MKERROR
  upc_forall(i=0; i<THREADS; i++; i){
     p = pow(2.0, K[MYTHREAD]);
     printf("For thread %d, 2^MYTHREAD is %d\n", 
            MYTHREAD,p);
  }
#endif

  upc_forall(i=0; i<THREADS; i++; i){
     k =  K[MYTHREAD];
     p = pow(2.0, k);
     printf("For thread %d, 2^MYTHREAD is %g\n", 
            MYTHREAD,p);
  }
  upc_forall(i=0; i<THREADS; i++; i){
     p = pow(2.0, (double) K[MYTHREAD]);
     printf("For thread %d, 2^MYTHREAD is %g\n", 
            MYTHREAD,p);
  }
}