blas_impl.hpp
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010-2023 Joel Andersson, Joris Gillis, Moritz Diehl,
6  * KU Leuven. All rights reserved.
7  * Copyright (C) 2011-2014 Greg Horn
8  *
9  * CasADi is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 3 of the License, or (at your option) any later version.
13  *
14  * CasADi is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with CasADi; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 
25 
26 #ifndef CASADI_BLAS_IMPL_HPP
27 #define CASADI_BLAS_IMPL_HPP
28 
29 #include "blas.hpp"
30 #include "plugin_interface.hpp"
31 #include "runtime/casadi_runtime.hpp"
32 
33 namespace casadi { class CodeGenerator; }
34 
35 
37 namespace casadi {
38 
39  /* \brief CBLAS_TRANSPOSE values, mirrored so plugins don't need <cblas.h> */
40  enum {
41  CASADI_BLAS_NO_TRANS = 111,
42  CASADI_BLAS_TRANS = 112
43  };
44 
56  class CASADI_EXPORT
57  Blas : public PluginInterface<Blas> {
58  public:
59  /* \brief CBLAS-style dgemm: C := alpha*op(A)*op(B) + beta*C; column-major */
60  typedef void (* Dgemm)(int transa, int transb,
61  casadi_int m, casadi_int n, casadi_int k,
62  double alpha,
63  const double* A, casadi_int lda,
64  const double* B, casadi_int ldb,
65  double beta,
66  double* C, casadi_int ldc);
67 
68  /* \brief Codegen counterpart of mtimes: emit C += A*B at the call site */
69  typedef void (* CodegenMtimes)(CodeGenerator& g,
70  const std::string& A,
71  casadi_int m, casadi_int k,
72  const std::string& B, casadi_int n,
73  const std::string& C);
74 
75  /* \brief L1 runtime hook signatures (double-only; templates handle other T) */
76  typedef void (* Daxpy)(casadi_int n, double alpha, const double* x, double* y);
77  typedef double (* Ddot )(casadi_int n, const double* x, const double* y);
78  typedef void (* Dscal)(casadi_int n, double alpha, double* x);
79  typedef double (* Dnrm2)(casadi_int n, const double* x);
80  typedef double (* Dasum)(casadi_int n, const double* x);
81  typedef void (* Dcopy)(const double* x, casadi_int n, double* y);
82 
83  /* \brief Codegen counterpart of an L1 op: emit the auxiliary block */
84  typedef void (* CodegenL1Aux)(CodeGenerator& g,
85  const std::vector<std::string>& inst);
86 
87  /* \brief Creator function (unused; kept for PluginInterface uniformity) */
88  typedef Blas* (*Creator)();
89 
90  static const std::string meta_doc;
91 
92  /* \brief Function-pointer table populated by each registered plugin */
93  struct Exposed {
94  Dgemm dgemm;
95  CodegenMtimes codegen_mtimes;
96  Daxpy daxpy;
97  Ddot ddot;
98  Dscal dscal;
99  Dnrm2 dnrm2;
100  Dasum dasum;
101  Dcopy dcopy;
102  CodegenL1Aux codegen_axpy_aux;
103  CodegenL1Aux codegen_dot_aux;
104  CodegenL1Aux codegen_scal_aux;
105  CodegenL1Aux codegen_nrm2_aux;
106  CodegenL1Aux codegen_asum_aux;
107  };
108 
109  /* \brief Collection of registered plugins, keyed by name */
110  static std::map<std::string, Plugin> solvers_;
111 
112  /* \brief Fast lookup structure for BLAS plugins */
113  static std::vector<const Plugin*> dispatch_;
114 
115  /* \brief Active default BLAS shorthand (index into dispatch_; 0 = reference) */
116  static casadi_int default_;
117 
118  /* \brief Get the active default BLAS name */
119  static std::string getDefault();
120 
121  /* \brief Resolve a plugin name to its dispatch shorthand */
122  static casadi_int shorthand_for(const std::string& name);
123 
124  /* \brief Reverse lookup: shorthand -> plugin name ("reference" for 0) */
125  static const char* name_for_shorthand(casadi_int shorthand);
126  private:
127  friend class GlobalOptions;
128 
129  /* \brief Set default_; private, callers go through GlobalOptions::setDefaultBlas */
130  static void setDefault(const std::string& name);
131 
132  public:
133 
134 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
135  static std::mutex mutex_solvers_;
136 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
137 
138  /* \brief Infix used by PluginInterface to derive DLL / register-symbol names */
139  static const std::string infix_;
140 
141  /* \brief Full CBLAS dgemm dispatched by shorthand (column-major) */
142  static void dgemm(casadi_int shorthand,
143  int transa, int transb,
144  casadi_int m, casadi_int n, casadi_int k,
145  double alpha,
146  const double* A, casadi_int lda,
147  const double* B, casadi_int ldb,
148  double beta,
149  double* C, casadi_int ldc);
150 
151  /* \brief Built-in dense dgemm (shorthand-0 fast path; exposed for tests) */
152  static void reference_dgemm(int transa, int transb,
153  casadi_int m, casadi_int n, casadi_int k,
154  double alpha,
155  const double* A, casadi_int lda,
156  const double* B, casadi_int ldb,
157  double beta,
158  double* C, casadi_int ldc);
159 
160  /* \brief Canonical contiguous mtimes-accumulate: C += A*B */
161  static void mtimes(casadi_int shorthand,
162  const double* A, casadi_int m, casadi_int k,
163  const double* B, casadi_int n,
164  double* C);
165 
166  /* \brief Emit a C statement that performs C += A*B; codegen counterpart of mtimes */
167  static void codegen_mtimes(CodeGenerator& g, casadi_int shorthand,
168  const std::string& A,
169  casadi_int m, casadi_int k,
170  const std::string& B, casadi_int n,
171  const std::string& C);
172 
173  /* \brief Emit aux block for casadi_copy (memcpy/memset; never plugin-dispatched) */
174  static void codegen_copy_aux(CodeGenerator& g,
175  const std::vector<std::string>& inst);
176  /* \brief Try-emit aux block for casadi_axpy via active plugin (false on fallback) */
177  static bool codegen_axpy_aux(CodeGenerator& g,
178  const std::vector<std::string>& inst);
179  /* \brief Try-emit aux block for casadi_dot via active plugin (false on fallback) */
180  static bool codegen_dot_aux(CodeGenerator& g,
181  const std::vector<std::string>& inst);
182  /* \brief Try-emit aux block for casadi_scal via active plugin (false on fallback) */
183  static bool codegen_scal_aux(CodeGenerator& g,
184  const std::vector<std::string>& inst);
185  /* \brief Try-emit aux block for casadi_norm_2 via active plugin (false on fallback) */
186  static bool codegen_norm_2_aux(CodeGenerator& g,
187  const std::vector<std::string>& inst);
188  /* \brief Try-emit aux block for casadi_norm_1 via active plugin (false on fallback) */
189  static bool codegen_norm_1_aux(CodeGenerator& g,
190  const std::vector<std::string>& inst);
191  };
192 
193 } // namespace casadi
194 
196 
197 #endif // CASADI_BLAS_IMPL_HPP
The casadi namespace.
Definition: archiver.hpp:32