// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced // at the Lawrence Livermore National Laboratory. All Rights reserved. See files // LICENSE and NOTICE for details. LLNL-CODE-806117. // // This file is part of the MFEM library. For more information and source code // availability visit https://mfem.org. // // MFEM is free software; you can redistribute it and/or modify it under the // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. #include "batched.hpp" #include "native.hpp" #include "gpu_blas.hpp" #include "magma.hpp" namespace mfem { BatchedLinAlg::BatchedLinAlg() { backends[NATIVE].reset(new NativeBatchedLinAlg); if (Device::Allows(mfem::Backend::CUDA_MASK | mfem::Backend::HIP_MASK)) { #ifdef MFEM_USE_CUDA_OR_HIP backends[GPU_BLAS].reset(new GPUBlasBatchedLinAlg); #endif #ifdef MFEM_USE_MAGMA backends[MAGMA].reset(new MagmaBatchedLinAlg); #endif #if defined(MFEM_USE_MAGMA) active_backend = MAGMA; #elif defined(MFEM_USE_CUDA_OR_HIP) active_backend = GPU_BLAS; #else active_backend = NATIVE; #endif } else { active_backend = NATIVE; } } BatchedLinAlg &BatchedLinAlg::Instance() { static BatchedLinAlg instance; return instance; } void BatchedLinAlg::AddMult(const DenseTensor &A, const Vector &x, Vector &y, real_t alpha, real_t beta, Op op) { Get(Instance().active_backend).AddMult(A, x, y, alpha, beta, op); } void BatchedLinAlg::Mult(const DenseTensor &A, const Vector &x, Vector &y) { Get(Instance().active_backend).Mult(A, x, y); } void BatchedLinAlg::MultTranspose(const DenseTensor &A, const Vector &x, Vector &y) { Get(Instance().active_backend).MultTranspose(A, x, y); } void BatchedLinAlg::Invert(DenseTensor &A) { Get(Instance().active_backend).Invert(A); } void BatchedLinAlg::LUFactor(DenseTensor &A, Array &P) { Get(Instance().active_backend).LUFactor(A, P); } void BatchedLinAlg::LUSolve(const DenseTensor &A, const Array &P, Vector &x) { Get(Instance().active_backend).LUSolve(A, P, x); } bool BatchedLinAlg::IsAvailable(BatchedLinAlg::Backend backend) { return Instance().backends[backend] != nullptr; } void BatchedLinAlg::SetActiveBackend(BatchedLinAlg::Backend backend) { MFEM_VERIFY(IsAvailable(backend), "Requested backend not supported."); Instance().active_backend = backend; } BatchedLinAlg::Backend BatchedLinAlg::GetActiveBackend() { return Instance().active_backend; } const BatchedLinAlgBase &BatchedLinAlg::Get(BatchedLinAlg::Backend backend) { auto &backend_ptr = Instance().backends[backend]; MFEM_VERIFY(backend_ptr, "Requested backend not supported.") return *backend_ptr; } void BatchedLinAlgBase::Mult(const DenseTensor &A, const Vector &x, Vector &y) const { AddMult(A, x, y, 1.0, 0.0); } void BatchedLinAlgBase::MultTranspose(const DenseTensor &A, const Vector &x, Vector &y) const { AddMult(A, x, y, 1.0, 0.0, Op::T); } }