1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2025-01-08 20:33:36 +01:00

Introducing read test

This commit is contained in:
Anthony Scemama 2023-10-17 18:40:03 +02:00
parent 38946c8ab7
commit 000c83f275
2 changed files with 230 additions and 46 deletions

View File

@ -83,6 +83,9 @@ def make_functions():
"str" : "str"}
r = ["""
use std::iter::zip;
use std::ffi::CString;
impl File {""" ]
for group in data:
@ -147,15 +150,17 @@ pub fn write_{group_l}_{element_l}(&self, data: {type_r}) -> Result<(), ExitCode
elif data[group][element][0] in [ "str" ]:
r += [ """
pub fn read_{group_l}_{element_l}(&self, capacity: usize) -> Result<String, ExitCode> {
let mut data_c = String::with_capacity(capacity);
let data_c = data_c.as_mut_ptr() as *mut c_char;
let data_c = CString::new(vec![ b' ' ; capacity]).expect("CString::new failed");
let (rc, data) = unsafe {
let data_c = data_c.into_raw() as *mut c_char;
let rc = c::trexio_read_{group}_{element}(self.ptr, data_c, capacity.try_into().expect("try_into failed in read_{group_l}_{element_l}"));
(rc, String::from_raw_parts(data_c as *mut u8, capacity, capacity))
(rc, CString::from_raw(data_c))
};
rc_return(data, rc)
let result : String = CString::into_string(data).expect("into_string failed in read_{group_l}_{element_l}");
rc_return(result, rc)
}
pub fn write_{group_l}_{element_l}(&self, data: &str) -> Result<(), ExitCode> {
let size : i32 = data.len().try_into().expect("try_into failed in write_{group_l}_{element_l}");
let data = string_to_c(data);
@ -205,11 +210,12 @@ pub fn read_{group_l}_{element_l}(&self) -> Result<{type_r}, ExitCode> {
t_prime += [f" let size = size * {dim};"]
t += t_prime
t += [ """
let data: Vec<{type_r}> = Vec::with_capacity(size);
let data_c = data.as_ptr() as *mut {type_c};
let (rc, data) = unsafe {
let rc = c::trexio_read_safe_{group}_{element}_64(self.ptr, data_c, size.try_into().expect("try_into failed in read_{group}_{element}"));
(rc, data)
let mut data: Vec<{type_r}> = Vec::with_capacity(size);
let rc = unsafe {
let data_c = data.as_mut_ptr() as *mut {type_c};
let rc = c::trexio_read_safe_{group}_{element}_64(self.ptr, data_c, size.try_into().expect("try_into failed in read_{group}_{element} (size)"));
data.set_len(size);
rc
};
rc_return(data, rc)
}
@ -223,7 +229,7 @@ pub fn read_{group_l}_{element_l}(&self) -> Result<{type_r}, ExitCode> {
.replace("{element_l}",element_l) ]
r += [ """
pub fn write_{group_l}_{element_l}(&self, data: Vec<{type_r}>) -> Result<(), ExitCode> {
pub fn write_{group_l}_{element_l}(&self, data: &[{type_r}]) -> Result<(), ExitCode> {
let size: i64 = data.len().try_into().expect("try_into failed in write_{group_l}_{element_l}");
let data = data.as_ptr() as *const {type_c};
let rc = unsafe { c::trexio_write_safe_{group}_{element}_64(self.ptr, data, size) };
@ -249,14 +255,40 @@ pub fn write_{group_l}_{element_l}(&self, data: Vec<{type_r}>) -> Result<(), Exi
t_prime += [f" let size = size * {dim};"]
t += t_prime
t += [ """
let data = vec![ String::with_capacity(capacity) ; size ];
let data_c = data.as_ptr() as *mut *mut c_char;
let (rc, data) = unsafe {
let rc = c::trexio_read_{group}_{element}(self.ptr, data_c, capacity.try_into().expect("try_into failed in read_{group}_{element}") );
(rc, data)
// Allocate an array of *mut i8 pointers (initialized to null)
let mut dset_out: Vec<*mut i8> = vec![std::ptr::null_mut(); size];
// Allocate C-style strings and populate dset_out
for i in 0..size{
let c_str: *mut i8 = unsafe { std::alloc::alloc_zeroed(std::alloc::Layout::array::<i8>(capacity).unwrap()) as *mut i8 };
if c_str.is_null() {
return Err(ExitCode::AllocationFailed);
}
dset_out[i] = c_str;
}
let rc = unsafe {
c::trexio_read_{group}_{element}(self.ptr, dset_out.as_mut_ptr(), capacity.try_into().expect("try_into failed in read_{group}_{element} (capacity)") )
};
rc_return(data, rc)
// Convert the populated C strings to Rust Strings
let mut rust_strings = Vec::new();
for &c_str in &dset_out {
let rust_str = unsafe {
std::ffi::CStr::from_ptr(c_str)
.to_string_lossy()
.into_owned()
};
rust_strings.push(rust_str);
}
// Clean up allocated C strings
for &c_str in &dset_out {
unsafe { std::alloc::dealloc(c_str as *mut u8, std::alloc::Layout::array::<i8>(capacity).unwrap()) };
}
rc_return(rust_strings, rc)
}
""" ]
r += [ '\n'.join(t)
@ -266,7 +298,7 @@ pub fn write_{group_l}_{element_l}(&self, data: Vec<{type_r}>) -> Result<(), Exi
.replace("{element_l}",element_l) ]
r += [ """
pub fn write_{group_l}_{element_l}(&self, data: Vec<&str>) -> Result<(), ExitCode> {
pub fn write_{group_l}_{element_l}(&self, data: &[&str]) -> Result<(), ExitCode> {
let mut size = 0;
// Find longest string
for s in data.iter() {
@ -274,9 +306,9 @@ pub fn write_{group_l}_{element_l}(&self, data: Vec<&str>) -> Result<(), ExitCod
size = if l>size {l} else {size};
}
size = size+1;
let data_c : Vec<std::ffi::CString> = data.iter().map(|&x| string_to_c(x)).collect::<Vec<_>>();
let data_c : Vec<CString> = data.iter().map(|&x| string_to_c(x)).collect::<Vec<_>>();
let data_c : Vec<*const c_char> = data_c.iter().map(|x| x.as_ptr() as *const c_char).collect::<Vec<_>>();
let size : i32 = size.try_into().expect("try_into failed in write_{group}_{element}");
let size : i32 = size.try_into().expect("try_into failed in write_{group}_{element} (size)");
let data_c = data_c.as_ptr() as *mut *const c_char;
let rc = unsafe { c::trexio_write_{group}_{element}(self.ptr, data_c, size) };
rc_return((), rc)
@ -289,12 +321,42 @@ pub fn write_{group_l}_{element_l}(&self, data: Vec<&str>) -> Result<(), ExitCod
elif data[group][element][0] in [ "float sparse" ]:
size = len(data[group][element][1])
typ = "&[(" + ",".join( [ "usize" for _ in range(size) ]) + ", f64)]"
typ = "(" + ",".join( [ "usize" for _ in range(size) ]) + ", f64)"
r += [ ("""
pub fn write_{group_l}_{element_l}(&self, offset: usize, data: {typ}) -> Result<(), ExitCode> {
pub fn read_{group_l}_{element_l}(&self, offset: usize, buffer_size:usize) -> Result<Vec<{typ}>, ExitCode> {
let idx = Vec::<i32>::with_capacity({size}*buffer_size);
let val = Vec::<f64>::with_capacity(buffer_size);
let idx_ptr = idx.as_ptr() as *mut i32;
let val_ptr = val.as_ptr() as *mut f64;
let offset: i64 = offset.try_into().expect("try_into failed in read_{group}_{element} (offset)");
let mut buffer_size_read: i64 = buffer_size.try_into().expect("try_into failed in read_{group}_{element} (buffer_size)");
let rc = unsafe { c::trexio_read_safe_{group}_{element}(self.ptr,
offset, &mut buffer_size_read, idx_ptr, buffer_size_read, val_ptr, buffer_size_read) };
let idx: Vec::<&[i32]> = idx.chunks({size}).collect();
let mut result = Vec::<{typ}>::with_capacity(buffer_size);
for (i, v) in zip(idx, val) {
result.push( ( """ +
','.join([ f"i[{k}].try_into().unwrap()" for k in range(size) ]) +
""",v) );
}
rc_return(result, rc)
}
""")
.replace("{size}",str(size))
.replace("{typ}",typ)
.replace("{type_c}",type_c)
.replace("{type_r}",type_r)
.replace("{group}",group)
.replace("{group_l}",group_l)
.replace("{element}",element)
.replace("{element_l}",element_l) ]
r += [ ("""
pub fn write_{group_l}_{element_l}(&self, offset: usize, data: &[{typ}]) -> Result<(), ExitCode> {
let mut idx = Vec::<i32>::with_capacity({size}*data.len());
let mut val = Vec::<f64>::with_capacity(data.len());
// Array of indices
for d in data.iter() {
""" +
'\n'.join([ f" idx.push(d.{i}.try_into().unwrap());" for i in range(size) ]) +
@ -302,11 +364,11 @@ f"\n val.push(d.{size});" +
"""
}
let size_max: i64 = data.len().try_into().expect("try_into failed in write_{group}_{element}");
let size_max: i64 = data.len().try_into().expect("try_into failed in write_{group}_{element} (size_max)");
let buffer_size = size_max;
let idx_ptr = idx.as_ptr() as *const i32;
let val_ptr = val.as_ptr() as *const f64;
let offset: i64 = offset.try_into().expect("try_into failed in write_{group}_{element}");
let offset: i64 = offset.try_into().expect("try_into failed in write_{group}_{element} (offset)");
let rc = unsafe { c::trexio_write_safe_{group}_{element}(self.ptr,
offset, buffer_size, idx_ptr, size_max, val_ptr, size_max) };
rc_return((), rc)
@ -324,6 +386,8 @@ f"\n val.push(d.{size});" +
r += [ "}" ]
with open(generated_rs,'w') as f:
f.write('\n'.join(r))

View File

@ -9,18 +9,19 @@ fn write(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> {
let nucleus_num = 12;
let state_id = 2;
let charge = vec![6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1.0f64];
let coord = vec![ 0.00000000f64, 1.39250319 , 0.00 ,
-1.20594314, 0.69625160 , 0.00 ,
-1.20594314, -0.69625160 , 0.00 ,
0.00000000, -1.39250319 , 0.00 ,
1.20594314, -0.69625160 , 0.00 ,
1.20594314, 0.69625160 , 0.00 ,
-2.14171677, 1.23652075 , 0.00 ,
-2.14171677, -1.23652075 , 0.00 ,
0.00000000, -2.47304151 , 0.00 ,
2.14171677, -1.23652075 , 0.00 ,
2.14171677, 1.23652075 , 0.00 ,
0.00000000, 2.47304151 , 0.00 ];
let coord = vec![ [ 0.00000000f64, 1.39250319 , 0.00 ],
[ -1.20594314, 0.69625160 , 0.00 ],
[ -1.20594314, -0.69625160 , 0.00 ],
[ 0.00000000, -1.39250319 , 0.00 ],
[ 1.20594314, -0.69625160 , 0.00 ],
[ 1.20594314, 0.69625160 , 0.00 ],
[ -2.14171677, 1.23652075 , 0.00 ],
[ -2.14171677, -1.23652075 , 0.00 ],
[ 0.00000000, -2.47304151 , 0.00 ],
[ 2.14171677, -1.23652075 , 0.00 ],
[ 2.14171677, 1.23652075 , 0.00 ],
[ 0.00000000, 2.47304151 , 0.00 ]];
let flat_coord = coord.into_iter().flatten().collect::<Vec<f64>>();
let mo_num = 150;
let ao_num = 1000;
let basis_shell_num = 24;
@ -32,7 +33,7 @@ fn write(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> {
let sym_str = "B3U with some comments";
println!("{}", file_name);
println!("Write {}", file_name);
assert!( ! trexio::File::inquire(file_name)? );
let trex_file = trexio::File::open(file_name, 'w', back_end)?;
@ -45,12 +46,12 @@ fn write(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> {
assert!( ! trex_file.has_determinant_list()? );
trex_file.write_nucleus_num(nucleus_num)?;
trex_file.write_nucleus_charge(charge)?;
trex_file.write_nucleus_charge(&charge)?;
trex_file.write_nucleus_point_group(sym_str)?;
trex_file.write_nucleus_coord(coord)?;
trex_file.write_nucleus_label(label)?;
trex_file.write_nucleus_coord(&flat_coord)?;
trex_file.write_nucleus_label(&label)?;
trex_file.write_basis_shell_num(basis_shell_num)?;
trex_file.write_basis_nucleus_index(basis_nucleus_index)?;
trex_file.write_basis_nucleus_index(&basis_nucleus_index)?;
trex_file.write_state_id(state_id)?;
if ! trex_file.has_ao_num()? {
@ -66,13 +67,13 @@ fn write(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> {
let e: f64 = i as f64 -100.0f64;
energy.push(e);
}
trex_file.write_mo_energy(energy)?;
trex_file.write_mo_energy(&energy)?;
let mut spin = vec![0 ; mo_num];
for i in mo_num/2..mo_num {
spin[i] = 1;
}
trex_file.write_mo_spin(spin)?;
trex_file.write_mo_spin(&spin)?;
// Integrals
let nmax = 100;
@ -88,12 +89,129 @@ fn write(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> {
}
let mut offset = 0;
for i in 0..n_buffers {
for _ in 0..n_buffers {
trex_file.write_ao_2e_int_eri(offset, &ao_2e_int_eri[offset..offset+bufsize])?;
offset += bufsize;
}
// Determinants
let det_num = 50;
let mut det_list = Vec::with_capacity(det_num);
for i in 0..det_num {
let mut d = [0i64 ; 6 ];
for j in 0..6 {
d[j] = 6*(i as i64)+(j as i64);
}
det_list.push( Bitfield::from_vec(&d) );
}
let n_buffers = 5;
let bufsize = 50/n_buffers;
let mut offset = 0;
for _ in 0..n_buffers {
trex_file.write_determinant_list(offset, &det_list[offset..offset+bufsize])?;
offset += bufsize;
}
trex_file.close()
}
fn read(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> {
println!("Read {}", file_name);
assert!( trexio::File::inquire(file_name)? );
let trex_file = trexio::File::open(file_name, 'r', back_end)?;
assert!( trex_file.has_nucleus()? );
assert!( trex_file.has_nucleus_num()? );
assert!( trex_file.has_nucleus_charge()? );
assert!( trex_file.has_ao_2e_int()? );
assert!( trex_file.has_ao_2e_int_eri()? );
assert!( trex_file.has_determinant_list()? );
let nucleus_num = trex_file.read_nucleus_num()?;
assert_eq!(nucleus_num, 12);
let sym_str = trex_file.read_nucleus_point_group(64)?;
assert_eq!(sym_str, "B3U with some comments");
let charge = trex_file.read_nucleus_charge()?;
assert_eq!(charge, vec![6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1.0f64]);
let coord = trex_file.read_nucleus_coord()?;
assert_eq!(coord, vec![ 0.00000000f64, 1.39250319 , 0.00,
-1.20594314, 0.69625160 , 0.00,
-1.20594314, -0.69625160 , 0.00,
0.00000000, -1.39250319 , 0.00,
1.20594314, -0.69625160 , 0.00,
1.20594314, 0.69625160 , 0.00,
-2.14171677, 1.23652075 , 0.00,
-2.14171677, -1.23652075 , 0.00,
0.00000000, -2.47304151 , 0.00,
2.14171677, -1.23652075 , 0.00,
2.14171677, 1.23652075 , 0.00,
0.00000000, 2.47304151 , 0.00 ]);
let label = trex_file.read_nucleus_label(6)?;
assert_eq!(label, vec![ "C", "Na", "C", "C 66", "C",
"C", "H 99", "Ru", "H", "H", "H", "H" ]);
let basis_shell_num = trex_file.read_basis_shell_num()?;
assert_eq!(basis_shell_num, 24);
let basis_nucleus_index = trex_file.read_basis_nucleus_index()?;
let ref_val : Vec<usize> = (0..24).collect();
assert_eq!(basis_nucleus_index, ref_val);
let state_id = trex_file.read_state_id()?;
assert_eq!(state_id, 2);
let ao_num = trex_file.read_ao_num()?;
assert_eq!(ao_num, 1000);
let mo_num = trex_file.read_mo_num()?;
assert_eq!(mo_num, 150);
let mut energy_ref = Vec::with_capacity(mo_num);
for i in 0..mo_num {
let e: f64 = i as f64 -100.0f64;
energy_ref.push(e);
}
let energy = trex_file.read_mo_energy()?;
assert_eq!(energy, energy_ref);
let mut spin_ref = vec![0 ; mo_num];
for i in mo_num/2..mo_num {
spin_ref[i] = 1;
}
let spin = trex_file.read_mo_spin()?;
assert_eq!(spin, spin_ref);
/*
// Integrals
let nmax = 100;
let mut ao_2e_int_eri_ref = Vec::<(usize,usize,usize,usize,f64)>::with_capacity(nmax);
let n_buffers = 5;
let bufsize = nmax/n_buffers;
for i in 0..100 {
// Quadruplet of indices + value
let data = (4*i, 4*i+1, 4*i+2, 4*i+3, 3.14 + (i as f64));
ao_2e_int_eri_ref.push(data);
}
let mut offset = 0;
for i in 0..n_buffers {
trex_file.read_ao_2e_int_eri(offset, &ao_2e_int_eri[offset..offset+bufsize])?;
offset += bufsize;
}
// Determinants
let det_num = 50;
let mut det_list = Vec::with_capacity(det_num);
@ -112,7 +230,7 @@ fn write(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> {
trex_file.write_determinant_list(offset, &det_list[offset..offset+bufsize])?;
offset += bufsize;
}
*/
trex_file.close()
@ -129,12 +247,14 @@ use std::fs;
#[test]
pub fn text_backend() {
let _ = write("tmp/test_write.dir", trexio::BackEnd::Text);
let _ = read("tmp/test_write.dir", trexio::BackEnd::Text);
fs::remove_dir_all("tmp/test_write.dir").unwrap()
}
#[test]
pub fn hdf5_backend() {
let _ = write("tmp/test_write.hdf5", trexio::BackEnd::Hdf5);
let _ = read("tmp/test_write.hdf5", trexio::BackEnd::Hdf5);
fs::remove_file("tmp/test_write.hdf5").unwrap()
}