xref: /libCEED/interface/ceed-tensor.c (revision 288c044332e33f37503f09b6484fec9d0a55fba1)
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       return CeedError(ceed, 1,
49                        "Backend does not support TensorContractCreate");
50 
51     ierr = CeedTensorContractCreate(delegate, basis, contract);
52     CeedChk(ierr);
53     return 0;
54   }
55 
56   ierr = CeedCalloc(1,contract); CeedChk(ierr);
57 
58   (*contract)->ceed = ceed;
59   ceed->refcount++;
60   ierr = ceed->TensorContractCreate(basis, *contract);
61   CeedChk(ierr);
62   return 0;
63 };
64 
65 /**
66   @brief Apply tensor contraction
67 
68     Contracts on the middle index
69     NOTRANSPOSE: v_ajc = t_jb u_abc
70     TRANSPOSE:   v_ajc = t_bj u_abc
71     If add != 0, "=" is replaced by "+="
72 
73   @param contract   CeedTensorContract to use
74   @param A          First index of u, v
75   @param B          Middle index of u, one index of t
76   @param C          Last index of u, v
77   @param J          Middle index of v, one index of t
78   @param[in] t      Tensor array to contract against
79   @param tmode      Transpose mode for t, \ref CEED_NOTRANSPOSE for t_jb
80                     \ref CEED_TRANSPOSE for t_bj
81   @param add        Add mode
82   @param[in] u      Input array
83   @param[out] v     Output array
84 
85   @return An error code: 0 - success, otherwise - failure
86 
87   @ref Advanced
88 **/
89 int CeedTensorContractApply(CeedTensorContract contract, CeedInt A, CeedInt B,
90                             CeedInt C, CeedInt J, const CeedScalar *restrict t,
91                             CeedTransposeMode tmode, const CeedInt add,
92                             const CeedScalar *restrict u,
93                             CeedScalar *restrict v) {
94   int ierr;
95 
96   ierr = contract->Apply(contract, A, B, C, J, t, tmode, add,  u, v);
97   CeedChk(ierr);
98   return 0;
99 };
100 
101 /**
102   @brief Get Ceed associated with a CeedTensorContract
103 
104   @param contract      CeedTensorContract
105   @param[out] ceed  Variable to store Ceed
106 
107   @return An error code: 0 - success, otherwise - failure
108 
109   @ref Advanced
110 **/
111 int CeedTensorContractGetCeed(CeedTensorContract contract, Ceed *ceed) {
112   *ceed = contract->ceed;
113 
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) return 0;
160   if ((*contract)->Destroy) {
161     ierr = (*contract)->Destroy(*contract); CeedChk(ierr);
162   }
163   ierr = CeedDestroy(&(*contract)->ceed); CeedChk(ierr);
164   ierr = CeedFree(contract); CeedChk(ierr);
165   return 0;
166 };
167 
168 /// @}
169