Files
mfem/linalg/batched/batched.cpp
T

123 lines
3.1 KiB
C++

// 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<int> &P)
{
Get(Instance().active_backend).LUFactor(A, P);
}
void BatchedLinAlg::LUSolve(const DenseTensor &A, const Array<int> &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);
}
}