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