GNU UPC
A GCC-Based Compilation and Execution Environment
for the Unified Parallel C (UPC) Language


Introduction

The GNU UPC toolset provides a compilation and execution environment for programs written in the UPC (Unified Parallel C) language. The GNU UPC compiler extends the capabilities of the GNU GCC (version 2.95.2) compiler. The GNU UPC compiler is implemented as a C Language dialect translator, in a fashion similar to the implementation of the GNU Objective C compiler.

Supported Platforms

The discussion that follows describes how to build and use the initial release (version 1.8) of the GNU UPC compiler. This release was developed exclusively for use on SGI workstations and servers running the MIPS instruction set, the Irix (release 6.5 or higher) operating system, and the mips2 32-bit ABI. Supported systems include Origin 2000 super-servers, and Octane workstations. By default, this release of the GNU UPC compiler will support systems with as many as 256 independent processing units.

At this time, no other ports of the GNU UPC compiler have been attempted. If you would like to learn of future ports to other platforms, or would like to discuss the feasibility of implementing GNU UPC on a platform of interest to you, we recommend that join the GNU UPC discussion list.

Documentation

Before you build and use the GNU UPC compiler, we recommend that you review GNU UPC for the SGI Origin 2000 (html/ PDF).

For a quick summary of the switches used to compile and link a UPC program, consult the GNU UPC manual page.

License

GNU UPC is implemented as an extension to the GNU C Compiler (GCC) and is distributed under the terms of the GNU General Public License.

The GNU UPC Discussion list

The GNU UPC discussion list provides a forum for tracking the status of UPC compilers based on the GNU GCC compiler. Announcements of new compiler ports, future plans, as well as known problems will be posted to the GNU UPC discussion list. To subscribe to the GNU UPC list, send an email message to gnu-upc-request@hermes.gwu.edu with the single word "subscribe" (without the quotes) in the body of the message, or visit the GNU UPC discussion list home page to manage your subscription.

Check out the mailing-list archive here.



Getting Started

Pre-requisites: Install These GNU Tools First

Before attempting to build the GNU UPC compiler, we recommend that you first build and install the versions of the GNU tools listed below:

With some difficulty, you may be able to build the GNU UPC compiler using the proprietary SGI development tools, however, you will obtain the best results if you use the GNU tools (and versions) listed above. The tool version numbers shown are the versions of the tools that were used to initially develop the compiler and runtime. You should be able to safely use later versions of the GNU tools.

You will likely encounter problems if you attempt to build UPC using SGI's make program. We recommend that use a recent version of patch because versions earlier than 2.5.4 do not support the set time/date option, which is required to properly establish source file dependencies. We also recommend that you do not try to use the `parallel make' option (the -j option on GNU make), because the version 2.95.2 GCC make files are not properly constructed to support parallel make.

Build the GNU UPC Compiler

The procedure for building the GNU UPC compiler is detailed in GNU UPC for the SGI Origin 2000. Briefly, the key steps are:

Compile and Run a simple UPC test program

Once the compiler has been built and installed, try running the following simple test program,


$ mkdir ~/upctest
$ cd ~/upctest
$ cat > hello.upc << EOF
#include <upc.h>
#include <stdio.h>
int main (int argc, char *argv[])
{
  int i;
  for (i = 0; i < THREADS; ++i)
    {
      upc_barrier;
      if (i == MYTHREAD)
        printf ("Hello world from thread: %d\n", MYTHREAD);
    }
  return 0;
}
EOF
$ upc -fupc-threads-4 hello.upc -o hello 
$ ./hello

The output should appear as follows:


Hello world from thread: 0
Hello world from thread: 1
Hello world from thread: 2
Hello world from thread: 3


Frequently Asked Questions

How do I specify the value of THREADS (statically) at compile time?

The -fupc-threads-n switch specifies the number of threads to be created. For example, the following command tells the UPC compiler to use a value of 32 for the value of THREADS, when compiling the source file src.upc,

     % upc -fupc-threads-32 src.upc

NOTE: The same value of n must specified for all UPC source files compiled into a given application.

How do I specify the value of THREADS (dynamically) at runtime?

First do not compile any of the UPC source files in your application with a compile-time specified value. Then, at runtime, provide the -fupc-threads-n option on the command line, just after the executable program's file name. The UPC runtime strips off all of the initial command line arguments that begin with the prefix -fupc-threads, and passes the remaining arguments to your application's main program. The following example, shows how this is done:


     % cat > dynamic.upc << EOF
     ? #include <upc.h>
     ? #include <stdio.h>
     ? main ()
     ? {
     ?   if (MYTHREAD == 0)
     ?     printf ("There are %d UPC threads\n", THREADS);
     ?   return 0;
     ? }
     ? EOF
     % upc dynamic.upc -o dynamic
     % dynamic -fupc-threads-7
     There are 7 UPC threads

How do I compile UPC source files that end with a .c extension?

By default, source files ending with a .upc extension are recognized as UPC source files. To compile files that end with some other extension use the -x upc switch. For example,

     % upc -x upc src.c -o pgm

I tried to link my UPC program, and the link failed with some unusual error messages, including "unterminated string or character constant". What happened?

It is likely the case that you inadvertently supplied the -x upc switch on the command line. The -x upc switch tells the UPC compiler to treat all filenames on the command line as if they are UPC source files; the compiler does not attempt to determine a file's type based on its file's extension. Thus, the following sequence of commands will fail on the final step where the user intended to link the application's object files.


     % upc -x upc -c main.c f1.c f2.c
     % upc -x upc main.o f1.o f2.o -o pgm
     main.o:1: unterminated string or character constant
     main.o:1: possible real start of unterminated constant
     f1.o:1: unterminated string or character constant
     f1.o:1: possible real start of unterminated constant
     f2.o:1: unterminated string or character constant
     f2.o:1: possible real start of unterminated constant

The problem is easily corrected by omitting the -x upc switch from the command line when linking the program:


     % upc main.o f1.o f2.o -o pgm


My program runs fine but terminates with the message "conflicting exit status ...". What happened?

It is likely that your UPC main() program does not terminate with either an explicit return statement or a call to exit(). The UPC runtime library makes a special check when each thread terminates to ensure that all threads terminate with the same exit value. If all threads do not exit with the same value, then the runtime library will print one or more "conflicting exit status" messages. The following example illustrates a situation where each main program terminates with whatever value happens to be in the register used for the function return value. Each thread will terminate with a different value. The runtime notices that the return values are different and prints an error diagnostic.


     % cat > retcode.upc << EOF
     ? #include <upc.h>
     ? f() { return MYTHREAD; }
     ? main()
     ? {
     ?   int i;
     ?   i = f ();
     ? }
     ? EOF
     % upc -O0 retcode.upc -o retcode
     % retcode -fupc-threads-3
     conflicting exit status (0) for thread 0
     conflicting exit status (1) for thread 1

The fix is to make sure that all threads terminate with the same value by adding an explicit call to exit():


     % cat retcode.upc
     #include <upc.h>
     f() { return MYTHREAD; }
     main()
     {
       int i;
       i = f ();
       exit (0);
     }
     % upc -O0 retcode.upc -o retcode
     % retcode -fupc-threads-3
     % echo $status
     0

My program printed the message, "UPC Warning: There are no UPC source files compiled into this program, or <upc.h> was not included?". What do I do to get rid of that warning?

It is likely that you have either (1) asked the UPC compiler to compile and link only pure C language source files, or (2) you have forgotten to include either <upc.h>, <upc_strict.h>, or <upc_relaxed.h> in your UPC source files. Often, this ommission will be discovered at compile-time, when your program attempts to make references to THREADS or MYTHREAD, however very simple programs might slip through the compilation step, and the omission is not detected until the program is executed. Here is an example,


     % cat > empty.upc << EOF
     ? main()
     ? {
     ?   return 0;
     ? }
     ? EOF
     % upc empty.upc -o empty
     % empty -fupc-threads-4
     empty: UPC Warning: There are no UPC source files compiled into this
     program, or <upc.h> was not included?

My program terminates with the message "UPC error: Invalid conversion of shared address to local pointer. Thread does not have affinity to shared address.". What does that mean?

Any attempt to cast a shared pointer to a local per-thread pointer is considered erroneous if the thread component of the shared pointer does not equal the thread number of the referencing thread. This error can arise, even though the program doesn't try to derefence the invalid local pointer. The following example illustrates this situation.


     % cat badptr.upc
     #include <upc.h>
     shared int v[THREADS];
     main ()
     {
       int *vp;
       v[MYTHREAD] = MYTHREAD;
       upc_barrier;
       vp = (int *)&v[0];
       if (MYTHREAD == 0)
	 printf ("v[0] = %d\n", *vp);
       return 0;
     }
     % upc -fupc-threads-4 badptr.upc -o badptr
     % badptr
     badptr: UPC error: Invalid conversion of shared address to local pointer.
     Thread does not have affinity to shared address.
     v[0] = 0
     thread 1 terminated with 'Abort' signal
     Terminated

The error can be corrected by ensuring that the pointer conversion is made only in a valid context.


     % cat goodptr.upc
     #include <upc.h>
     shared int v[THREADS];
     main ()
     {
       v[MYTHREAD] = MYTHREAD;
       upc_barrier;
       if (MYTHREAD == 0)
	 {
	   int *vp = (int *)&v[0];
	   printf ("v[0] = %d\n", *vp);
	 }
       return 0;
     }
     % upc -fupc-threads-4 goodptr.upc -o goodptr
     % goodptr
     v[0] = 0


Known Bugs

Some features are not yet implemented in version 1.8 of GNU UPC:

To report bugs or get the latest news concerning bug fixes, subscribe or send email to the GNU UPC mailing list.



Limitations

The maximum number of threads is limited to 256.

The maximum layout specifier (block size) value is limited to 16777215.

An operating system process is created for each UPC thread. Therefore, the maximum number of supported threads is further constrained by system capacity limitations, such as available swap space and process load. Typically, a UPC program will fail with the diagnostic "UPC initialization failed. reason: Resource temporarily unavailable" if there are insufficient system resources to create the requested number of threads.



Acknowledgments

The SGI GNU UPC compiler is based on the earlier work of Jesse Draper (IDA) and Bill Carlson (IDA). Howard ("Flash") Gordon (NSA) and his organization helped sponsor the development work, and provided invaluable technical feedback at each stage of development. Ed Burgess (CSC) served as project manager. Gerhard Harrop (CSC) rigorously reviewed early design proposals and was a source of both technical and editorial guidance throughout the course of the project. Jody Hencin of Silicon Graphics brought the team together, and made sure that the required resources were ready when required. Jason Mader (GWU) provided feedback on installation issues. Dr. Tarek El-Ghazawi (GWU and GMU) was instrumental in the effort to refine the UPC specification, and patiently helped us gain an understanding of the UPC language definition. Brian Wibecan (Compaq), both in his participation on the UPC Developer's List and off, provided valuable insight into the more difficult aspects of the UPC language and its implementation. Ludovic Courtès (GWU) worked tirelessly and with good humor on improvements to both the appearance and the content of the information on the UPC web site. Ludovic also independently validated the installation of the compiler, and ran various conformance tests.


Back to the software page | the UPC home page
Last modified: Thu Jan 24 16:17:45 EST 2002