1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2024-06-02 03:15:40 +02:00

Introduced OCaml interface

This commit is contained in:
Anthony Scemama 2022-07-01 10:31:41 +02:00
commit a5632ab7a8
12 changed files with 1091 additions and 5 deletions

3
ocaml/trexio/.ocamlinit Normal file
View File

@ -0,0 +1,3 @@
#use "topfind";;
open Printf;;

9
ocaml/trexio/README.md Normal file
View File

@ -0,0 +1,9 @@
# TREXIO OCaml interface
## Building the source code
The hand-written source files are located in the `src` directory. These files contain
the pieces of code that can't be generated automatically. The source code distributed
in the OPAM package is generated by the `read_json.py` script, and is written in files
located in the `lib` directory.

31
ocaml/trexio/dune-project Normal file
View File

@ -0,0 +1,31 @@
(lang dune 3.1)
(name trexio)
(generate_opam_files true)
(source
(github trex-coe/trexio))
(authors
"Anthony Scemama <scemama@irsamc.ups-tlse.fr>"
"Evgeny Posenitskiy <posenitskiy@irsamc.ups-tlse.fr>"
)
(maintainers
"Anthony Scemama <scemama@irsamc.ups-tlse.fr>"
)
(license "BSD-3-Clause")
(documentation "https://trex-coe.github.io/trexio/")
(package
(name trexio)
(synopsis "Binding for the TREXIO Input/Output library")
(description "TREXIO is a file format and library for storing wave functions and integrals for quantum chemistry.")
(depends ocaml dune)
(tags
("Quantum chemistry" "Library")))
; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project

View File

@ -0,0 +1,22 @@
module C = Configurator.V1
let () =
C.main ~name:"trexio" (fun c ->
let default : C.Pkg_config.package_conf =
{ libs = ["-ltrexio"]
; cflags = ["-fPIC"]
}
in
let conf =
match C.Pkg_config.get c with
| None -> default
| Some pc ->
match (C.Pkg_config.query pc ~package:"trexio") with
| None -> default
| Some deps -> deps
in
C.Flags.write_sexp "c_flags.sexp" conf.cflags;
C.Flags.write_sexp "c_library_flags.sexp" conf.libs)

View File

@ -0,0 +1,3 @@
(executable
(name discover)
(libraries dune-configurator))

19
ocaml/trexio/lib/dune Normal file
View File

@ -0,0 +1,19 @@
(library
(name trexio)
(public_name trexio)
(foreign_stubs
(language c)
(names trexio_stubs)
(flags (:include c_flags.sexp) "-fPIC"))
(c_library_flags (:include c_library_flags.sexp))
)
(rule
(targets c_flags.sexp c_library_flags.sexp)
(action (run ./config/discover.exe)))
(env
(dev
(flags ))
(release
(ocamlopt_flags )))

646
ocaml/trexio/read_json.py Executable file
View File

@ -0,0 +1,646 @@
#!/usr/bin/env python
import json
json_file = "../../trex.json"
stubs_file= "trexio_stubs.c"
ml_file = "trexio.ml"
mli_file = ml_file+"i"
def write_stubs(data):
with open("src/"+stubs_file,'r') as f:
content = f.readlines()
index = -1
for i, line in enumerate(content):
if line.startswith("/**** ****/"):
index = i
break
content_pre = ''.join(content[:index])
content_post = ''.join(content[index:])
with open("lib/"+stubs_file,'w') as f:
f.write(content_pre)
for group in data:
t = """
CAMLprim value caml_delete_{group}(value file)
{
CAMLparam1(file);
trexio_exit_code rc = trexio_delete_{group}( File_val(file) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
"""
f.write( t.replace("{group}",group) )
for element in data[group]:
t = """
CAMLprim value caml_has_{group}_{element}(value file)
{
CAMLparam1(file);
trexio_exit_code rc = trexio_has_{group}_{element}( File_val(file) );
CAMLreturn ( Val_bool(rc == TREXIO_SUCCESS) );
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element) )
# Scalar elements
if data[group][element][1] == []:
if data[group][element][0] in [ "int", "dim", "index" ]:
t = """
CAMLprim value caml_read_{group}_{element}(value file)
{
CAMLparam1(file);
int64_t result;
trexio_exit_code rc = trexio_read_{group}_{element}_64( File_val(file), &result );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_int(result) );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_write_{group}_{element}(value file, value data)
{
CAMLparam2(file, data);
trexio_exit_code rc = trexio_write_{group}_{element}_64( File_val(file), (int64_t) Int_val(data) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "float" ]:
t = """
CAMLprim value caml_read_{group}_{element}(value file)
{
CAMLparam1(file);
double result;
trexio_exit_code rc = trexio_read_{group}_{element}_64( File_val(file), &result );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( caml_copy_double(result) );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_write_{group}_{element}(value file, value data)
{
CAMLparam2(file, data);
trexio_exit_code rc = trexio_write_{group}_{element}_64( File_val(file), (double) Double_val(data) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "string" ]:
t = """
CAMLprim value caml_read_{group}_{element}(value file, value max_str_len_in)
{
CAMLparam2(file, max_str_len_in);
int32_t max_str_len = Int_val(max_str_len_in);
char result[max_str_len];
trexio_exit_code rc = trexio_read_{group}_{element}( File_val(file), result, max_str_len);
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( caml_copy_string(result) );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_write_{group}_{element}(value file, value data)
{
CAMLparam2(file, data);
const char* val = String_val(data);
trexio_exit_code rc = trexio_write_{group}_{element}( File_val(file), val, (int32_t) strlen(val));
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
if data[group][element][0] in [ "dim readonly" ]:
t = """
CAMLprim value caml_read_{group}_{element}(value file)
{
CAMLparam1(file);
int64_t result;
trexio_exit_code rc = trexio_read_{group}_{element}_64( File_val(file), &result );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_int(result) );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0].split()[0]) )
# Array elements
else:
if data[group][element][0] in [ "float" ]:
t = """
CAMLprim value caml_read_safe_{group}_{element}(value file_in, value size_max_in)
{
CAMLparam2 ( file_in, size_max_in );
CAMLlocal1 ( result );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
double* read_data = (double*) malloc (size_max * sizeof(double));
trexio_exit_code rc = trexio_read_safe_{group}_{element}_64(file, read_data, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(size_max * Double_wosize, Double_array_tag);
for (size_t i=0 ; i<size_max ; ++i) {
Store_double_field( result, i, read_data[i] );
}
free(read_data);
CAMLreturn (result);
}
CAMLprim value caml_write_safe_{group}_{element}(value file_in, value size_max_in, value array)
{
CAMLparam3 ( file_in, size_max_in, array );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
double* c_array = (double*) malloc (size_max * sizeof(double));
for (size_t i=0 ; i<size_max ; ++i) {
c_array[i] = Double_field(array, i);
}
trexio_exit_code rc = trexio_write_safe_{group}_{element}_64(file, c_array, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(c_array);
CAMLreturn ( Val_unit );
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "int", "index", "dim" ]:
t = """
CAMLprim value caml_read_safe_{group}_{element}(value file_in, value size_max_in)
{
CAMLparam2 ( file_in, size_max_in );
CAMLlocal1 ( result );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
int64_t* read_data = (int64_t*) malloc (size_max * sizeof(int64_t));
trexio_exit_code rc = trexio_read_safe_{group}_{element}_64(file, read_data, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(size_max, 0);
for (size_t i=0 ; i<size_max ; ++i) {
Store_field( result, i, Val_int(read_data[i]) );
}
free(read_data);
CAMLreturn (result);
}
CAMLprim value caml_write_safe_{group}_{element}(value file_in, value size_max_in, value array)
{
CAMLparam3 ( file_in, size_max_in, array );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
int64_t* c_array = (int64_t*) malloc (size_max * sizeof(int64_t));
for (size_t i=0 ; i<size_max ; ++i) {
c_array[i] = Int_val( Field(array, i) );
}
trexio_exit_code rc = trexio_write_safe_{group}_{element}_64(file, c_array, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(c_array);
CAMLreturn ( Val_unit );
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "string" ]:
t = """
CAMLprim value caml_read_safe_{group}_{element}(value file_in, value size_max_in, value max_str_len_in)
{
CAMLparam3 ( file_in, size_max_in, max_str_len_in );
CAMLlocal1 ( result );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
int32_t max_str_len = Int_val(max_str_len_in);
char** read_data = (char**) malloc (size_max * sizeof(char*));
read_data[0] = (char*) malloc (size_max * (int64_t) (max_str_len+1) * sizeof(char));
for (size_t i=1 ; i<size_max ; ++i) {
read_data[i] = read_data[i-1] + max_str_len+1;
}
trexio_exit_code rc = trexio_read_{group}_{element}(file, read_data, max_str_len);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(size_max, 0);
for (size_t i=0 ; i<size_max ; ++i) {
Store_field( result, i, caml_copy_string(read_data[i]) );
}
free(read_data[0]);
free(read_data);
CAMLreturn (result);
}
CAMLprim value caml_write_safe_{group}_{element}(value file_in, value size_max_in, value max_str_len_in, value array)
{
CAMLparam4 ( file_in, size_max_in, max_str_len_in, array );
trexio_t* file = File_val( file_in );
int64_t size_max = (int64_t) Int_val(size_max_in);
int32_t max_str_len = Int_val(max_str_len_in);
char** c_array = (char**) malloc (size_max * sizeof(char*));
c_array[0] = (char*) malloc (size_max * (max_str_len+1) * sizeof(char*));
for (size_t i=1 ; i<size_max ; ++i) {
c_array[i] = c_array[i-1] + max_str_len+1;
}
for (size_t i=0 ; i<size_max ; ++i) {
strcpy(c_array[i], String_val( Field(array, i) ));
}
printf("%d\\n", max_str_len);
fprintf(stderr,"%d\\n", max_str_len);
trexio_exit_code rc = trexio_write_{group}_{element}(file, (const char**) c_array, max_str_len);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(c_array[0]);
free(c_array);
CAMLreturn ( Val_unit );
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
if data[group][element][0] in [ "float sparse" ]:
size = len(data[group][element][1])
t = """
CAMLprim value caml_read_{group}_{element}(value file_in, value offset_in, value buffer_size_in)
{
CAMLparam3 ( file_in, offset_in, buffer_size_in );
CAMLlocal2 ( result, data );
trexio_t* file = File_val( file_in );
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Int_val( buffer_size_in );
int64_t size_max = buffer_size;
int32_t* index_sparse_read = (int32_t*) malloc ({size}*size_max*sizeof(int32_t));
double* value_sparse_read = (double*) malloc (size_max*sizeof(double));
trexio_exit_code rc = trexio_read_safe_{group}_{element}(file, offset, &buffer_size,
index_sparse_read, size_max,
value_sparse_read, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(buffer_size, 0);
for (size_t i=0 ; i<buffer_size ; ++i) {
data = caml_alloc_tuple({size}+1);
for (int j=0 ; j<{size} ; ++j) {
Store_field(data, j, Val_int( index_sparse_read[{size}*i+j] ));
}
Store_field(data, {size}, caml_copy_double( value_sparse_read[i] ));
Store_field(result, i, data);
}
free(index_sparse_read);
free(value_sparse_read);
CAMLreturn(result);
}
CAMLprim value caml_write_{group}_{element}(value file_in, value offset_in, value buffer_in)
{
CAMLparam3 ( file_in, offset_in, buffer_in );
CAMLlocal1 ( data );
trexio_t* file = File_val( file_in );
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Wosize_val( buffer_in );
const int64_t size_max = buffer_size;
int32_t* index_sparse_write = (int32_t*) malloc ({size}*size_max*sizeof(int32_t));
double* value_sparse_write = (double*) malloc (size_max*sizeof(double));
for (size_t i=0 ; i<buffer_size ; ++i) {
data = Field(buffer_in, i);
for (int j=0 ; j<{size} ; ++j) {
index_sparse_write[{size}*i+j] = Int_val( Field(data, j) );
}
value_sparse_write[i] = Double_val( Field(data, {size}) );
}
trexio_exit_code rc = trexio_write_safe_{group}_{element}(file, offset, buffer_size,
index_sparse_write, size_max,
value_sparse_write, size_max);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(index_sparse_write);
free(value_sparse_write);
CAMLreturn( Val_unit );
}
"""
f.write( t.replace("{group}", group)
.replace("{element}", element)
.replace("{size}", str(size))
.replace("{type}", data[group][element][0]) )
f.write(content_post)
def write_mli(data):
with open("src/"+mli_file,'r') as f:
content = f.readlines()
index = -1
for i, line in enumerate(content):
if line.startswith("(**** ****)"):
index = i
break
content_pre = ''.join(content[:index])
content_post = ''.join(content[index:])
with open("lib/"+mli_file,'w') as f:
f.write(content_pre)
for group in data:
t = "val delete_{group}: trexio_file -> unit\n"
f.write( t.replace("{group}",group) )
for element in data[group]:
t = "val has_{group}_{element}: trexio_file -> bool\n"
f.write( t.replace("{group}", group)
.replace("{element}", element) )
# Scalar elements
if data[group][element][1] == []:
if data[group][element][0] in [ "int", "float", "dim", "index" ]:
t = [ "val read_{group}_{element} : trexio_file -> {type}\n" ,
"val write_{group}_{element}: trexio_file -> {type} -> unit\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "string" ]:
t = [ "val read_{group}_{element} : ?max_str_len:int -> trexio_file -> {type}\n" ,
"val write_{group}_{element}: trexio_file -> {type} -> unit\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "dim readonly" ]:
t = [ "val read_{group}_{element} : trexio_file -> {type}\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0].split()[0]) )
# Arrays
else:
if data[group][element][0] in [ "int", "float", "dim", "index" ]:
t = [ "val read_safe_{group}_{element} : trexio_file -> int -> {type} array\n" ,
"val write_safe_{group}_{element}: trexio_file -> int -> {type} array -> unit\n"
"val read_{group}_{element} : trexio_file -> {type} array\n" ,
"val write_{group}_{element}: trexio_file -> {type} array -> unit\n"
]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "string" ]:
t = [ "val read_safe_{group}_{element} : trexio_file -> int -> int -> {type} array\n" ,
"val write_safe_{group}_{element}: trexio_file -> int -> int -> {type} array -> unit\n"
"val read_{group}_{element} : ?max_str_len:int -> trexio_file -> {type} array\n" ,
"val write_{group}_{element}: trexio_file -> {type} array -> unit\n"
]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "float sparse" ]:
size = len(data[group][element][1])
typ = "(" + "*".join( [ "int" for _ in range(size) ]) + " * float) array"
t = [ "val read_{group}_{element} : trexio_file -> offset:dim -> buffer_size:dim -> {type}\n" ,
"val write_{group}_{element} : trexio_file -> offset:dim -> {type} -> unit\n" ,
]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", typ) )
f.write(content_post)
def write_ml(data):
with open("src/"+ml_file,'r') as f:
content = f.readlines()
index = -1
for i, line in enumerate(content):
if line.startswith("(**** ****)"):
index = i
break
content_pre = ''.join(content[:index])
content_post = ''.join(content[index:])
with open("lib/"+ml_file,'w') as f:
f.write(content_pre)
for group in data:
t = "external delete_{group}: trexio_file -> unit = \"caml_delete_{group}\"\n"
f.write( t.replace("{group}",group) )
for element in data[group]:
t = "external has_{group}_{element}: trexio_file -> bool = \"caml_has_{group}_{element}\"\n"
f.write( t.replace("{group}", group)
.replace("{element}", element) )
# Scalar elements
if data[group][element][1] == []:
if data[group][element][0] in [ "int", "float", "dim", "index" ]:
t = [ "external read_{group}_{element} : trexio_file -> {type} = \"caml_read_{group}_{element}\"\n" ,
"external write_{group}_{element}: trexio_file -> {type} -> unit = \"caml_write_{group}_{element}\"\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
if data[group][element][0] in [ "string" ]:
t = [ "external read_{group}_{element}_c : trexio_file -> int -> {type} = \"caml_read_{group}_{element}\"\n" ,
"let read_{group}_{element} ?(max_str_len=8192) f = read_{group}_{element}_c f max_str_len\n",
"external write_{group}_{element}: trexio_file -> {type} -> unit = \"caml_write_{group}_{element}\"\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "dim readonly" ]:
t = [ "external read_{group}_{element} : trexio_file -> {type} = \"caml_read_{group}_{element}\"\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0].split()[0]) )
# Arrays
else:
if data[group][element][0] in [ "int", "float", "dim", "index" ]:
t = [ "external read_safe_{group}_{element} : trexio_file -> int -> {type} array = \"caml_read_safe_{group}_{element}\"\n" ,
"external write_safe_{group}_{element}: trexio_file -> int -> {type} array -> unit = \"caml_write_safe_{group}_{element}\"\n",
"let read_{group}_{element} f = \n let size = 1 in \n"]
t_prime = []
for dim in data[group][element][1]:
try: # A dimensioning variable
dim_group, dim_element = dim.split('.')
t_prime += [f" let size = size * read_{dim_group}_{dim_element} f in\n"]
except: # Only an integer
t_prime += [f" let size = size * {dim} in\n"]
t += t_prime
t += [ " read_safe_{group}_{element} f size\n\n" ]
t += [ "let write_{group}_{element} f a = \n let size = 1 in \n"]
t += t_prime
t += [ " write_safe_{group}_{element} f size a\n\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "string" ]:
t = [ "external read_safe_{group}_{element} : trexio_file -> int -> int -> {type} array = \"caml_read_safe_{group}_{element}\"\n" ,
"external write_safe_{group}_{element}: trexio_file -> int -> int -> {type} array -> unit = \"caml_write_safe_{group}_{element}\"\n",
"let read_{group}_{element} ?(max_str_len=1024) f = \n let size = 1 in \n"]
t_prime = []
for dim in data[group][element][1]:
try: # A dimensioning variable
dim_group, dim_element = dim.split('.')
t_prime += [f" let size = size * read_{dim_group}_{dim_element} f in\n"]
except: # Only an integer
t_prime += [f" let size = size * {dim} in\n"]
t += t_prime
t += [ " read_safe_{group}_{element} f size max_str_len\n\n" ,
"let write_{group}_{element} f a = \n let size = 1 in \n",
" let max_str_len = Array.map String.length a\n" ,
" |> Array.fold_left (fun x y -> if x>y then x else y) 0\n",
" |> (+) 1 in\n" ]
t += t_prime
t += [ " write_safe_{group}_{element} f size max_str_len a\n\n" ]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", data[group][element][0]) )
elif data[group][element][0] in [ "float sparse" ]:
size = len(data[group][element][1])
typ = "(" + "*".join( [ "int" for _ in range(size) ]) + " * float) array"
t = [ "external read_{group}_{element} : trexio_file -> offset:dim -> buffer_size:dim -> {type} = \"caml_read_{group}_{element}\"\n" ,
"external write_{group}_{element} : trexio_file -> offset:dim -> {type} -> unit = \"caml_write_{group}_{element}\"\n"
]
for i in t:
f.write( i.replace("{group}", group)
.replace("{element}", element)
.replace("{type}", typ) )
f.write(content_post)
def main():
with open(json_file,'r') as f:
data = json.load(f)
for group in data:
for element in data[group]:
if data[group][element][0] == "str":
data[group][element][0] = "string"
write_ml(data)
write_mli(data)
write_stubs(data)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,37 @@
type trexio_file
type trexio_exit_code = int
type trexio_backend =
| HDF5
| TEXT
| AUTO
type index = int
type dim = int
external open_file : string -> char -> trexio_backend -> trexio_file = "caml_open_file"
external close_file : trexio_file -> unit = "caml_close_file"
external inquire_file : string -> bool = "caml_inquire_file"
external set_one_based : trexio_file -> unit = "caml_set_one_based"
external get_state : trexio_file -> int = "caml_get_state"
external set_state : trexio_file -> int -> unit = "caml_set_state"
external info : unit -> unit = "caml_info"
external to_orbital_list : Int64.t array -> int list = "caml_to_orbital_list"
(**** ****)
external read_determinant_list : trexio_file -> offset:int -> buffer_size:int -> (bytes * bytes) array = "caml_read_determinant_list"
external write_determinant_list : trexio_file -> offset:int -> (bytes * bytes) array -> unit = "caml_write_determinant_list"
external read_determinant_coefficient : trexio_file -> offset:int -> buffer_size:int -> float array = "caml_read_determinant_coefficient"
external write_determinant_coefficient : trexio_file -> offset:int -> float array -> unit = "caml_write_determinant_coefficient"
let to_orbital_list_up_dn (up,dn) =
(to_orbital_list up, to_orbital_list dn)

View File

@ -0,0 +1,41 @@
(*
(** Constants *)
val package_version : string
val version_major : int
val version_minor : int
val version_patch : int
val git_hash : string
*)
(** Open/close *)
type trexio_file
type trexio_exit_code
type trexio_backend =
| HDF5
| TEXT
| AUTO
type index = int
type dim = int
val open_file : string -> char -> trexio_backend -> trexio_file
val inquire_file : string -> bool
val close_file : trexio_file -> unit
val set_one_based : trexio_file -> unit
val get_state : trexio_file -> int
val set_state : trexio_file -> int -> unit
val info : unit -> unit
val to_orbital_list : Int64.t array -> int list
val to_orbital_list_up_dn : (Int64.t array)*(Int64.t array) -> (int list)*(int list)
(**** ****)
val read_determinant_list : trexio_file -> offset:int -> buffer_size:int -> (bytes * bytes) array
val write_determinant_list : trexio_file -> offset:int -> (bytes * bytes) array -> unit
val read_determinant_coefficient : trexio_file -> offset:int -> buffer_size:int -> float array
val write_determinant_coefficient : trexio_file -> offset:int -> float array -> unit

View File

@ -0,0 +1,268 @@
#include <stdio.h>
#include <trexio.h>
#include <string.h>
#define CAML_NAME_SPACE
#include <caml/alloc.h>
#include <caml/custom.h>
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/fail.h>
#include <caml/misc.h>
static trexio_t* File_val( value file )
{
return *((trexio_t**) Data_abstract_val(file));
}
CAMLprim value caml_open_file(value filename, value mode, value backend)
{
CAMLparam3(filename, mode, backend);
trexio_exit_code rc = 0;
value v = caml_alloc(1, Abstract_tag);
trexio_t* result = trexio_open (String_val(filename),
Int_val(mode),
Int_val(backend),
&rc);
*((trexio_t **) Data_abstract_val(v)) = result;
if (rc == TREXIO_SUCCESS) {
CAMLreturn( v );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_close_file(value file)
{
CAMLparam1(file);
trexio_exit_code rc = trexio_close( File_val(file) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_inquire_file(value filename)
{
CAMLparam1 (filename);
trexio_exit_code rc = trexio_inquire( String_val (filename) );
CAMLreturn(Val_bool(rc == TREXIO_SUCCESS));
}
CAMLprim value caml_set_one_based(value file)
{
CAMLparam1(file);
trexio_exit_code rc = trexio_set_one_based( File_val(file) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_set_state(value file, value state)
{
CAMLparam2(file, state);
printf("%d\n", Int_val(state));
trexio_exit_code rc = trexio_set_state( File_val(file), (int32_t) Int_val(state) );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_get_state(value file)
{
CAMLparam1(file);
int32_t result;
trexio_exit_code rc = trexio_get_state( File_val(file), &result );
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_int(result) );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_info(value unit)
{
CAMLparam1(unit);
trexio_exit_code rc = trexio_info();
if (rc == TREXIO_SUCCESS) {
CAMLreturn ( Val_unit );
} else {
caml_failwith(trexio_string_of_error(rc));
}
}
CAMLprim value caml_to_orbital_list(value bitfield)
{
CAMLparam1 ( bitfield );
CAMLlocal2 ( result, cons );
int32_t N_int = Wosize_val(bitfield);
bitfield_t* d1 = (bitfield_t*) malloc (N_int * sizeof(bitfield_t));
for (int i=0 ; i<N_int ; ++i) {
d1[i] = Int64_val(Field(bitfield,i));
}
int32_t* list = (int32_t*) malloc(N_int * sizeof(bitfield_t) * sizeof(int32_t));
int32_t occupied_num = 0;
trexio_exit_code rc = trexio_to_orbital_list (N_int, d1, list, &occupied_num);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(d1);
result = Val_emptylist;
for (int i=occupied_num-1 ; i >= 0 ; --i) {
cons = caml_alloc(2, 0);
Store_field(cons, 0, Val_int(list[i])); // head
Store_field(cons, 1, result); // head
result = cons;
}
free(list);
CAMLreturn(result);
}
/**** ****/
CAMLprim value caml_read_determinant_list(value file_in, value offset_in, value buffer_size_in)
{
CAMLparam3 ( file_in, offset_in, buffer_size_in );
CAMLlocal4 ( result, detup, detdn, det );
trexio_t* file = File_val(file_in);
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Int_val( buffer_size_in );
int32_t int_num = 0;
trexio_exit_code rc = trexio_get_int64_num(file, &int_num);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
int64_t* buffer = (int64_t*) malloc ( buffer_size * int_num * 2 * sizeof(int64_t) );
rc = trexio_read_determinant_list (file, offset, &buffer_size, buffer);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(buffer_size, 0);
size_t icount = 0;
for (size_t i=0 ; i<buffer_size ; ++i) {
detup = caml_alloc_initialized_string(int_num*sizeof(int64_t), (char*) &(buffer[icount]));
icount += int_num;
detdn = caml_alloc_initialized_string(int_num*sizeof(int64_t), (char*) &(buffer[icount]));
icount += int_num;
det = caml_alloc_tuple(2);
Store_field( det, 0, detup );
Store_field( det, 1, detdn );
Store_field( result, i, det );
}
free(buffer);
CAMLreturn(result);
}
CAMLprim value caml_write_determinant_list(value file_in, value offset_in, value array)
{
CAMLparam3 ( file_in, offset_in, array );
CAMLlocal3 ( detup, detdn, det );
trexio_t* file = File_val(file_in);
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Wosize_val( array );
int32_t int_num = 0;
trexio_exit_code rc = trexio_get_int64_num(file, &int_num);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
int64_t* buffer = (int64_t*) malloc ( buffer_size * int_num * 2 * sizeof(int64_t) );
for (size_t i=0 ; i<buffer_size ; ++i) {
det = Field(array, i);
detup = Field(det, 0);
detdn = Field(det, 1);
memcpy(&(buffer[i*int_num*2]), String_val(detup), int_num*sizeof(int64_t));
memcpy(&(buffer[i*int_num*2 + int_num]), String_val(detdn), int_num*sizeof(int64_t));
}
rc = trexio_write_determinant_list (file, offset, buffer_size, buffer);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(buffer);
CAMLreturn( Val_unit );
}
CAMLprim value caml_read_determinant_coefficient(value file_in, value offset_in, value buffer_size_in)
{
CAMLparam3 ( file_in, offset_in, buffer_size_in );
CAMLlocal1 ( result );
trexio_t* file = File_val(file_in);
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Int_val( buffer_size_in );
double* buffer = (double*) malloc ( buffer_size * sizeof(double) );
trexio_exit_code rc = trexio_read_determinant_coefficient (file, offset, &buffer_size, buffer);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
result = caml_alloc(buffer_size * Double_wosize, Double_array_tag);
for (size_t i=0 ; i<buffer_size ; ++i) {
Store_double_field( result, i, buffer[i]);
}
free(buffer);
CAMLreturn(result);
}
CAMLprim value caml_write_determinant_coefficient(value file_in, value offset_in, value array)
{
CAMLparam3 ( file_in, offset_in, array );
trexio_t* file = File_val(file_in);
int64_t offset = Int_val( offset_in );
int64_t buffer_size = Wosize_val( array );
double* buffer = (double*) malloc ( buffer_size * sizeof(double) );
for (size_t i=0 ; i<buffer_size ; ++i) {
buffer[i] = Double_field(array, i);
}
trexio_exit_code rc = trexio_write_determinant_coefficient (file, offset, buffer_size, buffer);
if (rc != TREXIO_SUCCESS) {
caml_failwith(trexio_string_of_error(rc));
}
free(buffer);
CAMLreturn( Val_unit );
}

View File

@ -232,7 +232,7 @@ def iterative_populate_file (filename: str, paths: dict, detailed_all: dict) ->
for line in f_in :
id = check_triggers(line, triggers)
if id == 0:
# special case for proper error handling when deallocting text groups
# special case for proper error handling when deallocating text groups
error_handler = ' if (rc != TREXIO_SUCCESS) return rc;\n'
populated_line = iterative_replace_line(line, '$group$', detailed_all['groups'], add_line=error_handler)
f_out.write(populated_line)

View File

@ -37,6 +37,8 @@ fetched using multiple function calls to perform I/O on buffers.
For more information on how to read/write sparse data structures, see
the [[./examples.html][examples]].
For determinants, the ~special~ attribute is present in the type. This
means that the source code is not produced by the generator, but hand-written.
#+begin_src python :tangle trex.json :exports none
{
@ -678,11 +680,16 @@ prim_factor =
in the memory.
\[
D_I = \alpha_1 \alpha_2 \ldots \alpha_{n\uparrow} \beta_1 \beta_2 \ldots \beta_{n\downarrow}
D_I = \alpha_1 \alpha_2 \ldots \alpha_{n_\uparrow} \beta_1 \beta_2 \ldots \beta_{n_\downarrow}
\]
where $\alpha$ and $\beta$ denote $\uparrow$-spin and $\downarrow$-spin electrons, respectively,
$n\uparrow$ and $n\downarrow$ correspond to ~electron.up_num~ and ~electron.dn_num~, respectively.
where $\alpha$ and $\beta$ denote \uparrow-spin and \downarrow-spin electrons, respectively,
$n_\uparrow$ and $n_\downarrow$ correspond to ~electron.up_num~ and ~electron.dn_num~, respectively.
Note: the ~special~ attribute is present in the types, meaning that the source node is not
produced by the code generator.
An illustration on how to read determinants is presented in the [[./examples.html][examples]].
#+NAME: determinant
| Variable | Type | Dimensions | Description |
@ -734,7 +741,7 @@ prim_factor =
The reduced density matrices are defined in the basis of molecular
orbitals.
The $\uparrow$-spin and $\downarrow$-spin components of the one-body
The \uparrow-spin and \downarrow-spin components of the one-body
density matrix are given by
\begin{eqnarray*}
\gamma_{ij}^{\uparrow} &=& \langle \Psi | \hat{a}^{\dagger}_{j\alpha}\, \hat{a}_{i\alpha} | \Psi \rangle \\