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