Skip to content

Commit 2afb0dc

Browse files
committed
Upgrade to FLINT 3.5, memory bugs remain
1 parent 8838844 commit 2afb0dc

96 files changed

Lines changed: 765 additions & 608 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ autobenches = false
1414

1515
[dependencies]
1616
criterion = { version = "0.8", features = ["html_reports"] }
17-
flint-sys = "0.7"
17+
flint-sys = "0.9.0"
1818
libc = "0"
1919
paste = "1"
2020
rand = "0.10"

src/integer.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ pub use poly_over_z::PolyOverZ;
2626
pub(crate) use poly_over_z::fmpz_poly_helpers;
2727
pub use z::Z;
2828
pub(crate) use z::fmpz_helpers;
29+
30+
pub(crate) use mat_z::debug_fmpz_mat_struct;
31+
pub(crate) use z::debug_fmpz;

src/integer/mat_poly_over_z.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//! This implementation uses the [FLINT](https://flintlib.org/) library.
1111
1212
use crate::utils::parse::partial_string;
13-
use flint_sys::fmpz_poly_mat::fmpz_poly_mat_struct;
13+
use flint_sys::fmpz_types::fmpz_poly_mat_struct;
1414
use std::fmt;
1515

1616
mod arithmetic;
@@ -88,10 +88,20 @@ impl fmt::Debug for MatPolyOverZ {
8888
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8989
write!(
9090
f,
91-
"MatPolyOverZ: {{matrix: {}, storage: {:?}}}",
91+
"MatPolyOverZ: {{matrix: {}, storage: {{ matrix: {}}}}}",
9292
// printing the entire matrix is not meaningful for large matrices
9393
partial_string(self, 3, 3),
94-
self.matrix
94+
debug_fmpz_poly_mat_struct(&self.matrix)
9595
)
9696
}
9797
}
98+
99+
pub(crate) fn debug_fmpz_poly_mat_struct(value: &fmpz_poly_mat_struct) -> String {
100+
format!(
101+
"fmpz_poly_mat_struct {{ entries: {:#x}, r: {}, c: {}, stride: {} }}",
102+
value.entries.addr(),
103+
value.r,
104+
value.c,
105+
value.stride
106+
)
107+
}

src/integer/mat_poly_over_z/get.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ use crate::{
1414
traits::{MatrixDimensions, MatrixGetEntry, MatrixGetSubmatrix},
1515
};
1616
use flint_sys::{
17-
fmpz_poly::{fmpz_poly_set, fmpz_poly_struct},
17+
fmpz_poly::fmpz_poly_set,
1818
fmpz_poly_mat::{
1919
fmpz_poly_mat_entry, fmpz_poly_mat_init_set, fmpz_poly_mat_window_clear,
2020
fmpz_poly_mat_window_init,
2121
},
22+
fmpz_types::fmpz_poly_struct,
2223
};
2324
use std::mem::MaybeUninit;
2425

@@ -178,7 +179,7 @@ impl MatPolyOverZ {
178179
for row in 0..self.get_num_rows() {
179180
for col in 0..self.get_num_columns() {
180181
// efficiently get entry without cloning the entry itself
181-
let entry = unsafe { *fmpz_poly_mat_entry(&self.matrix, row, col) };
182+
let entry = unsafe { std::ptr::read(fmpz_poly_mat_entry(&self.matrix, row, col)) };
182183
entries.push(entry);
183184
}
184185
}
@@ -592,16 +593,16 @@ mod test_collect_entries {
592593
let entries_2 = mat_2.collect_entries();
593594

594595
assert_eq!(entries_1.len(), 6);
595-
assert_eq!(unsafe { *entries_1[0].coeffs }.0, 1);
596-
assert!(unsafe { *entries_1[2].coeffs }.0 >= 2_i64.pow(62));
597-
assert!(unsafe { *entries_1[3].coeffs }.0 >= 2_i64.pow(62));
598-
assert_eq!(unsafe { *entries_1[4].coeffs }.0, -3);
596+
assert_eq!(unsafe { *entries_1[0].coeffs }, 1);
597+
assert!(unsafe { *entries_1[2].coeffs } >= 2_i64.pow(62));
598+
assert!(unsafe { *entries_1[3].coeffs } >= 2_i64.pow(62));
599+
assert_eq!(unsafe { *entries_1[4].coeffs }, -3);
599600

600601
assert_eq!(entries_2.len(), 2);
601-
assert_eq!(unsafe { *entries_2[0].coeffs.offset(0) }.0, -1);
602+
assert_eq!(unsafe { *entries_2[0].coeffs.offset(0) }, -1);
602603
assert_eq!(entries_2[0].length, 1);
603-
assert_eq!(unsafe { *entries_2[1].coeffs.offset(0) }.0, 1);
604-
assert_eq!(unsafe { *entries_2[1].coeffs.offset(1) }.0, 2);
604+
assert_eq!(unsafe { *entries_2[1].coeffs.offset(0) }, 1);
605+
assert_eq!(unsafe { *entries_2[1].coeffs.offset(1) }, 2);
605606
assert_eq!(entries_2[1].length, 2);
606607
}
607608
}

src/integer/mat_poly_over_z/ownership.rs

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl Clone for MatPolyOverZ {
3030
// we can unwrap since we know, that the number of rows and columns is positive and fits into an [`i64`]
3131
let mut clone = MatPolyOverZ::new(self.get_num_rows(), self.get_num_columns());
3232

33-
unsafe { fmpz_poly_mat_set(&mut clone.matrix, &mut self.matrix.to_owned()) }
33+
unsafe { fmpz_poly_mat_set(&mut clone.matrix, &self.matrix) }
3434

3535
clone
3636
}
@@ -78,20 +78,26 @@ mod test_clone {
7878
// an i64, both should be a pointer and their values should differ
7979
unsafe {
8080
assert_ne!(
81-
(*(*poly_1.matrix.entries).coeffs.offset(0)).0,
82-
(*(*poly_2.matrix.entries).coeffs.offset(0)).0
81+
(*(*poly_1.matrix.entries).coeffs.offset(0)),
82+
(*(*poly_2.matrix.entries).coeffs.offset(0))
8383
);
8484
}
8585
unsafe {
8686
assert_ne!(
87-
(*(*poly_1.matrix.entries).coeffs.offset(1)).0,
88-
(*(*poly_2.matrix.entries).coeffs.offset(1)).0
87+
(*(*poly_1.matrix.entries).coeffs.offset(1)),
88+
(*(*poly_2.matrix.entries).coeffs.offset(1))
8989
);
9090
}
9191

9292
// check if length of polynomial is correctly cloned
93-
assert_eq!(unsafe { *poly_1.matrix.entries.offset(0) }.length, 2);
94-
assert_eq!(unsafe { *poly_2.matrix.entries.offset(0) }.length, 2);
93+
assert_eq!(
94+
unsafe { std::ptr::read(poly_1.matrix.entries.offset(0)) }.length,
95+
2
96+
);
97+
assert_eq!(
98+
unsafe { std::ptr::read(poly_2.matrix.entries.offset(0)) }.length,
99+
2
100+
);
95101

96102
assert_eq!(poly_1, poly_2);
97103
}
@@ -110,20 +116,26 @@ mod test_clone {
110116
// both should be stored directly on stack and their values should be equal
111117
unsafe {
112118
assert_eq!(
113-
(*(*poly_1.matrix.entries).coeffs.offset(0)).0,
114-
(*(*poly_2.matrix.entries).coeffs.offset(0)).0
119+
(*(*poly_1.matrix.entries).coeffs.offset(0)),
120+
(*(*poly_2.matrix.entries).coeffs.offset(0))
115121
);
116122
}
117123
unsafe {
118124
assert_eq!(
119-
(*(*poly_1.matrix.entries).coeffs.offset(1)).0,
120-
(*(*poly_2.matrix.entries).coeffs.offset(1)).0
125+
(*(*poly_1.matrix.entries).coeffs.offset(1)),
126+
(*(*poly_2.matrix.entries).coeffs.offset(1))
121127
);
122128
}
123129

124130
// check if length of polynomial is correctly cloned
125-
assert_eq!(unsafe { *poly_1.matrix.entries.offset(0) }.length, 2);
126-
assert_eq!(unsafe { *poly_2.matrix.entries.offset(0) }.length, 2);
131+
assert_eq!(
132+
unsafe { std::ptr::read(poly_1.matrix.entries.offset(0)) }.length,
133+
2
134+
);
135+
assert_eq!(
136+
unsafe { std::ptr::read(poly_2.matrix.entries.offset(0)) }.length,
137+
2
138+
);
127139

128140
assert_eq!(poly_1, poly_2);
129141
}
@@ -151,7 +163,7 @@ mod test_drop {
151163
/// Creates and drops a [`MatPolyOverZ`], and returns the storage points in memory
152164
fn create_and_drop_poly_over_z() -> i64 {
153165
let a = MatPolyOverZ::from_str(&format!("[[1 {}]]", u64::MAX)).unwrap();
154-
unsafe { *(*a.matrix.entries).coeffs.offset(0) }.0
166+
unsafe { *(*a.matrix.entries).coeffs.offset(0) }
155167
}
156168

157169
/// Check whether freed memory is reused afterwards
@@ -166,13 +178,12 @@ mod test_drop {
166178
assert!(set.capacity() < 5);
167179

168180
let a = MatPolyOverZ::from_str(&format!("[[2 {} {}]]", u64::MAX - 1, u64::MAX)).unwrap();
169-
let storage_point = unsafe { *(*a.matrix.entries).coeffs.offset(0) }.0;
181+
let storage_point = unsafe { *(*a.matrix.entries).coeffs.offset(0) };
170182

171183
// memory slots differ due to previously created large integer
172184
let d = MatPolyOverZ::from_str(&format!("[[2 {} {}]]", u64::MAX - 1, u64::MAX)).unwrap();
173-
assert_ne!(
174-
storage_point,
175-
unsafe { *(*d.matrix.entries).coeffs.offset(0) }.0
176-
);
185+
assert_ne!(storage_point, unsafe {
186+
*(*d.matrix.entries).coeffs.offset(0)
187+
});
177188
}
178189
}

src/integer/mat_poly_over_z/unsafe_functions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
1212
use super::MatPolyOverZ;
1313
use crate::macros::unsafe_passthrough::{unsafe_getter, unsafe_setter};
14-
use flint_sys::fmpz_poly_mat::{fmpz_poly_mat_clear, fmpz_poly_mat_struct};
14+
use flint_sys::{fmpz_poly_mat::fmpz_poly_mat_clear, fmpz_types::fmpz_poly_mat_struct};
1515

1616
unsafe_getter!(MatPolyOverZ, matrix, fmpz_poly_mat_struct);
1717
unsafe_setter!(

src/integer/mat_z.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//! This implementation uses the [FLINT](https://flintlib.org/) library.
1111
1212
use crate::utils::parse::partial_string;
13-
use flint_sys::fmpz_mat::fmpz_mat_struct;
13+
use flint_sys::fmpz_types::fmpz_mat_struct;
1414
use std::fmt;
1515

1616
mod arithmetic;
@@ -99,10 +99,20 @@ impl fmt::Debug for MatZ {
9999
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100100
write!(
101101
f,
102-
"MatZ: {{matrix: {}, storage: {:?}}}",
102+
"MatZ: {{matrix: {}, storage: {{ matrix: {}}}}}",
103103
// printing the entire matrix is not meaningful for large matrices
104104
partial_string(self, 3, 3),
105-
self.matrix
105+
debug_fmpz_mat_struct(&self.matrix)
106106
)
107107
}
108108
}
109+
110+
pub(crate) fn debug_fmpz_mat_struct(value: &fmpz_mat_struct) -> String {
111+
format!(
112+
"fmpz_mat_struct {{ entries: {:#x}, r: {}, c: {}, stride: {} }}",
113+
value.entries.addr(),
114+
value.r,
115+
value.c,
116+
value.stride
117+
)
118+
}

src/integer/mat_z/arithmetic/mul.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ impl Mul<&MatZq> for &MatZ {
9797
other.get_mod(),
9898
);
9999
unsafe {
100-
fmpz_mat_mul(&mut new.matrix.mat[0], &self.matrix, &other.matrix.mat[0]);
101-
_fmpz_mod_mat_reduce(&mut new.matrix)
100+
fmpz_mat_mul(&mut new.matrix, &self.matrix, &other.matrix);
101+
_fmpz_mod_mat_reduce(&mut new.matrix, other.modulus.get_fmpz_mod_ctx_struct())
102102
}
103103
new
104104
}

src/integer/mat_z/arithmetic/sub.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ impl Sub<&MatZq> for &MatZ {
135135

136136
let mut out = MatZq::new(self.get_num_rows(), self.get_num_columns(), other.get_mod());
137137
unsafe {
138-
fmpz_mat_sub(&mut out.matrix.mat[0], &self.matrix, &other.matrix.mat[0]);
139-
_fmpz_mod_mat_reduce(&mut out.matrix);
138+
fmpz_mat_sub(&mut out.matrix, &self.matrix, &other.matrix);
139+
_fmpz_mod_mat_reduce(&mut out.matrix, other.modulus.get_fmpz_mod_ctx_struct());
140140
}
141141
out
142142
}

src/integer/mat_z/get.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ use crate::{
1414
traits::{MatrixDimensions, MatrixGetEntry, MatrixGetSubmatrix},
1515
};
1616
use flint_sys::{
17-
fmpz::{fmpz, fmpz_init_set},
17+
flint::fmpz,
18+
fmpz::fmpz_init_set,
1819
fmpz_mat::{fmpz_mat_entry, fmpz_mat_init_set, fmpz_mat_window_clear, fmpz_mat_window_init},
1920
};
2021
use std::mem::MaybeUninit;
@@ -78,7 +79,7 @@ impl MatrixGetEntry<Z> for MatZ {
7879
/// assert_eq!(unsafe { matrix.get_entry_unchecked(2, 1) }, Z::from(8));
7980
/// ```
8081
unsafe fn get_entry_unchecked(&self, row: i64, column: i64) -> Z {
81-
let mut copy = fmpz(0);
82+
let mut copy: fmpz = 0;
8283
let entry = unsafe { fmpz_mat_entry(&self.matrix, row, column) };
8384
unsafe { fmpz_init_set(&mut copy, entry) };
8485

@@ -685,15 +686,15 @@ mod test_collect_entries {
685686
let entries_2 = mat_2.collect_entries();
686687

687688
assert_eq!(entries_1.len(), 6);
688-
assert_eq!(entries_1[0].0, 1);
689-
assert_eq!(entries_1[1].0, 2);
690-
assert!(entries_1[2].0 >= 2_i64.pow(62));
691-
assert!(entries_1[3].0 >= 2_i64.pow(62));
692-
assert_eq!(entries_1[4].0, 3);
693-
assert_eq!(entries_1[5].0, 4);
689+
assert_eq!(entries_1[0], 1);
690+
assert_eq!(entries_1[1], 2);
691+
assert!(entries_1[2] >= 2_i64.pow(62));
692+
assert!(entries_1[3] >= 2_i64.pow(62));
693+
assert_eq!(entries_1[4], 3);
694+
assert_eq!(entries_1[5], 4);
694695

695696
assert_eq!(entries_2.len(), 2);
696-
assert_eq!(entries_2[0].0, -1);
697-
assert_eq!(entries_2[1].0, 2);
697+
assert_eq!(entries_2[0], -1);
698+
assert_eq!(entries_2[1], 2);
698699
}
699700
}

0 commit comments

Comments
 (0)