MEMORY back end
Table of Contents
- 1. Template for group-related structures in memory back end
- 2. Template for general structure in memory back end
- 3. Initialize function (constant part)
- 4. Deinitialize function (templated part)
- 5. Flush function (templated part)
- 6. Template for memory read a group
- 7. Template for memory has a group
- 8. Template for memory flush a group
- 9. Template for memory free memory
- 10. Template for has/read/write a numerical attribute
- 11. Template for has/read/write a dataset of numerical data
- 12. Template for has/read/write a dataset of strings
- 13. Template for has/read/write a string attribute
- 14. Template for memory delete a group (UNSAFE mode)
- 15. Template for has/read/write the dataset of sparse data
- 16. Template for has/read/write a buffered vector
- 17. Source code for the determinant part
The in-memory back end keeps everything in the memory of the calling
process and writes nothing to disk. It supports the same data as the
other two back ends – numerical and string attributes, dense
datasets, sparse datasets, buffered quantities and the determinant
list – and is selected by passing TREXIO_MEMORY to
trexio_open.
It exists so that data can be passed through the TREXIO API between parts of one program without a file in between: a producer writes into the handle and a consumer reads from the same handle, using the same calls it would use on a file.
Because there is no file, three things differ from the other back ends, and all three follow from that:
- the
file_namegiven totrexio_openis not used for anything, although it still has to be a valid non-empty string; - a file cannot be opened in
'r'mode, since an in-memory file never exists before it is opened. That combination returnsTREXIO_INVALID_ARG_2, reported against the mode; trexio_closediscards the data instead of saving it, andtrexio_flushsucceeds without doing anything. There is no way to recover the contents afterwards, so anything that has to outlive the process must be written to one of the other back ends.
Internally it mirrors the TEXT back end without the file I/O: reading a group returns the in-RAM struct, an empty one if the group has not been written yet. The struct-based categories – numerical attributes, numerical and string datasets, string attributes – live in per-group structs, while sparse, buffered and determinant data live in a generic name-keyed blob store on the handle.
1. Template for group-related structures in memory back end
typedef struct $group$_mem_s { $group_num_dtype_double$ $group_num$; $group_dset_dtype$* $group_dset$; uint64_t dims_$group_dset$[16]; uint64_t len_$group_str$; uint32_t rank_$group_dset$; uint32_t to_flush; bool $group_num$_isSet; char* $group_str$; } $group$_mem_t;
2. Template for general structure in memory back end
Polymorphism of the trexio_t type is handled by ensuring that the
back-end struct starts with a trexio_t parent attribute, so it can be
safely cast to trexio_t.
typedef struct trexio_memory_s { trexio_t parent ; trexio_mem_blob_t* blobs; $group$_mem_t* $group$; } trexio_memory_t;
3. Initialize function (constant part)
trexio_mem_blob_t* trexio_mem_blob_find (trexio_memory_t* const file, const char* name) { trexio_mem_blob_t* b = file->blobs; while (b != NULL) { if (strncmp(b->name, name, sizeof(b->name)) == 0) return b; b = b->next; } return NULL; } trexio_mem_blob_t* trexio_mem_blob_get (trexio_memory_t* const file, const char* name, const int32_t rank) { trexio_mem_blob_t* b = trexio_mem_blob_find(file, name); if (b != NULL) return b; b = (trexio_mem_blob_t*) calloc(1, sizeof(trexio_mem_blob_t)); if (b == NULL) return NULL; strncpy(b->name, name, sizeof(b->name)-1); b->name[sizeof(b->name)-1] = '\0'; b->rank = rank; b->next = file->blobs; file->blobs = b; return b; } void trexio_mem_blob_free_all (trexio_memory_t* const file) { trexio_mem_blob_t* b = file->blobs; while (b != NULL) { trexio_mem_blob_t* next = b->next; free(b->index); free(b->list); free(b->value); free(b); b = next; } file->blobs = NULL; } /* Grow the blob to hold at least `need` items. */ static trexio_exit_code trexio_mem_blob_reserve (trexio_mem_blob_t* const b, const int64_t need, const bool want_index, const bool want_list, const bool want_value) { if (need <= b->capacity) return TREXIO_SUCCESS; int64_t cap = (b->capacity > 0) ? b->capacity : 1024L; while (cap < need) cap *= 2L; if (want_index) { int32_t* p = (int32_t*) realloc(b->index, (size_t) cap * (size_t) b->rank * sizeof(int32_t)); if (p == NULL) return TREXIO_ALLOCATION_FAILED; b->index = p; } if (want_list) { int64_t* p = (int64_t*) realloc(b->list, (size_t) cap * (size_t) b->rank * sizeof(int64_t)); if (p == NULL) return TREXIO_ALLOCATION_FAILED; b->list = p; } if (want_value) { double* p = (double*) realloc(b->value, (size_t) cap * sizeof(double)); if (p == NULL) return TREXIO_ALLOCATION_FAILED; b->value = p; } b->capacity = cap; return TREXIO_SUCCESS; } trexio_exit_code trexio_mem_blob_append_sparse (trexio_mem_blob_t* const b, const int64_t size, const int32_t* index, const double* value) { trexio_exit_code rc = trexio_mem_blob_reserve(b, b->n_items + size, true, false, true); if (rc != TREXIO_SUCCESS) return rc; memcpy(b->index + b->n_items * b->rank, index, (size_t) size * (size_t) b->rank * sizeof(int32_t)); memcpy(b->value + b->n_items, value, (size_t) size * sizeof(double)); b->n_items += size; return TREXIO_SUCCESS; } trexio_exit_code trexio_mem_blob_read_sparse (const trexio_mem_blob_t* const b, const int64_t offset, const int64_t size, int32_t* const index, double* const value, int64_t* const eof) { if (b == NULL || offset >= b->n_items) { *eof = 0L; return TREXIO_END; } const int64_t avail = b->n_items - offset; const int64_t n = (size <= avail) ? size : avail; memcpy(index, b->index + offset * b->rank, (size_t) n * (size_t) b->rank * sizeof(int32_t)); memcpy(value, b->value + offset, (size_t) n * sizeof(double)); if (n < size) { *eof = n; return TREXIO_END; } return TREXIO_SUCCESS; } trexio_exit_code trexio_mem_blob_append_value (trexio_mem_blob_t* const b, const int64_t size, const double* value) { trexio_exit_code rc = trexio_mem_blob_reserve(b, b->n_items + size, false, false, true); if (rc != TREXIO_SUCCESS) return rc; memcpy(b->value + b->n_items, value, (size_t) size * sizeof(double)); b->n_items += size; return TREXIO_SUCCESS; } trexio_exit_code trexio_mem_blob_read_value (const trexio_mem_blob_t* const b, const int64_t offset, const int64_t size, double* const value, int64_t* const eof) { if (b == NULL || offset >= b->n_items) { *eof = 0L; return TREXIO_END; } const int64_t avail = b->n_items - offset; const int64_t n = (size <= avail) ? size : avail; memcpy(value, b->value + offset, (size_t) n * sizeof(double)); if (n < size) { *eof = n; return TREXIO_END; } return TREXIO_SUCCESS; } trexio_exit_code trexio_mem_blob_append_list (trexio_mem_blob_t* const b, const int64_t size, const int64_t* list) { trexio_exit_code rc = trexio_mem_blob_reserve(b, b->n_items + size, false, true, false); if (rc != TREXIO_SUCCESS) return rc; memcpy(b->list + b->n_items * b->rank, list, (size_t) size * (size_t) b->rank * sizeof(int64_t)); b->n_items += size; return TREXIO_SUCCESS; } trexio_exit_code trexio_mem_blob_read_list (const trexio_mem_blob_t* const b, const int64_t offset, const int64_t size, int64_t* const list, int64_t* const eof) { if (b == NULL || offset >= b->n_items) { *eof = 0L; return TREXIO_END; } const int64_t avail = b->n_items - offset; const int64_t n = (size <= avail) ? size : avail; memcpy(list, b->list + offset * b->rank, (size_t) n * (size_t) b->rank * sizeof(int64_t)); if (n < size) { *eof = n; return TREXIO_END; } return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_inquire (const char* file_name) { /* In-memory files do not persist on disk and are never pre-existing. */ (void) file_name; return TREXIO_FAILURE; }
trexio_exit_code trexio_memory_init (trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; trexio_memory_t* const f = (trexio_memory_t*) file; /* Put all pointers to NULL but leave parent untouched */ memset(&(f->parent)+1, 0, sizeof(trexio_memory_t)-sizeof(trexio_t)); return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_lock (trexio_t* const file) { /* Nothing to lock for an in-memory, single-process file. */ if (file == NULL) return TREXIO_INVALID_ARG_1; return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_unlock (trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; return TREXIO_SUCCESS; }
4. Deinitialize function (templated part)
trexio_exit_code trexio_memory_deinit (trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; trexio_exit_code rc; /* Free the in-RAM blob store (sparse / buffered / determinant data). */ trexio_mem_blob_free_all((trexio_memory_t*) file); /* Error handling for this call is added by the generator */ rc = trexio_memory_free_$group$( (trexio_memory_t*) file); return TREXIO_SUCCESS; }
5. Flush function (templated part)
trexio_exit_code trexio_memory_flush (trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; trexio_exit_code rc; trexio_memory_t* f = (trexio_memory_t*) file; rc = trexio_memory_flush_$group$(f); if (rc != TREXIO_SUCCESS) return rc; return TREXIO_SUCCESS; }
6. Template for memory read a group
$group$_mem_t* trexio_memory_read_$group$ (trexio_memory_t* const file) { if (file == NULL) return NULL; /* If the data structure exists, return it; otherwise create an empty one. There is no file to read from for the in-memory back end. */ if (file->$group$ != NULL) { return file->$group$; } $group$_mem_t* $group$ = MALLOC($group$_mem_t); if ($group$ == NULL) return NULL; memset($group$, 0, sizeof($group$_mem_t)); file->$group$ = $group$; return $group$; }
7. Template for memory has a group
trexio_exit_code trexio_memory_has_$group$ (trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; trexio_memory_t* const f = (trexio_memory_t*) file; if (f->$group$ != NULL) { return TREXIO_SUCCESS; } else { return TREXIO_HAS_NOT; } }
8. Template for memory flush a group
trexio_exit_code trexio_memory_flush_$group$ (trexio_memory_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (file->parent.mode == 'r') return TREXIO_READONLY; /* Nothing to flush: the data already lives in memory. */ if (file->$group$ != NULL) file->$group$->to_flush = 0; return TREXIO_SUCCESS; }
9. Template for memory free memory
trexio_exit_code trexio_memory_free_$group$ (trexio_memory_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; $group$_mem_t* $group$ = file->$group$; if ($group$ == NULL) return TREXIO_SUCCESS; // START REPEAT GROUP_DSET_NUM if ($group$->$group_dset$ != NULL) FREE ($group$->$group_dset$); // END REPEAT GROUP_DSET_NUM // START REPEAT GROUP_DSET_STR if ($group$->$group_dset$ != NULL) { if ($group$->rank_$group_dset$ != 0) FREE ($group$->$group_dset$[0]); FREE ($group$->$group_dset$); } // END REPEAT GROUP_DSET_STR // START REPEAT GROUP_ATTR_STR if ($group$->$group_str$ != NULL) FREE ($group$->$group_str$); // END REPEAT GROUP_ATTR_STR FREE ($group$); file->$group$ = NULL; return TREXIO_SUCCESS; }
10. Template for has/read/write a numerical attribute
trexio_exit_code trexio_memory_read_$group_num$ (trexio_t* const file, $group_num_dtype_double$* const num) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (num == NULL) return TREXIO_INVALID_ARG_2; $group$_mem_t* $group$ = trexio_memory_read_$group$((trexio_memory_t*) file); if ($group$ == NULL) return TREXIO_FAILURE; *num = $group$->$group_num$; return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_write_$group_num$ (trexio_t* const file, const $group_num_dtype_double$ num) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (file->mode == 'r') return TREXIO_READONLY; $group$_mem_t* $group$ = trexio_memory_read_$group$((trexio_memory_t*) file); if ($group$ == NULL) return TREXIO_FAILURE; $group$->$group_num$ = num; $group$->$group_num$_isSet = true; $group$->to_flush = 1; return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_has_$group_num$ (trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; $group$_mem_t* $group$ = trexio_memory_read_$group$((trexio_memory_t*) file); if ($group$ == NULL) return TREXIO_FAILURE; if ($group$->$group_num$_isSet == true){ return TREXIO_SUCCESS; } else { return TREXIO_HAS_NOT; } }
11. Template for has/read/write a dataset of numerical data
trexio_exit_code trexio_memory_read_$group_dset$ (trexio_t* const file, $group_dset_dtype$* const $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 (rank < 1) return TREXIO_INVALID_ARG_3; if (dims == NULL) return TREXIO_INVALID_ARG_4; $group$_mem_t* const $group$ = trexio_memory_read_$group$((trexio_memory_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 (uint32_t 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; }
trexio_exit_code trexio_memory_write_$group_dset$ (trexio_t* const 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 (rank < 1) return TREXIO_INVALID_ARG_3; if (dims == NULL) return TREXIO_INVALID_ARG_4; if (file->mode == 'r') return TREXIO_READONLY; $group$_mem_t* const $group$ = trexio_memory_read_$group$((trexio_memory_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 (uint32_t i=0; i<$group$->rank_$group_dset$; ++i){ $group$->dims_$group_dset$[i] = dims[i]; dim_size *= dims[i]; } $group$->$group_dset$ = CALLOC(dim_size, $group_dset_dtype$); if ($group$->$group_dset$ == NULL) return TREXIO_ALLOCATION_FAILED; for (uint64_t i=0 ; i<dim_size ; ++i) { $group$->$group_dset$[i] = $group_dset$[i]; } $group$->to_flush = 1; return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_has_$group_dset$ (trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; $group$_mem_t* const $group$ = trexio_memory_read_$group$((trexio_memory_t*) file); if ($group$ == NULL) return TREXIO_FAILURE; if ($group$->rank_$group_dset$ > 0){ return TREXIO_SUCCESS; } else { return TREXIO_HAS_NOT; } }
12. Template for has/read/write a dataset of strings
trexio_exit_code trexio_memory_read_$group_dset$ (trexio_t* const file, char* const dset, const uint32_t rank, const uint64_t* dims, const uint32_t max_str_len) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (dset == NULL) return TREXIO_INVALID_ARG_2; $group$_mem_t* const $group$ = trexio_memory_read_$group$((trexio_memory_t*) file); if ($group$ == NULL) return TREXIO_FAILURE; if (rank != $group$->rank_$group_dset$) return TREXIO_INVALID_ARG_3; for (uint32_t i=0 ; i<rank ; ++i) { if (dims[i] != $group$->dims_$group_dset$[i]) return TREXIO_INVALID_ARG_4; } strcpy(dset, ""); for (uint64_t i=0 ; i<dims[0] ; ++i) { strncat(dset, $group$->$group_dset$[i], max_str_len); strcat(dset, TREXIO_DELIM); } return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_write_$group_dset$ (trexio_t* const file, const char** dset, const uint32_t rank, const uint64_t* dims) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (dset == NULL) return TREXIO_INVALID_ARG_2; if (file->mode == 'r') return TREXIO_READONLY; $group$_mem_t* const $group$ = trexio_memory_read_$group$((trexio_memory_t*) file); if ($group$ == NULL) return TREXIO_FAILURE; if ($group$->$group_dset$ != NULL) { if ($group$->rank_$group_dset$ != 0) FREE($group$->$group_dset$[0]); FREE($group$->$group_dset$); } $group$->rank_$group_dset$ = rank; for (uint32_t i=0; i<$group$->rank_$group_dset$; ++i){ $group$->dims_$group_dset$[i] = dims[i]; } $group$->$group_dset$ = CALLOC(dims[0], char*); if ($group$->$group_dset$ == NULL) return TREXIO_ALLOCATION_FAILED; /* Compute the exact amount of memory needed to store all the strings * contiguously instead of assuming an arbitrary maximum string length, * which would silently truncate or overflow longer strings. */ size_t tmp_str_size = 0; for (uint64_t i=0 ; i<dims[0] ; ++i) { tmp_str_size += strlen(dset[i]) + 2; } char* tmp_str = CALLOC(tmp_str_size, char); if (tmp_str == NULL) return TREXIO_ALLOCATION_FAILED; for (uint64_t i=0 ; i<dims[0] ; ++i) { size_t tmp_len = strlen(dset[i])+1; $group$->$group_dset$[i] = tmp_str; strncpy(tmp_str, dset[i], tmp_len); tmp_str[tmp_len-1] = '\0'; tmp_str += tmp_len + 1; } $group$->to_flush = 1; return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_has_$group_dset$ (trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; $group$_mem_t* const $group$ = trexio_memory_read_$group$((trexio_memory_t*) file); if ($group$ == NULL) return TREXIO_FAILURE; if ($group$->rank_$group_dset$ > 0){ return TREXIO_SUCCESS; } else { return TREXIO_HAS_NOT; } }
13. Template for has/read/write a string attribute
trexio_exit_code trexio_memory_read_$group_str$ (trexio_t* const file, char* const str, const uint32_t max_str_len) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (str == NULL) return TREXIO_INVALID_ARG_2; $group$_mem_t* const $group$ = trexio_memory_read_$group$((trexio_memory_t*) file); if ($group$ == NULL) return TREXIO_FAILURE; strncpy(str, $group$->$group_str$, max_str_len); str[max_str_len-1] = '\0'; return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_write_$group_str$ (trexio_t* const file, const char *str) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (str == NULL) return TREXIO_INVALID_ARG_2; if (file->mode == 'r') return TREXIO_READONLY; $group$_mem_t* const $group$ = trexio_memory_read_$group$((trexio_memory_t*) file); if ($group$ == NULL) return TREXIO_FAILURE; if ($group$->$group_str$ != NULL) FREE($group$->$group_str$); size_t tmp_len = strlen(str); $group$->$group_str$ = CALLOC(tmp_len + 1, char); if ($group$->$group_str$ == NULL) return TREXIO_ALLOCATION_FAILED; $group$->len_$group_str$ = tmp_len + 1; strncpy($group$->$group_str$, str, tmp_len + 1); $group$->$group_str$[tmp_len] = '\0'; $group$->to_flush = 1; return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_has_$group_str$ (trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; $group$_mem_t* const $group$ = trexio_memory_read_$group$((trexio_memory_t*) file); if ($group$ == NULL) return TREXIO_FAILURE; if ($group$->len_$group_str$ > 0){ return TREXIO_SUCCESS; } else { return TREXIO_HAS_NOT; } }
14. Template for memory delete a group (UNSAFE mode)
trexio_exit_code trexio_memory_delete_$group$ (trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; trexio_memory_t* f = (trexio_memory_t*) file; /* Dropping the in-memory struct deletes the group. */ trexio_exit_code rc_free = trexio_memory_free_$group$(f); if (rc_free != TREXIO_SUCCESS) return rc_free; return TREXIO_SUCCESS; }
15. Template for has/read/write the dataset of sparse data
Sparse data (e.g. two-electron integrals, Cholesky vectors, 2-RDMs) is held in a name-keyed in-RAM blob of growable index/value arrays. Writing appends; reading returns chunks from a given item offset.
trexio_exit_code trexio_memory_write_$group_dset$(trexio_t* const file, const int64_t offset_file, const int64_t size, const int64_t size_max, const int64_t size_start, const int32_t* index_sparse, const double* value_sparse) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (file->mode == 'r') return TREXIO_READONLY; (void) offset_file; (void) size_max; (void) size_start; trexio_mem_blob_t* b = trexio_mem_blob_get((trexio_memory_t*) file, "$group_dset$", $group_dset_rank$); if (b == NULL) return TREXIO_ALLOCATION_FAILED; return trexio_mem_blob_append_sparse(b, size, index_sparse, value_sparse); }
trexio_exit_code trexio_memory_read_$group_dset$(trexio_t* const file, const int64_t offset_file, const int64_t size, const int64_t size_max, int64_t* const eof_read_size, int32_t* const index_sparse, double* const value_sparse) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (eof_read_size == NULL) return TREXIO_INVALID_ARG_5; (void) size_max; trexio_mem_blob_t* b = trexio_mem_blob_find((trexio_memory_t*) file, "$group_dset$"); return trexio_mem_blob_read_sparse(b, offset_file, size, index_sparse, value_sparse, eof_read_size); } trexio_exit_code trexio_memory_read_$group_dset$_size(trexio_t* const file, int64_t* const size_max) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (size_max == NULL) return TREXIO_INVALID_ARG_2; trexio_mem_blob_t* b = trexio_mem_blob_find((trexio_memory_t*) file, "$group_dset$"); *size_max = (b == NULL) ? 0L : b->n_items; return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_has_$group_dset$(trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; trexio_mem_blob_t* b = trexio_mem_blob_find((trexio_memory_t*) file, "$group_dset$"); return (b != NULL && b->n_items > 0) ? TREXIO_SUCCESS : TREXIO_HAS_NOT; }
16. Template for has/read/write a buffered vector
Buffered vectors (e.g. CI/CSF coefficients) are held in a name-keyed in-RAM blob of growable values. Writing appends; reading returns a chunk.
trexio_exit_code trexio_memory_write_$group_dset$(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, const double* dset) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (offset_file < 0) return TREXIO_INVALID_ARG_2; if (rank < 1) return TREXIO_INVALID_ARG_3; if (dims == NULL) return TREXIO_INVALID_ARG_4; if (dset == NULL) return TREXIO_INVALID_ARG_5; if (file->mode == 'r') return TREXIO_READONLY; (void) offset_file; trexio_mem_blob_t* b = trexio_mem_blob_get((trexio_memory_t*) file, "$group_dset$", 1); if (b == NULL) return TREXIO_ALLOCATION_FAILED; return trexio_mem_blob_append_value(b, (int64_t) dims[0], dset); }
trexio_exit_code trexio_memory_read_$group_dset$(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, int64_t* const eof_read_size, double* const dset) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (offset_file < 0) return TREXIO_INVALID_ARG_2; if (rank < 1) return TREXIO_INVALID_ARG_3; if (dims == NULL) return TREXIO_INVALID_ARG_4; if (eof_read_size == NULL) return TREXIO_INVALID_ARG_5; if (dset == NULL) return TREXIO_INVALID_ARG_6; trexio_mem_blob_t* b = trexio_mem_blob_find((trexio_memory_t*) file, "$group_dset$"); return trexio_mem_blob_read_value(b, offset_file, (int64_t) dims[0], dset, eof_read_size); } trexio_exit_code trexio_memory_read_$group_dset$_size(trexio_t* const file, int64_t* const size_max) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (size_max == NULL) return TREXIO_INVALID_ARG_2; trexio_mem_blob_t* b = trexio_mem_blob_find((trexio_memory_t*) file, "$group_dset$"); *size_max = (b == NULL) ? 0L : b->n_items; return TREXIO_SUCCESS; }
trexio_exit_code trexio_memory_has_$group_dset$(trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; trexio_mem_blob_t* b = trexio_mem_blob_find((trexio_memory_t*) file, "$group_dset$"); return (b != NULL && b->n_items > 0) ? TREXIO_SUCCESS : TREXIO_HAS_NOT; }
17. Source code for the determinant part
The determinant list (bit-field occupation strings) is stored in a single name-keyed in-RAM blob of int64 values; the coefficients use the buffered mechanism above. These functions are constant (not templated).
trexio_exit_code trexio_memory_write_determinant_list(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, const int64_t* list) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (offset_file < 0) return TREXIO_INVALID_ARG_2; if (rank != 2) return TREXIO_INVALID_ARG_3; if (dims == NULL) return TREXIO_INVALID_ARG_4; if (list == NULL) return TREXIO_INVALID_ARG_5; if (file->mode == 'r') return TREXIO_READONLY; (void) offset_file; trexio_mem_blob_t* b = trexio_mem_blob_get((trexio_memory_t*) file, "determinant_list", (int32_t) dims[1]); if (b == NULL) return TREXIO_ALLOCATION_FAILED; return trexio_mem_blob_append_list(b, (int64_t) dims[0], list); }
trexio_exit_code trexio_memory_read_determinant_list(trexio_t* const file, const int64_t offset_file, const uint32_t rank, const uint64_t* dims, int64_t* const eof_read_size, int64_t* const list) { if (file == NULL) return TREXIO_INVALID_ARG_1; if (offset_file < 0) return TREXIO_INVALID_ARG_2; if (rank != 2) return TREXIO_INVALID_ARG_3; if (dims == NULL) return TREXIO_INVALID_ARG_4; if (eof_read_size == NULL) return TREXIO_INVALID_ARG_5; if (list == NULL) return TREXIO_INVALID_ARG_6; trexio_mem_blob_t* b = trexio_mem_blob_find((trexio_memory_t*) file, "determinant_list"); return trexio_mem_blob_read_list(b, offset_file, (int64_t) dims[0], list, eof_read_size); }
trexio_exit_code trexio_memory_has_determinant_list(trexio_t* const file) { if (file == NULL) return TREXIO_INVALID_ARG_1; trexio_mem_blob_t* b = trexio_mem_blob_find((trexio_memory_t*) file, "determinant_list"); return (b != NULL && b->n_items > 0) ? TREXIO_SUCCESS : TREXIO_HAS_NOT; }