Last active
March 5, 2018 19:59
-
-
Save guyer/f4ea5a0443d7bb25c18348661b4634d3 to your computer and use it in GitHub Desktop.
PyTrilnos script that demonstrates memory leak even after calling `del`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! ${PYTHON_EXECUTABLE} | |
# -*- python -*- | |
# @HEADER | |
# *********************************************************************** | |
# | |
# PyTrilinos: Python Interfaces to Trilinos Packages | |
# Copyright (2014) Sandia Corporation | |
# | |
# Under the terms of Contract DE-AC04-94AL85000 with Sandia | |
# Corporation, the U.S. Government retains certain rights in this | |
# software. | |
# | |
# Redistribution and use in source and binary forms, with or without | |
# modification, are permitted provided that the following conditions are | |
# met: | |
# | |
# 1. Redistributions of source code must retain the above copyright | |
# notice, this list of conditions and the following disclaimer. | |
# | |
# 2. Redistributions in binary form must reproduce the above copyright | |
# notice, this list of conditions and the following disclaimer in the | |
# documentation and/or other materials provided with the distribution. | |
# | |
# 3. Neither the name of the Corporation nor the names of the | |
# contributors may be used to endorse or promote products derived from | |
# this software without specific prior written permission. | |
# | |
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY | |
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE | |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
# | |
# Questions? Contact William F. Spotz ([email protected]) | |
# | |
# *********************************************************************** | |
# @HEADER | |
# | |
# System imports | |
from __future__ import print_function | |
from optparse import * | |
import sys | |
# | |
# Parse the command-line arguments | |
parser = OptionParser() | |
parser.add_option("-t", "--testharness", action="store_true", | |
dest="testharness", default=False, | |
help="test local build modules; prevent loading system-installed modules") | |
parser.add_option("-v", "--verbosity", type="int", dest="verbosity", default=2, | |
help="set the verbosity level [default 2]") | |
options,args = parser.parse_args() | |
# | |
# Under normal usage, simply use 'from PyTrilinos import Epetra'. For testing, | |
# we want to be able to control whether we import from the build directory or | |
# from a system-installed version of PyTrilinos. | |
# from testutil import fromPyTrilinosImport | |
# Epetra = fromPyTrilinosImport('Epetra' , options.testharness) | |
# Galeri = fromPyTrilinosImport('Galeri' , options.testharness) | |
# AztecOO = fromPyTrilinosImport('AztecOO', options.testharness) | |
from PyTrilinos import Epetra | |
from PyTrilinos import Galeri | |
from PyTrilinos import AztecOO | |
# Main routine, takes a communicator and a solution tolerance | |
from memory_profiler import profile | |
# fs = open("memory_main.log", "a+") | |
# @profile(stream=fs) | |
def main(comm, tol): | |
# Obtain the example matrix from Galeri | |
nx = 300 | |
ny = 300 | |
galeriList = {"n": nx * ny, # for Linear map | |
"nx": nx, # for Laplace2D, which requires nx | |
"ny": ny # and ny | |
} | |
map = Galeri.CreateMap("Linear", comm, galeriList) | |
matrix = Galeri.CreateCrsMatrix("Laplace2D", map, galeriList) | |
# Allocate and initialize the solution and RHS vector | |
exact = Epetra.Vector(map) | |
x = Epetra.Vector(map) | |
b = Epetra.Vector(map) | |
exact.Random() # Fix exact solution | |
x.PutScalar(0.0) # Fix starting guess for solution | |
matrix.Multiply(False, exact, b) # Fix rhs corresponding to exact | |
# Build the solver object | |
if 0: | |
# this does not work on most installations | |
problem = Epetra.LinearProblem(matrix, x, b) | |
solver = AztecOO.AztecOO(problem) | |
else: | |
solver = AztecOO.AztecOO(matrix, x, b) | |
# Set the solver parameters | |
try: | |
plist = {"Solver" : "CG", | |
"Precond" : "Dom_Decomp", | |
"Subdomain_Solve" : "ICC", | |
"Output" : 0 | |
} | |
solver.SetParameters(plist,True) | |
except AttributeError: | |
# If AztecOO and its python wrappers have been compiled without Teuchos | |
# support, then then the SetParameters method will not exist, thus raising | |
# an AttributeError exception | |
print("Teuchos ParameterLists not supported") | |
solver.SetAztecOption(AztecOO.AZ_solver, AztecOO.AZ_cg) | |
solver.SetAztecOption(AztecOO.AZ_precond, AztecOO.AZ_dom_decomp) | |
solver.SetAztecOption(AztecOO.AZ_subdomain_solve, AztecOO.AZ_icc) | |
solver.SetAztecOption(AztecOO.AZ_output, 16) | |
# Solve the system | |
solver.Iterate(galeriList["n"], tol) | |
# Compute and return the solution error | |
error = Epetra.Vector(map, (x - exact)) | |
del map | |
del matrix | |
del exact | |
del x | |
del b | |
del solver | |
return error | |
if __name__ == "__main__": | |
# Call the main routine | |
comm = Epetra.PyComm() | |
tol = 1e-5 | |
for sweep in range(50): | |
error = main(comm, tol) | |
del error | |
error = main(comm, tol) | |
# Check the results | |
myErrors = 0 | |
solnError = error.Norm2() / error.Map().NumGlobalElements() | |
if solnError > tol: | |
myErrors = 1 | |
totalErrors = comm.SumAll(myErrors) | |
# Print results message | |
if comm.MyPID() == 0: | |
print("solution error norm =", solnError) | |
if totalErrors == 0: | |
print("End Result: TEST PASSED") | |
else: | |
print("End Result: TEST FAILED") | |
# It is possible to get the following error message with this script: | |
# | |
# *** The MPI_comm_size() function was called after MPI_FINALIZE was invoked. | |
# *** This is disallowed by the MPI standard. | |
# *** Your MPI job will now abort. | |
# | |
# What this means is that the Epetra module (which calls MPI_Finalize() when | |
# deleted) is getting deleted before the Epetra map created by the TriUtils | |
# module (which lives on due to the error Vector). One workaround is to | |
# delete this Vector object before the exit process. | |
del error | |
# Exit | |
sys.exit(totalErrors) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment