.. default-domain:: chpl

.. module:: BlockDist

BlockDist
=========
.. class:: Block

   
   This Block distribution partitions indices into blocks
   according to a ``boundingBox`` domain
   and maps each entire block onto a locale from a ``targetLocales`` array.
   
   The indices inside the bounding box are partitioned "evenly" across
   the target locales. An index outside the bounding box is mapped to the
   same locale as the nearest index inside the bounding box.
   
   Formally, an index ``idx`` is mapped to ``targetLocales[locIdx]``,
   where ``locIdx`` is computed as follows.
   
   In the 1-dimensional case, for a Block distribution with:
   
   
     =================   ====================
     ``boundingBox``     ``{low..high}``
     ``targetLocales``   ``[0..N-1] locale``
     =================   ====================
   
   we have:
   
     ===================    ==========================================
     if ``idx`` is ...      ``locIdx`` is ...
     ===================    ==========================================
     ``low<=idx<=high``     ``floor(  (idx-low)*N / (high-low+1)  )``
     ``idx < low``          ``0``
     ``idx > high``         ``N-1``
     ===================    ==========================================
   
   In the multidimensional case, ``idx`` and ``locIdx`` are tuples
   of indices; ``boundingBox`` and ``targetLocales`` are multi-dimensional;
   the above computation is applied in each dimension.
   
   
   **Example**
   
   The following code declares a domain ``D`` distributed over
   a Block distribution with a bounding box equal to the domain ``Space``,
   and declares an array ``A`` over that domain.
   The `forall` loop sets each array element
   to the ID of the locale to which it is mapped.
   
     .. code-block:: chapel
   
       use BlockDist;
   
       const Space = {1..8, 1..8};
       const D: domain(2) dmapped Block(boundingBox=Space) = Space;
       var A: [D] int;
   
       forall a in A do
         a = a.locale.id;
   
       writeln(A);
   
   When run on 6 locales, the output is:
   
     ::
   
       0 0 0 0 1 1 1 1
       0 0 0 0 1 1 1 1
       0 0 0 0 1 1 1 1
       2 2 2 2 3 3 3 3
       2 2 2 2 3 3 3 3
       2 2 2 2 3 3 3 3
       4 4 4 4 5 5 5 5
       4 4 4 4 5 5 5 5
   
   
   **Constructor Arguments**
   
   The ``Block`` class constructor is defined as follows:
   
     .. code-block:: chapel
   
       proc Block(
         boundingBox: domain,
         targetLocales: [] locale  = Locales, 
         dataParTasksPerLocale     = // value of  dataParTasksPerLocale      config const,
         dataParIgnoreRunningTasks = // value of  dataParIgnoreRunningTasks  config const,
         dataParMinGranularity     = // value of  dataParMinGranularity      config const,
         param rank                = boundingBox.rank,
         type  idxType             = boundingBox.idxType)
   
   The arguments ``boundingBox`` (a domain) and ``targetLocales`` (an array)
   define the mapping of any index of ``idxType`` type to a locale
   as described above.
   
   The rank of ``targetLocales`` must match the rank of the distribution,
   or be ``1``.  If the rank of ``targetLocales`` is ``1``, a greedy
   heuristic is used to reshape the array of target locales so that it
   matches the rank of the distribution and each dimension contains an
   approximately equal number of indices.
   
   The arguments ``dataParTasksPerLocale``, ``dataParIgnoreRunningTasks``,
   and ``dataParMinGranularity`` set the knobs that are used to
   control intra-locale data parallelism for Block-distributed domains
   and arrays in the same way that the like-named config constants
   control data parallelism for ranges and default-distributed domains
   and arrays.
   
   The ``rank`` and ``idxType`` arguments are inferred from the
   ``boundingBox`` argument unless explicitly set.
   They must match the rank and index type of the domains
   "dmapped" using that Block instance.
   
   
   **Data-Parallel Iteration**
   
   A `forall` loop over a Block-distributed domain or array
   executes each iteration on the locale where that iteration's index
   is mapped to.
   
   Parallelism within each locale is guided by the values of
   ``dataParTasksPerLocale``, ``dataParIgnoreRunningTasks``, and
   ``dataParMinGranularity`` of the respective Block instance.
   Updates to these values, if any, take effect only on the locale
   where the updates are made.


