Rudimentary documentation for the charm++ port of the ARMCI interface.
authorChee Wai Lee <cheelee@illinois.edu>
Mon, 25 Jun 2007 23:20:13 +0000 (23:20 +0000)
committerChee Wai Lee <cheelee@illinois.edu>
Mon, 25 Jun 2007 23:20:13 +0000 (23:20 +0000)
doc/armci/Makefile [new file with mode: 0644]
doc/armci/examples/Makefile [new file with mode: 0644]
doc/armci/examples/hello.c [new file with mode: 0644]
doc/armci/manual.tex [new file with mode: 0644]

diff --git a/doc/armci/Makefile b/doc/armci/Makefile
new file mode 100644 (file)
index 0000000..41e81a1
--- /dev/null
@@ -0,0 +1,11 @@
+# Stub makefile for LaTeX PPL manual
+FILE=manual
+TEX=$(FILE).tex 
+
+DEST=armci
+LATEX2HTML=$(L2H) -split 5
+
+include ../Makefile.common
+
+index.tex:
+       touch index.tex
diff --git a/doc/armci/examples/Makefile b/doc/armci/examples/Makefile
new file mode 100644 (file)
index 0000000..1653bbe
--- /dev/null
@@ -0,0 +1,10 @@
+CHARMBIN = ../../../bin
+
+hello: hello.c
+       $(CHARMBIN)/charmc -o hello hello.c -language armci
+
+run: hello
+       ./charmrun +p2 ./hello
+
+clean:
+       rm -f hello charmrun
diff --git a/doc/armci/examples/hello.c b/doc/armci/examples/hello.c
new file mode 100644 (file)
index 0000000..bbbb8d7
--- /dev/null
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <armci.h>
+
+#define MAX_PROCESSORS 2
+
+int main(int argc, char * argv[]) {
+  void *baseAddress[MAX_PROCESSORS];
+  char *myBuffer;
+  int thisImage;
+
+  // initialize
+  ARMCI_Init();
+  ARMCI_Myid(&thisImage);
+
+  // allocate data (collective operation)
+  ARMCI_Malloc(baseAddress, strlen("hello")+1);
+
+  if (thisImage == 0) {
+    sprintf((char *)baseAddress[0], "%s", "hello");
+  } else if (thisImage == 1) {
+    sprintf((char *)baseAddress[1], "%s", "world");
+  }
+
+  // allocate space for local buffer
+  myBuffer = (char *)ARMCI_Malloc_local(strlen("hello")+1);
+
+  ARMCI_Barrier();
+
+  if (thisImage == 0) {
+    ARMCI_Get(baseAddress[1], myBuffer, strlen("hello")+1, 1);
+    printf("[%d] %s %s\n",thisImage, baseAddress[0], myBuffer);
+  } else if (thisImage == 1) {
+    ARMCI_Get(baseAddress[0], myBuffer, strlen("hello")+1, 0);
+    printf("[%d] %s %s\n",thisImage, myBuffer, baseAddress[1]);
+  }
+
+  // sanity check (should segfault)
+  // printf("[%d] %s %s\n",thisImage, baseAddress[0], baseAddress[1]);
+
+  // finalize
+  ARMCI_Finalize();
+  return 0;
+}
diff --git a/doc/armci/manual.tex b/doc/armci/manual.tex
new file mode 100644 (file)
index 0000000..b466875
--- /dev/null
@@ -0,0 +1,456 @@
+%\documentclass[10pt,dvips]{article}
+\documentclass[10pt]{article}
+\usepackage{../pplmanual}
+\usepackage[pdftex]{graphicx}
+%\usepackage[dvips]{graphicx}
+%\usepackage[usenames,dvipsnames]{color}
+%\usepackage[pdftex]{hyperref}
+\usepackage{epsfig}
+\input{../pplmanual}
+
+\ifpdf
+\DeclareGraphicsExtensions{.jpg,.pdf,.mps,.png}
+\else
+\DeclareGraphicsExtensions{.eps}
+\fi
+
+\title{ARMCI Interface under \charmpp{}}
+\version{1.0}
+\credits{
+Chee Wai Lee and Chao Huang
+}
+
+\begin{document}
+\maketitle
+
+\section{Introduction}
+\label{sec::introduction}
+
+This manual describes the basic features and API of the Aggregate
+Remote Memory Copy Interface (ARMCI) library implemented under
+\charmpp{}. It is meant for developers using ARMCI who desire the
+performance features of the \charmpp{} run-time system (e.g. dynamic
+load balancing, fault tolerance and scalability) applied transparently
+to their libraries written using the ARMCI API.
+
+ARMCI is a library that supports remote memory copy functionality. It
+focuses on non-contiguous data transfers and is meant to be used by
+other libraries as opposed to application development. Libraries that
+the original ARMCI developers have targetted include Global Arrays,
+P++/Overture and the Adlib PCRC run-time system.
+
+ARMCI remote copy operations are one-sided and complete, regardless of
+the actions taken by the remote process. For performance reasons,
+polling can be helpful but should not be necessary to ensure
+progress. The operations are ordered when referencing the same remote
+process. Operations issued to different processes can complete in an
+arbitrary order. Both blocking and non-blocking APIs are supported.
+
+ARMCI supports three classes of operations: data transfer using {\em
+put}, {\em get} and {\em accumulate} operations; synchronization with
+local and global {\em fence} operations and atomic read-modify-write;
+and utility functions for memory management and error handling. {\em
+Accumulate} and atomic read-modify-write operations are currently not
+implemented for the charmpp{} port.
+
+A {\em get} operation transfers data from the remote process memory
+(source) to the calling processing local memory (destination). A {\em
+put} operation transfers data from the local memory of the calling
+process (source) to the memory of the remote process (destination).
+
+This manual will include several useful \charmpp{}-specific extensions to
+the ARMCI API. It will also list the functions that have not yet been
+implemented but exists in the original ARMCI implementation. Readers
+of this manual are advised to refer to the original ARMCI
+documentation (See Section \ref{sec::related doc}) for more complete
+information and motivation for the development of this library.
+
+\subsection{Building ARMCI Support under The \charmpp{} Runtime System}
+\label{sec::charm build}
+
+Build charm target ARMCI (instead of charm or AMPI):
+\begin{verbatim}
+> cd charm
+> ./build ARMCI net-linux -O3
+\end{verbatim}
+
+\subsection{Writing a Simple ARMCI Program}
+\label{sec::simple program}
+
+The following simple example has two processes place their own string
+into the global array and then acquire the appropriate string from the
+other's global address space in order to print ``hello world''. 
+
+The main function has to be compliant to ANSI C:
+
+\begin{verbatim}
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <armci.h>
+
+#define MAX_PROCESSORS 2
+
+int main(int argc, char * argv[]) {
+  void *baseAddress[MAX_PROCESSORS];
+  char *myBuffer;
+  int thisImage;
+  
+  // initialize
+  ARMCI_Init();
+  ARMCI_Myid(&thisImage);
+
+  // allocate data (collective operation)
+  ARMCI_Malloc(baseAddress, strlen("hello")+1);
+  if (thisImage == 0) {
+    sprintf((char *)baseAddress[0], "%s", "hello");
+  } else if (thisImage == 1) {
+    sprintf((char *)baseAddress[1], "%s", "world");
+  }
+
+  // allocate space for local buffer
+  myBuffer = (char *)AMRCI_Malloc_local(strlen("hello")+1);
+  
+  ARMCI_Barrier();
+
+  if (thisImage == 0) {
+    ARMCI_Get(baseAddress[1], myBuffer, strlen("hello")+1, 1);
+    printf("[%d] %s %s\n",thisImage, baseAddress[0], myBuffer);
+  } else if (thisImage == 1) {
+    ARMCI_Get(baseAddress[0], myBuffer, strlen("hello")+1, 0);
+    printf("[%d] %s %s\n",thisImage, myBuffer, baseAddress[1]);
+  }
+
+  // finalize
+  ARMCI_Finalize();
+  return 0;
+}
+\end{verbatim}
+
+\subsection{Building an ARMCI Binary and Execution}
+\label{sec::armci build}
+
+Compiling the code with:
+\begin{verbatim}
+> charm/bin/charmc -c hello.c /$(OPTS)
+\end{verbatim}
+
+\noindent
+Linking the program with:
+\begin{verbatim}
+> charm/bin/charmc hello.o -o hello -swapglobals -memory isomalloc -language armci $(OPTS)
+\end{verbatim}
+
+\noindent
+Run the program:
+\begin{verbatim}
+> ./charmrun ./hello +p2 +vp8
+\end{verbatim}
+
+\section{ARMCI Data Structures}
+\label{sec::data structures}
+
+ARMCI provides two formats to describe non-contiguous layouts of data
+in memory.
+
+The {\em generalized I/O vector} is the most general format intended
+for multiple sets of equally sized data segments to be moved between
+arbitrary local and remote memory locations. It uses two arrays of
+pointers: one for source and one for destination addresses. The length
+of each array is equal to the number of segments.
+
+\begin{verbatim}
+typedef struct {
+  void *src_ptr_ar;
+  void *dst_ptr_ar;
+  int bytes;
+  int ptr_ar_len;
+} armci_giov_t;
+\end{verbatim}
+
+Currently, there is no support for {\em generalized I/O vector}
+operations in the charmpp{} implementation.
+
+The {\em strided} format is an optimization of the generalized I/O
+vector format. It is inteded to minimize storage required to describe
+sections of dense multi-dimensional arrays. Instead of including
+addresses for all the segments, it specifies only an address of the
+first segment in the set for source and destination. The addresses of
+the other segments can be computed using the stride information.
+
+\section{Application Programmer's Interface}
+\label{sec::api}
+
+The following is a list of functions supported on the \charmpp{} port
+of ARMCI. The integer value returned by most ARMCI operations
+represents the error code. The zero value is successful, other values
+represent failure (See Section \ref{sec::error codes} for details).
+
+\subsection{Startup, Cleanup and Status Functions}
+
+\begin{verbatim}
+int ARMCI_Init(void);
+\end{verbatim}
+Initializes the ARMCI library. This function must be called before any
+ARMCI functions may be used.
+
+\begin{verbatim}
+int ARMCI_Finalize(void);
+\end{verbatim}
+Shuts down the ARMCI library. No ARMCI functions may be called after
+this call is made. It must be used before terminating the program normally.
+
+\begin{verbatim}
+void ARMCI_Cleanup(void);
+\end{verbatim}
+Releases system resources that the ARMCI library might be holding. This is
+intended to be used before terminating the program in case of error.
+
+\begin{verbatim}
+void ARMCI_Error(char *msg, int code);
+\end{verbatim}
+Combines the functionality of ARMCI\_Cleanup and \charmpp{}'s CkAbort
+call. Prints to {\em stdout} and {\em stderr} {\tt msg} followed by an
+integer {\tt code}.
+
+\begin{verbatim}
+int ARMCI_Procs(int *procs);
+\end{verbatim}
+The number of processes is stored in the address {\tt procs}.
+
+\begin{verbatim}
+int ARMCI_Myid(int *myid);
+\end{verbatim}
+The id of the process making this call is stored in the address {\tt myid}.
+
+\subsection{ARMCI Memory Allocation}
+
+\begin{verbatim}
+int ARMCI_Malloc(void* ptr_arr[], int bytes);
+\end{verbatim}
+Collective operation to allocate memory that can be used in the
+context of ARMCI copy operations. Memory of size {\tt bytes} is
+allocated on each process. The pointer address of each process'
+allocated memory is stored at {\tt ptr\_arr[]} indexed by the process'
+id (see {\tt ARMCI\_Myid}). Each process gets a copy of {\tt ptr\_arr}.
+
+\begin{verbatim}
+int ARMCI_Free(void *ptr);
+\end{verbatim}
+Collective operation to free memory which was allocated by 
+{\tt ARMCI\_Malloc}.
+
+\begin{verbatim}
+void *ARMCI_Malloc_local(int bytes);
+\end{verbatim}
+Local memory of size {\tt bytes} allocated. Essentially a wrapper for
+{\tt malloc}.
+
+\begin{verbatim}
+int ARMCI_Free_local(void *ptr);
+\end{verbatim}
+Local memory address pointed to by {\tt ptr} is freed. Essentially a
+wrapper for {\tt free}.
+
+\subsection{Put and Get Communication}
+
+\begin{verbatim}
+int ARMCI_Put(void *src, void *dst, int bytes, int proc);
+\end{verbatim}
+Transfer contiguous data of size {\tt bytes} from the local process
+memory (source) pointed to by {\tt src} into the remote memory of
+process id {\tt proc} pointed to by {\tt dst} (remote memory pointer
+at destination).
+
+\begin{verbatim}
+int ARMCI_NbPut(void *src, void* dst, int bytes, int proc, 
+                armci_hdl_t *handle);
+\end{verbatim}
+The non-blocking version of {\tt ARMCI\_Put}. Passing a {\tt NULL}
+value to {\tt handle} makes this function perform an implicit handle
+non-blocking transfer.
+
+\begin{verbatim}
+int ARMCI_PutS(void *src_ptr, int src_stride_ar[],
+               void *dst_ptr, int dst_stride_ar[],
+               int count[], int stride_levels, int proc);
+\end{verbatim}
+Transfer strided data from the local process memory (source) into
+remote memory of process id {\tt proc}. {\tt src\_ptr} points to the
+first memory segment in local process memory. {\tt dst\_ptr} is a
+remote memory address that points to the first memory segment in the
+memory of process {\tt proc}. {\tt stride\_levels} represents the
+number of additional dimensions of striding beyond 1. {\tt
+src\_stride\_ar} is an array of size {\tt stride\_levels} whose values
+indicate the number of bytes to skip on the local process memory
+layout. {\tt dst\_stride\_ar} is an array of size {\tt stride\_levels}
+whose values indicate the number of bytes to skip on process {\tt
+proc}'s memory layout. {\tt count} is an array of size {\tt
+stride\_levels + 1} whose values indicate the number of bytes to copy.
+
+As an example, assume two 2-dimensional C arrays residing on different
+processes.
+
+\begin{verbatim}
+          double A[10][20]; /* local process */
+          double B[20][30]; /* remote process */
+\end{verbatim}
+
+To put a block of data of 3x6 doubles starting at location (1,2) in
+{\tt A} into location (3,4) in {\tt B}, the arguments to {\tt
+ARMCI\_PutS} will be as follows (assuming C/C++ memory layout):
+
+\begin{verbatim}
+          src_ptr = &A[0][0] + (1 * 20 + 2); /* location (1,2) */
+          src_stride_ar[0] = 20 * sizeof(double);
+          dst_ptr = &B[0][0] + (3 * 30 + 4); /* location (3,4) */
+          dst_stride_ar[0] = 30 * sizeof(double);
+          count[0] = 6; * sizeof(double); /* contiguous data */
+          count[1] = 3; /* number of rows of contiguous data */
+          stride_levels = 1;
+          proc = <B's id>;
+\end{verbatim}
+
+\begin{verbatim}
+int ARMCI_NbPutS(void *src_ptr, int src_stride_ar[],
+                 void *dst_ptr, int dst_stride_ar[],
+                 int count[], int stride_levels, int proc
+                 armci_hdl_t *handle);
+\end{verbatim}
+The non-blocking version of {\tt ARMCI\_PutS}. Passing a {\tt NULL}
+value to {\tt handle} makes this function perform an implicit handle
+non-blocking transfer.
+
+\begin{verbatim}
+int ARMCI_Get(void *src, void *dst, int bytes, int proc);
+\end{verbatim}
+Transfer contiguous data of size {\tt bytes} from the remote process
+memory at process {\tt proc} (source) pointed to by {\tt src} into the
+local memory of the calling process pointed to by {\tt dst}.
+
+\begin{verbatim}
+int ARMCI_NbGet(void *src, void *dst, int bytes, int proc,
+                armci_hdl_t *handle);
+\end{verbatim}
+The non-blocking version of {\tt ARMCI\_Get}. Passing a {\tt NULL}
+value to {\tt handle} makes this function perform an implicit handle
+non-blocking transfer.
+
+\begin{verbatim}
+int ARMCI_GetS(void *src_ptr, int src_stride_ar[],
+               void* dst_ptr, int dst_stride_ar[],
+               int count[], int stride_levels, int proc);
+\end{verbatim}
+Transfer strided data segments from remote process memory on process
+{\tt proc} to the local memory of the calling process. The semantics
+of the parameters to this function are the same as that for {\tt
+ARMCI\_PutS}.
+
+\begin{verbatim}
+int ARMCI_NbGetS(void *src_ptr, int src_stride_ar[],
+                 void* dst_ptr, int dst_stride_ar[],
+                 int count[], int stride_levels, int proc,
+                 armci_hdl_t *handle);
+\end{verbatim}
+The non-blocking version of {\tt ARMCI\_GetS}. Passing a {\tt NULL}
+value to {\tt handle} makes this function perform an implicit handle
+non-blocking transfer.
+
+\subsection{Explicit Synchronization}
+
+\begin{verbatim}
+int ARMCI_Wait(armci_hdl_t *handle);
+int ARMCI_WaitProc(int proc);
+int ARMCI_WaitAll();
+int ARMCI_Test(armci_hdl_t *handle);
+int ARMCI_Barrier();
+\end{verbatim}
+
+\begin{verbatim}
+int ARMCI_Fence(int proc);
+\end{verbatim}
+Blocks the calling process until all {\em put} or {\em accumulate}
+operations the process issued to the remote process {\tt proc} are
+completed at the destination.
+
+\begin{verbatim}
+int ARMCI_AllFence(void);
+\end{verbatim}
+Blocks the calling process until all outstanding {\em put} or {\em
+accumulate} operations it issued are completed on all remote
+destinations.
+
+\subsection{Extensions to the Standard API}
+\label{sec::extensions}
+
+\begin{verbatim}
+void ARMCI_Migrate(void);
+void ARMCI_Async_Migrate(void);
+void ARMCI_Checkpoint(char* dirname);
+void ARMCI_MemCheckpoint(void);
+
+int armci_notify(int proc);
+int armci_notify_wait(int proc, int *pval);
+\end{verbatim}
+
+\section{List of Unimplemented Functions}
+
+The following functions are supported on the standard ARMCI
+implementation but not yet supported in the \charmpp{} port.
+
+\begin{verbatim}
+int ARMCI_GetV(...);
+int ARMCI_NbGetV(...);
+int ARMCI_PutV(...);
+int ARMCI_NbPutV(...);
+int ARMCI_AccV(...);
+int ARMCI_NbAccV(...);
+
+int ARMCI_Acc(...);
+int ARMCI_NbAcc(...);
+int ARMCI_AccS(...);
+int ARMCI_NbAccS(...);
+
+int ARMCI_PutValueLong(long src, void* dst, int proc);
+int ARMCI_PutValueInt(int src, void* dst, int proc);
+int ARMCI_PutValueFloat(float src, void* dst, int proc);
+int ARMCI_PutValueDouble(double src, void* dst, int proc);
+int ARMCI_NbPutValueLong(long src, void* dst, int proc, armci_hdl_t* handle);
+int ARMCI_NbPutValueInt(int src, void* dst, int proc, armci_hdl_t* handle);
+int ARMCI_NbPutValueFloat(float src, void* dst, int proc, armci_hdl_t* handle);
+int ARMCI_NbPutValueDouble(double src, void* dst, int proc, armci_hdl_t* handle);
+long ARMCI_GetValueLong(void *src, int proc);
+int ARMCI_GetValueInt(void *src, int proc);
+float ARMCI_GetValueFloat(void *src, int proc);
+double ARMCI_GetValueDouble(void *src, int proc);
+
+void ARMCI_SET_AGGREGATE_HANDLE (armci_hdl_t* handle);
+void ARMCI_UNSET_AGGREGATE_HANDLE (armci_hdl_t* handle);
+
+int ARMCI_Rmw(int op, int *ploc, int *prem, int extra, int proc);
+int ARMCI_Create_mutexes(int num);
+int ARMCI_Destroy_mutexes(void);
+void ARMCI_Lock(int mutex, int proc);
+void ARMCI_Unlock(int mutex, int proc);
+\end{verbatim}
+
+\section{Error Codes}
+\label{sec::error codes}
+
+As of this writing, attempts to locate the documented error codes have
+failed because the release notes have not been found. Attempts are
+being made to derive these from the ARMCI source directly. Currently
+\charmpp{} implementation does not implement any error codes.
+
+\section{Related Manuals and Documents}
+\label{sec::related doc}
+
+\noindent
+ARMCI website:
+\begin{verbatim}
+http://www.emsl.pnl.gov/docs/parsoft/armci/index.html
+\end{verbatim}
+
+\end{document}