xref: /libCEED/interface/ceed-tensor.c (revision 442e7f0bef50859918b48bfcea0f6ad2d729e89e)
1 // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3 // reserved. See files LICENSE and NOTICE for details.
4 //
5 // This file is part of CEED, a collection of benchmarks, miniapps, software
6 // libraries and APIs for efficient high-order finite element and spectral
7 // element discretizations for exascale applications. For more information and
8 // source code availability see http://github.com/ceed.
9 //
10 // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11 // a collaborative effort of two U.S. Department of Energy organizations (Office
12 // of Science and the National Nuclear Security Administration) responsible for
13 // the planning and preparation of a capable exascale ecosystem, including
14 // software, applications, hardware, advanced system engineering and early
15 // testbed platforms, in support of the nation's exascale computing imperative.
16 
17 #include <ceed-impl.h>
18 #include <ceed-backend.h>
19 
20 /// @file
21 /// Implementation of backend CeedTensorContract interfaces
22 ///
23 /// @addtogroup CeedBasis
24 /// @{
25 
26 /**
27   @brief Create a CeedTensorContract object for a CeedBasis
28 
29   @param ceed          A Ceed object where the CeedTensorContract will be created
30   @param basis         CeedBasis for which the tensor contraction will be used
31   @param[out] contract Address of the variable where the newly created
32                          CeedTensorContract will be stored.
33 
34   @return An error code: 0 - success, otherwise - failure
35 
36   @ref Advanced
37 **/
38 int CeedTensorContractCreate(Ceed ceed, CeedBasis basis,
39                              CeedTensorContract *contract) {
40   int ierr;
41 
42   if (!ceed->TensorContractCreate) {
43     Ceed delegate;
44     ierr = CeedGetObjectDelegate(ceed, &delegate, "TensorContract");
45     CeedChk(ierr);
46 
47     if (!delegate)
48       // LCOV_EXCL_START
49       return CeedError(ceed, 1, "Backend does not support TensorContractCreate");
50     // LCOV_EXCL_STOP
51 
52     ierr = CeedTensorContractCreate(delegate, basis, contract);
53     CeedChk(ierr);
54     return 0;
55   }
56 
57   ierr = CeedCalloc(1,contract); CeedChk(ierr);
58 
59   (*contract)->ceed = ceed;
60   ceed->refcount++;
61   ierr = ceed->TensorContractCreate(basis, *contract);
62   CeedChk(ierr);
63   return 0;
64 };
65 
66 /**
67   @brief Apply tensor contraction
68 
69     Contracts on the middle index
70     NOTRANSPOSE: v_ajc = t_jb u_abc
71     TRANSPOSE:   v_ajc = t_bj u_abc
72     If add != 0, "=" is replaced by "+="
73 
74   @param contract   CeedTensorContract to use
75   @param A          First index of u, v
76   @param B          Middle index of u, one index of t
77   @param C          Last index of u, v
78   @param J          Middle index of v, one index of t
79   @param[in] t      Tensor array to contract against
80   @param tmode      Transpose mode for t, \ref CEED_NOTRANSPOSE for t_jb
81                     \ref CEED_TRANSPOSE for t_bj
82   @param add        Add mode
83   @param[in] u      Input array
84   @param[out] v     Output array
85 
86   @return An error code: 0 - success, otherwise - failure
87 
88   @ref Advanced
89 **/
90 int CeedTensorContractApply(CeedTensorContract contract, CeedInt A, CeedInt B,
91                             CeedInt C, CeedInt J, const CeedScalar *restrict t,
92                             CeedTransposeMode tmode, const CeedInt add,
93                             const CeedScalar *restrict u,
94                             CeedScalar *restrict v) {
95   int ierr;
96 
97   ierr = contract->Apply(contract, A, B, C, J, t, tmode, add,  u, v);
98   CeedChk(ierr);
99   return 0;
100 };
101 
102 /**
103   @brief Get Ceed associated with a CeedTensorContract
104 
105   @param contract      CeedTensorContract
106   @param[out] ceed  Variable to store Ceed
107 
108   @return An error code: 0 - success, otherwise - failure
109 
110   @ref Advanced
111 **/
112 int CeedTensorContractGetCeed(CeedTensorContract contract, Ceed *ceed) {
113   *ceed = contract->ceed;
114   return 0;
115 };
116 
117 /**
118   @brief Get backend data of a CeedTensorContract
119 
120   @param contract   CeedTensorContract
121   @param[out] data  Variable to store data
122 
123   @return An error code: 0 - success, otherwise - failure
124 
125   @ref Advanced
126 **/
127 int CeedTensorContractGetData(CeedTensorContract contract, void **data) {
128   *data = contract->data;
129   return 0;
130 }
131 
132 /**
133   @brief Set backend data of a CeedTensorContract
134 
135   @param[out] contract CeedTensorContract
136   @param data          Data to set
137 
138   @return An error code: 0 - success, otherwise - failure
139 
140   @ref Advanced
141 **/
142 int CeedTensorContractSetData(CeedTensorContract contract, void **data) {
143   contract->data = *data;
144   return 0;
145 }
146 
147 /**
148   @brief Destroy a CeedTensorContract
149 
150   @param contract   CeedTensorContract to destroy
151 
152   @return An error code: 0 - success, otherwise - failure
153 
154   @ref Advanced
155 **/
156 int CeedTensorContractDestroy(CeedTensorContract *contract) {
157   int ierr;
158 
159   if (!*contract || --(*contract)->refcount > 0)
160     return 0;
161   if ((*contract)->Destroy) {
162     ierr = (*contract)->Destroy(*contract); CeedChk(ierr);
163   }
164   ierr = CeedDestroy(&(*contract)->ceed); CeedChk(ierr);
165   ierr = CeedFree(contract); CeedChk(ierr);
166   return 0;
167 };
168 
169 /// @}
170