diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 57d3622c8e..df346c359c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,6 +24,7 @@ variables: stages: - src - tpl + - asan - examples - benchmarks - comparison @@ -35,6 +36,7 @@ stages: rules: - if: $SMITH_CI_WORKFLOW_TYPE != "examples" && $SMITH_CI_WORKFLOW_TYPE != "tpl" && + $SMITH_CI_WORKFLOW_TYPE != "asan" && $SMITH_CI_WORKFLOW_TYPE != "benchmarks" && $SMITH_CI_WORKFLOW_TYPE != "comparison" @@ -50,6 +52,12 @@ stages: rules: - if: $SMITH_CI_WORKFLOW_TYPE == "tpl" +# Run asan build as a nightly scheduled pipeline +.asan_workflow: + stage: asan + rules: + - if: $SMITH_CI_WORKFLOW_TYPE == "asan" + # Run benchmarks build as a weekly scheduled pipeline # or, run benchmarks and save them in tmp location for comparison .benchmarks_workflow: diff --git a/.gitlab/build_toss4.yml b/.gitlab/build_toss4.yml index e0985a2042..8394c698fa 100644 --- a/.gitlab/build_toss4.yml +++ b/.gitlab/build_toss4.yml @@ -21,6 +21,10 @@ .src_build_on_toss4: extends: [.src_build_script, .on_toss4, .src_workflow] +# NOTE: the asan build is just a src build with a different pipeline schedule, so re-use src build script. +.asan_build_on_toss4: + extends: [.src_build_script, .on_toss4, .asan_workflow] + .examples_build_on_toss4: extends: [.examples_build_script, .on_toss4, .examples_workflow] @@ -88,6 +92,16 @@ toss4-gcc_13_3_1-src-no-optional-solvers: ALLOC_TIME: "30" extends: .src_build_on_toss4 +toss4-llvm_19_1_3-src-asan: + variables: + COMPILER: "llvm@19.1.3" + HOST_CONFIG: "dane-toss_4_x86_64_ib-${COMPILER}.cmake" + EXTRA_CMAKE_OPTIONS: "-DENABLE_DOCS=OFF -DCMAKE_BUILD_TYPE=Debug -DENABLE_ASAN=ON" + LSAN_OPTIONS: "suppressions=${CI_PROJECT_DIR}/suppressions.asan" + ALLOC_NODES: "1" + ALLOC_TIME: "30" + extends: .asan_build_on_toss4 + toss4-llvm_19_1_3-tpl: variables: COMPILER: "llvm@19.1.3" diff --git a/scripts/spack/spack_repo/smith/packages/smith/package.py b/scripts/spack/spack_repo/smith/packages/smith/package.py index 9cbb4c2b1e..3492d05e2e 100644 --- a/scripts/spack/spack_repo/smith/packages/smith/package.py +++ b/scripts/spack/spack_repo/smith/packages/smith/package.py @@ -467,7 +467,7 @@ def initconfig_hardware_entries(self): hip_link_flags += "-lompstub " if spec.satisfies("^hipblas"): - hip_link_flags += "-lhipblas" + hip_link_flags += "-lhipblas " entries.append(cmake_cache_string("CMAKE_EXE_LINKER_FLAGS", hip_link_flags)) diff --git a/src/docs/sphinx/dev_guide/memory_checking.rst b/src/docs/sphinx/dev_guide/memory_checking.rst index b1ff36359e..a26c140a8e 100644 --- a/src/docs/sphinx/dev_guide/memory_checking.rst +++ b/src/docs/sphinx/dev_guide/memory_checking.rst @@ -52,7 +52,7 @@ Helpful options: * ``fast_unwind_on_malloc=0``: This improves Asan's stack tracing ability but also greatly slows down the run - * ``exitcode=0``: This stops Asan from returning a a non-zero exit code from your executable + * ``exitcode=0``: This stops Asan from returning a non-zero exit code from your executable (defaults to 23) (``LSAN_OPTIONS``) diff --git a/src/smith/mesh_utils/mesh_utils.cpp b/src/smith/mesh_utils/mesh_utils.cpp index 6fc441045b..d757cbf1cd 100644 --- a/src/smith/mesh_utils/mesh_utils.cpp +++ b/src/smith/mesh_utils/mesh_utils.cpp @@ -240,7 +240,10 @@ mfem::Mesh buildCylinderMesh(int radial_refinement, int elements_lengthwise, dou mesh.SetVertices(new_vertices); } - return mfem::Mesh(*mfem::Extrude2D(&mesh, elements_lengthwise, height)); + mfem::Mesh* extruded_ptr = mfem::Extrude2D(&mesh, elements_lengthwise, height); + mfem::Mesh extruded_obj(*extruded_ptr); + delete extruded_ptr; + return extruded_obj; } /// @brief Constructs a 2D MFEM mesh of a ring @@ -357,7 +360,10 @@ mfem::Mesh buildHollowCylinderMesh(int radial_refinement, int elements_lengthwis double outer_radius, double height, double total_angle, int sectors) { auto mesh = buildRing(radial_refinement, inner_radius, outer_radius, total_angle, sectors); - return mfem::Mesh(*mfem::Extrude2D(&mesh, elements_lengthwise, height)); + mfem::Mesh* extruded_ptr = mfem::Extrude2D(&mesh, elements_lengthwise, height); + mfem::Mesh extruded_obj(*extruded_ptr); + delete extruded_ptr; + return extruded_obj; } /// @brief Constructs an MFEM mesh of a hollow cylinder restricted to the first orthant diff --git a/src/smith/mesh_utils/mesh_utils_base.hpp b/src/smith/mesh_utils/mesh_utils_base.hpp index 9417d0c28e..b3462dc837 100644 --- a/src/smith/mesh_utils/mesh_utils_base.hpp +++ b/src/smith/mesh_utils/mesh_utils_base.hpp @@ -103,7 +103,7 @@ mfem::Mesh buildCylinderMesh(int radial_refinement, int elements_lengthwise, dou * @param[in] total_angle the angle in radians over which to generate the portion of an extruded cylinder * @param[in] sectors the number of starting sectors in the hollow cylinder * - * @return A unique_ptr containing the constructed mesh + * @return The constructed mesh */ mfem::Mesh buildHollowCylinderMesh(int radial_refinement, int elements_lengthwise, double inner_radius, double outer_radius, double height, double total_angle = M_PI, int sectors = 8); diff --git a/src/smith/numerics/functional/tests/domain_tests.cpp b/src/smith/numerics/functional/tests/domain_tests.cpp index 3ff6392d18..67435ad2fa 100644 --- a/src/smith/numerics/functional/tests/domain_tests.cpp +++ b/src/smith/numerics/functional/tests/domain_tests.cpp @@ -97,7 +97,6 @@ TEST(domain, of_edges) { constexpr int dim = 2; auto bmesh = import_mesh("beam-quad.mesh"); - bmesh.FinalizeQuadMesh(true); auto mesh = smith::mesh::refineAndDistribute(std::move(bmesh)); Domain d0 = Domain::ofEdges(*mesh, std::function([](std::vector x, int /* bdr_attr */) { return (0.5 * (x[0][0] + x[1][0])) < 0.25; // x coordinate of edge midpoint diff --git a/src/smith/numerics/petsc_solvers.cpp b/src/smith/numerics/petsc_solvers.cpp index cb875315ab..45c7307f99 100644 --- a/src/smith/numerics/petsc_solvers.cpp +++ b/src/smith/numerics/petsc_solvers.cpp @@ -306,6 +306,7 @@ void PetscPCSolver::SetOperator(const mfem::Operator& op) PetscCallAbort(GetComm(), MatCreateVecs(A22, &zero, nullptr)); PetscCallAbort(GetComm(), VecSet(zero, 0)); PetscCallAbort(GetComm(), MatDiagonalSet(A22, zero, ADD_VALUES)); + PetscCallAbort(GetComm(), VecDestroy(&zero)); if (delete_pA) { delete pA; } @@ -666,6 +667,23 @@ PetscKSPSolver::PetscKSPSolver(const mfem::HypreParMatrix& A, KSPType ksp_type, Customize(); } +PetscKSPSolver::~PetscKSPSolver() +{ + if (pA_) { + delete pA_; + } + if (X) { + delete X; + } + if (B) { + delete B; + } + + pA_ = nullptr; + X = nullptr; + B = nullptr; +} + void PetscKSPSolver::SetTolerances() { PetscCallAbort(GetComm(), KSPSetTolerances(*this, rel_tol, abs_tol, PETSC_DEFAULT, max_iter)); diff --git a/src/smith/numerics/petsc_solvers.hpp b/src/smith/numerics/petsc_solvers.hpp index 20092560a5..c26d58dc49 100644 --- a/src/smith/numerics/petsc_solvers.hpp +++ b/src/smith/numerics/petsc_solvers.hpp @@ -327,6 +327,12 @@ class PetscKSPSolver : virtual public mfem::IterativeSolver, public mfem::PetscL PetscKSPSolver(const mfem::HypreParMatrix& A, KSPType ksp_type = KSPCG, const std::string& prefix = std::string(), bool wrap = false, bool iter_mode = false); + /** + * @brief Cleanup extra petsc variables (pa_, B, X) + * + */ + ~PetscKSPSolver(); + /** * @brief Get the MPI communicator * @return The MPI communicator used by the vectors and matrices in the solve diff --git a/src/smith/numerics/tests/CMakeLists.txt b/src/smith/numerics/tests/CMakeLists.txt index deaf3a1105..10e693b21a 100644 --- a/src/smith/numerics/tests/CMakeLists.txt +++ b/src/smith/numerics/tests/CMakeLists.txt @@ -7,9 +7,9 @@ set(numerics_test_dependencies smith_numerics smith_boundary_conditions gtest) set(numerics_serial_test_sources - equationsolver.cpp - operator.cpp - odes.cpp + test_equationsolver.cpp + test_operator.cpp + test_odes.cpp test_block_preconditioner.cpp test_block_preconditioner_backend.cpp test_block_preconditioner_custom_operators.cpp @@ -21,7 +21,7 @@ smith_add_tests( SOURCES ${numerics_serial_test_sources} if(PETSC_FOUND) set(petsc_solver_tests - equationsolver_petsc.cpp + test_equationsolver_petsc.cpp ) smith_add_tests(SOURCES ${petsc_solver_tests} DEPENDS_ON ${numerics_test_dependencies} @@ -29,7 +29,7 @@ if(PETSC_FOUND) if(SLEPC_FOUND) set(slepc_solver_tests - eigensolver.cpp + test_eigensolver.cpp test_trust_region_solver.cpp ) smith_add_tests(SOURCES ${slepc_solver_tests} diff --git a/src/smith/numerics/tests/eigensolver.cpp b/src/smith/numerics/tests/test_eigensolver.cpp similarity index 100% rename from src/smith/numerics/tests/eigensolver.cpp rename to src/smith/numerics/tests/test_eigensolver.cpp diff --git a/src/smith/numerics/tests/equationsolver.cpp b/src/smith/numerics/tests/test_equationsolver.cpp similarity index 100% rename from src/smith/numerics/tests/equationsolver.cpp rename to src/smith/numerics/tests/test_equationsolver.cpp diff --git a/src/smith/numerics/tests/equationsolver_petsc.cpp b/src/smith/numerics/tests/test_equationsolver_petsc.cpp similarity index 100% rename from src/smith/numerics/tests/equationsolver_petsc.cpp rename to src/smith/numerics/tests/test_equationsolver_petsc.cpp diff --git a/src/smith/numerics/tests/odes.cpp b/src/smith/numerics/tests/test_odes.cpp similarity index 100% rename from src/smith/numerics/tests/odes.cpp rename to src/smith/numerics/tests/test_odes.cpp diff --git a/src/smith/numerics/tests/operator.cpp b/src/smith/numerics/tests/test_operator.cpp similarity index 100% rename from src/smith/numerics/tests/operator.cpp rename to src/smith/numerics/tests/test_operator.cpp diff --git a/suppressions.asan b/suppressions.asan index 227385f139..47bd8acc95 100644 --- a/suppressions.asan +++ b/suppressions.asan @@ -1,2 +1,3 @@ # Library that isn't built by us leak:libpsm2.so.2 +leak:MPIU_Find_local_and_external