Fixed a memory problem with GraphAddEntries() and non-cell data (see [issue659]).

Added a regression test also.
This commit is contained in:
falgout 2011-12-09 18:53:20 +00:00
parent 5cd1a8b11e
commit 879368cd2c
7 changed files with 146 additions and 76 deletions

View File

@ -357,7 +357,6 @@ HYPRE_SStructGraphAssemble( HYPRE_SStructGraph graph )
HYPRE_Int part, var;
hypre_IndexRef index;
hypre_Index cindex;
HYPRE_Int startrank;
HYPRE_Int boxnum;
HYPRE_Int aUventries;
HYPRE_Int ndim = hypre_SStructGridNDim(grid);
@ -544,10 +543,9 @@ HYPRE_SStructGraphAssemble( HYPRE_SStructGraph graph )
* set up the UVEntry and iUventries
*---------------------------------------------------------*/
/* allocate proper storage */
aUventries = hypre_max(hypre_SStructGridGhlocalSize(grid), n_add_entries);
aUventries = hypre_SStructGridGhlocalSize(grid);
iUventries = hypre_TAlloc(HYPRE_Int, aUventries);
iUventries = hypre_TAlloc(HYPRE_Int, n_add_entries);
Uventries = hypre_CTAlloc(hypre_SStructUVEntry *, aUventries);
hypre_SStructGraphAUVEntries(graph) = aUventries;
@ -571,71 +569,69 @@ HYPRE_SStructGraphAssemble( HYPRE_SStructGraph graph )
/* compute location (rank) for Uventry */
hypre_CopyToCleanIndex(index, ndim, cindex);
/* NOTE: This is the same code as in SStructGraphFindUVEntry() */
hypre_SStructGridFindBoxManEntry(grid, part, cindex, var, &boxman_entry);
/* GEC0203 getting the rank */
hypre_SStructBoxManEntryGetGlobalRank(boxman_entry, cindex, &rank, type);
/* GEC 0902 filling up the iUventries with local ghrank
* since HYPRE_SSTRUCT is chosen */
if (type == HYPRE_SSTRUCT || type == HYPRE_STRUCT)
{
startrank = hypre_SStructGridGhstartRank(grid);
rank -= hypre_SStructGridGhstartRank(grid);
}
if (type == HYPRE_PARCSR)
{
startrank = hypre_SStructGridStartRank(grid);
rank -= hypre_SStructGridStartRank(grid);
}
rank -= startrank;
iUventries[nUventries] = rank;
if (Uventries[rank] == NULL)
/* only add the entry if it is in my processor's range */
if ((rank > -1) && (rank < aUventries))
{
Uventry = hypre_TAlloc(hypre_SStructUVEntry, 1);
hypre_SStructUVEntryPart(Uventry) = part;
hypre_CopyToCleanIndex(index, ndim, hypre_SStructUVEntryIndex(Uventry));
hypre_SStructUVEntryVar(Uventry) = var;
hypre_SStructBoxManEntryGetBoxnum(boxman_entry, &boxnum);
hypre_SStructUVEntryBoxnum(Uventry) = boxnum;
nUentries = 1;
Uentries = hypre_TAlloc(hypre_SStructUEntry, nUentries);
}
else
{
Uventry = Uventries[rank];
nUentries = hypre_SStructUVEntryNUEntries(Uventry) + 1;
Uentries = hypre_SStructUVEntryUEntries(Uventry);
Uentries = hypre_TReAlloc(Uentries, hypre_SStructUEntry, nUentries);
}
hypre_SStructUVEntryNUEntries(Uventry) = nUentries;
hypre_SStructUVEntryUEntries(Uventry) = Uentries;
iUventries[nUventries] = rank;
i = nUentries - 1;
hypre_SStructUVEntryToPart(Uventry, i) = to_part;
hypre_CopyToCleanIndex(to_index, ndim,
hypre_SStructUVEntryToIndex(Uventry, i));
hypre_SStructUVEntryToVar(Uventry, i) = to_var;
if (Uventries[rank] == NULL)
{
Uventry = hypre_TAlloc(hypre_SStructUVEntry, 1);
hypre_SStructUVEntryPart(Uventry) = part;
hypre_CopyToCleanIndex(index, ndim, hypre_SStructUVEntryIndex(Uventry));
hypre_SStructUVEntryVar(Uventry) = var;
hypre_SStructBoxManEntryGetBoxnum(boxman_entry, &boxnum);
hypre_SStructUVEntryBoxnum(Uventry) = boxnum;
nUentries = 1;
Uentries = hypre_TAlloc(hypre_SStructUEntry, nUentries);
}
else
{
Uventry = Uventries[rank];
nUentries = hypre_SStructUVEntryNUEntries(Uventry) + 1;
Uentries = hypre_SStructUVEntryUEntries(Uventry);
Uentries = hypre_TReAlloc(Uentries, hypre_SStructUEntry, nUentries);
}
hypre_SStructUVEntryNUEntries(Uventry) = nUentries;
hypre_SStructUVEntryUEntries(Uventry) = Uentries;
i = nUentries - 1;
hypre_SStructUVEntryToPart(Uventry, i) = to_part;
hypre_CopyToCleanIndex(to_index, ndim,
hypre_SStructUVEntryToIndex(Uventry, i));
hypre_SStructUVEntryToVar(Uventry, i) = to_var;
hypre_CopyToCleanIndex(to_index, ndim, cindex);
hypre_CopyToCleanIndex(to_index, ndim, cindex);
hypre_SStructGridFindBoxManEntry(
dom_grid, to_part, cindex, to_var, &boxman_entry);
hypre_SStructBoxManEntryGetBoxnum(boxman_entry, &to_boxnum);
hypre_SStructUVEntryToBoxnum(Uventry, i) = to_boxnum;
hypre_SStructBoxManEntryGetProcess(boxman_entry, &to_proc);
hypre_SStructUVEntryToProc(Uventry, i)= to_proc;
hypre_SStructGridFindBoxManEntry(
dom_grid, to_part, cindex, to_var, &boxman_entry);
hypre_SStructBoxManEntryGetBoxnum(boxman_entry, &to_boxnum);
hypre_SStructUVEntryToBoxnum(Uventry, i) = to_boxnum;
hypre_SStructBoxManEntryGetProcess(boxman_entry, &to_proc);
hypre_SStructUVEntryToProc(Uventry, i)= to_proc;
Uventries[rank] = Uventry; /* GEC1102 where rank labels Uventries */
Uventries[rank] = Uventry; /* GEC1102 where rank labels Uventries */
nUventries++;
hypre_SStructGraphNUVEntries(graph) = nUventries;
nUventries++;
hypre_SStructGraphNUVEntries(graph) = nUventries;
hypre_SStructGraphUVEntries(graph) = Uventries;
hypre_SStructGraphUVEntries(graph) = Uventries;
hypre_SStructGraphTotUEntries(graph) ++;
hypre_SStructGraphTotUEntries(graph) ++;
}
/*free each add entry after copying */
hypre_TFree(new_entry);

View File

@ -10,7 +10,6 @@
* $Revision$
***********************************************************************EHEADER*/
/******************************************************************************
*
* Member functions for hypre_SStructGraph class.
@ -33,8 +32,6 @@ hypre_SStructGraphRef( hypre_SStructGraph *graph,
}
/*--------------------------------------------------------------------------
* NOTE: This may search an Octree in the future.
*
* 9/09 AB - modified to use the box manager
*--------------------------------------------------------------------------*/
@ -47,27 +44,36 @@ hypre_SStructGraphFindUVEntry( hypre_SStructGraph *graph,
{
hypre_SStructUVEntry **Uventries = hypre_SStructGraphUVEntries(graph);
hypre_SStructGrid *grid = hypre_SStructGraphGrid(graph);
HYPRE_Int type = hypre_SStructGraphObjectType(graph);
HYPRE_Int type = hypre_SStructGraphObjectType(graph);
hypre_BoxManEntry *boxman_entry;
HYPRE_Int rank;
HYPRE_Int rank, max_rank;
/* Should we be checking the neighbor box manager also ?*/
/* Should we be checking the neighbor box manager also? */
hypre_SStructGridFindBoxManEntry(grid, part, index, var, &boxman_entry);
hypre_SStructBoxManEntryGetGlobalRank(boxman_entry, index, &rank, type);
/* compute local rank */
if (type == HYPRE_SSTRUCT || type == HYPRE_STRUCT)
{
rank -= hypre_SStructGridGhstartRank(grid);
rank -= hypre_SStructGridGhstartRank(grid);
}
if (type == HYPRE_PARCSR)
{
rank -= hypre_SStructGridStartRank(grid);
rank -= hypre_SStructGridStartRank(grid);
}
/* only return an entry if it is in my processor's range */
max_rank = hypre_SStructGridGhlocalSize(hypre_SStructGraphGrid(graph));
if ((rank > -1) && (rank < max_rank))
{
*Uventry_ptr = Uventries[rank];
}
else
{
*Uventry_ptr = NULL;
}
*Uventry_ptr = Uventries[rank];
return hypre_error_flag;
}

View File

@ -891,10 +891,13 @@ hypre_SStructUMatrixSetValues( hypre_SStructMatrix *matrix,
/* non-stencil entries */
entry -= size;
hypre_SStructGraphFindUVEntry(graph, part, index, var, &Uventry);
col_coords[ncoeffs] = hypre_SStructUVEntryRank(Uventry, entry);
coeffs[ncoeffs] = values[i];
ncoeffs++;
if (Uventry)
{
col_coords[ncoeffs] = hypre_SStructUVEntryRank(Uventry, entry);
coeffs[ncoeffs] = values[i];
ncoeffs++;
}
}
}

View File

@ -11,12 +11,6 @@
# $Revision$
#EHEADER**********************************************************************
#=============================================================================
#=============================================================================
@ -38,3 +32,8 @@ mpirun -np 2 ./sstruct -in sstruct.in.amr.2Dc -solver 20 -P 2 1 1 \
> amr2d.out.7
mpirun -np 6 ./sstruct -in sstruct.in.amr.2De -solver 18 -P 6 1 1 \
> amr2d.out.8
mpirun -np 1 ./sstruct -in sstruct.in.amr.graphadd -solver 20 -r 2 1 1 \
> amr2d.out.10
mpirun -np 2 ./sstruct -in sstruct.in.amr.graphadd -solver 20 -P 2 1 1 \
> amr2d.out.11

View File

@ -34,3 +34,11 @@ Final Relative Residual Norm = 7.452823e-08
Iterations = 21
Final Relative Residual Norm = 5.392338e-07
# Output file: amr2d.out.10
Iterations = 3
Final Relative Residual Norm = 5.312236e-08
# Output file: amr2d.out.11
Iterations = 3
Final Relative Residual Norm = 7.814210e-08

View File

@ -11,10 +11,6 @@
# $Revision$
#EHEADER**********************************************************************
TNAME=`basename $0 .sh`
#=============================================================================
@ -31,6 +27,8 @@ FILES="\
${TNAME}.out.6\
${TNAME}.out.7\
${TNAME}.out.8\
${TNAME}.out.10\
${TNAME}.out.11\
"
for i in $FILES

View File

@ -0,0 +1,60 @@
##############################################################################
#
# This is a simple example that tests GraphAddEntries() when data is shared by
# multiple processors.
#
##############################################################################
# GridCreate: ndim nparts
GridCreate: 2 2
# GridSetExtents: part ilower(ndim) iupper(ndim)
GridSetExtents: 0 (0- 0-) (3+ 3+)
GridSetExtents: 1 (2- 2-) (9+ 9+)
# GridSetVariables: part nvars vartypes[nvars]
# NODE = 1
GridSetVariables: 0 1 [1]
GridSetVariables: 1 1 [1]
###########################################################
# (note: Stencil and FEMStencil cannot be used together)
# StencilCreate: nstencils sizes[nstencils]
StencilCreate: 1 [5]
# StencilSetEntry: stencil_num entry offset[ndim] var value
StencilSetEntry: 0 0 [ 0 0] 0 5.0
StencilSetEntry: 0 1 [-1 0] 0 -1.0
StencilSetEntry: 0 2 [ 1 0] 0 -1.0
StencilSetEntry: 0 3 [ 0 -1] 0 -1.0
StencilSetEntry: 0 4 [ 0 1] 0 -1.0
# RhsSet: value
RhsSet: 1.0
###########################################################
# GraphSetStencil: part var stencil_num
GraphSetStencil: 0 0 0
GraphSetStencil: 1 0 0
# GraphAddEntries: \
# part ilower(ndim) iupper(ndim) stride[ndim] var \
# to_part to_ilower(ndim) to_iupper(ndim) to_stride[ndim] to_var \
# index_map[ndim] entry value
# (note: this could be made to work with FEMStencil, but 'entry' needs to change)
GraphAddEntries: 0 (1- 1- : -1 -1) (2+ 2+ : 0 0) [1 1] 0 1 (2- 2- : -1 -1) (5+ 5+ : 0 0) [2 2] 0 [0 1] 5 -0.5
###########################################################
# ProcessPoolCreate: num_pools
ProcessPoolCreate: 1
# ProcessPoolSetPart: pool part
ProcessPoolSetPart: 0 0
ProcessPoolSetPart: 0 1
###########################################################