19if (!lmmc_storage_envelope_checked(
22 !lmmc_storage_envelope_checked(
25 !lmmc_storage_envelope_checked(
30if (lmmc_storage_envelopes_overlap(&c_envelope, &a_envelope) ||
31 lmmc_storage_envelopes_overlap(&c_envelope, &b_envelope)) {
42if (!lmmc_storage_envelope_checked(A->
data, A->
rows, A->
cols,
45 !lmmc_storage_envelope_checked(x->
data, 1, x->
size, x->
size,
47 !lmmc_storage_envelope_checked(y->
data, 1, y->
size, y->
size,
51if (lmmc_storage_envelopes_overlap(&y_envelope, &a_envelope) ||
52 lmmc_storage_envelopes_overlap(&y_envelope, &x_envelope)) {
60 for (
size_t i = 0; i < C->
rows; ++i) {
61 for (
size_t j = 0; j < C->
cols; ++j) {
65 }
else if (beta != 1.0) {
66 for (
size_t i = 0; i < C->
rows; ++i) {
67 for (
size_t j = 0; j < C->
cols; ++j) {
78 for (
size_t i = 0; i < y->
size; ++i) {
81 }
else if (beta != 1.0) {
82 for (
size_t i = 0; i < y->
size; ++i) {
92 size_t ii,
size_t kk,
size_t jj) {
97 size_t i_end = ii + 64;
98 if (i_end > C->
rows) {
101 size_t k_end = kk + 64;
105 size_t j_end = jj + 64;
106 if (j_end > C->
cols) {
109 for (
size_t i = ii; i < i_end; ++i) {
110 for (
size_t k = kk; k < k_end; ++k) {
119 for (
size_t j = jj; j < j_end; ++j) {
139 size_t a_stride = A->
stride;
148 for (
size_t i = 0; i < M; ++i) {
150 for (
size_t j = 0; j < N; ++j) {
153 a_ij = a_data[j * a_stride + i];
155 a_ij = a_data[i * a_stride + j];
176 for (
size_t ii = 0; ii < C->
rows; ii += 64) {
177 for (
size_t kk = 0; kk < K; kk += 64) {
178 for (
size_t jj = 0; jj < C->
cols; jj += 64) {
179 lmmc_gemm_block(alpha, A, transA, B, transB, C, ii, kk, jj);
187 if (!lmmc_mat_descriptor_is_valid(A) ||
188 !lmmc_mat_descriptor_is_valid(B) ||
189 !lmmc_mat_descriptor_is_valid(C)) {
194 size_t K_A = A->
cols;
195 size_t K_B = B->
rows;
216 lmmc_gemm_scale(C, beta);
220 lmmc_gemm_accumulate(alpha, A, transA, B, transB, C, K_A);
230 if (!lmmc_vec_descriptor_is_valid(a) ||
231 !lmmc_vec_descriptor_is_valid(b) || out_dot == NULL) {
243 for (i = 0; i < a->
size; ++i) {
258 if (!lmmc_mat_descriptor_is_valid(A) ||
259 !lmmc_vec_descriptor_is_valid(x) ||
260 !lmmc_vec_descriptor_is_valid(y)) {
265 size_t M = transA ? A->
cols : A->
rows;
266 size_t N = transA ? A->
rows : A->
cols;
276 lmmc_gemv_scale(y, beta);
278 lmmc_gemv_accumulate(alpha, A, transA, x, y);
288 if (!lmmc_vec_descriptor_is_valid(x) ||
289 !lmmc_vec_descriptor_is_valid(y)) {
299 for (
size_t i = 0; i < x->
size; ++i) {
LMMC binary real type and arithmetic spelling.
#define LMMC_REAL_CLEAR(x)
释放一个 lmmc_real_t 变量(POD 类型为空操作)。
#define LMMC_REAL_INIT(x)
初始化一个 lmmc_real_t 变量(POD 类型为空操作)。
#define LMMC_REAL_ADD(res, a, b)
计算 *res = *a + *b 。
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_REAL_SET(dst, src)
将一个 lmmc_real_t 赋值到另一个:*dst = *src 。
#define LMMC_REAL_MUL(res, a, b)
计算 *res = *a * *b 。
#define LMMC_REAL_SET_D(dst, dbl)
将一个 double 字面量赋值到 lmmc_real_t 。
lmmc_status_t lmmc_vec_dot(const lmmc_vec_t *a, const lmmc_vec_t *b, lmmc_real_t *out_dot)
计算两个等长向量的内积: 。
lmmc_status_t lmmc_mat_gemv(lmmc_real_t alpha, const lmmc_mat_t *A, int transA, const lmmc_vec_t *x, lmmc_real_t beta, lmmc_vec_t *y)
通用矩阵-向量乘法(GEMV): 。
lmmc_status_t lmmc_mat_gemm(lmmc_real_t alpha, const lmmc_mat_t *A, int transA, const lmmc_mat_t *B, int transB, lmmc_real_t beta, lmmc_mat_t *C)
通用矩阵-矩阵乘法(GEMM): 。
lmmc_status_t lmmc_vec_axpy(lmmc_real_t alpha, const lmmc_vec_t *x, lmmc_vec_t *y)
向量 AXPY 运算: 。
lmmc_status_t lmmc_mat_vec_mul(const lmmc_mat_t *a, const lmmc_vec_t *x, lmmc_vec_t *y)
计算矩阵与向量的乘积:y = A * x。
lmmc_status_t lmmc_mat_mul(const lmmc_mat_t *a, const lmmc_mat_t *b, lmmc_mat_t *c)
计算矩阵乘积:c = a * b。
稠密矩阵直接分解接口(LU、Cholesky、QR)。
Private recoverable allocator for persistent LMMC ownership.
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_INVALID_ARGUMENT