Fixed a memory problem with GraphAddEntries() and non-cell data (see [issue659]).
Added a regression test also.
This commit is contained in:
parent
5cd1a8b11e
commit
879368cd2c
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
60
test/TEST_sstruct/sstruct.in.amr.graphadd
Normal file
60
test/TEST_sstruct/sstruct.in.amr.graphadd
Normal 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
|
||||
|
||||
###########################################################
|
||||
|
||||
Loading…
Reference in New Issue
Block a user