1
0
mirror of https://github.com/TREX-CoE/trexio.git synced 2024-11-03 20:54:07 +01:00

TODO: templator for text backend

This commit is contained in:
q-posev 2021-03-10 16:56:45 +01:00
parent 9244e6f0c0
commit 76fe1b9783

View File

@ -0,0 +1,858 @@
#+Title: TEXT back end of the TREX Input/Ouput library (TREXIO)
* File prefixes :noxport:
#+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 trexio_text.h :noweb yes
<<header>>
#ifndef _TREXIO_TEXT_H
#define _TREXIO_TEXT_H
#include "trexio.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 trexio_text.c :noweb yes
<<header>>
#include "trexio_text.h"
#+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.
*** Structs for blocks
#+begin_src c :tangle trexio_text.h
typedef struct nucleus_s {
FILE* file;
uint64_t dim_coord;
uint64_t dim_charge;
double* coord;
double* charge;
uint64_t num;
int to_flush;
} nucleus_t;
typedef struct electron_s {
FILE* file;
uint64_t alpha_num;
uint64_t beta_num;
int to_flush;
} electron_t;
typedef struct rdm_s {
FILE* file;
uint64_t dim_one_e;
double* one_e;
char* two_e_file_name;
int to_flush;
} rdm_t;
#+end_src
*** TO DO
- to_flush = 1 in write
- to_flush = 0 when flushed
- name
*** Structs for the text back end
#+begin_src c :tangle trexio_text.h
typedef struct trexio_text_s {
trexio_t parent ;
int lock_file;
nucleus_t* nucleus;
electron_t* electron;
rdm_t* rdm;
} trexio_text_t;
#+end_src
*** Init/deinit functions
#+begin_src c :tangle trexio_text.h
trexio_exit_code trexio_text_init(trexio_t* file);
#+end_src
#+begin_src c :tangle trexio_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;
/* 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 = (char*)
calloc( strlen(file->file_name) + strlen(lock_file_name) + 1,
sizeof(char));
assert (file_name != NULL);
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);
assert (f->lock_file > 0);
free(file_name);
f->nucleus = NULL;
f->electron= NULL;
f->rdm = NULL;
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle trexio_text.h
trexio_exit_code trexio_text_lock(trexio_t* file);
#+end_src
#+begin_src c :tangle trexio_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 trexio_text.h
trexio_exit_code trexio_text_finalize(trexio_t* file);
#+end_src
#+begin_src c :tangle trexio_text.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_nucleus( (trexio_text_t*) file);
assert (rc == TREXIO_SUCCESS);
rc = trexio_text_free_rdm( (trexio_text_t*) file);
assert (rc == TREXIO_SUCCESS);
return TREXIO_SUCCESS;
}
#+end_src
#+begin_src c :tangle trexio_text.h
trexio_exit_code trexio_text_unlock(trexio_t* file);
#+end_src
#+begin_src c :tangle trexio_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
*** Nucleus struct
**** Read the struct
#+begin_src c :tangle trexio_text.h
nucleus_t* trexio_text_read_nucleus(trexio_text_t* file);
#+end_src
#+begin_src c :tangle trexio_text.c
nucleus_t* trexio_text_read_nucleus(trexio_text_t* file) {
if (file == NULL) return NULL;
if (file->nucleus != NULL) return file->nucleus;
/* Allocate the data structure */
nucleus_t* nucleus = (nucleus_t*) malloc(sizeof(nucleus_t));
assert (nucleus != NULL);
nucleus->file = NULL;
nucleus->num = 0;
nucleus->coord = NULL;
nucleus->charge = NULL;
nucleus->to_flush = 0;
/* Try to open the file. If the file does not exist, return */
const char* nucleus_file_name = "/nucleus.txt";
char * file_name = (char*)
calloc( strlen(file->parent.file_name) + strlen(nucleus_file_name) + 1,
sizeof(char));
assert (file_name != NULL);
strcpy (file_name, file->parent.file_name);
strcat (file_name, nucleus_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 = (char*) malloc(sz*sizeof(char));
/* Read the dimensioning variables */
int rc;
rc = fscanf(f, "%s", buffer);
assert (rc == 1);
assert (strcmp(buffer, "dim_charge") == 0);
rc = fscanf(f, "%lu", &(nucleus->dim_charge));
assert (rc == 1);
rc = fscanf(f, "%s", buffer);
assert (rc == 1);
assert (strcmp(buffer, "dim_coord") == 0);
rc = fscanf(f, "%lu", &(nucleus->dim_coord));
assert (rc == 1);
/* Allocate arrays */
nucleus->charge = (double*) calloc(nucleus->dim_charge, sizeof(double));
assert (nucleus->charge != NULL);
nucleus->coord = (double*) calloc(nucleus->dim_coord, sizeof(double));
assert (nucleus->coord != NULL);
/* Read data */
rc = fscanf(f, "%s", buffer);
assert (rc == 1);
assert (strcmp(buffer, "num") == 0);
rc = fscanf(f, "%lu", &(nucleus->num));
assert (rc == 1);
rc = fscanf(f, "%s", buffer);
assert (rc == 1);
assert (strcmp(buffer, "charge") == 0);
for (uint64_t i=0 ; i<nucleus->dim_charge ; i++) {
rc = fscanf(f, "%lf", &(nucleus->charge[i]));
assert (rc == 1);
}
rc = fscanf(f, "%s", buffer);
assert (rc == 1);
assert (strcmp(buffer, "coord") == 0);
for (uint64_t i=0 ; i<nucleus->dim_coord ; i++) {
rc = fscanf(f, "%lf", &(nucleus->coord[i]));
assert (rc == 1);
}
free(buffer);
fclose(f);
f = NULL;
}
if (file->parent.mode == 'w') {
nucleus->file = fopen(file_name,"a");
} else {
nucleus->file = fopen(file_name,"r");
}
free(file_name);
file->nucleus = nucleus;
return nucleus;
}
#+end_src
**** Flush the struct
#+begin_src c :tangle trexio_text.h
trexio_exit_code trexio_text_flush_nucleus(const trexio_text_t* file);
#+end_src
#+begin_src c :tangle trexio_text.c
trexio_exit_code trexio_text_flush_nucleus(const trexio_text_t* file) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (file->parent.mode == 'r') return TREXIO_READONLY;
nucleus_t* nucleus = file->nucleus;
if (nucleus == NULL) return TREXIO_SUCCESS;
if (nucleus->to_flush == 0) return TREXIO_SUCCESS;
FILE* f = nucleus->file;
assert (f != NULL);
rewind(f);
/* Write the dimensioning variables */
fprintf(f, "dim_charge %ld\n", nucleus->dim_charge);
fprintf(f, "dim_coord %ld\n", nucleus->dim_coord );
/* Write arrays */
fprintf(f, "num %ld\n", nucleus->num);
fprintf(f, "charge\n");
for (uint64_t i=0 ; i<nucleus->dim_charge ; i++) {
fprintf(f, "%lf\n", nucleus->charge[i]);
}
fprintf(f, "coord\n");
for (uint64_t i=0 ; i<nucleus->dim_coord ; i++) {
fprintf(f, "%lf\n", nucleus->coord[i]);
}
fflush(f);
file->nucleus->to_flush = 0;
return TREXIO_SUCCESS;
}
#+end_src
**** Free memory
Memory is allocated when reading. The following function frees memory.
#+begin_src c :tangle trexio_text.h
trexio_exit_code trexio_text_free_nucleus(trexio_text_t* file);
#+end_src
#+begin_src c :tangle trexio_text.c
trexio_exit_code trexio_text_free_nucleus(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_nucleus(file);
if (rc != TREXIO_SUCCESS) return TREXIO_FAILURE;
}
nucleus_t* nucleus = file->nucleus;
if (nucleus == NULL) return TREXIO_SUCCESS;
if (nucleus->file != NULL) {
fclose(nucleus->file);
nucleus->file = NULL;
}
if (nucleus->coord != NULL) {
free (nucleus->coord);
nucleus->coord = NULL;
}
if (nucleus->charge != NULL) {
free (nucleus->charge);
nucleus->charge = NULL;
}
free (nucleus);
file->nucleus = NULL;
return TREXIO_SUCCESS;
}
#+end_src
**** Read/Write the num attribute
#+begin_src c :tangle trexio_text.h
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);
#+end_src
#+begin_src c :tangle trexio_text.c
trexio_exit_code trexio_text_read_nucleus_num(const trexio_t* file, uint64_t* num) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (num == NULL) return TREXIO_INVALID_ARG_2;
nucleus_t* nucleus = trexio_text_read_nucleus((trexio_text_t*) file);
if (nucleus == NULL) return TREXIO_FAILURE;
/**/ *num = nucleus->num;
return TREXIO_SUCCESS;
}
trexio_exit_code trexio_text_write_nucleus_num(const trexio_t* file, const uint64_t num) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (file->mode == 'r') return TREXIO_READONLY;
nucleus_t* nucleus = trexio_text_read_nucleus((trexio_text_t*) file);
if (nucleus == NULL) return TREXIO_FAILURE;
nucleus->num = num;
nucleus->to_flush = 1;
return TREXIO_SUCCESS;
}
#+end_src
**** Read/Write the coord attribute
The ~coord~ array is assumed allocated with the appropriate size.
#+begin_src c :tangle trexio_text.h
trexio_exit_code trexio_text_read_nucleus_coord(const trexio_t* file, double* coord, const uint64_t dim_coord);
trexio_exit_code trexio_text_write_nucleus_coord(const trexio_t* file, const double* coord, const uint64_t dim_coord);
#+end_src
#+begin_src c :tangle trexio_text.c
trexio_exit_code trexio_text_read_nucleus_coord(const trexio_t* file, double* coord, const uint64_t dim_coord) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (coord == NULL) return TREXIO_INVALID_ARG_2;
nucleus_t* nucleus = trexio_text_read_nucleus((trexio_text_t*) file);
if (nucleus == NULL) return TREXIO_FAILURE;
if (dim_coord != nucleus->dim_coord) return TREXIO_INVALID_ARG_3;
for (uint64_t i=0 ; i<dim_coord ; i++) {
coord[i] = nucleus->coord[i];
}
return TREXIO_SUCCESS;
}
trexio_exit_code trexio_text_write_nucleus_coord(const trexio_t* file, const double* coord, const uint64_t dim_coord) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (coord == NULL) return TREXIO_INVALID_ARG_2;
if (file->mode == 'r') return TREXIO_READONLY;
nucleus_t* nucleus = trexio_text_read_nucleus((trexio_text_t*) file);
if (nucleus == NULL) return TREXIO_FAILURE;
if (nucleus->coord != NULL) {
free(nucleus->coord);
nucleus->coord = NULL;
}
nucleus->dim_coord = dim_coord;
nucleus->coord = (double*) calloc(dim_coord, sizeof(double));
for (uint64_t i=0 ; i<dim_coord ; i++) {
nucleus->coord[i] = coord[i];
}
nucleus->to_flush = 1;
return TREXIO_SUCCESS;
}
#+end_src
**** Read/Write the charge attribute
The ~charge~ array is assumed allocated with the appropriate size.
#+begin_src c :tangle trexio_text.h
trexio_exit_code trexio_text_read_nucleus_charge(const trexio_t* file, double* charge, const uint64_t dim_charge);
trexio_exit_code trexio_text_write_nucleus_charge(const trexio_t* file, const double* charge, const uint64_t dim_charge);
#+end_src
#+begin_src c :tangle trexio_text.c
trexio_exit_code trexio_text_read_nucleus_charge(const trexio_t* file, double* charge, const uint64_t dim_charge) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (charge == NULL) return TREXIO_INVALID_ARG_2;
nucleus_t* nucleus = trexio_text_read_nucleus((trexio_text_t*) file);
if (nucleus == NULL) return TREXIO_FAILURE;
if (dim_charge != nucleus->dim_charge) return TREXIO_INVALID_ARG_3;
for (uint64_t i=0 ; i<dim_charge ; i++) {
charge[i] = nucleus->charge[i];
}
return TREXIO_SUCCESS;
}
trexio_exit_code trexio_text_write_nucleus_charge(const trexio_t* file, const double* charge, const uint64_t dim_charge) {
if (file == NULL) return TREXIO_INVALID_ARG_1;
if (charge == NULL) return TREXIO_INVALID_ARG_2;
if (file->mode == 'r') return TREXIO_READONLY;
nucleus_t* nucleus = trexio_text_read_nucleus((trexio_text_t*) file);
if (nucleus == NULL) return TREXIO_FAILURE;
if (nucleus->charge != NULL) {
free(nucleus->charge);
nucleus->charge = NULL;
}
nucleus->dim_charge = dim_charge;
nucleus->charge = (double*) calloc(dim_charge, sizeof(double));
for (uint64_t i=0 ; i<dim_charge ; i++) {
nucleus->charge[i] = charge[i];
}
nucleus->to_flush = 1;
return TREXIO_SUCCESS;
}
#+end_src
*** RDM struct
**** Read the complete struct
#+begin_src c :tangle trexio_text.h
rdm_t* trexio_text_read_rdm(trexio_text_t* file);
#+end_src
#+begin_src c :tangle trexio_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 = (rdm_t*) malloc(sizeof(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 = (char*) malloc(sz*sizeof(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 = (char*) malloc (strlen(buffer)*sizeof(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 trexio_text.h
trexio_exit_code trexio_text_flush_rdm(const trexio_text_t* file);
#+end_src
#+begin_src c :tangle trexio_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 trexio_text.h
trexio_exit_code trexio_text_free_rdm(trexio_text_t* file);
#+end_src
#+begin_src c :tangle trexio_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);
rdm->one_e = NULL;
}
if (rdm->two_e_file_name != NULL) {
free (rdm->two_e_file_name);
rdm->two_e_file_name = NULL;
}
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 trexio_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 trexio_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 trexio_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 trexio_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
* File suffixes :noxport:
#+begin_src c :tangle trexio_text.h
#endif
#+end_src