1use crate::models::base::BaseModel;
10use crate::ModelConfig;
11use anyhow::{anyhow, Result};
12use chrono::{DateTime, Utc};
13use scirs2_core::ndarray_ext::{Array1, Array2, Array3};
14use serde::{Deserialize, Serialize};
15use std::collections::HashMap;
16use uuid::Uuid;
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct MatrixF64 {
21 pub rows: usize,
22 pub cols: usize,
23 pub data: Vec<f64>,
24}
25
26impl MatrixF64 {
27 pub fn from_array(a: &Array2<f64>) -> Self {
29 let (rows, cols) = a.dim();
30 Self {
31 rows,
32 cols,
33 data: a.iter().copied().collect(),
34 }
35 }
36
37 pub fn to_array(&self) -> Result<Array2<f64>> {
39 if self.rows * self.cols != self.data.len() {
40 return Err(anyhow!(
41 "corrupt matrix payload: {}x{} != {} elements",
42 self.rows,
43 self.cols,
44 self.data.len()
45 ));
46 }
47 Array2::from_shape_vec((self.rows, self.cols), self.data.clone())
48 .map_err(|e| anyhow!("failed to rebuild matrix: {}", e))
49 }
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct MatrixF32 {
55 pub rows: usize,
56 pub cols: usize,
57 pub data: Vec<f32>,
58}
59
60impl MatrixF32 {
61 pub fn from_array(a: &Array2<f32>) -> Self {
62 let (rows, cols) = a.dim();
63 Self {
64 rows,
65 cols,
66 data: a.iter().copied().collect(),
67 }
68 }
69
70 pub fn to_array(&self) -> Result<Array2<f32>> {
71 if self.rows * self.cols != self.data.len() {
72 return Err(anyhow!(
73 "corrupt matrix payload: {}x{} != {} elements",
74 self.rows,
75 self.cols,
76 self.data.len()
77 ));
78 }
79 Array2::from_shape_vec((self.rows, self.cols), self.data.clone())
80 .map_err(|e| anyhow!("failed to rebuild matrix: {}", e))
81 }
82}
83
84#[derive(Debug, Clone, Serialize, Deserialize)]
86pub struct VectorF32 {
87 pub data: Vec<f32>,
88}
89
90impl VectorF32 {
91 pub fn from_array(a: &Array1<f32>) -> Self {
92 Self {
93 data: a.iter().copied().collect(),
94 }
95 }
96
97 pub fn to_array(&self) -> Array1<f32> {
98 Array1::from_vec(self.data.clone())
99 }
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct Tensor3F64 {
105 pub d0: usize,
106 pub d1: usize,
107 pub d2: usize,
108 pub data: Vec<f64>,
109}
110
111impl Tensor3F64 {
112 pub fn from_array(a: &Array3<f64>) -> Self {
113 let (d0, d1, d2) = a.dim();
114 Self {
115 d0,
116 d1,
117 d2,
118 data: a.iter().copied().collect(),
119 }
120 }
121
122 pub fn to_array(&self) -> Result<Array3<f64>> {
123 if self.d0 * self.d1 * self.d2 != self.data.len() {
124 return Err(anyhow!(
125 "corrupt tensor payload: {}x{}x{} != {} elements",
126 self.d0,
127 self.d1,
128 self.d2,
129 self.data.len()
130 ));
131 }
132 Array3::from_shape_vec((self.d0, self.d1, self.d2), self.data.clone())
133 .map_err(|e| anyhow!("failed to rebuild tensor: {}", e))
134 }
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct BaseModelSnapshot {
143 pub config: ModelConfig,
144 pub model_id: Uuid,
145 pub entity_to_id: HashMap<String, usize>,
146 pub id_to_entity: HashMap<usize, String>,
147 pub relation_to_id: HashMap<String, usize>,
148 pub id_to_relation: HashMap<usize, String>,
149 pub triples: Vec<(usize, usize, usize)>,
150 pub is_trained: bool,
151 pub creation_time: DateTime<Utc>,
152 pub last_training_time: Option<DateTime<Utc>>,
153}
154
155impl BaseModelSnapshot {
156 pub fn capture(base: &BaseModel) -> Self {
158 Self {
159 config: base.config.clone(),
160 model_id: base.model_id,
161 entity_to_id: base.entity_to_id.clone(),
162 id_to_entity: base.id_to_entity.clone(),
163 relation_to_id: base.relation_to_id.clone(),
164 id_to_relation: base.id_to_relation.clone(),
165 triples: base.triples.clone(),
166 is_trained: base.is_trained,
167 creation_time: base.creation_time,
168 last_training_time: base.last_training_time,
169 }
170 }
171
172 pub fn restore_into(self, base: &mut BaseModel) {
175 base.config = self.config;
176 base.model_id = self.model_id;
177 base.entity_to_id = self.entity_to_id;
178 base.id_to_entity = self.id_to_entity;
179 base.relation_to_id = self.relation_to_id;
180 base.id_to_relation = self.id_to_relation;
181 base.positive_triples = self.triples.iter().copied().collect();
182 base.triples = self.triples;
183 base.is_trained = self.is_trained;
184 base.creation_time = self.creation_time;
185 base.last_training_time = self.last_training_time;
186 }
187}