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