Docs: Review mblock 13/4913/2
authorEvan Ramos <evan@hpccharm.com>
Tue, 22 Jan 2019 00:03:12 +0000 (18:03 -0600)
committerEvan Ramos <evan@hpccharm.com>
Tue, 22 Jan 2019 18:58:13 +0000 (12:58 -0600)
Change-Id: I557c4f0e9897f8bc1f6e11ab3f0a751d12f7017d

doc/mblock/manual.rst

index e8d27f4..e0e43b0 100644 (file)
@@ -14,8 +14,8 @@ grid is often made rectangular, when it is called a *block*. These
 blocks may face one another or various parts of the outside world, and
 taken together comprise a *multiblock computation*.
 
-There are two main types of multiblock computations- implicit and
-explicit. In an implicit computation a global matrix, which represents
+There are two main types of multiblock computations -- implicit and
+explicit. In an implicit computation, a global matrix, which represents
 the entire problem domain, is formed and solved. Implicit computations
 require a fast sparse matrix solver, and are typically used for
 steady-state problems. In an explicit computation, the solution proceeds
@@ -51,7 +51,7 @@ For example, Figure :numref:`fig:terminology` shows a 3D 4x8x7-voxel
 block, with a face and 6x3 patch indicated.
 
 The computational domain is tiled with such blocks, which are required
-to be conformal- the voxels must match exactly. The blocks need not be
+to be conformal -- the voxels must match exactly. The blocks need not be
 the same size or orientation, however, as illustrated in the 2D domain
 of Figure :numref:`fig:decompose`.
 
@@ -80,7 +80,7 @@ ghost cells is illustrated in Figure :numref:`fig:indexing`.
 
    The ghost cells around a 5x3-voxel 2D block
 
-The Multiblock framework manages all the boundary conditions- both
+The Multiblock framework manages all the boundary conditions -- both
 internal and external. Internal boundary conditions are sent across
 processors, and require you to register the data “fields” you wish
 exchanged. External boundary conditions are not communicated, but
@@ -108,19 +108,19 @@ These block files are generated with a separate, offline tool called
 Structure of a Multiblock Framework Program
 ===========================================
 
-A Multiblock framework program consists of several subroutines: init,
-driver,finalize, and external boundary condition subroutines.
+A Multiblock framework program consists of several subroutines: ``init``,
+``driver``, ``finalize``, and external boundary condition subroutines.
 
-init and finalize are called by the Multiblock framework only on the
-first processor - these routines typically do specialized I/O, startup
+``init`` and ``finalize`` are called by the Multiblock framework only on the
+first processor -- these routines typically do specialized I/O, startup
 and shutdown tasks.
 
-A separate driver subroutine runs for each block, and does the main work
+A separate driver subroutine runs for each block, doing the main work
 of the program. Because there may be several blocks per processor,
-several driver routines may be executing as threads simultaneously.
+several driver routines may execute as threads simultaneously.
 
 The boundary condition subroutines are called by the framework after a
-request from driver.
+request from the driver.
 
 .. code-block:: none
 
@@ -155,13 +155,13 @@ Compilation and Execution
 
 A Multiblock framework program is a Charm++ program, so you must begin
 by downloading the latest source version of Charm++ from
-``http://charm.cs.uiuc.edu/``. Build the source with
+https://charm.cs.illinois.edu. Build the source with
 ``./build MBLOCK version`` or ``cd`` into the build directory,
-``version/tmp``, and type ``make MBLOCK``. To compile a MULTIBLOCK
+``<version>/tmp``, and type ``make MBLOCK``. To compile a MULTIBLOCK
 program, pass the ``-language mblock`` (for C) or ``-language mblockf``
 (for Fortran) option to ``charmc``.
 
-In a charm installation, see charm/version/pgms/charm++/mblock/ for
+In a charm installation, see ``charm/<version>/pgms/charm++/mblock/`` for
 example and test programs.
 
 Preparing Input Files
@@ -170,13 +170,13 @@ Preparing Input Files
 The Multiblock framework reads its description of the problem domain
 from input "block" files, which are in a Multiblock-specific format. The
 files are named with the pattern prefixnumber.ext, where prefix is a
-arbitrary string prefix you choose; number is the number of this block
-(virtual processor); and ext is either “mblk”, which contains binary
+arbitrary string prefix you choose, number is the number of this block
+(virtual processor), and ext is either “mblk”, which contains binary
 data with the block coordinates, or “bblk”, which contains ASCII data
 with the block’s boundary conditions.
 
 You generate these Multiblock input files using a tool called
-makemblock, which can be found in charm/version/pgms/charm++/makemblock.
+*makemblock*, which can be found in ``charm/<version>/pgms/charm++/makemblock``.
 makemblock can read a description of the problem domain generated by the
 structured meshing program Gridgen (from Pointwise) in .grd and .inp
 format; or read a binary .msh format. makemblock divides this input
@@ -237,7 +237,7 @@ if the input block files are named “gridX00001.mblk” and
 
 This call is made to set the number of partitioned blocks to be used.
 Each block is read from an input file and a separate driver is spawned
-for each. The number of blocks determines the available parallelism;
+for each. The number of blocks determines the available parallelism,
 so be sure to have at least as many blocks as processors. We recommend
 using several times more blocks than processors, to ease load
 balancing and allow adaptive overlap of computation and communication.
@@ -361,7 +361,7 @@ the current block.
   character*, intent(in) :: str
 
 Print the given string, prepended by the block id if called from the
-driver. Works on all machines; unlike printf or print \*, which may
+driver. Works on all machines, unlike ``printf`` or ``print *``, which may
 not work on all parallel machines.
 
 Internal Boundary Conditions and Block Fields
@@ -369,8 +369,8 @@ Internal Boundary Conditions and Block Fields
 
 The Multiblock framework handles the exchange of boundary values between
 neighboring blocks. The basic mechanism to do this exchange is the
-*field*- numeric data items associated with each cell of a block. These
-items must be arranged in a regular 3D grid; but otherwise we make no
+*field* -- numeric data items associated with each cell of a block. These
+items must be arranged in a regular 3D grid, but otherwise we make no
 assumptions about the meaning of a field.
 
 You create a field once, with MBLK_Create_Field, then pass the resulting
@@ -394,37 +394,37 @@ Creates and returns a Multiblock field ID, which can be passed to
 MBLK_Update_Field and MBLK_Reduce_Field. Can only be called from
 driver().
 
-dimensions describes the size of the array the field is in. Dimensions
-is itself an array of size 3, giving the :math:`i`, :math:`j`, and
-:math:`k` sizes. The size should include the ghost regions- i.e., pass
-the actual allocated size of the array. isVoxel describes whether the
+``dimensions`` describes the size of the array the field is in as an
+array of size 3, giving the :math:`i`, :math:`j`, and
+:math:`k` sizes. The size should include the ghost regions -- i.e., pass
+the actual allocated size of the array. ``isVoxel`` describes whether the
 data item is to be associated with a voxel (1, a volume-centered value)
-or the nodes (0, a node-centered value). base_type describes the type of
+or the nodes (0, a node-centered value). ``base_type`` describes the type of
 each data item, one of:
 
--  MBLK_BYTE- unsigned char, INTEGER*1, or CHARACTER*1
+-  MBLK_BYTE -- ``unsigned char``, ``INTEGER*1``, or ``CHARACTER*1``
 
--  MBLK_INT- int or INTEGER*4
+-  MBLK_INT -- ``int`` or ``INTEGER*4``
 
--  MBLK_REAL- float or REAL*4
+-  MBLK_REAL -- ``float`` or ``REAL*4``
 
--  MBLK_DOUBLE- double, DOUBLE PRECISION, or REAL*8
+-  MBLK_DOUBLE -- ``double``, ``DOUBLE PRECISION``, or ``REAL*8``
 
-vec_len describes the number of data items associated with each cell, an
+``vec_len`` describes the number of data items associated with each cell, an
 integer at least 1.
 
-offset is the byte offset from the start of the array to the first
+``offset`` is the byte offset from the start of the array to the first
 interior cell’s data items, a non-negative integer. This can be
-calculated using the offsetof() function; normally with
-offsetof(array(1,1,1),array(interiorX,interiorY,interiorZ)). Be sure to
+calculated using the ``offsetof()`` function, normally with
+``offsetof(array(1,1,1), array(interiorX,interiorY,interiorZ))``. Be sure to
 skip over any ghost regions.
 
-dist is the byte offset from the first cell’s data items to the second,
+``dist`` is the byte offset from the first cell’s data items to the second,
 a positive integer (normally the size of the data items). This can also
-be calculated using offsetof(); normally with
-offsetof(array(1,1,1),array(2,1,1)).
+be calculated using ``offsetof()``; normally with
+``offsetof(array(1,1,1), array(2,1,1))``.
 
-fid is the identifier for the field that is created by the function.
+``fid`` is the identifier for the field that is created by the function.
 
 In the example below, we register a single double-precision value with
 each voxel. The ghost region is 2 cells deep along all sides.
@@ -453,9 +453,9 @@ each voxel. The ghost region is 2 cells deep along all sides.
               &offsetof(grid(1,1,1),grid(2,1,1)),fid,err)
 
 
-This example uses the Fortran-only helper routine offsetof, which
+This example uses the Fortran-only helper routine ``offsetof``, which
 returns the offset in bytes of memory between its two given variables. C
-users can use the built-in sizeof keyword or pointer arithmetic to
+users can use the built-in ``sizeof`` keyword or pointer arithmetic to
 achieve the same result.
 
 ::
@@ -474,7 +474,7 @@ Update the values in the ghost regions specified when the field was
 created. This call sends this block’s interior region out, and
 receives this block’s boundary region from adjoining blocks.
 
-Ghostwidth controls the thickness of the ghost region. To only exchange
+``ghostwidth`` controls the thickness of the ghost region. To exchange only
 one cell on the boundary, pass 1. To exchange two cells, pass 2. To
 include diagonal regions, make the ghost width negative. A ghost width
 of zero would communicate no data.
@@ -484,15 +484,15 @@ of zero would communicate no data.
    :width: 2in
 
    The 2D ghost cells communicated for various ghost widths. The heavy
-   line is the block interior boundary- this is the lower left portion
+   line is the block interior boundary -- this is the lower left portion
    of the block.
 
-MBLK_Update_field can only be called from driver, and to be useful, must
+MBLK_Update_field can only be called from the driver, and to be useful, must
 be called from every block’s driver routine.
 
-MBLK_Update_field blocks till the field has been updated. After this
+MBLK_Update_field blocks until the field has been updated. After this
 routine returns, the given field will updated. If the update was
-successful MBLK_SUCCESS is returned and MBLK_FAILURE is returned in case
+successful MBLK_SUCCESS is returned, otherwise MBLK_FAILURE is returned in case
 of error.
 
 ::
@@ -511,15 +511,15 @@ Update the values in the ghost regions which were specified when the
 field was created. For the example above the ghost regions will be
 updated once for each step in the time loop.
 
-MBLK_Iupdate_field can only be called from driver, and to be useful,
+MBLK_Iupdate_field can only be called from the driver, and to be useful,
 must be called from every block’s driver routine.
 
-MBLK_Iupdate_field is a non blocking call similar to MPI_IRecv. After
-the routine returns the update may not yet be complete; and the outgrid
-may be in an inconsistent state. Before using the values the status of
+MBLK_Iupdate_field is a non blocking call similar to MPI_Irecv. After
+the routine returns the update may not yet be complete and the outgrid
+may be in an inconsistent state. Before using the values, the status of
 the update must be checked using MBLK_Test_update or MBLK_Wait_update.
 
-There can be only one outstanding iupdate call in progress at any time.
+There can be only one outstanding Iupdate call in progress at any time.
 
 ::
 
@@ -531,8 +531,8 @@ There can be only one outstanding iupdate call in progress at any time.
   integer, intent(out) :: status,err
 
 MBLK_Test_update is a call that is used in association with
-MBLK_Iupdate_field from the driver sub routine. It tests whether the
-preceding iupdate has completed or not. status is returned as
+MBLK_Iupdate_field from the driver subroutine. It tests whether the
+preceding Iupdate has completed or not. ``status`` is returned as
 MBLK_DONE if the update was completed or MBLK_NOTDONE if the update is
 still pending. Rather than looping if the update is still pending,
 call MBLK_Wait_update to relinquish the CPU.
@@ -559,23 +559,23 @@ MBLK_Iupdate_field call. It blocks until the update is completed.
   varies, intent(in) :: grid
   varies, intent(out) :: outVal
 
-Combine a field from each block, according to op, across all blocks.
-Only the interior values of the field will be combined; not the ghost
+Combine a field from each block, according to ``op``, across all blocks.
+Only the interior values of the field will be combined, not the ghost
 cells. After Reduce_Field returns, all blocks will have identical
-values in outVal, which must be vec_len copies of base_type.
+values in ``outVal``, which must be ``vec_len`` copies of ``base_type``.
 
-May only be called from driver, and to complete, must be called from
+May only be called from the driver, and to complete, must be called from
 every chunk’s driver routine.
 
 op must be one of:
 
--  MBLK_SUM- each element of outVal will be the sum of the corresponding
+-  MBLK_SUM -- each element of ``outVal`` will be the sum of the corresponding
    fields of all blocks
 
--  MBLK_MIN- each element of outVal will be the smallest value among the
+-  MBLK_MIN -- each element of ``outVal`` will be the smallest value among the
    corresponding field of all blocks
 
--  MBLK_MAX- each element of outVal will be the largest value among the
+-  MBLK_MAX -- each element of ``outVal`` will be the largest value among the
    corresponding field of all blocks
 
 ::
@@ -589,12 +589,12 @@ op must be one of:
   varies, intent(in) :: inVal
   varies, intent(out) :: outVal
 
-Combine a field from each block, acoording to op, across all blocks.
-Fid is only used for the base_type and vec_len- offset and dist are
-not used. After this call returns, all blocks will have identical
-values in outVal. Op has the same values and meaning as
-MBLK_Reduce_Field. May only be called from driver, and to complete,
-must be called from every blocks driver routine.
+Combine a field from each block, acoording to ``op``, across all blocks.
+``fid`` is only used for ``base_type`` and ``vec_len`` -- ``offset`` and
+``dist`` are not used. After this call returns, all blocks will have
+identical values in ``outVal``. ``op`` has the same values and meaning as
+MBLK_Reduce_Field. May only be called from the driver, and to complete,
+must be called from every block's driver routine.
 
 External Boundary Conditions
 ----------------------------
@@ -623,13 +623,13 @@ This call is used to bind an external boundary condition
 subroutine, written by you, to a boundary condition number.
 MBLK_Register_bc should only be called from the driver.
 
--  bcnum The boundary condition number to be associated with the
+-  ``bcnum`` -- The boundary condition number to be associated with the
    function.
 
--  ghostWidth The width of the ghost cells where this boundary condition
+-  ``ghostWidth`` -- The width of the ghost cells where this boundary condition
    is to be applied.
 
--  bcfn The user subroutine to be called to apply this boundry
+-  ``bcfn`` -- The user subroutine to be called to apply this boundry
    condition.
 
 When you ask the framework to apply boundary conditions, it will call
@@ -648,15 +648,15 @@ this routine. The routine should be declared like:
        /* In C */
        void applyMyBC(void *param1,void *param2,int *start,int *end);
 
-param1 and param2 are not used by the framework- they are passed in
-unmodified from MBLK_Apply_bc and MBLK_Apply_bc_all. param1 and param2
+``param1`` and ``param2`` are not used by the framework -- they are passed in
+unmodified from MBLK_Apply_bc and MBLK_Apply_bc_all. ``param1`` and ``param2``
 typically contain the block data and dimensions.
 
-start and end are 3-element arrays that give the :math:`i`,\ :math:`j`,
+``start`` and ``end`` are 3-element arrays that give the :math:`i`,\ :math:`j`,
 :math:`k` block locations where the boundary condition is to be applied.
-They are both inclusive and both relative to the block interior- you
+They are both inclusive and both relative to the block interior -- you
 must shift them over your ghost cells. The C versions are 0-based (the
-first index is zero); the Fortran versions are 1-based (the first index
+first index is zero), while the Fortran versions are 1-based (the first index
 is one).
 
 For example, a Fortran subroutine to apply the constant value 1.0 across
@@ -694,7 +694,7 @@ the boundary, with a 2-deep ghost region, would be:
   integer,intent(out)::err
 
 MBLK_Apply_bc call is made to apply all boundary condition functions
-of type bcnum to the block. param1 and param2 are passed unmodified to
+of type ``bcnum`` to the block. ``param1`` and ``param2`` are passed unmodified to
 the boundary condition function.
 
 ::
@@ -714,8 +714,8 @@ boundary conditions to the block.
 Migration
 ---------
 
-The Charm++ runtime framework includes an automated, run-time load
-balancer, which will automatically monitor the performance of your
+The Charm++ runtime system includes automated, runtime load
+balancing, which will automatically monitor the performance of your
 parallel program. If needed, the load balancer can “migrate” mesh chunks
 from heavily-loaded processors to more lightly-loaded processors,
 improving the load balance and speeding up the program. For this to be
@@ -725,23 +725,23 @@ calling MBLK_Migrate and migration will never take place.
 
 The runtime system can automatically move your thread stack to the new
 processor, but you must write a PUP function to move any global or
-heap-allocated data to the new processor (global data is declared at
-file scope or static in C and COMMON in Fortran77; heap allocated data
-comes from C malloc, C++ new, or Fortran90 ALLOCATE). A PUP
+heap-allocated data to the new processor. (Global data is declared at
+file scope or ``static`` in C and ``COMMON`` in Fortran77. Heap allocated data
+comes from C ``malloc``, C++ ``new``, or Fortran90 ``ALLOCATE``.) A PUP
 (Pack/UnPack) function performs both packing (converting heap data into
 a message) and unpacking (converting a message back into heap data). All
-your global and heap data must be collected into a single block (struct
-in C; user-defined TYPE in Fortran) so the PUP function can access it
+your global and heap data must be collected into a single block (``struct``
+in C, user-defined ``TYPE`` in Fortran) so the PUP function can access it
 all.
 
 Your PUP function will be passed a pointer to your heap data block and a
 special handle called a “pupper”, which contains the network message to
 be sent. Your PUP function returns a pointer to your heap data block. In
-a PUP function, you pass all your heap data to routines named pup_type,
-where type is either a basic type (such as int, char, float, or double)
+a PUP function, you pass all your heap data to routines named ``pup_type``,
+where type is either a basic type (such as ``int``, ``char``, ``float``, or ``double``)
 or an array type (as before, but with a “s” suffix). Depending on the
 direction of packing, the pupper will either read from or write to the
-values you pass- normally, you shouldn’t even know which. The only time
+values you pass -- normally, you shouldn’t even know which. The only time
 you need to know the direction is when you are leaving a processor or
 just arriving. Correspondingly, the pupper passed to you may be deleting
 (indicating that you are leaving the processor, and should delete your
@@ -750,7 +750,7 @@ on a processor, and should allocate your heap storage before unpacking),
 or neither (indicating the system is merely sizing a buffer, or
 checkpointing your values).
 
-PUP functions are much easier to write than explain- a simple C heap
+PUP functions are much easier to write than explain -- a simple C heap
 block and the corresponding PUP function is:
 
 ::
@@ -782,11 +782,11 @@ block and the corresponding PUP function is:
   }
 
 This single PUP function can be used to copy the my_block data into a
-message buffer and free the old heap storage (deleting pupper); allocate
+message buffer and free the old heap storage (deleting pupper), allocate
 storage on the new processor and copy the message data back (unpacking
-pupper); or save the heap data for debugging or checkpointing.
+pupper), or save the heap data for debugging or checkpointing.
 
-A Fortran block TYPE and corresponding PUP routine is as follows:
+A Fortran ``TYPE`` block and corresponding PUP routine is as follows:
 
 .. code-block:: fortran
 
@@ -858,7 +858,7 @@ MBLK_Register as:
              INTEGER :: myId,err
              MBLK_Register(m,pup_my_block,myId,err)
 
-Note that Fortran blocks must be allocated on the stack in driver; while
+Note that Fortran blocks must be allocated on the stack in driver, while
 C/C++ blocks may be allocated on the heap.
 
 ::
@@ -872,21 +872,21 @@ C/C++ blocks may be allocated on the heap.
 Informs the load balancing
 system that you are ready to be migrated, if needed. If the system
 decides to migrate you, the PUP function passed to MBLK_Register will be
-called with a sizing pupper, then a packing, deleting pupper. Your stack
+called with a sizing pupper, then a packing and deleting pupper. Your stack
 (and pupped data) will then be sent to the destination machine, where
 your PUP function will be called with an unpacking pupper. MBLK_Migrate
 will then return, whereupon you should call MBLK_Get_registered to get
-your unpacked data block. Can only be called from driver.
+your unpacked data block. Can only be called from the driver.
 
 ::
 
   int MBLK_Get_Userdata(int n, void** block)
 
 Return your unpacked
-userdata after migration- that is, the return value of the unpacking
-call to your PUP function. Takes the userdata ID returned by
-MBLK_Register. Can be called from driver at any time.
+userdata after migration -- that is, the return value of the unpacking
+call -- to your PUP function. Takes the userdata ID returned by
+MBLK_Register. Can be called from the driver at any time.
 
 Since Fortran blocks are always allocated on the stack, the system
 migrates them to the same location on the new processor, so no
-Get_registered call is needed from Fortran.
+Get_Registered call is needed from Fortran.