13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 32f86a920SJeremy L Thompson // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 52f86a920SJeremy L Thompson // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 72f86a920SJeremy L Thompson 83d576824SJeremy L Thompson #include <ceed-impl.h> 949aac155SJeremy L Thompson #include <ceed.h> 102b730f8bSJeremy L Thompson #include <ceed/backend.h> 1149aac155SJeremy L Thompson #include <stddef.h> 122f86a920SJeremy L Thompson 132f86a920SJeremy L Thompson /// @file 147a982d89SJeremy L. Thompson /// Implementation of CeedTensorContract interfaces 157a982d89SJeremy L. Thompson 167a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 177a982d89SJeremy L. Thompson /// CeedTensorContract Backend API 187a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 197a982d89SJeremy L. Thompson /// @addtogroup CeedBasisBackend 202f86a920SJeremy L Thompson /// @{ 212f86a920SJeremy L Thompson 222f86a920SJeremy L Thompson /** 232f86a920SJeremy L Thompson @brief Create a CeedTensorContract object for a CeedBasis 242f86a920SJeremy L Thompson 25ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedTensorContract will be created 26ea61e9acSJeremy L Thompson @param[in] basis CeedBasis for which the tensor contraction will be used 27ea61e9acSJeremy L Thompson @param[out] contract Address of the variable where the newly created CeedTensorContract will be stored. 282f86a920SJeremy L Thompson 292f86a920SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 302f86a920SJeremy L Thompson 317a982d89SJeremy L. Thompson @ref Backend 322f86a920SJeremy L Thompson **/ 332b730f8bSJeremy L Thompson int CeedTensorContractCreate(Ceed ceed, CeedBasis basis, CeedTensorContract *contract) { 342f86a920SJeremy L Thompson if (!ceed->TensorContractCreate) { 352f86a920SJeremy L Thompson Ceed delegate; 36*6574a04fSJeremy L Thompson 372b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "TensorContract")); 38*6574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support TensorContractCreate"); 392b730f8bSJeremy L Thompson CeedCall(CeedTensorContractCreate(delegate, basis, contract)); 40e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 412f86a920SJeremy L Thompson } 422f86a920SJeremy L Thompson 432b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, contract)); 442f86a920SJeremy L Thompson 452f86a920SJeremy L Thompson (*contract)->ceed = ceed; 462b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 472b730f8bSJeremy L Thompson CeedCall(ceed->TensorContractCreate(basis, *contract)); 48e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 497a982d89SJeremy L. Thompson } 502f86a920SJeremy L Thompson 512f86a920SJeremy L Thompson /** 522f86a920SJeremy L Thompson @brief Apply tensor contraction 532f86a920SJeremy L Thompson 542f86a920SJeremy L Thompson Contracts on the middle index 552f86a920SJeremy L Thompson NOTRANSPOSE: v_ajc = t_jb u_abc 562f86a920SJeremy L Thompson TRANSPOSE: v_ajc = t_bj u_abc 572f86a920SJeremy L Thompson If add != 0, "=" is replaced by "+=" 582f86a920SJeremy L Thompson 59ea61e9acSJeremy L Thompson @param[in] contract CeedTensorContract to use 60ea61e9acSJeremy L Thompson @param[in] A First index of u, v 61ea61e9acSJeremy L Thompson @param[in] B Middle index of u, one index of t 62ea61e9acSJeremy L Thompson @param[in] C Last index of u, v 63ea61e9acSJeremy L Thompson @param[in] J Middle index of v, one index of t 642f86a920SJeremy L Thompson @param[in] t Tensor array to contract against 65ea61e9acSJeremy L Thompson @param[in] t_mode Transpose mode for t, \ref CEED_NOTRANSPOSE for t_jb \ref CEED_TRANSPOSE for t_bj 66ea61e9acSJeremy L Thompson @param[in] add Add mode 672f86a920SJeremy L Thompson @param[in] u Input array 682f86a920SJeremy L Thompson @param[out] v Output array 692f86a920SJeremy L Thompson 702f86a920SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 712f86a920SJeremy L Thompson 727a982d89SJeremy L. Thompson @ref Backend 732f86a920SJeremy L Thompson **/ 742b730f8bSJeremy L Thompson int CeedTensorContractApply(CeedTensorContract contract, CeedInt A, CeedInt B, CeedInt C, CeedInt J, const CeedScalar *restrict t, 752b730f8bSJeremy L Thompson CeedTransposeMode t_mode, const CeedInt add, const CeedScalar *restrict u, CeedScalar *restrict v) { 762b730f8bSJeremy L Thompson CeedCall(contract->Apply(contract, A, B, C, J, t, t_mode, add, u, v)); 77e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 787a982d89SJeremy L. Thompson } 792f86a920SJeremy L Thompson 802f86a920SJeremy L Thompson /** 81c4e3f59bSSebastian Grimberg @brief Apply tensor contraction 82c4e3f59bSSebastian Grimberg 83c4e3f59bSSebastian Grimberg Contracts on the middle index 84c4e3f59bSSebastian Grimberg NOTRANSPOSE: v_dajc = t_djb u_abc 85c4e3f59bSSebastian Grimberg TRANSPOSE: v_ajc = t_dbj u_dabc 86c4e3f59bSSebastian Grimberg If add != 0, "=" is replaced by "+=" 87c4e3f59bSSebastian Grimberg 88c4e3f59bSSebastian Grimberg @param[in] contract CeedTensorContract to use 89c4e3f59bSSebastian Grimberg @param[in] A First index of u, second index of v 90c4e3f59bSSebastian Grimberg @param[in] B Middle index of u, one of last two indices of t 91c4e3f59bSSebastian Grimberg @param[in] C Last index of u, v 92c4e3f59bSSebastian Grimberg @param[in] D First index of v, first index of t 93c4e3f59bSSebastian Grimberg @param[in] J Third index of v, one of last two indices of t 94c4e3f59bSSebastian Grimberg @param[in] t Tensor array to contract against 95c4e3f59bSSebastian Grimberg @param[in] t_mode Transpose mode for t, \ref CEED_NOTRANSPOSE for t_jb \ref CEED_TRANSPOSE for t_bj 96c4e3f59bSSebastian Grimberg @param[in] add Add mode 97c4e3f59bSSebastian Grimberg @param[in] u Input array 98c4e3f59bSSebastian Grimberg @param[out] v Output array 99c4e3f59bSSebastian Grimberg 100c4e3f59bSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 101c4e3f59bSSebastian Grimberg 102c4e3f59bSSebastian Grimberg @ref Backend 103c4e3f59bSSebastian Grimberg **/ 104c4e3f59bSSebastian Grimberg int CeedTensorContractStridedApply(CeedTensorContract contract, CeedInt A, CeedInt B, CeedInt C, CeedInt D, CeedInt J, const CeedScalar *restrict t, 105c4e3f59bSSebastian Grimberg CeedTransposeMode t_mode, const CeedInt add, const CeedScalar *restrict u, CeedScalar *restrict v) { 106c4e3f59bSSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 107c4e3f59bSSebastian Grimberg for (CeedInt d = 0; d < D; d++) { 108c4e3f59bSSebastian Grimberg CeedCall(contract->Apply(contract, A, J, C, B, t + d * B * J, t_mode, add, u + d * A * J * C, v)); 109c4e3f59bSSebastian Grimberg } 110c4e3f59bSSebastian Grimberg } else { 111c4e3f59bSSebastian Grimberg for (CeedInt d = 0; d < D; d++) { 112c4e3f59bSSebastian Grimberg CeedCall(contract->Apply(contract, A, B, C, J, t + d * B * J, t_mode, add, u, v + d * A * J * C)); 113c4e3f59bSSebastian Grimberg } 114c4e3f59bSSebastian Grimberg } 115c4e3f59bSSebastian Grimberg return CEED_ERROR_SUCCESS; 116c4e3f59bSSebastian Grimberg } 117c4e3f59bSSebastian Grimberg 118c4e3f59bSSebastian Grimberg /** 1192f86a920SJeremy L Thompson @brief Get Ceed associated with a CeedTensorContract 1202f86a920SJeremy L Thompson 121ea61e9acSJeremy L Thompson @param[in] contract CeedTensorContract 1222f86a920SJeremy L Thompson @param[out] ceed Variable to store Ceed 1232f86a920SJeremy L Thompson 1242f86a920SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1252f86a920SJeremy L Thompson 1267a982d89SJeremy L. Thompson @ref Backend 1272f86a920SJeremy L Thompson **/ 1282f86a920SJeremy L Thompson int CeedTensorContractGetCeed(CeedTensorContract contract, Ceed *ceed) { 1292f86a920SJeremy L Thompson *ceed = contract->ceed; 130e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1317a982d89SJeremy L. Thompson } 1322f86a920SJeremy L Thompson 1332f86a920SJeremy L Thompson /** 1342f86a920SJeremy L Thompson @brief Get backend data of a CeedTensorContract 1352f86a920SJeremy L Thompson 136ea61e9acSJeremy L Thompson @param[in] contract CeedTensorContract 1372f86a920SJeremy L Thompson @param[out] data Variable to store data 1382f86a920SJeremy L Thompson 1392f86a920SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1402f86a920SJeremy L Thompson 1417a982d89SJeremy L. Thompson @ref Backend 1422f86a920SJeremy L Thompson **/ 143777ff853SJeremy L Thompson int CeedTensorContractGetData(CeedTensorContract contract, void *data) { 144777ff853SJeremy L Thompson *(void **)data = contract->data; 145e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1462f86a920SJeremy L Thompson } 1472f86a920SJeremy L Thompson 1482f86a920SJeremy L Thompson /** 1492f86a920SJeremy L Thompson @brief Set backend data of a CeedTensorContract 1502f86a920SJeremy L Thompson 151ea61e9acSJeremy L Thompson @param[in,out] contract CeedTensorContract 152ea61e9acSJeremy L Thompson @param[in] data Data to set 1532f86a920SJeremy L Thompson 1542f86a920SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1552f86a920SJeremy L Thompson 1567a982d89SJeremy L. Thompson @ref Backend 1572f86a920SJeremy L Thompson **/ 158777ff853SJeremy L Thompson int CeedTensorContractSetData(CeedTensorContract contract, void *data) { 159777ff853SJeremy L Thompson contract->data = data; 160e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1612f86a920SJeremy L Thompson } 1622f86a920SJeremy L Thompson 1632f86a920SJeremy L Thompson /** 16434359f16Sjeremylt @brief Increment the reference counter for a CeedTensorContract 16534359f16Sjeremylt 166ea61e9acSJeremy L Thompson @param[in,out] contract CeedTensorContract to increment the reference counter 16734359f16Sjeremylt 16834359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 16934359f16Sjeremylt 17034359f16Sjeremylt @ref Backend 17134359f16Sjeremylt **/ 1729560d06aSjeremylt int CeedTensorContractReference(CeedTensorContract contract) { 17334359f16Sjeremylt contract->ref_count++; 17434359f16Sjeremylt return CEED_ERROR_SUCCESS; 17534359f16Sjeremylt } 17634359f16Sjeremylt 17734359f16Sjeremylt /** 1782f86a920SJeremy L Thompson @brief Destroy a CeedTensorContract 1792f86a920SJeremy L Thompson 180ea61e9acSJeremy L Thompson @param[in,out] contract CeedTensorContract to destroy 1812f86a920SJeremy L Thompson 1822f86a920SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1832f86a920SJeremy L Thompson 1847a982d89SJeremy L. Thompson @ref Backend 1852f86a920SJeremy L Thompson **/ 1862f86a920SJeremy L Thompson int CeedTensorContractDestroy(CeedTensorContract *contract) { 187ad6481ceSJeremy L Thompson if (!*contract || --(*contract)->ref_count > 0) { 188ad6481ceSJeremy L Thompson *contract = NULL; 189ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 190ad6481ceSJeremy L Thompson } 1912f86a920SJeremy L Thompson if ((*contract)->Destroy) { 1922b730f8bSJeremy L Thompson CeedCall((*contract)->Destroy(*contract)); 1932f86a920SJeremy L Thompson } 1942b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*contract)->ceed)); 1952b730f8bSJeremy L Thompson CeedCall(CeedFree(contract)); 196e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1977a982d89SJeremy L. Thompson } 1982f86a920SJeremy L Thompson 1992f86a920SJeremy L Thompson /// @} 200