atrstm

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

commit d5dc1afde8e99ca425cd9dd0dc6ee8f608ea27f5
parent 322d3145e26a1b71579cba02f8c0f35e636095df
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 20 Jan 2021 17:23:14 +0100

Upd how volumetric mesh voxelization is parallelised

Share one pool of voxels partition between all threads.

Diffstat:
Msrc/atrstm_setup_octrees.c | 81++++++++++++++++++++++++++++++-------------------------------------------------
Msrc/atrstm_setup_uvm.c | 2+-
2 files changed, 32 insertions(+), 51 deletions(-)

diff --git a/src/atrstm_setup_octrees.c b/src/atrstm_setup_octrees.c @@ -38,7 +38,7 @@ struct build_octree_context { struct atrstm* atrstm; - struct pool* pools; /* Per thread pool of voxel partitions */ + struct pool* pool; /* Pool of voxel partitions */ /* Optical thickness threshold criteria for the merge process */ double tau_threshold; @@ -254,7 +254,7 @@ static res_T voxelize_volumetric_mesh (struct atrstm* atrstm, const struct atrri_refractive_index* refract_id, - struct pool* pools) + struct pool* pool) { struct darray_prims_list prims_list; /* Per thread list of primitives */ const size_t part_def = PARTITION_DEFINITION; @@ -263,11 +263,12 @@ voxelize_volumetric_mesh double vol_low[3]; double vol_upp[3]; double vxsz[3]; - uint64_t ipart; + int64_t i; int progress = 0; + ATOMIC part_mcode = -1; ATOMIC nparts_voxelized = 0; ATOMIC res = RES_OK; - ASSERT(atrstm && pools); + ASSERT(atrstm && pool); darray_prims_list_init(atrstm->allocator, &prims_list); @@ -298,9 +299,8 @@ voxelize_volumetric_mesh * the primitives that intersect it */ omp_set_num_threads((int)atrstm->nthreads); #pragma omp parallel for schedule(static, 1/*chunk size*/) - for(ipart = 0; ipart < nparts_adjusted; ++ipart) { + for(i = 0; i < (int64_t)nparts_adjusted; ++i) { struct darray_size_t* prims = NULL; - struct pool* pool = NULL; double part_low[3]; double part_upp[3]; uint32_t part_ids[3]; @@ -308,6 +308,7 @@ voxelize_volumetric_mesh struct part* part = NULL; int pcent; size_t n; + uint64_t ipart; res_T res_local = RES_OK; /* Handle error */ @@ -316,8 +317,8 @@ voxelize_volumetric_mesh /* Fetch the per thread list of primitives and partition pool */ prims = darray_prims_list_data_get(&prims_list)+ithread; darray_size_t_clear(prims); - pool = pools + ithread; + ipart = (uint64_t)ATOMIC_INCR(&part_mcode); morton_xyz_decode_u21(ipart, part_ids); /* Check that the partition is not out of bound due to Morton indexing */ @@ -354,6 +355,7 @@ voxelize_volumetric_mesh ATOMIC_SET(&res, res_local); continue; } + pool_commit_partition(pool, part); /* Update progress message */ @@ -381,10 +383,9 @@ static void voxel_get(const size_t xyz[3], const uint64_t mcode, void* dst, void* context) { const struct build_octree_context* ctx = context; - struct pool* pool = NULL; struct part* part = NULL; float* vox = NULL; - uint64_t ivox, ipart, ipool; + uint64_t ivox, ipart; ASSERT(xyz && dst && ctx); (void)xyz; @@ -395,16 +396,8 @@ voxel_get(const size_t xyz[3], const uint64_t mcode, void* dst, void* context) ipart = (mcode >> (LOG2_PARTITION_DEFINITION*3)); ivox = (mcode & (BIT_U64(LOG2_PARTITION_DEFINITION*3)-1)); - /* Compute the pool index containing the partition. Partitions are - * alternatively stored into the per thread pool. Consequentlu the i^th - * partition is stored in the (i % #thread)^th pool. */ - ipool = ipart % ctx->atrstm->nthreads; - - /* Fetch the pool storing the partition */ - pool = ctx->pools + ipool; - /* Fetch the partition storing the voxel */ - part = pool_fetch_partition(pool, ipart); + part = pool_fetch_partition(ctx->pool, ipart); if(!part) { /* An error occurs */ memset(dst, 0, NFLOATS_PER_VOXEL * sizeof(float)); @@ -416,7 +409,7 @@ voxel_get(const size_t xyz[3], const uint64_t mcode, void* dst, void* context) /* Free the partition if the fetch voxel was its last one */ if(ivox == PARTITION_NVOXELS - 1) { - pool_free_partition(pool, part); + pool_free_partition(ctx->pool, part); } } } @@ -537,7 +530,7 @@ voxels_challenge_merge static res_T build_octree (struct atrstm* atrstm, - struct pool* pools) + struct pool* pool) { struct svx_voxel_desc vox_desc = SVX_VOXEL_DESC_NULL; struct build_octree_context ctx = BUILD_OCTREE_CONTEXT_NULL; @@ -545,11 +538,11 @@ build_octree double upper[3]; size_t definition[3]; res_T res = RES_OK; - ASSERT(atrstm && pools); + ASSERT(atrstm && pool); /* Setup the build octree context */ ctx.atrstm = atrstm; - ctx.pools = pools; + ctx.pool = pool; ctx.tau_threshold = atrstm->optical_thickness; /* Setup the voxel descriptor. TODO in shortwave, the NFLOATS_PER_VOXEL @@ -580,9 +573,9 @@ static res_T build_octrees(struct atrstm* atrstm) { struct atrri_refractive_index refract_id = ATRRI_REFRACTIVE_INDEX_NULL; - struct pool* pools = NULL; - size_t i; + struct pool pool; double wlen; + int pool_is_init = 0; ATOMIC res = RES_OK; ASSERT(atrstm && check_octrees_parameters(atrstm)); @@ -596,21 +589,18 @@ build_octrees(struct atrstm* atrstm) res = atrri_fetch_refractive_index(atrstm->atrri, wlen, &refract_id); if(res != RES_OK) goto error; - /* Allocate the per thread pool of partition */ - pools = MEM_CALLOC(atrstm->allocator, atrstm->nthreads, sizeof(*pools)); - if(!pools) { res = RES_MEM_ERR; goto error; } - FOR_EACH(i, 0, atrstm->nthreads) { - res = pool_init(atrstm->allocator, pools+i); - if(res != RES_OK) { - log_err(atrstm, - "Error initializing the pool of voxel partitions -- %s.\n", - res_to_cstr((res_T)res)); - goto error; - } + /* Initialise the pool of partitions */ + res = pool_init(atrstm->allocator, 16 * atrstm->nthreads, &pool); + if(res != RES_OK) { + log_err(atrstm, + "Error initializing the pool of voxel partitions -- %s.\n", + res_to_cstr((res_T)res)); + goto error; } + pool_is_init = 1; log_info(atrstm, - "Evaluating and partitionning the field of optical properties.\n"); + "Evaluate and partition the field of optical properties.\n"); omp_set_nested(1); /* Enable nested threads for voxelize_volumetric_mesh */ #pragma omp parallel sections num_threads(2) @@ -618,28 +608,22 @@ build_octrees(struct atrstm* atrstm) #pragma omp section { const res_T res_local = voxelize_volumetric_mesh - (atrstm, &refract_id, pools); + (atrstm, &refract_id, &pool); if(res_local != RES_OK) { - size_t ipool; log_err(atrstm, "Error voxelizing the volumetric mesh -- %s\n", res_to_cstr(res_local)); - FOR_EACH(ipool, 0, atrstm->nthreads) { - pool_invalidate(pools+ipool); - } + pool_invalidate(&pool); ATOMIC_SET(&res, res_local); } } #pragma omp section { - const res_T res_local = build_octree(atrstm, pools); + const res_T res_local = build_octree(atrstm, &pool); if(res_local != RES_OK) { - size_t ipool; log_err(atrstm, "Error building the octree -- %s\n", res_to_cstr(res_local)); - FOR_EACH(ipool, 0, atrstm->nthreads) { - pool_invalidate(pools+ipool); - } + pool_invalidate(&pool); ATOMIC_SET(&res, res_local); } } @@ -661,10 +645,7 @@ build_octrees(struct atrstm* atrstm) } exit: - if(pools) { - FOR_EACH(i, 0, atrstm->nthreads) pool_release(pools+i); - MEM_RM(atrstm->allocator, pools); - } + if(pool_is_init) pool_release(&pool); return (res_T)res; error: goto exit; diff --git a/src/atrstm_setup_uvm.c b/src/atrstm_setup_uvm.c @@ -68,7 +68,7 @@ setup_unstructured_volumetric_mesh res_T res = RES_OK; ASSERT(atrstm && sth_filename && out_volume); - log_info(atrstm, "Loading and structuring the volumetric mesh '%s'\n", + log_info(atrstm, "Load and structure the volumetric mesh '%s'\n", sth_filename); time_current(&t0);