atrstm

Load and structure a combustion gas mixture
git clone git://git.meso-star.fr/atrstm.git
Log | Files | Refs | README | LICENSE

commit 53552af739157da351f96a3a8eb1b4d2688cc90e
parent 069779bdcec8d9f59b8225db3e7a26ca20c6b0e4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri,  8 Jan 2021 15:20:07 +0100

Implement partition and pool internal data structures

These data structures are going to be used in the parallel construction
of the octree partitionning volumetric optical properties.

Diffstat:
Mcmake/CMakeLists.txt | 4+++-
Msrc/atrstm.h | 24++++++++++++++++++++++--
Asrc/atrstm_partition.c | 175+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/atrstm_partition.h | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/atrstm_svx.h | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 368 insertions(+), 3 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -51,10 +51,12 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(ATRSTM_FILES_SRC atrstm.c atrstm_log.c + atrstm_partition.c atrstm_setup_uvm.c) set(ATRSTM_FILES_INC atrstm_c.h - atrstm_log.h) + atrstm_log.h + atrstm_partition.h) set(ATRSTM_FILES_INC_API atrstm.h) diff --git a/src/atrstm.h b/src/atrstm.h @@ -38,6 +38,26 @@ #define ATRSTM(Func) atrstm_ ## Func #endif +enum atrstm_property { + ATRSTM_Ks, /* Scattering coefficient */ + ATRSTM_Ka, /* Absorption coefficient */ + ATRSTM_Kext, /* Extinction coefficient = Ks + Ka */ + ATRSTM_PROPS_COUNT__ +}; + +/* List of medium components */ +enum atrstm_component { + ATRSTM_CPNT_GAS, + ATRSTM_CPNT_SOOT, + ATRSTM_CPNTS_COUNT__ +}; + +enum atrstm_svx_op { + ATRSTM_SVX_MIN, + ATRSTM_SVX_MAX, + ATRSTM_SVX_OPS_COUNT__ +}; + enum atrstm_spectral_type { ATRSTM_SPECTRAL_LW, /* Longwave */ ATRSTM_SPECTRAL_SW, /* Shortwave */ @@ -54,7 +74,7 @@ struct atrstm_args { double wlen_range[2]; /* Spectral range to handle In nm */ unsigned grid_max_definition[3]; /* Maximum definition of the grid */ double optical_thickness; /* Threshold used during octree building */ - int precompute_normals; /* Pre-compute the Tetrahedron normals */ + int precompute_normals; /* Pre-compute the tetrahedra normals */ unsigned nthreads; /* Hint on the number of threads to use */ int verbose; /* Verbosity level */ }; @@ -69,7 +89,7 @@ struct atrstm_args { {DBL_MAX,-DBL_MAX}, /* Spectral integration range */ \ {UINT_MAX, UINT_MAX, UINT_MAX}, /* Acceleration grid max definition */ \ 1, /* Optical thickness */ \ - 1, /* Precompute tetrahedron normals */ \ + 1, /* Precompute tetrahedra normals */ \ (unsigned)~0, /* #threads */ \ 0 /* Verbosity level */ \ } diff --git a/src/atrstm_partition.c b/src/atrstm_partition.c @@ -0,0 +1,175 @@ +/* Copyright (C) 2020 CNRS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "atrstm_partition.h" + +#include <rsys/condition.h> +#include <rsys/mem_allocator.h> +#include <rsys/mutex.h> + +#include <string.h> + +/****************************************************************************** + * Local functions + ******************************************************************************/ +res_T +pool_init(struct mem_allocator* mem_allocator, struct pool* pool) +{ + STATIC_ASSERT(POOL_MAX_NPARTITIONS > 0, + Unexpected_value_of_POOL_MAX_NPARTITIONS); + size_t ipart; + res_T res = RES_OK; + ASSERT(pool); + + memset(pool, 0, sizeof(*pool)); + + list_init(&pool->parts_free); + list_init(&pool->parts_full); + pool->allocator = mem_allocator ? mem_allocator : &mem_default_allocator; + + pool->mutex = mutex_create(); + if(!pool->mutex) { res = RES_UNKNOWN_ERR; goto error; } + pool->cond_new = cond_create(); + if(pool->cond_new) { res = RES_UNKNOWN_ERR; goto error; } + pool->cond_fetch = cond_create(); + if(pool->cond_fetch) { res = RES_UNKNOWN_ERR; goto error; } + + FOR_EACH(ipart, 0, POOL_MAX_NPARTITIONS) { + struct part* part = MEM_ALLOC_ALIGNED(pool->allocator, sizeof(*part), 64); + if(!part) { + res = RES_MEM_ERR; + goto error; + } + list_add(&pool->parts_free, &part->node); + } + +exit: + pool_release(pool); + return res; +error: + goto exit; +} + +void +pool_release(struct pool* pool) +{ + struct list_node* node; + struct list_node* tmp_node; + ASSERT(pool); + + if(pool->mutex) mutex_destroy(pool->mutex); + if(pool->cond_new) cond_destroy(pool->cond_new); + if(pool->cond_fetch) cond_destroy(pool->cond_fetch); + + LIST_FOR_EACH_SAFE(node, tmp_node, &pool->parts_free) { + struct part* part = CONTAINER_OF(node, struct part, node); + list_del(node); + MEM_RM(pool->allocator, part); + } + + LIST_FOR_EACH_SAFE(node, tmp_node, &pool->parts_full) { + struct part* part = CONTAINER_OF(node, struct part, node); + list_del(node); + MEM_RM(pool->allocator, part); + } + + ASSERT(is_list_empty(&pool->parts_free)); + ASSERT(is_list_empty(&pool->parts_full)); + + memset(pool, 0, sizeof(*pool)); +} + +struct part* +pool_new_partition(struct pool* pool) +{ + struct list_node* node = NULL; + struct part* part = NULL; + ASSERT(pool); + + mutex_lock(pool->mutex); + if(is_list_empty(&pool->parts_free)) { + cond_wait(pool->cond_new, pool->mutex); + } + node = list_head(&pool->parts_free); + list_del(node); + mutex_unlock(pool->mutex); + + part = CONTAINER_OF(node, struct part, node); + return part; +} + +void +pool_free_partition(struct pool* pool, struct part* part) +{ + ASSERT(pool && part && is_list_empty(&part->node)); + + mutex_lock(pool->mutex); + list_add_tail(&pool->parts_free, &part->node); + mutex_unlock(pool->mutex); + + cond_signal(pool->cond_new); +} + +void +pool_commit_partition(struct pool* pool, struct part* part) +{ + struct list_node* node = NULL; + ASSERT(pool && part); + + mutex_lock(pool->mutex); + LIST_FOR_EACH_REVERSE(node, &pool->parts_full) { + struct part* part2 = CONTAINER_OF(node, struct part, node); + if(part2->id <= part->id) break; + } + list_add(node, &part->node); + mutex_unlock(pool->mutex); + + cond_signal(pool->cond_fetch); +} + +struct part* +pool_fetch_partition(struct pool* pool, size_t part_id) +{ + struct part* found_part = NULL; + struct list_node* node = NULL; + ASSERT(pool); + + mutex_lock(pool->mutex); + for(;;) { + /* Search for a partition that match the submitted id */ + LIST_FOR_EACH(node, &pool->parts_full) { + struct part* part = CONTAINER_OF(node, struct part, node); + + if(part->id == part_id) { + found_part = part; + break; + } + + /* Partitions are sorted in ascending order. Stop the linear search if the + * current id is greater than the submitted one */ + if(part->id > part_id) break; + } + if(!found_part) { + cond_wait(pool->cond_fetch, pool->mutex); + } else { + list_del(&found_part->node); + break; + } + } + mutex_unlock(pool->mutex); + + return found_part; +} + diff --git a/src/atrstm_partition.h b/src/atrstm_partition.h @@ -0,0 +1,91 @@ +/* Copyright (C) 2020 CNRS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef ATRSTM_PARTITION_H +#define ATRSTM_PARTITION_H + +#include "atrstm_svx.h" +#include <rsys/list.h> + +/* Definition of a partition along the 4 axis */ +#define PARTITION_DEFINITION 32 + +/* Max #partitions stored into the partition pool */ +#define POOL_MAX_NPARTITIONS 16 + +/* Forward declarations */ +struct cond; +struct mem_allocator; +struct mutex; + +struct part { + /* Morton ordered list of voxels */ + float voxels + [ PARTITION_DEFINITION + * PARTITION_DEFINITION + * PARTITION_DEFINITION + * NFLOATS_PER_VOXEL]; + struct list_node node; + size_t id; /* Unique identifier of the partition */ +}; + +struct pool { + /* Linked list of pre-allocated partitions */ + struct list_node parts_free; + + /* List of available partition sorted in ascending order wrt partition id */ + struct list_node parts_full; + + struct mutex* mutex; + struct cond* cond_new; + struct cond* cond_fetch; + + struct mem_allocator* allocator; +}; + +extern LOCAL_SYM res_T +pool_init + (struct mem_allocator* allocator, /* May be NULL <=> default allocator */ + struct pool* pool); + +extern LOCAL_SYM void +pool_release + (struct pool* pool); + +/* Return a free partition. Wait until a free partition is available */ +extern LOCAL_SYM struct part* +pool_new_partition + (struct pool* pool); + +/* Register the partition as a free partition against the pool */ +extern LOCAL_SYM void +pool_free_partition + (struct pool* pool, + struct part* part); + +/* Register the partition as a valid partition that can be fetched */ +extern LOCAL_SYM void +pool_commit_partition + (struct pool* pool, + struct part* part); + +/* Return the partition whose id is `part_id`. Wait until the expected + * partition is available */ +extern LOCAL_SYM struct part* +pool_fetch_partition + (struct pool* pool, + const size_t part_id); + +#endif /* ATRSTM_PARTITION_H */ diff --git a/src/atrstm_svx.h b/src/atrstm_svx.h @@ -0,0 +1,77 @@ +/* Copyright (C) 2020 CNRS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef ATRSTM_SVX_H +#define ATRSTM_SVX_H + +#include "atrstm.h" + +/* SVX Memory layout + * ----------------- + * + * For each SVX voxel, the data of the optical property are stored + * linearly as N single precision floating point data, with N computed as + * bellow: + * + * N = ATRSTM_PROPS_COUNT__ #optical properties per voxel + * * ATRSTM_SVX_OPS_COUNT__ #supported operations on each properties + * * ATRSTM_CPNTS_COUNT__; #components on which properties are defined + * + * In a given voxel, the index `id' in [0, N-1] corresponding to the optical + * property `enum atrstm_property P' of the component `enum atrstm_component + * C' according to the operation `enum atrstm_svx_op O' is + * then computed as bellow: + * + * id = C * NFLOATS_PER_CPNT + P * HTSKY_SVX_OPS_COUNT__ + O; + * NFLOATS_PER_CPNT = ATRSTM_SVX_OPS_COUNT__ * ATRSTM_PROPS_COUNT__; + */ + +/* Constant defining the number of floating point data per component */ +#define NFLOATS_PER_CPNT (ATRSTM_SVX_OPS_COUNT__ * ATRSTM_PROPS_COUNT__) + +/* Constant defining the overall number of floating point data of a voxel */ +#define NFLOATS_PER_VOXEL (NFLOATS_PER_CPNT * ATRSTM_CPNTS_COUNT__) + +static FINLINE float +vox_get + (const float* data, + const enum atrstm_component cpnt, + const enum atrstm_property prop, + const enum atrstm_svx_op op) +{ + ASSERT(data); + ASSERT((unsigned)cpnt < ATRSTM_CPNTS_COUNT__); + ASSERT((unsigned)prop < ATRSTM_PROPS_COUNT__); + ASSERT((unsigned)op < ATRSTM_SVX_OPS_COUNT__); + return data[cpnt*NFLOATS_PER_CPNT + prop*ATRSTM_SVX_OPS_COUNT__ + op]; +} + +static FINLINE void +vox_set + (float* data, + const enum atrstm_component cpnt, + const enum atrstm_property prop, + const enum atrstm_svx_op op, + const float val) +{ + ASSERT(data); + ASSERT((unsigned)cpnt < ATRSTM_CPNTS_COUNT__); + ASSERT((unsigned)prop < ATRSTM_PROPS_COUNT__); + ASSERT((unsigned)op < ATRSTM_SVX_OPS_COUNT__); + data[cpnt*NFLOATS_PER_CPNT + prop*ATRSTM_SVX_OPS_COUNT__ + op] = val; +} + +#endif /* ATRSTM_SVX_H */ +