xref: /libCEED/interface/ceed-tensor.c (revision 3446d1b5ce8d1a4e72ebab9baee4f1efd0361227)
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 CeedTensorContract interfaces
22 
23 /// ----------------------------------------------------------------------------
24 /// CeedTensorContract Backend API
25 /// ----------------------------------------------------------------------------
26 /// @addtogroup CeedBasisBackend
27 /// @{
28 
29 /**
30   @brief Create a CeedTensorContract object for a CeedBasis
31 
32   @param ceed          A Ceed object where the CeedTensorContract will be created
33   @param basis         CeedBasis for which the tensor contraction will be used
34   @param[out] contract Address of the variable where the newly created
35                          CeedTensorContract will be stored.
36 
37   @return An error code: 0 - success, otherwise - failure
38 
39   @ref Backend
40 **/
41 int CeedTensorContractCreate(Ceed ceed, CeedBasis basis,
42                              CeedTensorContract *contract) {
43   int ierr;
44 
45   if (!ceed->TensorContractCreate) {
46     Ceed delegate;
47     ierr = CeedGetObjectDelegate(ceed, &delegate, "TensorContract");
48     CeedChk(ierr);
49 
50     if (!delegate)
51       // LCOV_EXCL_START
52       return CeedError(ceed, 1, "Backend does not support TensorContractCreate");
53     // LCOV_EXCL_STOP
54 
55     ierr = CeedTensorContractCreate(delegate, basis, contract);
56     CeedChk(ierr);
57     return 0;
58   }
59 
60   ierr = CeedCalloc(1,contract); CeedChk(ierr);
61 
62   (*contract)->ceed = ceed;
63   ceed->refcount++;
64   ierr = ceed->TensorContractCreate(basis, *contract);
65   CeedChk(ierr);
66   return 0;
67 }
68 
69 /**
70   @brief Apply tensor contraction
71 
72     Contracts on the middle index
73     NOTRANSPOSE: v_ajc = t_jb u_abc
74     TRANSPOSE:   v_ajc = t_bj u_abc
75     If add != 0, "=" is replaced by "+="
76 
77   @param contract   CeedTensorContract to use
78   @param A          First index of u, v
79   @param B          Middle index of u, one index of t
80   @param C          Last index of u, v
81   @param J          Middle index of v, one index of t
82   @param[in] t      Tensor array to contract against
83   @param tmode      Transpose mode for t, \ref CEED_NOTRANSPOSE for t_jb
84                     \ref CEED_TRANSPOSE for t_bj
85   @param add        Add mode
86   @param[in] u      Input array
87   @param[out] v     Output array
88 
89   @return An error code: 0 - success, otherwise - failure
90 
91   @ref Backend
92 **/
93 int CeedTensorContractApply(CeedTensorContract contract, CeedInt A, CeedInt B,
94                             CeedInt C, CeedInt J, const CeedScalar *restrict t,
95                             CeedTransposeMode tmode, const CeedInt add,
96                             const CeedScalar *restrict u,
97                             CeedScalar *restrict v) {
98   int ierr;
99 
100   ierr = contract->Apply(contract, A, B, C, J, t, tmode, add,  u, v);
101   CeedChk(ierr);
102   return 0;
103 }
104 
105 /**
106   @brief Get Ceed associated with a CeedTensorContract
107 
108   @param contract      CeedTensorContract
109   @param[out] ceed  Variable to store Ceed
110 
111   @return An error code: 0 - success, otherwise - failure
112 
113   @ref Backend
114 **/
115 int CeedTensorContractGetCeed(CeedTensorContract contract, Ceed *ceed) {
116   *ceed = contract->ceed;
117   return 0;
118 }
119 
120 /**
121   @brief Get backend data of a CeedTensorContract
122 
123   @param contract   CeedTensorContract
124   @param[out] data  Variable to store data
125 
126   @return An error code: 0 - success, otherwise - failure
127 
128   @ref Backend
129 **/
130 int CeedTensorContractGetData(CeedTensorContract contract, void *data) {
131   *(void **)data = contract->data;
132   return 0;
133 }
134 
135 /**
136   @brief Set backend data of a CeedTensorContract
137 
138   @param[out] contract CeedTensorContract
139   @param data          Data to set
140 
141   @return An error code: 0 - success, otherwise - failure
142 
143   @ref Backend
144 **/
145 int CeedTensorContractSetData(CeedTensorContract contract, void *data) {
146   contract->data = data;
147   return 0;
148 }
149 
150 /**
151   @brief Destroy a CeedTensorContract
152 
153   @param contract   CeedTensorContract to destroy
154 
155   @return An error code: 0 - success, otherwise - failure
156 
157   @ref Backend
158 **/
159 int CeedTensorContractDestroy(CeedTensorContract *contract) {
160   int ierr;
161 
162   if (!*contract || --(*contract)->refcount > 0) return 0;
163   if ((*contract)->Destroy) {
164     ierr = (*contract)->Destroy(*contract); CeedChk(ierr);
165   }
166   ierr = CeedDestroy(&(*contract)->ceed); CeedChk(ierr);
167   ierr = CeedFree(contract); CeedChk(ierr);
168   return 0;
169 }
170 
171 /// @}
172