// Copyright (c) 2010-2023, 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. #ifndef MFEM_OCCA_HPP #define MFEM_OCCA_HPP #include "../config/config.hpp" #ifdef MFEM_USE_OCCA #include "mem_manager.hpp" #include "device.hpp" #include namespace mfem { /// Return the default occa::device used by MFEM. occa::device &OccaDev(); /// Wrap a pointer as occa::memory with the default occa::device used by MFEM. /** It is assumed that @a ptr is suitable for use with the current mfem::Device configuration. */ occa::memory OccaMemoryWrap(void *ptr, std::size_t bytes); /** @brief Wrap a Memory object as occa::memory for read only access with the mfem::Device MemoryClass. The returned occa::memory is associated with the default occa::device used by MFEM. */ template const occa::memory OccaMemoryRead(const Memory &mem, size_t size) { mem.UseDevice(true); const void *ptr = mem.Read(Device::GetDeviceMemoryClass(), size); return OccaMemoryWrap(const_cast(ptr), size*sizeof(T)); } /** @brief Wrap a Memory object as occa::memory for write only access with the mfem::Device MemoryClass. The returned occa::memory is associated with the default occa::device used by MFEM. */ template occa::memory OccaMemoryWrite(Memory &mem, size_t size) { mem.UseDevice(true); return OccaMemoryWrap(mem.Write(Device::GetDeviceMemoryClass(), size), size*sizeof(T)); } /** @brief Wrap a Memory object as occa::memory for read-write access with the mfem::Device MemoryClass. The returned occa::memory is associated with the default occa::device used by MFEM. */ template occa::memory OccaMemoryReadWrite(Memory &mem, size_t size) { mem.UseDevice(true); return OccaMemoryWrap(mem.ReadWrite(Device::GetDeviceMemoryClass(), size), size*sizeof(T)); } /** @brief Function that determines if an OCCA kernel should be used, based on the current mfem::Device configuration. */ inline bool DeviceCanUseOcca() { return Device::Allows(Backend::OCCA_CUDA) || (Device::Allows(Backend::OCCA_OMP) && !Device::Allows(Backend::DEVICE_MASK)) || (Device::Allows(Backend::OCCA_CPU) && !Device::Allows(Backend::DEVICE_MASK|Backend::OMP_MASK)); } typedef std::pair occa_id_t; typedef std::map occa_kernel_t; } // namespace mfem #endif // MFEM_USE_OCCA #endif // MFEM_OCCA_HPP