via environment variable OMP_NUM_THREADS or via omp_set_num_threads(). The function 'hypre_NumThreads()' returns the number of threads.
455 lines
15 KiB
C
455 lines
15 KiB
C
/*BHEADER**********************************************************************
|
|
* (c) 1997 The Regents of the University of California
|
|
*
|
|
* See the file COPYRIGHT_and_DISCLAIMER for a complete copyright
|
|
* notice, contact person, and disclaimer.
|
|
*
|
|
* $Revision$
|
|
*********************************************************************EHEADER*/
|
|
/******************************************************************************
|
|
*
|
|
* Header info for the Box structures
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#ifndef hypre_BOX_HEADER
|
|
#define hypre_BOX_HEADER
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* hypre_Index:
|
|
* This is used to define indices in index space, or dimension
|
|
* sizes of boxes.
|
|
*
|
|
* The spatial dimensions x, y, and z may be specified by the
|
|
* integers 0, 1, and 2, respectively (see the hypre_IndexD macro below).
|
|
* This simplifies the code in the hypre_Box class by reducing code
|
|
* replication.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
typedef int hypre_Index[3];
|
|
typedef int *hypre_IndexRef;
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* hypre_Box:
|
|
* Structure describing a cartesian region of some index space.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
typedef struct hypre_Box_struct
|
|
{
|
|
hypre_Index imin; /* min bounding indices */
|
|
hypre_Index imax; /* max bounding indices */
|
|
|
|
} hypre_Box;
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* hypre_BoxArray:
|
|
* An array of boxes.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
typedef struct hypre_BoxArray_struct
|
|
{
|
|
hypre_Box *boxes; /* Array of boxes */
|
|
int size; /* Size of box array */
|
|
int alloc_size; /* Size of currently alloced space */
|
|
|
|
} hypre_BoxArray;
|
|
|
|
#define hypre_BoxArrayExcess 10
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* hypre_BoxArrayArray:
|
|
* An array of box arrays.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
typedef struct hypre_BoxArrayArray_struct
|
|
{
|
|
hypre_BoxArray **box_arrays; /* Array of pointers to box arrays */
|
|
int size; /* Size of box array array */
|
|
|
|
} hypre_BoxArrayArray;
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Accessor macros: hypre_Index
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
#define hypre_IndexD(index, d) (index[d])
|
|
|
|
#define hypre_IndexX(index) hypre_IndexD(index, 0)
|
|
#define hypre_IndexY(index) hypre_IndexD(index, 1)
|
|
#define hypre_IndexZ(index) hypre_IndexD(index, 2)
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Member functions: hypre_Index
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
#define hypre_SetIndex(index, ix, iy, iz) \
|
|
( hypre_IndexX(index) = ix,\
|
|
hypre_IndexY(index) = iy,\
|
|
hypre_IndexZ(index) = iz )
|
|
|
|
#define hypre_ClearIndex(index) hypre_SetIndex(index, 0, 0, 0)
|
|
|
|
#define hypre_CopyIndex(index1, index2) \
|
|
( hypre_IndexX(index2) = hypre_IndexX(index1),\
|
|
hypre_IndexY(index2) = hypre_IndexY(index1),\
|
|
hypre_IndexZ(index2) = hypre_IndexZ(index1) )
|
|
|
|
#define hypre_CopyToCleanIndex(in_index, ndim, out_index) \
|
|
{\
|
|
int d;\
|
|
for (d = 0; d < ndim; d++)\
|
|
{\
|
|
hypre_IndexD(out_index, d) = hypre_IndexD(in_index, d);\
|
|
}\
|
|
for (d = ndim; d < 3; d++)\
|
|
{\
|
|
hypre_IndexD(out_index, d) = 0;\
|
|
}\
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Accessor macros: hypre_Box
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
#define hypre_BoxIMin(box) ((box) -> imin)
|
|
#define hypre_BoxIMax(box) ((box) -> imax)
|
|
|
|
#define hypre_BoxIMinD(box, d) (hypre_IndexD(hypre_BoxIMin(box), d))
|
|
#define hypre_BoxIMaxD(box, d) (hypre_IndexD(hypre_BoxIMax(box), d))
|
|
#define hypre_BoxSizeD(box, d) \
|
|
hypre_max(0, (hypre_BoxIMaxD(box, d) - hypre_BoxIMinD(box, d) + 1))
|
|
|
|
#define hypre_BoxIMinX(box) hypre_BoxIMinD(box, 0)
|
|
#define hypre_BoxIMinY(box) hypre_BoxIMinD(box, 1)
|
|
#define hypre_BoxIMinZ(box) hypre_BoxIMinD(box, 2)
|
|
|
|
#define hypre_BoxIMaxX(box) hypre_BoxIMaxD(box, 0)
|
|
#define hypre_BoxIMaxY(box) hypre_BoxIMaxD(box, 1)
|
|
#define hypre_BoxIMaxZ(box) hypre_BoxIMaxD(box, 2)
|
|
|
|
#define hypre_BoxSizeX(box) hypre_BoxSizeD(box, 0)
|
|
#define hypre_BoxSizeY(box) hypre_BoxSizeD(box, 1)
|
|
#define hypre_BoxSizeZ(box) hypre_BoxSizeD(box, 2)
|
|
|
|
#define hypre_CopyBox(box1, box2) \
|
|
( hypre_CopyIndex(hypre_BoxIMin(box1), hypre_BoxIMin(box2)),\
|
|
hypre_CopyIndex(hypre_BoxIMax(box1), hypre_BoxIMax(box2)) )
|
|
|
|
#define hypre_BoxVolume(box) \
|
|
(hypre_BoxSizeX(box) * hypre_BoxSizeY(box) * hypre_BoxSizeZ(box))
|
|
|
|
#define hypre_BoxIndexRank(box, index) \
|
|
((hypre_IndexX(index) - hypre_BoxIMinX(box)) + \
|
|
((hypre_IndexY(index) - hypre_BoxIMinY(box)) + \
|
|
((hypre_IndexZ(index) - hypre_BoxIMinZ(box)) * \
|
|
hypre_BoxSizeY(box))) * \
|
|
hypre_BoxSizeX(box))
|
|
|
|
#define hypre_BoxOffsetDistance(box, index) \
|
|
(hypre_IndexX(index) + \
|
|
(hypre_IndexY(index) + \
|
|
(hypre_IndexZ(index) * \
|
|
hypre_BoxSizeY(box))) * \
|
|
hypre_BoxSizeX(box))
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Accessor macros: hypre_BoxArray
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
#define hypre_BoxArrayBoxes(box_array) ((box_array) -> boxes)
|
|
#define hypre_BoxArrayBox(box_array, i) &((box_array) -> boxes[(i)])
|
|
#define hypre_BoxArraySize(box_array) ((box_array) -> size)
|
|
#define hypre_BoxArrayAllocSize(box_array) ((box_array) -> alloc_size)
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Accessor macros: hypre_BoxArrayArray
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
#define hypre_BoxArrayArrayBoxArrays(box_array_array) \
|
|
((box_array_array) -> box_arrays)
|
|
#define hypre_BoxArrayArrayBoxArray(box_array_array, i) \
|
|
((box_array_array) -> box_arrays[(i)])
|
|
#define hypre_BoxArrayArraySize(box_array_array) \
|
|
((box_array_array) -> size)
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Looping macros:
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
#define hypre_ForBoxI(i, box_array) \
|
|
for (i = 0; i < hypre_BoxArraySize(box_array); i++)
|
|
|
|
#define hypre_ForBoxArrayI(i, box_array_array) \
|
|
for (i = 0; i < hypre_BoxArrayArraySize(box_array_array); i++)
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* BoxLoop macros:
|
|
*
|
|
* NOTE: PThreads version of BoxLoop looping macros are in `box_pthreads.h'.
|
|
*
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
#ifndef HYPRE_USE_PTHREADS
|
|
|
|
#define hypre_BoxLoopDeclareS(dbox, stride, sx, sy, sz) \
|
|
int sx = (hypre_IndexX(stride));\
|
|
int sy = (hypre_IndexY(stride)*hypre_BoxSizeX(dbox));\
|
|
int sz = (hypre_IndexZ(stride)*\
|
|
hypre_BoxSizeX(dbox)*hypre_BoxSizeY(dbox))
|
|
|
|
#define hypre_BoxLoopDeclareN(loop_size) \
|
|
int hypre__nx = hypre_IndexX(loop_size);\
|
|
int hypre__ny = hypre_IndexY(loop_size);\
|
|
int hypre__nz = hypre_IndexZ(loop_size);\
|
|
int hypre__mx = hypre__nx;\
|
|
int hypre__my = hypre__ny;\
|
|
int hypre__mz = hypre__nz;\
|
|
int hypre__dir, hypre__max;\
|
|
int hypre__div, hypre__mod;\
|
|
int hypre__block, hypre__num_blocks;\
|
|
hypre__dir = 0;\
|
|
hypre__max = hypre__nx;\
|
|
if (hypre__ny > hypre__max)\
|
|
{\
|
|
hypre__dir = 1;\
|
|
hypre__max = hypre__ny;\
|
|
}\
|
|
if (hypre__nz > hypre__max)\
|
|
{\
|
|
hypre__dir = 2;\
|
|
hypre__max = hypre__nz;\
|
|
}\
|
|
hypre__num_blocks = hypre_NumThreads();\
|
|
if (hypre__max < hypre__num_blocks)\
|
|
{\
|
|
hypre__num_blocks = hypre__max;\
|
|
}\
|
|
if (hypre__num_blocks > 0)\
|
|
{\
|
|
hypre__div = hypre__max / hypre__num_blocks;\
|
|
hypre__mod = hypre__max % hypre__num_blocks;\
|
|
}
|
|
|
|
#define hypre_BoxLoopSet(i, j, k) \
|
|
i = 0;\
|
|
j = 0;\
|
|
k = 0;\
|
|
hypre__nx = hypre__mx;\
|
|
hypre__ny = hypre__my;\
|
|
hypre__nz = hypre__mz;\
|
|
if (hypre__num_blocks > 1)\
|
|
{\
|
|
if (hypre__dir == 0)\
|
|
{\
|
|
i = hypre__block * hypre__div + hypre_min(hypre__mod, hypre__block);\
|
|
hypre__nx = hypre__div + ((hypre__mod > hypre__block) ? 1 : 0);\
|
|
}\
|
|
else if (hypre__dir == 1)\
|
|
{\
|
|
j = hypre__block * hypre__div + hypre_min(hypre__mod, hypre__block);\
|
|
hypre__ny = hypre__div + ((hypre__mod > hypre__block) ? 1 : 0);\
|
|
}\
|
|
else if (hypre__dir == 2)\
|
|
{\
|
|
k = hypre__block * hypre__div + hypre_min(hypre__mod, hypre__block);\
|
|
hypre__nz = hypre__div + ((hypre__mod > hypre__block) ? 1 : 0);\
|
|
}\
|
|
}
|
|
|
|
/*-----------------------------------*/
|
|
|
|
#define hypre_BoxLoop0Begin(loop_size)\
|
|
{\
|
|
hypre_BoxLoopDeclareN(loop_size);
|
|
|
|
#define hypre_BoxLoop0For(i, j, k)\
|
|
for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++)\
|
|
{\
|
|
hypre_BoxLoopSet(i, j, k);\
|
|
for (k = 0; k < hypre__nz; k++)\
|
|
{\
|
|
for (j = 0; j < hypre__ny; j++)\
|
|
{\
|
|
for (i = 0; i < hypre__nx; i++)\
|
|
{
|
|
|
|
#define hypre_BoxLoop0End()\
|
|
}\
|
|
}\
|
|
}\
|
|
}\
|
|
}
|
|
|
|
/*-----------------------------------*/
|
|
|
|
#define hypre_BoxLoop1Begin(loop_size,\
|
|
dbox1, start1, stride1, i1)\
|
|
{\
|
|
int hypre__i1start = hypre_BoxIndexRank(dbox1, start1);\
|
|
hypre_BoxLoopDeclareS(dbox1, stride1, hypre__sx1, hypre__sy1, hypre__sz1);\
|
|
hypre_BoxLoopDeclareN(loop_size);
|
|
|
|
#define hypre_BoxLoop1For(i, j, k, i1)\
|
|
for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++)\
|
|
{\
|
|
hypre_BoxLoopSet(i, j, k);\
|
|
i1 = hypre__i1start + i*hypre__sx1 + j*hypre__sy1 + k*hypre__sz1;\
|
|
for (k = 0; k < hypre__nz; k++)\
|
|
{\
|
|
for (j = 0; j < hypre__ny; j++)\
|
|
{\
|
|
for (i = 0; i < hypre__nx; i++)\
|
|
{
|
|
|
|
#define hypre_BoxLoop1End(i1)\
|
|
i1 += hypre__sx1;\
|
|
}\
|
|
i1 += hypre__sy1 - hypre__nx*hypre__sx1;\
|
|
}\
|
|
i1 += hypre__sz1 - hypre__ny*hypre__sy1;\
|
|
}\
|
|
}\
|
|
}
|
|
|
|
/*-----------------------------------*/
|
|
|
|
#define hypre_BoxLoop2Begin(loop_size,\
|
|
dbox1, start1, stride1, i1,\
|
|
dbox2, start2, stride2, i2)\
|
|
{\
|
|
int hypre__i1start = hypre_BoxIndexRank(dbox1, start1);\
|
|
int hypre__i2start = hypre_BoxIndexRank(dbox2, start2);\
|
|
hypre_BoxLoopDeclareS(dbox1, stride1, hypre__sx1, hypre__sy1, hypre__sz1);\
|
|
hypre_BoxLoopDeclareS(dbox2, stride2, hypre__sx2, hypre__sy2, hypre__sz2);\
|
|
hypre_BoxLoopDeclareN(loop_size);
|
|
|
|
#define hypre_BoxLoop2For(i, j, k, i1, i2)\
|
|
for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++)\
|
|
{\
|
|
hypre_BoxLoopSet(i, j, k);\
|
|
i1 = hypre__i1start + i*hypre__sx1 + j*hypre__sy1 + k*hypre__sz1;\
|
|
i2 = hypre__i2start + i*hypre__sx2 + j*hypre__sy2 + k*hypre__sz2;\
|
|
for (k = 0; k < hypre__nz; k++)\
|
|
{\
|
|
for (j = 0; j < hypre__ny; j++)\
|
|
{\
|
|
for (i = 0; i < hypre__nx; i++)\
|
|
{
|
|
|
|
#define hypre_BoxLoop2End(i1, i2)\
|
|
i1 += hypre__sx1;\
|
|
i2 += hypre__sx2;\
|
|
}\
|
|
i1 += hypre__sy1 - hypre__nx*hypre__sx1;\
|
|
i2 += hypre__sy2 - hypre__nx*hypre__sx2;\
|
|
}\
|
|
i1 += hypre__sz1 - hypre__ny*hypre__sy1;\
|
|
i2 += hypre__sz2 - hypre__ny*hypre__sy2;\
|
|
}\
|
|
}\
|
|
}
|
|
|
|
/*-----------------------------------*/
|
|
|
|
#define hypre_BoxLoop3Begin(loop_size,\
|
|
dbox1, start1, stride1, i1,\
|
|
dbox2, start2, stride2, i2,\
|
|
dbox3, start3, stride3, i3)\
|
|
{\
|
|
int hypre__i1start = hypre_BoxIndexRank(dbox1, start1);\
|
|
int hypre__i2start = hypre_BoxIndexRank(dbox2, start2);\
|
|
int hypre__i3start = hypre_BoxIndexRank(dbox3, start3);\
|
|
hypre_BoxLoopDeclareS(dbox1, stride1, hypre__sx1, hypre__sy1, hypre__sz1);\
|
|
hypre_BoxLoopDeclareS(dbox2, stride2, hypre__sx2, hypre__sy2, hypre__sz2);\
|
|
hypre_BoxLoopDeclareS(dbox3, stride3, hypre__sx3, hypre__sy3, hypre__sz3);\
|
|
hypre_BoxLoopDeclareN(loop_size);
|
|
|
|
#define hypre_BoxLoop3For(i, j, k, i1, i2, i3)\
|
|
for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++)\
|
|
{\
|
|
hypre_BoxLoopSet(i, j, k);\
|
|
i1 = hypre__i1start + i*hypre__sx1 + j*hypre__sy1 + k*hypre__sz1;\
|
|
i2 = hypre__i2start + i*hypre__sx2 + j*hypre__sy2 + k*hypre__sz2;\
|
|
i3 = hypre__i3start + i*hypre__sx3 + j*hypre__sy3 + k*hypre__sz3;\
|
|
for (k = 0; k < hypre__nz; k++)\
|
|
{\
|
|
for (j = 0; j < hypre__ny; j++)\
|
|
{\
|
|
for (i = 0; i < hypre__nx; i++)\
|
|
{
|
|
|
|
#define hypre_BoxLoop3End(i1, i2, i3)\
|
|
i1 += hypre__sx1;\
|
|
i2 += hypre__sx2;\
|
|
i3 += hypre__sx3;\
|
|
}\
|
|
i1 += hypre__sy1 - hypre__nx*hypre__sx1;\
|
|
i2 += hypre__sy2 - hypre__nx*hypre__sx2;\
|
|
i3 += hypre__sy3 - hypre__nx*hypre__sx3;\
|
|
}\
|
|
i1 += hypre__sz1 - hypre__ny*hypre__sy1;\
|
|
i2 += hypre__sz2 - hypre__ny*hypre__sy2;\
|
|
i3 += hypre__sz3 - hypre__ny*hypre__sy3;\
|
|
}\
|
|
}\
|
|
}
|
|
|
|
/*-----------------------------------*/
|
|
|
|
#define hypre_BoxLoop4Begin(loop_size,\
|
|
dbox1, start1, stride1, i1,\
|
|
dbox2, start2, stride2, i2,\
|
|
dbox3, start3, stride3, i3,\
|
|
dbox4, start4, stride4, i4)\
|
|
{\
|
|
int hypre__i1start = hypre_BoxIndexRank(dbox1, start1);\
|
|
int hypre__i2start = hypre_BoxIndexRank(dbox2, start2);\
|
|
int hypre__i3start = hypre_BoxIndexRank(dbox3, start3);\
|
|
int hypre__i4start = hypre_BoxIndexRank(dbox4, start4);\
|
|
hypre_BoxLoopDeclareS(dbox1, stride1, hypre__sx1, hypre__sy1, hypre__sz1);\
|
|
hypre_BoxLoopDeclareS(dbox2, stride2, hypre__sx2, hypre__sy2, hypre__sz2);\
|
|
hypre_BoxLoopDeclareS(dbox3, stride3, hypre__sx3, hypre__sy3, hypre__sz3);\
|
|
hypre_BoxLoopDeclareS(dbox4, stride4, hypre__sx4, hypre__sy4, hypre__sz4);\
|
|
hypre_BoxLoopDeclareN(loop_size);
|
|
|
|
#define hypre_BoxLoop4For(i, j, k, i1, i2, i3, i4)\
|
|
for (hypre__block = 0; hypre__block < hypre__num_blocks; hypre__block++)\
|
|
{\
|
|
hypre_BoxLoopSet(i, j, k);\
|
|
i1 = hypre__i1start + i*hypre__sx1 + j*hypre__sy1 + k*hypre__sz1;\
|
|
i2 = hypre__i2start + i*hypre__sx2 + j*hypre__sy2 + k*hypre__sz2;\
|
|
i3 = hypre__i3start + i*hypre__sx3 + j*hypre__sy3 + k*hypre__sz3;\
|
|
i4 = hypre__i4start + i*hypre__sx4 + j*hypre__sy4 + k*hypre__sz4;\
|
|
for (k = 0; k < hypre__nz; k++)\
|
|
{\
|
|
for (j = 0; j < hypre__ny; j++)\
|
|
{\
|
|
for (i = 0; i < hypre__nx; i++)\
|
|
{
|
|
|
|
#define hypre_BoxLoop4End(i1, i2, i3, i4)\
|
|
i1 += hypre__sx1;\
|
|
i2 += hypre__sx2;\
|
|
i3 += hypre__sx3;\
|
|
i4 += hypre__sx4;\
|
|
}\
|
|
i1 += hypre__sy1 - hypre__nx*hypre__sx1;\
|
|
i2 += hypre__sy2 - hypre__nx*hypre__sx2;\
|
|
i3 += hypre__sy3 - hypre__nx*hypre__sx3;\
|
|
i4 += hypre__sy4 - hypre__nx*hypre__sx4;\
|
|
}\
|
|
i1 += hypre__sz1 - hypre__ny*hypre__sy1;\
|
|
i2 += hypre__sz2 - hypre__ny*hypre__sy2;\
|
|
i3 += hypre__sz3 - hypre__ny*hypre__sy3;\
|
|
i4 += hypre__sz4 - hypre__ny*hypre__sy4;\
|
|
}\
|
|
}\
|
|
}
|
|
|
|
/*-----------------------------------*/
|
|
|
|
#endif /* ifndef HYPRE_USE_PTHREADS */
|
|
|
|
#endif
|