finished converting the old html FAQ page to the new format in LaTeX.
authorFilippo Gioachin <gioachin@illinois.edu>
Tue, 18 Dec 2007 00:51:45 +0000 (00:51 +0000)
committerFilippo Gioachin <gioachin@illinois.edu>
Tue, 18 Dec 2007 00:51:45 +0000 (00:51 +0000)
13 files changed:
doc/faq/Makefile
doc/faq/arrays.tex
doc/faq/charm.tex
doc/faq/converse.tex
doc/faq/debugging.tex
doc/faq/groups.tex
doc/faq/install.tex
doc/faq/internals.tex
doc/faq/manual.tex
doc/faq/messages.tex
doc/faq/other.tex
doc/faq/ports.tex
doc/faq/pup.tex [new file with mode: 0644]

index eea9833b924081cfdecf609b76a88e5b6edb1adc..7b6eae481c4c939df93656eb6092437d65b15e23 100644 (file)
@@ -1,7 +1,7 @@
 # Stub makefile for LaTeX PPL manual
 FILE=manual
-TEX=$(FILE).tex overview.tex general.tex charm.tex arrays.tex groups.tex nodegroups.tex messages.tex \
-       other.tex install.tex debugging.tex ports.tex converse.tex internals.tex
+TEX=$(FILE).tex overview.tex general.tex charm.tex arrays.tex groups.tex messages.tex \
+       other.tex install.tex debugging.tex ports.tex converse.tex internals.tex pup.tex
 DEST=faq
 LATEX2HTML=$(L2H) -split 2
 
index 948e3557a0e4a47e6c89d8444f4b5c0284098e2a..b811aa292ab3d1835be75f212c8975ce31b6370e 100644 (file)
@@ -1,2 +1,123 @@
 \subsection{\charmpp{} Arrays}
 
+\subsubsection{How do I know which processor a chare array element is running on?}
+
+At any given instant, you can call \textrm{CkMyPe()} to find out where
+you are. There is no reliable way to tell where another array element is;
+even if you could find out at some instant, the element might immediately
+migrate somewhere else!
+
+\subsubsection{Should I use Charm++ Arrays in my program?}
+
+Yes! Most of your computation should happen inside array elements.
+Arrays are the main way to automatically balance the load using one of the
+load balancers available.
+
+\subsubsection{How many array elements should I have per processor?}
+
+To do load balancing, you need more than one array element per processor.
+To keep the time and space overheads reasonable, you probably don't want
+more than a few thousand array elements per processor. The optimal
+value depends on the program, but is usually between 10 and 100.
+If you come from an MPI background, this may seem like a lot.
+
+\subsubsection{What does the term reduction refer to?}
+
+You can {\em reduce} a set of data to a single value. For example,
+finding the sum of values, where each array element contributes a value
+to the final sum. Reductions are supported directly by Charm++ arrays, and some
+operations most commonly used are predefined. Other more complicated reductions
+can implement if needed.
+
+\subsubsection{Can I do multiple reductions on an array?}
+
+You {\em can} have several reductions happen one after another; but
+you {\em cannot} mix up the execution of two reductions over the same
+array. That is, if you want to reduce A, then B, every array element has
+to contribute to A, then contribute to B; you cannot have some elements
+contribute to B, then contribute to A.
+
+\subsubsection{Does Charm++ do automatic load balancing without the user asking
+for it?}
+
+No. You only get load balancing if you explicitly ask for it either at link-time
+with the {\em +balancer} option, or at runtime with the {\em -balancer} option.
+
+\subsubsection{What is the migration constructor and why do I need it?}
+
+The migration constructor (a constructor that takes \textrm{CkMigrateMessage *}
+as parameter) is invoked when an array element migrates to a new
+processor. If there is anything you want to do when you migrate, you could put
+it here. However, even if you don't want to do anything, you must create it, as
+it is called from the code automatically generated by the Charm++ translator,
+and constructors aren't inherited, so we can't just put a migration constructor
+in the base class.
+
+The migration constructor should not be declared in the {\em .ci} file. Of
+course the array element will require also at least one regular constructor so
+that it can be created, and these must be declared in the {\em .ci} file.
+
+\subsubsection{What happens to the old copy of an array element after it migrates?}
+
+After sizing and packing a migrating array element, the array manager
+\textrm{delete}s
+the old copy. As long as all the array element destructors in the non-leaf
+nodes of your inheritance hierarchy are {\em virtual destructors}, with
+declaration syntax:
+\begin{alltt}
+class foo : ... \{
+  ...
+  virtual ~foo(); // <- virtual destructor
+\};
+\end{alltt}
+then everything will get deleted properly.\\
+Note that deleting things in a packing pup happens to work for the
+current array manager, but {\em WILL NOT} work for checkpointing, debugging,
+or any of the (many) other uses for packing puppers we might dream up -
+so DON'T DO IT!
+
+\subsubsection{Is it possible to turn migratability on and off for an individual array
+element?}
+
+%<br>No.
+
+
+\subsubsection{Is it possible to insist that a particular array element gets migrated
+at the next {\em AtSync()}?}
+
+%<br>No.
+
+
+\subsubsection{When not using \textrm{AtSync} for LB, when does the LB start
+up? Where is the code that periodically checks if load balancing can be
+done?}
+
+If not using \textrm{usesAtSync}, the load balancer can start up at
+anytime. There is a dummy \textrm{AtSync} for each array element which
+by default tells the load balancer that it is always ready. The LDBD manager
+has a syncer (\textrm{LBDB::batsyncer}) which periodically calls \textrm{AtSync}
+roughly every 1ms to trigger the load balancing (this timeout can be changed
+with the {\em +LBPeriod} option). In this load balancing
+mode, users have to make sure all migratable objects are always ready to
+migrate (e.g. not depending on a global variable which cannot be migrated).
+
+\subsubsection{Should I use AtSync explicitely, or leave it to the system?}
+
+You almost certaintly want to use AtSync directly. In most cases there are
+points in the execution where the memory in use by a chare is bigger due to
+transitory data, which does not need to be transferred if the migration happens
+at predefined points.
+
+%<b>Who calls </b><tt>void staticAtSync(void*)</tt><b>?</b></li>
+
+%<br><tt>staticAtSync</tt> is an internal function for load balancer strategy
+%modules, and is called by the load balancing framework. For each object
+%participating in migration, you register a local barrier like this:
+%<pre>theLbdb->AddLocalBarrierClient(...);</pre>
+%and this registers a callback with the LB framework (this can have any
+%name, not just <tt>staticAtSync</tt>). When you think it is time to migrate,
+%AtSync is called and the local barrier is reached via:
+%<pre>theLbdb->AtLocalBarrier(LdBarrierhandle);</pre>
+%by all local registered clients. Then the <tt>staticAtSync</tt> callbacks
+%will be executed.
+%<br>&nbsp;</ol>
index b169b1d15a922c7c7a12336e4d02c60d618742a4..95903e8c8419d3ca3bf3aa7b8d02ad5d12bee00d 100644 (file)
@@ -51,47 +51,92 @@ keyword before the method in the .ci file. This requires the sender to be a thre
 entry method, as it will be suspended until the callee finishes.
 Sync entry methods are allowed to return values to the caller.
 
+\subsubsection{What is a threaded entry method? How does one make an entry method threaded?}
+
+A threaded entry method is an entry method for a chare that executes
+in a separate user-level thread. It is useful when the entry method wants
+to suspend itself (for example, to wait for more data). Note that
+threaded entry methods have nothing to do with kernel-level threads or
+pthreads; they run in user-level threads that are scheduled by Charm++
+itself.
+
+In order to make an entry method threaded, one should add the keyword
+{\em threaded} withing square brackets after the {\em entry} keyword in the
+interface file:
+\begin{alltt}
+module M \{
+  chare X \{
+    entry [threaded] E1(void);
+  \};
+\};
+\end{alltt}
+
 \subsubsection{If I don't want to use threads, how can an asynchronous method return a value?}
 
-%<br>It can't--at least, not directly. The usual way to get data back to
-%your caller is via another invocation in the opposite direction:
-%<br><tt>void a::start(void) {</tt>
-%<br><tt>&nbsp;&nbsp;&nbsp; b->giveMeSomeData();</tt>
-%<br><tt>}</tt>
-%<br><tt>void b::giveMeSomeData(void) {</tt>
-%<br><tt>&nbsp;&nbsp;&nbsp; a->hereIsTheData(data);</tt>
-%<br><tt>}</tt>
-%<br><tt>void a::hereIsTheData(myclass_t data) {</tt>
-%<br><tt>&nbsp;&nbsp;&nbsp; ...use data somehow...</tt>
-%<br><tt>}</tt>
-%<p>This is contorted, but it exactly matches what the machine has to do.
-%The difficulty of accessing remote data encourages programmers to use local
-%data, bundle outgoing requests, and develop higher-level abstractions,
-%which leads to good performance and good code.
-%<br>&nbsp;
+The usual way to get data back to
+your caller is via another invocation in the opposite direction:
+\begin{alltt}
+void A::start(void) \{
+  b->giveMeSomeData();
+\}
+void B::giveMeSomeData(void) \{
+  a->hereIsTheData(data);
+\}
+void A::hereIsTheData(myclass_t data) \{
+  ...use data somehow...
+\}
+\end{alltt}
+This is contorted, but it exactly matches what the machine has to do.
+The difficulty of accessing remote data encourages programmers to use local
+data, bundle outgoing requests, and develop higher-level abstractions,
+which leads to good performance and good code.
 
 \subsubsection{Isn't there a better way to send data back to whoever called me?}
 
-%<br>The above example is very non-modular, because <tt>b</tt> has to know
-%that <tt>a</tt> called it, and what method to call a back on.&nbsp; For
-%this kind of request/response code, you can abstract away the "where to
-%return the data"&nbsp;with a <tt>CkCallback</tt> object:
-%<br><tt>void a::start(void) {</tt>
-%<br><tt>&nbsp;&nbsp;&nbsp; b->giveMeSomeData(CkCallback(CkIndex_a::hereIsTheData,thisProxy));</tt>
-%<br><tt>}</tt>
-%<br><tt>void b::giveMeSomeData(CkCallback returnDataHere) {</tt>
-%<br><tt>&nbsp;&nbsp;&nbsp; returnDataHere.send(data);</tt>
-%<br><tt>}</tt>
-%<br><tt>void a::hereIsTheData(myclass_t data) {</tt>
-%<br><tt>&nbsp;&nbsp;&nbsp; ...use data somehow...</tt>
-%<br><tt>}</tt>
-%<br>Now<tt> b</tt> can be called from several different places in <tt>a</tt>,
-%or from several different modules.
-%<br><b></b>&nbsp;
+The above example is very non-modular, because {\em b} has to know
+that {\em a} called it, and what method to call a back on. For
+this kind of request/response code, you can abstract away the ``where to
+return the data'' with a {\em CkCallback} object:
+\begin{alltt}
+void A::start(void) \{
+  b->giveMeSomeData(CkCallback(CkIndex_A::hereIsTheData,thisProxy));
+\}
+void B::giveMeSomeData(CkCallback returnDataHere) \{
+  returnDataHere.send(data);
+\}
+void A::hereIsTheData(myclass_t data) \{
+  ...use data somehow...
+\}
+\end{alltt}
+Now {\em b} can be called from several different places in {\em a},
+or from several different modules.
 
 \subsubsection{Why should I prefer the callback way to return data rather than using \textrm{[sync]} entry methods?}
 
+There are a few reasons for that:
+
+\begin{itemize}
+
+\item
+The caller needs to be threaded, which implies some overhead in creating the
+thread. Moreover the threaded entry method will suspend waiting for the data,
+preventing any code after the remote method invocation to proceed in parallel.
+
+\item
+Threaded entry methods are still methods of an object. While they are suspended
+other entry methods for the same object (or even the same threaded entry method)
+can be called. This allows for potential problems if the suspending method does
+leave some objects in an inconsistent state.
+
+\item
+Finally, and probably most important, \textrm{[sync]} entry methods can only be
+used to return a value that can be computed by a single chare. When more
+flexibility is needed, such in cases where the resulting value needs to the
+contribution of multiple objects, the callback methodology is the only one
+available. The caller could for example send a broadcast to a chare array, which
+will use a reduction to collect back the results after they have been computed.
 
+\end{itemize}
 
 \subsubsection{Does Charm++ support C and Fortran?}
 
@@ -103,40 +148,43 @@ Sync entry methods are allowed to return values to the caller.
 
 \subsubsection{What is a proxy?}
 
-%<br>A proxy is a local C++ class that represents a remote C++ class. When
-%you invoke a method on a proxy, it sends the request across the network
-%to the real object it represents.&nbsp; In Charm++, all communication is
-%done using proxies.
-%<p>A proxy class for each of your classes is generated based on the methods
-%you list in the .ci file.
-%<br><b></b>&nbsp;
+A proxy is a local C++ class that represents a remote C++ class. When
+you invoke a method on a proxy, it sends the request across the network
+to the real object it represents. In Charm++, all communication is
+done using proxies.
+
+A proxy class for each of your classes is generated based on the methods
+you list in the .ci file.
 
 \subsubsection{What are the different ways one can can create proxies?}
 
-%<br>Proxies can be:
-%<ul>
-%<li>
-%Created using ckNew. This is the only method that actually creates a new
-%parallel object. "CProxy_A::ckNew(...)" returns a proxy, as described in
-%the <a href="/manuals/html/charm++/">manual</a>.</li>
+Proxies can be:
+\begin{itemize}
+\item
+Created using ckNew. This is the only method that actually creates a new
+parallel object. ``CProxy\_A::ckNew(...)'' returns a proxy, as described in
+the \htmladdnormallink{manual}{http://charm.cs.uiuc.edu/manuals/html/charm++/}.
 
-%<li>
-%Copied from an existing proxy. This happens when you assign two proxies
-%or send a proxy in a message.</li>
+\item
+Copied from an existing proxy. This happens when you assign two proxies
+or send a proxy in a message.
 
-%<li>
-%Created from a "handle".&nbsp; This happens when you say "CProxy_A p=thishandle;"</li>
+\item
+Created from a ``handle''. This happens when you say ``CProxy\_A p=thishandle;''
 
-%<li>
-%Created uninitialized. This is the default when you say "CProxy_A p;".&nbsp;
-%You'll get a runtime error "proxy has not been initialized" if you try
-%to use an uninitialized proxy.</li>
-%</ul>
+\item
+Created uninitialized. This is the default when you say ``CProxy\_A p;''.
+You'll get a runtime error ``proxy has not been initialized'' if you try
+to use an uninitialized proxy.
+\end{itemize}
 
 \subsubsection{What is wrong if I do \textrm{A *ap = new CProxy\_A(handle)}?}
 
-%<br>This will not compile, because a <tt>CProxy_A</tt> is not an <tt>A</tt>.
-%What you want is <tt>CProxy_A *ap = new CProxy_A(handle)</tt>.
+This will not compile, because a {\em CProxy\_A} is not an {\em A}.
+What you want is {\em CProxy\_A *ap = new CProxy\_A(handle)}.
+
+
+
 %<br>&nbsp;
 %<li>
 %<b>When sending messages by invoking a method, can we be just in the middle
@@ -157,138 +205,111 @@ Sync entry methods are allowed to return values to the caller.
 %ChareID). Object B's method gets invoked. It constructs a proxy to A using
 %A's handle from the message, and invokes a method on A using that proxy.
 %<br>&nbsp;
-%<li>
-%<b>Why is the </b><tt>def.h</tt><b> usually included at the end? Is it
-%necessary or can I just include it at the beginning?</b></li>
-
-%<br>You can include the <tt>def.h</tt> file once you've actually declared
-%everything it will reference-- all your chares and readonly variables.
-%If your chares and readonlies are in your own header files, it is legal
-%to include the <tt>def.h</tt> right away.
-%<p>However, if the class declaration for a chare isn't visible when you
-%include the <tt>def.h</tt> file, you'll get a confusing compiler error.
-%This is why we recommend including the <tt>def.h</tt> file at the end.
-%<br>&nbsp;
 
-\subsubsection{How can I use a global variable across different processors?}
+\subsubsection{Why is the {\em def.h} usually included at the end? Is it
+necessary or can I just include it at the beginning?}
 
-%<br>Make the global variable "readonly" by declaring it in the .ci file.
-%<br>&nbsp;
-%<li>
-%<b>Can I have a class static read-only variable?</b></li>
-
-%<br>One can have class-static variables as read-onlies. Inside a chare,
-%group or array declaration in the <tt>.ci</tt> file, one can have a readonly
-%variable declaration. Thus:
-%<pre>chare someChare {
-%&nbsp; ...
-%&nbsp; readonly CkGroupID someGroup;
-%&nbsp; ...
-%};</pre>
-%is fine. In the <tt>.h </tt>declaration for <tt>class someChare</tt> ,
-%you will have have to put <tt>someGroup </tt>as a public static variable,
-%and you are done.
-%<p>You then refer to the variable in your program as <tt>someChare::someGroup</tt>.
-%<br>&nbsp;
-
-\subsubsection{How do I measure the time taken by a program or operation?}
+You can include the {\em def.h} file once you've actually declared
+everything it will reference-- all your chares and readonly variables.
+If your chares and readonlies are in your own header files, it is legal
+to include the {\em def.h} right away.
 
-%<br>You can use CkWallTimer() to determine the time on some particular
-%processor.&nbsp; To time some parallel computation, you need to call CkWallTimer
-%on some processor, do the parallel computation, then call CkWallTimer again
-%on the same processor and subtract.
-%<br>&nbsp;
-
-\subsubsection{What do \textrm{CmiAssert} and
-\textrm{CkAssert} do?}
+However, if the class declaration for a chare isn't visible when you
+include the {\em def.h} file, you'll get a confusing compiler error.
+This is why we recommend including the {\em def.h} file at the end.
 
-%<br>These are just like the standard C++ <tt>assert</tt> calls in <tt>&lt;assert.h></tt>--
-%they call abort if the condition passed to them is false.
-%<p>We use our own version rather than the standard version because we have
-%to call <tt>CkAbort</tt>, and because we can turn our asserts off when
-%<tt>CMK_OPTIMIZE</tt>
-%is defined.
-%<br>&nbsp;
+\subsubsection{How can I use a global variable across different processors?}
 
-\subsubsection{How do I know which processor a chare array element is running on?}
+Make the global variable ``readonly'' by declaring it in the .ci file.
+Remember also that read-onlies can be safely set only in che mainchare
+constructor. Any change after the mainchare constructor has finished will be
+local to the processor that made the change. To change a global variable later
+in the program, every processor must modify it accordingly (e.g by using a chare
+group. Note that chare arrays are not guaranteed to cover all processors)
 
-%<br>At any given instant, you can call <tt>CkMyPe()</tt> to find out where
-%you are. There is no reliable way to tell where another array element is;
-%even if you could find out at some instant, the element might immediately
-%migrate somewhere else!
-%<br>&nbsp;
+\subsubsection{Can I have a class static read-only variable?}
 
-\subsubsection{What is a threaded entry method? How does one make an entry method threaded?}
+One can have class-static variables as read-onlies. Inside a chare,
+group or array declaration in the {\em .ci} file, one can have a readonly
+variable declaration. Thus:
+\begin{alltt}
+chare someChare \{
+  ...
+  readonly CkGroupID someGroup;
+  ...
+\};
+\end{alltt}
+is fine. In the {\em .h} declaration for {\em class someChare},
+you will have have to put {\em someGroup} as a public static variable,
+and you are done.
 
-%<br>A threaded entry method is an entry method for a chare that executes
-%in a separate user-level thread. It is useful when the entry method wants
-%to suspend itself (for example, to wait for more data).&nbsp; Note that
-%threaded entry methods have nothing to do with kernel-level threads or
-%pthreads; they run in user-level threads that are scheduled by Charm++
-%itself.
-%<p>In order to make an entry method threaded, one should add the keyword
-%<tt>threaded</tt>
-%withing square brackets after the <tt>entry</tt> keyword in the interface
-%file:
-%<br><tt>module M {</tt>
-%<br><tt>&nbsp; chare X {</tt>
-%<br><tt>&nbsp;&nbsp;&nbsp; entry [threaded] E1(void);</tt>
-%<br><tt>&nbsp; };</tt>
-%<br><tt>};</tt>
-%<br>&nbsp;
-%<li>
-%<b>I have a situation in which I pass messages from one chare array to
-%another, but I don't know how many messages each element of the destination
-%chare array will receive. How can an element find out that it has all its
-%messages?</b></li>
+You then refer to the variable in your program as {\em someChare::someGroup}.
 
-%<br>There isn't yet a nice library to solve this problem; but you can still:
-%<ul>
-%<li>
-%Send a return receipt message, wait until all the receipts for the messages
-%you sent have arrived, then go to a barrier.</li>
+\subsubsection{How do I measure the time taken by a program or operation?}
 
-%<li>
-%Do all the sends, then wait for quiescence.</li>
-%</ul>
+You can use \textrm{CkWallTimer()} to determine the time on some particular
+processor. To time some parallel computation, you need to call CkWallTimer
+on some processor, do the parallel computation, then call CkWallTimer again
+on the same processor and subtract.
 
-%<li>
-%<b>What is "quiescence"?</b></li>
+\subsubsection{What do \textrm{CmiAssert} and
+\textrm{CkAssert} do?}
 
-%<br>When nothing is happening anywhere on the parallel machine.
-%<br>&nbsp;
-%<li>
-%<b>How does Charm++ detect quiescence?</b></li>
+These are just like the standard C++ {\em assert} calls in {\em <assert.h>}--
+they call abort if the condition passed to them is false.
+
+We use our own version rather than the standard version because we have
+to call {\em CkAbort}, and because we can turn our asserts off when
+{\em CMK\_OPTIMIZE} is defined.
+
+\subsubsection{Can I know how many messages are being sent to a chare?}
+
+No.
+
+There is no nice library to solve this problem, as some messages might be queued
+on the receiving processor, some on the sender, and some on the network. You can
+still:
+\begin{itemize}
+\item Send a return receipt message to the sender, and wait until all the
+receipts for the messages sent have arrived, then go to a barrier;
+\item Do all the sends, then wait for quiescence.
+\end{itemize}
+
+\subsubsection{What is "quiescence"? How does it work?}
+
+Quiescence is When nothing is happening anywhere on the parallel machine.
+
+A low-level background task counts sent and received messages.
+When, across the machine, all the messages that have been sent have been
+received, and nothing is being processed, quiescence is triggered.
+
+\subsubsection{Should I use quiescence detection?}
+
+Probably not.
+
+In some ways, quiescence is a very strong property (it guarentees {\em nothing}
+is happening {\em anywhere}) so if some other library is doing something,
+you won't reach quiescence. In other ways, quiescence is a very weak property,
+since it doesn't guarentee anything about the state of your application
+like a reduction does, only that nothing is happening. Because quiescence
+detection is on the one hand so strong it breaks modularity, and on the
+other hand is too weak to guarentee anything useful, it's often better
+to use something else.
+
+Often global properties can be replaced by much easier-to-compute local
+properties. For example, my object could wait until all {\em its} neighbors
+have sent it messages (a local property my object can easily detect by
+counting message arrivals), rather than waiting until {\em all} neighbor
+messages across the whole machine have been sent (a global property that's
+difficult to determine). Sometimes a simple reduction is needed instead
+of quiescence, which has the benefits of being activated explicitly (each
+element of a chare array or chare group has to call contribute) and allows
+some data to be collected
+at the same time. A reduction is also a few times faster than quiescence
+detection. Finally, there are a few situations, such as some tree-search
+problems, where quiescence detection is actually the most sensible, efficient
+solution.
 
-%<br>It uses a low-level background task that counts sent and received messages.&nbsp;
-%When, across the machine, all the messages that have been sent have been
-%received, and nothing is being processed, you've reached quiescence.
-%<br>&nbsp;
-%<li>
-%<b>Should I use quiescence detection?</b></li>
-
-%<br>Probably not.
-%<p>In some ways, quiescence is a very strong property--it guarentees <u>nothing</u>
-%is happening <u>anywhere</u>--so if some other library is doing something,
-%you won't reach quiescence. In other ways, quiescence is a very weak property,
-%since it doesn't guarentee anything about the state of your application
-%like a reduction does, only that nothing is happening. Because quiescence
-%detection is on the one hand so strong it breaks modularity, and on the
-%other hand is too weak to guarentee anything useful, it's often better
-%to use something else.
-%<p>Often global properties can be replaced by much easier-to-compute local
-%properties--for example, my object could wait until all <u>its</u> neighbors
-%have sent it messages (a local property my object can easily detect by
-%counting message arrivals), rather than waiting until <u>all</u> neighbor
-%messages across the whole machine have been sent (a global property that's
-%difficult to determine). Sometimes a simple reduction is needed instead
-%of quiescence, which has the benefits of being activated explicitly (each
-%array element has to call contribute) and allows some data to be collected
-%at the same time. A reduction is also a few times faster than quiescence
-%detection.&nbsp; Finally, there are a few situations, such as some tree-search
-%problems, where quiescence detection is actually the most sensible, efficient
-%solution.
-%<br>&nbsp;
 %<li>
 %<b>Can a chare be deleted by using </b><tt>delete this</tt><b>?</b></li>
 
@@ -300,17 +321,6 @@ Sync entry methods are allowed to return values to the caller.
 %this;</tt>.
 %<br>&nbsp;
 %<li>
-%<b>When I compile the </b><tt>.ci</tt><b> file I get the message:
-%</b><tt>failed
-%assertion `isConstructor()'</tt><b>. What does this mean?</b></li>
-
-%<br>This problem has already been fixed in the latest version of Charm++.
-%Make sure your copy of Charm++ is the latest. (An old version of Charm++
-%would give this error when you declared a non-constructor entry method
-%in
-%<tt>.ci</tt> file without any parameter.)
-%<br>&nbsp;
-%<li>
 %<b>Is there any way to put inheritance in a
 %</b><tt>.ci</tt><b> file?</b></li>
 
index 5eeb47b4712f61993a8dcc4263dd7f84ee021ed2..c761d47c7bdd7daabe2e06fb9afb710e3bd9ee80 100644 (file)
@@ -1,2 +1,25 @@
 \section{\converse{} Programming}
 
+\subsubsection{What is Converse? Should I use it?}
+
+\htmladdnormallink{Converse}{http://charm.cs.uiuc.edu/research/converse/}
+is the low-level portable messaging layer that Charm++ is built on, but
+you don't have to know anything about Converse to use Charm++. You might
+want to learn about Converse if you want a capable, portable foundation
+to implement a new parallel language on.
+
+\subsubsection{How much does getting a random number generator ``right'' matter?}
+
+drand48 is nonportable and woefully inadequate for any real simulation
+task. Even if each processor seeds drand48 differently, there is no guarantee
+that the streams of pseduo-random numbers won't quickly overlap. A better
+generator would be required to ``do it right'' (See Park \& Miller, CACM
+Oct. 88).
+
+\subsubsection{What should I use to get a proper random number generator?}
+
+Converse provides a 64-bit pseudorandom number generator based on the
+SPRNG package originally written by Ashok Shrinivasan at NCSA. For detailed
+documentation, please take a look at the Converse Extensions Manual on
+the Charm++ website. In short, you can use {\em CrnDrand()} function
+instead of the unportable {\em drand48()} in Charm++.
index 23b1e085d70db63998ecc5c2f6102d02b1bc9e18..1b7717484b3d2502beec062d5990c79388aa828e 100644 (file)
@@ -1,2 +1,208 @@
 \section{Debugging}
 
+\subsubsection{How can I debug Charm++ programs?}
+
+There are many ways to debug programs written in Charm++:
+
+\begin{description}
+
+\item[print] By using \textrm{CkPrintf}, values from critical point in the program can be
+printed.
+
+\item[gdb] This can be used both on a single processor, and in parallel
+simulations. In the latter, each processor has a terminal window with a gdb
+connected.
+
+\item[charmdebug] This is the most sofisticated method to debug parallel
+programs in Charm++. It is tailored to Charm++ and it can display and inspect
+chare objects as well as messages in the system. Single {\em gdb}s can be
+attached to specific processors on demand.
+
+\end{description}
+
+\subsubsection{How do I use charmdebug?}
+
+Currently charmdebug is tested to work only under net- versions. With other versions,
+testing is pending. The executable is present in \textrm{java/bin/charmdebug} of
+the Charm++ distribution. To start, simply substitute ``charmdebug'' to
+``charmrun'':
+\begin{alltt}shell> <path>/charmdebug ./myprogram\end{alltt}
+
+\subsubsection{Can I use TotalView?}
+
+Yes, on mpi- versions of Charm++. In this case, the program is a regular MPI
+application, and as such any tool available for MPI programs can be used. Notice
+that some of the internal data structures (like messages in queue) might be
+difficult to find.
+
+\subsubsection{How do I use {\em gdb} with Charm++ programs?}
+
+It depends on the machine. On the net- versions of Charm++, like net-linux,
+you can just run the serial debugger:
+\begin{alltt}shell> gdb myprogram\end{alltt}
+
+If the problem only shows up in parallel, and you're running on an X
+terminal, you can use the {\em ++debug} or {\em ++debug-no-pause} options of charmrun
+to get a separate window for each process:
+\begin{alltt}
+shell> export DISPLAY="myterminal:0"
+shell> ./charmrun ./myprogram +p2 ++debug
+\end{alltt}
+
+%On the SGI Origin2000, you can again run with ++debug, but this only
+%prints out the process ID of each processor and waits 10 seconds. In another
+%window, you have to manually attach a debugger to the running process,
+%like this:
+%<br><tt>&nbsp; > ./charmrun ./myprogram +p2 ++debug</tt>
+%<br><tt>Running on 2 processors:&nbsp; ./myprogram ++debug</tt>
+%<br><tt>CHARMDEBUG> Processor 0 has PID 34554234</tt>
+%<br><tt>CHARMDEBUG> Processor 1 has PID 35086430</tt>
+%<br><tt>...</tt>
+%<br><tt>&nbsp; > dbx -p 34554234</tt>
+
+\subsubsection{When I try to use the {\em ++debug} option I get: \textrm{remote
+host not responding... connection closed}}
+
+First, make sure the program at least starts to run properly without {\em ++debug}
+(i.e. charmrun is working and there are no problems with the program startup
+phase). You need to make sure that gdb or dbx, and xterm are installed
+on all the machines you are using (not the one that is running \textrm{charmrun}).
+If you are working on remote machines from Linux, you need to run ``xhost +''
+locally to give the remote machines permission to display an xterm on
+your desktop. If you are working from a Windows machine, you need an X-win
+application such as exceed. You need to set this up to give the right permissions
+for X windows. You need to make sure the DISPLAY environment variable on
+the remote machine is set correctly to your local machine. I recommend
+ssh and putty, because it will take care of the DISPLAY environment automatically,
+and you can set up ssh to use tunnels so that it even works from a private
+subnet(e.g. 192.168.0.8). Since the xterm is displayed from the node machines,
+you have to make sure they have the correct DISPLAY set. Again, setting
+up ssh in the nodelist file to spawn node programs should take care of
+that. If you are using rsh, you need to set DISPLAY in {\em ~/.charmrunrc}
+which will be read at start up time by each node program.
+
+%<li>
+%<b>I've been having some trouble using </b><tt>charmrun</tt><b> with the
+%</b><tt>++debug</tt><b>
+%option. I have XWinPro running and use ttssh to do X forwarding. I can
+%get xemacs to pop up, but when I try to
+%</b><tt>charmrun pgm ++debug</tt><b>,
+%I receive the following error messages from ttssh:
+%</b><tt>Remote X application
+%sent incorrect authentication data. Its X session is being cancelled.</tt></li>
+
+%<br>X forwarding generally doesn't work with charmrun, because X forwarding
+%assumes all the programs you want to see are running on the machine you're
+%logged in to.&nbsp; Charmrun starts your program on the nodes of the parallel
+%machine, which generally confuses X forwarding.&nbsp; So forget about forwarding
+%and just set the DISPLAY directly.
+%<br>&nbsp;
+%<li>
+%<b>How else can I debug my Charm++ programs?</b></li>
+
+%<br>The usual methods still work in parallel--diagnostic printouts, selective
+%code removal, working up from tiny input sizes, etc.
+
+
+\subsubsection{My debugging printouts seem to be out of order. How can I prevent this?}
+
+Printouts from different processors do not normally stay ordered. Consider
+the code:
+\begin{alltt}
+...somewhere... \{
+  CkPrintf("cause\textbackslash{}n");
+  proxy.effect();
+\}
+void effect(void) \{
+  CkPrintf("effect\textbackslash{}n");
+\}
+\end{alltt}
+
+Though you might expect this code to always print ``cause, effect'', you
+may get ``effect, cause''. This can only happen when the cause and
+effect execute on different processors, so cause's output is delayed.
+
+If you pass the extra command-line parameter {\em +syncprint}, then CkPrintf
+actually blocks until the output is queued, so your printouts should at
+least happen in causal order. Note that this does dramatically slow down
+output.
+
+\subsubsection{Is there a way to flush the print buffers in Charm++ (like
+\textrm{fflush()})?}
+
+Charm++ automatically flushes the print buffers every newline and at
+program exit. There is no way to manually flush the buffers at another
+point.
+
+\subsubsection{My Charm++ program is causing a seg fault, and the debugger shows that
+it's crashing inside {\em malloc} or {\em printf} or {\em fopen}!}
+
+This isn't a bug in the C library, it's a bug in your program -- you're
+corrupting the heap. Link your program again with {\em -memory paranoid} and
+run it again in the debugger. {\em -memory paranoid} will check the heap and
+detect buffer over- and under-run errors, double-deletes, delete-garbage,
+and other common mistakes that trash the heap.
+
+\subsubsection{Everything works fine on one processor, but when I run on
+multiple processors it crashes!}
+
+It's very convenient to do your testing on one processor (i.e., with
+{\em +p1}); but there are several things that only happen on multiple processors.
+
+A single processor has just one set of global variables, but multiple
+processors have different global variables. This means on one processor,
+you can set a global variable and it stays set ``everywhere'' (i.e., right
+here!), while on two processors the global variable never gets initialized
+on the other processor. If you must use globals, either set them on every
+processor or make them into {\em readonly} globals.
+
+A single processor has just one address space, so you actually {\em can}
+pass pointers around between chares. When running on multiple processors,
+the pointers dangle. This can cause incredibly weird behavior -- reading
+from uninitialized data, corrupting the heap, etc. The solution is to never,
+ever send pointers in messages -- you need to send the data the pointer points
+to, not the pointer.
+
+\subsubsection{I get the error: ``\textrm{Group ID is zero-{}- invalid!}''. What does
+this mean?}
+
+The {\em group} it is refering to is the chare group. This
+error is often due to using an uninitialized proxy or handle; but it's
+possible this indicates severe corruption. Run with {\em ++debug} and check
+it you just sent a message via an uninitialized proxy.
+
+\subsubsection{I get the error: \textrm{Null-Method Called. Program may have Unregistered
+Module!!} What does this mean?}
+
+You are trying to use code from a module that has not been properly
+initialized.
+
+So, in the {\em .ci} file for your {\em mainmodule}, you should
+add an ``extern module'' declaration:
+\begin{alltt}
+mainmodule whatever \{
+  extern module someModule;
+  ...
+\}
+\end{alltt}
+
+\subsubsection{When I run my program, it gives this error:}
+
+\begin{alltt}
+Charmrun: error on request socket-{}-
+Socket closed before recv.
+\end{alltt}
+
+This means that the node program died without informing \textrm{charmrun}
+about it, which typically means a segmentation fault while in the interrupt
+handler or other critical communications code. This indicates severe
+corruption in Charm++'s data structures, which is likely the result of
+a heap corruption bug in your program. Re-linking with {\em -memory paranoid}
+may clarify the true problem.
+
+\subsubsection{When I run my program, sometimes I get a \textrm{Hangup}, and
+sometimes \textrm{Bus Error}. What do these messages indicate?}
+
+\textrm{Bus Error} and \textrm{Hangup} both are indications that your
+program is terminating abnormally, i.e. with an uncaught signal (SEGV or
+SIGBUS). You should definitely run the program with gdb, or use {\em ++debug}.
index 84b7523d1615e18bb5c4a1b47ac16d36c88ab65a..236c6bb290bc6cf53ead3797be6c9fa15f1bf4e2 100644 (file)
@@ -1,2 +1,85 @@
-\subsection{\charmpp{} Groups}
+\subsection{\charmpp{} Groups and Nodegroups}
 
+\subsubsection{What are groups and nodegroups used for?}
+
+They are used for optimizations at the processor and node level respectively.
+
+\subsubsection{Should I use groups?}
+
+Probably not. People with an MPI background often overuse groups, which
+results in MPI-like Charm++ programs. Arrays should generally be used
+instead, because arrays can be migrated to acheive load balance.
+
+Groups tend to be most useful in constructing communication optimization
+libraries. For example, all the array elements on a processor can
+contribute something to their local group, which can then send a combined
+message to another processor. This can be much more efficient than
+having each array element send a separate message.
+
+\subsubsection{Is it safe to use a local pointer to a group, such as from ckLocalBranch?}
+
+Yes. Groups never migrate, so a local pointer is safe. The only caveat
+is to make sure {\em you} don't migrate without updating the pointer.
+
+A local pointer can be used for very efficient access to data held by
+a group.
+
+%<li>
+%<b>If a Group is constructed from </b><tt>main::main</tt><b>, the constructor
+%gets called immediately on PE 0. Therefore, a Group constructor may create
+%another Group, and get a valid group ID back. Correct?</b></li>
+
+%<br>Yes. Groups may create other groups in their constructor.</ol>
+
+
+\subsubsection{What are migratable groups?}
+
+Migratable groups are declared so by adding the ``[migratable]'' attribute in
+the .ci file. They {\em cannot} migrate from one processor to another during
+normal execution, but only to disk for checkpointing purposes.
+
+Migratable groups must declare a migration constructor (taking
+\textrm{CkMigrateMessage *} as a parameter) and a pup routine. The migration
+construtor {\em must} call the superclass migration constructor as in this
+example:
+\begin{alltt}
+class MyGroup : public CBase\_MyGroup \{
+  ...
+  MyGroup (CkMigrateMessage *msg) : CBase\_MyGroup(msg) \{ \}
+  ...
+\}
+\end{alltt}
+
+\subsubsection{Should I use nodegroups?}
+
+Almost certainly not. You should use arrays for most computation, and
+even quite low-level communication optimizations are often best handled
+by groups. Nodegroups are very difficult to get right.
+
+\subsubsection{What's the difference between groups and nodegroups?}
+
+There's one group element per processor (CkNumPes() elements); and
+one nodegroup element per node (CkNumNodes() elements). Because they
+execute on a node, nodegroups have very different semantics from the rest
+of Charm++.
+
+Note that on a non-SMP machine, groups and nodegroups are identical.
+
+
+\subsubsection{Do nodegroup entry methods execute on one fixed processor of the node,
+or on the next available processor?}
+
+Entries in node groups execute on the next available processor. Thus,
+if two messages were sent to a branch of a nodegroup, two processors could
+execute one each simultaneously.
+
+\subsubsection{Are nodegroups single-threaded?}
+
+No. They {\em can} be accessed by multiple threads at once.
+
+\subsubsection{Do we have to worry about two entry methods in an object executing simultaneously?}
+
+Yes, which makes nodegroups different from everything else in Charm++.
+
+If a nodegroup method accesses a data structure in a non-threadsafe
+way (such as writing to it), you need to lock it, for example using a CmiNodeLock.
index eb3d21b3c48fb8576ace916e0f5a8eaf39dd207b..907f83ae05ef15f42a7e594ccd727f0503eda926 100644 (file)
@@ -1,2 +1,312 @@
 \section{Installation and Usage}
 
+\subsubsection{How do I get Charm++?}
+
+See our \htmladdnormallink{download}{http://charm.cs.uiuc.edu/download/} page.
+
+\subsubsection{Should I use the CVS version of Charm++?}
+
+The developers of Charm++ routinely use the latest CVS versions, and most of the
+time this is the best case. Occasionally something breaks, but the CVS version
+will likely contain bug fixes not found in the releases.
+
+\subsubsection{How do I compile Charm++?}
+
+Run the interactive build script \textrm{./build} with no extra arguments If this fails,
+email \htmladdnormallink{ppl@cs.uiuc.edu}{mailto:ppl@cs.uiuc.edu} with the
+problem. Include the build line used (this is saved automatically in
+\textrm{smart-build.log})
+
+If you have a very unusual machine configuration, you will have to run
+\textrm{./build\ --help} to list all possible build options. You will then choose the closest
+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
+in the distribution.
+
+\subsubsection{How do I compile AMPI?}
+
+Run the interactive build script \textrm{./build} and choose the option for building
+``Charm++, AMPI, ParFUM, FEM and other libraries''.
+
+\subsubsection{Can I remove part of charm tree after compilation to free disk space?}
+
+
+\subsubsection{If the interactive script fails, how do I compile Charm++?}
+
+%<p>First, on a typical Linux machine, unpack the tarball, cd into "charm",
+%and type <tt>./build AMPI net-linux -g</tt>.
+
+%<p>Next, if your machine is similar to one of the machines below, 
+%use the listed "build" command:
+%<table border="1">
+%<tr><th>Computer</th><th>Type</th><th>Charm Build</th>
+
+%<tr>
+%      <td>UIUC CSE <a href="http://www.cse.uiuc.edu/turing/">Turing</a> Cluster</td>
+%      <td>Myrinet Linux Cluster. <br>
+%              640 2GHz G5 processors as 2-way nodes.</td>
+%      <td>
+%              Debug: ./build AMPI net-ppc-darwin -g<br>
+%              Production: ./build AMPI net-ppc-darwin gm -O3<br>
+%              To run a job, use "rjc" to find nodes, then "charmrun".
+%      </td>
+%</tr>
+%<tr>
+%      <td>PSC <a href="http://www.psc.edu/machines/tcs/lemieux.html">Lemieux</a></td>
+%      <td>HP/Compaq AlphaServer. <br> 
+%              3,000 64-bit Alpha processors as 750 4-way SMP nodes. 3TB total RAM.
+%      </td>
+%      <td>
+%              Use: ./build AMPI elan-axp cxx -O<br>
+%              To run a short job, use "charmrun".
+%              To run a long job, prepare a batch script and use "qsub".
+%      </td>
+%</tr>
+%<tr>
+%      <td>NCSA <a href="http://www.ncsa.uiuc.edu/UserInfo/Resources/Hardware/IBMp690/">Copper</a></td>
+%      <td>IBM SP (pSeries 690). <br> 
+%              Use up to 32 1.3GHz 64-bit IBM Power4 processors as a single SMP node.
+%      </td>
+%      <td>
+%              32-bit Mode: ./build AMPI mpi-sp -O<br>
+%              64-bit Mode: ./build AMPI mpi-sp mpcc64 -O<br>
+%              To run an interactive job, use "charmrun".
+%              To run a long job, write a batch script and use "llsubmit".
+%      </td>
+%</tr>
+%<tr>
+%      <td>NCSA <a href="http://www.ncsa.uiuc.edu/UserInfo/Resources/Hardware/XeonCluster/">Tungsten</a></td>
+%      <td>Myrinet Linux Cluster. <br>
+%              2,560 3.2 GHz Intel Xeon processors as 2-way nodes with Myrinet, 3 GB RAM per node.
+%      </td>
+%      <td>
+%              Use: ./build AMPI net-linux gm -O , or<br>
+%                   ./build AMPI net-linux gm icc ifort -O (Intel compilers) , or<br>
+%                   ./build AMPI mpi-linux cmpi -O (Champion MPI)<br>
+%      </td>
+%</tr>
+%<tr>
+%      <td>NCSA <a href="http://www.ncsa.uiuc.edu/UserInfo/Resources/Hardware/TGIA64LinuxCluster/">Mercury</a></td>
+%      <td>Myrinet Linux Cluster. <br>
+%              1,744 1.3/1.5 GHz Intel Itanium-2 processors as 2-way nodes with Myrinet, 4 GB RAM per node.
+%      </td>
+%      <td>
+%              Use: ./build AMPI net-linux-ia64 gm -O , or<br>
+%                   ./build AMPI mpi-linux-ia64 gm -nobs -O (MPICH over GM)<br>
+%      </td>
+%</tr>
+%<tr>
+%      <td>NCSA <a href="http://www.ncsa.uiuc.edu/UserInfo/Resources/Hardware/SGIAltix/">Cobalt</a></td>
+%      <td>SGI Altix 3700 <br>
+%              1,024 1.6 GHz Intel Itanium-2 processors as two 512-processor shared memory systems, 1,024 GB RAM in one system and 2,048 GB RAM in the other
+%      </td>
+%      <td>
+%              Use: ./build AMPI mpi-linux-ia64 ifort mpt icc -O <br>
+%      </td>
+%</tr>
+%<tr>
+%      <td>NCSA <a href="http://www.ncsa.uiuc.edu/UserInfo/Resources/Hardware/IA32LinuxCluster/">Platinum</a></td>
+%      <td>Myrinet Linux Cluster with VMI. <br>
+%              968 1 GHz 32-bit Intel Pentium III processors as 2-way nodes with Myrinet.
+%      </td>
+%      <td>
+%              Debug: ./build AMPI net-linux gm icc -O<br>
+%              Production: ./build AMPI mpi-linux vmi icc -O<br>
+%              To run an interactive job with net version, use "charmrun". To run with mpi version, use vmirun. Checkout NCSA's webpage for how to write a job script.<br>
+%      </td>
+%</tr>
+%<tr>
+%      <td>NCSA <a href="http://www.ncsa.uiuc.edu/UserInfo/Resources/Hardware/IA32LinuxCluster/">Titanium</a></td>
+%      <td>Myrinet Itanium Linux Cluster. <br>
+%              256 800 MHz 64-bit Intel Itanium processors as 2-way nodes with Myrinet.
+%      </td>
+%      <td>
+%              Use: ./build AMPI net-linux-ia64 gm ecc -O , or<br>
+%                   ./build AMPI mpi-linux-ia64 vmi ecc -O<br>
+%              To run an interactive job with net version, use "charmrun". To run with mpi version, use vmirun.<br>
+%      </td>
+%</tr>
+%<tr>
+%      <td><a href=http://www.hpcx.ac.uk/">HPCx</td>
+%      <td>IBM eServer 575 LPARs with HPC Federation interconnect. <br>
+%              96 1.5 GHz 64-bit Power5</td>
+%      <td>Use: ./build AMPI lapi -O3 -qstrict
+%              "charmrun" will allocate jobs to the load leveler. A prototype file is needed for the accounting</td>
+%</tr>
+%<tr>
+%      <td>Architecture Cluster</a></td>
+%      <td>Fast Ethernet Linux Cluster. <br>
+%              140 1.7 GHz 32-bit Athlon MP 2000 processors as 2-way nodes.
+%      </td>
+%      <td>
+%              Debug: ./build AMPI net-linux -g<br>
+%              Production: ./build AMPI net-linux -O<br>
+%              To run interactive use "frun", "fsub" for batch submission.<br> 
+%      </td>
+%</tr>
+
+%</table>
+
+%<br>
+%For a computer not in the list above, you can decide which build options to use based
+%on the following rules of thumb.
+%<ul>
+%<li>The compiler defaults to gcc or mpicc on most platforms.  
+%If you'd like to use another compiler, you can usually add an 
+%option like "icc", "pgcc", "xlc", "xlc64", or many others--
+%see the README file or charm/src/arch/common for a complete list.
+%For platform specific options, one can run build command with "help" option, for example: <br>
+%./build charm++ net-linux help
+
+%<li>Under Linux, if you or your communication layer uses pthreads,
+%and you use Charm threads (such as AMPI), and your Glibc is less than
+%version 3.2, you'll get a horrible crash unless you add the "smp" option.
+%This version links in a special version of pthreads that works with
+%our user-level threads.
+
+%<li>On the net- version, if you're having trouble with rsh/ssh or just
+%want to spawn processes on your own machine, add the "local" option, 
+%like <tt>./build AMPI net-linux local -g</tt>
+
+%<li>Run "./build --help" to display detailed help page for supported build options
+
+%</ul>
+
+%See the README file for extensive details.
+%<br>
+%<br>
+
+%<li>
+%<b>How do I set up my linux box for parallel runs?</b>
+%or <b>What does "rsh> protocol failure in circuit setup" mean?</b>
+%</li>
+
+%<br>Charmrun normally uses rsh to start the individual programs in a parallel
+%run. If you can't execute "rsh localhost echo Hello", you need to set up rsh.
+
+%<p>Rsh is normally started by the inetd service.  For pre-RedHat 7 Linux systems,
+%you ask inetd to start rsh by adding, as root, this line to /etc/inetd.conf:
+%<pre>
+%shell stream  tcp     nowait.1000     root    /usr/sbin/tcpd  in.rshd
+%</pre>
+%You'll then need to restart inetd using "/etc/rc.d/init.d/inetd restart".
+
+%<p>On a modern Linux system you probably don't have an /etc/inetd.conf file,
+%because your system uses xinetd.  With xinetd, you enable rsh by adding,
+%as root, a file called "rsh" to the directory /etc/xinetd.d/ containing:
+%<pre>
+%# default: on
+%# description: The rshd server is the server for the rcmd(3) routine and, \
+%#     consequently, for the rsh(1) program.  The server provides \
+%#     remote execution facilities with authentication based on \
+%#     privileged port numbers from trusted hosts.
+%service shell
+%{
+%      socket_type             = stream
+%      wait                    = no
+%      user                    = root
+%      only_from               = 127.0.0.1 ...your subnet address here.../24
+%      cps                     = 1000 30
+%      log_on_success          += USERID
+%      log_on_failure          += USERID
+%      server                  = /usr/sbin/in.rshd
+%}
+%</pre>
+
+%Afer adding this file, you'll need to restart xinetd using "/etc/rc.d/init.d/xinetd restart".
+
+%<p>Finally, no matter what kind of inetd you have, you probably also want a
+%/etc/hosts.equiv file.  This file contains a list of hosts you want to be able to
+%rsh from without using a password.  Since Charm never uses passwords with rsh,
+%you want to add all the machines you'll be starting Charm jobs from.
+%For example, if I start jobs on this machine from localhost and foo.bar.edu,
+%my /etc/hosts.equiv file would contain:
+%<pre>
+%localhost
+%foo.bar.edu
+%</pre>
+
+\subsubsection{How do I specify the processors I want to use?}
+
+For the net versions, you need to write a nodelist file which lists
+all the machine hostnames available for parallel runs.
+\begin{alltt}
+group main
+  host foo1
+  host foo2 ++cpus 4
+  host foo3.bar.edu
+\end{alltt}
+
+%<p>For the net SCYLD version, you don't need nodelist file,
+%<tt>charmrun
+%+p n</tt> will automatically find the first n available nodes.
+
+For the MPI version, you need to set up an MPI configuration for available
+machines as for normal MPI applications.
+
+\subsubsection{How do I use {\em ssh} instead of the deprecated {\em rsh}?}
+
+You need to set up your \textrm{.ssh/authorized\_keys} file
+correctly. Setup no-password logins using ssh by putting the correct host
+key (ssh-keygen) in the file \textrm{.ssh/authorized\_keys}.
+
+Finally, in the \textrm{.nodelist} file,
+you specify the shell to use for remote execution of a program using
+the keyword {\em ++shell}.
+\begin{alltt}
+group main ++shell ssh
+  host foo1
+  host foo2
+  host foo3
+\end{alltt}
+
+\subsubsection{Can I use the serial library X from a Charm program?}
+
+Yes.  Some of the known working serial libraries include:
+\begin{itemize}
+\item The Tcl/Tk interpreter (in NAMD)
+\item The Python interpreter (in Cosmo prototype)
+\item OpenGL graphics (in graphics demos)
+\item Metis mesh partitioning (included with charm)
+\end{itemize}
+
+\subsubsection{How do I get the command-line switches available for a specific
+program?}
+
+Try \begin{alltt}./charmrun ./pgm --help\end{alltt} to see a list of parameters
+at the command line. The charmrun arguments are documented in the
+\htmladdnormallink{Installation and Usage Manual}{http://charm.cs.uiuc.edu/manuals/html/install/manual.html}
+the arguments for the installed libraries are listed in the library manuals.
+
+%<b>Could you tell me how to run speedshop?</b></li>
+
+%<br><b>speedshop</b> is the performance analysis tool on Origin2000. In
+%order to use it, one need not specify any special compilation or linking
+%options. It can also be used for parallel programs. Here is what to do
+%to use speedshop.
+%<p>Suppose the name of the executable is <tt>pgm</tt>, and it is an MPI
+%program (or a Charm++ program on mpi-origin version). You run:
+%<pre>mpirun -np 4 ssrun -ideal pgm &lt;pgm-options></pre>
+%<tt>ssrun</tt> is the command that instruments the executable (original
+%executable is not modified), and runs it. The
+%<tt>-ideal</tt> option specifies
+%what data needs to be collected. It is called <b>experiment</b> in speedshop
+%terminology.
+%<p>This will produce a few files called
+%<tt>pgm.ideal.*</tt>. To be precise,
+%when <tt>-np</tt> is 4, it will produce 5 files: one of them is
+%<tt>pgm.ideal.m*</tt>,
+%and the rest are
+%<tt>pgm.ideal.f*</tt>. * is the PID of each process. the
+%m* file corresponds to the master program of MPI (and also the lazy thread),
+%so it does not contain any user data. The user processes generate <tt>pgm.ideal.f*</tt>
+%files.
+%<p>Now run prof on it: <tt>prof [-gprof] pgm.ideal.f*</tt>
+%<p>This will print the profiling statistics to stdout. The
+%<tt>-gprof</tt>
+%option asks prof to generate gprof style output.
+%<p>There are various interesting experiements one can run with speedshop.
+%See speedshop(1) for more details.
+%<br>&nbsp;</ol>
index db636f7c4241f8bf5185e3c5384a78cecdefbffd..2cb1294a625d53dfddcd21c08da42d389e443b49 100644 (file)
@@ -1,2 +1,54 @@
 \section{\charmpp{} and \converse{} Internals}
 
+\subsubsection{How is the Charm++ source code organized and built?}
+
+All the Charm++ core source code is soft-linked into the
+\textrm{charm/<archname>/tmp}
+directory when you run the build script. The libraries and frameworks are
+under \textrm{charm/<archname>/tmp/libs}, in either \textrm{ck-libs} or
+\textrm{conv-libs}.
+
+\subsubsection{I just changed the Charm++ core. How do I recompile Charm++?}
+
+cd into the \textrm{charm/<archname>/tmp} directory and make. If you want to
+compile only a subset of the entire set of libraries, you can specify it to
+make. For example, to compile only the Charm++ RTS, type {\em make charm++}.
+
+\subsubsection{Do we have a {\em \#define charm\_version} somewhere? If not,
+which version number should I use for the current version?}
+
+%<br>Yes, there is a Charm++ version number defined in macro<tt>CHARM_VERSION</tt>.
+%This is defined in <tt>charm/src/Common/script/charmconfig</tt>, which
+%is an autoconf script generated by
+%<tt>charm/src/Common/script/configure.in</tt>.
+%At compile time, the <tt>charmconfig</tt> will created a header file
+%<tt>conv-autoconfig.h</tt>
+%based on system settings and compiler testings. <tt>conv-autoconfig.h</tt>
+%includes the
+%<tt>CHARM_VERSION</tt> macro, and this file is included in
+%<tt>converse.h/charm++.h</tt>.
+
+%<li>
+%<b>How do you use </b><tt>UsrToEnv</tt><b>? The compiler complains
+%</b><tt>implicit
+%declaration of function</tt><b>. If I include </b><tt>envelope.h</tt><b>
+%it gives several weird errors.</b></li>
+
+%<br>To use <tt>UsrToEnv</tt>, include
+%<tt>envelope.h</tt>.
+%<tt>envelope.h</tt>
+%is to be used for C++ programs only. And since it uses Converse functions,
+%one needs to include
+%<tt>converse.h</tt> before
+%<tt>envelope.h</tt> as
+%well.
+
+%<li>
+%<b>How can one determine if two messages are identical or not? We get the
+%size of the message and compare from start to end. The problem is that
+%one particular field is expected to be different and envelopes may be different.
+%So we want to compare the messages excluding the envelope and some particular
+%fields of the message.</b></li>
+
+%<br>You can use EnvToUsr(env) to get the message pointer after the envelope,
+%then use memcmp on the parts of the message you want to match.</ol>
index 15acbf530bfa20a6ce78a63e3ced4a46837db9be..9ade097a9f5763e1e9fecd33adbdc0ed84d8b896 100644 (file)
 For answers to questions not on this list, please contact us at \htmladdnormallink{ppl@cs.uiuc.edu}{mailto:ppl@cs.uiuc.edu}
 
 \input{overview}
+\input{install}
 \input{charm}
-  \input{general}
   \input{arrays}
   \input{groups}
-  \input{nodegroups}
   \input{messages}
+  \input{pup}
 \input{other}
-\input{install}
 \input{debugging}
 \input{ports}
 \input{converse}
index 3ce55056d183ceb1195ad33712cf85e1c92842e7..5188c675fe16719b3a17ff24ad9187875193004d 100644 (file)
@@ -1,2 +1,91 @@
 \subsection{\charmpp{} Messages}
 
+\subsubsection{What are messages?}
+
+A bundle of data sent, via a proxy, to another chare. A message is
+a special kind of heap-allocated C++ object.
+
+\subsubsection{Should I use messages?}
+
+It depends on the application. We've found parameter marshalling to be less
+confusing and error-prone than messages for small parameters. Nevertheless,
+messages can be more efficient, especially if you need to buffer incoming data,
+or send complicated data structures (like a portion of a tree).
+
+\subsubsection{What is the best way to pass pointers in a message?}
+
+You can't pass pointers across processors. This is a basic fact of
+life on distributed-memory machines.
+
+You can, of course, pass a copy of an object referenced via a pointer
+across processors--either dereference the pointer before sending, or use
+a varsize message.
+
+\subsubsection{Can I allocate a message on the stack?}
+
+No. You must allocate messages with {\em new}.
+
+\subsubsection{Do I need to delete messages that are sent to me?}
+
+Yes, or you will leak memory! If you receive a message, you are responsible
+for deleting it. This is exactly opposite of parameter marshalling,
+and much common practice. The only exception are entry methods declared as
+[nokeep]; for these the system will free the message automatically at the end of
+the method.
+
+\subsubsection{Do I need to delete messages that I allocate and send?}
+
+No, this will certainly corrupt both the message and the heap! Once
+you've sent a message, it's not yours any more. This is again exactly the
+opposite of parameter marshalling.
+
+\subsubsection{What can a variable-length message contain?}
+
+Variable-length messages can contain arrays of any type, both primitive type or
+any user-defined type. The only restriction is that they have to be 1D arrays.
+
+\subsubsection{Do I need to delete the arrays in variable-length messages?}
+
+No, this will certainly corrupt the heap! These arrays are allocated in a single
+contiguous buffer together with the message itself, and is deleted when the
+message is deleted.
+
+\subsubsection{What are priorities?}
+
+Priorities are special values that can be associated with messages, so that the
+Charm++ scheduler will prefer higher priority messages when choosing a message
+to deliver. Priorities are respected by Charm++ as much as possible: until there
+are higher priority messages in the queue, lower priority message will never be
+delivered. Nevertheless, this is not a guarantee, and a lower priority message
+can be delivered before a higher priority one.
+
+Messages with priorities are typically used to perform optimizations on the
+order of the computation.
+
+For integer priorities, the smaller the priority value, the higher the priority
+of the message. Negative value are therefore higher priority than positive ones. 
+To enable and set a message's priority there is a special {\em new} syntax and
+{\em CkPriorityPtr} function; see the manual for details. If no priority is set,
+messages have a default priority of zero.
+
+\subsubsection{Can messages have multiple inheritance in Charm++?}
+
+%<br>Messages can't be inherited at all-- they don't even have *single*
+%inheritance. This is a silly limitation; but the fact that messages need
+%to be transmitted as flat byte streams puts strong limits on what we can
+%do with them.
+
+\subsubsection{What is the difference between \textrm{new} and \textrm{alloc}?}
+
+%My understanding is that </b><tt>new</tt><b>
+%calls </b><tt>alloc</tt><b>, but what else is
+%</b><tt>new</tt><b> doing?
+%I.e. why do both exist?</b></li>
+
+%<br><tt>new</tt> is an operator for the class, and
+%<tt>alloc</tt> is a
+%static method. <tt>alloc</tt> basically calls <tt>CkAlloc</tt> after calculating
+%the sizes and the priority bits etc. <tt>new</tt> is just a wrapper around
+%<tt>alloc</tt>.
+%You should always call <tt>new</tt>.
+
index 9c9cc406bcf285ed512fb68da7c02b2b234db1ed..320780578c8948505d57b1c6d894d77576057c5d 100644 (file)
@@ -1,2 +1,43 @@
 \section{Other PPL Tools, Libraries and Applications}
 
+\subsubsection{What is Structured Dagger?}
+
+{\em Structured Dagger} is a structured notation for specifying intra-process
+control dependencies in message-driven programs. It combines the efficiency
+of message-driven execution with the explicitness of control specification.
+Structured Dagger allows easy expression of dependencies among messages
+and computations and also among computations within the same object using
+\textrm{when-blocks}
+and various structured constructs. See the Charm++ manual for the details.
+
+\subsubsection{What are the performance problems with AMPI packing and unpacking?}
+
+There is an extra copy involved, because the AMPI message is reusable
+immediately after the AMPI call returns. Since Charm++ messages are to
+be handed over to the system, there is an extra copy involved (plus creation
+of a Charm++ message) while sending.
+
+%<li>
+%<b>Why does AMPI now derive from </b><tt>ArrayElement1D</tt><b> rather
+%than </b><tt>TempoArray</tt><b>?</b></li>
+
+%<br>Deriving it from <tt>TempoArray</tt> was causing some inefficiencies
+%because of the introduction of derived data types. Basically, it was causing
+%multiple copies. Also, I felt that some more optimizations, especially
+%with collective operations can be done this way, so I have changed AMPI
+%to be a standalone Charm++ library, rather than being dependent on Tempo.
+
+\subsubsection{Is \textrm{TempoArray::ckTempoSendElem()} the only way for non-AMPI
+code to communicate with running AMPI code?}
+
+%<br>A static method <tt>sendraw</tt> is added to the AMPI class, that allows
+%you to send a message to AMPI threads from outside AMPI. So, instead of
+%using the <tt>TempoArray</tt> method, you can use:
+%<tt>ampi::sendraw(tag1,tag2,msg,len,arrayid,index);</tt>
+
+\subsubsection{What is Charisma?}
+
+
+\subsubsection{Does Projections use wall time or CPU time?}
+
+Wall time.
index 2c20608d641b9b02cda23a89d4f0accf71e320cc..bf5bd2ab7659d1865b8f3c43e1a34d6f8449d851 100644 (file)
@@ -1,2 +1,352 @@
 \section{Versions and Ports}
 
+\subsubsection{Is Charm++/Converse etc. available on CD or as an RPM?}
+
+No, and there are no plans.
+
+\subsubsection{Has charm been ported to use MPI underneath? What about OpenMP?}
+
+Charm++ supports MPI and uses it as communication library. We
+have tested on MPICH and LAM, and also some other MPI variants for example
+MPI-GM, MPI/VMI. Charm++ also has explicit support for SMP nodes in MPI
+version. Charm++ hasn't been ported to use OpenMP.
+
+\subsubsection{How complicated is porting Charm++/Converse?}
+
+Depends. Hopefully, the porting only involves fixing compiler compatibility
+issues. But porting to new platforms with specific communication libraries
+usually involve porting Converse threads and writing Converse communication
+layers. Charm++, which is on top of Converse, should be free of architecture
+dependent porting issues.
+
+\subsubsection{If the source is available how feasible would it be for us to do ports
+ourselves?}
+
+The source is always available, and you're welcome to make it run anywhere.
+Any kind of UNIX, Windows, and MacOS machine should be straightforward: just a
+few modifications to \textrm{charm/src/arch/.../conv-mach.h} (for compiler
+issues) and possibly
+a new {\em machine.c} (if there's a new communication system involved).
+However, porting to a Lisp machine or VAX would be fairly difficult.
+
+\subsubsection{To what platform has Charm++/Converse been ported to?}
+
+Charm++/Converse has been ported to most UNIX and Linux OS, Windows, and MacOS.
+
+\subsubsection{Is it hard to port Charm++ programs to different machines?}
+
+\label{porting}
+Charm++ itself it fully portable, and should provide exactly 
+the same interfaces everywhere (even if the implementations are 
+sometimes different).  Still, it's often harder than we'd like
+to port user code to new machines.
+
+Many parallel machines have old or weird compilers, and 
+sometimes a strange operating system or unique set of libraries.  
+Hence porting code to a parallel machine can be suprisingly difficult.
+
+Unless you're absolutely sure you will only run your code on a
+single, known machine, we recommend you be very conservative in 
+your use of the language and libraries.  ``But it works with my gcc!''
+is often true, but not very useful.
+
+Things that seem to work well everywhere include:
+\begin{itemize}
+\item Small, straightforward Makefiles.  gmake-specific (e.g.,
+``ifeq'', filter variables) or convoluted makefiles can lead 
+to porting problems and confusion.  Calling charmc instead
+of the platform-specific compiler will save you many headaches,
+as charmc abstracts away the platform specific flags.
+\item Basically all of ANSI C and fortran 77 work everywhere.  These seem 
+to be old enough to now have the bugs largely worked out.
+%Thankfully, K\&R (no-prototype) C compilers have now died out.
+\item C++ classes, inheritance, virtual methods, and namespaces
+work without problems everywhere.  Not so uniformly supported 
+are C++ templates, the STL, new-style C++ system headers, 
+and the other features listed in the C++ question below.
+\end{itemize}
+
+\subsubsection{Which C language features cause porting problems?}
+
+Our suggestions for Charm++ developers are:
+
+\begin{itemize}
+\item Avoid the nonstandard type ``long long'', even though many compilers
+happen to support it.  Use CMK\_INT8 or CMK\_UINT8,
+from conv-config.h, which are macros for the right thing.
+``long long'' is not supported on many 64-bit machines (where ``long''
+is 64 bits) or on Windows machines (where it's ``\_\_int64'').
+\item The ``long double'' type isn't present on all compilers.  You can protect
+long double code with {\em \#ifdef CMK\_LONG\_DOUBLE\_DEFINED} if it's really needed.
+\item Never use C++ ``//'' comments in C code, or headers included by C.
+This will not compile under many compilers, including the IBM SP C compiler.
+\item ``bzero'' and ``bcopy'' are BSD-specific calls.  
+Use memset and memcpy for portable programs.
+\end{itemize}
+
+\subsubsection{Which C++ language features cause porting problems?}
+
+Our suggestions for Charm++ developers are:
+
+\begin{itemize}
+
+\item Never declare the same loop index inside two adjacent loops.
+The C++ standard recently changed to make this legal:
+\begin{alltt}
+for (int i=...) ...
+for (int i=...) ...
+\end{alltt}
+However, many compilers choke on the above, complaining of 
+``duplicate declaration of int i''.  Instead, use:
+\begin{alltt}
+int i;
+for (i=...) ...
+for (i=...) ...
+\end{alltt}
+
+\item Be wary of the C++ STL (Standard Template Library).
+Many compilers (such as Alpha cxx) do not accept the new-style 
+ANSI header names without ".h", like <iostream>. The
+preprocessor symbol {\em CMK\_STL\_USE\_DOT\_H} will be set if the 
+compiler demands <iostream.g>.
+Other compilers, such as older versions of g++, are missing 
+only certain ANSI headers, such as <limits>.
+Sometimes a compiler will appear to have perfectly good
+ANSI headers, but none of the members are declared in the ``std''
+namespace.
+
+\item Be wary of C++ exception handling when mixing with C code. 
+Many compilers, including gcc on Linux, sensibly choose not 
+to allow C++ exceptions to propagate through C code.  Hence
+a C++ exception becomes std::unexpected when unwinding hits
+the first C routine.
+
+\item Templates should be declared ``inline'' to avoid linking problems.
+Non-``inline'' templates have to be ``instantiated'',
+a process which works differently on different compilers.
+For example, non-inline templates work automatically under gcc;
+but when used inside a library under Sun CC 7, fail to link
+unless explicitly instantiated. So use this:
+\begin{alltt}
+template <class T>
+inline void foo() {...}
+\end{alltt}
+not this, which may (someday) cause a link error saying ``can't find
+foo<bar>'':
+\begin{alltt}
+template <class T>
+void foo() {...}
+\end{alltt}
+
+\item Templated class members should be declared right in the class. 
+This avoids the ugly syntax of outside template members, and 
+makes them implicitly ``inline'', which avoids linking problems.
+In addition, declaring in the class works around a bug where
+templated members of a templated class cannot be defined outside the 
+class under MS Visual C++ 6.0.
+
+\item Templated functions work best when the template types can 
+be deduced from the function parameters.  We've had problems with
+Sun CC failing to instantiate an explicitly-named, non-inline
+function template used for a function pointer.
+
+So use this:
+\begin{alltt}
+template <class T>
+inline void foo(T t) {...}
+\end{alltt}
+not this, which may (someday) cause a compile error saying 
+``"can't determine template type'':
+\begin{alltt}
+template <class T>
+inline void foo(void *t) {...}
+\end{alltt}
+
+\item ``Fancy'' uses of templates can fail, often in spectacularly
+bizarre ways.  For example, partial template specialization can 
+lead to compiler crashes; and ``int'' parameters are not always 
+supported in function templates. 
+
+\end{itemize}
+
+Luckily, C++ support, especially STL support, is improving
+rapidly.  Hopefully soon several of the above features will
+become widely supported enough to use everywhere.
+
+\subsubsection{Why do I get a link error when mixing Fortran and C/C++?}
+
+\label{f2c}
+
+Fortran compilers ``mangle'' their routine names in a variety
+of ways.  g77 and most compilers make names all lowercase, and 
+append an underscore, like ``foo\_''.  The IBM xlf compiler makes 
+names all lowercase without an underscore, like ``foo''. Absoft f90 
+makes names all uppercase, like ``FOO''. 
+
+If the Fortran compiler expects a routine to be named ``foo\_'',
+but you only define a C routine named ``foo'', you'll get a link 
+error (``undefined symbol foo\_'').  Sometimes the UNIX command-line
+tool {\em nm} (list symbols in a .o or .a file) can help you see exactly what the 
+Fortran compiler is asking for, compared to what you're providing.
+
+Charm++ automatically detects the fortran name mangling scheme
+at configure time, and provides a C/C++ macro ``FTN\_NAME'', in ``charm-api.h'',
+that expands to a properly mangled fortran routine name.
+You pass the FTN\_NAME macro
+two copies of the routine name: once in all uppercase, and again 
+in all lowercase.
+The FTN\_NAME macro then picks the appropriate name and applies any
+needed underscores.  ``charm-api.h'' also includes a macro ``FDECL''
+that makes the symbol linkable from fortran (in C++, this expands
+to extern ``C''), so a complete Fortran subroutine looks like in C or C++:
+\begin{alltt}
+FDECL void FTN\_NAME(FOO,foo)(void);
+\end{alltt}
+
+This same syntax can be used for C/C++ routines called from
+fortran, or for calling fortran routines from C/C++.
+We strongly recommend using FTN\_NAME instead of hardcoding your
+favorite compiler's name mangling into the C routines.
+
+If designing an API with the same routine names in C and 
+Fortran, be sure to include both upper and lowercase letters
+in your routine names.  This way, the C name (with mixed case)
+will be different from all possible Fortran manglings (which
+all have uniform case).  For example, a routine named ``foo''
+will have the same name in C and Fortran when using the IBM
+xlf compilers, which is bad because the C and Fortran versions
+should take different parameters.  A routine named ``Foo'' does
+not suffer from this problem, because the C version is ``Foo,
+while the Fortran version is ``foo\_'', ``foo'', or ``FOO''.
+
+\subsubsection{How does parameter passing work between Fortran and C?}
+
+Fortran and C have rather different parameter-passing 
+conventions, but it is possible to pass simple objects 
+back and forth between Fortran and C:
+
+\begin{itemize}
+
+\item Fortran and C/C++ data types are generally completely
+interchangeable:
+
+\begin{tabular}{|l|l|}
+\hline
+\textbf{C/C++ Type} & \textbf{Fortran Type} \\
+\hline
+int & INTEGER, LOGICAL \\
+double & DOUBLE PRECISION, REAL*8 \\
+float & REAL, REAL*4 \\
+char & CHARACTER \\
+\hline
+\end{tabular}
+
+\item Fortran internally passes everything, including 
+constants, integers, and doubles, by passing a pointer
+to the object.  Hence a fortran ``INTEGER'' argument becomes 
+an ``int *'' in C/C++:
+\begin{alltt}
+/* Fortran */
+SUBROUTINE BAR(i) 
+    INTEGER :: i
+    x=i
+END SUBROUTINE
+
+/* C/C++ */
+FDECL void FTN\_NAME(BAR,bar)(int *i) \{
+    x=*i;
+\}
+\end{alltt}
+
+\item 1D arrays are passed exactly the same in Fortran and C/C++:
+both languages pass the array by passing the address of the 
+first element of the array.
+Hence a fortran ``INTEGER, DIMENSION(:)'' array is an ``int *''
+in C or C++.  However, Fortran programmers normally think of 
+their array indices as starting from index 1, while in C/C++ 
+arrays always start from index 0.  This does NOT change how 
+arrays are passed in, so x is actually the same in both 
+these subroutines:
+\begin{alltt}
+/* Fortran */
+SUBROUTINE BAR(arr) 
+    INTEGER :: arr(3)
+    x=arr(1)
+END SUBROUTINE
+
+/* C/C++ */
+FDECL void FTN\_NAME(BAR,bar)(int *arr) \{
+    x=arr[0];
+\}
+\end{alltt}
+
+\item There is a subtle but important difference between the way
+f77 and f90 pass array arguments.  f90 will pass an array object
+(which is not intelligible from C/C++) instead of a simple pointer 
+if all of the following are true:
+\begin{itemize}
+\item A f90 ``INTERFACE'' statement is available on the call side.
+\item The subroutine is declared as taking an unspecified-length
+       array (e.g., ``myArr(:)'') or POINTER variable.
+\end{itemize}
+Because these f90 array objects can't be used from C/C++, we recommend 
+C/C++ routines either provide no f90 INTERFACE or else all the arrays 
+in the INTERFACE are given explicit lengths.
+
+\item Multidimensional allocatable arrays are stored with
+the smallest index first in Fortran.  C/C++ do not support
+allocatable multidimensional arrays, so they must fake them
+using arrays of pointers or index arithmetic.
+
+\begin{alltt}
+/* Fortran */
+SUBROUTINE BAR2(arr,len1,len2) 
+    INTEGER :: arr(len1,len2)
+    INTEGER :: i,j
+    DO j=1,len2
+      DO i=1,len1
+        arr(i,j)=i;
+      END DO
+    END DO
+END SUBROUTINE
+
+/* C/C++ */
+FDECL void FTN\_NAME(BAR2,bar2)(int *arr,int *len1p,int *len2p) \{
+    int i,j; int len1=*len1p, len2=*len2p;
+    for (j=0;j<len2;j++)
+    for (i=0;i<len1;i++)
+        arr[i+j*len1]=i;
+\}
+\end{alltt}
+
+\item Fortran strings are passed in a very strange fashion.
+A string argument is passed as a character pointer and a 
+length, but the length field, unlike all other Fortran arguments,
+is passed by value, and goes after all other arguments.
+Hence 
+
+\begin{alltt}
+/* Fortran */
+SUBROUTINE CALL\_BARS(arg) 
+    INTEGER :: arg
+    CALL BARS('some string',arg);
+END SUBROUTINE
+
+/* C/C++ */
+FDECL void FTN\_NAME(BARS,bars)(char *str,int *arg,int strlen) \{
+    char *s=(char *)malloc(strlen+1);
+    memcpy(s,str,strlen);
+    s[strlen]=0; /* nul-terminate string */
+    printf("Received Fortran string '\%s' (\%d characters){\textbackslash}n",s,strlen);
+    free(s);
+\}
+\end{alltt}
+
+
+\item A f90 named TYPE can sometimes successfully be passed into a 
+C/C++ struct, but this can fail if the compilers insert different
+amounts of padding.  There does not seem to be a portable way to 
+pass f90 POINTER variables into C/C++, since different compilers
+represent POINTER variables differently.  
+
+\end{itemize}
diff --git a/doc/faq/pup.tex b/doc/faq/pup.tex
new file mode 100644 (file)
index 0000000..b755107
--- /dev/null
@@ -0,0 +1,98 @@
+\subsection{PUP Framework}
+
+\subsubsection{How does one write a pup for a dynamically allocated 2-dimensional array?}
+
+The usual way: pup the size(s), allocate the array if unpacking, and
+then pup all the elements.
+
+For example, if you have a 2D grid like this:
+\begin{alltt}
+class foo \{
+ private:
+  int wid,ht;
+  double **grid;
+  ...other data members
+
+  //Utility allocation/deallocation routines
+  void allocateGrid(void) \{
+    grid=new double*[ht];
+    for (int y=0;y<ht;y++)
+      grid[y]=new double[wid];
+  \}
+  void freeGrid(void) \{
+    for (int y=0;y<ht;y++)
+      delete[] grid[y];
+    delete[] grid;
+    grid=NULL;
+  \}
+
+ public:
+  //Regular constructor
+  foo() \{
+    ...set wid, ht...
+    allocateGrid();
+  \}
+  //Migration constructor
+  foo(CkMigrateMessage *) \{\}
+  //Destructor
+  \~foo() \{
+    freeGrid();
+  \}
+
+  //pup method
+  virtual void pup(PUP::er \&p) \{
+    p(wid); p(ht);
+    if (p.isUnpacking()) \{
+      //Now that we know wid and ht, allocate grid
+      allocateGrid(wid,ht);
+    \}
+    //Pup grid values element-by-element
+    for (int y=0;y<ht;y++)
+      for (int x=0; x<wid; x++)
+        p|grid[y][x];
+    ...pup other data members...
+  \}
+\};
+\end{alltt}
+
+\subsubsection{When using automatic allocation via PUP::able, what do these calls mean?
+\textrm{PUPable\_def(parent); PUPable\_def(child);}}
+
+For the automatic allocation described in {\em Automatic allocation via
+\textrm{PUP::able}} of the manual, each class needs four things:
+\begin{itemize}
+\item A migration constructor
+
+\item
+\textrm{PUPable\_decl(className)} in the class declaration in the {\em .h}
+file
+
+\item
+\textrm{PUPable\_def(className)} at file scope in the {\em .C} file
+
+\item
+\textrm{PUPable\_reg(className)} called exactly once on every node. You
+typically use the {\em initproc} mechanism to call these.
+\end{itemize}
+See \textrm{charm/tests/charm++/megatest/marshall.[hC]} for an executable
+example.
+
+\subsubsection{What is the difference between \textrm{p|data;} and
+\textrm{p(data);}? Which one should I use?}
+
+For most system- and user-defined structure {\em someHandle}, you want
+\textrm{p|someHandle;} instead of \textrm{p(someHandle);}
+
+The reason for the two incompatible syntax varieties is that the bar
+operator can be overloaded {\em outside} \textrm{pup.h} (just like the
+\textrm{std::ostream}'s \textrm{operator{<}<});
+while the parenthesis operator can take multiple arguments (which is needed
+for efficiently PUPing arrays).
+
+The bar syntax will be able to copy {\em any} structure, whether it
+has a pup method or not. If there is no pup method, the C++ operator overloading
+rules decay the bar operator into packing the {\em bytes} of the structure,
+which will work fine for simple types on homogenous machines. For dynamically
+allocated structures or heterogeneous migration, you'll need to define
+a pup method for all packed classes/structures. As an added benefit, the
+same pup methods will get called during parameter marshalling.