List of all members | Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Friends
casadi::Blas Class Referenceabstract

Pluggable dense BLAS backend, dispatched per-call by shorthand. More...

#include <blas_impl.hpp>

Detailed Description

Shorthand 0 is the built-in reference impl (fast path, no indirection). External plugins (classic, blasfeo, ...) live in their own DLLs and are dlopen'd on first use; each populates Exposed with its own function pointers.

Author
Joris Gillis
Date
2026

Extra doc: https://github.com/casadi/casadi/wiki/L_2ge

Definition at line 56 of file blas_impl.hpp.

Inheritance diagram for casadi::Blas:
Inheritance graph
[legend]
Collaboration diagram for casadi::Blas:
Collaboration graph
[legend]

Classes

struct  Exposed
 

Public Types

typedef void(* Dgemm) (int transa, int transb, casadi_int m, casadi_int n, casadi_int k, double alpha, const double *A, casadi_int lda, const double *B, casadi_int ldb, double beta, double *C, casadi_int ldc)
 
typedef void(* CodegenMtimes) (CodeGenerator &g, const std::string &A, casadi_int m, casadi_int k, const std::string &B, casadi_int n, const std::string &C)
 
typedef void(* Daxpy) (casadi_int n, double alpha, const double *x, double *y)
 
typedef double(* Ddot) (casadi_int n, const double *x, const double *y)
 
typedef void(* Dscal) (casadi_int n, double alpha, double *x)
 
typedef double(* Dnrm2) (casadi_int n, const double *x)
 
typedef double(* Dasum) (casadi_int n, const double *x)
 
typedef void(* Dcopy) (const double *x, casadi_int n, double *y)
 
typedef void(* CodegenL1Aux) (CodeGenerator &g, const std::vector< std::string > &inst)
 
typedef Blas *(* Creator) ()
 
typedef int(* RegFcn) (Plugin *plugin)
 

Public Member Functions

virtual const char * plugin_name () const=0
 
virtual void deps_version_check (const std::string &stage) const
 
void serialize_type (SerializingStream &s) const
 Serialize type information. More...
 

Static Public Member Functions

static std::string getDefault ()
 
static casadi_int shorthand_for (const std::string &name)
 
static const char * name_for_shorthand (casadi_int shorthand)
 
static void dgemm (casadi_int shorthand, int transa, int transb, casadi_int m, casadi_int n, casadi_int k, double alpha, const double *A, casadi_int lda, const double *B, casadi_int ldb, double beta, double *C, casadi_int ldc)
 
static void reference_dgemm (int transa, int transb, casadi_int m, casadi_int n, casadi_int k, double alpha, const double *A, casadi_int lda, const double *B, casadi_int ldb, double beta, double *C, casadi_int ldc)
 
static void mtimes (casadi_int shorthand, const double *A, casadi_int m, casadi_int k, const double *B, casadi_int n, double *C)
 
static void codegen_mtimes (CodeGenerator &g, casadi_int shorthand, const std::string &A, casadi_int m, casadi_int k, const std::string &B, casadi_int n, const std::string &C)
 
static void codegen_copy_aux (CodeGenerator &g, const std::vector< std::string > &inst)
 
static bool codegen_axpy_aux (CodeGenerator &g, const std::vector< std::string > &inst)
 
static bool codegen_dot_aux (CodeGenerator &g, const std::vector< std::string > &inst)
 
static bool codegen_scal_aux (CodeGenerator &g, const std::vector< std::string > &inst)
 
static bool codegen_norm_2_aux (CodeGenerator &g, const std::vector< std::string > &inst)
 
static bool codegen_norm_1_aux (CodeGenerator &g, const std::vector< std::string > &inst)
 
static bool has_plugin (const std::string &pname, bool verbose=false)
 Check if a plugin is available or can be loaded. More...
 
static const Optionsplugin_options (const std::string &pname)
 Get the plugin options. More...
 
static Deserialize plugin_deserialize (const std::string &pname)
 Get the plugin deserialize_map. More...
 
static Plugin pluginFromRegFcn (RegFcn regfcn)
 Instantiate a Plugin struct from a factory function. More...
 
static Plugin load_plugin (const std::string &pname, bool register_plugin=true, bool needs_lock=true)
 Load a plugin dynamically. More...
 
static handle_t load_library (const std::string &libname, std::string &resultpath, bool global)
 Load a library dynamically. More...
 
static void registerPlugin (const Plugin &plugin, bool needs_lock=true)
 Register an integrator in the factory. More...
 
static void registerPlugin (RegFcn regfcn, bool needs_lock=true)
 Register an integrator in the factory. More...
 
static Plugin & getPlugin (const std::string &pname)
 Load and get the creator function. More...
 
static Blasinstantiate (const std::string &fname, const std::string &pname, Problem problem)
 
static ProtoFunctiondeserialize (DeserializingStream &s)
 Deserialize with type disambiguation. More...
 

Static Public Attributes

static const std::string meta_doc
 
static std::map< std::string, Plugin > solvers_
 
static std::vector< const Plugin * > dispatch_
 
static casadi_int default_ = 0
 
static const std::string infix_ = "blas"
 

Friends

class GlobalOptions
 

Member Typedef Documentation

◆ CodegenL1Aux

typedef void(* casadi::Blas::CodegenL1Aux) (CodeGenerator &g, const std::vector< std::string > &inst)

Definition at line 84 of file blas_impl.hpp.

◆ CodegenMtimes

typedef void(* casadi::Blas::CodegenMtimes) (CodeGenerator &g, const std::string &A, casadi_int m, casadi_int k, const std::string &B, casadi_int n, const std::string &C)

Definition at line 69 of file blas_impl.hpp.

◆ Creator

typedef Blas*(* casadi::Blas::Creator) ()

Definition at line 88 of file blas_impl.hpp.

◆ Dasum

typedef double(* casadi::Blas::Dasum) (casadi_int n, const double *x)

Definition at line 80 of file blas_impl.hpp.

◆ Daxpy

typedef void(* casadi::Blas::Daxpy) (casadi_int n, double alpha, const double *x, double *y)

Definition at line 76 of file blas_impl.hpp.

◆ Dcopy

typedef void(* casadi::Blas::Dcopy) (const double *x, casadi_int n, double *y)

Definition at line 81 of file blas_impl.hpp.

◆ Ddot

typedef double(* casadi::Blas::Ddot) (casadi_int n, const double *x, const double *y)

Definition at line 77 of file blas_impl.hpp.

◆ Dgemm

typedef void(* casadi::Blas::Dgemm) (int transa, int transb, casadi_int m, casadi_int n, casadi_int k, double alpha, const double *A, casadi_int lda, const double *B, casadi_int ldb, double beta, double *C, casadi_int ldc)

Definition at line 60 of file blas_impl.hpp.

◆ Dnrm2

typedef double(* casadi::Blas::Dnrm2) (casadi_int n, const double *x)

Definition at line 79 of file blas_impl.hpp.

◆ Dscal

typedef void(* casadi::Blas::Dscal) (casadi_int n, double alpha, double *x)

Definition at line 78 of file blas_impl.hpp.

◆ RegFcn

typedef int(* casadi::PluginInterface< Blas >::RegFcn) (Plugin *plugin)
inherited

Definition at line 73 of file plugin_interface.hpp.

Member Function Documentation

◆ codegen_axpy_aux()

bool casadi::Blas::codegen_axpy_aux ( CodeGenerator g,
const std::vector< std::string > &  inst 
)
static

Definition at line 296 of file blas.cpp.

297  {
298  if (!default_) return false;
299  CodegenL1Aux fn = dispatch_[default_]->exposed.codegen_axpy_aux;
300  if (!fn) return false;
301  fn(g, inst);
302  return true;
303 }
static casadi_int default_
Definition: blas_impl.hpp:116
void(* CodegenL1Aux)(CodeGenerator &g, const std::vector< std::string > &inst)
Definition: blas_impl.hpp:84
static std::vector< const Plugin * > dispatch_
Definition: blas_impl.hpp:113

References default_, and dispatch_.

Referenced by casadi::CodeGenerator::add_auxiliary().

◆ codegen_copy_aux()

void casadi::Blas::codegen_copy_aux ( CodeGenerator g,
const std::vector< std::string > &  inst 
)
static

Definition at line 283 of file blas.cpp.

284  {
285  g.add_include("string.h");
286  g.auxiliaries << g.sanitize_source(
287  "// SYMBOL \"copy\"\n"
288  "void casadi_copy(const casadi_real* x, casadi_int n, casadi_real* y) {\n"
289  " if (!y) return;\n"
290  " if (x) memcpy(y, x, n*sizeof(casadi_real));\n"
291  " else memset(y, 0, n*sizeof(casadi_real));\n"
292  "}\n",
293  inst);
294 }

References casadi::CodeGenerator::add_include(), casadi::CodeGenerator::auxiliaries, and casadi::CodeGenerator::sanitize_source().

Referenced by casadi::CodeGenerator::add_auxiliary().

◆ codegen_dot_aux()

bool casadi::Blas::codegen_dot_aux ( CodeGenerator g,
const std::vector< std::string > &  inst 
)
static

Definition at line 305 of file blas.cpp.

306  {
307  if (!default_) return false;
308  CodegenL1Aux fn = dispatch_[default_]->exposed.codegen_dot_aux;
309  if (!fn) return false;
310  fn(g, inst);
311  return true;
312 }

References default_, and dispatch_.

Referenced by casadi::CodeGenerator::add_auxiliary().

◆ codegen_mtimes()

void casadi::Blas::codegen_mtimes ( CodeGenerator g,
casadi_int  shorthand,
const std::string &  A,
casadi_int  m,
casadi_int  k,
const std::string &  B,
casadi_int  n,
const std::string &  C 
)
static

Definition at line 229 of file blas.cpp.

233  {
234  if (shorthand == 0) {
235  // Reference fast path: emit the built-in casadi_mtimes_dense call.
236  g << g.mtimes(A, m, k, B, n, C, false) << '\n';
237  return;
238  }
239  // External plugin: trust the caller obtained `shorthand` via shorthand_for(),
240  // so dispatch_[shorthand] is populated and its codegen_mtimes is non-null
241  // (otherwise the plugin would have failed to register).
242  casadi_assert_dev(shorthand < static_cast<casadi_int>(dispatch_.size()));
243  casadi_assert_dev(dispatch_[shorthand] != nullptr);
244  const Plugin* p = dispatch_[shorthand];
245  casadi_assert(p->exposed.codegen_mtimes != nullptr,
246  "BLAS plugin '" + std::string(p->name) + "' does not implement codegen.");
247  p->exposed.codegen_mtimes(g, A, m, k, B, n, C);
248 }

References casadi::C, dispatch_, and casadi::CodeGenerator::mtimes().

Referenced by casadi::DenseMultiplication::generate(), and casadi::PseudoDenseMultiplication::generate().

◆ codegen_norm_1_aux()

bool casadi::Blas::codegen_norm_1_aux ( CodeGenerator g,
const std::vector< std::string > &  inst 
)
static

Definition at line 332 of file blas.cpp.

333  {
334  if (!default_) return false;
335  CodegenL1Aux fn = dispatch_[default_]->exposed.codegen_asum_aux;
336  if (!fn) return false;
337  fn(g, inst);
338  return true;
339 }

References default_, and dispatch_.

Referenced by casadi::CodeGenerator::add_auxiliary().

◆ codegen_norm_2_aux()

bool casadi::Blas::codegen_norm_2_aux ( CodeGenerator g,
const std::vector< std::string > &  inst 
)
static

Definition at line 323 of file blas.cpp.

324  {
325  if (!default_) return false;
326  CodegenL1Aux fn = dispatch_[default_]->exposed.codegen_nrm2_aux;
327  if (!fn) return false;
328  fn(g, inst);
329  return true;
330 }

References default_, and dispatch_.

Referenced by casadi::CodeGenerator::add_auxiliary().

◆ codegen_scal_aux()

bool casadi::Blas::codegen_scal_aux ( CodeGenerator g,
const std::vector< std::string > &  inst 
)
static

Definition at line 314 of file blas.cpp.

315  {
316  if (!default_) return false;
317  CodegenL1Aux fn = dispatch_[default_]->exposed.codegen_scal_aux;
318  if (!fn) return false;
319  fn(g, inst);
320  return true;
321 }

References default_, and dispatch_.

Referenced by casadi::CodeGenerator::add_auxiliary().

◆ deps_version_check()

virtual void casadi::PluginInterface< Blas >::deps_version_check ( const std::string &  stage) const
inlinevirtualinherited

Definition at line 112 of file plugin_interface.hpp.

112 {}

◆ deserialize()

static ProtoFunction* casadi::PluginInterface< Blas >::deserialize ( DeserializingStream s)
inlinestaticinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_rr

Definition at line 124 of file plugin_interface.hpp.

124  {
125  std::string class_name, plugin_name;
126  s.unpack("PluginInterface::plugin_name", plugin_name);
128  return deserialize(s);
129  }
static Deserialize plugin_deserialize(const std::string &pname)
Get the plugin deserialize_map.
static ProtoFunction * deserialize(DeserializingStream &s)
Deserialize with type disambiguation.
virtual const char * plugin_name() const=0
ProtoFunction *(* Deserialize)(DeserializingStream &)

◆ dgemm()

void casadi::Blas::dgemm ( casadi_int  shorthand,
int  transa,
int  transb,
casadi_int  m,
casadi_int  n,
casadi_int  k,
double  alpha,
const double *  A,
casadi_int  lda,
const double *  B,
casadi_int  ldb,
double  beta,
double *  C,
casadi_int  ldc 
)
static

Definition at line 180 of file blas.cpp.

187  {
188  if (shorthand == 0) {
189  // Reference fast path: skip indirection entirely.
190  reference_dgemm(transa, transb, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc);
191  return;
192  }
193  // External plugin: trust the caller obtained `shorthand` via shorthand_for(),
194  // which guarantees dispatch_[shorthand] is populated. Hot path, no lock.
195  casadi_assert_dev(shorthand < static_cast<casadi_int>(dispatch_.size()));
196  casadi_assert_dev(dispatch_[shorthand] != nullptr);
197  dispatch_[shorthand]->exposed.dgemm(
198  transa, transb, m, n, k, alpha, A, lda, B, ldb, beta, C, ldc);
199 }
static void reference_dgemm(int transa, int transb, casadi_int m, casadi_int n, casadi_int k, double alpha, const double *A, casadi_int lda, const double *B, casadi_int ldb, double beta, double *C, casadi_int ldc)
Definition: blas.cpp:62

References casadi::C, dispatch_, and reference_dgemm().

◆ getDefault()

std::string casadi::Blas::getDefault ( )
static

Definition at line 279 of file blas.cpp.

279  {
281 }
static const char * name_for_shorthand(casadi_int shorthand)
Definition: blas.cpp:220

References default_, and name_for_shorthand().

Referenced by casadi::GlobalOptions::getDefaultBlas().

◆ getPlugin()

PluginInterface< Blas >::Plugin & casadi::PluginInterface< Blas >::getPlugin ( const std::string &  pname)
staticinherited

Definition at line 102 of file plugin_interface.hpp.

295  {
296 
297 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
298  std::lock_guard<std::mutex> lock(Derived::mutex_solvers_);
299 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
300 
301  // Check if the solver has been loaded
302  auto it=Derived::solvers_.find(pname);
303 
304  // Load the solver if needed
305  if (it==Derived::solvers_.end()) {
306  load_plugin(pname, true, false);
307  it=Derived::solvers_.find(pname);
308  }
309  casadi_assert_dev(it!=Derived::solvers_.end());
310  return it->second;
311  }
static Plugin load_plugin(const std::string &pname, bool register_plugin=true, bool needs_lock=true)
Load a plugin dynamically.

◆ has_plugin()

bool casadi::PluginInterface< Blas >::has_plugin ( const std::string &  pname,
bool  verbose = false 
)
staticinherited

Definition at line 76 of file plugin_interface.hpp.

134  {
135 
136 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
137  std::lock_guard<std::mutex> lock(Derived::mutex_solvers_);
138 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
139 
140  // Quick return if available
141  if (Derived::solvers_.find(pname) != Derived::solvers_.end()) {
142  return true;
143  }
144 
145  // Try loading the plugin
146  try {
147  (void)load_plugin(pname, false, false);
148  return true;
149  } catch (CasadiException& ex) {
150  if (verbose) {
151  casadi_warning(ex.what());
152  }
153  return false;
154  }
155  }
std::vector< casadi_int > find(const std::vector< T > &v)
find nonzeros

◆ instantiate()

Blas * casadi::PluginInterface< Blas >::instantiate ( const std::string &  fname,
const std::string &  pname,
Problem  problem 
)
staticinherited

Definition at line 106 of file plugin_interface.hpp.

317  {
318 
319  // Assert the plugin exists (needed for adaptors)
320  if (!has_plugin(pname, true)) {
321  casadi_error("Plugin '" + pname + "' is not found.");
322  }
323  return getPlugin(pname).creator(fname, problem);
324  }
static bool has_plugin(const std::string &pname, bool verbose=false)
Check if a plugin is available or can be loaded.
static Plugin & getPlugin(const std::string &pname)
Load and get the creator function.

◆ load_library()

handle_t casadi::PluginInterface< Blas >::load_library ( const std::string &  libname,
std::string &  resultpath,
bool  global 
)
staticinherited

Definition at line 92 of file plugin_interface.hpp.

187  {
188 
189 #ifndef WITH_DL
190  casadi_error("WITH_DL option needed for dynamic loading");
191 #else // WITH_DL
192 
193  // Get the name of the shared library
194  std::string lib = std::string(CasadiMeta::shared_library_prefix()) + libname +
195  CasadiMeta::shared_library_suffix();
196 
197  // Build up search paths;
198  std::vector<std::string> search_paths = get_search_paths();
199  return open_shared_library(lib, search_paths, resultpath,
200  "PluginInterface::load_plugin", global);
201 
202 #endif // WITH_DL
203  }
std::vector< std::string > get_search_paths()
Definition: casadi_os.cpp:79

◆ load_plugin()

PluginInterface< Blas >::Plugin casadi::PluginInterface< Blas >::load_plugin ( const std::string &  pname,
bool  register_plugin = true,
bool  needs_lock = true 
)
staticinherited

Definition at line 88 of file plugin_interface.hpp.

208  {
209 
210 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
211  casadi::conditional_lock_guard<std::mutex> lock(Derived::mutex_solvers_, needs_lock);
212 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
213 
214  // Issue warning and quick return if already loaded
215  if (Derived::solvers_.find(pname) != Derived::solvers_.end()) {
216  casadi_warning("PluginInterface: Solver " + pname + " is already in use. Ignored.");
217  return Plugin();
218  }
219 
220  // Logger singletons are lazily instantiated on first uout()/uerr() calls
221  // This instantation may lead to a data race with potential instatiations in plugin
222  // To be safe, trigger instantatin before any plugin loading
223  uout();
224  uerr();
225 
226 #ifndef WITH_DL
227  casadi_error("WITH_DL option needed for dynamic loading");
228 #else // WITH_DL
229  // Retrieve the registration function
230  RegFcn reg;
231 
232  // Load the dll
233  std::string regName = "casadi_register_" + Derived::infix_ + "_" + pname;
234 
235  std::string searchpath;
236  handle_t handle = load_library("casadi_" + Derived::infix_ + "_" + pname, searchpath,
237  false);
238 
239 #ifdef _WIN32
240 
241 #if __GNUC__
242 #pragma GCC diagnostic push
243 #pragma GCC diagnostic ignored "-Wcast-function-type"
244 #endif
245  reg = reinterpret_cast<RegFcn>(GetProcAddress(handle, TEXT(regName.c_str())));
246 #if __GNUC__
247 #pragma GCC diagnostic pop
248 #endif
249 
250 #else // _WIN32
251  // Reset error
252  dlerror();
253 
254  // Load creator
255  reg = reinterpret_cast<RegFcn>(dlsym(handle, regName.c_str()));
256 #endif // _WIN32
257  casadi_assert(reg!=nullptr,
258  "PluginInterface::load_plugin: no \"" + regName + "\" found in " + searchpath + ".");
259 
260  // Create a temporary struct
261  Plugin plugin = pluginFromRegFcn(reg);
262  // Register the plugin
263  if (register_plugin) {
264  registerPlugin(plugin, false);
265  }
266 
267  return plugin;
268 
269 #endif // WITH_DL
270  }
static handle_t load_library(const std::string &libname, std::string &resultpath, bool global)
Load a library dynamically.
static Plugin pluginFromRegFcn(RegFcn regfcn)
Instantiate a Plugin struct from a factory function.
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
std::ostream & uerr()
void * handle_t
Definition: casadi_os.hpp:109
std::ostream & uout()

◆ mtimes()

void casadi::Blas::mtimes ( casadi_int  shorthand,
const double *  A,
casadi_int  m,
casadi_int  k,
const double *  B,
casadi_int  n,
double *  C 
)
static

Definition at line 201 of file blas.cpp.

204  {
205  if (shorthand == 0) {
206  // Reference fast path: arguments are already canonical here, so skip
207  // dgemm's canonical-detection branch and call the loop directly.
208  casadi_mtimes_dense<double>(A, m, k, B, n, C, /*tr=*/0);
209  return;
210  }
211  // External plugin: indirect through dispatch_, no lock. The caller
212  // obtained `shorthand` via shorthand_for() so the slot is populated.
213  casadi_assert_dev(shorthand < static_cast<casadi_int>(dispatch_.size()));
214  casadi_assert_dev(dispatch_[shorthand] != nullptr);
215  dispatch_[shorthand]->exposed.dgemm(
217  m, n, k, 1.0, A, m, B, k, 1.0, C, m);
218 }
@ CASADI_BLAS_NO_TRANS
Definition: blas_impl.hpp:41

References casadi::C, casadi::CASADI_BLAS_NO_TRANS, and dispatch_.

Referenced by casadi::DenseMultiplication::eval_kernel(), and casadi::PseudoDenseMultiplication::eval_kernel().

◆ name_for_shorthand()

const char * casadi::Blas::name_for_shorthand ( casadi_int  shorthand)
static

Definition at line 220 of file blas.cpp.

220  {
221  if (shorthand == 0) return "reference";
222  // Read-only fast path: dispatch_ entries are stable for process lifetime
223  // and shorthand_for() is the sole writer. No lock needed; trust caller.
224  casadi_assert_dev(shorthand < static_cast<casadi_int>(dispatch_.size()));
225  casadi_assert_dev(dispatch_[shorthand] != nullptr);
226  return dispatch_[shorthand]->name;
227 }

References dispatch_.

Referenced by getDefault(), and casadi::Multiplication::serialize_body().

◆ plugin_deserialize()

Deserialize casadi::PluginInterface< Blas >::plugin_deserialize ( const std::string &  pname)
staticinherited

Definition at line 82 of file plugin_interface.hpp.

165  {
166  Deserialize m = getPlugin(pname).deserialize;
167  casadi_assert(m, "Plugin \"" + pname + "\" does not support deserialize");
168  return m;
169  }

◆ plugin_name()

virtual const char* casadi::PluginInterface< Blas >::plugin_name ( ) const
pure virtualinherited

◆ plugin_options()

const Options & casadi::PluginInterface< Blas >::plugin_options ( const std::string &  pname)
staticinherited

Definition at line 79 of file plugin_interface.hpp.

158  {
159  const Options *op = getPlugin(pname).options;
160  casadi_assert(op!=nullptr, "Plugin \"" + pname + "\" does not support options");
161  return *op;
162  }

◆ pluginFromRegFcn()

PluginInterface< Blas >::Plugin casadi::PluginInterface< Blas >::pluginFromRegFcn ( RegFcn  regfcn)
staticinherited

Definition at line 85 of file plugin_interface.hpp.

173  {
174  // Create a temporary struct
175  Plugin plugin;
176 
177  // Set the fields
178  int flag = regfcn(&plugin);
179  casadi_assert(flag==0, "Registration of plugin failed.");
180 
181  return plugin;
182  }

◆ reference_dgemm()

void casadi::Blas::reference_dgemm ( int  transa,
int  transb,
casadi_int  m,
casadi_int  n,
casadi_int  k,
double  alpha,
const double *  A,
casadi_int  lda,
const double *  B,
casadi_int  ldb,
double  beta,
double *  C,
casadi_int  ldc 
)
static

Definition at line 62 of file blas.cpp.

68  {
69  const bool transa_yes = (transa == CASADI_BLAS_TRANS);
70  const bool transb_yes = (transb == CASADI_BLAS_TRANS);
71 
72  // Fast path: canonical contiguous column-major layout, alpha=beta=1, transb=No.
73  // casadi_mtimes_dense takes (x, nrow_x, ncol_x, y, ncol_y, z, tr) and
74  // computes z += op(x) * y where:
75  // tr=0: x is (nrow_x, ncol_x), y is (ncol_x, ncol_y) -> z (nrow_x, ncol_y)
76  // tr=1: x is (nrow_x, ncol_x), y is (nrow_x, ncol_y) -> z (ncol_x, ncol_y)
77  const casadi_int lda_canonical = transa_yes ? k : m;
78  const bool canonical = !transb_yes
79  && alpha == 1.0 && beta == 1.0
80  && lda == lda_canonical && ldb == k && ldc == m;
81 
82  if (canonical) {
83  if (transa_yes) {
84  // z (m, n) += A^T (m, k from k-by-m) * B (k, n)
85  casadi_mtimes_dense<double>(A, k, m, B, n, C, 1);
86  } else {
87  // z (m, n) += A (m, k) * B (k, n)
88  casadi_mtimes_dense<double>(A, m, k, B, n, C, 0);
89  }
90  return;
91  }
92 
93  // General fallback: scale C, then accumulate.
94  if (beta == 0.0) {
95  for (casadi_int j = 0; j < n; ++j) {
96  double* col = C + j * ldc;
97  for (casadi_int i = 0; i < m; ++i) col[i] = 0.0;
98  }
99  } else if (beta != 1.0) {
100  for (casadi_int j = 0; j < n; ++j) {
101  double* col = C + j * ldc;
102  for (casadi_int i = 0; i < m; ++i) col[i] *= beta;
103  }
104  }
105 
106  for (casadi_int j = 0; j < n; ++j) {
107  for (casadi_int l = 0; l < k; ++l) {
108  const double b_lj = transb_yes ? B[j + l * ldb] : B[l + j * ldb];
109  if (b_lj == 0.0) continue;
110  const double scl = alpha * b_lj;
111  double* col = C + j * ldc;
112  if (transa_yes) {
113  const double* a_col = A + l; // walks A^T's column l = A's row l
114  // a_il = A[l + i * lda]
115  for (casadi_int i = 0; i < m; ++i) col[i] += scl * a_col[i * lda];
116  } else {
117  const double* a_col = A + l * lda; // A's column l
118  for (casadi_int i = 0; i < m; ++i) col[i] += scl * a_col[i];
119  }
120  }
121  }
122 }
@ CASADI_BLAS_TRANS
Definition: blas_impl.hpp:42

References casadi::C, and casadi::CASADI_BLAS_TRANS.

Referenced by dgemm().

◆ registerPlugin() [1/2]

void casadi::PluginInterface< Blas >::registerPlugin ( const Plugin &  plugin,
bool  needs_lock = true 
)
staticinherited

Definition at line 96 of file plugin_interface.hpp.

278  {
279 
280 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
281  casadi::conditional_lock_guard<std::mutex> lock(Derived::mutex_solvers_, needs_lock);
282 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
283 
284  // Check if the solver name is in use
285  typename std::map<std::string, Plugin>::iterator it=Derived::solvers_.find(plugin.name);
286  casadi_assert(it==Derived::solvers_.end(),
287  "Solver " + str(plugin.name) + " is already in use");
288 
289  // Add to list of solvers
290  Derived::solvers_[plugin.name] = plugin;
291  }
std::string str(const T &v)
String representation, any type.

◆ registerPlugin() [2/2]

void casadi::PluginInterface< Blas >::registerPlugin ( RegFcn  regfcn,
bool  needs_lock = true 
)
staticinherited

Definition at line 99 of file plugin_interface.hpp.

273  {
274  registerPlugin(pluginFromRegFcn(regfcn), needs_lock);
275  }

◆ serialize_type()

void casadi::PluginInterface< Blas >::serialize_type ( SerializingStream s) const
inlineinherited

Extra doc: https://github.com/casadi/casadi/wiki/L_rq

Definition at line 117 of file plugin_interface.hpp.

117  {
118  s.pack("PluginInterface::plugin_name", std::string(plugin_name()));
119  }

◆ shorthand_for()

casadi_int casadi::Blas::shorthand_for ( const std::string &  name)
static

Definition at line 141 of file blas.cpp.

141  {
142 #ifdef CASADI_CORE_BLAS_DEPENDENCY
143  static bool core_blas_inited = false;
144  if (!core_blas_inited) {
145  core_blas_inited = true; // set first: setDefault re-enters here
146  casadi_load_blas_classic(); // register the absorbed plugin (no dlopen)
147  setDefault("classic"); // sets Blas::default_ (L3 codegen) + hooks
148  }
149 #endif
150  if (name == "reference") return 0;
151 #ifdef CASADI_WITH_THREADSAFE_SYMBOLICS
152  std::lock_guard<std::mutex> lock(Blas::mutex_solvers_);
153 #endif // CASADI_WITH_THREADSAFE_SYMBOLICS
154 
155  // Lazy-init the dispatch_ vector: plant the slot-0 sentinel.
156  if (dispatch_.empty()) {
157  dispatch_.push_back(nullptr); // index 0 == reference, never indexed
158  }
159 
160  auto it = solvers_.find(name);
161  if (it == solvers_.end()) {
162  // Auto-load (lock already held, so pass needs_lock=false)
163  load_plugin(name, true, false);
164  it = solvers_.find(name);
165  casadi_assert_dev(it != solvers_.end());
166  }
167 
168  // Find existing shorthand by pointer identity (small N, linear scan is fine).
169  // Start at 1 — slot 0 is the reference sentinel.
170  const Plugin* p = &it->second;
171  for (casadi_int sh = 1; sh < static_cast<casadi_int>(dispatch_.size()); ++sh) {
172  if (dispatch_[sh] == p) return sh;
173  }
174 
175  // Newly registered plugin: assign next shorthand
176  dispatch_.push_back(p);
177  return static_cast<casadi_int>(dispatch_.size() - 1);
178 }
static std::map< std::string, Plugin > solvers_
Definition: blas_impl.hpp:110
void CASADI_BLAS_CLASSIC_EXPORT casadi_load_blas_classic()

References casadi::casadi_load_blas_classic(), dispatch_, casadi::PluginInterface< Blas >::load_plugin(), and solvers_.

Referenced by casadi::Multiplication::Multiplication().

Friends And Related Function Documentation

◆ GlobalOptions

friend class GlobalOptions
friend

Definition at line 127 of file blas_impl.hpp.

Member Data Documentation

◆ default_

casadi_int casadi::Blas::default_ = 0
static

◆ dispatch_

std::vector< const Blas::Plugin * > casadi::Blas::dispatch_
static

◆ infix_

const std::string casadi::Blas::infix_ = "blas"
static

Definition at line 139 of file blas_impl.hpp.

◆ meta_doc

const std::string casadi::Blas::meta_doc
static

Definition at line 90 of file blas_impl.hpp.

◆ solvers_

std::map< std::string, Blas::Plugin > casadi::Blas::solvers_
static

Definition at line 110 of file blas_impl.hpp.

Referenced by shorthand_for().


The documentation for this class was generated from the following files: