Merge branch 'charm' of charmgit:charm into charm
authorIsaac Dooley <idooley2@krakenpf1.nics.utk.edu>
Tue, 26 Jan 2010 18:06:46 +0000 (13:06 -0500)
committerIsaac Dooley <idooley2@krakenpf1.nics.utk.edu>
Tue, 26 Jan 2010 18:06:46 +0000 (13:06 -0500)
71 files changed:
doc/charm++/controlpoints.tex [new file with mode: 0644]
doc/charm++/manual.tex
doc/faq/install.tex
doc/faq/manual.tex
doc/faq/overview.tex
src/arch/common/conv-mach-bigsim.h
src/arch/cuda/hybridAPI/cuda-hybrid-api.cu
src/arch/mpi-crayxt/conv-mach-smp.h
src/arch/mpi-crayxt3/conv-mach-smp.h
src/arch/mpi-darwin-ppc/conv-mach-smp.h
src/arch/mpi-linux-mips64/conv-mach-smp.h
src/arch/mpi-linux-x86_64/cc-mpicxx.sh
src/arch/mpi-linux-x86_64/conv-mach-smp.h
src/arch/mpi-linux/conv-mach-smp.h
src/arch/mpi-linux/conv-mach-vmi.h
src/arch/multicore-darwin-x86/conv-mach.h
src/arch/multicore-darwin-x86_64/conv-mach.h
src/arch/net-darwin-x86/conv-mach-smp.h
src/arch/net-linux-x86_64/conv-mach.h
src/arch/net-linux/conv-mach-smp.h
src/arch/net-linux/conv-mach.h
src/ck-com/ComlibManager.C
src/ck-com/ComlibStats.C
src/ck-core/charm++.h
src/ck-core/ck.C
src/ck-core/ck.h
src/ck-core/ckcallback.C
src/ck-core/ckcallback.h
src/ck-core/ckcheckpoint.C
src/ck-core/ckmemcheckpoint.C
src/ck-core/ckreduction.C
src/ck-core/ckreduction.h
src/ck-core/debug-charm.C
src/ck-core/envelope.h
src/ck-core/init.C
src/ck-core/init.h
src/ck-cp/controlPoints.C
src/ck-cp/controlPoints.h
src/ck-ldb/NullLB.C
src/ck-perf/trace-controlPoints.C
src/ck-perf/trace-controlPoints.h
src/ck-perf/trace-recordreplay.C [deleted file]
src/ck-perf/trace-recordreplay.h [deleted file]
src/conv-ccs/conv-ccs.c
src/conv-core/converse.h
src/conv-core/debug-conv.c
src/conv-core/debug-conv.h
src/conv-core/memory-charmdebug.c
src/conv-core/memory.c
src/conv-core/quiescence.c
src/conv-core/threads.c
src/libs/ck-libs/armci/armci.h
src/libs/ck-libs/armci/armci_api.C
src/libs/ck-libs/armci/armci_impl.h
src/libs/ck-libs/armci/armci_vp.C
src/scripts/Make.depends
src/scripts/Makefile
src/scripts/configure
src/scripts/configure.in
src/util/ckhashtable.C
src/util/ckhashtable.h
src/util/crc32.c
src/util/crc32.h
src/util/simd.h
tests/charm++/simplearrayhello-crosscorruption/Makefile [new file with mode: 0644]
tests/charm++/simplearrayhello-crosscorruption/hello.C [new file with mode: 0644]
tests/charm++/simplearrayhello-crosscorruption/hello.ci [new file with mode: 0644]
tests/util/Makefile
tests/util/headerpad.C [new file with mode: 0644]
tests/util/headerpad.ci [new file with mode: 0644]
tests/util/headerpad.h [new file with mode: 0644]

diff --git a/doc/charm++/controlpoints.tex b/doc/charm++/controlpoints.tex
new file mode 100644 (file)
index 0000000..a70d7b6
--- /dev/null
@@ -0,0 +1,128 @@
+\section{Control Point Automatic Tuning Framework}
+
+\index{Control Point Automatic Tuning Framework}
+\label{sec:controlpoint}
+
+
+\charmpp{} currently includes an experimental automatic tuning
+framework that can dynamically adapt a program at runtime to improve
+its performance. The program provides a set of tunable knobs that are
+adjusted automatically by the tuning framework. The user program also
+provides information about the control points so that intelligent
+tuning choices can be made. This information will be used to steer the
+program instead of requiring the tuning framework to blindly search
+the possible program configurations.
+
+\textbf{Warning: this is still an experimental feature not meant for production applications}
+
+\subsection{Exposing Control Points in a Charm++ Program}
+The program should include a header file before any of its \texttt{*.decl.h} files:
+
+\begin{alltt} 
+    #include <controlPoints.h> 
+\end{alltt} 
+
+The control point framework initializes itself, so no changes need to be made at startup in the program.
+
+The program will request the values for each control point on PE 0. Control point values are non-negative integers:
+
+\begin{alltt} 
+    my_var = controlPoint("any_name", 5, 10);
+    my_var2 = controlPoint("another_name", 100,101);
+\end{alltt} 
+
+To specify information about the effects of each control point, make calls such as these once on PE 0 before accessing any control point values:
+
+\begin{alltt} 
+    ControlPoint::EffectDecrease::Granularity("num_chare_rows");
+    ControlPoint::EffectDecrease::Granularity("num_chare_cols");
+    ControlPoint::EffectIncrease::NumMessages("num_chare_rows");
+    ControlPoint::EffectIncrease::NumMessages("num_chare_cols");
+    ControlPoint::EffectDecrease::MessageSizes("num_chare_rows");
+    ControlPoint::EffectDecrease::MessageSizes("num_chare_cols");
+    ControlPoint::EffectIncrease::Concurrency("num_chare_rows");
+    ControlPoint::EffectIncrease::Concurrency("num_chare_cols");
+    ControlPoint::EffectIncrease::NumComputeObjects("num_chare_rows");
+    ControlPoint::EffectIncrease::NumComputeObjects("num_chare_cols");
+\end{alltt} 
+
+For a complete list of these functions, see \texttt{cp\_effects.h} in \texttt{charm/include}.
+
+
+The program, of course, has to adapt its behavior to use these new control point values. There are two ways for a the control point values to change over time. The program can request that a new phase (with its own control point values) be used whenever it wants, or the control point framework can automatically advance to a new phase periodically. The structure of the program will be slightly different in these to cases. Sections \ref{frameworkAdvancesPhases} and \ref{programAdvancesPhases} describe the additional changes to the program that should be made for each case.
+
+\subsubsection{Control Point Framework Advances Phases}
+\label{frameworkAdvancesPhases}
+
+The program provides a callback to the control point framework in a manner such as this:
+
+\begin{alltt} 
+    // Once early on in program, create a callback, and register it 
+    CkCallback cb(CkIndex_Main::granularityChange(NULL),thisProxy); 
+    registerCPChangeCallback(cb, true);
+\end{alltt} 
+
+In the callback or after the callback has executed, the program should request the new control point values on PE 0, and adapt its behavior appropriately.
+
+Alternatively, the program can specify that it wants to call \texttt{gotoNextPhase();} itself when it is ready. Perhaps the program wishes to delay its adaptation for a while. To do this, it specifies \texttt{false} as the final parameter to \texttt{registerCPChangeCallback} as follows:
+
+\begin{alltt} 
+   registerCPChangeCallback(cb, false);
+\end{alltt} 
+
+
+\subsubsection{Program Advances Phases}
+\label{programAdvancesPhases}
+
+\begin{alltt} 
+     registerControlPointTiming(duration); // called after each program iteration on PE 0
+     gotoNextPhase(); // called after some number of iterations on PE 0
+    // Then request new control point values
+\end{alltt} 
+
+
+
+\subsection{Linking With The Control Point Framework}
+
+The program should be linked with the following options to compile in the control point framework:
+
+\texttt{-module ControlPoints -tracemode controlPoints}
+
+The \texttt{ControlPoint} module contains the framework code responsible for recording information about the running program as well as adjust the control point values. The trace module will enable measurements to be gathered including information about utilization, idle time, and memory usage. 
+
+\subsection{Runtime Command Line Arguments}
+
+Various following command line arguments will affect the behavior of the program when running with the control point framework. As this is an experimental framework, these are subject to change.
+
+The scheme used for tuning can be selected at runtime by the use of one of the following options:
+\begin{alltt} 
+    +CPSchemeRandom            Randomly Select Control Point Values
+ +CPExhaustiveSearch            Exhaustive Search of Control Point Values
+      +CPSimulAnneal            Simulated Annealing Search of Control Point Values
+ +CPCriticalPathPrio            Use Critical Path to adapt Control Point Values
+        +CPBestKnown            Use BestKnown Timing for Control Point Values
+         +CPSteering            Use Steering to adjust Control Point Values
+      +CPMemoryAware            Adjust control points to approach available memory
+\end{alltt} 
+
+To intelligently tune or steer an application's performance, performance measurements ought to be used. Some of the schemes above require that memory footprint statistics and utilization statistics be gathered. The following flags enable the gathering of such measurements.
+\begin{alltt} 
+       +CPGatherAll            Gather all types of measurements for each phase
++CPGatherMemoryUsage            Gather memory usage after each phase
++CPGatherUtilization            Gather utilization & Idle time after each phase
+\end{alltt} 
+
+
+The control point framework will periodically adapt the control point values. The following command line flag determines the frequency at which the control point framework will attempt to adjust things.
+\begin{alltt} 
+     +CPSamplePeriod     number The time between Control Point Framework samples (in seconds)
+\end{alltt} 
+
+The data from one run of the program can be saved and used in subsequent runs. The following command line arguments specify that a file named \texttt{controlPointData.txt} should be created or loaded. This file contains measurements for each phase as well as the control point values used in each phase. 
+\begin{alltt} 
+        +CPSaveData            Save Control Point timings & configurations at completion
+         +CPLoadData            Load Control Point timings & configurations at startup
+\end{alltt} 
+
+It might be useful for example, to run once with \texttt{+CPSimulAnneal +CPSaveData} to try to find a good configuration for the program, and then use  \texttt{+CPBestKnown +CPLoadData} for all subsequent production runs.
+
index b39e0d583a0cff320c64fde01223bcc80b043260..e55a5655b32581178e68e99fdbdb6dbda6a8d267 100644 (file)
@@ -2,60 +2,64 @@
 
 \usepackage{../pplmanual} \input{../pplmanual} \usepackage{html}
 \title{The\\ \charmpp\\ Programming Language\\ Manual} \version{6.0
-(Release 1)} \credits{ {\small The Charm software was developed as a
-group effort.  The earliest prototype, Chare Kernel(1.0), was
-developed by Wennie Shu and Kevin Nomura working with Laxmikant Kale.
-The second prototype, Chare Kernel(2.0), a complete re-write with
-major design changes, was developed by a team consisting of Wayne
-Fenton, Balkrishna Ramkumar, Vikram Saletore, Amitabh B. Sinha and
-Laxmikant Kale. The translator for Chare Kernel(2.0) was written by
-Manish Gupta.  Charm(3.0), with significant design changes, was
-developed by a team consisting of Attila Gursoy, Balkrishna Ramkumar,
-Amitabh B.  Sinha and Laxmikant Kale, with a new translator written by
-Nimish Shah.  The \charmpp\ implementation was done by Sanjeev
-Krishnan.  Charm(4.0) included \charmpp\ and was released in fall
-1993.  Charm(4.5) was developed by Attila Gursoy, Sanjeev Krishnan,
-Milind Bhandarkar, Joshua Yelon, Narain Jagathesan and Laxmikant Kale.
-Charm(4.8), developed by the same team included Converse, a parallel
-runtime system that allows interoperability among modules written
-using different paradigms within a single application. \charmpp\
-runtime system was re-targetted at Converse. Syntactic extensions in
-\charmpp\ were dropped, and a simple interface translator was
-developed (by Sanjeev Krishnan and Jay DeSouza) that, along with the
-\charmpp\ runtime, became the \charmpp\ language.  Charm (5.4R1)
-included the following: a complete rewrite of the \charmpp\ runtime
-system (using \CC) and the interface translator (done by Milind
-Bhandarkar), several new features such as Chare Arrays (developed by
-Robert Brunner and Orion Lawlor), various libraries (written by Terry
-Wilmarth, Gengbin Zheng, Laxmikant Kale, Zehra Sura, Milind
-Bhandarkar, Robert Brunner, and Krishnan Varadarajan.) A coordination
-language ``Structured Dagger'' was been implemented on top of
-\charmpp\ (Milind Bhandarkar), dynamic seed-based load balancing
-(Terry Wilmarth and Joshua Yelon), a client-server interface for
-Converse programs, and debugging support by Parthasarathy
-Ramachandran, Jeff Wright, and Milind Bhandarkar, Projections, the
-performance visualization and analysis tool, was redesigned and
-rewritten using Java by Michael Denardo. The test suite for \charmpp\
-was developed by Michael Lang, Jackie Wang, and Fang Hu. Converse was
-been ported to ASCI Red (Joshua Yelon), Cray T3E (Robert Brunner), and
-SGI Origin2000 (Milind Bhandarkar). For the current version Charm 6.0
-(R1), Converse has been ported to new platforms including
-BlueGene/[LP] (Kumar, Huang, Bhatele), Cray XT3/4 (Zheng), Apple G5,
-Myrinet (Zheng), and Infiniband (Chakravorty).  Charm 6.0 introduces a
-dedicated no network SMP multicore Converse layer for stand-alone
-workstation experimenters (Zheng, Chakravorty, Kale, Jetley).  Charm
-6.0 also includes cross platform network topology aware chare
-placement for 3D tori and mesh networks (Kumar, Huang, Bhatele,
-Bohm). The test suite was extended for automated testing on all
-supported platforms by Gengbin Zheng.  The Projection tool was
-substantially improved by Chee Wai Lee and Isaac Dooley. Debugging
-support was enhanced with memory inspection features by Filippo
-Gioachin. The Charisma orchestration language was implemented on top
-of Charm++ by Chao Huang and Sanjay Kale.  Sanjay Kale, Orion Lawlor,
-Gengbin Zheng, Terry Wilmarth, Filippo Gioachin, Sayantan Chakravorty,
-Chao Huang, David Kunzman, Isaac Dooley, Eric Bohm, Sameer Kumar, Chao
-Mei, Pritish Jetley, and Abhinav Bhatele, have been responsible for
-the changes to the system since the last release.  } }
+  (Release 1)} \credits{ {\small The Charm software was developed as a
+    group effort.  The earliest prototype, Chare Kernel(1.0), was
+    developed by Wennie Shu and Kevin Nomura working with Laxmikant
+    Kale.  The second prototype, Chare Kernel(2.0), a complete
+    re-write with major design changes, was developed by a team
+    consisting of Wayne Fenton, Balkrishna Ramkumar, Vikram Saletore,
+    Amitabh B. Sinha and Laxmikant Kale. The translator for Chare
+    Kernel(2.0) was written by Manish Gupta.  Charm(3.0), with
+    significant design changes, was developed by a team consisting of
+    Attila Gursoy, Balkrishna Ramkumar, Amitabh B.  Sinha and
+    Laxmikant Kale, with a new translator written by Nimish Shah.  The
+    \charmpp\ implementation was done by Sanjeev Krishnan.  Charm(4.0)
+    included \charmpp\ and was released in fall 1993.  Charm(4.5) was
+    developed by Attila Gursoy, Sanjeev Krishnan, Milind Bhandarkar,
+    Joshua Yelon, Narain Jagathesan and Laxmikant Kale.  Charm(4.8),
+    developed by the same team included Converse, a parallel runtime
+    system that allows interoperability among modules written using
+    different paradigms within a single application. \charmpp\ runtime
+    system was re-targetted at Converse. Syntactic extensions in
+    \charmpp\ were dropped, and a simple interface translator was
+    developed (by Sanjeev Krishnan and Jay DeSouza) that, along with
+    the \charmpp\ runtime, became the \charmpp\ language.  Charm
+    (5.4R1) included the following: a complete rewrite of the
+    \charmpp\ runtime system (using \CC) and the interface translator
+    (done by Milind Bhandarkar), several new features such as Chare
+    Arrays (developed by Robert Brunner and Orion Lawlor), various
+    libraries (written by Terry Wilmarth, Gengbin Zheng, Laxmikant
+    Kale, Zehra Sura, Milind Bhandarkar, Robert Brunner, and Krishnan
+    Varadarajan.) A coordination language ``Structured Dagger'' was
+    been implemented on top of \charmpp\ (Milind Bhandarkar), dynamic
+    seed-based load balancing (Terry Wilmarth and Joshua Yelon), a
+    client-server interface for Converse programs, and debugging
+    support by Parthasarathy Ramachandran, Jeff Wright, and Milind
+    Bhandarkar, Projections, the performance visualization and
+    analysis tool, was redesigned and rewritten using Java by Michael
+    Denardo. The test suite for \charmpp\ was developed by Michael
+    Lang, Jackie Wang, and Fang Hu. Converse was been ported to ASCI
+    Red (Joshua Yelon), Cray T3E (Robert Brunner), and SGI Origin2000
+    (Milind Bhandarkar). For the current version Charm 6.0 (R1),
+    Converse has been ported to new platforms including BlueGene/[LP]
+    (Kumar, Huang, Bhatele), Cray XT3/4 (Zheng), Apple G5, Myrinet
+    (Zheng), and Infiniband (Chakravorty).  Charm 6.0 introduces a
+    dedicated no network SMP multicore Converse layer for stand-alone
+    workstation experimenters (Zheng, Chakravorty, Kale, Jetley).
+    Charm 6.0 also includes cross platform network topology aware
+    chare placement for 3D tori and mesh networks (Kumar, Huang,
+    Bhatele, Bohm). The test suite was extended for automated testing
+    on all supported platforms by Gengbin Zheng.  The Projection tool
+    was substantially improved by Chee Wai Lee and Isaac Dooley. The
+    Control Point performance tuning framework was created by Isaac
+    Dooley. Debugging support was enhanced with memory inspection
+    features by Filippo Gioachin. The Charisma orchestration language
+    was implemented on top of Charm++ by Chao Huang and Sanjay Kale.
+    Sanjay Kale, Orion Lawlor, Gengbin Zheng, Terry Wilmarth, Filippo
+    Gioachin, Sayantan Chakravorty, Chao Huang, David Kunzman, Isaac
+    Dooley, Eric Bohm, Sameer Kumar, Chao Mei, Pritish Jetley, and
+    Abhinav Bhatele, have been responsible for the changes to the
+    system since the last release.  } }
 
 \begin{document}
 
@@ -90,6 +94,9 @@ the changes to the system since the last release.  } }
 
 \input{checkpoint}
 
+\input{controlpoints}
+
+
 \appendix
 
 \input{sdag}
index 7ffbf1a3cea438eae6de62af017b0bff76761029..e23a99fedc673bbb8662303baaf0ed73bb0eadd6 100644 (file)
@@ -13,7 +13,7 @@ will likely contain bug fixes not found in the releases.
 \subsubsection{How do I compile Charm++?}
 
 Run the interactive build script {\tt ./build} with no extra arguments If this fails,
-email \htmladdnormallink{ppl@cs.uiuc.edu}{mailto:ppl@cs.uiuc.edu} with the
+email \htmladdnormallink{charm AT cs.uiuc.edu}{mailto:charm AT cs.uiuc.edu} with the
 problem. Include the build line used (this is saved automatically in
 {\tt smart-build.log})
 
@@ -22,7 +22,7 @@ If you have a very unusual machine configuration, you will have to run
 architecture, and then you may have to modify the associated conf-mach.sh and
 conv-mach.h files in src/arch to point to your desired compilers and options. If
 you develop a significantly different platform, send the modified files to
-\htmladdnormallink{ppl@cs.uiuc.edu}{mailto:ppl@cs.uiuc.edu} so we can include it
+\htmladdnormallink{charm AT cs.uiuc.edu}{mailto:charm AT cs.uiuc.edu} so we can include it
 in the distribution.
 
 \subsubsection{How do I compile AMPI?}
index 9ade097a9f5763e1e9fecd33adbdc0ed84d8b896..2444960b5cf0f70b6cf971068962ecf41134dc50 100644 (file)
@@ -4,14 +4,15 @@
 \usepackage{html}
 
 \title{\charmpp{}\\Frequently Asked Questions}
-\version{5.9 (Release 1)}
+\version{6.2 pre-release}
 \credits{empty}
 
 \begin{document}
 
 \maketitle
 
-For answers to questions not on this list, please contact us at \htmladdnormallink{ppl@cs.uiuc.edu}{mailto:ppl@cs.uiuc.edu}
+For answers to questions not on this list, please contact us at
+\htmladdnormallink{charm AT cs.uiuc.edu}{mailto:charm AT cs.uiuc.edu}
 
 \input{overview}
 \input{install}
index 4ac624e810171b71086257215af9a39f6d9df1c7..ed665c12167f8b6efcfcb836172498b93f46858d 100644 (file)
@@ -92,5 +92,6 @@ The actual, legal license is included with Charm++ (in charm/LICENSE).
 \subsubsection{I have a suggestion/feature request/bug report. Who should I send
 it to?}
 
-Our mailing list is \htmladdnormallink{ppl@cs.uiuc.edu}{mailto:ppl@cs.uiuc.edu} and our Wiki is \htmladdnormallink{CharmWiki}{http://charm.cs.uiuc.edu/xTwiki/bin/view}.
+Our mailing list is \htmladdnormallink{charm AT
+  cs.uiuc.edu}{mailto:charm AT cs.uiuc.edu}.
 We're always glad to get feedback on our software.
index e55a4c8b1f227830cc93909dad5b461105d1bba7..cfb0dfaaf06c55a0afe3fe962263650572b97826 100644 (file)
@@ -14,3 +14,6 @@
 
 #define BIGSIM_OUT_OF_CORE                                 0
 #define BIGSIM_OOC_PREFETCH                                0
+
+
+#define CMK_CHARE_USE_PTR                                  1
index bb783b82317cb08a2aca8c293544944672cd58c0..27253616ba8e63491b2328bf870260ce88a519f2 100644 (file)
@@ -194,10 +194,6 @@ void allocateBuffers(workRequest *wr) {
       int index = bufferInfo[i].bufferID; 
       int size = bufferInfo[i].size; 
 
-      if (bufferInfo[i].transferToDevice == 0) {
-       continue; 
-      }
-
       // if index value is invalid, use an available ID  
       if (index < 0 || index >= NUM_BUFFERS) {
        int found = 0; 
index 03de8fac024fd5e37a430c33c61fecc694d1f028..c561708cd719b98e5d6cd4e7b9cb01b577979e65 100644 (file)
@@ -7,5 +7,3 @@
 #undef CMK_SHARED_VARS_POSIX_THREADS_SMP
 #define CMK_SHARED_VARS_UNAVAILABLE                        0
 #define CMK_SHARED_VARS_POSIX_THREADS_SMP                  1
-
-#define CMK_LINUX_PTHREAD_HACK                             0
index 13a1e6c98b57d955c0b909c32547aba691bba9ee..397c743dd43c99b60f0026020753b142b578e567 100644 (file)
@@ -8,5 +8,3 @@
 #undef CMK_SHARED_VARS_POSIX_THREADS_SMP
 #define CMK_SHARED_VARS_UNAVAILABLE                        0
 #define CMK_SHARED_VARS_POSIX_THREADS_SMP                  1
-
-#define CMK_LINUX_PTHREAD_HACK                             1
index 767aa5652dff89359618e2cf2a092b1a4a25d848..f06e2a96ab19418ecd55c03da29eea1b981674eb 100644 (file)
@@ -1,10 +1,3 @@
-/*****************************************************************************
- * $Source$
- * $Author$
- * $Date$
- * $Revision$
- *****************************************************************************/
-
 #define CMK_SMP                                                   1
 
 #undef CMK_MALLOC_USE_GNU_MALLOC
@@ -23,8 +16,6 @@
 #define CMK_SHARED_VARS_UNAVAILABLE                        0
 #define CMK_SHARED_VARS_POSIX_THREADS_SMP                  1
 
-#define CMK_LINUX_PTHREAD_HACK                             1
-
 #undef CMK_SYNCHRONIZE_ON_TCP_CLOSE
 #define CMK_SYNCHRONIZE_ON_TCP_CLOSE                       1
 
index 767aa5652dff89359618e2cf2a092b1a4a25d848..f06e2a96ab19418ecd55c03da29eea1b981674eb 100644 (file)
@@ -1,10 +1,3 @@
-/*****************************************************************************
- * $Source$
- * $Author$
- * $Date$
- * $Revision$
- *****************************************************************************/
-
 #define CMK_SMP                                                   1
 
 #undef CMK_MALLOC_USE_GNU_MALLOC
@@ -23,8 +16,6 @@
 #define CMK_SHARED_VARS_UNAVAILABLE                        0
 #define CMK_SHARED_VARS_POSIX_THREADS_SMP                  1
 
-#define CMK_LINUX_PTHREAD_HACK                             1
-
 #undef CMK_SYNCHRONIZE_ON_TCP_CLOSE
 #define CMK_SYNCHRONIZE_ON_TCP_CLOSE                       1
 
index 60745844fd8c62d02e98b9fa9d918a51c26f68bd..f49ef1f89dad345c3251480f000b1917e43f1568 100644 (file)
@@ -18,6 +18,7 @@ CMK_REAL_COMPILER=`$MPICXX -show 2>/dev/null | cut -d' ' -f1 `
 case "$CMK_REAL_COMPILER" in
 g++)   CMK_AMD64="-m64 -fPIC" ;;
 icpc)  CMK_AMD64="-m64";;
+pgCC)  CMK_AMD64="-DCMK_CC_PGCC=1" ;;
 esac
 
 CMK_CPP_CHARM="/lib/cpp -P"
index e7cf1e84bae47831d008fdd09754517d7f8cee35..d151c6de355011430d9fd2abde8603243d35ef2b 100644 (file)
@@ -1,10 +1,3 @@
-/*****************************************************************************
- * $Source$
- * $Author$
- * $Date$
- * $Revision$
- *****************************************************************************/
-
 #define CMK_SMP                                                   1
 
 #undef CMK_NODE_QUEUE_AVAILABLE
@@ -15,8 +8,6 @@
 #define CMK_SHARED_VARS_UNAVAILABLE                        0
 #define CMK_SHARED_VARS_POSIX_THREADS_SMP                  1
 
-#define CMK_LINUX_PTHREAD_HACK                             0
-
 #undef CMK_TIMER_USE_GETRUSAGE
 #undef CMK_TIMER_USE_SPECIAL
 #define CMK_TIMER_USE_GETRUSAGE                            1
index 767aa5652dff89359618e2cf2a092b1a4a25d848..f06e2a96ab19418ecd55c03da29eea1b981674eb 100644 (file)
@@ -1,10 +1,3 @@
-/*****************************************************************************
- * $Source$
- * $Author$
- * $Date$
- * $Revision$
- *****************************************************************************/
-
 #define CMK_SMP                                                   1
 
 #undef CMK_MALLOC_USE_GNU_MALLOC
@@ -23,8 +16,6 @@
 #define CMK_SHARED_VARS_UNAVAILABLE                        0
 #define CMK_SHARED_VARS_POSIX_THREADS_SMP                  1
 
-#define CMK_LINUX_PTHREAD_HACK                             1
-
 #undef CMK_SYNCHRONIZE_ON_TCP_CLOSE
 #define CMK_SYNCHRONIZE_ON_TCP_CLOSE                       1
 
index f88be75e5e2857a7b1141db5fbff721e1e8bd2e2..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1 +0,0 @@
-#define CMK_LINUX_PTHREAD_HACK                             1
index 88e217b2e555932d690794682334c1ca3fa85c6b..2535cc964fbaf40b2ecd2381013a675d446f7344 100644 (file)
@@ -1,10 +1,3 @@
-/*****************************************************************************
- * $Source$
- * $Author$
- * $Date$
- * $Revision$
- *****************************************************************************/
-
 #ifndef _CONV_MACH_H
 #define _CONV_MACH_H
 
@@ -76,8 +69,6 @@
 */
 #define CMK_USE_KQUEUE                                     1
 
-#define CMK_MACOSX_PTHREAD_HACK                            1
-
 #if !CMK_GCC_X86_ASM || !CMK_GCC_X86_ASM_ATOMICINCREMENT
 #define CMK_PCQUEUE_LOCK                                   1
 #endif
index 43bd6fe473141f3272a43e6e9492356cbf8f31bd..0855967be332d7659e60e25cf866744497cee32b 100644 (file)
@@ -1,10 +1,3 @@
-/*****************************************************************************
- * $Source$
- * $Author$
- * $Date$
- * $Revision$
- *****************************************************************************/
-
 #ifndef _CONV_MACH_H
 #define _CONV_MACH_H
 
@@ -77,8 +70,6 @@
 */
 #define CMK_USE_KQUEUE                                     1
 
-#define CMK_MACOSX_PTHREAD_HACK                            1
-
 #if !CMK_GCC_X86_ASM || !CMK_GCC_X86_ASM_ATOMICINCREMENT
 #define CMK_PCQUEUE_LOCK                                   1
 #endif
index c02f35b821e757bbe333cd9f097786e026b2a12f..024c04001a7ec9cb00638efd3e39ab124224d534 100644 (file)
@@ -9,8 +9,6 @@
 #define CMK_SHARED_VARS_UNAVAILABLE                        0
 #define CMK_SHARED_VARS_POSIX_THREADS_SMP                  1
 
-#define CMK_MACOSX_PTHREAD_HACK                            1
-
 #if !CMK_GCC_X86_ASM || !CMK_GCC_X86_ASM_ATOMICINCREMENT
 #define CMK_PCQUEUE_LOCK                                   1
 #endif
index 36d6b51789e492b7e4746c47d0116381433c948d..d07d6ebf22a38ff2558629c0df17e73dfc49ef0e 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef _CONV_MACH_H
 #define _CONV_MACH_H
 
+#define CMK_NETPOLL         1
+
 #define CMK_AMD64                                         1
 
 #define CMK_ASYNC_NOT_NEEDED                               0
index 13a1e6c98b57d955c0b909c32547aba691bba9ee..397c743dd43c99b60f0026020753b142b578e567 100644 (file)
@@ -8,5 +8,3 @@
 #undef CMK_SHARED_VARS_POSIX_THREADS_SMP
 #define CMK_SHARED_VARS_UNAVAILABLE                        0
 #define CMK_SHARED_VARS_POSIX_THREADS_SMP                  1
-
-#define CMK_LINUX_PTHREAD_HACK                             1
index 2f64cbb8daaad80c5fb81e19f9cf164dd23b2ab7..953cabd39334897587392107789cdc49c42c4fb5 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef _CONV_MACH_H
 #define _CONV_MACH_H
 
+#define CMK_NETPOLL         1
 
 #define CMK_ASYNC_NOT_NEEDED                               0
 #define CMK_ASYNC_USE_FIOASYNC_AND_FIOSETOWN               0
index 135eb2921b3af300074dbe7d5f92cf3482c0ab8a..a122e23003f30dff42b8d3535d019780cd2cd432 100644 (file)
@@ -115,6 +115,7 @@ void ComlibManager::init(){
        CkpvAccess(RecvmsgHandle) =CkRegisterHandler((CmiHandler)recv_array_msg);
 
        bcast_pelist = new int [CkNumPes()];
+       _MEMCHECK(bcast_pelist);
        for(int brcount = 0; brcount < CkNumPes(); brcount++)
                bcast_pelist[brcount] = brcount;
 
index 22f83582aad88c81386b505241a841884bd0cf89..759f284c2899173ad792c5b0d1e39f4a88fe1fdb 100644 (file)
@@ -9,6 +9,7 @@
 
 ComlibGlobalStats::ComlibGlobalStats() {
     statsArr = new ComlibLocalStats[CkNumPes()];
+    _MEMCHECK(statsArr);
 }
 
 void ComlibGlobalStats::updateStats(ComlibLocalStats &stats, int p) {
index 3f19838279293b281c05998d9fc96ec6c5729677..8dab92637db6e2d0d69445c592476a31907c37e2 100644 (file)
 #include <stdlib.h>
 #include <memory.h>
 
+#include "charm.h"
+#include "middle.h"
+
 #if CMK_HAS_STRINGS_H
   #include <strings.h>            /* defines bzero */
 #else
   #define bzero(s,n)   memset(s,0,n)
 #endif
 
-#include "charm.h"
-#include "middle.h"
-
 class CMessage_CkArgMsg {
 public: static int __idx;
 };
@@ -418,7 +418,7 @@ class Chare {
     CkObjectMsgQ objQ;                // object message queue
 #endif
   public:
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
     int chareIdx;                  // index in the chare obj table (chare_objs)
 #endif
 #ifdef _FAULT_MLOG_
@@ -726,7 +726,7 @@ class CProxy_Chare : public CProxy {
     }
 #ifndef CMK_OPTIMIZE
     inline void ckCheck(void) const  {   //Make sure this proxy has a value
-#if !CMK_FT_CHARE
+#ifdef CMK_CHARE_USE_PTR
        if (_ck_cid.objPtr==0)
                CkAbort("Error! This chare proxy has not been initialized!");
 #endif
index 2291a4b6194c5afc851bb2f16e2a205f7990d412..a7e497911eb85b9905356971a6eec490d331d9c2 100644 (file)
@@ -25,7 +25,7 @@ void automaticallySetMessagePriority(envelope *env); // in control point framewo
 #include "LBDatabase.h"
 #endif // CMK_LBDB_ON
 
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
 CpvDeclare(CkVec<void *>, chare_objs);
 CpvDeclare(CkVec<VidBlock *>, vidblocks);
 #endif
@@ -46,7 +46,7 @@ extern int _defaultObjectQ;
 Chare::Chare(void) {
   thishandle.onPE=CkMyPe();
   thishandle.objPtr=this;
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
      // for plain chare, objPtr is actually the index to chare table
   if (chareIdx >= 0) thishandle.objPtr=(void*)chareIdx;
 #endif
@@ -82,7 +82,7 @@ void Chare::pup(PUP::er &p)
 {
   p(thishandle.onPE);
   thishandle.objPtr=(void *)this;
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
   p(chareIdx);
   if (chareIdx != -1) thishandle.objPtr=(void*)chareIdx;
 #endif
@@ -551,7 +551,7 @@ void CkCreateChare(int cIdx, int eIdx, void *msg, CkChareID *pCid, int destPE)
     _MEMCHECK(pCid->objPtr);
     env->setMsgtype(NewVChareMsg);
     env->setVidPtr(pCid->objPtr);
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
     CpvAccess(vidblocks).push_back((VidBlock*)pCid->objPtr);
     int idx = CpvAccess(vidblocks).size()-1;
     pCid->objPtr = (void *)idx;
@@ -595,7 +595,7 @@ void CkCreateLocalGroup(CkGroupID groupID, int epIdx, envelope *env)
 
   CkpvAccess(_currentGroup) = groupID;
   CkpvAccess(_currentGroupRednMgr) = env->getRednMgr();
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
   ((Chare *)obj)->chareIdx = -1;
 #endif
   _invokeEntryNoTrace(epIdx,env,obj); /* can't trace groups: would cause nested begin's */
@@ -618,7 +618,7 @@ void CkCreateLocalNodeGroup(CkGroupID groupID, int epIdx, envelope *env)
 // User may call CkLocalNodeBranch() inside the nodegroup constructor
 //  store nodegroup into _currentNodeGroupObj
   CkpvAccess(_currentNodeGroupObj) = obj;
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
   ((Chare *)obj)->chareIdx = -1;
 #endif
   _invokeEntryNoTrace(epIdx,env,obj);
@@ -684,7 +684,7 @@ void _createNodeGroup(CkGroupID groupID, envelope *env)
     CkPackMessage(&env);
     CmiSetHandler(env, _bocHandlerIdx);
     _numInitMsgs++;
-    CksvAccess(_numInitNodeMsgs)++;
+    if (CkpvAccess(_charmEpoch)==0) CksvAccess(_numInitNodeMsgs)++;
     CmiSyncNodeBroadcast(env->getTotalsize(), (char *)env);
     CpvAccess(_qd)->create(CkNumNodes()-1);
     CkUnpackMessage(&env);
@@ -774,7 +774,7 @@ static inline void *_allocNewChare(envelope *env, int &idx)
 {
   int chareIdx = _entryTable[env->getEpIdx()]->chareIdx;
   void *tmp=malloc(_chareTable[chareIdx]->size);
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
   CpvAccess(chare_objs).push_back(tmp);
   idx = CpvAccess(chare_objs).size()-1;
 #endif
@@ -787,7 +787,7 @@ static void _processNewChareMsg(CkCoreState *ck,envelope *env)
 {
   int idx;
   register void *obj = _allocNewChare(env, idx);
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
   ((Chare *)obj)->chareIdx = idx;
 #endif
   _invokeEntry(env->getEpIdx(),env,obj);
@@ -800,7 +800,7 @@ static void _processNewVChareMsg(CkCoreState *ck,envelope *env)
   register CkChareID *pCid = (CkChareID *)
       _allocMsg(FillVidMsg, sizeof(CkChareID));
   pCid->onPE = CkMyPe();
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
   pCid->objPtr = (void*)idx;
 #else
   pCid->objPtr = obj;
@@ -813,7 +813,7 @@ static void _processNewVChareMsg(CkCoreState *ck,envelope *env)
   CmiSetHandler(ret, _charmHandlerIdx);
   CmiSyncSendAndFree(srcPe, ret->getTotalsize(), (char *)ret);
   CpvAccess(_qd)->create();
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
   ((Chare *)obj)->chareIdx = idx;
 #endif
   _invokeEntry(env->getEpIdx(),env,obj);
@@ -831,7 +831,7 @@ static inline void _processForPlainChareMsg(CkCoreState *ck,envelope *env)
     obj = _mainTable[mainIdx]->getObj();
   }
   else {
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
     if (_chareTable[_entryTable[epIdx]->chareIdx]->chareType == TypeChare)
       obj = CpvAccess(chare_objs)[(CmiIntPtr)env->getObjPtr()];
     else
@@ -852,7 +852,7 @@ static inline void _processForChareMsg(CkCoreState *ck,envelope *env)
 
 static inline void _processFillVidMsg(CkCoreState *ck,envelope *env)
 {
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
   register VidBlock *vptr = CpvAccess(vidblocks)[(CmiIntPtr)env->getVidPtr()];
 #else
   register VidBlock *vptr = (VidBlock *) env->getVidPtr();
@@ -866,7 +866,7 @@ static inline void _processFillVidMsg(CkCoreState *ck,envelope *env)
 
 static inline void _processForVidMsg(CkCoreState *ck,envelope *env)
 {
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
   register VidBlock *vptr = CpvAccess(vidblocks)[(CmiIntPtr)env->getVidPtr()];
 #else
   VidBlock *vptr = (VidBlock *) env->getVidPtr();
@@ -1340,7 +1340,7 @@ static inline int _prepareMsg(int eIdx,void *msg,const CkChareID *pCid)
   if (pCid->onPE < 0) { //Virtual chare ID (VID)
     register int pe = -(pCid->onPE+1);
     if(pe==CkMyPe()) {
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
       VidBlock *vblk = CpvAccess(vidblocks)[(CmiIntPtr)pCid->objPtr];
 #else
       VidBlock *vblk = (VidBlock *) pCid->objPtr;
@@ -1395,15 +1395,19 @@ void CkSendMsg(int entryIdx, void *msg,const CkChareID *pCid, int opts)
 #endif
   register envelope *env = UsrToEnv(msg);
   int destPE=_prepareMsg(entryIdx,msg,pCid);
+  // Before it traced the creation only if destPE!=-1 (i.e it did not when the
+  // VidBlock was not yet filled). The problem is that the creation was never
+  // traced later when the VidBlock was filled. One solution is to trace the
+  // creation here, the other to trace it in VidBlock->msgDeliver().
+  _TRACE_CREATION_1(env);
   if (destPE!=-1) {
-    _TRACE_CREATION_1(env);
     CpvAccess(_qd)->create();
     if (opts & CK_MSG_SKIP_OR_IMM)
       _noCldEnqueue(destPE, env);
     else
       CldEnqueue(destPE, env, _infoIdx);
-    _TRACE_CREATION_DONE(1);
   }
+  _TRACE_CREATION_DONE(1);
 }
 
 extern "C"
@@ -1433,12 +1437,17 @@ void CkSendMsgInline(int entryIndex, void *msg, const CkChareID *pCid, int opts)
 static inline envelope *_prepareMsgBranch(int eIdx,void *msg,CkGroupID gID,int type)
 {
   register envelope *env = UsrToEnv(msg);
+  CkNodeGroupID nodeRedMgr;
   _CHECK_USED(env);
   _SET_USED(env, 1);
   env->setMsgtype(type);
   env->setEpIdx(eIdx);
   env->setGroupNum(gID);
   env->setSrcPe(CkMyPe());
+#ifndef CMK_OPTIMIZE
+  nodeRedMgr.setZero();
+  env->setRednMgr(nodeRedMgr);
+#endif
 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
   criticalPath_send(env);
   automaticallySetMessagePriority(env);
@@ -1832,6 +1841,9 @@ printf("[%d] DELETE!\n", CkMyPe());
 //------------------- Message Watcher (record/replay) ----------------
 
 #include "crc32.h"
+
+CkpvDeclare(int, envelopeEventID);
+
 CkMessageWatcher::~CkMessageWatcher() {}
 
 class CkMessageRecorder : public CkMessageWatcher {
@@ -1845,8 +1857,13 @@ public:
 private:
   virtual CmiBool process(envelope *env,CkCoreState *ck) {
     if (env->getEvent()) {
-      unsigned int crc = crc32(((unsigned char*)env)+CmiMsgHeaderSizeBytes, env->getTotalsize()-CmiMsgHeaderSizeBytes);
-      fprintf(f,"%d %d %d %d %x\n",env->getSrcPe(),env->getTotalsize(),env->getEvent(), env->getMsgtype()==NodeBocInitMsg || env->getMsgtype()==ForNodeBocMsg, crc);
+      bool wasPacked = env->isPacked();
+      if (!wasPacked) CkPackMessage(&env);
+      //unsigned int crc = crc32_initial(((unsigned char*)env)+CmiMsgHeaderSizeBytes, env->getTotalsize()-CmiMsgHeaderSizeBytes);
+      unsigned int crc1 = crc32_initial(((unsigned char*)env)+CmiMsgHeaderSizeBytes, sizeof(*env)-CmiMsgHeaderSizeBytes);
+      unsigned int crc2 = crc32_initial(((unsigned char*)env)+sizeof(*env), env->getTotalsize()-sizeof(*env));
+      fprintf(f,"%d %d %d %hhd %x %x\n",env->getSrcPe(),env->getTotalsize(),env->getEvent(), env->getMsgtype()==NodeBocInitMsg || env->getMsgtype()==ForNodeBocMsg, crc1, crc2);
+      if (!wasPacked) CkUnpackMessage(&env);
     }
     return CmiTrue;
   }
@@ -1865,9 +1882,12 @@ public:
   ~CkMessageDetailRecorder() {fclose(f);}
 private:
   virtual CmiBool process(envelope *env, CkCoreState *ck) {
+    bool wasPacked = env->isPacked();
+    if (!wasPacked) CkPackMessage(&env);
     CmiUInt4 size = env->getTotalsize();
     fwrite(&size, 4, 1, f);
     fwrite(env, env->getTotalsize(), 1, f);
+    if (!wasPacked) CkUnpackMessage(&env);
     return CmiTrue;
   }
 };
@@ -1875,15 +1895,19 @@ private:
 //#define REPLAYDEBUG(args) ckout<<"["<<CkMyPe()<<"] "<< args <<endl;
 #define REPLAYDEBUG(args) /* empty */
 
+extern "C" void CkMessageReplayQuiescence(void *rep, double time);
+
 class CkMessageReplay : public CkMessageWatcher {
+  int counter;
        int nextPE, nextSize, nextEvent, nexttype; //Properties of next message we need:
-       unsigned int crc;
+       unsigned int crc1, crc2;
        /// Read the next message we need from the file:
        void getNext(void) {
-               if (5!=fscanf(f,"%d%d%d%d%x", &nextPE,&nextSize,&nextEvent,&nexttype,&crc)) {
+               if (6!=fscanf(f,"%d%d%d%d%x%x", &nextPE,&nextSize,&nextEvent,&nexttype,&crc1,&crc2)) {
                        // CkAbort("CkMessageReplay> Syntax error reading replay file");
                        nextPE=nextSize=nextEvent=nexttype=-1; //No destructor->record file just ends in the middle!
                }
+               counter++;
        }
        /// If this is the next message we need, advance and return CmiTrue.
        CmiBool isNext(envelope *env) {
@@ -1894,10 +1918,18 @@ class CkMessageReplay : public CkMessageWatcher {
                        CkPrintf("CkMessageReplay> Message size changed during replay org: [%d %d %d] got: [%d %d %d]\n", nextPE, nextEvent, nextSize, env->getSrcPe(), env->getEvent(), env->getTotalsize());
                         return CmiFalse;
                 }
-               unsigned int crcnew = crc32(((unsigned char*)env)+CmiMsgHeaderSizeBytes, env->getTotalsize()-CmiMsgHeaderSizeBytes);
-               if (crcnew != crc) {
-                 CkPrintf("CkMessageReplay> Message CRC changed during replay org: [0x%x] got: [0x%x]\n",crc,crcnew);
+               bool wasPacked = env->isPacked();
+               if (!wasPacked) CkPackMessage(&env);
+               //unsigned int crcnew = crc32_initial(((unsigned char*)env)+CmiMsgHeaderSizeBytes, env->getTotalsize()-CmiMsgHeaderSizeBytes);
+               unsigned int crcnew1 = crc32_initial(((unsigned char*)env)+CmiMsgHeaderSizeBytes, sizeof(*env)-CmiMsgHeaderSizeBytes);
+               unsigned int crcnew2 = crc32_initial(((unsigned char*)env)+sizeof(*env), env->getTotalsize()-sizeof(*env));
+               if (crcnew1 != crc1) {
+                 CkPrintf("CkMessageReplay %d> Envelope CRC changed during replay org: [0x%x] got: [0x%x]\n",CkMyPe(),crc1,crcnew1);
                }
+        if (crcnew2 != crc2) {
+          CkPrintf("CkMessageReplay %d> Message CRC changed during replay org: [0x%x] got: [0x%x]\n",CkMyPe(),crc2,crcnew2);
+        }
+        if (!wasPacked) CkUnpackMessage(&env);
                return CmiTrue;
        }
 
@@ -1925,9 +1957,11 @@ class CkMessageReplay : public CkMessageWatcher {
 
 public:
        CkMessageReplay(FILE *f_) {
+         counter=0;
          f=f_;
          getNext();
          REPLAYDEBUG("Constructing ckMessageReplay: "<< nextPE <<" "<< nextSize <<" "<<nextEvent);
+         CmiStartQD(CkMessageReplayQuiescence, this);
        }
        ~CkMessageReplay() {fclose(f);}
 
@@ -1962,6 +1996,12 @@ private:
        }
 };
 
+extern "C" void CkMessageReplayQuiescence(void *rep, double time) {
+  CkPrintf("[%d] Quiescence detected\n",CkMyPe());
+  CkMessageReplay *replay = (CkMessageReplay*)rep;
+  
+}
+
 #include "trace-common.h" /* For traceRoot and traceRootBaseLength */
 
 static FILE *openReplayFile(const char *prefix, const char *suffix, const char *permissions) {
@@ -1987,16 +2027,20 @@ void CkMessageWatcherInit(char **argv,CkCoreState *ck) {
     if (CmiGetArgStringDesc(argv,"+record-detail",&procs,"Record full message content for the specified processors")) {
         CkListString list(procs);
         if (list.includes(CkMyPe())) {
+          CpdSetInitializeMemory(1);
           ck->addWatcher(new CkMessageDetailRecorder(openReplayFile("ckreplay_",".detail","w")));
         }
     }
        if (CmiGetArgFlagDesc(argv,"+record","Record message processing order")) {
+           CpdSetInitializeMemory(1);
                ck->addWatcher(new CkMessageRecorder(openReplayFile("ckreplay_",".log","w")));
        }
        if (CmiGetArgFlagDesc(argv,"+replay","Re-play recorded message stream")) {
+           CpdSetInitializeMemory(1);
                ck->addWatcher(new CkMessageReplay(openReplayFile("ckreplay_",".log","r")));
        }
        if (CmiGetArgStringDesc(argv,"+replay-detail",&procs,"Re-play the specified processors from recorded message content")) {
+           CpdSetInitializeMemory(1);
          /*Nothing yet*/
        }
 }
index f33cf43973180ba597dffe0993a4d550254867f4..0fdb3cc197cf1e9bcbfd3109eafd67cd1e41de17 100644 (file)
@@ -32,7 +32,8 @@ class VidBlock {
     PtrQ *msgQ;
     CkChareID actualID;
     void msgDeliver(envelope *env) {
-        env->setSrcPe(CkMyPe());
+        // This was causing sync entry methods not to return properly in some cases
+        //env->setSrcPe(CkMyPe());
         env->setMsgtype(ForChareMsg);
         env->setObjPtr(actualID.objPtr);
         CldEnqueue(actualID.onPE, env, _infoIdx);
@@ -63,7 +64,7 @@ class VidBlock {
       return NULL;
     }
     void pup(PUP::er &p) {
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
       int s;
       if (!p.isUnpacking()) s = state-FILLED;
       p|s;
index 884095414e846c84d41f983ad7ca694a5ec56805..0b0aa7f5da6aa64a61106eb344f8caa843686ee0 100644 (file)
@@ -16,6 +16,10 @@ Initial version by Orion Sky Lawlor, olawlor@acm.org, 2/8/2002
 
 /*readonly*/ CProxy_ckcallback_group _ckcallbackgroup;
 
+typedef CkHashtableT<CkHashtableAdaptorT<unsigned int>, CkCallback*> threadCB_t;
+CpvStaticDeclare(threadCB_t, threadCBs);
+CpvStaticDeclare(unsigned int, nextThreadCB);
+
 //This main chare is only used to create the callback forwarding group
 class ckcallback_main : public CBase_ckcallback_main {
 public:
@@ -41,10 +45,17 @@ public:
 //Initialize the callback's thread fields before sending it off:
 void CkCallback::impl_thread_init(void)
 {
-       d.thread.onPE=CkMyPe();
-       d.thread.cb=this; //<- so we can find this structure later
+    int exist;
+    CkCallback **cb;
+    d.thread.onPE=CkMyPe();
+       do {
+         if (CpvAccess(nextThreadCB)==0) CpvAccess(nextThreadCB)=1;
+         d.thread.cb=CpvAccess(nextThreadCB)++;
+         cb = &CpvAccess(threadCBs).put(d.thread.cb, &exist);
+       } while (exist==1);
+       *cb = this; //<- so we can find this structure later
        d.thread.th=NULL; //<- thread isn't suspended yet
-       d.thread.ret=NULL;//<- no data to return yet
+       d.thread.ret=(void*)-1;//<- no data to return yet
 }
 
 //Actually suspend this thread
@@ -57,12 +68,14 @@ void *CkCallback::impl_thread_delay(void) const
        
        //Find the original callback object:
        CkCallback *dest=(CkCallback *)this;
-       if (d.thread.cb!=NULL) dest=d.thread.cb;
-       if (dest->d.thread.cb!=NULL) 
+       if (d.thread.cb!=0) dest=CpvAccess(threadCBs).get(d.thread.cb);
+       if (dest==0)
+           CkAbort("Called thread_delay on an already deleted callback");
+       if (dest->d.thread.ret==(void*)-1) 
        {  //We need to sleep for the result:
                dest->d.thread.th=CthSelf(); //<- so we know a thread is waiting
                CthSuspend();
-               if (dest->d.thread.cb!=NULL
+               if (dest->d.thread.ret==(void*)-1
                        CkAbort("thread resumed, but callback data is still empty");
        }
        return dest->d.thread.ret;
@@ -72,54 +85,70 @@ void *CkCallback::impl_thread_delay(void) const
 /*These can't be defined in the .h file like the other constructors
  * because we need CkCallback before CProxyElement* are defined.
  */
-CkCallback::CkCallback(Chare *p, int ep, CmiBool doInline)
-               :type(doInline?isendChare:sendChare)
-{
+CkCallback::CkCallback(Chare *p, int ep, CmiBool doInline) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=doInline?isendChare:sendChare;
        d.chare.ep=ep; 
        d.chare.id=p->ckGetChareID();
 }
-CkCallback::CkCallback(Group *p, int ep, CmiBool doInline)
-               :type(doInline?isendGroup:sendGroup)
-{
+CkCallback::CkCallback(Group *p, int ep, CmiBool doInline) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=doInline?isendGroup:sendGroup;
        d.group.ep=ep; d.group.id=p->ckGetGroupID(); d.group.onPE=CkMyPe();
 }
-CkCallback::CkCallback(NodeGroup *p, int ep, CmiBool doInline)
-               :type(doInline?isendNodeGroup:sendNodeGroup)
-{
+CkCallback::CkCallback(NodeGroup *p, int ep, CmiBool doInline) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=doInline?isendNodeGroup:sendNodeGroup;
        d.group.ep=ep; d.group.id=p->ckGetGroupID(); d.group.onPE=CkMyNode();
 }
 
-CkCallback::CkCallback(int ep,const CProxy_NodeGroup &ngp)
-               :type(bcastNodeGroup) 
-{
+CkCallback::CkCallback(int ep,const CProxy_NodeGroup &ngp) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=bcastNodeGroup;
        d.group.ep=ep; d.group.id=ngp.ckGetGroupID();
 }
 
-CkCallback::CkCallback(int ep,int onPE,const CProxy_NodeGroup &ngp,CmiBool doInline)
-       :type(doInline?isendNodeGroup:sendNodeGroup) 
-{
+CkCallback::CkCallback(int ep,int onPE,const CProxy_NodeGroup &ngp,CmiBool doInline) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=doInline?isendNodeGroup:sendNodeGroup;
        d.group.ep=ep; d.group.id=ngp.ckGetGroupID(); d.group.onPE=onPE;
 }
 
-CkCallback::CkCallback(int ep,const CProxyElement_Group &grpElt,CmiBool doInline) 
-       :type(doInline?isendGroup:sendGroup) 
-{
+CkCallback::CkCallback(int ep,const CProxyElement_Group &grpElt,CmiBool doInline) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=doInline?isendGroup:sendGroup;
        d.group.ep=ep; 
        d.group.id=grpElt.ckGetGroupID(); 
        d.group.onPE=grpElt.ckGetGroupPe();
 }
-CkCallback::CkCallback(int ep,const CProxyElement_ArrayBase &arrElt,CmiBool doInline)
-       :type(doInline?isendArray:sendArray) 
-{
+CkCallback::CkCallback(int ep,const CProxyElement_ArrayBase &arrElt,CmiBool doInline) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=doInline?isendArray:sendArray;
        d.array.ep=ep; 
        d.array.id=arrElt.ckGetArrayID(); 
        d.array.idx.asMax()=arrElt.ckGetIndex();
 }
 
-CkCallback::CkCallback(ArrayElement *p, int ep,CmiBool doInline)
-       :type(doInline?isendArray:sendArray) 
-{
-        d.array.ep=ep; 
+CkCallback::CkCallback(ArrayElement *p, int ep,CmiBool doInline) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=doInline?isendArray:sendArray;
+    d.array.ep=ep; 
        d.array.id=p->ckGetArrayID(); 
        d.array.idx.asMax()=p->ckGetArrayIndex();
 }
@@ -145,11 +174,10 @@ void CkCallback::send(void *msg) const
                break;
        case resumeThread: //Resume a waiting thread
                if (d.thread.onPE==CkMyPe()) {
-                       CkCallback *dest=d.thread.cb;
-                       if (dest==NULL)
+                       CkCallback *dest=CpvAccess(threadCBs).get(d.thread.cb);
+                       if (dest==0 || dest->d.thread.ret!=(void*)-1)
                                CkAbort("Already sent a value to this callback!\n");
                        dest->d.thread.ret=msg; //<- return data
-                       dest->d.thread.cb=NULL; //<- mark callback as finished
                        if (dest->d.thread.th!=NULL)
                                CthAwaken(dest->d.thread.th);
                } 
@@ -230,6 +258,68 @@ void CkCallback::send(void *msg) const
        };
 }
 
+void CkCallback::pup(PUP::er &p) {
+  //p((char*)this, sizeof(CkCallback));
+  int t = (int)type;
+  p|t;
+  type = (callbackType)t;
+  switch (type) {
+  case resumeThread:
+    p|d.thread.onPE;
+    p|d.thread.cb;
+    break;
+  case isendChare:
+  case sendChare:
+    p|d.chare.ep;
+    p|d.chare.id;
+    break;
+  case isendGroup:
+  case sendGroup:
+  case isendNodeGroup:
+  case sendNodeGroup:
+    p|d.group.onPE;
+  case bcastNodeGroup:
+  case bcastGroup:
+    p|d.group.ep;
+    p|d.group.id;
+    break;
+  case isendArray:
+  case sendArray:
+    p|d.array.idx;
+  case bcastArray:
+    p|d.array.ep;
+    p|d.array.id;
+    break;
+  case replyCCS:
+    p((char*)&d.ccsReply.reply, sizeof(d.ccsReply.reply));
+    break;
+  case call1Fn:
+    p((char*)&d.c1fn, sizeof(d.c1fn));
+    break;
+  case callCFn:
+    p((char*)&d.cfn, sizeof(d.cfn));
+    break;
+  case ignore:
+  case ckExit:
+  case invalid:
+    break;
+  default:
+    CkAbort("Inconsistent CkCallback type");
+  }
+}
+
+void CkCallback::thread_destroy() const {
+  if (type==resumeThread && CpvAccess(threadCBs).get(d.thread.cb)==this) {
+    CpvAccess(threadCBs).remove(d.thread.cb);
+  }
+}
+
+CkCallbackResumeThread::~CkCallbackResumeThread() {
+  void * res = thread_delay(); //<- block thread here if it hasn't already
+  if (result != NULL) *result = res;
+  else CkFreeMsg(res);
+  thread_destroy();
+}
 
 /****** Callback-from-CCS ******/
 
@@ -272,5 +362,11 @@ void CkDataMsg::check(void)
                CkAbort("CkDataMsg corrupted-- bad tag.");
 }
 
+void CkCallbackInit() {
+  CpvInitialize(threadCB_t, threadCBs);
+  CpvInitialize(unsigned int, nextThreadCB);
+  CpvAccess(nextThreadCB)=1;
+}
+
 #include "CkCallback.def.h"
 
index e7e755f9bfa035daba75e530739ad3cc87e9246b..79f387cd56490b5a03883f5fcd6b29707577fb6c 100644 (file)
@@ -53,7 +53,7 @@ private:
        union callbackData {
        struct s_thread { //resumeThread
                int onPE; //Thread is waiting on this PE
-               CkCallback *cb; //The suspending callback (NULL if already done)
+               int cb; //The suspending callback (0 if already done)
                CthThread th; //Thread to resume (NULL if none waiting)
                void *ret; //Place to put the returned message
        } thread;
@@ -84,60 +84,98 @@ private:
        } ccsReply;
        };
 public:        
-       callbackType type; 
+       callbackType type;
        callbackData d;
        
        void impl_thread_init(void);
        void *impl_thread_delay(void) const;
 public:
-       CkCallback(void) :type(invalid) {}
+       CkCallback(void) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=invalid;
+       }
        //This is how you create ignore, ckExit, and resumeThreads:
-       CkCallback(callbackType t) 
-               :type(t) { if (t==resumeThread) impl_thread_init(); }
+       CkCallback(callbackType t) {
+#ifndef CMK_OPTIMIZE
+         bzero(this, sizeof(CkCallback));
+#endif
+         if (t==resumeThread) impl_thread_init();
+         type=t;
+       }
 
     // Call a C function on the current PE
-       CkCallback(Ck1CallbackFn fn)
-               :type(call1Fn)
-               {d.c1fn.fn=fn;}
+       CkCallback(Ck1CallbackFn fn) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=call1Fn;
+         d.c1fn.fn=fn;
+       }
 
     // Call a C function on the current PE
-       CkCallback(CkCallbackFn fn,void *param)
-               :type(callCFn) 
-               {d.cfn.onPE=CkMyPe(); d.cfn.fn=fn; d.cfn.param=param;}
+       CkCallback(CkCallbackFn fn,void *param) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=callCFn;
+         d.cfn.onPE=CkMyPe(); d.cfn.fn=fn; d.cfn.param=param;
+       }
 
     // Call a chare entry method
-       CkCallback(int ep,const CkChareID &id,CmiBool doInline=CmiFalse)
-               :type(doInline?isendChare:sendChare) 
-               {d.chare.ep=ep; d.chare.id=id;}
+       CkCallback(int ep,const CkChareID &id,CmiBool doInline=CmiFalse) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=doInline?isendChare:sendChare;
+         d.chare.ep=ep; d.chare.id=id;
+       }
 
     // Bcast to nodegroup
        CkCallback(int ep,const CProxy_NodeGroup &ngp);
 
     // Bcast to a group or nodegroup
-       CkCallback(int ep,const CkGroupID &id, int isNodeGroup=0)
-               :type(isNodeGroup?bcastNodeGroup:bcastGroup) 
-               {d.group.ep=ep; d.group.id=id;}
+       CkCallback(int ep,const CkGroupID &id, int isNodeGroup=0) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=isNodeGroup?bcastNodeGroup:bcastGroup;
+         d.group.ep=ep; d.group.id=id;
+       }
 
     // Send to nodegroup element
        CkCallback(int ep,int onPE,const CProxy_NodeGroup &ngp,CmiBool doInline=CmiFalse);
 
     // Send to group/nodegroup element
-       CkCallback(int ep,int onPE,const CkGroupID &id,CmiBool doInline=CmiFalse, int isNodeGroup=0)
-               :type(doInline?(isNodeGroup?isendNodeGroup:isendGroup):(isNodeGroup?sendNodeGroup:sendGroup)) 
-               {d.group.ep=ep; d.group.id=id; d.group.onPE=onPE;}
+       CkCallback(int ep,int onPE,const CkGroupID &id,CmiBool doInline=CmiFalse, int isNodeGroup=0) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=doInline?(isNodeGroup?isendNodeGroup:isendGroup):(isNodeGroup?sendNodeGroup:sendGroup); 
+      d.group.ep=ep; d.group.id=id; d.group.onPE=onPE;
+       }
 
     // Send to specified group element
        CkCallback(int ep,const CProxyElement_Group &grpElt,CmiBool doInline=CmiFalse);
        
     // Bcast to array
-       CkCallback(int ep,const CkArrayID &id)
-               :type(bcastArray) 
-               {d.array.ep=ep; d.array.id=id;}
+       CkCallback(int ep,const CkArrayID &id) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=bcastArray;
+         d.array.ep=ep; d.array.id=id;
+       }
 
     // Send to array element
-       CkCallback(int ep,const CkArrayIndex &idx,const CkArrayID &id,CmiBool doInline=CmiFalse)
-               :type(doInline?isendArray:sendArray) 
-               {d.array.ep=ep; d.array.id=id; d.array.idx.asMax()=*(CkArrayIndexMax*)&idx;}
+       CkCallback(int ep,const CkArrayIndex &idx,const CkArrayID &id,CmiBool doInline=CmiFalse) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=doInline?isendArray:sendArray;
+         d.array.ep=ep; d.array.id=id; d.array.idx.asMax()=*(CkArrayIndexMax*)&idx;
+       }
 
     // Bcast to array
        CkCallback(int ep,const CProxyElement_ArrayBase &arrElt,CmiBool doInline=CmiFalse);
@@ -154,9 +192,18 @@ public:
     // Send to specified array element 
        CkCallback(ArrayElement *p, int ep,CmiBool doInline=CmiFalse);
 
-       CkCallback(const CcsDelayedReply &reply) 
-               :type(replyCCS) {d.ccsReply.reply=reply;}
+       CkCallback(const CcsDelayedReply &reply) {
+#ifndef CMK_OPTIMIZE
+      bzero(this, sizeof(CkCallback));
+#endif
+      type=replyCCS;
+         d.ccsReply.reply=reply;
+       }
 
+       ~CkCallback() {
+         thread_destroy();
+       }
+       
        int isInvalid(void) const {return type==invalid;}
 
 /**
@@ -171,6 +218,8 @@ public:
                return NULL;
        }
 
+       void thread_destroy() const;
+       
 /**
  * Send this message back to the caller.
  *
@@ -184,8 +233,10 @@ public:
  * Send this data, formatted as a CkDataMsg, back to the caller.
  */
        void send(int length,const void *data) const;
+       
+       void pup(PUP::er &p);
 };
-PUPbytes(CkCallback) //FIXME: write a real pup routine
+//PUPbytes(CkCallback) //FIXME: write a real pup routine
 
 /**
  * Convenience class: a thread-suspending callback.  
@@ -203,15 +254,13 @@ class CkCallbackResumeThread : public CkCallback {
                :CkCallback(resumeThread) { result = NULL; }
        CkCallbackResumeThread(void * &ptr)
            :CkCallback(resumeThread) { result = &ptr; }
-       ~CkCallbackResumeThread(void) {
-           void * res = thread_delay(); //<- block thread here if it hasn't already
-           if (result != NULL) *result = res;
-           else CkFreeMsg(res);
-       }
+        ~CkCallbackResumeThread(void);
 };
 
 void _registerCkCallback(void); //used by init
 
+void CkCallbackInit();
+
 #endif
 
 
index 5e154fae46c73befb1348b9ec893c325be518f71..952900a8dd22f955c41b0811859e0821b3c6293d 100644 (file)
@@ -101,6 +101,17 @@ void CkCheckpointMgr::Checkpoint(const char *dirname, CkCallback& cb){
        }
 
        char fileName[1024];
+
+#ifndef CMK_CHARE_USE_PTR
+       // save groups into Chares.dat
+       sprintf(fileName,"%s/Chares_%d.dat",dirname,CkMyPe());
+       FILE* fChares = fopen(fileName,"wb");
+       if(!fChares) CkAbort("Failed to create checkpoint file for chares!");
+       PUP::toDisk pChares(fChares);
+       CkPupChareData(pChares);
+       fclose(fChares);
+#endif
+
        // save groups into Groups.dat
        // content of the file: numGroups, GroupInfo[numGroups], _groupTable(PUP'ed), groups(PUP'ed)
        sprintf(fileName,"%s/Groups_%d.dat",dirname,CkMyPe());
@@ -192,7 +203,7 @@ void CkPupMainChareData(PUP::er &p, CkArgMsg *args)
                bdcastRO();
 }
 
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
 
 CpvExtern(CkVec<void *>, chare_objs);
 CpvExtern(CkVec<VidBlock *>, vidblocks);
@@ -452,7 +463,7 @@ static void checkpointOne(const char* dirname, CkCallback& cb){
        int _numPes = CkNumPes();
        pRO|_numPes;
        CkPupROData(pRO);
-       pRO((char *)&cb, sizeof(cb));
+       pRO|cb;
        fclose(fRO);
 
        // save mainchares into MainChares.dat
@@ -542,6 +553,18 @@ void CkRestartMain(const char* dirname, CkArgMsg *args){
                //bdcastRO(); // moved to CkPupMainChareData()
        }
        
+#ifndef CMK_CHARE_USE_PTR
+       // restore chares only when number of pes is the same 
+       if(CkNumPes() == _numPes) {
+               sprintf(filename,"%s/Chares_%d.dat",dirname,CkMyPe());
+               FILE* fChares = fopen(filename,"rb");
+               if(!fChares) CkAbort("Failed to open checkpoint file for chares!");
+               PUP::fromDisk pChares(fChares);
+               CkPupChareData(pChares);
+               fclose(fChares);
+       }
+#endif
+
        // restore groups
        // content of the file: numGroups, GroupInfo[numGroups], _groupTable(PUP'ed), groups(PUP'ed)
        // restore from PE0's copy if shrink/expand
index 49bf80b81e923ea38871d7f6cf3e838b994f6994..f8be9cbbb5a75ecb1c4ca007508414ea33a82976 100644 (file)
@@ -423,7 +423,7 @@ static inline void _handleProcData(PUP::er &p)
     // save mainchares into MainChares.dat
     if(CkMyPe()==0) CkPupMainChareData(p, (CkArgMsg*)NULL);
        
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
     // save non-migratable chare
     CkPupChareData(p);
 #endif
index 7c094a25cc71e225d9154c96c80be26a0e9abe51..3f7f8b829bbeebcf31d7125c85e465ffa6d563f6 100644 (file)
@@ -391,7 +391,7 @@ void CkReductionMgr::contribute(contributorInfo *ci,CkReductionMsg *m)
   _TRACE_BG_TLINE_END(&(m->log));
 #endif
   DEBR((AA"Contributor %p contributed for %d in grp %d ismigratable %d \n"AB,ci,ci->redNo,thisgroup.idx,m->isMigratableContributor()));
-  m->ci=ci;
+  //m->ci=ci;
   m->redNo=ci->redNo++;
   m->sourceFlag=-1;//A single contribution
   m->gcount=0;
@@ -1291,7 +1291,7 @@ CkReductionMsg *CkReductionMsg::buildNew(int NdataSize,const void *srcData,
     memcpy(ret->data,srcData,NdataSize);
   ret->userFlag=-1;
   ret->reducer=reducer;
-  ret->ci=NULL;
+  //ret->ci=NULL;
   ret->sourceFlag=-1000;
   ret->gcount=0;
   ret->migratableContributor = true;
@@ -1731,7 +1731,7 @@ void CkNodeReductionMgr::contribute(contributorInfo *ci,CkReductionMsg *m)
     CpvAccess(_currentObj) = this;
 #endif
 
-  m->ci=ci;
+  //m->ci=ci;
   m->redNo=ci->redNo++;
   m->sourceFlag=-1;//A single contribution
   m->gcount=0;
@@ -1755,7 +1755,7 @@ void CkNodeReductionMgr::contributeWithCounter(contributorInfo *ci,CkReductionMs
     Chare *oldObj =CpvAccess(_currentObj);
     CpvAccess(_currentObj) = this;
 #endif
-  m->ci=ci;
+  //m->ci=ci;
   m->redNo=ci->redNo++;
   m->gcount=count;
 #if DEBUGRED
index 6080477699c60ee874063d30685bb6acb295ee35..be7678ca5e0ff877f7898505d05bbe228618afaa 100644 (file)
@@ -319,7 +319,7 @@ private:
         void *log;
 #endif
        CkReduction::reducerType reducer;
-       contributorInfo *ci;//Source contributor, or NULL if none
+       //contributorInfo *ci;//Source contributor, or NULL if none
        int redNo;//The serial number of this reduction
        int gcount;//Contribution to the global contributor count
         // for section multicast/reduction library
index ff95ea2a0085a459eb641b296d1b757f60a48beb..360b3e5c09b4b12be0f1d81f2dfea5171e24989d 100644 (file)
@@ -48,6 +48,9 @@ CkQ<DebugRecursiveEntry> _debugData;
 void *CpdGetCurrentObject() { return _debugData.peek().obj; }
 void *CpdGetCurrentMsg() { return _debugData.peek().msg; }
 
+extern int cpdInSystem;
+extern "C" int CpdInUserCode() {return cpdInSystem==0 && _debugData.length()>0 && _debugData.peek().alreadyUserCode==1;}
+
 // Function called right before an entry method
 void CpdBeforeEp(int ep, void *obj, void *msg) {
 #ifndef CMK_OPTIMIZE
index 963cfd85968fe357146e06a4baca7750c3993ed5..724f1cd708cd2a7ac0a70d77e8d5bf941cce2fa1 100644 (file)
@@ -95,6 +95,11 @@ typedef unsigned char  UChar;
 
 /**
 @addtogroup CkEnvelope
+*/
+
+CkpvExtern(int, envelopeEventID);
+
+/**
 @{
 The class envelope defines a Charm++ message's header. The first
 'CmiReservedHeaderSize' bytes of memory is exclusively reserved for Converse
@@ -244,7 +249,7 @@ private:
       env->setPacked(0);
       _SET_USED(env, 0);
       //for record-replay
-      env->setEvent(0);
+      env->setEvent(++CkpvAccess(envelopeEventID));
       env->setRef(0);
 
 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
index e062865cc4f4a64066d33fc9e8239f46d725dbeb..73ee1ca3bd3947192048ac2dbbd9ac417b26b110 100644 (file)
@@ -32,8 +32,34 @@ into _initHandler, it counts messages until it is fully
 initialized, then calls _initDone to clean out the queues 
 and resume normal operation.  
 
-Possible race conditions abound during this process,
-which is probably overly complex.
+Upon resume of normal operation, the user code is guaranteed that
+all readonlies (both data and messages) have been set consistently
+on all processors, and that the constructors for all nodegroups
+and groups allocated from a mainchare have been called.
+
+It is not guaranteed the order in which (node)groups allocated
+outside of a mainchare are constructed, nor that the construction
+will happen before other messages have been delivered by the scheduler.
+
+Even though not exposed to the final users, the creation order of
+groups and nodegroups allocated in mainchares is deterministic and
+respects the following points:
+<ul>
+<li>On all processors, there is no guarantee of the order of creation
+between (node)groups allocated from different mainchares;
+<li>On processor zero, within a mainchare, all (node)groups are created
+in the order specified by the source code (strictly), including array
+allocation of initial elements;
+<li>On processors other than zero, within a mainchare, the order
+specified by the source code is maintained between different nodegroups
+and between different groups;
+<li>On processors other than zero, the ordering between groups and
+nodegroups is NOT maintained, as all nodegroups are created before any
+group is created.
+</ul>
+
+This process should not have race conditions, but it can
+never be excluded...
 */
 /*@{*/
 
@@ -69,16 +95,31 @@ UChar _defaultQueueing = CK_QUEUEING_FIFO;
 UInt  _printCS = 0;
 UInt  _printSS = 0;
 
+/**
+ * This value has the number of total initialization message a processor awaits.
+ * It is received on nodes other than zero together with the ROData message.
+ * Even though it is shared by all processors it is ok: it doesn't matter when and
+ * by who it is set, provided that it becomes equal to the number of awaited messages
+ * (which is always at least one ---the readonly data message).
+ */
 UInt  _numExpectInitMsgs = 0;
+/**
+ * This number is used only by processor zero to count how many messages it will
+ * send out for the initialization process. After the readonly data message is sent
+ * (containing this counter), its value becomes irrelevant.
+ */
 UInt  _numInitMsgs = 0;
+/**
+ * Count the number of nodegroups that have been created in mainchares.
+ * Since the nodegroup creation is executed by a single processor in a
+ * given node, this value must be seen by all processors in a node.
+ */
 CksvDeclare(UInt,_numInitNodeMsgs);
 int   _infoIdx;
 int   _charmHandlerIdx;
 int   _initHandlerIdx;
-int   _roHandlerIdx;
 int   _roRestartHandlerIdx;
 int   _bocHandlerIdx;
-int   _nodeBocHandlerIdx;
 int   _qdHandlerIdx;
 int   _qdCommHandlerIdx;
 int   _triggerHandlerIdx;
@@ -115,11 +156,11 @@ CkpvDeclare(MsgPool*, _msgPool);
 CkpvDeclare(_CkOutStream*, _ckout);
 CkpvDeclare(_CkErrStream*, _ckerr);
 
-CkpvStaticDeclare(int,  _numInitsRecd); /* UInt changed to int */
+CkpvStaticDeclare(int,  _numInitsRecd);
 CkpvStaticDeclare(PtrQ*, _buffQ);
 CkpvStaticDeclare(PtrVec*, _bocInitVec);
 
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
 CpvExtern(CkVec<void *>, chare_objs);
 CpvExtern(CkVec<VidBlock *>, vidblocks);
 #endif
@@ -362,7 +403,6 @@ static void _exitHandler(envelope *env)
       _exitStarted = 1;
       CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler);
       CkNumberHandler(_bocHandlerIdx, (CmiHandler)_discardHandler);
-      CkNumberHandler(_nodeBocHandlerIdx, (CmiHandler)_discardHandler);
       env->setMsgtype(ReqStatMsg);
       env->setSrcPe(CkMyPe());
       // if exit in ring, instead of broadcasting, send in ring
@@ -386,7 +426,6 @@ static void _exitHandler(envelope *env)
       DEBUGF(("ReqStatMsg on %d\n", CkMyPe()));
       CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler);
       CkNumberHandler(_bocHandlerIdx, (CmiHandler)_discardHandler);
-      CkNumberHandler(_nodeBocHandlerIdx, (CmiHandler)_discardHandler);
        /*FAULT_EVAC*/
       if(CmiNodeAlive(CkMyPe())){
          _sendStats();
@@ -434,6 +473,11 @@ static void _exitHandler(envelope *env)
   }
 }
 
+/**
+ * Create all groups in this processor (not called on processor zero).
+ * Notice that only groups created in mainchares are processed here;
+ * groups created later are processed as regular messages.
+ */
 static inline void _processBufferedBocInits(void)
 {
   CkCoreState *ck = CkpvAccess(_coreState);
@@ -441,9 +485,9 @@ static inline void _processBufferedBocInits(void)
   register int i = 0;
   PtrVec &inits=*CkpvAccess(_bocInitVec);
   register int len = inits.size();
-  for(i=0; i<len; i++) {
+  for(i=1; i<len; i++) {
     envelope *env = inits[i];
-    if(env==0) continue;
+    if(env==0) CkAbort("_processBufferedBocInits: empty message");
     if(env->isPacked())
       CkUnpackMessage(&env);
     _processBocInitMsg(ck,env);
@@ -451,16 +495,20 @@ static inline void _processBufferedBocInits(void)
   delete &inits;
 }
 
+/**
+ * Create all nodegroups in this node (called only by rank zero, and never on node zero).
+ * Notice that only nodegroups created in mainchares are processed here;
+ * nodegroups created later are processed as regular messages.
+ */
 static inline void _processBufferedNodeBocInits(void)
 {
   CkCoreState *ck = CkpvAccess(_coreState);
-  CkNumberHandlerEx(_nodeBocHandlerIdx,(CmiHandlerEx)_processHandler,ck);
   register int i = 0;
   PtrVec &inits=*CksvAccess(_nodeBocInitVec);
   register int len = inits.size();
-  for(i=0; i<len; i++) {
+  for(i=1; i<len; i++) {
     envelope *env = inits[i];
-    if(env==0) continue;
+    if(env==0) CkAbort("_processBufferedNodeBocInits: empty message");
     if(env->isPacked())
       CkUnpackMessage(&env);
     _processNodeBocInitMsg(ck,env);
@@ -490,6 +538,14 @@ static int _charmLoadEstimator(void)
   return CkpvAccess(_buffQ)->length();
 }
 
+/**
+ * This function is used to send other processors on the same node a signal so
+ * they can check if their _initDone can be called: the reason for this is that
+ * the check at the end of _initHandler can fail due to a missing message containing
+ * a Nodegroup creation. When that message arrives only one processor will receive
+ * it, and thus if no notification is sent to the other processors in the node, they
+ * will never proceed.
+ */
 static void _sendTriggers(void)
 {
   int i, num, first;
@@ -498,7 +554,7 @@ static void _sendTriggers(void)
   {
     _triggersSent++;
     num = CmiMyNodeSize();
-    register envelope *env = _allocEnv(RODataMsg);
+    register envelope *env = _allocEnv(RODataMsg); // Notice that the type here is irrelevant
     env->setSrcPe(CkMyPe());
     CmiSetHandler(env, _triggerHandlerIdx);
     first = CmiNodeFirst(CmiMyNode());
@@ -510,6 +566,15 @@ static void _sendTriggers(void)
   CmiImmediateUnlock(CksvAccess(_nodeGroupTableImmLock));
 }
 
+/**
+ * This function (not a handler) is called once and only once per processor.
+ * It signals the processor that the initialization is done and regular messages
+ * can be processed.
+ *
+ * On processor zero it is called by _initCharm, on all other processors either
+ * by _initHandler or _triggerHandler (cannot be both).
+ * When fault-tolerance is active, it is called by the fault-tolerance scheme itself.
+ */
 void _initDone(void)
 {
   DEBUGF(("[%d] _initDone.\n", CkMyPe()));
@@ -528,6 +593,13 @@ void _initDone(void)
   CkpvAccess(_charmEpoch)=1;
 }
 
+/**
+ * Converse handler receiving a signal from another processors in the same node.
+ * (On _sendTrigger there is the explanation of why this is necessary)
+ * Simply check if with the NodeGroup processed by another processor we reached
+ * the expected count. Notice that it can only be called before _initDone: after
+ * _initDone, a message destined for this handler will go instead to the _discardHandler.
+ */
 static void _triggerHandler(envelope *env)
 {
   if (_numExpectInitMsgs && CkpvAccess(_numInitsRecd) + CksvAccess(_numInitNodeMsgs) == _numExpectInitMsgs)
@@ -551,39 +623,52 @@ static inline void _processRODataMsg(envelope *env)
   CmiFree(env);
 }
 
+/**
+ * This is similar to the _initHandler, only that the Groups and Nodegroups are
+ * initialized from disk, so only one single message is expected.
+ *
+ * It is unclear how Readonly Messages are treated during restart... (if at all considered)
+ */
 static void _roRestartHandler(void *msg)
 {
   CkAssert(CkMyPe()!=0);
   register envelope *env = (envelope *) msg;
-  CkpvAccess(_numInitsRecd)+=2;  /*++;*/
+  CkpvAccess(_numInitsRecd)++;
   _numExpectInitMsgs = env->getCount();
   _processRODataMsg(env);
 }
 
-static void _roHandler(void *msg)
-{
-  CpvAccess(_qd)->process();
-  _roRestartHandler(msg);
-}
-
+/**
+ * This handler is used only during initialization. It receives messages from
+ * processor zero regarding Readonly Data (in one single message), Readonly Messages,
+ * Groups, and Nodegroups.
+ * The Readonly Data message also contains the total number of messages expected
+ * during the initialization phase.
+ * For Groups and Nodegroups, only messages with epoch=0 (meaning created from within
+ * a mainchare) are buffered for special creation, the other messages are buffered
+ * together with all the other regular messages by _bufferHandler (and will be flushed
+ * after all the initialization messages have been processed).
+ */
 static void _initHandler(void *msg)
 {
   CkAssert(CkMyPe()!=0);
   register envelope *env = (envelope *) msg;
   switch (env->getMsgtype()) {
     case BocInitMsg:
-      if (env->getGroupEpoch()==0)
+      if (env->getGroupEpoch()==0) {
         CkpvAccess(_numInitsRecd)++;
-      CpvAccess(_qd)->process();
-      CkpvAccess(_bocInitVec)->insert(env->getGroupNum().idx, env);
+        CpvAccess(_qd)->process();
+        CkpvAccess(_bocInitVec)->insert(env->getGroupNum().idx, env);
+      } else _bufferHandler(msg);
       break;
     case NodeBocInitMsg:
-      CmiImmediateLock(CksvAccess(_nodeGroupTableImmLock));
-      if (env->getGroupEpoch()==0)
+      if (env->getGroupEpoch()==0) {
+        CmiImmediateLock(CksvAccess(_nodeGroupTableImmLock));
         CksvAccess(_numInitNodeMsgs)++;
-      CksvAccess(_nodeBocInitVec)->insert(env->getGroupNum().idx, env);
-      CmiImmediateUnlock(CksvAccess(_nodeGroupTableImmLock));
-      CpvAccess(_qd)->process();
+        CksvAccess(_nodeBocInitVec)->insert(env->getGroupNum().idx, env);
+        CmiImmediateUnlock(CksvAccess(_nodeGroupTableImmLock));
+        CpvAccess(_qd)->process();
+      } else _bufferHandler(msg);
       break;
     case ROMsgMsg:
       CkpvAccess(_numInitsRecd)++;
@@ -592,7 +677,7 @@ static void _initHandler(void *msg)
       _processROMsgMsg(env);
       break;
     case RODataMsg:
-      CkpvAccess(_numInitsRecd)+=2;  /*++;*/
+      CkpvAccess(_numInitsRecd)++;
       CpvAccess(_qd)->process();
       _numExpectInitMsgs = env->getCount();
       _processRODataMsg(env);
@@ -600,8 +685,8 @@ static void _initHandler(void *msg)
     default:
       CmiAbort("Internal Error: Unknown-msg-type. Contact Developers.\n");
   }
-       DEBUGF(("[%d,%.6lf] _numExpectInitMsgs %d CkpvAccess(_numInitsRecd)+CksvAccess(_numInitNodeMsgs) %d\n",CmiMyPe(),CmiWallTimer(),_numExpectInitMsgs,CkpvAccess(_numInitsRecd)+CksvAccess(_numInitNodeMsgs)));
-  if(_numExpectInitMsgs&&(CkpvAccess(_numInitsRecd)+CksvAccess(_numInitNodeMsgs)>=_numExpectInitMsgs)) {
+       DEBUGF(("[%d,%.6lf] _numExpectInitMsgs %d CkpvAccess(_numInitsRecd)+CksvAccess(_numInitNodeMsgs) %d+%d\n",CmiMyPe(),CmiWallTimer(),_numExpectInitMsgs,CkpvAccess(_numInitsRecd),CksvAccess(_numInitNodeMsgs)));
+  if(_numExpectInitMsgs&&(CkpvAccess(_numInitsRecd)+CksvAccess(_numInitNodeMsgs)==_numExpectInitMsgs)) {
     _initDone();
   }
 }
@@ -616,7 +701,6 @@ void _CkExit(void)
   //
   CkNumberHandler(_charmHandlerIdx,(CmiHandler)_discardHandler);
   CkNumberHandler(_bocHandlerIdx, (CmiHandler)_discardHandler);
-  CkNumberHandler(_nodeBocHandlerIdx, (CmiHandler)_discardHandler);
   DEBUGF(("[%d] CkExit - _exitStarted:%d %d\n", CkMyPe(), _exitStarted, _exitHandlerIdx));
 
   if(CkMyPe()==0) {
@@ -710,7 +794,7 @@ void InitCallTable::enumerateInitCalls()
   for (i=0; i<initProcCalls.length(); i++) initProcCalls[i]();
 }
 
-CpvCExtern(int, cmiArgDebugFlag);
+CpvCExtern(int, cpdSuspendStartup);
 extern "C" void CpdFreeze(void);
 
 extern int _dummy_dq;
@@ -771,7 +855,7 @@ void _initCharm(int unused_argc, char **argv)
 #endif
        CpvInitialize(int,serializer);
 
-#if CMK_FT_CHARE
+#ifndef CMK_CHARE_USE_PTR
           /* chare and vidblock table */
         CpvInitialize(CkVec<void *>, chare_objs);
         CpvInitialize(CkVec<VidBlock *>, vidblocks);
@@ -812,6 +896,8 @@ void _initCharm(int unused_argc, char **argv)
                CksvAccess(_nodeBocInitVec) = new PtrVec();
        }
 
+       CkCallbackInit();
+       
        CmiNodeAllBarrier();
 
 #if ! CMK_BLUEGENE_CHARM
@@ -820,18 +906,16 @@ void _initCharm(int unused_argc, char **argv)
 
        CkpvAccess(_coreState)=new CkCoreState();
 
-       CkpvAccess(_numInitsRecd) = -1;  /*0;*/
+       CkpvAccess(_numInitsRecd) = 0;
 
        CkpvAccess(_ckout) = new _CkOutStream();
        CkpvAccess(_ckerr) = new _CkErrStream();
 
        _charmHandlerIdx = CkRegisterHandler((CmiHandler)_bufferHandler);
        _initHandlerIdx = CkRegisterHandler((CmiHandler)_initHandler);
-       _roHandlerIdx = CkRegisterHandler((CmiHandler)_roHandler);
        _roRestartHandlerIdx = CkRegisterHandler((CmiHandler)_roRestartHandler);
        _exitHandlerIdx = CkRegisterHandler((CmiHandler)_exitHandler);
        _bocHandlerIdx = CkRegisterHandler((CmiHandler)_initHandler);
-       _nodeBocHandlerIdx = CkRegisterHandler((CmiHandler)_initHandler);
        _infoIdx = CldRegisterInfoFn((CldInfoFn)_infoFn);
        _triggerHandlerIdx = CkRegisterHandler((CmiHandler)_triggerHandler);
        _ckModuleInit();
@@ -851,6 +935,8 @@ void _initCharm(int unused_argc, char **argv)
         traceCharmInit(argv);
 #endif
        
+    CkpvInitialize(int, envelopeEventID);
+    CkpvAccess(envelopeEventID) = 0;
        CkMessageWatcherInit(argv,CkpvAccess(_coreState));
        
        /**
@@ -1094,7 +1180,7 @@ void _initCharm(int unused_argc, char **argv)
         }
 
 #if CMK_CCS_AVAILABLE
-       if (CpvAccess(cmiArgDebugFlag))
+       if (CpvAccess(cpdSuspendStartup))
        { 
           //CmiPrintf("In Parallel Debugging mode .....\n");
           CpdFreeze();
index 69578316cabe0ae7d906f48aba873aac201a9052..2df503bf0adddea6a5e58bb78c6f2a8ab3835599 100644 (file)
@@ -124,11 +124,8 @@ extern unsigned int    _printSS;
 
 extern int     _infoIdx;
 extern int     _charmHandlerIdx;
-extern int     _roHandlerIdx;
 extern int     _roRestartHandlerIdx;     /* for checkpoint/restart */
-extern int     _initHandlerIdx;
 extern int     _bocHandlerIdx;
-extern int     _nodeBocHandlerIdx;
 extern int     _qdHandlerIdx;
 extern unsigned int   _numInitMsgs;
 
index 0eaca99b25b7441fc91a333dedae29b1e6fa0139..9698c61a7186b578a967a3ab74ca5009217251cb 100644 (file)
@@ -40,6 +40,13 @@ static void periodicProcessControlPoints(void* ptr, double currWallTime);
 /* readonly */ bool shouldGatherAll;
 
 
+
+/// The control point values to be used for the first few phases if the strategy doesn't choose to do something else.
+/// These probably come from the command line arguments, so are available only on PE 0
+std::map<std::string, int> defaultControlPointValues;
+
+
+
 typedef enum tuningSchemeEnum {RandomSelection, SimulatedAnnealing, ExhaustiveSearch, CriticalPathAutoPrioritization, UseBestKnownTiming, UseSteering, MemoryAware}  tuningScheme;
 
 
@@ -103,21 +110,16 @@ CkReductionMsg *idleTimeReduction(int nMsg,CkReductionMsg **msgs){
 /// A reduction type that combines idle, overhead, and memory measurements
 CkReduction::reducerType allMeasuresReductionType;
 /// A reducer that combines idle, overhead, and memory measurements
+#define ALL_REDUCTION_SIZE 12
 CkReductionMsg *allMeasuresReduction(int nMsg,CkReductionMsg **msgs){
-  double ret[7];
+  double ret[ALL_REDUCTION_SIZE];
   if(nMsg > 0){
-    CkAssert(msgs[0]->getSize()==7*sizeof(double));
+    CkAssert(msgs[0]->getSize()==ALL_REDUCTION_SIZE*sizeof(double));
     double *m=(double *)msgs[0]->getData();
-    ret[0]=m[0];
-    ret[1]=m[1];
-    ret[2]=m[2];
-    ret[3]=m[3];
-    ret[4]=m[4];
-    ret[5]=m[5];
-    ret[6]=m[6];
+    memcpy(ret, m, ALL_REDUCTION_SIZE*sizeof(double) );
   }
   for (int i=1;i<nMsg;i++) {
-    CkAssert(msgs[i]->getSize()==7*sizeof(double));
+    CkAssert(msgs[i]->getSize()==ALL_REDUCTION_SIZE*sizeof(double));
     double *m=(double *)msgs[i]->getData();
     // idle time (min/sum/max)
     ret[0]=min(ret[0],m[0]);
@@ -129,8 +131,15 @@ CkReductionMsg *allMeasuresReduction(int nMsg,CkReductionMsg **msgs){
     ret[5]=max(ret[5],m[5]);
     // mem usage (max)
     ret[6]=max(ret[6],m[6]);
+    // bytes per invocation for two types of entry methods
+    ret[7]+=m[7];
+    ret[8]+=m[8];
+    ret[9]+=m[9];
+    ret[10]+=m[10];
+    // Grain size (avg)
+    ret[11]+=m[11];
   }  
-  return CkReductionMsg::buildNew(7*sizeof(double),ret);   
+  return CkReductionMsg::buildNew(ALL_REDUCTION_SIZE*sizeof(double),ret);   
 }
 
 
@@ -269,10 +278,17 @@ controlPointManager::controlPointManager(){
       iss >> ips->memoryUsageMB;
       //     CkPrintf("Memory usage loaded from file: %d\n", ips.memoryUsageMB);
 
+      // Read idle time
       iss >> ips->idleTime.min;
       iss >> ips->idleTime.avg;
       iss >> ips->idleTime.max;
 
+      // read bytePerInvoke
+      iss >> ips->bytesPerInvoke;
+
+      // read grain size
+      iss >> ips->grainSize;
+
       // Read control point values
       for(int cp=0;cp<numControlPointNames;cp++){
        int cpvalue;
@@ -280,6 +296,12 @@ controlPointManager::controlPointManager(){
        ips->controlPoints.insert(make_pair(names[cp],cpvalue));
       }
 
+      // ignore median time
+      double mt;
+      iss >> mt;
+
+      // Read all times
+
       double time;
 
       while(iss >> time){
@@ -315,7 +337,7 @@ controlPointManager::controlPointManager(){
   }
 
   /// User can register a callback that is called when application should advance to next phase
-  void controlPointManager::setGranularityCallback(CkCallback cb, bool _frameworkShouldAdvancePhase){
+  void controlPointManager::setCPCallback(CkCallback cb, bool _frameworkShouldAdvancePhase){
     frameworkShouldAdvancePhase = _frameworkShouldAdvancePhase;
     granularityCallback = cb;
     haveGranularityCallback = true;
@@ -707,40 +729,53 @@ controlPointManager::controlPointManager(){
 
   /// Entry method called on all PEs to request CPU utilization statistics and memory usage
   void controlPointManager::requestAll(CkCallback cb){
-    const double i = localControlPointTracingInstance()->idleRatio();
-    const double o = localControlPointTracingInstance()->overheadRatio();
-    const double m = localControlPointTracingInstance()->memoryUsageMB();
-    
-    double data[3+3+1];
+    TraceControlPoints *t = localControlPointTracingInstance();
+
+    double data[ALL_REDUCTION_SIZE];
 
     double *idle = data;
     double *over = data+3;
     double *mem = data+6;
+    double *msgBytes = data+7;  
+    double *grainsize = data+11;  
 
+    const double i = t->idleRatio();
     idle[0] = i;
     idle[1] = i;
     idle[2] = i;
 
+    const double o = t->overheadRatio();
     over[0] = o;
     over[1] = o;
     over[2] = o;
 
+    const double m = t->memoryUsageMB();
     mem[0] = m;
+
+    msgBytes[0] = t->b2;
+    msgBytes[1] = t->b3;
+    msgBytes[2] = t->b2mlen;
+    msgBytes[3] = t->b3mlen;
+
+    grainsize[0] = t->grainSize();
     
     localControlPointTracingInstance()->resetAll();
 
-    contribute(7*sizeof(double),data,allMeasuresReductionType, cb);
+    contribute(ALL_REDUCTION_SIZE*sizeof(double),data,allMeasuresReductionType, cb);
   }
   
   /// All processors reduce their memory usages in requestIdleTime() to this method
   void controlPointManager::gatherAll(CkReductionMsg *msg){
+    CkAssert(msg->getSize()==ALL_REDUCTION_SIZE*sizeof(double));
     int size=msg->getSize() / sizeof(double);
-    CkAssert(size==7);
     double *data=(double *) msg->getData();
         
     double *idle = data;
     double *over = data+3;
     double *mem = data+6;
+    double *msgBytes = data+7;
+    double *granularity = data+11;
+
 
     //    std::string b = allData.toString();
 
@@ -754,6 +789,23 @@ controlPointManager::controlPointManager(){
       
       CkPrintf("Stored idle time min=%lf, mem=%lf in prevPhase=%p\n", (double)prevPhase->idleTime.min, (double)prevPhase->memoryUsageMB, prevPhase);
 
+      double bytesPerInvoke2 = msgBytes[2] / msgBytes[0];
+      double bytesPerInvoke3 = msgBytes[3] / msgBytes[1];
+
+      /** The average of the grain sizes on all PEs in us */
+      prevPhase->grainSize = (granularity[0] / (double)CkNumPes());
+
+      CkPrintf("Bytes Per Invokation 2 = %f\n", bytesPerInvoke2);
+      CkPrintf("Bytes Per Invokation 3 = %f\n", bytesPerInvoke3);
+
+      CkPrintf("Bytes Per us of work 2 = %f\n", bytesPerInvoke2/prevPhase->grainSize);
+      CkPrintf("Bytes Per us of work 3 = %f\n", bytesPerInvoke3/prevPhase->grainSize);
+
+      if(bytesPerInvoke2 > bytesPerInvoke3)
+       prevPhase->bytesPerInvoke = bytesPerInvoke2;
+      else
+       prevPhase->bytesPerInvoke = bytesPerInvoke3;
+
       //      prevPhase->print();
       // CkPrintf("prevPhase=%p number of timings=%d\n", prevPhase, prevPhase->times.size() );
 
@@ -909,8 +961,8 @@ public:
     int usec = (int)((time - (double)sec)*1000000.0);
     random_seed =  sec ^ usec;
 #endif
-
-
+    
+    
     double period;
     bool haveSamplePeriod = CmiGetArgDoubleDesc(args->argv,"+CPSamplePeriod", &period,"The time between Control Point Framework samples (in seconds)");
     if(haveSamplePeriod){
@@ -919,9 +971,9 @@ public:
     } else {
       controlPointSamplePeriod =  DEFAULT_CONTROL_POINT_SAMPLE_PERIOD;
     }
-
-
-
+    
+    
+    
     whichTuningScheme = RandomSelection;
 
 
@@ -941,6 +993,34 @@ public:
       whichTuningScheme = MemoryAware;
     }
 
+    char *defValStr = NULL;
+    if( CmiGetArgStringDesc(args->argv, "+CPDefaultValues", &defValStr, "Specify the default control point values used for the first couple phases") ){
+      CkPrintf("You specified default value string: %s\n", defValStr);
+      
+      // Parse the string, looking for commas
+     
+
+      char *tok = strtok(defValStr, ",");
+      while (tok) {
+       // split on the equal sign
+       int len = strlen(tok);
+       char *eqsign = strchr(tok, '=');
+       if(eqsign != NULL && eqsign != tok){
+         *eqsign = '\0';
+         char *cpname = tok;
+         std::string cpName(tok);
+         char *cpDefVal = eqsign+1;      
+         int v=-1;
+         if(sscanf(cpDefVal, "%d", &v) == 1){
+           CkPrintf("Command Line Argument Specifies that Control Point \"%s\" defaults to %d\n", cpname, v);
+           CkAssert(CkMyPe() == 0); // can only access defaultControlPointValues on PE 0
+           defaultControlPointValues[cpName] = v;
+         }
+       }
+       tok = strtok(NULL, ",");
+      }
+
+    }
 
     shouldGatherAll = false;
     shouldGatherMemoryUsage = false;
@@ -967,16 +1047,17 @@ public:
       loadDataFileAtStartup = true;
     }
 
+
     controlPointManagerProxy = CProxy_controlPointManager::ckNew();
   }
   ~controlPointMain(){}
 };
 
 /// An interface callable by the application.
-void registerGranularityChangeCallback(CkCallback cb, bool frameworkShouldAdvancePhase){
+void registerCPChangeCallback(CkCallback cb, bool frameworkShouldAdvancePhase){
   CkAssert(CkMyPe() == 0);
   CkPrintf("Application has registered a control point change callback\n");
-  controlPointManagerProxy.ckLocalBranch()->setGranularityCallback(cb, frameworkShouldAdvancePhase);
+  controlPointManagerProxy.ckLocalBranch()->setCPCallback(cb, frameworkShouldAdvancePhase);
 }
 
 /// An interface callable by the application.
@@ -1391,9 +1472,17 @@ int controlPoint(const char *name, int lb, int ub){
   
 
   if( phase_id < 4 ){
-    // For the first few phases, just use the lower bound. 
-    // This ensures that the ranges for all the control points known before we do anything fancy
+    // For the first few phases, just use the lower bound, or the default if one was provided 
+    // This ensures that the ranges for all the control points are known before we do anything fancy
     result = lb;
+
+
+    if(defaultControlPointValues.count(std::string(name)) > 0){
+      int v = defaultControlPointValues[std::string(name)];
+      CkPrintf("Startup phase using default value of %d for  \"%s\"\n", v, name);   
+      result = v;
+    }
+
   } else if(controlPointSpace.count(std::string(name)) == 0){
     // if this is the first time we've seen the CP, then return the lower bound
     result = lb;
index 9abc9f1173e83f5a69045826a393a75d52c13bba..6641e138144c9bbdf999c586e1a7fbe00c05d934 100644 (file)
@@ -18,6 +18,7 @@
 #include <cmath>
 #include <math.h>
 #include <iostream>
+#include <iomanip>
 #include <fstream>
 #include <string>
 #include <sstream>
@@ -50,7 +51,7 @@
 
 
 
-void registerGranularityChangeCallback(CkCallback cb, bool frameworkShouldAdvancePhase);
+void registerCPChangeCallback(CkCallback cb, bool frameworkShouldAdvancePhase);
 
 
 void registerControlPointTiming(double time);
@@ -149,14 +150,25 @@ public:
 
   idleTimeContainer idleTime;
 
+  /** Approximately records the average message size for an entry method. */
+  double bytesPerInvoke;
+
+  /** Records the average grain size (might be off a bit due to non application entry methods), in seconds */
+  double grainSize;
+
+
   instrumentedPhase(){
     memoryUsageMB = -1.0;
+    grainSize = -1.0;
+    bytesPerInvoke = -1.0;
   }
   
   void clear(){
     controlPoints.clear();
     times.clear();
     memoryUsageMB = -1.0;
+    grainSize = -1.0;
+    bytesPerInvoke = -1.0;
     //    criticalPaths.clear();
   }
 
@@ -295,7 +307,14 @@ public:
     } 
     
   }
-  
+
+  /** Determine the median time for this phase */
+  double medianTime(){
+    std::vector<double> sortedTimes = times;
+    std::sort(sortedTimes.begin(), sortedTimes.end());
+    return sortedTimes[sortedTimes.size() / 2];
+  }
+
   
 };
 
@@ -379,30 +398,43 @@ public:
       // SCHEMA:
       s << "# SCHEMA:\n";
       s << "# number of named control points:\n";
-      s << ps.size() << "\n";
-      
+      s << ps.size() << "\n";    
       for(cpiter = ps.begin(); cpiter != ps.end(); cpiter++){
        s << cpiter->first << "\n";
       }
       
       // DATA:
       s << "# DATA:\n";
-      s << "# first field is memory usage (MB). Then there are the " << ps.size()  << " control points values, followed by one or more timings" << "\n";
-      s << "# number of control point sets: " << phases.size() << "\n";
+      s << "# There are " << ps.size()  << " control points\n";
+      s << "# number of recorded phases: " << phases.size() << "\n";
+      
+      s << "# Memory (MB)\tIdle Min\tIdle Avg\tIdle Max\tByte Per Invoke\tGrain Size\t";
+      for(cpiter = ps.begin(); cpiter != ps.end(); cpiter++){
+       s << cpiter->first << "\t";
+      }
+      s << "Median Timing\tTimings\n";
+      
+   
       std::vector<instrumentedPhase*>::iterator runiter;
       for(runiter=phases.begin();runiter!=phases.end();runiter++){
        
        // Print the memory usage
-       s << (*runiter)->memoryUsageMB << "    "; 
+       s << (*runiter)->memoryUsageMB << "\t"; 
+
+       s << (*runiter)->idleTime.min << "\t" << (*runiter)->idleTime.avg << "\t" << (*runiter)->idleTime.max << "\t";
+
+       s << (*runiter)->bytesPerInvoke << "\t";
+
+       s << (*runiter)->grainSize << "\t";
 
-       s << (*runiter)->idleTime.min << " " << (*runiter)->idleTime.avg << " " << (*runiter)->idleTime.max << "   ";
 
        // Print the control point values
        for(cpiter = (*runiter)->controlPoints.begin(); cpiter != (*runiter)->controlPoints.end(); cpiter++){ 
-         s << cpiter->second << " "; 
+         s << cpiter->second << "\t"; 
        }
 
-       s << "     ";
+       // Print the median time
+       s << (*runiter)->medianTime() << "\t";
 
        // Print the times
        std::vector<double>::iterator titer;
@@ -560,7 +592,7 @@ public:
   void writeDataFile();
 
   /// User can register a callback that is called when application should advance to next phase
-  void setGranularityCallback(CkCallback cb, bool _frameworkShouldAdvancePhase);
+  void setCPCallback(CkCallback cb, bool _frameworkShouldAdvancePhase);
 
   /// Called periodically by the runtime to handle the control points
   /// Currently called on each PE
index 2f8d8d6df9964e98509c4510028a499a6f87a6b9..83fcdfedf61115b4746dfc69fb3a83806e9214a6 100644 (file)
@@ -33,8 +33,14 @@ static CkGroupID  _theNullLB;
 static int _migDoneHandle;             // converse handler
 // converse handler 
 // send converse message to avoid QD detection
-static void migrationDone(envelope *env)
+static void migrationDone(envelope *env, CkCoreState *ck)
 {
+  // Since migrationsDone will deal with Charm++ messages,
+  // the LB must obey to the CkMessageWatcher orders.
+  if (ck->watcher!=NULL) {
+    if (!ck->watcher->processMessage(env,ck)) return;
+  }
+  
   NullLB *lb = (NullLB*)CkLocalBranch(_theNullLB);
   lb->migrationsDone();
   CkFreeSysMsg(EnvToUsr(env));
@@ -48,6 +54,8 @@ static void lbinit(void) {
 static void lbprocinit(void) {
 #if NULLLB_CONVERSE
   _migDoneHandle = CkRegisterHandler((CmiHandler)migrationDone);
+  CkNumberHandlerEx(_migDoneHandle, (CmiHandlerEx)migrationDone, CkpvAccess(_coreState));
+  // FIXME: Really a function "CkRegisterHandlerEx" should exist...
 #endif
 }
 
index 30565738f0bf3d63739c68dfe814c615dc20a6ce..ea317b772869eb40d4d9c194bd45356dc292c559 100644 (file)
@@ -30,9 +30,12 @@ void _createTracecontrolPoints(char **argv)
 
 TraceControlPoints::TraceControlPoints(char **argv)
 {
-
   resetTimings();
 
+  b1=0;
+  b2=0;
+  b3=0;
+
   if (CkpvAccess(traceOnPe) == 0) return;
 
   // Process runtime arguments intended for the module
@@ -70,7 +73,7 @@ void TraceControlPoints::beginExecute(CmiObjId *tid)
   // CmiObjId is a 4-integer tuple uniquely identifying a migratable
   //   Charm++ object. Note that there are other non-migratable Charm++
   //   objects that CmiObjId will not identify.
-
+  b1++;
   lastBeginExecuteTime = CmiWallTimer();
   lastbeginMessageSize = -1;
 
@@ -81,7 +84,8 @@ void TraceControlPoints::beginExecute(envelope *e)
 {
   lastBeginExecuteTime = CmiWallTimer();
   lastbeginMessageSize = e->getTotalsize();
-
+  b2++;
+  b2mlen += lastbeginMessageSize;
   //  CkPrintf("[%d] WARNING ignoring TraceControlPoints::beginExecute(envelope *e)\n", CkMyPe());
 
   // no message means thread execution
@@ -93,10 +97,12 @@ void TraceControlPoints::beginExecute(envelope *e)
   //  CkPrintf("[%d] TraceControlPoints::beginExecute(envelope *e=%p)\n", CkMyPe(), e);
 
 }
-
 void TraceControlPoints::beginExecute(int event,int msgType,int ep,int srcPe, 
                               int mlen, CmiObjId *idx)
 {
+  b3++;
+  b3mlen += mlen;
   lastBeginExecuteTime = CmiWallTimer();
   lastbeginMessageSize = mlen;
   //  CkPrintf("[%d] TraceControlPoints::beginExecute event=%d, msgType=%d, ep=%d, srcPe=%d, mlen=%d CmiObjId is also avaliable\n", CkMyPe(), event, msgType, ep, srcPe, mlen);
@@ -108,7 +114,8 @@ void TraceControlPoints::endExecute(void)
 {
   double executionTime = CmiWallTimer() - lastBeginExecuteTime;
   totalEntryMethodTime += executionTime;
-  
+  totalEntryMethodInvocations ++;
+
   double m = (double)CmiMemoryUsage();
   if(memUsage < m){
     memUsage = m;
@@ -183,6 +190,7 @@ void TraceControlPointsBOC::printBGP_UPC_CountersBOC(void) {
 void TraceControlPoints::resetTimings(){
   totalIdleTime = 0.0;
   totalEntryMethodTime = 0.0;
+  totalEntryMethodInvocations = 0;
   lastResetTime = CmiWallTimer();
 }
 
@@ -190,6 +198,11 @@ void TraceControlPoints::resetAll(){
   totalIdleTime = 0.0;
   totalEntryMethodTime = 0.0;
   memUsage = 0;
+  totalEntryMethodInvocations = 0;
+  b2mlen=0;
+  b3mlen=0;
+  b2=0;
+  b3=0;
   lastResetTime = CmiWallTimer();
 }
 
index 7614a2a807cc36e3c188bf60efba38a53a284330..4e0b654de376e25f486ba26d2de1502555d065d9 100644 (file)
@@ -28,23 +28,29 @@ class TraceControlPoints : public Trace {
   double lastBeginExecuteTime;
   int lastbeginMessageSize;
 
-  /** The amount of time spent executing entry methods */
-  double totalEntryMethodTime;
-
-
   /** The start of the idle region */
   double lastBeginIdle;
   
-  /** The amount of time spent idle */
+  /** The amount of time spent executing entry methods since we last reset the counters */
+  double totalEntryMethodTime;
+
+  /** The amount of time spent idle since we last reset the counters */
   double totalIdleTime;
-  
-  /** The time we last rest the idle/entry totals */
-  double lastResetTime;
 
-  /** The highest seen memory usage */
+  /** The highest seen memory usage  since we last reset the counters */
   double memUsage;
 
-  
+  /** The number of entry method invocations since we last reset the counters */
+  long totalEntryMethodInvocations;
+
+    
+  /** The time we last rest the counters */
+  double lastResetTime;
+
+ public: 
+  int b1, b2, b3;
+  long b2mlen;
+  long b3mlen;
 
  public:
   TraceControlPoints(char **argv);
@@ -101,23 +107,31 @@ class TraceControlPoints : public Trace {
   /** Reset the idle, overhead, and memory measurements */
   void resetAll();
 
-  /** Fraction of the time spent idle */
+  /** Fraction of the time spent idle since resetting the counters */
   double idleRatio(){
     double t = CmiWallTimer() - lastResetTime;
     return (totalIdleTime) / t;
   }
 
-  /** Fraction of time spent as overhead */
+  /** Fraction of time spent as overhead since resetting the counters */
   double overheadRatio(){
     double t = CmiWallTimer() - lastResetTime;
     return (t - totalIdleTime - totalEntryMethodTime) / t;
   }
 
-  /** Highest memory usage (in MB) value we've seen since last time */
+  /** Highest memory usage (in MB) value we've seen since resetting the counters */
   double memoryUsageMB(){
     return ((double)memUsage) / 1024.0 / 1024.0;
   }
 
+  /** Determine the average grain size since last reset of counters */
+  double grainSize(){
+    return (double)totalEntryMethodTime / totalEntryMethodInvocations;
+  }
+
+  double bytesPerEntry() {
+    return (double)(b2mlen + b3mlen) / (double)(b2+b3);
+  }
 
 
 };
diff --git a/src/ck-perf/trace-recordreplay.C b/src/ck-perf/trace-recordreplay.C
deleted file mode 100644 (file)
index bd33cd9..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*****************************************************************************
- * $Source$
- * $Author$
- * $Date$
- * $Revision$
- *****************************************************************************/
-
-/**
- * \addtogroup CkPerf
-*/
-/*@{*/
-
-#include "charm++.h"
-#include "trace-recordreplay.h"
-#include "signal.h"
-
-#define DEBUGF(x)  // CmiPrintf x
-
-#define VER   4.0
-
-#define INVALIDEP     -2
-
-CkpvStaticDeclare(TraceRecordReplay*, _trace);
-
-/**
-  For each TraceFoo module, _createTraceFoo() must be defined.
-  This function is called in _createTraces() generated in moduleInit.C
-*/
-void _createTracerecordreplay(char **argv)
-{
-  DEBUGF(("%d createTraceRecordReplay\n", CkMyPe()));
-  CkpvInitialize(TraceRecordReplay*, _trace);
-  CkpvAccess(_trace) = new  TraceRecordReplay(argv);
-  CkpvAccess(_traces)->addTrace(CkpvAccess(_trace));
-}
-
-TraceRecordReplay::TraceRecordReplay(char **argv):curevent(1) {}
-
-void TraceRecordReplay::beginExecute(envelope *e)
-{
-  // no message means thread execution
-  if (e==NULL) {
-  }
-  else {
-    e->setEvent(curevent++);
-  }  
-}
-
-
-void TraceRecordReplay::creation(envelope *e, int ep, int num)
-{
-  e->setEvent(curevent++);
-}
-
-
-/*@}*/
diff --git a/src/ck-perf/trace-recordreplay.h b/src/ck-perf/trace-recordreplay.h
deleted file mode 100644 (file)
index ca7cd81..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*****************************************************************************
- * $Source$
- * $Author$
- * $Date$
- * $Revision$
- *****************************************************************************/
-
-/**
- * \addtogroup CkPerf
-*/
-/*@{*/
-
-#ifndef _RECORDREPLAY_H
-#define _RECORDREPLAY_H
-
-#include <stdio.h>
-#include <errno.h>
-
-#include "trace.h"
-#include "envelope.h"
-#include "register.h"
-#include "trace-common.h"
-
-// initial bin size, time in seconds
-#define  BIN_SIZE      0.001
-
-#define  MAX_MARKS       256
-
-#define  MAX_PHASES       10
-
-
-/// class for recording trace record replay 
-/**
-  TraceRecordReplay increments curEvent variable in the envelope everytime a message is executed 
-*/
-class TraceRecordReplay : public Trace {
-    int curevent;
-  public:
-    TraceRecordReplay(char **argv);
-    void creation(envelope *e, int epIdx, int num=1);
-
-    void beginExecute(envelope *e);
-};
-
-#endif
-
-/*@}*/
index 44054cb401af1ca870bc9c2f28a125dfa5b561ff..ac1e35c3b9431c6eb4197b5f3dcfddd5e1a28fa8 100644 (file)
@@ -492,6 +492,7 @@ void CcsBuiltinsInit(char **argv);
 
 CpvDeclare(int, cmiArgDebugFlag);
 CpvDeclare(char *, displayArgument);
+CpvDeclare(int, cpdSuspendStartup);
 
 void CcsInit(char **argv)
 {
@@ -502,9 +503,11 @@ void CcsInit(char **argv)
   _ccsHandlerIdx = CmiRegisterHandler((CmiHandler)req_fw_handler);
   CpvInitialize(int, cmiArgDebugFlag);
   CpvInitialize(char *, displayArgument);
+  CpvInitialize(int, cpdSuspendStartup);
   CpvAccess(cmiArgDebugFlag) = 0;
   CpvAccess(displayArgument) = NULL;
-
+  CpvAccess(cpdSuspendStartup) = 0;
+  
   CcsBuiltinsInit(argv);
 
   rep_fw_handler_idx = CmiRegisterHandler((CmiHandler)rep_fw_handler);
@@ -541,6 +544,9 @@ void CcsInit(char **argv)
             CmiPrintf("WARNING> x term for gdb needs to be specified as +DebugDisplay by debugger\n***\n");
      }
 
+     if (CmiGetArgFlagDesc(argv, "+DebugSuspend", "Suspend execution at beginning of program")) {
+       CpvAccess(cpdSuspendStartup) = 1;
+     }
   }
 }
 
index df4c609923697531bcc6ba9fbe87b53830059599..a0e07824f37aa3a6858b6fd38f0a664e3016f344 100644 (file)
@@ -84,6 +84,7 @@ extern "C" {
 #endif
 
 /* Global variables used by charmdebug to maintain information */
+extern void CpdSetInitializeMemory(int v);
 #ifndef CMK_OPTIMIZE
 extern int memory_status_info;
 extern int memory_chare_id;
index 57c0685021c87c7d68e4defeb695905594a84297..a730efed3b704399104982c1666f58966bf4901f 100644 (file)
@@ -351,8 +351,14 @@ void CpdInit(void)
 
 }
 
+void PrintDebugStackTrace(void *);
+
 #include <stdarg.h>
 void CpdNotify(int type, ...) {
+  void *ptr; int integer, i;
+  int levels=64;
+  void *stackPtrs[64];
+  void *sl;
   va_list list;
   va_start(list, type);
   switch (type) {
@@ -368,6 +374,24 @@ void CpdNotify(int type, ...) {
   case CPD_BREAKPOINT:
     CmiPrintf("CPD: %d BP %s\n",CmiMyPe(), va_arg(list, char*));
     break;
+  case CPD_CROSSCORRUPTION:
+    ptr = va_arg(list, void*);
+    integer = va_arg(list, int);
+    CmiPrintf("CPD: %d Cross %p %d ",CmiMyPe(), ptr, integer);
+    sl = MemoryToSlot(ptr);
+    if (sl != NULL) {
+      int stackLen; void **stackTrace;
+      stackLen = Slot_StackTrace(sl, &stackTrace);
+      CmiPrintf("%d %d ",Slot_ChareOwner(sl),stackLen);
+      for (i=0; i<stackLen; ++i) CmiPrintf("%p ",stackTrace[i]);
+    } else {
+      CmiPrintf("0 ");
+    }
+    CmiBacktraceRecord(stackPtrs,1,&levels);
+    CmiPrintf("%d ",levels);
+    for (i=0; i<levels; ++i) CmiPrintf("%p ",stackPtrs[i]);
+    CmiPrintf("\n");
+    break;
   }
   va_end(list);
 }
index 917cbeed063574714ae0f10eecaceec0a704e488..e733023acef43889a9f866edf9a75546b117816f 100644 (file)
@@ -41,7 +41,8 @@ enum {
   CPD_SIGNAL = 1,
   CPD_ABORT = 2,
   CPD_FREEZE = 3,
-  CPD_BREAKPOINT = 4
+  CPD_BREAKPOINT = 4,
+  CPD_CROSSCORRUPTION = 5
 };
 extern void CpdNotify(int type, ...);
 
index 18efde499ee145ab51e38405cb091035e4a50aea..da149141662befc3d0a3a9b5d473f37d5be59d13 100644 (file)
@@ -133,6 +133,19 @@ static int isLeakSlot(Slot *s) {
   return s->magic & LEAK_FLAG;
 }
 
+int Slot_ChareOwner(void *s) {
+  return ((Slot*)s)->chareID;
+}
+
+int Slot_AllocatedSize(void *s) {
+  return ((Slot*)s)->userSize;
+}
+
+int Slot_StackTrace(void *s, void ***stack) {
+  *stack = ((Slot*)s)->from;
+  return ((Slot*)s)->stackLen;
+}
+
 static void printSlot(Slot *s) {
   CmiPrintf("[%d] Leaked block of %d bytes at %p:\n",
            CmiMyPe(), s->userSize, SlotToUser(s));
@@ -834,24 +847,24 @@ static int CpdCRC32 = 0;
 
 static int checkSlotCRC(void *userPtr) {
   Slot *sl = UserToSlot(userPtr);
-  unsigned int crc = crc32((unsigned char*)sl, sizeof(Slot)-2*sizeof(unsigned int));
+  unsigned int crc = crc32_initial((unsigned char*)sl, sizeof(Slot)-2*sizeof(unsigned int));
   crc = crc32_update((unsigned char*)sl->from, sl->stackLen*sizeof(void*), crc);
   return sl->slotCRC == crc;
 }
 
 static int checkUserCRC(void *userPtr) {
   Slot *sl = UserToSlot(userPtr);
-  return sl->userCRC == crc32((unsigned char*)userPtr, sl->userSize);
+  return sl->userCRC == crc32_initial((unsigned char*)userPtr, sl->userSize);
 }
 
 static void resetUserCRC(void *userPtr) {
   Slot *sl = UserToSlot(userPtr);
-  sl->userCRC = crc32((unsigned char*)userPtr, sl->userSize);
+  sl->userCRC = crc32_initial((unsigned char*)userPtr, sl->userSize);
 }
 
 static void resetSlotCRC(void *userPtr) {
   Slot *sl = UserToSlot(userPtr);
-  unsigned int crc = crc32((unsigned char*)sl, sizeof(Slot)-2*sizeof(unsigned int));
+  unsigned int crc = crc32_initial((unsigned char*)sl, sizeof(Slot)-2*sizeof(unsigned int));
   crc = crc32_update((unsigned char*)sl->from, sl->stackLen*sizeof(void*), crc);
   sl->slotCRC = crc;
 }
@@ -870,9 +883,9 @@ static void CheckAllCRC(int report) {
   unsigned int crc1, crc2;
 
   SLOT_ITERATE_START(cur)
-    crc1 = crc32((unsigned char*)cur, sizeof(Slot)-2*sizeof(unsigned int));
+    crc1 = crc32_initial((unsigned char*)cur, sizeof(Slot)-2*sizeof(unsigned int));
     crc1 = crc32_update((unsigned char*)cur->from, cur->stackLen*sizeof(void*), crc1);
-    crc2 = crc32((unsigned char*)SlotToUser(cur), cur->userSize);
+    crc2 = crc32_initial((unsigned char*)SlotToUser(cur), cur->userSize);
     /* Here we can check if a modification has occured */
     if (report && cur->slotCRC != crc1) CmiPrintf("CRC: Object %d modified slot for %p\n",memory_chare_id,SlotToUser(cur));
     cur->slotCRC = crc1;
@@ -1003,8 +1016,9 @@ static void CpdMMAPhandler(int sig, siginfo_t *si, void *unused){
     unProtectedPages = newUnProtectedPages;
   }
   unProtectedPages[unProtectedPagesSize++] = pageToUnprotect;
-  CmiPrintf("Got SIGSEGV at address: 0x%lx\n", (long) si->si_addr);
-  CmiPrintStackTrace(0);
+  CpdNotify(CPD_CROSSCORRUPTION, si->si_addr, memory_chare_id);
+  //CmiPrintf("Got SIGSEGV at address: 0x%lx\n", (long) si->si_addr);
+  //CmiPrintStackTrace(0);
 }
 
 static void protectMemory() {
@@ -1014,7 +1028,12 @@ static void protectMemory() {
   SLOT_ITERATE_START(cur)
     if (cur->chareID != memory_chare_id && cur->chareID > 0) {
       /*printf(" %p",cur->userData);*/
-      mprotect(cur->userData, cur->userSize+SLOTSPACE+cur->stackLen*sizeof(void*), PROT_READ);
+#ifdef CMK_SEPARATE_SLOT
+      char * data = cur->userData;
+#else
+      char * data = (char *)cur;
+#endif
+      mprotect(data, cur->userSize+SLOTSPACE+cur->stackLen*sizeof(void*), PROT_READ);
     } /*else printf(" (%p)",cur->userData);*/
   SLOT_ITERATE_END
   /*printf("\n");*/
@@ -1025,7 +1044,12 @@ static void unProtectMemory() {
 #ifdef CPD_USE_MMAP
   Slot *cur;
   SLOT_ITERATE_START(cur)
-    mprotect(cur->userData, cur->userSize+SLOTSPACE+cur->stackLen*sizeof(void*), PROT_READ|PROT_WRITE);
+#ifdef CMK_SEPARATE_SLOT
+      char * data = cur->userData;
+#else
+      char * data = (char *)cur;
+#endif
+    mprotect(data, cur->userSize+SLOTSPACE+cur->stackLen*sizeof(void*), PROT_READ|PROT_WRITE);
   SLOT_ITERATE_END
   /*printf("unprotecting memory\n");*/
 #endif
@@ -1057,8 +1081,6 @@ void CpdCheckMemory(int report) {
   SLOT_ITERATE_END
 }
 
-static int cpdInSystem;
-
 void CpdSystemEnter() {
 #ifdef CPD_USE_MMAP
   Slot *cur;
@@ -1221,9 +1243,9 @@ static void *setSlot(Slot **sl,int userSize) {
   memcpy(s->from, &stackFrames[4], numStackFrames*sizeof(void*));
 
   if (CpdCRC32) {
-    unsigned int crc = crc32((unsigned char*)s, sizeof(Slot)-2*sizeof(unsigned int));
+    unsigned int crc = crc32_initial((unsigned char*)s, sizeof(Slot)-2*sizeof(unsigned int));
     s->slotCRC = crc32_update((unsigned char*)s->from, numStackFrames*sizeof(void*), crc);
-    s->userCRC = crc32((unsigned char*)user, userSize);
+    s->userCRC = crc32_initial((unsigned char*)user, userSize);
   }
   if (saveAllocationHistory) {
     if (allocatedSinceSize >= allocatedSinceMaxSize) {
@@ -1290,12 +1312,15 @@ static void status(char *msg) {
 extern int getCharmEnvelopeSize();
 
 static int disableVerbosity = 1;
+int cpdInitializeMemory;
+void CpdSetInitializeMemory(int v) { cpdInitializeMemory = v; }
 
 static void meta_init(char **argv) {
   status("Converse -memory mode: charmdebug\n");
   char buf[100];
   sprintf(buf,"slot size %d\n",sizeof(Slot));
   status(buf);
+  cpdInitializeMemory = 0;
   charmEnvelopeSize = getCharmEnvelopeSize();
   CpdDebugGetAllocationTree = (void* (*)(int*))CreateAllocationTree;
   CpdDebug_pupAllocationPoint = pupAllocationPoint;
@@ -1361,6 +1386,9 @@ static void *meta_malloc(size_t size) {
     user = mm_malloc(size);
     AFTER_MALLOC_CALL;
   }
+  if (cpdInitializeMemory) {
+    bzero(user, size); // for Record-Replay must initialize all memory otherwise paddings may differ (screwing up the CRC)
+  }
   return user;
 }
 
@@ -1554,3 +1582,26 @@ void setMemoryOwnedBy(void *ptr, int chareID) {
   Slot *sl = UserToSlot(ptr);
   sl->chareID = chareID;
 }
+
+void * MemoryToSlot(void *ptr) {
+  Slot *sl;
+  int i;
+#if defined(CPD_USE_MMAP) && defined(CMK_SEPARATE_SLOT)
+  for (i=0; i<1000; ++i) {
+    sl = UserToSlot((void*)(((CmiUInt8)ptr)-i*meta_getpagesize() & ~(meta_getpagesize()-1)));
+    if (sl != NULL) return sl;
+  }
+#endif
+  return NULL;
+}
+
+/*void PrintDebugStackTrace(void *ptr) {
+  int i;
+  Slot *sl = UserToSlot((void*)(((CmiUInt8)ptr) & ~(meta_getpagesize()-1)));
+  if (sl != NULL) {
+    CmiPrintf("%d %d ",sl->chareID,sl->stackLen);
+    for (i=0; i<sl->stackLen; ++i) CmiPrintf("%p ",sl->from[i]);
+  } else {
+    CmiPrintf("%d 0 ",sl->chareID);
+  }
+}*/
index cef93cdc7742763046880c07eeef77e240f579a4..0407b4db4119ffbbfbae0c49ec45bb2f7b4d61fb 100644 (file)
@@ -57,6 +57,7 @@
 #include "converse.h"
 
 void * memory_stack_top; /*The higher end of the stack (approximation)*/
+int cpdInSystem=0;
 
 /*Choose the proper default configuration*/
 #if CMK_MEMORY_BUILD_DEFAULT
@@ -735,6 +736,7 @@ void CmiOutOfMemoryInit(void) {
 
 #ifndef CMK_MEMORY_BUILD_CHARMDEBUG
 /* declare the cpd_memory routines */
+void CpdSetInitializeMemory(int v) { }
 size_t  cpd_memory_length(void *lenParam) { return 0; }
 void cpd_memory_pup(void *itemParam,pup_er p,CpdListItemsRequest *req) { }
 void cpd_memory_leak(void *itemParam,pup_er p,CpdListItemsRequest *req) { }
@@ -760,6 +762,10 @@ void CpdResetMemory() { }
 void CpdCheckMemory() { }
 
 int get_memory_allocated_user_total() { return 0; }
+void * MemoryToSlot(void *ptr) { return NULL; }
+int Slot_ChareOwner(void *s) { return 0; }
+int Slot_AllocatedSize(void *s) { return 0; }
+int Slot_StackTrace(void *s, void ***stack) { return 0; }
 #ifdef setMemoryChareIDFromPtr
 #undef setMemoryChareIDFromPtr
 #endif
index 6187d2a3c329235ab7b759e7e751bccc685b4f15..faef1f5bbddc2b4b19bde181b9afe10b5879fbe8 100644 (file)
@@ -24,7 +24,7 @@ quiescence detection!
 #include <stdio.h>
 #include <stdlib.h>
 #ifndef  DEBUGF
-#define  DEBUGF(x) printf x 
+#define  DEBUGF(x) /*printf x*/ 
 #endif
 
 CpvDeclare(CQdState, cQdState);
index 6325ee31b00b0bc3c6124a31d25bae09f91b84cf..23b023ff1445f70d7659228d2218d842eacbead8 100644 (file)
@@ -381,16 +381,6 @@ CthCpvStatic(int, _defaultStackSize);
 static void CthThreadBaseInit(CthThreadBase *th)
 {
   static int serialno = 1;
-#if CMK_LINUX_PTHREAD_HACK
-  /*HACK for LinuxThreads: to support our user-level threads
-    library, we use a slightly modified version of libpthread.a
-    with user-level threads support enabled via these flags.
-  */
-  extern int __pthread_find_self_with_pid;
-  extern int __pthread_nonstandard_stacks;
-  __pthread_find_self_with_pid=1;
-  __pthread_nonstandard_stacks=1;
-#endif
   th->token = (CthThreadToken *)malloc(sizeof(CthThreadToken));
   th->token->thread = S(th);
   th->scheduled = 0;
index 280e4cd143e991efcca4c030300e69918e27e04e..87fc36f09687d98f22a0d2ec5aff51ed17f3524a 100644 (file)
@@ -240,6 +240,10 @@ 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);
+long ARMCI_NbGetValueLong(void *src, int proc, armci_hdl_t* handle);
+int ARMCI_NbGetValueInt(void *src, int proc, armci_hdl_t* handle);
+float ARMCI_NbGetValueFloat(void *src, int proc, armci_hdl_t* handle);
+double ARMCI_NbGetValueDouble(void *src, int proc, armci_hdl_t* handle);
 
 /* ********************************** */
 /* Functions for Non-blocking support */
@@ -303,7 +307,12 @@ void ARMCI_MemCheckpoint(void);
 /* ******************************** */
 /* Collective Operations            */
 void armci_msg_brdcst(void *buffer, int len, int root);
+void armci_msg_bcast(void *buffer, int len, int root);
 void armci_msg_gop2(void *x, int n, int type, char *op);
+void armci_msg_igop(int *x, int n, char *op);
+void armci_msg_lgop(long *x, int n, char *op);
+void armci_msg_fgop(float *x, int n, char *op);
+void armci_msg_dgop(double *x, int n, char *op);
 void armci_msg_barrier(void);
 void armci_msg_reduce(void *x, int n, char *op, int type);
 
@@ -321,4 +330,4 @@ int armci_domain_my_id(armci_domain_t domain);
 
 #define ARMCI_INIT_HANDLE(hdl) 
 
-#endif
+#endif // _ARMCI_H
index 45e7c76166b96786f7c0ee5bc291dc0ca76536fc..6ff021115a10266d67675a4f6df477f14161a350 100644 (file)
@@ -120,7 +120,11 @@ CDECL int ARMCI_Put(void *src, void *dst, int bytes, int proc) {
 CDECL int ARMCI_NbPut(void *src, void* dst, int bytes, int proc, armci_hdl_t *handle){
   TCHARM_API_TRACE("ARMCI_NbPut", "armci");
   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
-  *handle = vp->nbput(src, dst, bytes, proc);
+  if (handle != NULL) {
+    *handle = vp->nbput(src, dst, bytes, proc);
+  } else {
+    vp->nbput_implicit(src, dst, bytes, proc);
+  }
   return 0;
 }
 
@@ -135,7 +139,11 @@ CDECL int ARMCI_Get(void *src, void *dst, int bytes, int proc) {
 CDECL int ARMCI_NbGet(void *src, void* dst, int bytes, int proc, armci_hdl_t *handle){
   TCHARM_API_TRACE("ARMCI_NbGet", "armci");
   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
-  *handle = vp->nbget(src, dst, bytes, proc);
+  if (handle != NULL) {
+    *handle = vp->nbget(src, dst, bytes, proc);
+  } else {
+    vp->nbget_implicit(src, dst, bytes, proc);
+  }
   return 0;
 }
 
@@ -175,7 +183,13 @@ CDECL int ARMCI_NbPutS(
                 ){
   TCHARM_API_TRACE("ARMCI_NbPutS", "armci");
   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
-  *handle = vp->nbputs(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar, count, stride_levels, proc);
+  if (handle != NULL) {
+    *handle = vp->nbputs(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar, 
+                        count, stride_levels, proc);
+  } else {
+    vp->nbputs_implicit(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar,
+                       count, stride_levels, proc);
+  }
   return 0;
 }
 
@@ -213,7 +227,13 @@ CDECL int ARMCI_NbGetS(
                ){
   TCHARM_API_TRACE("ARMCI_NbGetS", "armci");
   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
-  *handle = vp->nbgets(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar, count, stride_levels, proc);
+  if (handle != NULL) {
+    *handle = vp->nbgets(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar, 
+                        count, stride_levels, proc);
+  } else {
+    vp->nbgets_implicit(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar,
+                       count, stride_levels, proc);
+  }
   return 0;
 }
 
@@ -265,12 +285,20 @@ CDECL long ARMCI_GetValueLong(void *src, int proc) { return 0; }
 CDECL int ARMCI_GetValueInt(void *src, int proc) { return 0; }
 CDECL float ARMCI_GetValueFloat(void *src, int proc) { return 0.0; }
 CDECL double ARMCI_GetValueDouble(void *src, int proc) { return 0.0; }
+CDECL long ARMCI_NbGetValueLong(void *src, int proc, armci_hdl_t* handle) { return 0; }
+CDECL int ARMCI_NbGetValueInt(void *src, int proc, armci_hdl_t* handle) { return 0; }
+CDECL float ARMCI_NbGetValueFloat(void *src, int proc, armci_hdl_t* handle) { return 0.0; }
+CDECL double ARMCI_NbGetValueDouble(void *src, int proc, armci_hdl_t* handle) { return 0.0; }
 
 // global completion operations
 CDECL int ARMCI_Wait(armci_hdl_t *handle){
   TCHARM_API_TRACE("ARMCI_Wait", "armci");
   ArmciVirtualProcessor *vp = CtvAccess(_armci_ptr);
-  vp->wait(*handle);
+  if (handle != NULL) {
+    vp->wait(*handle);
+  } else {
+    CmiAbort("ARMCI ERROR: Cannot pass NULL to ARMCI_Wait\n");
+  }
   return 0;
 }
 
@@ -390,9 +418,24 @@ CDECL int armci_notify_wait(int proc, int *pval){
 CDECL void armci_msg_brdcst(void *buffer, int len, int root) {
 }
 
+CDECL void armci_msg_bcast(void *buffer, int len, int root) {
+}
+
 CDECL void armci_msg_gop2(void *x, int n, int type, char *op) {
 }
 
+CDECL void armci_msg_igop(int *x, int n, char *op) {
+}
+
+CDECL void armci_msg_lgop(long *x, int n, char *op) {
+}
+
+CDECL void armci_msg_fgop(float *x, int n, char *op) {
+}
+
+CDECL void armci_msg_dgop(double *x, int n, char *op) {
+}
+
 CDECL void armci_msg_barrier(void) {
 }
 
index afdbd52fa2dadf13a10397a67057c4275e6fa49d..f943f37e26ce04c8b682975cf939da01779501fd 100644 (file)
@@ -19,9 +19,15 @@ PUPbytes(pointer) //Pointers get sent as raw bytes
 #define ARMCI_GET      0x1
 #define ARMCI_PUT      0x2
 #define ARMCI_ACC      0x3
+#define ARMCI_BGET      0x5
 #define ARMCI_BPUT     0x6
 #define ARMCI_BACC     0x7
+
+#define ARMCI_IGET      0x9  // implicit get
+#define ARMCI_IPUT      0xa  // implicit put
+
 #define BLOCKING_MASK  0x4
+#define IMPLICIT_MASK   0x8  // anything that is implicit is non-blocking
 
 class Armci_Hdl {
 public:
@@ -29,18 +35,21 @@ public:
    int proc;
    int nbytes;
    int acked;
+   int wait;    // Is WaitProc or WaitAll waiting for me?
    pointer src;
    pointer dst;
    
  Armci_Hdl() : op(ARMCI_INVALID), proc(-1), nbytes(0), acked(0), src(NULL), dst(NULL) 
Armci_Hdl() : op(ARMCI_INVALID), proc(-1), nbytes(0), acked(0), wait(0), src(NULL), dst(NULL) 
        { }
    Armci_Hdl(int o, int p, int n, pointer s, pointer d):
-       op(o), proc(p), nbytes(n), acked(0), src(s), dst(d) { }
+   op(o), proc(p), nbytes(n), acked(0), wait(0), src(s), dst(d) { }
    void pup(PUP::er &p){
-     p|op; p|proc; p|nbytes; p|acked; p|src; p|dst;    
+     p|op; p|proc; p|nbytes; p|acked; p|wait; p|src; p|dst;    
    }
 };
 
+// Support for ARMCI notify feature designed for Co-Array Fortran. Should
+//   be orthogonal to wait/fence operations.
 class Armci_Note{
 public:
   int proc;
@@ -157,6 +166,7 @@ class ArmciVirtualProcessor : public TCharmClient1D {
   void putData(ArmciMsg* msg);
   void putAck(int hdl);
   int nbput(pointer src, pointer dst, int bytes, int dst_proc);
+  void nbput_implicit(pointer src, pointer dst, int bytes, int dst_proc);
   void wait(int hdl);
   int test(int hdl);
   void waitmulti(vector<int> procs);
@@ -168,6 +178,7 @@ class ArmciVirtualProcessor : public TCharmClient1D {
   
   void get(pointer src, pointer dst, int bytes, int src_proc);
   int nbget(pointer src, pointer dst, int bytes, int dst_proc);
+  void nbget_implicit(pointer src, pointer dst, int bytes, int dst_proc);
   void requestFromGet(pointer src, pointer dst, int nbytes, int dst_proc, int hdl);
   void putDataFromGet(pointer dst, int nbytes, char *data, int hdl);
   void putDataFromGet(ArmciMsg* msg);
@@ -178,6 +189,9 @@ class ArmciVirtualProcessor : public TCharmClient1D {
   int nbputs(pointer src_ptr, int src_stride_ar[], 
           pointer dst_ptr, int dst_stride_ar[],
           int count[], int stride_levels, int dst_proc);
+  void nbputs_implicit(pointer src_ptr, int src_stride_ar[], 
+                      pointer dst_ptr, int dst_stride_ar[],
+                      int count[], int stride_levels, int dst_proc);
   void putsData(pointer dst_ptr, int dst_stride_ar[], 
                int count[], int stride_levels,
                int nbytes, char *data, int src_proc, int hdl);
@@ -189,6 +203,9 @@ class ArmciVirtualProcessor : public TCharmClient1D {
   int nbgets(pointer src_ptr, int src_stride_ar[], 
           pointer dst_ptr, int dst_stride_ar[],
           int count[], int stride_levels, int src_proc);
+  void nbgets_implicit(pointer src_ptr, int src_stride_ar[], 
+                      pointer dst_ptr, int dst_stride_ar[],
+                      int count[], int stride_levels, int src_proc);
   void requestFromGets(pointer src_ptr, int src_stride_ar[], 
           pointer dst_ptr, int dst_stride_ar[],
           int count[], int stride_levels, int dst_proc, int hdl);
index b5c9a44405a5efedd4200c844468b7c2db1a1eed..dd0df31358151003f23f67985af58c5f4ad92a64 100644 (file)
@@ -108,6 +108,17 @@ int ArmciVirtualProcessor::nbput(pointer src, pointer dst,
   return hdl;
 }
 
+void ArmciVirtualProcessor::nbput_implicit(pointer src, pointer dst,
+                                         int nbytes, int dst_proc) {
+  int hdl = hdlList.size();
+  Armci_Hdl* entry = new Armci_Hdl(ARMCI_IPUT, dst_proc, nbytes, src, dst);
+  hdlList.push_back(entry);
+
+  ArmciMsg *msg = new (nbytes, 0) ArmciMsg(dst,nbytes,thisIndex,hdl);
+  memcpy(msg->data, src, nbytes);
+  thisProxy[dst_proc].putData(msg);
+}
+
 void ArmciVirtualProcessor::putData(pointer dst, int nbytes, char *data,
                                    int src_proc, int hdl) {
   memcpy(dst, data, nbytes);
@@ -123,6 +134,10 @@ void ArmciVirtualProcessor::putData(ArmciMsg *m) {
 void ArmciVirtualProcessor::putAck(int hdl) {
   if(hdl != -1) { // non-blocking 
     hdlList[hdl]->acked = 1;  
+    if (hdlList[hdl]->wait == 1) {
+      hdlList[hdl]->wait = 0;
+      thread->resume();
+    }
   }
   thread->resume();
 }
@@ -144,6 +159,7 @@ int ArmciVirtualProcessor::nbget(pointer src, pointer dst,
     memcpy(dst,src,nbytes);
     return -1;
   }*/
+
   int hdl = hdlList.size();
   Armci_Hdl* entry = new Armci_Hdl(ARMCI_GET, src_proc, nbytes, src, dst);
   hdlList.push_back(entry);
@@ -153,6 +169,15 @@ int ArmciVirtualProcessor::nbget(pointer src, pointer dst,
   return hdl;
 }
 
+void ArmciVirtualProcessor::nbget_implicit(pointer src, pointer dst,
+                                          int nbytes, int src_proc) {
+  int hdl = hdlList.size();
+  Armci_Hdl* entry = new Armci_Hdl(ARMCI_IGET, src_proc, nbytes, src, dst);
+  hdlList.push_back(entry);
+  
+  thisProxy[src_proc].requestFromGet(src, dst, nbytes, thisIndex, hdl);
+}
+
 void ArmciVirtualProcessor::wait(int hdl){
   if(hdl == -1) return;
   while (1) {
@@ -163,6 +188,13 @@ void ArmciVirtualProcessor::wait(int hdl){
   }
 }
 
+// CWL NOTE: This works only because in wait(), the while (1) loop
+//   insists on matching the first unackowledged non-blocking call 
+//   waitmulti is
+//   waiting on. Out-of-order acknowledgements will wake the thread
+//   but cause it to suspend itself again until the call is acknowledged.
+//   Subsequent calls to wait from waitmulti will then succeed because
+//   out-of-order acks would have set the acked flag.
 void ArmciVirtualProcessor::waitmulti(vector<int> procs){
   for(int i=0;i<procs.size();i++){
     wait(procs[i]);
@@ -172,8 +204,12 @@ void ArmciVirtualProcessor::waitmulti(vector<int> procs){
 void ArmciVirtualProcessor::waitproc(int proc){
   vector<int> procs;
   for(int i=0;i<hdlList.size();i++){
-    if(hdlList[i]->acked == 0 && hdlList[i]->proc == proc && hdlList[i]->op & BLOCKING_MASK == 0)
+    if((hdlList[i]->acked == 0) && 
+       (hdlList[i]->proc == proc) && 
+       (hdlList[i]->op & IMPLICIT_MASK != 0)) {
+      hdlList[i]->wait = 1;
       procs.push_back(i);
+    }
   }
   waitmulti(procs);
 }
@@ -181,8 +217,11 @@ void ArmciVirtualProcessor::waitproc(int proc){
 void ArmciVirtualProcessor::waitall(){
   vector<int> procs;
   for(int i=0;i<hdlList.size();i++){
-    if(hdlList[i]->acked == 0 && hdlList[i]->op & BLOCKING_MASK == 0)
+    if((hdlList[i]->acked == 0) && 
+       (hdlList[i]->op & IMPLICIT_MASK != 0)) {
+      hdlList[i]->wait = 1;
       procs.push_back(i);
+    }
   }
   waitmulti(procs);
 }
@@ -190,7 +229,9 @@ void ArmciVirtualProcessor::waitall(){
 void ArmciVirtualProcessor::fence(int proc){
   vector<int> procs;
   for(int i=0;i<hdlList.size();i++){
-    if(hdlList[i]->acked == 0 && (hdlList[i]->op & BLOCKING_MASK) && hdlList[i]->proc == proc)
+    if((hdlList[i]->acked == 0) && 
+       (hdlList[i]->op & BLOCKING_MASK != 0) && 
+       (hdlList[i]->proc == proc))
       procs.push_back(i);
   }
   waitmulti(procs);
@@ -198,7 +239,8 @@ void ArmciVirtualProcessor::fence(int proc){
 void ArmciVirtualProcessor::allfence(){
   vector<int> procs;
   for(int i=0;i<hdlList.size();i++){
-    if(hdlList[i]->acked == 0 && (hdlList[i]->op & BLOCKING_MASK))
+    if((hdlList[i]->acked == 0) && 
+       (hdlList[i]->op & BLOCKING_MASK != 0))
       procs.push_back(i);
   }
   waitmulti(procs);
@@ -233,6 +275,10 @@ void ArmciVirtualProcessor::putDataFromGet(pointer dst, int nbytes, char *data,
   memcpy(dst, data, nbytes);
   if(hdl != -1) { // non-blocking 
     hdlList[hdl]->acked = 1;  
+    if (hdlList[hdl]->wait == 1) {
+      hdlList[hdl]->wait = 0;
+      thread->resume();
+    }
   }
   thread->resume();
 }
@@ -241,6 +287,10 @@ void ArmciVirtualProcessor::putDataFromGet(ArmciMsg *m) {
   memcpy(m->dst, m->data, m->nbytes);
   if(m->hdl != -1) { // non-blocking 
     hdlList[m->hdl]->acked = 1;  
+    if (hdlList[m->hdl]->wait == 1) {
+      hdlList[m->hdl]->wait = 0;
+      thread->resume();
+    }
   }
   delete m;
   thread->resume();
@@ -299,6 +349,28 @@ int ArmciVirtualProcessor::nbputs(pointer src_ptr, int src_stride_ar[],
   return hdl;
 }
 
+void ArmciVirtualProcessor::nbputs_implicit(pointer src_ptr, 
+                                           int src_stride_ar[], 
+                                           pointer dst_ptr, 
+                                           int dst_stride_ar[],
+                                           int count[], int stride_levels, 
+                                           int dst_proc){
+  int nbytes = 1;
+  for(int i=0;i<stride_levels+1;i++) 
+    nbytes *= count[i];
+  int hdl = hdlList.size();
+  Armci_Hdl* entry = new Armci_Hdl(ARMCI_IPUT, dst_proc, nbytes, 
+                                  src_ptr, dst_ptr);
+  hdlList.push_back(entry);
+  ArmciStridedMsg *m = new (stride_levels,stride_levels+1,nbytes, 0) ArmciStridedMsg(dst_ptr,stride_levels,nbytes,thisIndex,hdl);
+
+  memcpy(m->dst_stride_ar,dst_stride_ar,sizeof(int)*stride_levels);
+  memcpy(m->count,count,sizeof(int)*(stride_levels+1));
+  stridedCopy(src_ptr, m->data, src_stride_ar, count, stride_levels, 1);
+  thisProxy[dst_proc].putsData(m);
+}
+
 void ArmciVirtualProcessor::putsData(pointer dst_ptr, int dst_stride_ar[], 
                int count[], int stride_levels,
                int nbytes, char *data, int src_proc, int hdl){
@@ -331,6 +403,7 @@ void ArmciVirtualProcessor::gets(pointer src_ptr, int src_stride_ar[],
   // wait for reply
   thread->suspend();
 }
+
 int ArmciVirtualProcessor::nbgets(pointer src_ptr, int src_stride_ar[], 
           pointer dst_ptr, int dst_stride_ar[],
           int count[], int stride_levels, int src_proc){
@@ -355,6 +428,25 @@ int ArmciVirtualProcessor::nbgets(pointer src_ptr, int src_stride_ar[],
 
   return hdl;
 }
+
+void ArmciVirtualProcessor::nbgets_implicit(pointer src_ptr, 
+                                           int src_stride_ar[], 
+                                           pointer dst_ptr, 
+                                           int dst_stride_ar[],
+                                           int count[], int stride_levels, 
+                                           int src_proc) {
+  int hdl = hdlList.size();
+  int nbytes = 1;
+  for(int i=0;i<stride_levels+1;i++) 
+    nbytes *= count[i];
+
+  Armci_Hdl* entry = new Armci_Hdl(ARMCI_IGET, src_proc, nbytes, src_ptr, dst_ptr);
+  hdlList.push_back(entry);
+
+  thisProxy[src_proc].requestFromGets(src_ptr, src_stride_ar, dst_ptr, dst_stride_ar, 
+                                       count, stride_levels, thisIndex, hdl);
+}
+
 void ArmciVirtualProcessor::requestFromGets(pointer src_ptr, int src_stride_ar[], 
           pointer dst_ptr, int dst_stride_ar[], int count[], int stride_levels, int dst_proc, int hdl){
   int nbytes = 1;
@@ -373,6 +465,10 @@ void ArmciVirtualProcessor::putDataFromGets(pointer dst_ptr, int dst_stride_ar[]
   stridedCopy(dst_ptr, data, dst_stride_ar, count, stride_levels, 0);
   if(hdl != -1) { // non-blocking 
     hdlList[hdl]->acked = 1;  
+    if (hdlList[hdl]->wait == 1) {
+      hdlList[hdl]->wait = 0;
+      thread->resume();
+    }
   }
   thread->resume();
 }
@@ -381,6 +477,10 @@ void ArmciVirtualProcessor::putDataFromGets(ArmciStridedMsg *m){
   stridedCopy(m->dst, m->data, m->dst_stride_ar, m->count, m->stride_levels, 0);
   if(m->hdl != -1) { // non-blocking 
     hdlList[m->hdl]->acked = 1;  
+    if (hdlList[m->hdl]->wait == 1) {
+      hdlList[m->hdl]->wait = 0;
+      thread->resume();
+    }
   }
   delete m;
   thread->resume();
index e43ef9642ca74b5f5bb381f3250b3c2f7c543353..67d4ac35d00d7559492d2830e9edc46b4baa0a6a 100644 (file)
@@ -366,24 +366,6 @@ trace-converse.o: trace-converse.c conv-trace.h converse.h conv-config.h \
 trace-all.o: trace-all.C
        $(CHARMC) -c -I. trace-all.C
 
-trace-recordreplay.o: trace-recordreplay.C charm++.h charm.h converse.h \
-  conv-config.h conv-autoconfig.h conv-common.h conv-mach.h \
-  conv-mach-opt.h pup_c.h conv-cpm.h conv-cpath.h conv-qd.h conv-random.h \
-  conv-lists.h conv-trace.h persistent.h debug-conv.h pup.h middle.h \
-  middle-conv.h cklists.h ckbitvector.h ckstream.h init.h ckhashtable.h \
-  debug-charm.h simd.h CkMarshall.decl.h cksection.h ckcallback.h \
-  conv-ccs.h sockRoutines.h ccs-server.h ckobjQ.h ckreduction.h \
-  CkReduction.decl.h cknodegroupreduction.h CkArrayReductionMgr.decl.h \
-  ckmemcheckpoint.h CkMemCheckpoint.decl.h readonly.h ckarray.h \
-  cklocation.h LBDatabase.h lbdb.h LBDBManager.h LBObj.h LBOM.h LBComm.h \
-  LBMachineUtil.h lbdb++.h LBDatabase.decl.h NullLB.decl.h BaseLB.decl.h \
-  CkLocation.decl.h CkArray.decl.h CkFutures.decl.h charisma.h \
-  charisma.decl.h tempo.h tempo.decl.h waitqd.h waitqd.decl.h sdag.h \
-  ckcheckpoint.h CkCheckpoint.decl.h ckevacuation.h ckarrayreductionmgr.h \
-  trace.h trace-bluegene.h envelope.h trace-recordreplay.h register.h \
-  trace-common.h
-       $(CHARMC) -c -I. trace-recordreplay.C
-
 trace-memory.o: trace-memory.C trace-memory.h charm++.h charm.h \
   converse.h conv-config.h conv-autoconfig.h conv-common.h conv-mach.h \
   conv-mach-opt.h pup_c.h conv-cpm.h conv-cpath.h conv-qd.h conv-random.h \
index 8bdc41927b6b4651d8f20515094a4e46153480dc..cff778f66c6de201bbcdf2f9cf4d1f462e960437 100644 (file)
@@ -114,6 +114,7 @@ Tau:
 
 LIBS: CONVLIBS CHARMLIBS
        cd libs; $(MAKE) otherlibs
+       echo "Built LIBS Successfully"
 
 bgtest: bigsim AMPI
        cd ../tests ; $(MAKE) bgtest OPTS='$(OPTS)'
@@ -326,7 +327,7 @@ TRACELIBS=$(L)/libtrace-projections.a  $(L)/libtrace-summary.a   $(L)/libtrace-u
          $(L)/libtrace-simple.a $(L)/libtrace-controlPoints.a\
           $(L)/libtrace-counter.a $(L)/libtrace-bluegene.a \
          $(L)/libtrace-projector.a $(L)/libtrace-all.a $(L)/libtrace-converse.a \
-          $(L)/libtrace-recordreplay.a  $(L)/libtracef_f.a $(L)/libtrace-memory.a
+          $(L)/libtracef_f.a $(L)/libtrace-memory.a
 MEMLIBS=$(L)/libmemory-default.o $(L)/libmemory-os.o $(L)/libmemory-gnu.o \
           $(L)/libmemory-gnuold.o $(L)/libmemory-verbose.o     \
          $(L)/libmemory-paranoid.o \
@@ -841,10 +842,6 @@ $(L)/libtrace-controlPoints.a: $(LIBTRACE_CONTROLPOINTS)
        $(CHARMC) -o $@ $^
 # Do not change this rule!
 
-LIBTRACE_RECREP=trace-recordreplay.o
-$(L)/libtrace-recordreplay.a: $(LIBTRACE_RECREP)
-       $(CHARMC) -o $@ $(LIBTRACE_RECREP)
-
 LIBTRACE_COUNT=trace-counter.o
 $(L)/libtrace-counter.a: $(LIBTRACE_COUNT)
        $(CHARMC) -o $@ $(LIBTRACE_COUNT)
@@ -858,7 +855,7 @@ $(L)/libtrace-memory.a: $(LIBTRACE_MEMORY)
        $(CHARMC) -o $@ $(LIBTRACE_MEMORY)
 
 LIBTRACE_ALL=trace-all.o trace-projections.o trace-summary.o trace-simple.o \
-$(TAU_TRACE_OBJ) trace-recordreplay.o trace-projector.o traceCore.o traceCoreCommon.o charmProjections.o converseProjections.o machineProjections.o trace-memory.o trace-controlPoints.o trace-utilization.o
+$(TAU_TRACE_OBJ) trace-projector.o traceCore.o traceCoreCommon.o charmProjections.o converseProjections.o machineProjections.o trace-memory.o trace-controlPoints.o trace-utilization.o
 
 $(L)/libtrace-all.a: $(LIBTRACE_ALL)
        $(CHARMC) -o $@ $(LIBTRACE_ALL)
@@ -882,7 +879,7 @@ tracef_f.o: tracef_f.f90
 TRACE_OBJS =  trace-projections.o  trace-summary.o  trace-simple.o \
              trace-counter.o trace-controlPoints.o trace-utilization.o \
              trace-bluegene.o trace-projector.o trace-converse.o trace-all.o \
-              trace-recordreplay.o trace-memory.o
+          trace-memory.o
 
 ######################################################################
 #
index ceb0f9dda17ca789a2f617dbb851b5b9eb064b50..9978dff4f886b9197c01b89d49d4b687b0e5d39d 100755 (executable)
@@ -616,10 +616,6 @@ host_alias
 target_alias
 base_version
 SYNC
-WGET
-LYNX
-TELNET
-UUDECODE
 LIBOBJS
 LTLIBOBJS'
 ac_subst_files=''
@@ -3392,232 +3388,21 @@ echo "${ECHO_T}\"$ext\"" >&6; }
   /bin/rm -f conftest.f90
 fi
 
-### go get libpthread.a from charm website ###
+### Check that Linux's C library is recent enough to provide working pthreads
 if test "$base_version" = "net-linux" || test "$base_version" = "mpi-linux"
 then
-case $version in
-*linux*smp*|*linux*vmi*)
-  if test ! -r ../lib/libpthread.a
-  then
-    # Extract the first word of "wget", so it can be a program name with args.
-set dummy wget; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_WGET+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$WGET"; then
-  ac_cv_prog_WGET="$WGET" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_WGET="wget "
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-WGET=$ac_cv_prog_WGET
-if test -n "$WGET"; then
-  { echo "$as_me:$LINENO: result: $WGET" >&5
-echo "${ECHO_T}$WGET" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-    # Extract the first word of "lynx", so it can be a program name with args.
-set dummy lynx; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_LYNX+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$LYNX"; then
-  ac_cv_prog_LYNX="$LYNX" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_LYNX="lynx "
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-LYNX=$ac_cv_prog_LYNX
-if test -n "$LYNX"; then
-  { echo "$as_me:$LINENO: result: $LYNX" >&5
-echo "${ECHO_T}$LYNX" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-    # Extract the first word of "telnet", so it can be a program name with args.
-set dummy telnet; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_TELNET+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$TELNET"; then
-  ac_cv_prog_TELNET="$TELNET" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_TELNET="telnet "
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-TELNET=$ac_cv_prog_TELNET
-if test -n "$TELNET"; then
-  { echo "$as_me:$LINENO: result: $TELNET" >&5
-echo "${ECHO_T}$TELNET" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-    # Extract the first word of "uudecode", so it can be a program name with args.
-set dummy uudecode; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_UUDECODE+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$UUDECODE"; then
-  ac_cv_prog_UUDECODE="$UUDECODE" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_UUDECODE="uudecode "
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-fi
-fi
-UUDECODE=$ac_cv_prog_UUDECODE
-if test -n "$UUDECODE"; then
-  { echo "$as_me:$LINENO: result: $UUDECODE" >&5
-echo "${ECHO_T}$UUDECODE" >&6; }
-else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-
-    CHARMIP='128.174.241.81'
-#    CHARMIP='charm.cs.uiuc.edu'
-#    VERSION=`nm /lib/libc.so.6 | grep "A GLIBC_" | tail -1 | sed -e "s/00000000 A GLIBC_//g"`
+case $version in *linux*smp*|*linux*vmi*)
     { echo "$as_me:$LINENO: checking glibc version" >&5
 echo $ECHO_N "checking glibc version... $ECHO_C" >&6; }
     get_glibc_version
     { echo "$as_me:$LINENO: result: $GLIBCVERSION" >&5
 echo "${ECHO_T}$GLIBCVERSION" >&6; }
-    if test 1 = `expr $GLIBCVERSION \> 2.2.92`
+    if test 0 = `expr $GLIBCVERSION \> 2.2.92`
     then
-      cat >> ./conv-mach-opt.h << EOT
-#undef CMK_LINUX_PTHREAD_HACK
-EOT
-    else
-      L="libpthread-$GLIBCVERSION.a"
-      LSO="libpthread-$GLIBCVERSION.so"
-      URL="http://${CHARMIP}/distrib/$L"
-      URLSO="http://${CHARMIP}/distrib/$LSO"
-      finish=0
-      printf "getting $L from $URL ..."
-      if test -n "$WGET"
-      then
-        printf "(wget) ..."
-        $WGET $URL > /dev/null 2>&1  && mv $L ../lib && finish=1
-        $WGET $URLSO > /dev/null 2>&1  && mv $LSO ../lib_so
-      fi
-      if test $finish = 0 && test -n "$LYNX"
-      then
-        printf "(lynx) ..."
-        $LYNX -source $URL > $L 2>/dev/null
-        if file -L $L | grep 'archive' > /dev/null
-        then
-          mv $L ../lib && finish=1
-        fi
-        $LYNX -source $URLSO > $L 2>/dev/null
-      fi
-      if test $finish = 0 && test -n "$TELNET" && test -n "$UUDECODE"
-      then
-        printf "(telnet) ..."
-        cat > get_libpthread <<EOT
-#! /bin/sh
-echo "GET /distrib/libpthread-$GLIBCVERSION.uu 1.0"
-echo
-# exit normally when the telnet session closes.
-trap "exit 0" 13
-while : ; do
- echo
- sleep 1
-done
-EOT
-        /bin/sh ./get_libpthread | ($TELNET $CHARMIP 80 > .uulib 2>/dev/null); $UUDECODE .uulib 2>/dev/null && rm -f .uulib && mv $L ../lib && finish=1
-      fi
-      ln -s $L ../lib/libpthread.a
-      ln -s $LSO ../lib_so/libpthread.so
-      if test $finish = 0 || test ! -r ../lib/libpthread.a
-      then
-        /bin/rm -f ../lib/libpthread.a
-        echo "failed"
-        echo "#####################################################################"
-        echo "wget, lynx or telnet must be installed to get libpthread.a from charm website."
-        echo "Alternately, your version of GLIBC ($GLIBCVERSION) is not yet supported--"
-        echo " contact ppl@cs.uiuc.edu for assistance."
-        echo "#####################################################################"
-        exit 1
-      else
-        echo "done"
-      fi
+       echo "Your version of GLIBC is ancient, and does not have sufficient "
+       echo "support for pthreads."
+       exit 1
     fi
-  fi
-  ;;
 esac
 fi
 
@@ -4286,15 +4071,11 @@ host_alias!$host_alias$ac_delim
 target_alias!$target_alias$ac_delim
 base_version!$base_version$ac_delim
 SYNC!$SYNC$ac_delim
-WGET!$WGET$ac_delim
-LYNX!$LYNX$ac_delim
-TELNET!$TELNET$ac_delim
-UUDECODE!$UUDECODE$ac_delim
 LIBOBJS!$LIBOBJS$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 45; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 41; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
index 518e3e5d25f41402db1c692a6ad4d849ac7dc42d..01703067e7f84ea40f7cb61e3ab7787456b4fb49 100644 (file)
@@ -1395,86 +1395,19 @@ EOF
   /bin/rm -f conftest.f90
 fi
 
-### go get libpthread.a from charm website ###
+### Check that Linux's C library is recent enough to provide working pthreads
 if test "$base_version" = "net-linux" || test "$base_version" = "mpi-linux"
 then
-case $version in
-*linux*smp*|*linux*vmi*)
-  if test ! -r ../lib/libpthread.a
-  then
-    AC_CHECK_PROG(WGET, wget, wget )
-    AC_CHECK_PROG(LYNX, lynx, lynx )
-    AC_CHECK_PROG(TELNET, telnet, telnet )
-    AC_CHECK_PROG(UUDECODE, uudecode, uudecode )
-    
-    CHARMIP='128.174.241.81'
-#    CHARMIP='charm.cs.uiuc.edu'
-#    VERSION=`nm /lib/libc.so.6 | grep "A GLIBC_" | tail -1 | sed -e "s/00000000 A GLIBC_//g"`
+case $version in *linux*smp*|*linux*vmi*)
     AC_MSG_CHECKING(glibc version)
     get_glibc_version
     AC_MSG_RESULT($GLIBCVERSION)
-    if test 1 = `expr $GLIBCVERSION \> 2.2.92` 
+    if test 0 = `expr $GLIBCVERSION \> 2.2.92`
     then
-      cat >> ./conv-mach-opt.h << EOT
-#undef CMK_LINUX_PTHREAD_HACK
-EOT
-    else
-      L="libpthread-$GLIBCVERSION.a"
-      LSO="libpthread-$GLIBCVERSION.so"
-      URL="http://${CHARMIP}/distrib/$L"
-      URLSO="http://${CHARMIP}/distrib/$LSO"
-      finish=0
-      printf "getting $L from $URL ..."
-      if test -n "$WGET"
-      then
-        printf "(wget) ..."
-        $WGET $URL > /dev/null 2>&1  && mv $L ../lib && finish=1
-        $WGET $URLSO > /dev/null 2>&1  && mv $LSO ../lib_so
-      fi
-      if test $finish = 0 && test -n "$LYNX"
-      then
-        printf "(lynx) ..."
-        $LYNX -source $URL > $L 2>/dev/null 
-        if file -L $L | grep 'archive' > /dev/null
-        then
-          mv $L ../lib && finish=1
-        fi
-        $LYNX -source $URLSO > $L 2>/dev/null 
-      fi
-      if test $finish = 0 && test -n "$TELNET" && test -n "$UUDECODE"
-      then
-        printf "(telnet) ..."
-        cat > get_libpthread <<EOT
-#! /bin/sh
-echo "GET /distrib/libpthread-$GLIBCVERSION.uu 1.0"
-echo
-# exit normally when the telnet session closes.
-trap "exit 0" 13
-while : ; do
- echo
- sleep 1
-done
-EOT
-        /bin/sh ./get_libpthread | ($TELNET $CHARMIP 80 > .uulib 2>/dev/null); $UUDECODE .uulib 2>/dev/null && rm -f .uulib && mv $L ../lib && finish=1
-      fi
-      ln -s $L ../lib/libpthread.a
-      ln -s $LSO ../lib_so/libpthread.so
-      if test $finish = 0 || test ! -r ../lib/libpthread.a
-      then
-        /bin/rm -f ../lib/libpthread.a
-        echo "failed"
-        echo "#####################################################################"
-        echo "wget, lynx or telnet must be installed to get libpthread.a from charm website."
-        echo "Alternately, your version of GLIBC ($GLIBCVERSION) is not yet supported--"
-        echo " contact ppl@cs.uiuc.edu for assistance."
-        echo "#####################################################################"
-        exit 1
-      else
-        echo "done"
-      fi
+       echo "Your version of GLIBC is ancient, and does not have sufficient "
+       echo "support for pthreads."
+       exit 1
     fi
-  fi
-  ;;
 esac
 fi
 
index 1a81a9c372f273d94da562d7db77fc6942400d8b..0a4f8b0d92e36b7d29add207b8099a805206d1ec 100644 (file)
@@ -174,7 +174,7 @@ void CkHashtable::empty(void)
 //Add the given object to this table under the given key
 // Returns pointer to object storage.
 // Table will be resized if needed.
-void *CkHashtable::put(const void *key)
+void *CkHashtable::put(const void *key, int *existing)
 {
        DEBUGF(("Putting key\n"))
 #if 0
@@ -192,6 +192,9 @@ void *CkHashtable::put(const void *key)
                nObj++;
                copyKey(layout.getKey(ent),key);
                layout.fill(ent);
+               if (existing != NULL) *existing = 0;
+       } else {
+         if (existing != NULL) *existing = 1;
        }
        return layout.getObject(ent);
 }
index 62eff03505ccf4fd5f70d512fffbe7c19d414db3..e821b748f09d681e4970519273e67bf249631070 100644 (file)
@@ -238,7 +238,7 @@ public:
        //Add the given object to this table under the given key
        // Returns pointer to object storage.
        // Table will be resized if needed.
-       void *put(const void *key);
+       void *put(const void *key, int *existing=NULL);
        
        //Look up the given object in this table.  Return NULL if not found.
        void *get(const void *key) const {
@@ -332,8 +332,8 @@ public:
         :CkHashtable(getLayout(),initLen,NloadFactor,Nhash,Ncompare)
         {}
        
-       OBJ &put(const KEY &key) {
-               void *obj = CkHashtable::put((const void *)&key);
+       OBJ &put(const KEY &key, int *existing=NULL) {
+               void *obj = CkHashtable::put((const void *)&key, existing);
                return *(OBJ *)obj;
        }
        OBJ get(const KEY &key) const {
index b8371cea98a6855cc77777bfaecbb46ec3a208e9..c0fff787bb0c73f5281f280dc1ec15834cff69fb 100644 (file)
@@ -67,7 +67,7 @@ unsigned int crctab[] = {
       0xbcb4666d,  0xb8757bda,  0xb5365d03,  0xb1f740b4
 };
 
-unsigned int crc32(unsigned char *data, int len)
+unsigned int crc32_initial(unsigned char *data, int len)
 {
     unsigned int        result = 0;
     int                 i;
index d92933bf17773bdb62de27fbee5737f20974462b..cec63532cd58a6f6d3f7e64febb63cc28e4fa8f4 100644 (file)
@@ -9,7 +9,7 @@ extern unsigned int crctab[];
 extern "C" {
 #endif
   
-unsigned int crc32(unsigned char *data, int len);
+unsigned int crc32_initial(unsigned char *data, int len);
 unsigned int crc32_update(unsigned char *data, int len, unsigned int previous);
 
 #ifdef __cplusplus
index 8e69f3a3e62e7236679dbdefbf8f077d5b25edb3..c0465345ecd3ded504a24888ecbeed28334c518d 100644 (file)
@@ -652,51 +652,105 @@ inline __veci __vcmplelf(const  __vecf a, const  __vecf b) {  __veci r; r.v0 = r
   /***** Data Types *****/
   typedef vector signed int veci;
   typedef vector float vecf;
+#ifdef defined(_ARCH_PWR7) 
+/** power 7 VSX supports 64 bit operands, it also includes VMX support
+ * which means that things like vec_div, vec_insert, etcetera work for
+ * ints floats and doubles.  These intrinsics also require a suitably
+ * new version of the compiler on Power 7.  If you are somehow using a
+ * Power 7 with an old compiler, please do not hesitate to open a can
+ * of whoopass on whoever installed the tool chain, because that kind
+ * of stupidity should not be tolerated.
+ */
+  typedef vector double  veclf;
+#else
   typedef __veclf veclf;
+#endif
 
   /***** Insert *****/
-  /* TODO | FIXME - Try to make these functions not reference memory so values stay in registers */
-  inline  veci  vinserti( veci v, const    int s, const int i) {  veci r = v;    int* rPtr = (   int*)(&r); rPtr[i] = s; return r; }
+  /* TODO | FIXME - Try to make these functions not reference memory
+     so values stay in registers */
+
+
+#ifdef defined(_ARCH_PWR7) 
+// swap argument order
+ #define  vinserti(a, b, c)  (vec_insert((b)), ((a)), ((c)))
+ #define  vinsertf(a, b, c)  (vec_insert((b)), ((a)), ((c)))
+ #define  vinsertlf(a, b, c)  (vec_insert((b)), ((a)), ((c)))
+#else
+  inline  veci  vec_inserti( veci v, const    int s, const int i) {  veci r = v;    int* rPtr = (   int*)(&r); rPtr[i] = s; return r; }
   inline  vecf  vinsertf( vecf v, const  float s, const int i) {  vecf r = v;  float* rPtr = ( float*)(&r); rPtr[i] = s; return r; }
-  inline veclf vinsertlf(veclf v, const double s, const int i) { veclf r = v; double* rPtr = (double*)(&r); rPtr[i] = s; return r; }
+  inline veclf vinsertlf(veclf v, const double s, const int i) { return vec_insert(s,v,i); }
 
+#endif
   /***** Extract *****/
+
+#ifdef defined(_ARCH_PWR7) 
+ #define  vextracti(a, b)  (vec_extract((a)), ((b)))
+ #define  vextractf(a, b)  (vec_extract((a)), ((b)))
+ #define  vextractlf(a, b)  (vec_extract((a)), ((b)))
+#else
   /* TODO | FIXME - Try to make these functions not reference memory so values stay in registers */
   inline    int  vextracti( veci v, const int i) {    int* vPtr = (   int*)(&v); return vPtr[i]; }
   inline  float  vextractf( vecf v, const int i) {  float* vPtr = ( float*)(&v); return vPtr[i]; }
-  inline double vextractlf(veclf v, const int i) { double* vPtr = (double*)(&v); return vPtr[i]; }
 
+  inline double vextractlf(veclf v, const int i) { double* vPtr = (double*)(&v); return vPtr[i]; }
+#endif
+  /***** Set *****/
+#ifdef defined(_ARCH_PWR7) 
   /***** Set *****/
-  /* TODO : FIXME - There must be a better way to do this, but it seems the
-   *   only way to convert scalar to vector is to go through memory instructions.
+ #define  vseti(a)  (vec_promote((a)), ((0)))
+ #define  vsetf(a)  (vec_promote((a)), ((0)))
+ #define  vsetlf(a)  (vec_promote((a)), ((0)))
+#else
+  /* TODO : FIXME - There must be a better way to do this, but it
+  seems the only way to convert scalar to vector is to go through
+  memory instructions.  
+
+  EJB: converting between scalar and vector is the sort of thing you
+  want to avoid doing on altivec.  Better to rethink and find a way to
+  stay in the vector engine if at all possible.
+
    */
   inline veci vseti(const   int a) { __veci r; r.v0 = a; return vec_splat(*((veci*)(&r)), 0); }
   inline vecf vsetf(const float a) { __vecf r; r.v0 = a; return vec_splat(*((vecf*)(&r)), 0); }
   #define vsetlf __vsetlf
-
+#endif
   /* NOTE: Declare one for unsigned char vector also (required by rotate functions) */
   inline vector unsigned char vset16uc(const unsigned char c) { vector unsigned char r __attribute__((aligned(16))); ((unsigned char*)(&r))[0] = c; return vec_splat(r, 0); }
 
   /***** Constant Zero *****/
   #define  const_vzeroi  (vec_splat_s32(0))
   #define  const_vzerof  (vec_ctf(vec_splat_s32(0), 0))
+#ifdef defined(_ARCH_PWR7) 
+  #define const_vzerolf  (vec_splats(0))
+#else
   #define const_vzerolf  (__const_vzerolf)
-
+#endif
   /***** Constant One *****/
   #define  const_vonei  (vec_splat_s32(1))
   #define  const_vonef  (vec_ctf(vec_splat_s32(1), 0))
+#ifdef defined(_ARCH_PWR7) 
+  #define const_vonelf  (vec_splats(1))
+#else
   #define const_vonelf  (__const_vonelf)
+#endif
 
   /***** Constant Two *****/
   #define  const_vtwoi  (vec_splat_s32(2))
   #define  const_vtwof  (vec_ctf(vec_splat_s32(2), 0))
+#ifdef defined(_ARCH_PWR7) 
+  #define const_vtwolf  (vec_splats(2))
+#else
   #define const_vtwolf  (__const_vtwolf)
-
+#endif
   /***** Constant Negative One *****/
   #define  const_vnegonei  (vec_splat_s32(-1))
   #define  const_vnegonef  (vec_ctf(vec_splat_s32(-1), 0))
+#ifdef defined(_ARCH_PWR7) 
+  #define const_vnegonelf  (vec_splats(-1))
+#else
   #define const_vnegonelf  (__const_veclf)
-
+#endif
   /***** Rotate *****/
   #define __vrotlbytes(a, s)  (vec_or(vec_slo((a), vset16uc(((s) & 0xf) << 3)), vec_sro((a), set16uc((16 - ((s) & 0xf)) << 3))))
   #define __vrotrbytes(a, s)  (vec_or(vec_sro((a), vset16uc(((s) & 0xf) << 3)), vec_slo((a), set16uc((16 - ((s) & 0xf)) << 3))))
@@ -710,99 +764,177 @@ inline __veci __vcmplelf(const  __vecf a, const  __vecf b) {  __veci r; r.v0 = r
   /***** Addition *****/
   #define  vaddi(a, b)  (vec_add((a), (b)))
   #define  vaddf(a, b)  (vec_add((a), (b)))
+#ifdef defined(_ARCH_PWR7) 
+  #define  vaddlf(a, b)  (vec_add((a), (b)))
+#else
   #define vaddlf __vaddlf
-
+#endif
   /***** Subtraction *****/
   #define  vsubi(a, b)  (vec_sub((a), (b)))
   #define  vsubf(a, b)  (vec_sub((a), (b)))
+#ifdef defined(_ARCH_PWR7) 
+  #define  vsublf(a, b)  (vec_sub((a), (b)))
+#else
   #define vsublf __vsublf
-
+#endif
   /***** Multiplication *****/
-  // NOTE: Try to find a way to do this without double evaluating a
+
+// NOTE: Try to find a way to do this without double evaluating a
+
+#ifdef defined(_ARCH_PWR7) 
+  #define  vmulf(a, b)  (vec_mul((a)), ((b)))
+  #define  vmullf(a, b)  (vec_mul((a)), ((b)))
+#else
   #define  vmulf(a, b)  (vec_madd((a), (b), vec_xor((a), (a))))
   #define vmullf __vmullf
-
+#endif
   /***** Division *****/
+#ifdef defined(_ARCH_PWR7) 
+  #define vdivf(a, b)  (vec_div((a)), ((b)))
+  #define vdivlf(a, b)  (vec_div((a)), ((b)))
+#else
   #define vdivf(a, b)  (vmulf((a), vec_re(b)))
   #define vdivlf __vdivlf
+#endif
 
   /***** Fused Multiply Add *****/
   #define vmaddf(a, b, c)  (vec_madd((a), (b), (c)))
+#ifdef defined(_ARCH_PWR7) 
+  #define vmaddlf(a, b, c)  (vec_madd((a), (b), (c)))
+#else
   #define vmaddlf __vmaddlf
+#endif
 
   /***** Reciprocal *****/
   #define vrecipf(a)  (vec_re(a))
+#ifdef defined(_ARCH_PWR7) 
+  #define vreciplf(a)  (vec_re(a))
+#else
   #define vreciplf __vreciplf
-
+#endif
   /***** Square Root *****/
   #define vsqrtf(a)  (vec_re(vec_rsqrte(a)))
+#ifdef defined(_ARCH_PWR7) 
+  #define vsqrtlf(a)  (vec_sqrte(a)))
+#else
   #define vsqrtlf __vsqrtlf
-
+#endif
   /***** Reciprocal Square Root *****/
   #define vrsqrtf(a)  (vec_rsqrte(a))
+#ifdef defined(_ARCH_PWR7) 
+  #define vrsqrtlf(a)  (vec_rsqrte(a))
+#else
   #define vrsqrtlf __vrsqrtlf
+#endif
 
   /***** Not *****/
+
+
+#ifdef defined(_ARCH_PWR7) 
+  #define vnoti(a)  (vec_neg(a))
+  #define vnotf(a)  (vec_neg(a))
+  #define vnotlf(a)  (vec_neg(a))
+#else
   #define vnoti(a)  (vec_xor((a), const_vnegonei))
   #define vnotf(a)  (vec_xor((a), const_vnegonei))
   #define vnotlf __vnotlf
+#endif
 
   /***** Or *****/
   #define vori(a, b)  (vec_or((a), (b)))
   #define vorf(a, b)  (vec_or((a), (b)))
+#ifdef defined(_ARCH_PWR7) 
+  #define vorlf(a, b)  (vec_or((a), (b)))
+#else
   #define vorlf __vorlf
+#endif
 
   /***** Nor *****/
   #define vnori(a, b)  (vec_nor((a), (b)))
   #define vnorf(a, b)  (vec_nor((a), (b)))
+#ifdef defined(_ARCH_PWR7) 
+  #define vnorlf(a, b)  (vec_nor((a), (b)))
+#else
   #define vnorlf __vnorlf
-
+#endif
   /***** And *****/
   #define vandi(a, b)  (vec_and((a), (b)))
   #define vandf(a, b)  (vec_and((a), (b)))
+#ifdef defined(_ARCH_PWR7) 
+  #define vandlf(a, b)  (vec_and((a), (b)))
+#else
   #define vandlf __vandlf
-
+#endif
   /***** Nand *****/
   #define vnandi(a, b)  (vnoti(vandi((a), (b))))
   #define vnandf(a, b)  (vnotf(vandf((a), (b))))
+#ifdef defined(_ARCH_PWR7) 
+  #define vnandlf(a, b)  (vnotf(vandf((a), (b))))
+#else
   #define vnandlf __vnandlf
-
+#endif
   /***** Xor *****/
   #define vxori(a, b)  (vec_xor((a), (b)))
   #define vxorf(a, b)  (vec_xor((a), (b)))
+#ifdef defined(_ARCH_PWR7) 
+  #define vxorlf(a, b)  (vec_xor((a), (b)))
+#else
   #define vxorlf __vxorlf
+#endif
 
   /***** Nxor *****/
   #define vnxori(a, b)  (vnoti(vxori((a), (b))))
   #define vnxorf(a, b)  (vnotf(vxorf((a), (b))))
+#ifdef defined(_ARCH_PWR7) 
+  #define vnxorlf(a, b)  (vnotlf(vxorf((a), (b))))
+#else
   #define vnxorlf __vnxorlf
-
+#endif
   /***** Equal To *****/
   #define  vcmpeqi(a, b)  ((veci)(vec_cmpeq((a), (b))))
   #define  vcmpeqf(a, b)  ((veci)(vec_cmpeq((a), (b))))
+#ifdef defined(_ARCH_PWR7) 
+  #define  vcmpeqlf(a, b)  ((veci)(vec_cmpeq((a), (b))))
+#else
   #define vcmpeqlf __vcmpeqlf
-
+#endif
   /***** Greater Than *****/
   #define  vcmpgti(a, b)  ((veci)(vec_cmpgt((a), (b))))
   #define  vcmpgtf(a, b)  ((veci)(vec_cmpgt((a), (b))))
+#ifdef defined(_ARCH_PWR7) 
+  #define  vcmpgtlf(a, b)  ((veci)(vec_cmpgt((a), (b))))
+#else
   #define vcmpgtlf __vcmpgtlf
+#endif
 
   /***** Greater Than Or Equal To *****/
   #define  vcmpgei(a, b)  ((veci)(vec_cmpge((a), (b))))
   #define  vcmpgef(a, b)  ((veci)(vec_cmpge((a), (b))))
+#ifdef defined(_ARCH_PWR7) 
+  #define  vcmpgelf(a, b)  ((veci)(vec_cmpge((a), (b))))
+#else
   #define vcmpgelf __vcmpgelf
+#endif
 
   /***** Less Than *****/
   #define  vcmplti(a, b)  ((veci)(vec_cmplt((a), (b))))
   #define  vcmpltf(a, b)  ((veci)(vec_cmplt((a), (b))))
+#ifdef defined(_ARCH_PWR7) 
+  #define  vcmpltlf(a, b)  ((veci)(vec_cmplt((a), (b))))
+#else
   #define vcmpltlf __vcmpltlf
+#endif
 
   /***** Less Than Or Equal To *****/
   #define  vcmplei(a, b)  ((veci)(vec_cmple((a), (b))))
   #define  vcmplef(a, b)  ((veci)(vec_cmple((a), (b))))
+#ifdef defined(_ARCH_PWR7) 
+  #define  vcmplelf(a, b)  ((veci)(vec_cmple((a), (b))))
+// NOTE: vec_cmple not listed in Calin's wiki page of builtins for
+// PWR7, but has a header definition in the compiler
+#else
   #define vcmplelf __vcmplelf
-
-
+#endif
 /*******************************************************************************
  *******************************************************************************
  ***** Mapping to Generic C Implementation
diff --git a/tests/charm++/simplearrayhello-crosscorruption/Makefile b/tests/charm++/simplearrayhello-crosscorruption/Makefile
new file mode 100644 (file)
index 0000000..220a03a
--- /dev/null
@@ -0,0 +1,23 @@
+CHARMC=../../../bin/charmc $(OPTS)
+
+OBJS = hello.o
+
+all: hello
+
+hello: $(OBJS)
+       $(CHARMC) -language charm++ -o hello $(OBJS)
+
+hello.decl.h: hello.ci
+       $(CHARMC)  hello.ci
+
+clean:
+       rm -f *.decl.h *.def.h conv-host *.o hello charmrun *.log *.sum *.sts
+
+hello.o: hello.C hello.decl.h
+       $(CHARMC) -c hello.C
+
+test: all
+       ./charmrun ./hello +p4 10 $(TESTOPTS)
+
+bgtest: all
+       ./charmrun ./hello +p4 10 +x2 +y2 +z2 +cth1 +wth1
diff --git a/tests/charm++/simplearrayhello-crosscorruption/hello.C b/tests/charm++/simplearrayhello-crosscorruption/hello.C
new file mode 100644 (file)
index 0000000..d23264c
--- /dev/null
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include "hello.decl.h"
+
+/*readonly*/ CProxy_Main mainProxy;
+/*readonly*/ int nElements;
+
+class MsgPointer : public CMessage_MsgPointer {
+public:
+  int *ptr;
+  MsgPointer(int *p) : ptr(p) { }
+};
+
+/*mainchare*/
+class Main : public Chare
+{
+public:
+  Main(CkArgMsg* m)
+  {
+    //Process command-line arguments
+    nElements=5;
+    if(m->argc >1 ) nElements=atoi(m->argv[1]);
+    delete m;
+
+    //Start the computation
+    CkPrintf("Running Hello on %d processors for %d elements\n",
+            CkNumPes(),nElements);
+    mainProxy = thishandle;
+
+    CProxy_Hello arr = CProxy_Hello::ckNew(nElements);
+
+    arr[0].SayHi(17);
+  };
+
+  void done(int i)
+  {
+    CkPrintf("All done\n");
+    //CkExit();
+  };
+};
+
+/*array [1D]*/
+class Hello : public CBase_Hello 
+{
+  int myInteger;
+  char pad[200];
+public:
+  Hello()
+  {
+    CkPrintf("Hello %d created\n",thisIndex);
+  }
+
+  Hello(CkMigrateMessage *m) {}
+  
+  void SayHi(int hiNo)
+  {
+    if (hiNo>30) *((int*)NULL) = 0;
+    CkPrintf("Hi[%d] from element %d: %d\n",hiNo,thisIndex,myInteger);
+    if (thisIndex < nElements-1) {
+      //Pass the hello on:
+      CkPrintf("sending pointer %p (%p)\n",&myInteger,this);
+      thisProxy[thisIndex+1].passPointer(new MsgPointer(&myInteger));
+      thisProxy[thisIndex+1].SayHi(hiNo+1);
+    } else 
+      //We've been around once-- we're done.
+      mainProxy.done(1);
+  }
+
+  void passPointer(MsgPointer *msg) {
+    int *ptr = msg->ptr;
+    CkPrintf("receiving pointer %p (%p)\n",ptr,this);
+    // this next line writes into the memory of another chare!
+    *ptr = 10;
+  }
+};
+
+#include "hello.def.h"
diff --git a/tests/charm++/simplearrayhello-crosscorruption/hello.ci b/tests/charm++/simplearrayhello-crosscorruption/hello.ci
new file mode 100644 (file)
index 0000000..10ad216
--- /dev/null
@@ -0,0 +1,17 @@
+mainmodule hello {
+  readonly CProxy_Main mainProxy;
+  readonly int nElements;
+
+  message MsgPointer;
+
+  mainchare Main {
+    entry Main(CkArgMsg *m);
+    entry void done(int);
+  };
+
+  array [1D] Hello {
+    entry Hello(void);
+    entry void SayHi(int hiNo);
+    entry void passPointer(MsgPointer *m);
+  };           
+};
index 95a4951bf770a9516cd2e2009db017e8b9ef5117..1970e4124190718960f595eb66150d9c9e747d00 100644 (file)
@@ -10,6 +10,16 @@ check: check.o
 check.o: check.C
        $(CHARMC) -c check.C
 
+headerpad: headerpad.o
+       $(CHARMC) -language charm++ -o headerpad headerpad.o -tracemode recordreplay
+
+headerpad.decl.h: headerpad.ci
+       $(CHARMC)  headerpad.ci
+
+headerpad.o: headerpad.C headerpad.decl.h headerpad.h
+       $(CHARMC) -c headerpad.C
+
+
 test: check
        ./charmrun +p1 ./check $(TESTOPTS)
        @echo tests if MACHINE_DEBUG is enabled in machine.h and fails if it is set
diff --git a/tests/util/headerpad.C b/tests/util/headerpad.C
new file mode 100644 (file)
index 0000000..7fed691
--- /dev/null
@@ -0,0 +1,52 @@
+#include <stdio.h>
+
+
+#include "headerpad.h"
+/*readonly*/ CProxy_main mainProxy;
+main::main(CkArgMsg *m) {
+    delete m;
+    mainProxy=thishandle;
+    CmiPrintf("Info: converse header: %d envelope: %d\n", CmiReservedHeaderSize, sizeof(envelope));
+    // make a message with 1 payload
+    testMsg *msg = new testMsg;
+    // get pointer to envelope header
+    unsigned char *env= (unsigned char*) UsrToEnv(msg);
+    unsigned char *hdr= (unsigned char*) msg;
+    hdr-=sizeof(envelope);
+    hdr-=CmiReservedHeaderSize;
+    // output converse header field by field
+    
+    // output converse header byte by byte
+    CkPrintf("CmiHeader\n");
+    for(int i=0;i<CmiReservedHeaderSize;i++)
+      CkPrintf("%03u|",hdr[i]);
+    CkPrintf("\n");
+    CkPrintf("Envelope\n");
+    for(int i=0;i<sizeof(envelope);i++)
+      CkPrintf("%03u|",env[i]);
+    CkPrintf("\n");
+    mainProxy.recv(msg);
+  }
+void main::recv(testMsg *msg)
+{
+  CkPrintf("message as received\n");
+    // get pointer to envelope header
+    unsigned char *env= (unsigned char*) UsrToEnv(msg);
+    unsigned char *hdr= (unsigned char*) msg;
+    hdr-=sizeof(envelope);
+    hdr-=CmiReservedHeaderSize;
+    // output converse header field by field
+    
+    // output converse header byte by byte
+    CkPrintf("CmiHeader\n");
+    for(int i=0;i<CmiReservedHeaderSize;i++)
+      CkPrintf("%03u|",hdr[i]);
+    CkPrintf("\n");
+    CkPrintf("Envelope\n");
+    for(int i=0;i<sizeof(envelope);i++)
+      CkPrintf("%03u|",env[i]);
+    CkPrintf("\n");
+    CkExit();
+}
+
+#include "headerpad.def.h"
diff --git a/tests/util/headerpad.ci b/tests/util/headerpad.ci
new file mode 100644 (file)
index 0000000..8d69675
--- /dev/null
@@ -0,0 +1,9 @@
+mainmodule headerpad {
+  readonly CProxy_main mainProxy;
+  message testMsg;        
+
+  mainchare main {
+    entry main(CkArgMsg *m);
+    entry void recv(testMsg *m);
+  };
+};
diff --git a/tests/util/headerpad.h b/tests/util/headerpad.h
new file mode 100644 (file)
index 0000000..6114722
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+** headerpad.h
+** 
+** Made by Eric Bohm
+** Login   <bohm@alacrity>
+** 
+** Started on  Thu Dec  3 14:15:51 2009 Eric Bohm
+** Last update Thu Dec  3 14:15:51 2009 Eric Bohm
+*/
+
+#ifndef        HEADERPAD_H_
+# define       HEADERPAD_H_
+#include "headerpad.decl.h"
+class testMsg : public CMessage_testMsg {
+public:
+  int userdata;
+};
+
+class main : public CBase_main
+{
+public:
+  main(CkMigrateMessage *m) {}
+  main(CkArgMsg *m);
+  void recv(testMsg *m);
+
+};
+
+#endif             /* !HEADERPAD_H_ */