LMMC
Lamina Mathematic core
Toggle main menu visibility
载入中...
搜索中...
未找到
sparse_symmetric.c
浏览该文件的文档.
1
5
#include "
memory_bridge.h
"
6
#include "
internal.h
"
7
#include "
sparse_internal.h
"
8
#include "
lmmc/sparse.h
"
9
10
static
size_t
lmmc_sparse_sym_count(
11
const
lmmc_sparse_mat_t
* full,
lmmc_sparse_sym_half_t
half)
12
{
13
size_t
i, p, n = full->
rows
, nnz_half = 0;
14
for
(i = 0; i < n; ++i) {
15
for
(p = full->
row_ptr
[i]; p < full->row_ptr[i + 1]; ++p) {
16
size_t
j = full->
col_idx
[p];
17
if
(half ==
LMMC_SPARSE_SYM_UPPER
) {
18
if
(j >= i) ++nnz_half;
19
}
else
{
20
if
(j <= i) ++nnz_half;
21
}
22
}
23
}
24
return
nnz_half;
25
}
26
27
static
void
lmmc_sparse_sym_copy(
28
const
lmmc_sparse_mat_t
* full,
lmmc_sparse_sym_half_t
half,
29
lmmc_sparse_sym_csr_t
* out)
30
{
31
size_t
i, p, n = full->
rows
, nz_idx;
32
nz_idx = 0;
33
out->
row_ptr
[0] = 0;
34
for
(i = 0; i < n; ++i) {
35
for
(p = full->
row_ptr
[i]; p < full->row_ptr[i + 1]; ++p) {
36
size_t
j = full->
col_idx
[p];
37
int
keep = 0;
38
if
(half ==
LMMC_SPARSE_SYM_UPPER
) {
39
keep = (j >= i);
40
}
else
{
41
keep = (j <= i);
42
}
43
if
(keep) {
44
out->
col_idx
[nz_idx] = j;
45
LMMC_REAL_SET
(&out->
values
[nz_idx], &full->
values
[p]);
46
++nz_idx;
47
}
48
}
49
out->
row_ptr
[i + 1] = nz_idx;
50
}
51
}
52
53
static
void
lmmc_sparse_sym_accumulate(
54
const
lmmc_sparse_sym_csr_t
* A,
const
lmmc_vec_t
* x,
55
lmmc_vec_t
* y,
lmmc_real_t
* prod)
56
{
57
size_t
i, p;
58
for
(i = 0; i < A->
n
; ++i) {
59
for
(p = A->
row_ptr
[i]; p < A->row_ptr[i + 1]; ++p) {
60
size_t
j = A->
col_idx
[p];
61
LMMC_REAL_MUL
(prod, &A->
values
[p], &x->
data
[j]);
62
64
{
65
lmmc_real_t
tmp;
66
LMMC_REAL_INIT
(&tmp);
67
LMMC_REAL_ADD
(&tmp, &y->
data
[i], prod);
68
LMMC_REAL_SET
(&y->
data
[i], &tmp);
69
LMMC_REAL_CLEAR
(&tmp);
70
}
71
73
if
(i != j) {
74
lmmc_real_t
prod2;
75
lmmc_real_t
tmp2;
76
LMMC_REAL_INIT
(&prod2);
77
LMMC_REAL_INIT
(&tmp2);
78
LMMC_REAL_MUL
(&prod2, &A->
values
[p], &x->
data
[i]);
79
LMMC_REAL_ADD
(&tmp2, &y->
data
[j], &prod2);
80
LMMC_REAL_SET
(&y->
data
[j], &tmp2);
81
LMMC_REAL_CLEAR
(&prod2);
82
LMMC_REAL_CLEAR
(&tmp2);
83
}
84
}
85
}
86
}
87
88
89
lmmc_status_t
lmmc_sparse_sym_csr_from_csr
(
const
lmmc_sparse_mat_t
* full,
90
lmmc_sparse_sym_half_t
half,
lmmc_sparse_sym_csr_t
* out) {
91
size_t
i;
92
size_t
n;
93
size_t
nnz_half = 0;
94
size_t
row_ptr_bytes, col_idx_bytes, val_bytes;
95
lmmc_status_t
st;
96
97
if
(full == NULL || out == NULL) {
98
return
LMMC_STATUS_INVALID_ARGUMENT
;
99
}
100
101
st = lmmc_sparse_validate(full);
102
if
(st !=
LMMC_STATUS_OK
) {
103
return
LMMC_STATUS_INVALID_ARGUMENT
;
104
}
105
106
if
(full->
rows
!= full->
cols
) {
107
return
LMMC_STATUS_INVALID_ARGUMENT
;
108
}
109
if
(full->
format
!=
LMMC_SPARSE_CSR
) {
110
return
LMMC_STATUS_INVALID_ARGUMENT
;
111
}
112
113
n = full->
rows
;
114
115
/* 第一遍:计算半三角中的非零元数量 */
116
nnz_half = lmmc_sparse_sym_count(full, half);
117
118
/* 分配内存 */
119
if
(!lmmc_safe_mul_size(n + 1,
sizeof
(
size_t
), &row_ptr_bytes) ||
120
!lmmc_safe_mul_size(nnz_half,
sizeof
(
size_t
), &col_idx_bytes) ||
121
!lmmc_safe_mul_size(nnz_half,
sizeof
(
lmmc_real_t
), &val_bytes)) {
122
return
LMMC_STATUS_INVALID_ARGUMENT
;
123
}
124
125
out->
row_ptr
= (
size_t
*)
lmmc_memory_alloc
(row_ptr_bytes);
126
if
(out->
row_ptr
== NULL) {
127
return
LMMC_STATUS_ALLOCATION_FAILED
;
128
}
129
130
out->
col_idx
= NULL;
131
out->
values
= NULL;
132
133
if
(nnz_half > 0) {
134
out->
col_idx
= (
size_t
*)
lmmc_memory_alloc
(col_idx_bytes);
135
if
(out->
col_idx
== NULL) {
136
lmmc_memory_free
(out->
row_ptr
);
137
out->
row_ptr
= NULL;
138
return
LMMC_STATUS_ALLOCATION_FAILED
;
139
}
140
141
out->
values
= (
lmmc_real_t
*)
lmmc_memory_alloc
(val_bytes);
142
if
(out->
values
== NULL) {
143
lmmc_memory_free
(out->
col_idx
);
144
lmmc_memory_free
(out->
row_ptr
);
145
out->
col_idx
= NULL;
146
out->
row_ptr
= NULL;
147
return
LMMC_STATUS_ALLOCATION_FAILED
;
148
}
149
}
150
if
(nnz_half == 0) {
151
for
(i = 0; i < n; ++i) {
152
out->
row_ptr
[i] = 0;
153
}
154
out->
row_ptr
[n] = 0;
155
out->
n
= n;
156
out->
nnz
= 0;
157
out->
half
= half;
158
out->
owns_data
= 1;
159
return
LMMC_STATUS_OK
;
160
}
161
162
/* 第二遍:填充数据 */
163
lmmc_sparse_sym_copy(full, half, out);
164
165
out->
n
= n;
166
out->
nnz
= nnz_half;
167
out->
half
= half;
168
out->
owns_data
= 1;
169
return
LMMC_STATUS_OK
;
170
}
171
172
lmmc_status_t
lmmc_sparse_sym_spmv
(
const
lmmc_sparse_sym_csr_t
* A,
173
const
lmmc_vec_t
* x,
lmmc_vec_t
* y) {
174
size_t
i;
175
lmmc_real_t
zero;
176
lmmc_real_t
prod;
177
178
if
(A == NULL || x == NULL || y == NULL) {
179
return
LMMC_STATUS_INVALID_ARGUMENT
;
180
}
181
if
(x->
data
== NULL || y->
data
== NULL) {
182
return
LMMC_STATUS_INVALID_ARGUMENT
;
183
}
184
if
(A->
row_ptr
== NULL) {
185
return
LMMC_STATUS_INVALID_ARGUMENT
;
186
}
187
if
(A->
nnz
> 0 && (A->
col_idx
== NULL || A->
values
== NULL)) {
188
return
LMMC_STATUS_INVALID_ARGUMENT
;
189
}
190
if
(x->
size
!= A->
n
|| y->
size
!= A->
n
) {
191
return
LMMC_STATUS_DIMENSION_MISMATCH
;
192
}
193
194
/* 清零输出向量 */
195
LMMC_REAL_INIT
(&zero);
196
LMMC_REAL_INIT
(&prod);
197
LMMC_REAL_SET_D
(&zero, 0.0);
198
199
for
(i = 0; i < A->
n
; ++i) {
200
LMMC_REAL_SET_D
(&y->
data
[i], 0.0);
201
}
202
203
/* 对称 SpMV:利用对称性,每个非对角元贡献两次 */
204
lmmc_sparse_sym_accumulate(A, x, y, &prod);
205
206
LMMC_REAL_CLEAR
(&zero);
207
LMMC_REAL_CLEAR
(&prod);
208
return
LMMC_STATUS_OK
;
209
}
210
211
void
lmmc_sparse_sym_csr_destroy
(
lmmc_sparse_sym_csr_t
* s) {
212
if
(s == NULL) {
213
return
;
214
}
215
if
(s->
owns_data
) {
216
if
(s->
row_ptr
!= NULL) {
217
lmmc_memory_free
(s->
row_ptr
);
218
}
219
if
(s->
col_idx
!= NULL) {
220
lmmc_memory_free
(s->
col_idx
);
221
}
222
if
(s->
values
!= NULL) {
223
lmmc_memory_free
(s->
values
);
224
}
225
}
226
s->
row_ptr
= NULL;
227
s->
col_idx
= NULL;
228
s->
values
= NULL;
229
s->
n
= 0;
230
s->
nnz
= 0;
231
s->
owns_data
= 0;
232
}
LMMC_REAL_CLEAR
#define LMMC_REAL_CLEAR(x)
释放一个 lmmc_real_t 变量(POD 类型为空操作)。
定义
config.h:38
LMMC_REAL_INIT
#define LMMC_REAL_INIT(x)
初始化一个 lmmc_real_t 变量(POD 类型为空操作)。
定义
config.h:36
LMMC_REAL_ADD
#define LMMC_REAL_ADD(res, a, b)
计算 *res = *a + *b 。
定义
config.h:46
lmmc_real_t
double lmmc_real_t
Public and internal LMMC real type.
定义
config.h:28
LMMC_REAL_SET
#define LMMC_REAL_SET(dst, src)
将一个 lmmc_real_t 赋值到另一个:*dst = *src 。
定义
config.h:41
LMMC_REAL_MUL
#define LMMC_REAL_MUL(res, a, b)
计算 *res = *a * *b 。
定义
config.h:50
LMMC_REAL_SET_D
#define LMMC_REAL_SET_D(dst, dbl)
将一个 double 字面量赋值到 lmmc_real_t 。
定义
config.h:43
lmmc_vec_t::size
size_t size
定义
dense_types.h:32
lmmc_vec_t::data
lmmc_real_t * data
定义
dense_types.h:33
lmmc_vec_t
一维稠密向量。
定义
dense_types.h:31
internal.h
LMMC 内部使用的公共工具(仅源文件可见).
lmmc_memory_alloc
void * lmmc_memory_alloc(size_t size)
定义
memory_bridge.c:46
lmmc_memory_free
void lmmc_memory_free(void *pointer)
定义
memory_bridge.c:75
memory_bridge.h
Private recoverable allocator for persistent LMMC ownership.
sparse.h
lmmc_sparse_sym_spmv
lmmc_status_t lmmc_sparse_sym_spmv(const lmmc_sparse_sym_csr_t *A, const lmmc_vec_t *x, lmmc_vec_t *y)
对称半存储 SpMV:y = A * x 。
定义
sparse_symmetric.c:172
sparse_internal.h
稀疏矩阵模块内部共享辅助函数(仅源文件可见)。
lmmc_sparse_sym_csr_from_csr
lmmc_status_t lmmc_sparse_sym_csr_from_csr(const lmmc_sparse_mat_t *full, lmmc_sparse_sym_half_t half, lmmc_sparse_sym_csr_t *out)
从完整 CSR 矩阵提取对称半存储。
定义
sparse_symmetric.c:89
lmmc_sparse_sym_csr_destroy
void lmmc_sparse_sym_csr_destroy(lmmc_sparse_sym_csr_t *s)
销毁对称半存储 CSR 矩阵,按所有权释放底层缓冲区。
定义
sparse_symmetric.c:211
lmmc_sparse_sym_csr_t::half
lmmc_sparse_sym_half_t half
定义
sparse_types.h:120
LMMC_SPARSE_CSR
@ LMMC_SPARSE_CSR
定义
sparse_types.h:14
lmmc_sparse_mat_t::rows
size_t rows
定义
sparse_types.h:35
lmmc_sparse_mat_t::row_ptr
size_t * row_ptr
定义
sparse_types.h:38
lmmc_sparse_sym_half_t
lmmc_sparse_sym_half_t
对称半存储选择:上三角或下三角。
定义
sparse_types.h:104
LMMC_SPARSE_SYM_UPPER
@ LMMC_SPARSE_SYM_UPPER
定义
sparse_types.h:105
lmmc_sparse_mat_t::col_idx
size_t * col_idx
定义
sparse_types.h:39
lmmc_sparse_sym_csr_t::values
lmmc_real_t * values
定义
sparse_types.h:119
lmmc_sparse_mat_t::values
lmmc_real_t * values
定义
sparse_types.h:40
lmmc_sparse_sym_csr_t::col_idx
size_t * col_idx
定义
sparse_types.h:118
lmmc_sparse_sym_csr_t::n
size_t n
定义
sparse_types.h:115
lmmc_sparse_mat_t::format
lmmc_sparse_format_t format
定义
sparse_types.h:41
lmmc_sparse_mat_t::cols
size_t cols
定义
sparse_types.h:36
lmmc_sparse_sym_csr_t::owns_data
int owns_data
定义
sparse_types.h:121
lmmc_sparse_sym_csr_t::nnz
size_t nnz
定义
sparse_types.h:116
lmmc_sparse_sym_csr_t::row_ptr
size_t * row_ptr
定义
sparse_types.h:117
lmmc_sparse_mat_t
通用稀疏矩阵(CSR / CSC 共用同一结构)。
定义
sparse_types.h:34
lmmc_sparse_sym_csr_t
对称半存储 CSR 格式矩阵。
定义
sparse_types.h:114
lmmc_status_t
lmmc_status_t
LMMC 库统一返回的状态码.
定义
status.h:22
LMMC_STATUS_OK
@ LMMC_STATUS_OK
定义
status.h:23
LMMC_STATUS_DIMENSION_MISMATCH
@ LMMC_STATUS_DIMENSION_MISMATCH
定义
status.h:25
LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_ALLOCATION_FAILED
定义
status.h:26
LMMC_STATUS_INVALID_ARGUMENT
@ LMMC_STATUS_INVALID_ARGUMENT
定义
status.h:24
src
sparse_symmetric.c
生成于
, 为 LMMC使用
1.18.0