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