LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
tensor_nd_views.c
浏览该文件的文档.
1
5#include "internal.h"
7
8static 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) {
14 }
15 if (in == out && in->owns_data) {
17 }
18 for (size_t i = 0; i < in->ndim; ++i) {
19 if (perm[i] >= in->ndim || seen[perm[i]]) {
21 }
22 seen[perm[i]] = 1;
23 new_dims[i] = in->dims[perm[i]];
24 }
25 return LMMC_STATUS_OK;
26}
27
28static 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
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
65static 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
79static 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) {
85 }
87 if (src == out_view && src->owns_data) {
89 }
90 if (new_ndim == 0 || new_ndim > LMMC_TENSOR_MAX_NDIM) {
92 }
93 return LMMC_STATUS_OK;
94}
95
96
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) {
103 }
104 if (lmmc_tensor_nd_layout(new_ndim, new_dims, view.strides, &new_total) !=
106 lmmc_tensor_nd_layout(src->ndim, src->dims, NULL, &old_total) !=
109 }
110 if (old_total != new_total) {
112 }
113 if (!lmmc_tensor_nd_is_contiguous(src)) {
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}
#define LMMC_REAL_SET(dst, src)
将一个 lmmc_real_t 赋值到另一个:*dst = *src 。
LMMC 内部使用的公共工具(仅源文件可见).
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_INVALID_ARGUMENT
lmmc_status_t lmmc_tensor_nd_permute(const lmmc_tensor_nd_t *in, const size_t *perm, lmmc_tensor_nd_t *out)
按指定轴顺序置换张量,生成独立数据副本(转置的推广)。
#define LMMC_TENSOR_MAX_NDIM
支持的最大张量维度.
lmmc_real_t * data
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 张量,返回共享缓冲区的非拥有视图。
size_t dims[LMMC_TENSOR_MAX_NDIM]
size_t strides[LMMC_TENSOR_MAX_NDIM]
N-D 张量结构.
N 维张量结果存储、索引遍历与乘积累加。