Skip to content

Commit

Permalink
Merge pull request #173 from vincentcasseau/main
Browse files Browse the repository at this point in the history
All: fix seg faults & mem leaks, part 2
  • Loading branch information
benoit128 authored Sep 10, 2024
2 parents 5c8b09e + bd2e198 commit 7cab9bf
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 63 deletions.
54 changes: 29 additions & 25 deletions Cassiopee/CPlot/apps/validCassiopee.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,11 +657,11 @@ def runSingleUnitaryTest(no, module, test):
print(output)

# Recupere success/failed
success = 1
success = 0
if regLeakError.search(output) is not None: success = 2 # always check first
if regDiff.search(output) is not None: success = 0
if regFailed.search(output) is not None: success = 0
if regError.search(output) is not None: success = 0
if regDiff.search(output) is not None: success = 1
if regFailed.search(output) is not None: success = 1
if regError.search(output) is not None: success = 1

# Recupere le CPU time
if mySystem == 'mingw' or mySystem == 'windows':
Expand Down Expand Up @@ -689,11 +689,11 @@ def runSingleUnitaryTest(no, module, test):
os.killpg(os.getpgid(PROCESS.pid), signal.SIGKILL)
os.kill(PROCESS.pid, signal.SIGKILL)
print('\nError: process TIMED OUT (killed).')
success = 0; CPUtime = 'Unknown'; coverage='0%' # Core dump/error
success = 3; CPUtime = 'Unknown'; coverage='0%'

except Exception as e:
print(e)
success = 0; CPUtime = 'Unknown'; coverage='0%' # Core dump/error
success = 1; CPUtime = 'Unknown'; coverage='0%' # Core dump/error

# update le fichier .time (si non present)
fileTime = '%s/%s/%s/%s/%s.time'%(MODULESDIR['LOCAL'][module], module, 'test', DATA, testr[0])
Expand All @@ -708,8 +708,9 @@ def runSingleUnitaryTest(no, module, test):
tag = readStar(fileStar)

# update status
if success == 1: status = 'OK'
elif success == 2: status = 'FAILEDMEM'
if success == 0: status = 'OK'
elif success == 2: status = 'MEMLEAK'
elif success == 3: status = 'TIMEOUT'
else: status = 'FAILED'
s = buildString(module, test, CPUtime, coverage, status, tag)
regTest = re.compile(' '+test+' ')
Expand Down Expand Up @@ -766,11 +767,11 @@ def runSingleCFDTest(no, module, test):
print(output)

# Recupere success/failed
success = 1
success = 0
if regLeakError.search(output) is not None: success = 2 # always check first
if regDiff.search(output) is not None: success = 0
if regFailed.search(output) is not None: success = 0
if regError.search(output) is not None: success = 0
if regDiff.search(output) is not None: success = 1
if regFailed.search(output) is not None: success = 1
if regError.search(output) is not None: success = 1

# Recupere le CPU time
if mySystem == 'mingw' or mySystem == 'windows':
Expand All @@ -791,11 +792,11 @@ def runSingleCFDTest(no, module, test):
os.killpg(os.getpgid(PROCESS.pid), signal.SIGKILL)
os.kill(PROCESS.pid, signal.SIGKILL)
print('\nError: process TIMED OUT (killed).')
success = 0; CPUtime = 'Unknown'; coverage='0%' # Core dump/error
success = 3; CPUtime = 'Unknown'; coverage='0%'

except Exception as e:
print(e)
success = 0; CPUtime = 'Unknown'; coverage='0%' # Core dump/error
success = 1; CPUtime = 'Unknown'; coverage='0%' # Core dump/error

# update le fichier .time (si non present)
fileTime = '%s/%s/%s.time'%(path, DATA, test)
Expand All @@ -810,8 +811,9 @@ def runSingleCFDTest(no, module, test):
tag = readStar(fileStar)

# update status
if success == 1: status = 'OK'
elif success == 2: status = 'FAILEDMEM'
if success == 0: status = 'OK'
elif success == 2: status = 'MEMLEAK'
elif success == 3: status = 'TIMEOUT'
else: status = 'FAILED'
s = buildString(module, test, CPUtime, coverage, status, tag)
regTest = re.compile(' '+test+' ')
Expand Down Expand Up @@ -992,7 +994,7 @@ def buildTestList(loadSession=False, modules=[]):
if testArr.size:
# Args are CPU time, Coverage, Status, and Tag if present
if ncolumns == 8:
if testArr[0][6].strip() in ['OK', 'FAILED', 'FAILEDMEM', '...']:
if testArr[0][6].strip() in ['OK', 'FAILED', 'MEMLEAK', 'TIMEOUT', '...']:
args = testArr[0][[2,5,6,7]]
else: args = testArr[0][[2,5,7,6]]
else: args = testArr[0][[2,5,6]]
Expand Down Expand Up @@ -1036,15 +1038,15 @@ def _substituteCustomFilters(filters):
if filtr[0] == '!':
if tmpFiltr == 'SEQ': outFilters.add('&m.$')
elif tmpFiltr == 'DIST': outFilters.add('&t.$')
elif tmpFiltr == 'RUN': outFilters.update(['&/!FAILED', '&/!FAILEDMEM', '&/!OK'])
elif tmpFiltr == 'UNRUN': outFilters.update(['/FAILED', '/FAILEDMEM', '/OK'])
elif tmpFiltr == 'RUN': outFilters.update(['&/!FAILED', '&/!MEMLEAK', '&/!TIMEOUT', '&/!OK'])
elif tmpFiltr == 'UNRUN': outFilters.update(['/FAILED', '/MEMLEAK', '/TIMEOUT', '/OK'])
elif tmpFiltr == 'TAG': outFilters.add(r'@^(?![\*,r,g,b])')
elif tmpFiltr == 'UNTAG': outFilters.add(r'@[\*,r,g,b]')
else:
if tmpFiltr == 'SEQ': outFilters.add('&t.$')
elif tmpFiltr == 'DIST': outFilters.add('&m.$')
elif tmpFiltr == 'RUN': outFilters.update(['/FAILED', '/FAILEDMEM', '/OK'])
elif tmpFiltr == 'UNRUN': outFilters.update(['&/!FAILED', '&/!FAILEDMEM', '&/!OK'])
elif tmpFiltr == 'RUN': outFilters.update(['/FAILED', '/MEMLEAK', '/TIMEOUT', '/OK'])
elif tmpFiltr == 'UNRUN': outFilters.update(['&/!FAILED', '&/!MEMLEAK', '&/!TIMEOUT', '&/!OK'])
elif tmpFiltr == 'TAG': outFilters.add(r'@[\*,r,g,b]')
elif tmpFiltr == 'UNTAG': outFilters.add(r'@^(?![\*,r,g,b])')
else: outFilters.add(filtr)
Expand Down Expand Up @@ -1145,7 +1147,7 @@ def selectAll(event=None):
displayProgress(0, total, remaining, 0.)

#==============================================================================
# Affiche les test FAILED ou FAILEDMEM dans la listbox
# Affiche les test FAILED ou MEMLEAK dans la listbox
#==============================================================================
def showFilter(filter='FAILED'):
Listbox.delete(0, 'end')
Expand Down Expand Up @@ -1724,8 +1726,10 @@ def updateASANLabel(entry_index):
#fileTab.add_command(label='Notify Ready for commit', command=notifyValidOK)
fileTab.add_command(label='Quit', command=Quit, accelerator='Ctrl+Q')
viewTab.add_command(label='Show FAILED', command=showFilter)
showFilterWithArgs = partial(showFilter, "FAILEDMEM")
viewTab.add_command(label='Show FAILEDMEM', command=showFilterWithArgs)
viewTab.add_command(label='Show MEMLEAK',
command=partial(showFilter, "MEMLEAK"))
viewTab.add_command(label='Show TIMEOUT',
command=partial(showFilter, "TIMEOUT"))
viewTab.add_command(label='Show ALL tests', command=showAll)
viewTab.add_separator()
viewTab.add_command(label='Show run cases', command=showRunCases)
Expand Down Expand Up @@ -1799,7 +1803,7 @@ def updateASANLabel(entry_index):
filterInfoBulle = 'Filter test database using a regexp.\n'+'-'*70+'\n'\
'1) White-spaced: ^cylinder ^sphere\n'\
'2) Module filter using #: #Apps #Fast #FF or simply #[A,F] \n'\
'3) Status filter using /: /FAILED /FAILEDMEM or simply /F\n'\
'3) Status filter using /: /FAILED /MEMLEAK or simply /F\n'\
'4) Coverage filter using %: %100\n'\
'5) Tag symbol filter using @: @r to catch red-coloured cases\n'\
'6) Keyworded filters: <SEQ>, <DIST>, <RUN>, <UNRUN>, <TAG>, <UNTAG>.\n'\
Expand Down
80 changes: 55 additions & 25 deletions Cassiopee/Converter/Converter/Adapter/diffIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
along with Cassiopee. If not, see <http://www.gnu.org/licenses/>.
*/
# include "converter.h"
# include <algorithm>

using namespace K_FLD;
#include <algorithm>


//=============================================================================
/* Make the difference between two index numpy arrays
On suppose que B est un sous ensemble de A
Retourne les indices de A qui ne sont pas dans B
NB: Si B contient des indices qui ne sont pas dans A, affiche un warning mais
calcule quand meme la difference
Attention: l'ordre des indices dans A et B est modifie
*/
//=============================================================================
Expand All @@ -49,6 +53,7 @@ PyObject* K_CONVERTER::diffIndex(PyObject* self, PyObject* args)
{
PyErr_SetString(PyExc_TypeError,
"diffIndex: arrayB numpy is invalid.");
RELEASESHAREDN(arrayA, indexA);
return NULL;
}

Expand All @@ -58,50 +63,75 @@ PyObject* K_CONVERTER::diffIndex(PyObject* self, PyObject* args)
E_Int nd = sizeA-sizeB;
E_Int* posA = indexA->begin();
E_Int* posB = indexB->begin();
//printf("diffindex: %d %d %d\n", sizeA, sizeB, nd);

if (sizeA == sizeB) // retourne vide?
{
PyObject* tpl = K_NUMPY::buildNumpyArray(E_Int(0), 1, 1, 1);
return tpl;
}

if (sizeB > sizeA)
if (sizeA == sizeB) // retourne vide
{
printf("Warning: diffIndex: listB is not included in listA.");
PyObject* tpl = K_NUMPY::buildNumpyArray(E_Int(0), 1, 1, 1);
RELEASESHAREDN(arrayA, indexA);
RELEASESHAREDN(arrayB, indexB);
return tpl;
}

if (sizeB == 0) // retourne une copie de sizeA
{
PyObject* tpl = K_NUMPY::buildNumpyArray(sizeA, 1, 1, 1);
E_Int* pos = K_NUMPY::getNumpyPtrI(tpl);
#pragma omp parallel for if (sizeA > __MIN_SIZE_MEAN__)
for (E_Int i = 0; i < sizeA; i++) pos[i] = posA[i];
RELEASESHAREDN(arrayA, indexA);
RELEASESHAREDN(arrayB, indexB);
return tpl;
}

}

if (sizeB > sizeA)
{
printf("Warning: diffIndex: listB is not included in listA.");
PyObject* tpl = K_NUMPY::buildNumpyArray(E_Int(0), 1, 1, 1);
RELEASESHAREDN(arrayA, indexA);
RELEASESHAREDN(arrayB, indexB);
return tpl;
}

// Il faut deja trier A et B
std::sort(posA, posA+sizeA);
std::sort(posB, posB+sizeB);

E_Bool isSubset = std::includes(posA, posA+sizeA, posB, posB+sizeB);
if (not isSubset)
{
printf("Warning: diffIndex: listB is not a subset of listA - proceed anyway");
// On retourne les indices de A qui ne sont pas dans B meme si B
// contient des indices qui ne sont pas dans A
/*std::cout << "sizes: " << sizeA << ", " << sizeB << std::endl;
for (E_Int i = 0; i < sizeA; i++) std::cout << " " << posA[i];
std::cout << "\ndone A\n" << std::endl;
for (E_Int i = 0; i < sizeB; i++) std::cout << " " << posB[i];
std::cout << "\ndone B\n" << std::endl;*/

std::vector<E_Int> subset(sizeA); // alloue initialement a la taille max, ie, sizeA
auto iter = std::set_difference(posA, posA+sizeA, posB, posB+sizeB, subset.begin());
nd = iter - subset.begin(); // corrige la taille du subset
//std::cout << "nd: " << nd << std::endl;

PyObject* tpl = K_NUMPY::buildNumpyArray(nd, 1, 1, 1);
E_Int* pos = K_NUMPY::getNumpyPtrI(tpl);
#pragma omp parallel for if (nd > __MIN_SIZE_MEAN__)
for (E_Int i = 0; i < nd; i++) pos[i] = subset[i];

/*for (E_Int i = 0; i < nd; i++) std::cout << " " << pos[i];
std::cout << "\ndone subset\n" << std::endl;*/

RELEASESHAREDN(arrayA, indexA);
RELEASESHAREDN(arrayB, indexB);
return tpl;
}

PyObject* tpl = K_NUMPY::buildNumpyArray(nd, 1, 1, 1);
E_Int* pos = K_NUMPY::getNumpyPtrI(tpl);

/*
bool isIncluded = std::includes(indexA->begin(), indexA->begin()+sizeA,
indexB->begin(), indexB->begin()+sizeB);
if (not isIncluded) printf("not included\n"); */
std::set_difference(posA, posA+sizeA,
posB, posB+sizeB,
pos);

/*
for (E_Int i = 0; i < nd; i++) printf("%d\n", pos[i]);
printf("done\n");
*/
std::set_difference(posA, posA+sizeA, posB, posB+sizeB, pos);

RELEASESHAREDN(arrayA, indexA);
RELEASESHAREDN(arrayB, indexB);

return tpl;
}
3 changes: 3 additions & 0 deletions Cassiopee/Envs/sh_Cassiopee_local
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,9 @@ elif [ "$MAC" = "juno_coda" ]; then
module load subversion/1.14.1-gnu831
export PYTHONEXE=python3
export PRODMODE=1
export ASAN_OPTIONS=verify_asan_link_order=false
export LSAN_OPTIONS=suppressions=$CASSIOPEE/Dist/bin/"$ELSAPROD"/asan.supp:print_suppressions=0
export ASAN_LIB=/opt/tools/gcc/10.2.0-gnu831/lib64/libasan.so

elif [ "$MAC" = "sator_brw" ]; then
#----------------------------- sator for broadwell -----------------------------------------
Expand Down
6 changes: 3 additions & 3 deletions Cassiopee/Geom/Geom/getCurvatureRadius.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@ PyObject* K_GEOM::getCurvatureRadius(PyObject* self, PyObject* args)
for (E_Int i = 0; i < npts; i++)
{
c = curv[i];
if ( K_FUNC::fEqualZero(c) == true && c >= 0)
if ( K_FUNC::fEqualZero(c) && c >= 0)
rad[i] = K_CONST::E_MAX_FLOAT;
else if ( K_FUNC::fEqualZero(c) == true && c <= 0)
else if ( K_FUNC::fEqualZero(c) && c <= 0)
rad[i] = -K_CONST::E_MAX_FLOAT;
else rad[i] = 1./c;
}
PyObject* tpl = K_ARRAY::buildArray(rad, "radius", npts, 1, 1);
delete &rad;
delete f; delete radp;
return tpl;
}
8 changes: 5 additions & 3 deletions Cassiopee/Geom/Geom/getUV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ PyObject* K_GEOM::getUV(PyObject* self, PyObject* args)
if (error != xatlas::AddMeshError::Success)
{
xatlas::Destroy(atlas);
delete [] coords;
RELEASESHAREDB(res, array, f, cn);
PyErr_SetString(PyExc_TypeError,
"getUV: can not create atlas.");
Expand Down Expand Up @@ -486,6 +487,7 @@ PyObject* K_GEOM::getUV(PyObject* self, PyObject* args)
}

// cleanup
delete [] coords;
delete [] connect;
delete [] fvc;

Expand Down Expand Up @@ -545,7 +547,7 @@ PyObject* K_GEOM::getUV(PyObject* self, PyObject* args)
}

PyObject* tpl = PyList_New(0);
PyList_Append(tpl, o); Py_DECREF(o);
PyList_Append(tpl, o); RELEASESHAREDU(o, fo, cno);

if (atlas->width <= 0 || atlas->height <= 0) return tpl;

Expand Down Expand Up @@ -757,7 +759,7 @@ PyObject* K_GEOM::getUV(PyObject* self, PyObject* args)
pg[ind] = imageData[3*ind+1];
pb[ind] = imageData[3*ind+2];
}
PyList_Append(tpl, o); Py_DECREF(o);
PyList_Append(tpl, o); RELEASESHAREDS(o, fo);
}

// Export images as a cartesian zone
Expand All @@ -784,7 +786,7 @@ PyObject* K_GEOM::getUV(PyObject* self, PyObject* args)
pg[ind] = imageData[3*ind+1];
pb[ind] = imageData[3*ind+2];
}
PyList_Append(tpl, o); Py_DECREF(o);
PyList_Append(tpl, o); RELEASESHAREDS(o, fo);
}

// End
Expand Down
4 changes: 2 additions & 2 deletions Cassiopee/Geom/Geom/lineGenerate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ PyObject* K_GEOM::lineGenerateMesh(PyObject* self, PyObject* args)
posx2 == -1 || posy2 == -1 || posz2 == -1)
{
PyErr_SetString(PyExc_TypeError,"lineGenerate: coordinates not found.");
delete f1; delete f2; delete cn2; return NULL;
delete f2; delete f1; delete cn1; return NULL;
}
posx1++; posy1++; posz1++;
posx2++; posy2++; posz2++;
Expand Down Expand Up @@ -331,7 +331,7 @@ PyObject* K_GEOM::lineGenerateMesh(PyObject* self, PyObject* args)
}
}

delete f1; delete f2;
delete f2; delete f1; delete cn1;
PyObject* tpl = K_ARRAY::buildArray(*coord, varString1,
*connect, -1, eltType);
delete coord; delete connect;
Expand Down
5 changes: 3 additions & 2 deletions Cassiopee/Intersector/PolyMeshTools/adaptCells.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ PyObject* K_INTERSECTOR::initForAdaptCells(PyObject* self, PyObject* args)
if (err)
{
std::cout << "adaptCells_mpi : input is not a dictionary" << std::endl;
delete f; delete cn;
return nullptr;
}

Expand All @@ -102,7 +103,7 @@ PyObject* K_INTERSECTOR::initForAdaptCells(PyObject* self, PyObject* args)
DELAUNAY::Triangulator dt;
bool has_been_reversed;
err = ngon_type::reorient_skins(dt, crd, ngi, has_been_reversed); //orientate normal outwards
if (err) return nullptr;
if (err) { delete f; delete cn; return nullptr; }

for (auto& transfo_map : transfo_to_list) //loop over each transformation (match, transla, rota, etc)
{
Expand Down Expand Up @@ -157,7 +158,7 @@ PyObject* K_INTERSECTOR::initForAdaptCells(PyObject* self, PyObject* args)
ngi.export_to_array(ng_arr);

PyObject* m = K_ARRAY::buildArray(crd, varString, ng_arr, 8, "NGON", false);

delete f; delete cn;
return m;
}

Expand Down
Loading

0 comments on commit 7cab9bf

Please sign in to comment.