From df1055f668868482c1ac3590908343ddc6c8d546 Mon Sep 17 00:00:00 2001 From: Benjamin Brock Date: Thu, 26 Sep 2024 15:43:17 -0700 Subject: [PATCH 1/2] Implement `allocator` --- include/binsparse/array.h | 18 ++++++++---------- include/binsparse/detail/allocator.h | 11 +++++++++++ include/binsparse/detail/shm_tools.h | 18 ++++++++++++++++++ include/binsparse/hdf5_wrapper.h | 27 +++++++++++++++++++++++---- include/binsparse/read_matrix.h | 4 ++++ 5 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 include/binsparse/detail/allocator.h diff --git a/include/binsparse/array.h b/include/binsparse/array.h index 6919f74..dd7a4ef 100644 --- a/include/binsparse/array.h +++ b/include/binsparse/array.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -10,15 +11,14 @@ typedef struct bsp_array_t { void* data; size_t size; bsp_type_t type; - bool shmat_memory; - bsp_shm_t shm; + bsp_allocator_t allocator; } bsp_array_t; bsp_array_t bsp_construct_default_array_t() { bsp_array_t array; array.data = NULL; array.size = 0; - array.shmat_memory = false; + array.allocator = bsp_default_allocator; return array; } @@ -26,11 +26,11 @@ bsp_array_t bsp_construct_array_t(size_t size, bsp_type_t type) { size_t byte_size = size * bsp_type_size(type); bsp_array_t array; - array.data = malloc(byte_size); + array.allocator = bsp_default_allocator; + array.data = array.allocator.malloc(byte_size); assert(array.data != NULL); array.size = size; array.type = type; - array.shmat_memory = false; return array; } @@ -49,6 +49,7 @@ bsp_array_t bsp_complex_array_to_fp(bsp_array_t other) { bsp_array_t array; array.data = other.data; array.size = other.size * 2; + array.allocator = other.allocator; if (other.type == BSP_COMPLEX_FLOAT32) { array.type = BSP_FLOAT32; @@ -65,6 +66,7 @@ bsp_array_t bsp_fp_array_to_complex(bsp_array_t other) { bsp_array_t array; array.data = other.data; array.size = other.size / 2; + array.allocator = other.allocator; if (other.type == BSP_FLOAT32) { array.type = BSP_COMPLEX_FLOAT32; @@ -76,11 +78,7 @@ bsp_array_t bsp_fp_array_to_complex(bsp_array_t other) { } void bsp_destroy_array_t(bsp_array_t array) { - if (array.shmat_memory == false) { - free(array.data); - } else { - bsp_shm_detach(array.data); - } + array.allocator.free(array.data); } bool bsp_array_equal(bsp_array_t x, bsp_array_t y) { diff --git a/include/binsparse/detail/allocator.h b/include/binsparse/detail/allocator.h new file mode 100644 index 0000000..8a1ee6d --- /dev/null +++ b/include/binsparse/detail/allocator.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +typedef struct bsp_allocator_t { + void* (*malloc)(size_t); + void (*free)(void*); +} bsp_allocator_t; + +const static bsp_allocator_t bsp_default_allocator = {.malloc = malloc, + .free = free}; diff --git a/include/binsparse/detail/shm_tools.h b/include/binsparse/detail/shm_tools.h index 65e6b90..497fd4c 100644 --- a/include/binsparse/detail/shm_tools.h +++ b/include/binsparse/detail/shm_tools.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -42,3 +43,20 @@ void* bsp_shm_attach(bsp_shm_t shm) { void bsp_shm_detach(void* data) { shmdt(data); } + +void* bsp_shm_malloc(size_t size) { + bsp_shm_t shm_id = bsp_shm_new(size); + + void* ptr = bsp_shm_attach(shm_id); + + bsp_shm_delete(shm_id); + + return ptr; +} + +void bsp_shm_free(void* ptr) { + bsp_shm_detach(ptr); +} + +const static bsp_allocator_t bsp_shm_allocator = {.malloc = bsp_shm_malloc, + .free = bsp_shm_free}; diff --git a/include/binsparse/hdf5_wrapper.h b/include/binsparse/hdf5_wrapper.h index 89e84e9..708e750 100644 --- a/include/binsparse/hdf5_wrapper.h +++ b/include/binsparse/hdf5_wrapper.h @@ -9,6 +9,10 @@ #include +#if __STDC_VERSION__ >= 201112L +#include +#endif + // Write an array to a dataset / file // Returns 0 on success, nonzero on error. int bsp_write_array(hid_t f, const char* label, bsp_array_t array, @@ -65,6 +69,7 @@ int bsp_write_array(hid_t f, const char* label, bsp_array_t array, return 0; } +#if __STDC_VERSION__ >= 201112L bsp_array_t bsp_read_array_parallel(hid_t f, const char* label, int num_threads) { hid_t dset = H5Dopen2(f, label, H5P_DEFAULT); @@ -91,12 +96,19 @@ bsp_array_t bsp_read_array_parallel(hid_t f, const char* label, bsp_type_t type = bsp_get_bsp_type(hdf5_type); + // Array will be written into a POSIX shared memory. bsp_shm_t array_shm = bsp_shm_new(dims[0] * bsp_type_size(type)); bsp_array_t array; array.type = type; array.size = dims[0]; - array.shm = array_shm; - array.shmat_memory = true; + array.allocator = bsp_shm_allocator; + + bsp_shm_t active_children_shm = bsp_shm_new(sizeof(_Atomic int)); + + _Atomic int* active_children = bsp_shm_attach(active_children_shm); + bsp_shm_delete(active_children_shm); + + *active_children = num_threads - 1; pid_t* pids = (pid_t*) malloc(sizeof(pid_t) * num_threads); @@ -115,7 +127,7 @@ bsp_array_t bsp_read_array_parallel(hid_t f, const char* label, array.data = bsp_shm_attach(array_shm); if (thread_num == 0) { - bsp_shm_delete(array.shm); + bsp_shm_delete(array_shm); } hsize_t chunk_size = (array.size + num_threads - 1) / num_threads; @@ -131,7 +143,7 @@ bsp_array_t bsp_read_array_parallel(hid_t f, const char* label, hid_t memspace_id = H5Screate_simple(1, &count, NULL); H5Dread(dset, bsp_get_hdf5_native_type(type), memspace_id, fspace, - H5P_DEFAULT, array.data + start * bsp_type_size(type)); + H5P_DEFAULT, ((char*) array.data) + start * bsp_type_size(type)); H5Sclose(memspace_id); } @@ -139,14 +151,21 @@ bsp_array_t bsp_read_array_parallel(hid_t f, const char* label, H5Sclose(fspace); if (thread_num > 0) { + atomic_fetch_add_explicit(active_children, -1, memory_order_relaxed); + bsp_shm_detach(active_children); bsp_shm_detach(array.data); exit(0); } free(pids); + while (atomic_load(active_children) > 0) { + } + bsp_shm_detach(active_children); + return array; } +#endif bsp_array_t bsp_read_array(hid_t f, const char* label) { hid_t dset = H5Dopen2(f, label, H5P_DEFAULT); diff --git a/include/binsparse/read_matrix.h b/include/binsparse/read_matrix.h index 4664be0..262187c 100644 --- a/include/binsparse/read_matrix.h +++ b/include/binsparse/read_matrix.h @@ -4,6 +4,7 @@ #include #include +#if __STDC_VERSION__ >= 201112L bsp_matrix_t bsp_read_matrix_from_group_parallel(hid_t f, int num_threads) { bsp_matrix_t matrix = bsp_construct_default_matrix_t(); @@ -107,6 +108,7 @@ bsp_matrix_t bsp_read_matrix_from_group_parallel(hid_t f, int num_threads) { return matrix; } +#endif bsp_matrix_t bsp_read_matrix_from_group(hid_t f) { bsp_matrix_t matrix = bsp_construct_default_matrix_t(); @@ -219,6 +221,7 @@ size_t bsp_final_dot(const char* str) { return dot_idx; } +#if __STDC_VERSION__ >= 201112L bsp_matrix_t bsp_read_matrix_parallel(const char* file_name, const char* group, int num_threads) { if (group == NULL) { @@ -243,6 +246,7 @@ bsp_matrix_t bsp_read_matrix_parallel(const char* file_name, const char* group, return matrix; } } +#endif bsp_matrix_t bsp_read_matrix(const char* file_name, const char* group) { if (group == NULL) { From 63d974d53da9558df38e9d271eb046ed83231f39 Mon Sep 17 00:00:00 2001 From: Benjamin Brock Date: Thu, 26 Sep 2024 16:55:51 -0700 Subject: [PATCH 2/2] Add SPDX to new file. --- include/binsparse/detail/allocator.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/binsparse/detail/allocator.h b/include/binsparse/detail/allocator.h index 8a1ee6d..86d817a 100644 --- a/include/binsparse/detail/allocator.h +++ b/include/binsparse/detail/allocator.h @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2024 Binsparse Developers + * + * SPDX-License-Identifier: BSD-3-Clause + */ + #pragma once #include