xref: /libCEED/rust/libceed-sys/c-src/backends/opt/ceed-opt-tensor.c (revision 9b2a10adca6d745eeaf97f6468bfab9f8937faaf)
1 // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC.
2 // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707.
3 // All Rights 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/ceed.h>
18 #include <ceed/backend.h>
19 #include "ceed-opt.h"
20 
21 //------------------------------------------------------------------------------
22 // Tensor Contract Core loop
23 //------------------------------------------------------------------------------
24 static inline int CeedTensorContractApply_Core_Opt(CeedTensorContract contract,
25     CeedInt A, CeedInt B, CeedInt C, CeedInt J, const CeedScalar *restrict t,
26     CeedTransposeMode t_mode, const CeedInt add, const CeedScalar *restrict u,
27     CeedScalar *restrict v) {
28   CeedInt t_stride_0 = B, t_stride_1 = 1;
29   if (t_mode == CEED_TRANSPOSE) {
30     t_stride_0 = 1; t_stride_1 = J;
31   }
32 
33   for (CeedInt a=0; a<A; a++)
34     for (CeedInt b=0; b<B; b++)
35       for (CeedInt j=0; j<J; j++) {
36         CeedScalar tq = t[j*t_stride_0 + b*t_stride_1];
37         for (CeedInt c=0; c<C; c++)
38           v[(a*J+j)*C+c] += tq * u[(a*B+b)*C+c];
39       }
40 
41   return CEED_ERROR_SUCCESS;
42 }
43 
44 //------------------------------------------------------------------------------
45 // Tensor Contract Apply
46 //------------------------------------------------------------------------------
47 static int CeedTensorContractApply_Opt(CeedTensorContract contract, CeedInt A,
48                                        CeedInt B, CeedInt C, CeedInt J,
49                                        const CeedScalar *restrict t,
50                                        CeedTransposeMode t_mode, const CeedInt add,
51                                        const CeedScalar *restrict u,
52                                        CeedScalar *restrict v) {
53   if (!add)
54     for (CeedInt q=0; q<A*J*C; q++)
55       v[q] = (CeedScalar) 0.0;
56 
57   if (C == 1)
58     return CeedTensorContractApply_Core_Opt(contract, A, B, 1, J, t, t_mode,
59                                             add, u, v);
60   else
61     return CeedTensorContractApply_Core_Opt(contract, A, B, C, J, t, t_mode,
62                                             add, u, v);
63 
64   return CEED_ERROR_SUCCESS;
65 }
66 
67 //------------------------------------------------------------------------------
68 // Tensor Contract Destroy
69 //------------------------------------------------------------------------------
70 static int CeedTensorContractDestroy_Opt(CeedTensorContract contract) {
71   return CEED_ERROR_SUCCESS;
72 }
73 
74 //------------------------------------------------------------------------------
75 // Tensor Contract Create
76 //------------------------------------------------------------------------------
77 int CeedTensorContractCreate_Opt(CeedBasis basis, CeedTensorContract contract) {
78   int ierr;
79   Ceed ceed;
80   ierr = CeedTensorContractGetCeed(contract, &ceed); CeedChkBackend(ierr);
81 
82   ierr = CeedSetBackendFunction(ceed, "TensorContract", contract, "Apply",
83                                 CeedTensorContractApply_Opt); CeedChkBackend(ierr);
84   ierr = CeedSetBackendFunction(ceed, "TensorContract", contract, "Destroy",
85                                 CeedTensorContractDestroy_Opt); CeedChkBackend(ierr);
86 
87   return CEED_ERROR_SUCCESS;
88 }
89 //------------------------------------------------------------------------------
90