1
1

Something I've been working on with low bandwidth over the past

several weeks: marshaling hello world and ring examples in all 4
languages (C, C++, F77, F90), making them consistent and pretty, and
adding them to the build system in a non-intrusive way.

This commit was SVN r10792.
This commit is contained in:
Jeff Squyres 2006-07-13 21:03:36 +00:00
parent 5617cb1a0a
commit cc4b980291
12 changed files with 530 additions and 0 deletions

View File

@ -9,6 +9,7 @@
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
@ -19,5 +20,7 @@
SUBDIRS = config contrib $(MCA_PROJECT_SUBDIRS) test
EXTRA_DIST = README INSTALL VERSION Doxyfile LICENSE
include examples/Makefile.include
dist-hook:
csh "$(top_srcdir)/config/distscript.csh" "$(top_srcdir)" "$(distdir)" "$(OMPI_VERSION)" "$(OMPI_SVN_R)"

70
examples/Makefile Normal file
View File

@ -0,0 +1,70 @@
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
# Use the Open MPI-provided wrapper compilers
CC = mpicc
CXX = mpic++
F77 = mpif77
FC = mpif90
# Using -g is not necessary, but it is helpful for example programs,
# especially if users want to examine them with debuggers.
CFLAGS = -g
CXXFLAGS = -g
F77FLAGS = -g
FCFLAGS = -g
# Example programs to build
EXAMPLES = hello_c hello_cxx hello_f77 hello_f90 \
ring_c ring_cxx ring_f77 ring_f90
# Default target. Always build the C example. Only build the others
# if Open MPI was build with the relevant language bindings.
all: hello_c ring_c
@ if test "`ompi_info --parsable | grep bindings:cxx:yes`" != ""; then \
$(MAKE) hello_cxx ring_cxx; \
fi
@ if test "`ompi_info --parsable | grep bindings:f77:yes`" != ""; then \
$(MAKE) hello_f77 ring_f77; \
fi
@ if test "`ompi_info --parsable | grep bindings:f90:yes`" != ""; then \
$(MAKE) hello_f90 ring_f90; \
fi
# The usual "clean" target
clean:
rm -f $(EXAMPLES) *~ *.o
# Don't rely on default rules for the fortran examples
hello_f77: hello_f77.f
$(F77) $(F77FLAGS) $< -o $@
ring_f77: ring_f77.f
$(F77) $(F77FLAGS) $< -o $@
hello_f90: hello_f90.f90
$(FC) $(FCFLAGS) $< -o $@
ring_f90: ring_f90.f90
$(FC) $(FCFLAGS) $< -o $@

40
examples/Makefile.include Normal file
View File

@ -0,0 +1,40 @@
# -*- makefile -*-
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
# Note that this file does not stand on its own. It is included by a
# higher-level Makefile so that Automake features such as "make dist"
# work properly (and include all the relevant files in this directory
# in the distribution tarball).
# If you are looking for the file that builds these examples, look at
# "Makefile" in this same directory (it is *NOT* generated by
# Automake).
EXTRA_DIST += \
examples/README \
examples/Makefile \
examples/hello_c.c \
examples/hello_cxx.cc \
examples/hello_f77.f \
examples/hello_f90.f90 \
examples/ring_c.c \
examples/ring_cxx.cc \
examples/ring_f77.f \
examples/ring_f90.f90

42
examples/README Normal file
View File

@ -0,0 +1,42 @@
Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
University Research and Technology
Corporation. All rights reserved.
Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
The files in this directory are sample MPI applications provided both
as a trivial primer to MPI as well as simple tests to ensure that your
Open MPI installation is working properly.
If you are looking for a comprehensive MPI tutorial, these samples are
not enough. An excellent MPI tutorial is available here:
http://webct.ncsa.uiuc.edu:8900/public/MPI/
There are 2 MPI examples in this directory, each in four languages:
- Hello world
C: hello_c.c
C++: hello_cxx.cc
F77: hello_f77.f
F90: hello_f90.f90
- Send a trivial message around in a ring
C: ring_c.c
C++: ring_cxx.cc
F77: ring_f77.f
F90: ring_f90.f90
The Makefile in this directory will build as many of the examples as
you have language support (e.g., if you do not have F90 bindings
compiled as part of Open MPI, the F90 examples will be skipped).
The Makefile assumes that the wrapper compilers mpicc, mpic++, mpif77,
and mpif90 are in your path.
Although the Makefile is tailored for Open MPI (e.g., it checks the
"ompi_info" command to see if you have support for C++, F77, and F90),
all of the example programs are pure MPI, and therefore not specific
to Open MPI. Hence, you can use a different MPI implementation to
complie and run these programs if you wish.
Make today an Open MPI day!

24
examples/hello_c.c Normal file
View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
*
* Sample MPI "hello world" application in C
*/
#include <stdio.h>
#include "mpi.h"
int main(int argc, char* argv[])
{
int rank, size;
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
printf("Hello, world, I am %d of %d\n", rank, size);
MPI_Finalize();
return 0;
}

24
examples/hello_cxx.cc Normal file
View File

@ -0,0 +1,24 @@
//
// Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
// University Research and Technology
// Corporation. All rights reserved.
// Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
//
// Sample MPI "hello world" application in C++
//
#include <iostream>
#include "mpi.h"
int main(int argc, char **argv)
{
int rank, size;
MPI::Init();
rank = MPI::COMM_WORLD.Get_rank();
size = MPI::COMM_WORLD.Get_size();
std::cout << "Hello, world! I am " << rank << " of " << size << std::endl;
MPI::Finalize();
return 0;
}

20
examples/hello_f77.f Normal file
View File

@ -0,0 +1,20 @@
C
C Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
C University Research and Technology
C Corporation. All rights reserved.
C Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
C
C Sample MPI "hello world" application in Fortran 77
C
program main
implicit none
include 'mpif.h'
integer ierr, rank, size
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)
print *, "Hello, world, I am ", rank, " of ", size
call MPI_FINALIZE(ierr)
end

21
examples/hello_f90.f90 Normal file
View File

@ -0,0 +1,21 @@
!
! Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
! University Research and Technology
! Corporation. All rights reserved.
! Copyright (c) 2004-2005 The Regents of the University of California.
! All rights reserved.
! Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
!
! Sample MPI "hello world" application in Fortran 90
!
program main
use mpi
implicit none
integer :: ierr, rank, size
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)
print *, "Hello, world, I am ", rank, " of ", size
call MPI_FINALIZE(ierr)
end

79
examples/ring_c.c Normal file
View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
*
* Simple ring test program
*/
#include <stdio.h>
#include "mpi.h"
int main(int argc, char *argv[])
{
int rank, size, next, prev, message, tag = 201;
/* Start up MPI */
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
/* Calculate the rank of the next process in the ring. Use the
modulus operator so that the last process "wraps around" to
rank zero. */
next = (rank + 1) % size;
prev = (rank + size - 1) % size;
/* If we are the "master" process (i.e., MPI_COMM_WORLD rank 0),
put the number of times to go around the ring in the
message. */
if (0 == rank) {
message = 10;
printf("Process 0 sending %d to %d, tag %d (%d processes in ring)\n",
message, next, tag, size);
MPI_Send(&message, 1, MPI_INT, next, tag, MPI_COMM_WORLD);
printf("Process 0 sent to %d\n", next);
}
/* Pass the message around the ring. The exit mechanism works as
follows: the message (a positive integer) is passed around the
ring. Each time it passes rank 0, it is decremented. When
each processes receives a message containing a 0 value, it
passes the message on to the next process and then quits. By
passing the 0 message first, every process gets the 0 message
and can quit normally. */
while (1) {
MPI_Recv(&message, 1, MPI_INT, prev, tag, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
if (0 == rank) {
--message;
printf("Process 0 decremented value: %d\n", message);
}
MPI_Send(&message, 1, MPI_INT, next, tag, MPI_COMM_WORLD);
if (0 == message) {
printf("Process %d exiting\n", rank);
break;
}
}
/* The last process does one extra send to process 0, which needs
to be received before the program can exit */
if (0 == rank) {
MPI_Recv(&message, 1, MPI_INT, prev, tag, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
}
/* All done */
MPI_Finalize();
return 0;
}

78
examples/ring_cxx.cc Normal file
View File

@ -0,0 +1,78 @@
//
// Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
// University Research and Technology
// Corporation. All rights reserved.
// Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
//
// Simple ring test program
//
#include <iostream>
#include "mpi.h"
int main(int argc, char *argv[])
{
int rank, size, next, prev, message, tag = 201;
// Start up MPI
MPI::Init();
rank = MPI::COMM_WORLD.Get_rank();
size = MPI::COMM_WORLD.Get_size();
// Calculate the rank of the next process in the ring. Use the
// modulus operator so that the last process "wraps around" to
// rank zero.
next = (rank + 1) % size;
prev = (rank + size - 1) % size;
// If we are the "master" process (i.e., MPI_COMM_WORLD rank 0),
// put the number of times to go around the ring in the message.
if (0 == rank) {
message = 10;
std::cout << "Process 0 sending " << message << " to " << next
<< ", tag " << tag << " (" << size << " processes in ring)"
<< std::endl;
MPI::COMM_WORLD.Send(&message, 1, MPI::INT, next, tag);
std::cout << "Process 0 sent to " << next << std::endl;
}
// Pass the message around the ring. The exit mechanism works as
// follows: the message (a positive integer) is passed around the
// ring. Each time it passes rank 0, it is decremented. When
// each processes receives a message containing a 0 value, it
// passes the message on to the next process and then quits. By
// passing the 0 message first, every process gets the 0 message
// and can quit normally.
while (1) {
MPI::COMM_WORLD.Recv(&message, 1, MPI::INT, prev, tag);
if (0 == rank) {
--message;
std::cout << "Process 0 decremented value: " << message
<< std::endl;
}
MPI::COMM_WORLD.Send(&message, 1, MPI::INT, next, tag);
if (0 == message) {
std::cout << "Process " << rank << " exiting" << std::endl;
break;
}
}
// The last process does one extra send to process 0, which needs
// to be received before the program can exit */
if (0 == rank) {
MPI::COMM_WORLD.Recv(&message, 1, MPI::INT, prev, tag);
}
// All done
MPI::Finalize();
return 0;
}

76
examples/ring_f77.f Normal file
View File

@ -0,0 +1,76 @@
C
C Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
C University Research and Technology
C Corporation. All rights reserved.
C Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
C
C Simple ring test program
C
program ring_f77
implicit none
include 'mpif.h'
integer rank, size, tag, next, from, message, ierr
C Start up MPI */
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)
C Calculate the rank of the next process in the ring. Use the
C modulus operator so that the last process "wraps around" to rank
C zero.
tag = 201
next = mod((rank + 1), size)
from = mod((rank + size - 1), size)
C If we are the "master" process (i.e., MPI_COMM_WORLD rank 0), put
C the number of times to go around the ring in the message.
if (rank .eq. 0) then
message = 10
print *, 'Process 0 sending ', message, ' to ', next
call MPI_SEND(message, 1, MPI_INTEGER, next, tag,
& MPI_COMM_WORLD, ierr)
endif
C Pass the message around the ring. The exit mechanism works as
C follows: the message (a positive integer) is passed around the
C ring. Each time it passes rank 0, it is decremented. When each
C processes receives a message containing a 0 value, it passes the
C message on to the next process and then quits. By passing the 0
C message first, every process gets the 0 message and can quit
C normally.
10 call MPI_RECV(message, 1, MPI_INTEGER, from, tag,
& MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr)
if (rank .eq. 0) then
message = message - 1
print *, 'Process 0 decremented value:', message
endif
call MPI_SEND(message, 1, MPI_INTEGER, next, tag,
& MPI_COMM_WORLD, ierr)
if (message .eq. 0) then
print *, 'Process ', rank, ' exiting'
goto 20
endif
goto 10
C The last process does one extra send to process 0, which needs to
C be received before the program can exit
20 if (rank .eq. 0) then
call MPI_RECV(message, 1, MPI_INTEGER, from, tag,
& MPI_COMM_WORLD, MPI_STATUS_IGNORE, ierr)
endif
C All done
call MPI_FINALIZE(ierr)
end

53
examples/ring_f90.f90 Normal file
View File

@ -0,0 +1,53 @@
!
! Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
! University Research and Technology
! Corporation. All rights reserved.
! Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
!
! Simple ring test program
!
program ring
use mpi
implicit none
integer :: rank, size, tag, next, from, message, ierr
call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)
tag = 201
next = mod((rank + 1), size)
from = mod((rank + size - 1), size)
if (rank .eq. 0) then
message = 10
print *, 'Process 0 sending ', message, ' to ', next
call MPI_SEND(message, 1, MPI_INTEGER, next, tag, MPI_COMM_WORLD, ierr)
endif
10 call MPI_RECV(message, 1, MPI_INTEGER, from, tag, MPI_COMM_WORLD, &
MPI_STATUS_IGNORE, ierr)
if (rank .eq. 0) then
message = message - 1
print *, 'Process 0 decremented num'
endif
call MPI_SEND(message, 1, MPI_INTEGER, next, tag, MPI_COMM_WORLD, ierr)
if (message .eq. 0) then
print *, 'Process ', rank, ' exiting'
goto 20
endif
goto 10
20 if (rank .eq. 0) then
call MPI_RECV(message, 1, MPI_INTEGER, from, tag, MPI_COMM_WORLD, &
MPI_STATUS_IGNORE, ierr)
endif
call MPI_FINALIZE(ierr)
end program