1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2024-12-31 16:45:59 +01:00

Merge pull request #27 from TREX-CoE/generator-1

implemented templates and generator
This commit is contained in:
Evgeny Posenitskiy 2021-03-18 18:56:52 +01:00 committed by GitHub
commit 3428657560
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 7025 additions and 932 deletions

62
src/build_trex.sh Executable file
View File

@ -0,0 +1,62 @@
#!/bin/bash
if [[ $(basename $PWD) != "src" ]] ; then
echo "This script should run in the src directory"
exit -1
fi
# We want the script to crash on the 1st error:
set -e
echo "create populated directories"
mkdir -p templates_front/populated
mkdir -p templates_text/populated
mkdir -p templates_hdf5/populated
# It is important to ad '--' to rm because it tells rm that what follows are
# not options. It is safer.
echo "remove existing templates"
rm -- templates_front/*.{c,h}
rm -- templates_text/*.{c,h}
rm -- templates_hdf5/*.{c,h}
echo "clean populated directories"
rm -- templates_front/populated/*
rm -- templates_text/populated/*
rm -- templates_hdf5/populated/*
echo "tangle org files to generate templates"
cd templates_front
emacs --batch --eval "(require 'org)" --eval '(org-babel-tangle-file "templator_front.org")'
cd ..
cd templates_text
emacs --batch --eval "(require 'org)" --eval '(org-babel-tangle-file "templator_text.org")'
cd ..
cd templates_hdf5
emacs --batch --eval "(require 'org)" --eval '(org-babel-tangle-file "templator_hdf5.org")'
cd ..
echo "run generator script to populate templates"
python3 generator.py
sleep 2
echo "compile populated files in the lib source files "
cd templates_front
source build.sh
cp trexio* ../
cd ..
cd templates_text
source build.sh
cp trexio* ../
cd ..
cd templates_hdf5
source build.sh
cp trexio* ../
cd ..

358
src/generator.py Normal file
View File

@ -0,0 +1,358 @@
import json
from os import listdir, scandir, remove
from os.path import isfile, join, dirname, abspath
fileDir = dirname(abspath(__file__))
parentDir = dirname(fileDir)
with open(join(parentDir,'trex.json'), 'r') as f:
config0 = json.load(f)
print('Metadata I/O currently not supported')
# TODO, for now remove metadata-related stuff
del config0['metadata']
config = {}
for k,v in config0.items():
if k == 'nucleus' or k == 'ecp':
#if k == 'nucleus':
config[k] = v
#print(config)
groups = [group for group in config.keys()]
dim_variables = {}
dim_list = []
dim_dict = {}
for k1,v1 in config.items():
grname = k1
for v2 in v1.values():
for dim in v2[1]:
if not dim.isdigit():
tmp = dim.replace('.','_')
dim_variables[tmp] = 0
if dim not in dim_list:
dim_list.append(tmp)
dim_dict[grname] = dim_list
dim_list = []
#print(dim_variables)
#print(dim_dict)
datasets = {}
numbers = {}
for k1,v1 in config.items():
for k2,v2 in v1.items():
if len(v2[1]) > 0:
datasets[f'{k1}_{k2}'] = v2
else:
var_name = f'{k1}_{k2}'
if var_name not in dim_variables.keys():
numbers[var_name] = v2[0]
print('Strings I/O currently not supported')
# TODO, for now remove char-related stuff
datasets_nostr = {}
for k,v in datasets.items():
tmp_dict = {}
if 'char' not in v[0]:
if v[0] == 'float':
datatype = 'double'
elif v[0] == 'int':
datatype = 'int64_t'
tmp_dict['dtype'] = datatype
tmp_dict['dims'] = [dim.replace('.','_') for dim in v[1]]
tmp_dict['rank'] = len(v[1])
dim_str = tmp_dict['dims'][0]
if tmp_dict['rank'] > 1:
for i in range(1, tmp_dict['rank']):
dim_toadd = tmp_dict['dims'][i]
dim_str += f', {dim_toadd}'
tmp_dict['dim_list'] = dim_str
datasets_nostr[k] = tmp_dict
#print(datasets_nostr['nucleus_coord'])
#put also dimensioning variables in numbers
numbers.update(dim_variables)
print(numbers)
templ_path_text = join(fileDir,'templates_text')
templ_path_hdf5 = join(fileDir,'templates_hdf5')
templ_path_front = join(fileDir,'templates_front')
#clean the populated/ directory
#for popdir in [templ_path_front, templ_path_front, templ_path_text]:
# cleandir = join(popdir, 'populated')
# for f in scandir(cleandir):
# remove(f.path)
files_exclude = ['prefix_hdf5.c', 'prefix_hdf5.h', 'suffix_hdf5.h',
'prefix_text.c', 'prefix_text.h', 'suffix_text.h',
'prefix_front.c', 'prefix_front.h', 'suffix_front.h',
'prefix_s_front.h', 'suffix_s_front.h',
'templator_front.org', 'templator_hdf5.org', 'templator_text.org']
files_text = [f for f in listdir(templ_path_text) if isfile(join(templ_path_text, f)) and f not in files_exclude]
files_hdf5 = [f for f in listdir(templ_path_hdf5) if isfile(join(templ_path_hdf5, f)) and f not in files_exclude]
files_front = [f for f in listdir(templ_path_front) if isfile(join(templ_path_front, f)) and f not in files_exclude]
files = files_text + files_hdf5 + files_front
files_funcs = [f for f in files if 'read_' in f or 'write_' in f or 'flush_' in f or 'free_' in f or 'rw_' in f ]
files_funcs_dsets = [f for f in files_funcs if 'dset' in f]
files_funcs_nums = [f for f in files_funcs if 'num' in f]
files_funcs_groups = [f for f in files_funcs if 'group' in f]
files_funcs_groups.append('struct_text_group_dset.h')
#print(files_funcs_groups)
files_auxil = [f for f in files if not ('read_' in f or 'write_' in f or 'rw_' in f)]
# build files with functions for text groups
for fname in files_funcs_groups:
fname_new = join('populated',f'pop_{fname}')
if '_text' in fname:
templ_path = templ_path_text
groups_done = []
for group in config.keys():
grname = group.split('_')[0]
if grname in groups_done:
continue
else:
groups_done.append(grname)
subloop = False
do_dset = False
do_num = False
loop_body = ''
with open(join(templ_path,fname), 'r') as f_in :
with open(join(templ_path,fname_new), 'a') as f_out :
for line in f_in :
if 'END REPEAT' in line:
if do_dset:
for dset,params in datasets_nostr.items():
dset_grname = dset.split('_')[0]
if dset_grname != grname:
continue
templine1 = loop_body.replace('$group_dset$', dset)
templine2 = templine1.replace('$group$', grname)
templine1 = templine2.replace('$group_dset_dtype$', params['dtype'])
templine2 = templine1
if params['dtype'] == 'double':
std_dtype = 'lf'
elif params['dtype'] == 'int64_t':
std_dtype = 'ld'
templine1 = templine2.replace('$group_dset_std_dtype$', std_dtype)
templine2 = templine1
f_out.write(templine2)
elif do_num:
#for dim in dim_variables.keys():
for dim in numbers.keys():
num_grname = dim.split('_')[0]
if num_grname != grname:
continue
templine1 = loop_body.replace('$group_num$', dim)
templine2 = templine1.replace('$group$', grname)
f_out.write(templine2)
else:
print('fishy')
#print(loop_body)
loop_body = ''
subloop = False
do_dset = False
do_num = False
continue
if subloop:
loop_body += line
if 'START REPEAT' in line:
if 'GROUP_DSET' in line:
do_dset = True
if 'GROUP_NUM' in line:
do_num = True
subloop = True
if '$group_dset' in line and not subloop:
for dset,params in datasets_nostr.items():
dset_grname = dset.split('_')[0]
if dset_grname != grname:
continue
templine1 = line.replace('$group_dset$', dset)
templine2 = templine1
templine1 = templine2.replace('$group_dset_dtype$', params['dtype'])
templine2 = templine1
templine1 = templine2.replace('$group$', grname)
templine2 = templine1.replace('$GROUP$', grname.upper())
f_out.write(templine2)
elif '$group_num' in line and not subloop:
#for dim in dim_variables.keys():
for dim in numbers.keys():
num_grname = dim.split('_')[0]
if num_grname != grname:
continue
templine1 = line.replace('$GROUP_NUM$', dim.upper())
templine2 = templine1.replace('$group_num$', dim)
templine1 = templine2.replace('$group$', grname)
templine2 = templine1.replace('$GROUP$', grname.upper())
f_out.write(templine2)
elif '$group$' in line and not subloop:
templine1 = line.replace('$group$', grname)
templine2 = templine1.replace('$GROUP$', grname.upper())
f_out.write(templine2)
elif not subloop:
f_out.write(line)
# build files with functions
for fname in files_funcs_dsets:
fname_new = join('populated',f'pop_{fname}')
if '_hdf5' in fname:
templ_path = templ_path_hdf5
if '_front' in fname:
templ_path = templ_path_front
if '_text' in fname:
templ_path = templ_path_text
for dset,params in datasets_nostr.items():
grname = dset.split('_')[0]
with open(join(templ_path,fname), 'r') as f_in :
with open(join(templ_path,fname_new), 'a') as f_out :
for line in f_in :
if '$' in line:
if '$group_dset_dim$' in line:
rc_line = ' if (rc != TREXIO_SUCCESS) return rc;\n'
for dim in params['dims']:
if not dim.isdigit():
templine1 = line.replace('$group_dset_dim$', dim)
templine2 = templine1
if '_read' in templine2 and 'hdf5' in fname:
templine1 = rc_line
templine2 += templine1
f_out.write(templine2)
continue
templine1 = line.replace('$GROUP$_$GROUP_DSET$', dset.upper())
templine2 = templine1.replace('$group$_$group_dset$', dset)
templine1 = templine2.replace('$group_dset$', dset)
templine2 = templine1
templine1 = templine2.replace('$group_dset_dtype$', params['dtype'])
templine2 = templine1
if params['dtype'] == 'double':
h5_dtype = 'double'
elif params['dtype'] == 'int64_t':
h5_dtype = 'long'
templine1 = templine2.replace('$group_dset_h5_dtype$', h5_dtype)
templine2 = templine1.replace('$group_dset_h5_dtype$'.upper(), h5_dtype.upper())
templine1 = templine2.replace('$group_dset_rank$', str(params['rank']))
templine2 = templine1
templine1 = templine2.replace('$group_dset_dim_list$', params['dim_list'])
templine2 = templine1
templine1 = templine2.replace('$group$', grname)
templine2 = templine1.replace('$GROUP$', grname.upper())
f_out.write(templine2)
else:
f_out.write(line)
# build files with functions
for fname in files_funcs_nums:
fname_new = join('populated',f'pop_{fname}')
if '_hdf5' in fname:
templ_path = templ_path_hdf5
if '_front' in fname:
templ_path = templ_path_front
if '_text' in fname:
templ_path = templ_path_text
for dim in dim_variables.keys():
#for dim in numbers.keys():
grname = dim.split('_')[0]
with open(join(templ_path,fname), 'r') as f_in :
with open(join(templ_path,fname_new), 'a') as f_out :
for line in f_in :
if '$' in line:
templine1 = line.replace('$GROUP_NUM$', dim.upper())
templine2 = templine1.replace('$group_num$', dim)
templine1 = templine2.replace('$group$', grname)
templine2 = templine1.replace('$GROUP$', grname.upper())
f_out.write(templine2)
else:
f_out.write(line)
# build files with $group$ and $group$-based
for fname in ['def_hdf5.c', 'basic_hdf5.c', 'basic_text_group.c',
'struct_hdf5.h', 'struct_text_group.h'] :
fname_new = join('populated',f'pop_{fname}')
if '_hdf5' in fname:
templ_path = templ_path_hdf5
if '_front' in fname:
templ_path = templ_path_front
if '_text' in fname:
templ_path = templ_path_text
with open(join(templ_path,fname), 'r') as f_in :
with open(join(templ_path,fname_new), 'a') as f_out :
for line in f_in :
if '$group_dset$' in line or '$GROUP_DSET$' in line :
for dset in datasets_nostr.keys():
templine1 = line.replace('$GROUP$_$GROUP_DSET$', dset.upper())
templine2 = templine1.replace('$group_dset$', dset)
f_out.write(templine2)
elif '$group_num$' in line or '$GROUP_NUM$' in line :
for num in dim_variables.keys():
#for num in numbers.keys():
templine1 = line.replace('$GROUP_NUM$', num.upper())
templine2 = templine1.replace('$group_num$', num)
f_out.write(templine2)
elif '$group$' in line or '$GROUP$' in line :
for grname in config.keys():
templine1 = line.replace('$group$', grname)
templine2 = templine1.replace('$GROUP$', grname.upper())
f_out.write(templine2)
else:
f_out.write(line)

View File

@ -0,0 +1,15 @@
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
cat $DIR/prefix_front.c > trexio.c
cat $DIR/prefix_front.h > trexio.h
cat $DIR/prefix_s_front.h > trexio_s.h
cat $DIR/populated/pop_*.c >> trexio.c
cat $DIR/populated/pop_*.h >> trexio.h
cat $DIR/suffix_s_front.h >> trexio_s.h
cat $DIR/suffix_front.h >> trexio.h

View File

@ -0,0 +1,555 @@
#+Title: Templator for frontend
* Constant file prefixes (not used by generator) :noxport:
** Prefixes
#+NAME:header
#+begin_src c
/* This file was generated from the trexio.org org-mode file.
To generate it, open trexio.org in Emacs and execute
M-x org-babel-tangle
*/
#+end_src
#+begin_src c :tangle prefix_front.h :noweb yes
<<header>>
#ifndef _TREXIO_H
#define _TREXIO_H
#include <stdint.h>
#+end_src
#+begin_src c :tangle prefix_front.c :noweb yes
<<header>>
#include <pthread.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "trexio.h"
#include "trexio_s.h"
#include "trexio_text.h"
#include "trexio_hdf5.h"
/*
#include "trexio_json.h"
,*/
#+end_src
#+begin_src c :tangle prefix_s_front.h :noweb yes
<<header>>
#ifndef _TREXIO_S_H
#define _TREXIO_S_H
#include "trexio.h"
#include <pthread.h>
#include <assert.h>
#+end_src
* Coding conventions
- integer types will be defined using types given in ~stdint.h~
- pointers are always initialized to ~NULL~
- when memory is freed, the pointer is set to ~NULL~
- ~assert.h~ should be used extensively
- variable names are in lower case
- ~#define~ constants are in upper case
- structs are suffixed by ~_s~
- types are suffixed by ~_t~
** Memory allocation
Memory allocation of structures can be facilitated by using the
following macro, which ensures that the size of the allocated
object is the same as the size of the data type pointed by the pointer.
#+begin_src c :tangle trexio_private.h
#define MALLOC(T) (T*) malloc (sizeof(T));
#define CALLOC(N,T) (T*) calloc ((N),sizeof(T));
#+end_src
When a pointer is freed, it should be set to ~NULL~.
This can be facilitated by the use of the following macro:
#+begin_src c :tangle trexio_private.h
#define FREE(X) { free(X) ; (X)=NULL; }
#+end_src
* Front end
All calls to TREXIO are thread-safe.
** Error handling
#+begin_src c :tangle prefix_front.h
typedef int32_t trexio_exit_code;
#define TREXIO_FAILURE ( (trexio_exit_code) -1 )
#define TREXIO_SUCCESS ( (trexio_exit_code) 0 )
#define TREXIO_INVALID_ARG_1 ( (trexio_exit_code) 1 )
#define TREXIO_INVALID_ARG_2 ( (trexio_exit_code) 2 )
#define TREXIO_INVALID_ARG_3 ( (trexio_exit_code) 3 )
#define TREXIO_INVALID_ARG_4 ( (trexio_exit_code) 4 )
#define TREXIO_INVALID_ARG_5 ( (trexio_exit_code) 5 )
#define TREXIO_END ( (trexio_exit_code) 10 )
#define TREXIO_READONLY ( (trexio_exit_code) 11 )
#define TREXIO_ERRNO ( (trexio_exit_code) 12 )
#define TREXIO_INVALID_ID ( (trexio_exit_code) 20 )
#define TREXIO_ALLOCATION_FAILED ( (trexio_exit_code) 21 )
#define TREXIO_INVALID_NUM ( (trexio_exit_code) 22 )
#+end_src
** Back ends
#+begin_src c :tangle prefix_front.h
typedef int32_t back_end_t;
#define TREXIO_HDF5 ( (back_end_t) 0 )
#define TREXIO_TEXT ( (back_end_t) 1 )
#define TREXIO_JSON ( (back_end_t) 2 )
#define TREXIO_INVALID_BACK_END ( (back_end_t) 3 )
#+end_src
** Read/write behavior
Every time a reading function is called, the data is read from the
disk. If data needs to be cached, this is left to the user of the
library.
Writing to TREXIO files is done with transactions (all-or-nothing
effect) in a per-group fashion. File writes are attempted by
calling explicitly the flush function, or when the TREXIO file is
closed. If writing is impossible because the data is not valid, no
data is written.
The order in which the data is written is not necessarily consistent
with the order in which the function calls were made.
The TREXIO files are supposed to be opened by only one program at a
time: if the same TREXIO file is modified simultaneously by multiple
concurrent programs, the behavior is not specified.
** TREXIO file type
~trexio_s~ is the the main type for TREXIO files, visible to the users
of the library. This type is kept opaque, and all modifications to
the files will be necessarily done through the use of functions,
taking such a type as argument.
File creation and opening functions will return /TREXIO file handles/,
namely pointers to ~trexio_s~ types. All functions accessing to the
TREXIO files will have as a first argument the TREXIO file handle.
#+begin_src c :tangle prefix_front.h
typedef struct trexio_s trexio_t;
#+end_src
#+begin_src c :tangle prefix_s_front.h
struct trexio_s {
char* file_name;
pthread_mutex_t thread_lock;
back_end_t back_end;
char mode;
char padding[7]; /* Ensures the proper alignment of back-ends */
};
#+end_src
** Polymorphism of the file handle
Polymorphism of the ~trexio_t~ type is handled by ensuring that the
corresponding types for all back ends can be safely casted to
~trexio_t~. This is done by making the back end structs start with
~struct trexio_s~:
#+begin_src c
struct trexio_back_end_s {
trexio_t parent ;
/* add below specific back end data */
}
#+end_src
** File opening
#+begin_src c :tangle prefix_front.h
trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t back_end);
#+end_src
#+begin_src c :tangle prefix_front.c
trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t back_end) {
if (file_name == NULL) return NULL;
if (file_name[0] == '\0') return NULL;
if (back_end < 0) return NULL;
if (back_end >= TREXIO_INVALID_BACK_END) return NULL;
if (mode != 'r' && mode != 'w' && mode != 'a') return NULL;
trexio_t* result = NULL;
/* Allocate data structures */
switch (back_end) {
case TREXIO_TEXT:
result = (trexio_t*) malloc (sizeof(trexio_text_t));
break;
case TREXIO_HDF5:
result = (trexio_t*) malloc (sizeof(trexio_hdf5_t));
break;
/*
case TREXIO_JSON:
result = (trexio_t*) malloc (sizeof(trexio_json_t));
break;
,*/
}
assert (result != NULL); /* TODO: Error handling */
/* Data for the parent type */
result->file_name = (char*) calloc(strlen(file_name)+1,sizeof(char));
strcpy(result->file_name, file_name);
result->back_end = back_end;
result->mode = mode;
int irc = pthread_mutex_init ( &(result->thread_lock), NULL);
assert (irc == 0);
trexio_exit_code rc;
/* Back end initialization */
rc = TREXIO_FAILURE;
switch (back_end) {
case TREXIO_TEXT:
rc = trexio_text_init(result);
break;
case TREXIO_HDF5:
rc = trexio_hdf5_init(result);
break;
/*
case TREXIO_JSON:
rc = trexio_json_init(result);
break;
,*/
}
if (rc != TREXIO_SUCCESS) {
free(result->file_name);
free(result);
return NULL;
}
/* File locking */
rc = TREXIO_FAILURE;
switch (back_end) {
case TREXIO_TEXT:
rc = trexio_text_lock(result);
break;
case TREXIO_HDF5:
rc = TREXIO_SUCCESS;
break;
/*
case TREXIO_JSON:
rc = trexio_json_lock(result);
break;
*/
}
if (rc != TREXIO_SUCCESS) {
free(result->file_name);
free(result);
return NULL;
}
return result;
}
#+end_src
** File closing
#+begin_src c :tangle prefix_front.h
trexio_exit_code trexio_close(trexio_t* file);
#+end_src
#+begin_src c :tangle prefix_front.c
trexio_exit_code trexio_close(trexio_t* file) {
if (file == NULL) return TREXIO_FAILURE;
trexio_exit_code rc;
/* Terminate the back end */
switch (file->back_end) {
case TREXIO_TEXT:
rc = trexio_text_finalize(file);
break;
case TREXIO_HDF5:
rc = trexio_hdf5_finalize(file);
break;
/*
case TREXIO_JSON:
rc = trexio_json_finalize(file);
break;
,*/
default:
assert (1 == 0); /* Impossible case */
}
if (rc != TREXIO_SUCCESS) {
free(file->file_name);
free(file);
return TREXIO_FAILURE;
}
/* File unlocking */
rc = TREXIO_FAILURE;
switch (file->back_end) {
case TREXIO_TEXT:
rc = trexio_text_unlock(file);
break;
case TREXIO_HDF5:
rc = TREXIO_SUCCESS;
break;
/*
case TREXIO_JSON:
rc = trexio_json_unlock(file);
break;
*/
}
/* Terminate front end */
free(file->file_name);
file->file_name = NULL;
int irc = pthread_mutex_destroy( &(file->thread_lock) );
free(file);
if (irc != 0) return TREXIO_ERRNO;
if (rc != TREXIO_SUCCESS) return TREXIO_FAILURE;
return TREXIO_SUCCESS;
}
#+end_src
* Templates for front end
** Template for frontend read/write a number
#+begin_src c :tangle rw_num_front.h
trexio_exit_code trexio_read_$group_num$(trexio_t* file, int64_t* num);
trexio_exit_code trexio_write_$group_num$(trexio_t* file, const int64_t num);
#+end_src
#+begin_src c :tangle read_num_front.c
trexio_exit_code trexio_read_$group_num$(trexio_t* file, int64_t* num) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
uint64_t u_num = 0;
trexio_exit_code rc = TREXIO_FAILURE;
switch (file->back_end) {
case TREXIO_TEXT:
rc = trexio_text_read_$group_num$(file, &u_num);
break;
case TREXIO_HDF5:
rc = trexio_hdf5_read_$group_num$(file, &u_num);
break;
/*
case TREXIO_JSON:
rc =trexio_json_read_$group_num$(file, &u_num);
break;
,*/
}
if (rc != TREXIO_SUCCESS) return rc;
/**/ *num = (int64_t) u_num;
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle write_num_front.c
trexio_exit_code trexio_write_$group_num$(trexio_t* file, const int64_t num) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (num < 0 ) return TREXIO_INVALID_ARG_2;
trexio_exit_code rc = TREXIO_FAILURE;
switch (file->back_end) {
case TREXIO_TEXT:
rc = trexio_text_write_$group_num$(file, (uint64_t) num);
break;
case TREXIO_HDF5:
rc = trexio_hdf5_write_$group_num$(file, (uint64_t) num);
break;
/*
case TREXIO_JSON:
rc = trexio_json_write_$group_num$(file, (uint64_t) num);
break;
,*/
}
if (rc != TREXIO_SUCCESS) return rc;
return TREXIO_SUCCESS;
}
#+end_src
** Template for frontend read/write a dataset
#+begin_src c :tangle rw_dset_front.h
trexio_exit_code trexio_read_$group$_$group_dset$(trexio_t* file, $group_dset_dtype$* $group_dset$);
trexio_exit_code trexio_write_$group$_$group_dset$(trexio_t* file, const $group_dset_dtype$* $group_dset$);
#+end_src
#+begin_src c :tangle read_dset_front.c
trexio_exit_code trexio_read_$group$_$group_dset$(trexio_t* file, $group_dset_dtype$* $group_dset$) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if ($group_dset$ == NULL) return TREXIO_INVALID_ARG_2;
trexio_exit_code rc;
uint64_t $group_dset_dim$ = -1;
switch (file->back_end) {
case TREXIO_TEXT:
rc = trexio_text_read_$group_dset_dim$(file, &$group_dset_dim$);
break;
case TREXIO_HDF5:
rc = trexio_hdf5_read_$group_dset_dim$(file, &$group_dset_dim$);
break;
/*
case TREXIO_JSON:
rc = trexio_json_read_$group_dset_dim$(file, &$group_dset_dim$);
break;
*/
}
if (rc != TREXIO_SUCCESS) return rc;
if ($group_dset_dim$ <= 0L) return TREXIO_INVALID_NUM;
uint32_t rank = $group_dset_rank$;
uint64_t dims[$group_dset_rank$] = {$group_dset_dim_list$};
switch (file->back_end) {
case TREXIO_TEXT:
return trexio_text_read_$group$_$group_dset$(file, $group_dset$, rank, dims);
break;
case TREXIO_HDF5:
return trexio_hdf5_read_$group$_$group_dset$(file, $group_dset$, rank, dims);
break;
/*
case TREXIO_JSON:
return trexio_json_read_$group$_$group_dset$(file, $group_dset$);
break;
,*/
default:
return TREXIO_FAILURE; /* Impossible case */
}
}
#+end_src
#+begin_src c :tangle write_dset_front.c
trexio_exit_code trexio_write_$group$_$group_dset$(trexio_t* file, const $group_dset_dtype$* $group_dset$) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if ($group_dset$ == NULL) return TREXIO_INVALID_ARG_2;
trexio_exit_code rc;
uint64_t $group_dset_dim$ = -1;
switch (file->back_end) {
case TREXIO_TEXT:
rc = trexio_text_read_$group_dset_dim$(file, &$group_dset_dim$);
break;
case TREXIO_HDF5:
rc = trexio_hdf5_read_$group_dset_dim$(file, &$group_dset_dim$);
break;
/*
case TREXIO_JSON:
rc = trexio_json_read_$group_dset_dim$(file, &$group_dset_dim$);
break;
*/
}
if (rc != TREXIO_SUCCESS) return rc;
if ($group_dset_dim$ <= 0L) return TREXIO_INVALID_NUM;
uint32_t rank = $group_dset_rank$;
uint64_t dims[$group_dset_rank$] = {$group_dset_dim_list$};
switch (file->back_end) {
case TREXIO_TEXT:
return trexio_text_write_$group$_$group_dset$(file, $group_dset$, rank, dims);
break;
case TREXIO_HDF5:
return trexio_hdf5_write_$group$_$group_dset$(file, $group_dset$, rank, dims);
break;
/*
case TREXIO_JSON:
return trexio_json_write_$group$_$group_dset$(file, $group_dset$);
break;
,*/
default:
return TREXIO_FAILURE; /* Impossible case */
}
}
#+end_src
* Back ends
TREXIO has multiple possible back ends:
- HDF5: The most efficient back-end, by default
- Text files: not to be used for production, but useful for debugging
- JSON: for portability
* File suffixes :noxport:
#+begin_src c :tangle suffix_front.h
#endif
#+end_src
#+begin_src c :tangle suffix_s_front.h
#endif
#+end_src

View File

@ -0,0 +1,18 @@
#!/bin/sh
cat prefix_hdf5.c > trexio_hdf5.c
cat prefix_hdf5.h > trexio_hdf5.h
cat populated/pop_def_hdf5.c >> trexio_hdf5.c
cat populated/pop_struct_hdf5.h >> trexio_hdf5.h
cat populated/pop_basic_hdf5.c >> trexio_hdf5.c
cat populated/pop_read_dset_hdf5.c >> trexio_hdf5.c
cat populated/pop_read_num_hdf5.c >> trexio_hdf5.c
cat populated/pop_write_dset_hdf5.c >> trexio_hdf5.c
cat populated/pop_write_num_hdf5.c >> trexio_hdf5.c
cat populated/pop_rw_num_hdf5.h >> trexio_hdf5.h
cat populated/pop_rw_dset_hdf5.h >> trexio_hdf5.h
cat suffix_hdf5.h >> trexio_hdf5.h

View File

@ -0,0 +1,349 @@
#+Title: Templator for HDF5 backend
** Constant file prefixes (not used by generator) for HDF5 :noxport:
#+NAME:header
#+begin_src c
/* This file was generated from the org-mode file.
To generate it, open templator_hdf5.org file in Emacs and execute
M-x org-babel-tangle
*/
#+end_src
#+begin_src c :tangle prefix_hdf5.h :noweb yes
<<header>>
#ifndef _TREXIO_HDF5_H
#define _TREXIO_HDF5_H
#include "trexio.h"
#include "trexio_s.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include "hdf5.h"
#include "hdf5_hl.h" // needed for high-level APIs like H5LT, requires additional linking in Makefile
#+end_src
#+begin_src c :tangle prefix_hdf5.c :noweb yes
<<header>>
#include "trexio_hdf5.h"
#+end_src
** Template for HDF5 definitions
#+begin_src c :tangle def_hdf5.c
#define $GROUP$_GROUP_NAME "$group$"
#define $GROUP_NUM$_NAME "$group_num$"
#define $GROUP$_$GROUP_DSET$_NAME "$group_dset$"
#+end_src
** Template for HDF5 structures
#+begin_src c :tangle struct_hdf5.h
typedef struct trexio_hdf5_s {
trexio_t parent ;
hid_t file_id;
hid_t $group$_group;
const char* file_name;
} trexio_hdf5_t;
trexio_exit_code trexio_hdf5_init(trexio_t* file);
trexio_exit_code trexio_hdf5_finalize(trexio_t* file);
#+end_src
** Template for HDF5 init/deinit
#+begin_src c :tangle basic_hdf5.c
trexio_exit_code trexio_hdf5_init(trexio_t* file) {
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
/* If file doesn't exist, create it */
int f_exists = 0;
struct stat st;
if (stat(file->file_name, &st) == 0) f_exists = 1;
if (f_exists == 1) {
switch (file->mode) {
case 'r':
// reading the existing file -> open as RDONLY
f->file_id = H5Fopen(file->file_name, H5F_ACC_RDONLY, H5P_DEFAULT);
break;
case 'a':
// appending the existing file -> open as RDWR
f->file_id = H5Fopen(file->file_name, H5F_ACC_RDWR, H5P_DEFAULT);
break;
case 'w':
// writing the existing file -> overwrite it (_TRUNC) [_EXCL | H5F_ACC_DEBUG as an alternative]
f->file_id = H5Fcreate(file->file_name, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
break;
}
} else {
switch (file->mode) {
case 'r':
case 'a':
// reading or appending non-existing file -> error
return TREXIO_FAILURE;
case 'w':
// writing non-existing file -> create it
f->file_id = H5Fcreate(file->file_name, H5F_ACC_EXCL, H5P_DEFAULT, H5P_DEFAULT);
break;
}
}
/* Create or open groups in the hdf5 file assuming that they exist if file exists */
switch (file->mode) {
// the switch for 'r'/'a' is reached only if file exists
case 'r':
case 'a':
f->$group$_group = H5Gopen(f->file_id, $GROUP$_GROUP_NAME, H5P_DEFAULT);
//f->electron_group = H5Gopen(f->file_id, ELECTRON_GROUP_NAME, H5P_DEFAULT);
break;
case 'w':
f->$group$_group = H5Gcreate(f->file_id, $GROUP$_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
//f->electron_group = H5Gcreate(f->file_id, ELECTRON_GROUP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
break;
}
assert (f->$group$_group > 0L);
//assert (f->electron_group > 0L);
return TREXIO_SUCCESS;
}
trexio_exit_code trexio_hdf5_finalize(trexio_t* file) {
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
H5Gclose(f->$group$_group);
f->$group$_group = 0;
/*
H5Gclose(f->electron_group);
f->electron_group = 0;
*/
H5Fclose(f->file_id);
f->file_id = 0;
return TREXIO_SUCCESS;
}
#+end_src
** Template for HDF5 read/write a number
#+begin_src c :tangle rw_num_hdf5.h
trexio_exit_code trexio_hdf5_read_$group_num$ (const trexio_t* file, uint64_t* num);
trexio_exit_code trexio_hdf5_write_$group_num$ (const trexio_t* file, const uint64_t num);
#+end_src
#+begin_src c :tangle read_num_hdf5.c
trexio_exit_code trexio_hdf5_read_$group_num$ (const trexio_t* file, uint64_t* num) {
assert (file != NULL);
assert (num != NULL);
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
/* Quit if the dimensioning attribute is missing in the file */
if (H5Aexists(f->$group$_group, $GROUP_NUM$_NAME) == 0) return TREXIO_FAILURE;
/* Read the nucleus_num attribute of nucleus group */
hid_t num_id = H5Aopen(f->$group$_group, $GROUP_NUM$_NAME, H5P_DEFAULT);
if (num_id <= 0) return TREXIO_INVALID_ID;
herr_t status = H5Aread(num_id, H5T_NATIVE_ULLONG, num);
if (status < 0) return TREXIO_FAILURE;
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle write_num_hdf5.c
trexio_exit_code trexio_hdf5_write_$group_num$ (const trexio_t* file, const uint64_t num) {
assert (file != NULL);
assert (num > 0L);
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
hid_t num_id;
herr_t status;
/* Write the dimensioning variables */
hid_t dtype = H5Tcopy(H5T_NATIVE_ULLONG);
if (H5Aexists(f->$group$_group, $GROUP_NUM$_NAME) == 0) {
hid_t dspace = H5Screate(H5S_SCALAR);
num_id = H5Acreate(f->$group$_group, $GROUP_NUM$_NAME, dtype, dspace,
H5P_DEFAULT, H5P_DEFAULT);
if (num_id <= 0) return TREXIO_INVALID_ID;
status = H5Awrite(num_id, dtype, &(num));
if (status < 0) return TREXIO_FAILURE;
H5Sclose(dspace);
} else {
uint64_t infile_num;
trexio_exit_code rc = trexio_hdf5_read_$group_num$(file, &(infile_num));
if (rc != TREXIO_SUCCESS) return rc;
if (infile_num != num) {
if (infile_num != 0) {
printf("%ld -> %ld %s \n", num, infile_num,
"This variable already exists. Overwriting it is not supported");
H5Tclose(dtype);
return TREXIO_FAILURE;
} else {
num_id = H5Aopen(f->$group$_group, $GROUP_NUM$_NAME, H5P_DEFAULT);
if (num_id <= 0) return TREXIO_INVALID_ID;
status = H5Awrite(num_id, dtype, &(num));
if (status < 0) return TREXIO_FAILURE;
}
}
}
H5Aclose(num_id);
H5Tclose(dtype);
return TREXIO_SUCCESS;
}
#+end_src
** Template for HDF5 read/write a dataset
#+begin_src c :tangle rw_dset_hdf5.h
trexio_exit_code trexio_hdf5_read_$group$_$group_dset$(const trexio_t* file, $group_dset_dtype$* $group_dset$, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_$group$_$group_dset$(const trexio_t* file, const $group_dset_dtype$* $group_dset$, const uint32_t rank, const uint64_t* dims);
#+end_src
#+begin_src c :tangle read_dset_hdf5.c
trexio_exit_code trexio_hdf5_read_$group$_$group_dset$(const trexio_t* file, $group_dset_dtype$* $group_dset$, const uint32_t rank, const uint64_t* dims) {
assert (file != NULL);
assert ($group_dset$ != NULL);
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
herr_t status;
int rrank;
// get the rank of the dataset in a file
status = H5LTget_dataset_ndims (f->$group$_group, $GROUP$_$GROUP_DSET$_NAME,
&rrank);
if (status < 0) return TREXIO_FAILURE;
if (rrank != (int) rank) return TREXIO_INVALID_ARG_3;
// open the dataset to get its dimensions
hid_t dset_id = H5Dopen(f->$group$_group, $GROUP$_$GROUP_DSET$_NAME, H5P_DEFAULT);
if (dset_id <= 0) return TREXIO_INVALID_ID;
// allocate space for the dimensions to be read
hsize_t* ddims = (hsize_t*) calloc( (int) rank, sizeof(hsize_t));
if (ddims == NULL) return TREXIO_FAILURE;
// read dimensions from the existing dataset
status = H5LDget_dset_dims(dset_id, ddims);
H5Dclose(dset_id);
if (status < 0) {
free(ddims);
return TREXIO_FAILURE;
}
for (uint32_t i=0; i<rank; i++){
if (ddims[i] != dims[i]) {
free(ddims);
return TREXIO_INVALID_ARG_4;
}
}
free(ddims);
/* High-level H5LT API. No need to deal with dataspaces and datatypes */
status = H5LTread_dataset_$group_dset_h5_dtype$(f->$group$_group,
$GROUP$_$GROUP_DSET$_NAME,
$group_dset$);
if (status < 0) return TREXIO_FAILURE;
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle write_dset_hdf5.c
trexio_exit_code trexio_hdf5_write_$group$_$group_dset$(const trexio_t* file, const $group_dset_dtype$* $group_dset$, const uint32_t rank, const uint64_t* dims) {
assert (file != NULL);
assert ($group_dset$ != NULL);
trexio_exit_code rc;
uint64_t $group_dset_dim$;
// error handling for rc is added by the generator
rc = trexio_hdf5_read_$group_dset_dim$(file, &($group_dset_dim$));
if ($group_dset_dim$ <= 0L) return TREXIO_INVALID_NUM;
trexio_hdf5_t* f = (trexio_hdf5_t*) file;
herr_t status;
if ( H5LTfind_dataset(f->$group$_group, $GROUP$_$GROUP_DSET$_NAME) != 1) {
status = H5LTmake_dataset_$group_dset_h5_dtype$ (f->$group$_group, $GROUP$_$GROUP_DSET$_NAME,
(int) rank, (hsize_t*) dims, $group_dset$);
if (status < 0) return TREXIO_FAILURE;
} else {
hid_t dset_id = H5Dopen(f->$group$_group, $GROUP$_$GROUP_DSET$_NAME, H5P_DEFAULT);
if (dset_id <= 0) return TREXIO_INVALID_ID;
status = H5Dwrite(dset_id, H5T_NATIVE_$GROUP_DSET_H5_DTYPE$, H5S_ALL, H5S_ALL, H5P_DEFAULT, $group_dset$);
H5Dclose(dset_id);
if (status < 0) return TREXIO_FAILURE;
}
return TREXIO_SUCCESS;
}
#+end_src
** Constant file suffixes (not used by generator) for HDF5 :noxport:
#+begin_src c :tangle suffix_hdf5.h
#endif
#+end_src

View File

@ -0,0 +1,31 @@
#!/bin/sh
cat prefix_text.c > trexio_text.c
cat prefix_text.h > trexio_text.h
cat basic_text.c >> trexio_text.c
cat populated/pop_basic_text_group.c >> trexio_text.c
cat populated/pop_struct_text_group_dset.h >> trexio_text.h
cat populated/pop_struct_text_group.h >> trexio_text.h
cat basic_text.h >> trexio_text.h
cat populated/pop_free_group_text.c >> trexio_text.c
cat populated/pop_read_group_text.c >> trexio_text.c
cat populated/pop_flush_group_text.c >> trexio_text.c
cat populated/pop_free_group_text.h >> trexio_text.h
cat populated/pop_read_group_text.h >> trexio_text.h
cat populated/pop_flush_group_text.h >> trexio_text.h
cat populated/pop_read_dset_text.c >> trexio_text.c
cat populated/pop_read_num_text.c >> trexio_text.c
cat populated/pop_write_dset_text.c >> trexio_text.c
cat populated/pop_write_num_text.c >> trexio_text.c
cat populated/pop_rw_num_text.h >> trexio_text.h
cat populated/pop_rw_dset_text.h >> trexio_text.h
cat rdm_text.c >> trexio_text.c
cat rdm_text.h >> trexio_text.h
cat suffix_text.h >> trexio_text.h

View File

@ -0,0 +1,946 @@
#+Title: Templator for TEXT backend
* Constant file prefixes (not used by generator) :noxport:
#+begin_src emacs-lisp
(setq-local org-babel-default-header-args:c '((:comments . "both")))
org-babel-default-header-args:c
#+end_src
#+RESULTS:
: ((:comments . both))
# Local Variables:
# eval: (setq-local org-babel-default-header-args:Python '((:session . "foo")))
# End:
#+NAME:header
#+begin_src c
/* This file was generated from the trexio.org org-mode file.
To generate it, open trexio.org in Emacs and execute
M-x org-babel-tangle
*/
#+end_src
#+begin_src c :tangle prefix_text.h :noweb yes
<<header>>
#ifndef _TREXIO_TEXT_H
#define _TREXIO_TEXT_H
#include "trexio.h"
#include "trexio_private.h"
#include "trexio_s.h"
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#+end_src
#+begin_src c :tangle prefix_text.c :noweb yes
/* This file was generated from the trexio.org org-mode file.
To generate it, open trexio.org in Emacs and execute
M-x org-babel-tangle
*/
#include "trexio_text.h"
#define DEBUG printf("%s : line %d\n", __FILE__, __LINE__);
#+end_src
* TEXT Back end
The "file" produced by the text back end is a directory with one
file per group.
When the file is open, it is locked by the current process. No other
process can read/write the same file. This guarantees that the
representation in memory is consistent with the file and avoid
re-reading the file before writing.
To lock the file, we lock the =.lock= file which is present in the
directory.
The file is written when closed, or when the flush function is called.
*** Template for group-related structures in text back end
#+begin_src c :tangle struct_text_group_dset.h
typedef struct $group$_s {
FILE* file;
$group_dset_dtype$* $group_dset$;
uint64_t $group_num$;
uint64_t dims_$group_dset$[16];
uint32_t rank_$group_dset$;
int to_flush;
} $group$_t;
#+end_src
*** Template for general structure in text back end
#+begin_src c :tangle struct_text_group.h
typedef struct rdm_s {
FILE* file;
uint64_t dim_one_e;
double* one_e;
char* two_e_file_name;
int to_flush;
} rdm_t;
typedef struct trexio_text_s {
trexio_t parent ;
int lock_file;
$group$_t* $group$;
rdm_t* rdm;
} trexio_text_t;
#+end_src
*** Init/deinit functions (constant part)
#+begin_src c :tangle basic_text.h
trexio_exit_code trexio_text_init(trexio_t* file);
#+end_src
#+begin_src c :tangle basic_text.c
trexio_exit_code trexio_text_init(trexio_t* file) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
trexio_text_t* f = (trexio_text_t*) file;
/* Put all pointers to NULL but leave parent untouched */
memset(&(f->parent)+1,0,sizeof(trexio_text_t)-sizeof(trexio_t));
/* If directory doesn't exist, create it in write mode */
struct stat st;
if (stat(file->file_name, &st) == 0 && S_ISDIR(st.st_mode)) {
/* Do nothing */
} else {
if (file->mode == 'r') return TREXIO_READONLY;
if (mkdir(file->file_name, 0777) != 0) {
return TREXIO_FAILURE;
}
}
/* Create the lock file in the directory */
const char* lock_file_name = "/.lock";
char* file_name =
CALLOC(strlen(file->file_name) + strlen(lock_file_name) + 1, char);
if (file_name == NULL) {
return TREXIO_ALLOCATION_FAILED;
}
strcpy (file_name, file->file_name);
strcat (file_name, lock_file_name);
f->lock_file = open(file_name,O_WRONLY|O_CREAT|O_TRUNC, 0644);
FREE(file_name);
if (f->lock_file <= 0) {
return TREXIO_FAILURE;
}
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle basic_text.h
trexio_exit_code trexio_text_lock(trexio_t* file);
#+end_src
#+begin_src c :tangle basic_text.c
trexio_exit_code trexio_text_lock(trexio_t* file) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
trexio_text_t* f = (trexio_text_t*) file;
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
int rc = fcntl(f->lock_file, F_SETLKW, &fl);
if (rc == -1) return TREXIO_FAILURE;
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle basic_text.h
trexio_exit_code trexio_text_finalize(trexio_t* file);
#+end_src
#+begin_src c :tangle basic_text.h
trexio_exit_code trexio_text_unlock(trexio_t* file);
#+end_src
#+begin_src c :tangle basic_text.c
trexio_exit_code trexio_text_unlock(trexio_t* file) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
trexio_text_t* f = (trexio_text_t*) file;
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_pid = getpid();
fl.l_type = F_UNLCK;
fcntl(f->lock_file, F_SETLK, &fl);
close(f->lock_file);
return TREXIO_SUCCESS;
}
#+end_src
*** Init/deinit functions (templated part)
#+begin_src c :tangle basic_text_group.c
trexio_exit_code trexio_text_finalize(trexio_t* file) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
trexio_exit_code rc;
//rc = trexio_text_free_$group$( (trexio_text_t*) file);
//assert (rc == TREXIO_SUCCESS);
assert (trexio_text_free_$group$( (trexio_text_t*) file) == TREXIO_SUCCESS);
rc = trexio_text_free_rdm( (trexio_text_t*) file);
assert (rc == TREXIO_SUCCESS);
return TREXIO_SUCCESS;
}
#+end_src
*** Template for text read struct
#+begin_src c :tangle read_group_text.h
$group$_t* trexio_text_read_$group$(trexio_text_t* file);
#+end_src
#+begin_src c :tangle read_group_text.c
$group$_t* trexio_text_read_$group$(trexio_text_t* file) {
if (file == NULL) return NULL;
/* If the data structure exists, return it */
if (file->$group$ != NULL) {
return file->$group$;
}
/* Allocate the data structure */
$group$_t* $group$ = MALLOC($group$_t);
if ($group$ == NULL) return NULL;
memset($group$,0,sizeof($group$_t));
/* Build the file name */
const char* $group$_file_name = "/$group$.txt";
char * file_name = (char*)
calloc( strlen(file->parent.file_name) + strlen($group$_file_name) + 1,
sizeof(char));
if (file_name == NULL) {
FREE($group$);
DEBUG
return NULL;
}
strcpy (file_name, file->parent.file_name);
strcat (file_name, $group$_file_name);
/* If the file exists, read it */
FILE* f = fopen(file_name,"r");
if (f != NULL) {
/* Find size of file to allocate the max size of the string buffer */
fseek(f, 0L, SEEK_END);
size_t sz = ftell(f);
fseek(f, 0L, SEEK_SET);
char* buffer = CALLOC(sz,char);
if (buffer == NULL) {
FREE(file_name);
FREE($group$);
DEBUG
return NULL;
}
/* Read the dimensioning variables */
int rc;
// START REPEAT GROUP_DSET
rc = fscanf(f, "%s", buffer);
if ((rc != 1) || (strcmp(buffer, "rank_$group_dset$") != 0)) {
FREE(buffer);
FREE(file_name);
FREE($group$);
DEBUG
return NULL;
}
rc = fscanf(f, "%u", &($group$->rank_$group_dset$));
if (rc != 1) {
FREE(buffer);
FREE(file_name);
FREE($group$);
DEBUG
return NULL;
}
uint64_t size_$group_dset$ = 1;
for (unsigned int i=0; i<$group$->rank_$group_dset$; i++){
unsigned int j=-1;
rc = fscanf(f, "%s %u", buffer, &j);
if ((rc != 2) || (strcmp(buffer, "dims_$group_dset$") != 0) || (j!=i)) {
FREE(buffer);
FREE(file_name);
FREE($group$);
DEBUG
return NULL;
}
rc = fscanf(f, "%lu\n", &($group$->dims_$group_dset$[i]));
assert(!(rc != 1));
if (rc != 1) {
FREE(buffer);
FREE(file_name);
FREE($group$);
DEBUG
return NULL;
}
size_$group_dset$ *= $group$->dims_$group_dset$[i];
}
// END REPEAT GROUP_DSET
// START REPEAT GROUP_NUM
/* Read data */
rc = fscanf(f, "%s", buffer);
assert(!((rc != 1) || (strcmp(buffer, "$group_num$") != 0)));
if ((rc != 1) || (strcmp(buffer, "$group_num$") != 0)) {
FREE(buffer);
FREE(file_name);
FREE($group$);
DEBUG
return NULL;
}
rc = fscanf(f, "%lu", &($group$->$group_num$));
assert(!(rc != 1));
if (rc != 1) {
FREE(buffer);
FREE(file_name);
FREE($group$);
DEBUG
return NULL;
}
// END REPEAT GROUP_NUM
// START REPEAT GROUP_DSET
/* Allocate arrays */
$group$->$group_dset$ = ($group_dset_dtype$*) calloc(size_$group_dset$, sizeof($group_dset_dtype$));
assert (!($group$->$group_dset$ == NULL));
if ($group$->$group_dset$ == NULL) {
FREE(buffer);
FREE(file_name);
FREE($group$);
DEBUG
return NULL;
}
rc = fscanf(f, "%s", buffer);
assert(!((rc != 1) || (strcmp(buffer, "$group_dset$") != 0)));
if ((rc != 1) || (strcmp(buffer, "$group_dset$") != 0)) {
FREE(buffer);
FREE(file_name);
// TODO: free all dsets
FREE($group$->$group_dset$);
FREE($group$);
DEBUG
return NULL;
}
for (uint64_t i=0 ; i<size_$group_dset$ ; i++) {
rc = fscanf(f, "%$group_dset_std_dtype$", &($group$->$group_dset$[i]));
assert(!(rc != 1));
if (rc != 1) {
FREE(buffer);
FREE(file_name);
// TODO: free all dsets
FREE($group$->$group_dset$);
FREE($group$);
DEBUG
return NULL;
}
}
// END REPEAT GROUP_DSET
FREE(buffer);
fclose(f);
f = NULL;
}
if (file->parent.mode == 'w') {
$group$->file = fopen(file_name,"a");
} else {
$group$->file = fopen(file_name,"r");
}
FREE(file_name);
assert (!($group$->file == NULL));
if ($group$->file == NULL) {
// TODO: free all dsets
FREE($group$->$group_dset$);
FREE($group$);
DEBUG
return NULL;
}
fseek($group$->file, 0L, SEEK_SET);
file->$group$ = $group$;
return $group$;
}
#+end_src
*** Template for text flush struct
#+begin_src c :tangle flush_group_text.h
trexio_exit_code trexio_text_flush_$group$(const trexio_text_t* file);
#+end_src
#+begin_src c :tangle flush_group_text.c
trexio_exit_code trexio_text_flush_$group$(const trexio_text_t* file) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (file->parent.mode == 'r') return TREXIO_READONLY;
$group$_t* $group$ = file->$group$;
if ($group$ == NULL) return TREXIO_SUCCESS;
if ($group$->to_flush == 0) return TREXIO_SUCCESS;
FILE* f = $group$->file;
assert (f != NULL);
rewind(f);
/* Write the dimensioning variables */
// START REPEAT GROUP_DSET
fprintf(f, "rank_$group_dset$ %d\n", $group$->rank_$group_dset$);
uint64_t size_$group_dset$ = 1;
for (unsigned int i=0; i<$group$->rank_$group_dset$; i++){
fprintf(f, "dims_$group_dset$ %d %ld\n", i, $group$->dims_$group_dset$[i]);
size_$group_dset$ *= $group$->dims_$group_dset$[i];
}
// END REPEAT GROUP_DSET
// START REPEAT GROUP_NUM
fprintf(f, "$group_num$ %ld\n", $group$->$group_num$);
// END REPEAT GROUP_NUM
// START REPEAT GROUP_DSET
/* Write arrays */
fprintf(f, "$group_dset$\n");
for (uint64_t i=0 ; i<size_$group_dset$ ; i++) {
fprintf(f, "%$group_dset_std_dtype$\n", $group$->$group_dset$[i]);
}
// END REPEAT GROUP_DSET
fflush(f);
file->$group$->to_flush = 0;
return TREXIO_SUCCESS;
}
#+end_src
*** Template for text free memory
Memory is allocated when reading. The following function frees memory.
#+begin_src c :tangle free_group_text.h
trexio_exit_code trexio_text_free_$group$(trexio_text_t* file);
#+end_src
#+begin_src c :tangle free_group_text.c
trexio_exit_code trexio_text_free_$group$(trexio_text_t* file) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
trexio_exit_code rc;
if (file->parent.mode != 'r') {
rc = trexio_text_flush_$group$(file);
if (rc != TREXIO_SUCCESS) return TREXIO_FAILURE;
}
$group$_t* $group$ = file->$group$;
if ($group$ == NULL) return TREXIO_SUCCESS;
if ($group$->file != NULL) {
fclose($group$->file);
$group$->file = NULL;
}
// START REPEAT GROUP_DSET
if ($group$->$group_dset$ != NULL) {
FREE ($group$->$group_dset$);
}
// END REPEAT GROUP_DSET
FREE ($group$);
return TREXIO_SUCCESS;
}
#+end_src
*** Template for read/write the $group_num$ attribute
#+begin_src c :tangle rw_num_text.h
trexio_exit_code trexio_text_read_$group_num$(const trexio_t* file, uint64_t* num);
trexio_exit_code trexio_text_write_$group_num$(const trexio_t* file, const uint64_t num);
#+end_src
#+begin_src c :tangle read_num_text.c
trexio_exit_code trexio_text_read_$group_num$(const trexio_t* file, uint64_t* num) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (num == NULL) return TREXIO_INVALID_ARG_2;
$group$_t* $group$ = trexio_text_read_$group$((trexio_text_t*) file);
if ($group$ == NULL) return TREXIO_FAILURE;
/**/ *num = $group$->$group_num$;
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle write_num_text.c
trexio_exit_code trexio_text_write_$group_num$(const trexio_t* file, const uint64_t num) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (file->mode == 'r') return TREXIO_READONLY;
$group$_t* $group$ = trexio_text_read_$group$((trexio_text_t*) file);
if ($group$ == NULL) return TREXIO_FAILURE;
$group$->$group_num$ = num;
$group$->to_flush = 1;
return TREXIO_SUCCESS;
}
#+end_src
*** Template for read/write the $group_dset$ dataset
The ~dset~ array is assumed allocated with the appropriate size.
#+begin_src c :tangle rw_dset_text.h
trexio_exit_code trexio_text_read_$group_dset$(const trexio_t* file, $group_dset_dtype$* $group_dset$, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_$group_dset$(const trexio_t* file, const $group_dset_dtype$* $group_dset$, const uint32_t rank, const uint64_t* dims);
#+end_src
#+begin_src c :tangle read_dset_text.c
trexio_exit_code trexio_text_read_$group_dset$(const trexio_t* file, $group_dset_dtype$* $group_dset$, const uint32_t rank, const uint64_t* dims) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if ($group_dset$ == NULL) return TREXIO_INVALID_ARG_2;
$group$_t* $group$ = trexio_text_read_$group$((trexio_text_t*) file);
if ($group$ == NULL) return TREXIO_FAILURE;
if (rank != $group$->rank_$group_dset$) return TREXIO_INVALID_ARG_3;
uint64_t dim_size = 1;
for (unsigned int i=0; i<rank; i++){
if (dims[i] != $group$->dims_$group_dset$[i]) return TREXIO_INVALID_ARG_4;
dim_size *= dims[i];
}
for (uint64_t i=0 ; i<dim_size ; i++) {
$group_dset$[i] = $group$->$group_dset$[i];
}
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle write_dset_text.c
trexio_exit_code trexio_text_write_$group_dset$(const trexio_t* file, const $group_dset_dtype$* $group_dset$, const uint32_t rank, const uint64_t* dims) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if ($group_dset$ == NULL) return TREXIO_INVALID_ARG_2;
if (file->mode == 'r') return TREXIO_READONLY;
$group$_t* $group$ = trexio_text_read_$group$((trexio_text_t*) file);
if ($group$ == NULL) return TREXIO_FAILURE;
if ($group$->$group_dset$ != NULL) {
FREE($group$->$group_dset$);
}
$group$->rank_$group_dset$ = rank;
uint64_t dim_size = 1;
for (unsigned int i=0; i<$group$->rank_$group_dset$; i++){
$group$->dims_$group_dset$[i] = dims[i];
dim_size *= dims[i];
}
$group$->$group_dset$ = ($group_dset_dtype$*) calloc(dim_size, sizeof($group_dset_dtype$));
for (uint64_t i=0 ; i<dim_size ; i++) {
$group$->$group_dset$[i] = $group_dset$[i];
}
$group$->to_flush = 1;
return TREXIO_SUCCESS;
}
#+end_src
*** RDM struct
**** Read the complete struct
#+begin_src c :tangle rdm_text.h
rdm_t* trexio_text_read_rdm(trexio_text_t* file);
#+end_src
#+begin_src c :tangle rdm_text.c
rdm_t* trexio_text_read_rdm(trexio_text_t* file) {
if (file == NULL) return NULL;
if (file->rdm != NULL) return file->rdm;
/* Allocate the data structure */
rdm_t* rdm = MALLOC(rdm_t);
assert (rdm != NULL);
rdm->one_e = NULL;
rdm->two_e_file_name = NULL;
rdm->file = NULL;
rdm->to_flush = 0;
/* Try to open the file. If the file does not exist, return */
const char* rdm_file_name = "/rdm.txt";
char * file_name = (char*)
calloc( strlen(file->parent.file_name) + strlen(rdm_file_name) + 1,
sizeof(char));
assert (file_name != NULL);
strcpy (file_name, file->parent.file_name);
strcat (file_name, rdm_file_name);
/* If the file exists, read it */
FILE* f = fopen(file_name,"r");
if (f != NULL) {
/* Find size of file to allocate the max size of the string buffer */
fseek(f, 0L, SEEK_END);
size_t sz = ftell(f);
fseek(f, 0L, SEEK_SET);
char* buffer = CALLOC(sz,char);
/* Read the dimensioning variables */
int rc;
rc = fscanf(f, "%s", buffer);
assert (rc == 1);
assert (strcmp(buffer, "dim_one_e") == 0);
rc = fscanf(f, "%lu", &(rdm->dim_one_e));
assert (rc == 1);
/* Allocate arrays */
rdm->one_e = (double*) calloc(rdm->dim_one_e, sizeof(double));
assert (rdm->one_e != NULL);
/* Read one_e */
rc = fscanf(f, "%s", buffer);
assert (rc == 1);
assert (strcmp(buffer, "one_e") == 0);
for (uint64_t i=0 ; i<rdm->dim_one_e; i++) {
rc = fscanf(f, "%lf", &(rdm->one_e[i]));
assert (rc == 1);
}
/* Read two_e */
rc = fscanf(f, "%s", buffer);
assert (rc == 1);
assert (strcmp(buffer, "two_e_file_name") == 0);
rc = fscanf(f, "%s", buffer);
assert (rc == 1);
rdm->two_e_file_name = CALLOC (strlen(buffer),char);
strcpy(rdm->two_e_file_name, buffer);
FREE(buffer);
fclose(f);
f = NULL;
}
if (file->parent.mode == 'w') {
rdm->file = fopen(file_name,"a");
} else {
rdm->file = fopen(file_name,"r");
}
FREE(file_name);
file->rdm = rdm ;
return rdm;
}
#+end_src
**** Flush the complete struct
#+begin_src c :tangle rdm_text.h
trexio_exit_code trexio_text_flush_rdm(const trexio_text_t* file);
#+end_src
#+begin_src c :tangle rdm_text.c
trexio_exit_code trexio_text_flush_rdm(const trexio_text_t* file) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (file->parent.mode == 'r') return TREXIO_READONLY;
rdm_t* rdm = file->rdm;
if (rdm == NULL) return TREXIO_SUCCESS;
if (rdm->to_flush == 0) return TREXIO_SUCCESS;
FILE* f = rdm->file;
assert (f != NULL);
rewind(f);
/* Write the dimensioning variables */
fprintf(f, "num %ld\n", rdm->dim_one_e);
/* Write arrays */
fprintf(f, "one_e\n");
for (uint64_t i=0 ; i< rdm->dim_one_e; i++) {
fprintf(f, "%lf\n", rdm->one_e[i]);
}
fprintf(f, "two_e_file_name\n");
fprintf(f, "%s\n", rdm->two_e_file_name);
fflush(f);
file->rdm->to_flush = 0;
return TREXIO_SUCCESS;
}
#+end_src
**** Free memory
Memory is allocated when reading. The followig function frees memory.
#+begin_src c :tangle rdm_text.h
trexio_exit_code trexio_text_free_rdm(trexio_text_t* file);
#+end_src
#+begin_src c :tangle rdm_text.c
trexio_exit_code trexio_text_free_rdm(trexio_text_t* file) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
trexio_exit_code rc;
if (file->parent.mode != 'r') {
rc = trexio_text_flush_rdm(file);
if (rc != TREXIO_SUCCESS) return TREXIO_FAILURE;
}
rdm_t* rdm = file->rdm;
if (rdm == NULL) return TREXIO_SUCCESS;
if (rdm->file != NULL) {
fclose(rdm->file);
rdm->file = NULL;
}
if (rdm->one_e != NULL) {
FREE (rdm->one_e);
}
if (rdm->two_e_file_name != NULL) {
FREE (rdm->two_e_file_name);
}
free (rdm);
file->rdm = NULL;
return TREXIO_SUCCESS;
}
#+end_src
**** Read/Write the one_e attribute
The ~one_e~ array is assumed allocated with the appropriate size.
#+begin_src c :tangle rdm_text.h
trexio_exit_code trexio_text_read_rdm_one_e(const trexio_t* file, double* one_e, const uint64_t dim_one_e);
trexio_exit_code trexio_text_write_rdm_one_e(const trexio_t* file, const double* one_e, const uint64_t dim_one_e);
#+end_src
#+begin_src c :tangle rdm_text.c
trexio_exit_code trexio_text_read_rdm_one_e(const trexio_t* file, double* one_e, const uint64_t dim_one_e) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (one_e == NULL) return TREXIO_INVALID_ARG_2;
rdm_t* rdm = trexio_text_read_rdm((trexio_text_t*) file);
if (rdm == NULL) return TREXIO_FAILURE;
if (dim_one_e != rdm->dim_one_e) return TREXIO_INVALID_ARG_3;
for (uint64_t i=0 ; i<dim_one_e ; i++) {
one_e[i] = rdm->one_e[i];
}
return TREXIO_SUCCESS;
}
trexio_exit_code trexio_text_write_rdm_one_e(const trexio_t* file, const double* one_e, const uint64_t dim_one_e) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (one_e == NULL) return TREXIO_INVALID_ARG_2;
if (file->mode != 'r') return TREXIO_READONLY;
rdm_t* rdm = trexio_text_read_rdm((trexio_text_t*) file);
if (rdm == NULL) return TREXIO_FAILURE;
rdm->dim_one_e = dim_one_e;
for (uint64_t i=0 ; i<dim_one_e ; i++) {
rdm->one_e[i] = one_e[i];
}
rdm->to_flush = 1;
return TREXIO_SUCCESS;
}
#+end_src
**** Read/Write the two_e attribute
~two_e~ is a sparse data structure, which can be too large to fit
in memory. So we provide functions to read and write it by
chunks.
In the text back end, the easiest way to do it is to create a
file for each sparse float structure.
#+begin_src c :tangle rdm_text.h
trexio_exit_code trexio_text_buffered_read_rdm_two_e(const trexio_t* file, const uint64_t offset, const uint64_t size, int64_t* index, double* value);
trexio_exit_code trexio_text_buffered_write_rdm_two_e(const trexio_t* file, const uint64_t offset, const uint64_t size, const int64_t* index, const double* value);
#+end_src
#+begin_src c :tangle rdm_text.c
trexio_exit_code trexio_text_buffered_read_rdm_two_e(const trexio_t* file, const uint64_t offset, const uint64_t size, int64_t* index, double* value) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (index == NULL) return TREXIO_INVALID_ARG_4;
if (value == NULL) return TREXIO_INVALID_ARG_5;
rdm_t* rdm = trexio_text_read_rdm((trexio_text_t*) file);
if (rdm == NULL) return TREXIO_FAILURE;
FILE* f = fopen(rdm->two_e_file_name, "r");
if (f == NULL) return TREXIO_END;
const uint64_t line_length = 64;
fseek(f, (long) offset * line_length, SEEK_SET);
int rc;
for (uint64_t i=0 ; i<size ; i++) {
rc = fscanf(f, "%9ld %9ld %9ld %9ld %24le\n",
&index[4*i],
&index[4*i+1],
&index[4*i+2],
&index[4*i+3],
&value[i]);
if (rc == 5) {
/* Do nothing */
} else if (rc == EOF) {
return TREXIO_END;
} else if (rc == EOF) {
return TREXIO_FAILURE;
}
}
return TREXIO_SUCCESS;
}
trexio_exit_code trexio_text_buffered_write_rdm_two_e(const trexio_t* file, const uint64_t offset, const uint64_t size, const int64_t* index, const double* value) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (index == NULL) return TREXIO_INVALID_ARG_4;
if (value == NULL) return TREXIO_INVALID_ARG_5;
if (file->mode != 'r') return TREXIO_READONLY;
rdm_t* rdm = trexio_text_read_rdm((trexio_text_t*) file);
if (rdm == NULL) return TREXIO_FAILURE;
FILE* f = fopen(rdm->two_e_file_name, "w");
if (f == NULL) return TREXIO_FAILURE;
const uint64_t line_length = 64;
fseek(f, (long) offset * line_length, SEEK_SET);
int rc;
for (uint64_t i=0 ; i<size ; i++) {
rc = fprintf(f, "%9ld %9ld %9ld %9ld %24le\n",
index[4*i],
index[4*i+1],
index[4*i+2],
index[4*i+3],
value[i]);
if (rc != 5) return TREXIO_FAILURE;
}
return TREXIO_SUCCESS;
}
#+end_src
:noexport:
* Constant file suffixes :noxport:
#+begin_src c :tangle suffix_text.h
#endif
#+end_src

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,6 @@
M-x org-babel-tangle
*/
#ifndef _TREXIO_H
#define _TREXIO_H
@ -12,19 +10,19 @@
typedef int32_t trexio_exit_code;
#define TREXIO_FAILURE ( (trexio_exit_code) -1 )
#define TREXIO_SUCCESS ( (trexio_exit_code) 0 )
#define TREXIO_INVALID_ARG_1 ( (trexio_exit_code) 1 )
#define TREXIO_INVALID_ARG_2 ( (trexio_exit_code) 2 )
#define TREXIO_INVALID_ARG_3 ( (trexio_exit_code) 3 )
#define TREXIO_INVALID_ARG_4 ( (trexio_exit_code) 4 )
#define TREXIO_INVALID_ARG_5 ( (trexio_exit_code) 5 )
#define TREXIO_END ( (trexio_exit_code) 10 )
#define TREXIO_READONLY ( (trexio_exit_code) 11 )
#define TREXIO_ERRNO ( (trexio_exit_code) 12 )
#define TREXIO_INVALID_ID ( (trexio_exit_code) 20 )
#define TREXIO_ALLOCATION_FAILED ( (trexio_exit_code) 21 )
#define TREXIO_INVALID_NUM ( (trexio_exit_code) 22 )
#define TREXIO_FAILURE ( (trexio_exit_code) -1 )
#define TREXIO_SUCCESS ( (trexio_exit_code) 0 )
#define TREXIO_INVALID_ARG_1 ( (trexio_exit_code) 1 )
#define TREXIO_INVALID_ARG_2 ( (trexio_exit_code) 2 )
#define TREXIO_INVALID_ARG_3 ( (trexio_exit_code) 3 )
#define TREXIO_INVALID_ARG_4 ( (trexio_exit_code) 4 )
#define TREXIO_INVALID_ARG_5 ( (trexio_exit_code) 5 )
#define TREXIO_END ( (trexio_exit_code) 10 )
#define TREXIO_READONLY ( (trexio_exit_code) 11 )
#define TREXIO_ERRNO ( (trexio_exit_code) 12 )
#define TREXIO_INVALID_ID ( (trexio_exit_code) 20 )
#define TREXIO_ALLOCATION_FAILED ( (trexio_exit_code) 21 )
#define TREXIO_INVALID_NUM ( (trexio_exit_code) 22 )
typedef int32_t back_end_t;
@ -38,20 +36,34 @@ typedef struct trexio_s trexio_t;
trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t back_end);
trexio_exit_code trexio_close(trexio_t* file);
trexio_exit_code trexio_read_nucleus_charge(trexio_t* file, double* nucleus_charge);
trexio_exit_code trexio_write_nucleus_charge(trexio_t* file, const double* nucleus_charge);
trexio_exit_code trexio_read_nucleus_coord(trexio_t* file, double* nucleus_coord);
trexio_exit_code trexio_write_nucleus_coord(trexio_t* file, const double* nucleus_coord);
trexio_exit_code trexio_read_ecp_lmax_plus_1(trexio_t* file, int64_t* ecp_lmax_plus_1);
trexio_exit_code trexio_write_ecp_lmax_plus_1(trexio_t* file, const int64_t* ecp_lmax_plus_1);
trexio_exit_code trexio_read_ecp_z_core(trexio_t* file, int64_t* ecp_z_core);
trexio_exit_code trexio_write_ecp_z_core(trexio_t* file, const int64_t* ecp_z_core);
trexio_exit_code trexio_read_ecp_local_n(trexio_t* file, int64_t* ecp_local_n);
trexio_exit_code trexio_write_ecp_local_n(trexio_t* file, const int64_t* ecp_local_n);
trexio_exit_code trexio_read_ecp_local_exponent(trexio_t* file, double* ecp_local_exponent);
trexio_exit_code trexio_write_ecp_local_exponent(trexio_t* file, const double* ecp_local_exponent);
trexio_exit_code trexio_read_ecp_local_coef(trexio_t* file, double* ecp_local_coef);
trexio_exit_code trexio_write_ecp_local_coef(trexio_t* file, const double* ecp_local_coef);
trexio_exit_code trexio_read_ecp_local_power(trexio_t* file, int64_t* ecp_local_power);
trexio_exit_code trexio_write_ecp_local_power(trexio_t* file, const int64_t* ecp_local_power);
trexio_exit_code trexio_read_ecp_non_local_n(trexio_t* file, int64_t* ecp_non_local_n);
trexio_exit_code trexio_write_ecp_non_local_n(trexio_t* file, const int64_t* ecp_non_local_n);
trexio_exit_code trexio_read_ecp_non_local_exponent(trexio_t* file, double* ecp_non_local_exponent);
trexio_exit_code trexio_write_ecp_non_local_exponent(trexio_t* file, const double* ecp_non_local_exponent);
trexio_exit_code trexio_read_ecp_non_local_coef(trexio_t* file, double* ecp_non_local_coef);
trexio_exit_code trexio_write_ecp_non_local_coef(trexio_t* file, const double* ecp_non_local_coef);
trexio_exit_code trexio_read_ecp_non_local_power(trexio_t* file, int64_t* ecp_non_local_power);
trexio_exit_code trexio_write_ecp_non_local_power(trexio_t* file, const int64_t* ecp_non_local_power);
trexio_exit_code trexio_read_nucleus_num(trexio_t* file, int64_t* num);
trexio_exit_code trexio_write_nucleus_num(trexio_t* file, const int64_t num);
trexio_exit_code trexio_read_nucleus_coord(trexio_t* file, double* coord);
trexio_exit_code trexio_write_nucleus_coord(trexio_t* file, const double* coord);
trexio_exit_code trexio_read_nucleus_charge(trexio_t* file, double* charge);
trexio_exit_code trexio_write_nucleus_charge(trexio_t* file, const double* charge);
trexio_exit_code trexio_read_rdm_one_e(trexio_t* file, double* one_e);
trexio_exit_code trexio_write_rdm_one_e(trexio_t* file, const double* one_e);
trexio_exit_code trexio_buffered_read_rdm_two_e(trexio_t* file, const int64_t offset, const int64_t size, int64_t* index, double* value);
trexio_exit_code trexio_buffered_write_rdm_two_e(trexio_t* file, const int64_t offset, const int64_t size, const int64_t* index, const double* value);
trexio_exit_code trexio_read_ecp_local_num_n_max(trexio_t* file, int64_t* num);
trexio_exit_code trexio_write_ecp_local_num_n_max(trexio_t* file, const int64_t num);
trexio_exit_code trexio_read_ecp_non_local_num_n_max(trexio_t* file, int64_t* num);
trexio_exit_code trexio_write_ecp_non_local_num_n_max(trexio_t* file, const int64_t num);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,12 @@
/* This file was generated from the trexio.org org-mode file.
To generate it, open trexio.org in Emacs and execute
/* This file was generated from the org-mode file.
To generate it, open templator_hdf5.org file in Emacs and execute
M-x org-babel-tangle
*/
#ifndef _TREXIO_HDF5_H
#define _TREXIO_HDF5_H
#include "trexio.h"
#include "trexio_private.h"
#include "trexio_s.h"
#include <stdint.h>
#include <stdio.h>
@ -20,79 +17,44 @@
#include "hdf5.h"
#include "hdf5_hl.h" // needed for high-level APIs like H5LT, requires additional linking in Makefile
typedef struct slab_s {
uint64_t a;
uint64_t b;
uint64_t c;
uint64_t d;
} slab_t;
typedef struct dset_s {
hid_t dset_id;
hid_t dspace_id;
hid_t dtype_id;
uint64_t* dims;
uint32_t rank;
const char* dset_name;
} dset_t;
typedef struct h5nucleus_s {
uint64_t num;
double *coord;
double *charge;
dset_t* h5_coord;
dset_t* h5_charge;
} h5nucleus_t;
typedef struct h5electron_s {
uint64_t alpha_num;
uint64_t beta_num;
} h5electron_t;
typedef struct trexio_hdf5_s {
trexio_t parent ;
hid_t file_id;
hid_t nucleus_group;
hid_t electron_group;
//... other groups' id
hid_t ecp_group;
const char* file_name;
} trexio_hdf5_t;
trexio_exit_code trexio_hdf5_init(trexio_t* file);
trexio_exit_code trexio_hdf5_finalize(trexio_t* file);
typedef struct one_index_s {
double value;
int64_t i;
} one_index_t;
typedef struct two_index_s {
double value;
int64_t i;
int64_t j;
} two_index_t;
typedef struct three_index_s {
double value;
int64_t i;
int64_t j;
int64_t k;
} three_index_t;
typedef struct four_index_s {
double value;
int64_t i;
int64_t j;
int64_t k;
int64_t l;
} four_index_t;
trexio_exit_code trexio_hdf5_read_nucleus_num(const trexio_t* file, uint64_t* num);
trexio_exit_code trexio_hdf5_write_nucleus_num(const trexio_t* file, const uint64_t num);
trexio_exit_code trexio_hdf5_read_nucleus_coord(const trexio_t* file, double* coord, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_nucleus_coord(const trexio_t* file, const double* coord, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_nucleus_num (const trexio_t* file, uint64_t* num);
trexio_exit_code trexio_hdf5_write_nucleus_num (const trexio_t* file, const uint64_t num);
trexio_exit_code trexio_hdf5_read_ecp_local_num_n_max (const trexio_t* file, uint64_t* num);
trexio_exit_code trexio_hdf5_write_ecp_local_num_n_max (const trexio_t* file, const uint64_t num);
trexio_exit_code trexio_hdf5_read_ecp_non_local_num_n_max (const trexio_t* file, uint64_t* num);
trexio_exit_code trexio_hdf5_write_ecp_non_local_num_n_max (const trexio_t* file, const uint64_t num);
trexio_exit_code trexio_hdf5_read_nucleus_charge(const trexio_t* file, double* nucleus_charge, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_nucleus_charge(const trexio_t* file, const double* nucleus_charge, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_nucleus_coord(const trexio_t* file, double* nucleus_coord, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_nucleus_coord(const trexio_t* file, const double* nucleus_coord, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_ecp_lmax_plus_1(const trexio_t* file, int64_t* ecp_lmax_plus_1, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_ecp_lmax_plus_1(const trexio_t* file, const int64_t* ecp_lmax_plus_1, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_ecp_z_core(const trexio_t* file, int64_t* ecp_z_core, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_ecp_z_core(const trexio_t* file, const int64_t* ecp_z_core, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_ecp_local_n(const trexio_t* file, int64_t* ecp_local_n, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_ecp_local_n(const trexio_t* file, const int64_t* ecp_local_n, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_ecp_local_exponent(const trexio_t* file, double* ecp_local_exponent, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_ecp_local_exponent(const trexio_t* file, const double* ecp_local_exponent, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_ecp_local_coef(const trexio_t* file, double* ecp_local_coef, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_ecp_local_coef(const trexio_t* file, const double* ecp_local_coef, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_ecp_local_power(const trexio_t* file, int64_t* ecp_local_power, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_ecp_local_power(const trexio_t* file, const int64_t* ecp_local_power, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_ecp_non_local_n(const trexio_t* file, int64_t* ecp_non_local_n, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_ecp_non_local_n(const trexio_t* file, const int64_t* ecp_non_local_n, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_ecp_non_local_exponent(const trexio_t* file, double* ecp_non_local_exponent, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_ecp_non_local_exponent(const trexio_t* file, const double* ecp_non_local_exponent, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_ecp_non_local_coef(const trexio_t* file, double* ecp_non_local_coef, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_ecp_non_local_coef(const trexio_t* file, const double* ecp_non_local_coef, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_read_ecp_non_local_power(const trexio_t* file, int64_t* ecp_non_local_power, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_hdf5_write_ecp_non_local_power(const trexio_t* file, const int64_t* ecp_non_local_power, const uint32_t rank, const uint64_t* dims);
#endif

View File

@ -3,13 +3,10 @@
M-x org-babel-tangle
*/
#ifndef _TREXIO_S_H
#define _TREXIO_S_H
#include "trexio.h"
#include "trexio_private.h"
#include <pthread.h>
#include <assert.h>
@ -20,5 +17,4 @@ struct trexio_s {
char mode;
char padding[7]; /* Ensures the proper alignment of back-ends */
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -20,26 +20,53 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
typedef struct nucleus_s {
FILE* file;
double* coord;
double* charge;
uint64_t num;
uint64_t dims_charge[16];
uint64_t dims_coord[16];
uint32_t rank_charge;
uint32_t rank_coord;
double* nucleus_charge;
double* nucleus_coord;
uint64_t nucleus_num;
uint64_t dims_nucleus_charge[16];
uint64_t dims_nucleus_coord[16];
uint32_t rank_nucleus_charge;
uint32_t rank_nucleus_coord;
int to_flush;
} nucleus_t;
typedef struct electron_s {
typedef struct ecp_s {
FILE* file;
uint64_t alpha_num;
uint64_t beta_num;
int to_flush;
} electron_t;
int64_t* ecp_lmax_plus_1;
int64_t* ecp_z_core;
int64_t* ecp_local_n;
double* ecp_local_exponent;
double* ecp_local_coef;
int64_t* ecp_local_power;
int64_t* ecp_non_local_n;
double* ecp_non_local_exponent;
double* ecp_non_local_coef;
int64_t* ecp_non_local_power;
uint64_t ecp_local_num_n_max;
uint64_t ecp_non_local_num_n_max;
uint64_t dims_ecp_lmax_plus_1[16];
uint64_t dims_ecp_z_core[16];
uint64_t dims_ecp_local_n[16];
uint64_t dims_ecp_local_exponent[16];
uint64_t dims_ecp_local_coef[16];
uint64_t dims_ecp_local_power[16];
uint64_t dims_ecp_non_local_n[16];
uint64_t dims_ecp_non_local_exponent[16];
uint64_t dims_ecp_non_local_coef[16];
uint64_t dims_ecp_non_local_power[16];
uint32_t rank_ecp_lmax_plus_1;
uint32_t rank_ecp_z_core;
uint32_t rank_ecp_local_n;
uint32_t rank_ecp_local_exponent;
uint32_t rank_ecp_local_coef;
uint32_t rank_ecp_local_power;
uint32_t rank_ecp_non_local_n;
uint32_t rank_ecp_non_local_exponent;
uint32_t rank_ecp_non_local_coef;
uint32_t rank_ecp_non_local_power;
int to_flush;
} ecp_t;
typedef struct rdm_s {
FILE* file;
uint64_t dim_one_e;
@ -51,12 +78,10 @@ typedef struct rdm_s {
typedef struct trexio_text_s {
trexio_t parent ;
int lock_file;
nucleus_t* nucleus;
electron_t* electron;
nucleus_t* nucleus;
ecp_t* ecp;
rdm_t* rdm;
} trexio_text_t;
trexio_exit_code trexio_text_init(trexio_t* file);
trexio_exit_code trexio_text_lock(trexio_t* file);
@ -64,22 +89,42 @@ trexio_exit_code trexio_text_lock(trexio_t* file);
trexio_exit_code trexio_text_finalize(trexio_t* file);
trexio_exit_code trexio_text_unlock(trexio_t* file);
nucleus_t* trexio_text_read_nucleus(trexio_text_t* file);
trexio_exit_code trexio_text_flush_nucleus(const trexio_text_t* file);
trexio_exit_code trexio_text_free_nucleus(trexio_text_t* file);
trexio_exit_code trexio_text_free_ecp(trexio_text_t* file);
nucleus_t* trexio_text_read_nucleus(trexio_text_t* file);
ecp_t* trexio_text_read_ecp(trexio_text_t* file);
trexio_exit_code trexio_text_flush_nucleus(const trexio_text_t* file);
trexio_exit_code trexio_text_flush_ecp(const trexio_text_t* file);
trexio_exit_code trexio_text_read_nucleus_num(const trexio_t* file, uint64_t* num);
trexio_exit_code trexio_text_write_nucleus_num(const trexio_t* file, const uint64_t num);
trexio_exit_code trexio_text_read_nucleus_coord(const trexio_t* file, double* coord, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_nucleus_coord(const trexio_t* file, const double* coord, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_nucleus_charge(const trexio_t* file, double* charge, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_nucleus_charge(const trexio_t* file, const double* charge, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_ecp_local_num_n_max(const trexio_t* file, uint64_t* num);
trexio_exit_code trexio_text_write_ecp_local_num_n_max(const trexio_t* file, const uint64_t num);
trexio_exit_code trexio_text_read_ecp_non_local_num_n_max(const trexio_t* file, uint64_t* num);
trexio_exit_code trexio_text_write_ecp_non_local_num_n_max(const trexio_t* file, const uint64_t num);
trexio_exit_code trexio_text_read_nucleus_charge(const trexio_t* file, double* nucleus_charge, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_nucleus_charge(const trexio_t* file, const double* nucleus_charge, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_nucleus_coord(const trexio_t* file, double* nucleus_coord, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_nucleus_coord(const trexio_t* file, const double* nucleus_coord, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_ecp_lmax_plus_1(const trexio_t* file, int64_t* ecp_lmax_plus_1, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_ecp_lmax_plus_1(const trexio_t* file, const int64_t* ecp_lmax_plus_1, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_ecp_z_core(const trexio_t* file, int64_t* ecp_z_core, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_ecp_z_core(const trexio_t* file, const int64_t* ecp_z_core, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_ecp_local_n(const trexio_t* file, int64_t* ecp_local_n, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_ecp_local_n(const trexio_t* file, const int64_t* ecp_local_n, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_ecp_local_exponent(const trexio_t* file, double* ecp_local_exponent, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_ecp_local_exponent(const trexio_t* file, const double* ecp_local_exponent, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_ecp_local_coef(const trexio_t* file, double* ecp_local_coef, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_ecp_local_coef(const trexio_t* file, const double* ecp_local_coef, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_ecp_local_power(const trexio_t* file, int64_t* ecp_local_power, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_ecp_local_power(const trexio_t* file, const int64_t* ecp_local_power, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_ecp_non_local_n(const trexio_t* file, int64_t* ecp_non_local_n, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_ecp_non_local_n(const trexio_t* file, const int64_t* ecp_non_local_n, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_ecp_non_local_exponent(const trexio_t* file, double* ecp_non_local_exponent, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_ecp_non_local_exponent(const trexio_t* file, const double* ecp_non_local_exponent, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_ecp_non_local_coef(const trexio_t* file, double* ecp_non_local_coef, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_ecp_non_local_coef(const trexio_t* file, const double* ecp_non_local_coef, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_read_ecp_non_local_power(const trexio_t* file, int64_t* ecp_non_local_power, const uint32_t rank, const uint64_t* dims);
trexio_exit_code trexio_text_write_ecp_non_local_power(const trexio_t* file, const int64_t* ecp_non_local_power, const uint32_t rank, const uint64_t* dims);
rdm_t* trexio_text_read_rdm(trexio_text_t* file);
trexio_exit_code trexio_text_flush_rdm(const trexio_text_t* file);
@ -91,5 +136,4 @@ trexio_exit_code trexio_text_write_rdm_one_e(const trexio_t* file, const double*
trexio_exit_code trexio_text_buffered_read_rdm_two_e(const trexio_t* file, const uint64_t offset, const uint64_t size, int64_t* index, double* value);
trexio_exit_code trexio_text_buffered_write_rdm_two_e(const trexio_t* file, const uint64_t offset, const uint64_t size, const int64_t* index, const double* value);
#endif