Intel® C++ Compiler for Linux* - Building UPC* to utilize the Intel® C++ Compiler


Introduction

This guide is intended to help Intel® C++ Compiler customers build the Berkeley* Unified Parallel C* (UPC*) compiler and configure it for use with symmetric multiprocessing (SMP) machines. UPC is a programming language that adds parallelization extensions to the C language.


Version information

This guide applies to version 2.4.0 of the Berkeley UPC runtime/front-end and UPC-to-C translator and the Intel® C++ Compiler version 10.0 for Linux*.


Application notes

UPC adds extensions to C that follow the Partitioned Global Address Space* (PGAS*) programming model. UPC can be used in both shared memory and distributed memory environments. In either case, the physical memory configuration is abstracted and appears as shared memory to the programmer. Though the memory appears to be shared by all threads, each shared variable has a thread affinity that is controlled by the programmer and will help UPC determine where to store the variable physically.

More information about the UPC language and the Berkeley UPC compiler can be found at: http://upc.lbl.gov/


Obtaining the source code

The source code can be found at: http://upc.lbl.gov/download/source.shtml

You will need both the Runtime/front-end package and the UPC-to-C translator. Please read and follow all licensing.

Note: Downloading the translator is not necessary if you use the remote translator provided by the Berkeley UPC website, but accessing the remote translator can be problematic for some users. For simplicity, this guide assumes that a local translator will be used.

After you download the source code, use the following commands to extract the archives:

tar -zxvf berkeley_upc_translator-2.4.0.tar.gz

tar -zxvf berkeley_upc-2.4.0.tar.gz

Obtaining the latest version of the Intel® C++ Compiler

Licensed users of the Intel compilers may download the most recent versions of the compiler from the Intel® Download Center which is accessed by logging into your account at the Intel® Registration Center.

Evaluation versions of the Intel compilers may be found at the Intel® Evaluation Software Center.


Prerequisites

Hardware: This note has been tested on Intel® Pentium® D processors.

Software: This note applies to use of version 10.0 of the Intel C++ Compiler for Linux.


Configuration and set-up information

In order to use this guide, you will need to have the Intel C++ Compiler installed. After installing the compiler, you will need to execute one of the following commands, depending on your architecture, to set the environment variables.

IA-32:
source /opt/intel/cc/10.0. xxx/bin/iccvars.sh

Intel® 64:
source /opt/intel/cce/10.0. xxx/bin/iccvars.sh You will need to replace  xxx in the above commands with the three digit build number of your compiler.


Source code changes

Some minor source code changes are required to build the UPC translator with the Intel® compiler. You will need to edit the following file:
berkeley_upc_translator-2.4.0/config-aux/abi.cc

Comment out line number five:
berkeley_upc_translator-2.4.0/config-aux/abi.cc (excerpt)

/* detect unsupported C++ compilers */
#if !defined(__GNUC__) ||
defined(__PATHCC__) || defined(__PGI) ||
defined(__INTEL_COMPILER) || defined(__xlC__)
// #error CXX compiler is not GNU g++!!!
#endif
...

You will also need to edit the following file:
berkeley_upc_translator-2.4.0/open64/osprey1.0/be/whirl2c/whirl2c_main.cxx

Add an include directive after line 45 pointing to the limits.h file in your system's include directory, specifying the absolute path:
berkeley_upc_translator-2.4.0/open64/osprey1.0/be/whirl2c/whirl2c_main.cxx (excerpt)

...
#include <stdio.h> /* for fprintf () */
#include <stdlib.h> /* for getenv() */
#include <unistd.h> /* for execv() */
#include <string.h> /* for strcpy(), strerror() */
#include <limits.h> /* for PATH_MAX */
#include "/usr/include/limits.h"
#include <errno.h> /* for errno */
#include <stdarg.h>
#include <cmplrs/rcodes.h>
#include "defs.h"
...

Now you should be ready to build UPC.


Building UPC

First, build the UPC-to-C translator. Execute the following commands in the directory where you downloaded the source code:

cd berkeley_upc_translator-2.4.0
make CC=icc CXX=icpc
make install PREFIX=<translator directory>

Replace <translator directory> in the above command with the directory where you would like to install the translator. If you omit the PREFIX, it will be installed to /usr/local/bupc_translator by default, assuming you have permission to write to that directory.

Next, build the runtime/front-end:

cd ../berkeley_upc-2.4.0
./configure CC=icc CXX=icpc LIBS=-lirc --prefix=<runtime directory>
make

Replace <runtime directory> in the above command with the directory where you would like to install the UPC front-end. If the prefix option is omitted, the runtime/front-end will be installed to /usr/local/berkeley_upc by default. Wherever you choose to install it, make sure the directory <runtime directory>/bin is in your PATH environment variable.

You will need to edit some settings in the upcc.conf file. Change the default_network to setting to smp:

default_network = smp

Change the translator setting to point to the translator that you built, replacing <translator directory> with the directory in which you chose to install the translator:
translator = <translator directory>/targ

Now you are ready to install the runtime/front-end:
make install

The executable you will need for compiling UPC programs will be: <runtime directory>/bin/upcc


Running UPC

Running UPC is similar to running other command line compilers such as the Intel or GNU compilers. For example, a single UPC source file named source.c can be compiled with the following command:

upcc --pthreads source.c

The --pthreads switch tells UPC to use multiple threads on an SMP machine. The compiled executable file will be called a.out. This default filename can be changed with the -o <filename> option. For a list of available options, use the following command:

upcc --help


Verifying correctness

For a basic test that UPC is working, you can compile and run a simple UPC program like the one below:

upctest.c

#include <upc.h>

#include <stdio.h>

int main()

printf("Thread %i of %i printing. ", MYTHREAD + 1, THREADS);
upc_barrier;
return 0;
}

You can compile this program using the following command:

upcc --pthreads=2 -o upctest upctest.c

Specifying the -pthreads=2 option states explicitly that UPC should use two threads. This will allow you to verify that multithreading is working even if you are testing UPC on a single-core machine. However, normally it would be better to allow UPC to choose the appropriate number of threads at run-time by omitting the =2 part of the command. You can run the compiled executable like this:

./upctest

The output you see should look something like:

UPCR: UPC threads 0..1 of 2 on computer1 (process 0 of 1, pid=15229)
Thread 1 of 2 printing.
Thread 2 of 2 printing.


Benefits

This note demonstrates the use of UPC with the latest version 10.0 Intel C++ Compiler technology. Following this method will produce object files and libraries that are compatible with the latest Intel compilers. The UPC translator translates UPC code into C code. The C code is then compiled into an executable. By following this method, you will not only be compiling t he UPC front-end and translator with the Intel compiler, but the UPC front-end itself will also use the Intel compiler to compile the C code produced by the UPC-to-C translator. Therefore, you may see performance benefits in your UPC applications by using the Intel compiler, depending on the particular application.


Known issues and limitations

There are no known issues or limitations with building UPC with the Intel C++ Compiler 10.0.

 
For more complete information about compiler optimizations, see our Optimization Notice.