LMMC
Lamina Mathematic core
Toggle main menu visibility
载入中...
搜索中...
未找到
tensor_nd_views.c
浏览该文件的文档.
1
5
#include "
internal.h
"
6
#include "
internal/tensor_nd_internal.h
"
7
8
static
lmmc_status_t
lmmc_tensor_nd_permutation_shape(
9
const
lmmc_tensor_nd_t
* in,
const
size_t
* perm,
const
lmmc_tensor_nd_t
* out,
10
size_t
* new_dims) {
11
int
seen[
LMMC_TENSOR_MAX_NDIM
] = {0};
12
if
(!lmmc_tensor_nd_descriptor_is_valid(in) || perm == NULL || out == NULL) {
13
return
LMMC_STATUS_INVALID_ARGUMENT
;
14
}
15
if
(in == out && in->
owns_data
) {
16
return
LMMC_STATUS_INVALID_ARGUMENT
;
17
}
18
for
(
size_t
i = 0; i < in->
ndim
; ++i) {
19
if
(perm[i] >= in->
ndim
|| seen[perm[i]]) {
20
return
LMMC_STATUS_INVALID_ARGUMENT
;
21
}
22
seen[perm[i]] = 1;
23
new_dims[i] = in->
dims
[perm[i]];
24
}
25
return
LMMC_STATUS_OK
;
26
}
27
28
static
void
lmmc_tensor_nd_copy_permuted(
29
const
lmmc_tensor_nd_t
* in,
const
size_t
* perm,
lmmc_tensor_nd_t
* out) {
30
size_t
idx[
LMMC_TENSOR_MAX_NDIM
] = {0};
32
do
{
33
const
size_t
src_offset = lmmc_tensor_nd_offset(in->
ndim
, in->
strides
, idx);
34
size_t
dst_offset = 0;
35
for
(
size_t
i = 0; i < in->
ndim
; ++i) {
36
dst_offset += idx[perm[i]] * out->
strides
[i];
37
}
38
LMMC_REAL_SET
(&out->
data
[dst_offset], &in->
data
[src_offset]);
39
}
while
(lmmc_tensor_nd_next_index(in->
ndim
, in->
dims
, idx));
40
}
41
42
lmmc_status_t
lmmc_tensor_nd_permute
(
43
const
lmmc_tensor_nd_t
* in,
const
size_t
* perm,
lmmc_tensor_nd_t
* out) {
44
lmmc_tensor_nd_t
input_snapshot;
45
lmmc_tensor_nd_t
result = {0};
46
size_t
new_dims[
LMMC_TENSOR_MAX_NDIM
];
47
lmmc_status_t
st = lmmc_tensor_nd_permutation_shape(in, perm, out, new_dims);
48
if
(st !=
LMMC_STATUS_OK
) {
49
return
st;
50
}
51
if
(in == out) {
52
input_snapshot = *in;
53
in = &input_snapshot;
54
}
55
st = lmmc_tensor_nd_allocate_result(in->
ndim
, new_dims, &result);
56
if
(st !=
LMMC_STATUS_OK
) {
57
return
st;
58
}
59
lmmc_tensor_nd_copy_permuted(in, perm, &result);
60
*out = result;
61
return
LMMC_STATUS_OK
;
62
}
63
65
static
int
lmmc_tensor_nd_is_contiguous(
const
lmmc_tensor_nd_t
* t) {
66
size_t
i;
67
size_t
expected_stride;
68
if
(t == NULL || t->
ndim
== 0)
return
0;
69
70
expected_stride = 1;
71
for
(i = t->
ndim
; i > 0; --i) {
72
if
(t->
strides
[i - 1] != expected_stride)
return
0;
73
if
(t->
dims
[i - 1] == 0 ||
74
!lmmc_safe_mul_size(expected_stride, t->
dims
[i - 1], &expected_stride))
return
0;
75
}
76
return
1;
77
}
78
79
static
lmmc_status_t
lmmc_tensor_nd_validate_reshape(
80
const
lmmc_tensor_nd_t
* src,
size_t
new_ndim,
const
size_t
* new_dims,
81
const
lmmc_tensor_nd_t
* out_view) {
82
if
(!lmmc_tensor_nd_descriptor_is_valid(src) ||
83
new_dims == NULL || out_view == NULL) {
84
return
LMMC_STATUS_INVALID_ARGUMENT
;
85
}
87
if
(src == out_view && src->
owns_data
) {
88
return
LMMC_STATUS_INVALID_ARGUMENT
;
89
}
90
if
(new_ndim == 0 || new_ndim >
LMMC_TENSOR_MAX_NDIM
) {
91
return
LMMC_STATUS_INVALID_ARGUMENT
;
92
}
93
return
LMMC_STATUS_OK
;
94
}
95
96
97
lmmc_status_t
lmmc_tensor_nd_reshape_view
(
const
lmmc_tensor_nd_t
* src,
98
size_t
new_ndim,
const
size_t
* new_dims,
lmmc_tensor_nd_t
* out_view) {
99
size_t
old_total, new_total;
100
lmmc_tensor_nd_t
view = {0};
101
if
(lmmc_tensor_nd_validate_reshape(src, new_ndim, new_dims, out_view) !=
LMMC_STATUS_OK
) {
102
return
LMMC_STATUS_INVALID_ARGUMENT
;
103
}
104
if
(lmmc_tensor_nd_layout(new_ndim, new_dims, view.
strides
, &new_total) !=
105
LMMC_STATUS_OK
||
106
lmmc_tensor_nd_layout(src->
ndim
, src->
dims
, NULL, &old_total) !=
107
LMMC_STATUS_OK
) {
108
return
LMMC_STATUS_INVALID_ARGUMENT
;
109
}
110
if
(old_total != new_total) {
111
return
LMMC_STATUS_INVALID_ARGUMENT
;
112
}
113
if
(!lmmc_tensor_nd_is_contiguous(src)) {
114
return
LMMC_STATUS_INVALID_ARGUMENT
;
115
}
116
118
for
(
size_t
i = 0; i < new_ndim; ++i) {
119
view.
dims
[i] = new_dims[i];
120
}
121
view.
ndim
= new_ndim;
122
view.
data
= src->
data
;
123
view.
owns_data
= 0;
124
*out_view = view;
125
return
LMMC_STATUS_OK
;
126
}
LMMC_REAL_SET
#define LMMC_REAL_SET(dst, src)
将一个 lmmc_real_t 赋值到另一个:*dst = *src 。
定义
config.h:41
internal.h
LMMC 内部使用的公共工具(仅源文件可见).
lmmc_status_t
lmmc_status_t
LMMC 库统一返回的状态码.
定义
status.h:22
LMMC_STATUS_OK
@ LMMC_STATUS_OK
定义
status.h:23
LMMC_STATUS_INVALID_ARGUMENT
@ LMMC_STATUS_INVALID_ARGUMENT
定义
status.h:24
lmmc_tensor_nd_permute
lmmc_status_t lmmc_tensor_nd_permute(const lmmc_tensor_nd_t *in, const size_t *perm, lmmc_tensor_nd_t *out)
按指定轴顺序置换张量,生成独立数据副本(转置的推广)。
定义
tensor_nd_views.c:42
lmmc_tensor_nd_t::owns_data
int owns_data
定义
tensor_nd.h:30
lmmc_tensor_nd_t::ndim
size_t ndim
定义
tensor_nd.h:26
LMMC_TENSOR_MAX_NDIM
#define LMMC_TENSOR_MAX_NDIM
支持的最大张量维度.
定义
tensor_nd.h:17
lmmc_tensor_nd_t::data
lmmc_real_t * data
定义
tensor_nd.h:29
lmmc_tensor_nd_reshape_view
lmmc_status_t lmmc_tensor_nd_reshape_view(const lmmc_tensor_nd_t *src, size_t new_ndim, const size_t *new_dims, lmmc_tensor_nd_t *out_view)
零拷贝重塑 N-D 张量,返回共享缓冲区的非拥有视图。
定义
tensor_nd_views.c:97
lmmc_tensor_nd_t::dims
size_t dims[LMMC_TENSOR_MAX_NDIM]
定义
tensor_nd.h:27
lmmc_tensor_nd_t::strides
size_t strides[LMMC_TENSOR_MAX_NDIM]
定义
tensor_nd.h:28
lmmc_tensor_nd_t
N-D 张量结构.
定义
tensor_nd.h:25
tensor_nd_internal.h
N 维张量结果存储、索引遍历与乘积累加。
src
tensor_nd_views.c
生成于
, 为 LMMC使用
1.18.0