diff options
author | eschnett <eschnett@b3af07ca-673a-47aa-a5b3-f2a15d1427d7> | 2010-12-03 15:32:13 +0000 |
---|---|---|
committer | eschnett <eschnett@b3af07ca-673a-47aa-a5b3-f2a15d1427d7> | 2010-12-03 15:32:13 +0000 |
commit | f2feb453dd6ee6eab59b375e99134fff179195ab (patch) | |
tree | d52ce03e390dae9ca1ea94a23b419cb1a5c536d2 | |
parent | 78a10d17d611a56c802ed54739a79c77162618ce (diff) |
Initial implementation
git-svn-id: http://svn.cactuscode.org/arrangements/CactusUtils/NoMPI/trunk@2 b3af07ca-673a-47aa-a5b3-f2a15d1427d7
-rw-r--r-- | README | 13 | ||||
-rw-r--r-- | doc/documentation.tex | 144 | ||||
-rw-r--r-- | interface.ccl | 5 | ||||
-rw-r--r-- | param.ccl | 1 | ||||
-rw-r--r-- | schedule.ccl | 1 | ||||
-rw-r--r-- | src/make.code.defn | 7 | ||||
-rw-r--r-- | src/nompi.c | 420 | ||||
-rw-r--r-- | src/nompi.h | 215 |
8 files changed, 806 insertions, 0 deletions
@@ -0,0 +1,13 @@ +Cactus Code Thorn NoMPI +Author(s) : Erik Schnetter <schnetter@cct.lsu.edu> +Maintainer(s): Erik Schnetter <schnetter@cct.lsu.edu> +Licence : GPL +-------------------------------------------------------------------------- + +1. Purpose + +Provide a dummy MPI implementation that works only a single process. +This implements only a subset of the MPI standard. + +This thorn disables itself when an actual MPI implementation is +present. diff --git a/doc/documentation.tex b/doc/documentation.tex new file mode 100644 index 0000000..d154c08 --- /dev/null +++ b/doc/documentation.tex @@ -0,0 +1,144 @@ +% *======================================================================* +% Cactus Thorn template for ThornGuide documentation +% Author: Ian Kelley +% Date: Sun Jun 02, 2002 +% $Header$ +% +% Thorn documentation in the latex file doc/documentation.tex +% will be included in ThornGuides built with the Cactus make system. +% The scripts employed by the make system automatically include +% pages about variables, parameters and scheduling parsed from the +% relevant thorn CCL files. +% +% This template contains guidelines which help to assure that your +% documentation will be correctly added to ThornGuides. More +% information is available in the Cactus UsersGuide. +% +% Guidelines: +% - Do not change anything before the line +% % START CACTUS THORNGUIDE", +% except for filling in the title, author, date, etc. fields. +% - Each of these fields should only be on ONE line. +% - Author names should be separated with a \\ or a comma. +% - You can define your own macros, but they must appear after +% the START CACTUS THORNGUIDE line, and must not redefine standard +% latex commands. +% - To avoid name clashes with other thorns, 'labels', 'citations', +% 'references', and 'image' names should conform to the following +% convention: +% ARRANGEMENT_THORN_LABEL +% For example, an image wave.eps in the arrangement CactusWave and +% thorn WaveToyC should be renamed to CactusWave_WaveToyC_wave.eps +% - Graphics should only be included using the graphicx package. +% More specifically, with the "\includegraphics" command. Do +% not specify any graphic file extensions in your .tex file. This +% will allow us to create a PDF version of the ThornGuide +% via pdflatex. +% - References should be included with the latex "\bibitem" command. +% - Use \begin{abstract}...\end{abstract} instead of \abstract{...} +% - Do not use \appendix, instead include any appendices you need as +% standard sections. +% - For the benefit of our Perl scripts, and for future extensions, +% please use simple latex. +% +% *======================================================================* +% +% Example of including a graphic image: +% \begin{figure}[ht] +% \begin{center} +% \includegraphics[width=6cm]{MyArrangement_MyThorn_MyFigure} +% \end{center} +% \caption{Illustration of this and that} +% \label{MyArrangement_MyThorn_MyLabel} +% \end{figure} +% +% Example of using a label: +% \label{MyArrangement_MyThorn_MyLabel} +% +% Example of a citation: +% \cite{MyArrangement_MyThorn_Author99} +% +% Example of including a reference +% \bibitem{MyArrangement_MyThorn_Author99} +% {J. Author, {\em The Title of the Book, Journal, or periodical}, 1 (1999), +% 1--16. {\tt http://www.nowhere.com/}} +% +% *======================================================================* + +% If you are using CVS use this line to give version information +% $Header$ + +\documentclass{article} + +% Use the Cactus ThornGuide style file +% (Automatically used from Cactus distribution, if you have a +% thorn without the Cactus Flesh download this from the Cactus +% homepage at www.cactuscode.org) +\usepackage{../../../../doc/latex/cactus} + +\begin{document} + +% The author of the documentation +\author{Erik Schnetter \textless schnetter@cct.lsu.edu\textgreater} + +% The title of the document (not necessarily the name of the Thorn) +\title{NoMPI} + +% the date your document was last changed, if your document is in CVS, +% please use: +% \date{$ $Date: 2004-01-07 14:12:39 -0600 (Wed, 07 Jan 2004) $ $} +\date{October 02 2010} + +\maketitle + +% Do not delete next line +% START CACTUS THORNGUIDE + +% Add all definitions used in this documentation here +% \def\mydef etc + +% Add an abstract for this thorn's documentation +\begin{abstract} + +\end{abstract} + +% The following sections are suggestive only. +% Remove them or add your own. + +\section{Introduction} + +\section{Physical System} + +\section{Numerical Implementation} + +\section{Using This Thorn} + +\subsection{Obtaining This Thorn} + +\subsection{Basic Usage} + +\subsection{Special Behaviour} + +\subsection{Interaction With Other Thorns} + +\subsection{Examples} + +\subsection{Support and Feedback} + +\section{History} + +\subsection{Thorn Source Code} + +\subsection{Thorn Documentation} + +\subsection{Acknowledgements} + + +\begin{thebibliography}{9} + +\end{thebibliography} + +% Do not delete next line +% END CACTUS THORNGUIDE + +\end{document} diff --git a/interface.ccl b/interface.ccl new file mode 100644 index 0000000..d86a9c4 --- /dev/null +++ b/interface.ccl @@ -0,0 +1,5 @@ +# Interface definition for thorn NoMPI + +IMPLEMENTS: NoMPI + +INCLUDES HEADER: nompi.h IN nompi.h diff --git a/param.ccl b/param.ccl new file mode 100644 index 0000000..6d9c56d --- /dev/null +++ b/param.ccl @@ -0,0 +1 @@ +# Parameter definitions for thorn NoMPI diff --git a/schedule.ccl b/schedule.ccl new file mode 100644 index 0000000..1ca88ec --- /dev/null +++ b/schedule.ccl @@ -0,0 +1 @@ +# Schedule definitions for thorn NoMPI diff --git a/src/make.code.defn b/src/make.code.defn new file mode 100644 index 0000000..f3f5bf3 --- /dev/null +++ b/src/make.code.defn @@ -0,0 +1,7 @@ +# Main make.code.defn file for thorn NoMPI + +# Source files in this directory +SRCS = nompi.c + +# Subdirectories containing source files +SUBDIRS = diff --git a/src/nompi.c b/src/nompi.c new file mode 100644 index 0000000..4bfb283 --- /dev/null +++ b/src/nompi.c @@ -0,0 +1,420 @@ +#include <cctk.h> + +#ifndef CCTK_MPI + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +// IRIX wants this before <time.h> +#if HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +#if TIME_WITH_SYS_TIME +# include <sys/time.h> +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# elif HAVE_TIME_H +# include <time.h> +# endif +#endif + +#if HAVE_UNISTD_H +# include <unistd.h> +#endif + +#include "nompi.h" + + + +int MPI_Abort (MPI_Comm const comm, int const errorcode) +{ + exit(errorcode); +} + +int +MPI_Allgather (void* const sendbuf, int const sendcnt, + MPI_Datatype const sendtype, + void* const recvbuf, int const recvcnt, + MPI_Datatype const recvtype, + MPI_Comm const comm) +{ + assert (sendbuf); + assert (sendcnt >= 0); + assert (recvbuf); + assert (recvcnt >= 0); + assert (recvcnt == sendcnt); + assert (recvtype == sendtype); + MPI_Aint const recvsize = recvtype; + assert (recvsize > 0); + memcpy (recvbuf, sendbuf, recvcnt * recvsize); + return 0; +} + +int +MPI_Allgatherv (void* const sendbuf, int const sendcnt, + MPI_Datatype const sendtype, + void* const recvbuf, int* const recvcnts, int* const recvoffs, + MPI_Datatype const recvtype, + MPI_Comm const comm) +{ + assert (sendbuf); + assert (sendcnt >= 0); + assert (recvbuf); + assert (recvcnts); + assert (recvcnts[0] == sendcnt); + assert (recvoffs[0] == 0); + assert (recvtype == sendtype); + MPI_Aint const recvsize = recvtype; + assert (recvsize > 0); + memcpy (recvbuf, sendbuf, recvcnts[0] * recvsize); + return 0; +} + +int +MPI_Allreduce (void* const sendbuf, void* const recvbuf, int const cnt, + MPI_Datatype const datatype, MPI_Op const op, + MPI_Comm const comm) +{ + assert (sendbuf); + assert (recvbuf); + assert (cnt >= 0); + MPI_Aint const recvsize = datatype; + assert (recvsize > 0); + memcpy (recvbuf, sendbuf, cnt * recvsize); + return 0; +} + +int +MPI_Alltoall (void* const sendbuf, int const sendcnt, + MPI_Datatype const sendtype, + void* const recvbuf, int const recvcnt, + MPI_Datatype const recvtype, + MPI_Comm const comm) +{ + assert (sendbuf); + assert (sendcnt >= 0); + assert (recvbuf); + assert (recvcnt >= 0); + assert (recvcnt == sendcnt); + assert (recvtype == sendtype); + MPI_Aint const recvsize = recvtype; + assert (recvsize > 0); + memcpy (recvbuf, sendbuf, recvcnt * recvsize); + return 0; +} + +int +MPI_Alltoallv (void* const sendbuf, int* const sendcnts, int* const sendoffs, + MPI_Datatype const sendtype, + void* const recvbuf, int* const recvcnts, int* const recvoffs, + MPI_Datatype const recvtype, + MPI_Comm const comm) +{ + assert (sendbuf); + assert (sendcnts); + assert (sendoffs); + assert (sendoffs[0] == 0); + assert (recvbuf); + assert (recvcnts); + assert (recvcnts[0] == sendcnts[0]); + assert (recvoffs); + assert (recvoffs[0] == 0); + assert (recvtype == sendtype); + MPI_Aint const recvsize = recvtype; + assert (recvsize > 0); + memcpy (recvbuf, sendbuf, recvcnts[0] * recvsize); + return 0; +} + +int +MPI_Barrier (MPI_Comm const comm) +{ + return 0; +} + +int +MPI_Bcast (void* const buf, int const cnt, + MPI_Datatype const datatype, + int const root, MPI_Comm const comm) +{ + assert (buf); + assert (cnt >= 0); + assert (root == 0); + return 0; +} + +int +MPI_Comm_rank (MPI_Comm const comm, int* const rank) +{ + assert (rank); + *rank = 0; + return 0; +} + +int +MPI_Comm_size (MPI_Comm const comm, int* const size) +{ + assert (size); + *size = 1; + return 0; +} + +int +MPI_Comm_split (MPI_Comm const comm, int const color, int const key, + MPI_Comm *const newcomm) +{ + assert (newcomm); + return 0; +} + +int +MPI_Dims_create (int const nnodes, int const ndims, int* const dims) +{ + assert (dims); + int npoints = 1; + for (int d=0; d<ndims; ++d) { + assert (dims[d] >= 0); + if (dims[d] > 0) npoints *= dims[d]; + } + assert (npoints % nnodes == 0); + assert (nnodes == 1); /* Assume there is one node per MPI process */ + for (int d=0; d<ndims; ++d) { + if (dims[d] == 0) dims[d] = 1; + } + return 0; +} + +int +MPI_Finalize (void) +{ + return 0; +} + +int +MPI_Gather (void* const sendbuf, int const sendcnt, + MPI_Datatype const sendtype, + void* const recvbuf, int const recvcnt, + MPI_Datatype const recvtype, + int const root, MPI_Comm const comm) +{ + assert (sendbuf); + assert (sendcnt >= 0); + assert (recvbuf); + assert (recvcnt >= 0); + assert (recvtype == sendtype); + assert (root == 0); + MPI_Aint const recvsize = recvtype; + assert (recvsize > 0); + memcpy (recvbuf, sendbuf, recvcnt * recvsize); + return 0; +} + +int +MPI_Gatherv (void* const sendbuf, int const sendcnt, + MPI_Datatype const sendtype, + void* const recvbuf, int* const recvcnts, int* const recvoffs, + MPI_Datatype const recvtype, + int const root, MPI_Comm const comm) +{ + assert (sendbuf); + assert (sendcnt >= 0); + assert (recvbuf); + assert (recvcnts); + assert (recvcnts[0] >= 0); + assert (recvcnts[0] == sendcnt); + assert (recvoffs); + assert (recvoffs[0] == 0); + assert (recvtype == sendtype); + assert (root == 0); + MPI_Aint const recvsize = recvtype; + assert (recvsize > 0); + memcpy (recvbuf, sendbuf, recvcnts[0] * recvsize); + return 0; +} + +int +MPI_Init (int* const argc, char*** const argv) +{ + return 0; +} + +int +MPI_Irecv (void* const buf, int const cnt, MPI_Datatype const datatype, + int const source, int const tag, MPI_Comm const comm, + MPI_Request* const request) +{ + /* this should not be called */ + assert(0); + return -1; +} + +int +MPI_Isend (void* const buf, int const count, MPI_Datatype const datatype, + int const dest, int const tag, MPI_Comm const comm, + MPI_Request* const request) +{ + /* this should not be called */ + assert(0); + return -1; +} + +int +MPI_Pcontrol (int const level, ... ) +{ + /* do nothing */ + return 0; +} + +int +MPI_Reduce (void* const sendbuf, void* const recvbuf, int const cnt, + MPI_Datatype const datatype, MPI_Op const op, int const root, + MPI_Comm const comm) +{ + assert (sendbuf); + assert (recvbuf); + assert (cnt >= 0); + assert (root == 0); + int const datasize = datatype; + assert (datasize > 0); + memcpy (recvbuf, sendbuf, cnt * datasize); + return 0; +} + +int +MPI_Send (void* const buf, int const count, MPI_Datatype const datatype, + int const dest, int const tag, MPI_Comm const comm) +{ + /* this should not be called */ + assert(0); + return -1; +} + +int +MPI_Ssend (void* const buf, int const count, MPI_Datatype const datatype, + int const dest, int const tag, MPI_Comm const comm) +{ + /* this should not be called */ + assert(0); + return -1; +} + +int +MPI_Type_commit (MPI_Datatype* const datatype) +{ + /* do nothing */ + return 0; +} + +int +MPI_Type_contiguous (int const cnt, MPI_Datatype const oldtype, + MPI_Datatype* const newtype) +{ + assert (oldtype > 0); + *newtype = cnt * oldtype; + return 0; +} + +int +MPI_Type_free (MPI_Datatype* const datatype) +{ + /* do nothing */ + return 0; +} + +int +MPI_Type_lb (MPI_Datatype const datatype, MPI_Aint* const displacement) +{ + assert (displacement); + *displacement = 0; + return 0; +} + +int +MPI_Type_size (MPI_Datatype const datatype, int* const size) +{ + assert (datatype > 0); + assert (size); + *size = datatype; + return 0; +} + +int +MPI_Type_struct (int const cnt, + int* const array_of_blocklengths, + MPI_Aint* const array_of_displacements, + MPI_Datatype* const array_of_types, + MPI_Datatype* const newtype) +{ + assert (cnt >= 0); + assert (array_of_blocklengths); + assert (array_of_displacements); + assert (array_of_types); + assert (newtype); + MPI_Aint newsize = 0; + for (int n=0; n<cnt; ++n) { + assert (array_of_displacements[n] >= 0); + assert (array_of_blocklengths[n] >= 0); + MPI_Aint size; + if (array_of_types[n] == MPI_UB) { + size = array_of_displacements[n]; + } else { + assert (array_of_types[n] > 0); + size = + array_of_displacements[n] + + array_of_blocklengths[n] * array_of_types[n]; + } + if (size > newsize) newsize = size; + } + *newtype = newsize; + return 0; +} + +int +MPI_Type_ub (MPI_Datatype const datatype, MPI_Aint* const displacement) +{ + assert (datatype > 0); + assert (displacement); + *displacement = datatype; + return 0; +} + +int +MPI_Type_vector (int const cnt, int const blocklength, int const stride, + MPI_Datatype const oldtype, MPI_Datatype* const newtype) +{ + assert (cnt >= 0); + assert (blocklength >= 0); + assert (stride > 0); + assert (oldtype > 0); + if (cnt == 0) { + *newtype = 0; + } else { + *newtype = (cnt * blocklength + (cnt-1) * stride) * oldtype; + } + return 0; +} + +int +MPI_Waitall (int const cnt, MPI_Request* const array_of_requests, + MPI_Status* const array_of_statuses) +{ + assert (cnt >= 0); + assert (array_of_requests); + return 0; +} + +double +MPI_Wtime (void) +{ + struct timeval tp; + gettimeofday (&tp, NULL); + return tp.tv_sec + tp.tv_usec / 1.0e+6; +} + + + +#endif /* #ifndef CCTK_MPI */ diff --git a/src/nompi.h b/src/nompi.h new file mode 100644 index 0000000..165d33d --- /dev/null +++ b/src/nompi.h @@ -0,0 +1,215 @@ +#ifndef NOMPI_H +#define NOMPI_H + +/* Provide (dummy) replacements for many MPI routines in case MPI is + not available */ + +#include <cctk.h> + + + +#ifndef CCTK_MPI + + + +#include <stdlib.h> + + + +typedef ptrdiff_t MPI_Aint; + +typedef int MPI_Comm; /* no content */ + +typedef MPI_Aint MPI_Datatype; + +typedef enum { + MPI_LOR, + MPI_MAX, + MPI_MIN, + MPI_PROD, + MPI_SUM, +} MPI_Op; + +typedef int MPI_Request; /* no content */ + +typedef int MPI_Status; /* no contend */ + + + +MPI_Comm const MPI_COMM_NULL = -1; +MPI_Comm const MPI_COMM_WORLD = 0; + +MPI_Datatype const MPI_DATATYPE_NULL = 0; +MPI_Datatype const MPI_CHAR = sizeof(char ); +MPI_Datatype const MPI_SHORT = sizeof(short ); +MPI_Datatype const MPI_INT = sizeof(int ); +MPI_Datatype const MPI_LONG = sizeof(long ); +MPI_Datatype const MPI_LONG_LONG_INT = sizeof(long long int ); +MPI_Datatype const MPI_UNSIGNED_CHAR = sizeof(unsigned char ); +MPI_Datatype const MPI_UNSIGNED_SHORT = sizeof(unsigned short); +MPI_Datatype const MPI_UNSIGNED = sizeof(unsigned ); +MPI_Datatype const MPI_UNSIGNED_LONG = sizeof(unsigned long ); +MPI_Datatype const MPI_FLOAT = sizeof(float ); +MPI_Datatype const MPI_DOUBLE = sizeof(double ); +MPI_Datatype const MPI_LONG_DOUBLE = sizeof(long double ); +MPI_Datatype const MPI_UB = -1; + +MPI_Request const MPI_REQUEST_NULL = -1; + +MPI_Status* const MPI_STATUSES_IGNORE = NULL; + + + +#ifdef __cplusplus +extern "C" { +#endif + +int +MPI_Abort (MPI_Comm const comm, int const errorcode); + +int +MPI_Allgather (void* const sendbuf, int const sendcnt, + MPI_Datatype const sendtype, + void* const recvbuf, int const recvcnt, + MPI_Datatype const recvtype, + MPI_Comm const comm); + +int +MPI_Allgatherv (void* const sendbuf, int const sendcnt, + MPI_Datatype const sendtype, + void* const recvbuf, int* const recvcnts, int* const recvoffs, + MPI_Datatype const recvtype, + MPI_Comm const comm); + +int +MPI_Allreduce (void* const sendbuf, void* const recvbuf, int const cnt, + MPI_Datatype const datatype, MPI_Op const op, + MPI_Comm const comm); + +int +MPI_Alltoall (void* const sendbuf, int const sendcnt, + MPI_Datatype const sendtype, + void* const recvbuf, int const recvcnt, + MPI_Datatype const recvtype, + MPI_Comm const comm); + +int +MPI_Alltoallv (void* const sendbuf, int* const sendcnts, int* const sendoffs, + MPI_Datatype const sendtype, + void* const recvbuf, int* const recvcnts, int* const recvoffs, + MPI_Datatype const recvtype, + MPI_Comm const comm); + +int +MPI_Barrier (MPI_Comm const comm); + +int +MPI_Bcast (void* const buf, int const cnt, + MPI_Datatype const datatype, + int const root, MPI_Comm const comm); + +int +MPI_Comm_rank (MPI_Comm const comm, int* const rank); + +int +MPI_Comm_size (MPI_Comm const comm, int* const size); + +int +MPI_Comm_split (MPI_Comm const comm, int const color, int const key, + MPI_Comm *const newcomm); + +int +MPI_Dims_create (int const nnodes, int const ndims, int* const dims); + +int +MPI_Finalize (void); + +int +MPI_Gather (void* const sendbuf, int const sendcnt, + MPI_Datatype const sendtype, + void* const recvbuf, int const recvcnt, + MPI_Datatype const recvtype, + int const root, MPI_Comm const comm); + +int +MPI_Gatherv (void* const sendbuf, int const sendcnt, + MPI_Datatype const sendtype, + void* const recvbuf, int* const recvcnts, int* const recvoffs, + MPI_Datatype const recvtype, + int const root, MPI_Comm const comm); + +int +MPI_Init (int* const argc, char*** const argv); + +int +MPI_Irecv (void* const buf, int const cnt, MPI_Datatype const datatype, + int const source, int const tag, MPI_Comm const comm, + MPI_Request* const request); + +int +MPI_Isend (void* const buf, int const count, MPI_Datatype const datatype, + int const dest, int const tag, MPI_Comm const comm, + MPI_Request* const request); + +int +MPI_Pcontrol (int const level, ... ); + +int +MPI_Reduce (void* const sendbuf, void* const recvbuf, int const cnt, + MPI_Datatype const datatype, MPI_Op const op, int const root, + MPI_Comm const comm); + +int +MPI_Send (void* const buf, int const count, MPI_Datatype const datatype, + int const dest, int const tag, MPI_Comm const comm); + +int +MPI_Ssend (void* const buf, int const count, MPI_Datatype const datatype, + int const dest, int const tag, MPI_Comm const comm); + +int +MPI_Type_commit (MPI_Datatype* const datatype); + +int +MPI_Type_contiguous (int const cnt, MPI_Datatype const oldtype, + MPI_Datatype* const newtype); + +int +MPI_Type_free (MPI_Datatype* const datatype); + +int +MPI_Type_lb (MPI_Datatype const datatype, MPI_Aint* const displacement); + +int +MPI_Type_size (MPI_Datatype const datatype, int* const size); + +int +MPI_Type_struct (int const cnt, + int* const array_of_blocklengths, + MPI_Aint* const array_of_displacements, + MPI_Datatype* const array_of_types, + MPI_Datatype* const newtype); + +int +MPI_Type_ub (MPI_Datatype const datatype, MPI_Aint* const displacement); + +int +MPI_Type_vector (int const cnt, int const blocklength, int const stride, + MPI_Datatype const oldtype, MPI_Datatype* const newtype); + +int +MPI_Waitall (int const cnt, MPI_Request* const array_of_requests, + MPI_Status* const array_of_statuses); + +double +MPI_Wtime (void); + +#ifdef __cplusplus +} +#endif + + + +#endif /* #ifndef CCTK_MPI */ + +#endif /* #ifndef NOMPI_H */ |