star-enclosures-2d

Extract enclosures from 2D geometry
git clone git://git.meso-star.fr/star-enclosures-2d.git
Log | Files | Refs | README | LICENSE

commit 5d34498c3e45d1bb7b7477581f8b784c20311577
parent 26a5ee9c563076f74631b041524080928d284df1
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date:   Fri,  1 May 2020 17:21:27 +0200

Make enclosure IDs reproducible

Diffstat:
Msrc/senc2d_scene_analyze.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 51 insertions(+), 10 deletions(-)

diff --git a/src/senc2d_scene_analyze.c b/src/senc2d_scene_analyze.c @@ -581,7 +581,7 @@ group_connex_components positions = darray_position_cdata_get(&desc->scene->vertices); /* Cast rays to find links between connex components */ - #pragma omp for + #pragma omp for schedule(dynamic) for(ccc = 0; ccc < (int64_t)cc_count; ccc++) { res_T tmp_res = RES_OK; component_id_t c = (component_id_t)ccc; @@ -914,12 +914,23 @@ collect_and_link_neighbours /* Threads are allowed to return whitout sync. */ } +static int +compare_enclosures + (const void* ptr1, const void* ptr2) +{ + const struct enclosure_data* e1 = ptr1; + const struct enclosure_data* e2 = ptr2; + ASSERT(e1->side_range.first != e2->side_range.first); + return (e1->side_range.first - e2->side_range.first); +} + static void build_result (struct senc2d_descriptor* desc, const struct darray_ptr_component_descriptor* connex_components, const struct darray_segment_comp* segments_comp_array, struct darray_vrtx_id* frontiers, + enclosure_id_t* ordered_ids, /* Shared error status. * We accept to overwrite an error with a different error */ res_T* res) @@ -956,11 +967,33 @@ build_result segments_comp = darray_segment_comp_cdata_get(segments_comp_array); #pragma omp single { + enclosure_id_t e; + size_t d; res_T tmp_res = darray_segment_enc_resize(&desc->segments_enc, scn->nusegs); - if(tmp_res != RES_OK) *res = tmp_res; + if(tmp_res != RES_OK) { + *res = tmp_res; + goto single_err; + } + /* Store initial enclosure order */ + FOR_EACH(e, 0, desc->enclosures_count) + enclosures[e].header.enclosure_id = e; + /* Move enclosures by first side while keeping enclosure 0 + * at rank 0 (its a convention) */ + qsort(enclosures + 1, desc->enclosures_count - 1, + sizeof(*enclosures), compare_enclosures); + /* Make conversion table */ + FOR_EACH(e, 0, desc->enclosures_count) { + enclosure_id_t rank = enclosures[e].header.enclosure_id; + ordered_ids[rank] = e; + } + /* Rewrite cc_descriptors */ + FOR_EACH(d, 0, darray_ptr_component_descriptor_size_get(connex_components)) + cc_descriptors[d]->enclosure_id = + ordered_ids[cc_descriptors[d]->enclosure_id]; + single_err: (void)0; }/* Implicit barrier here. */ - if(*res != RES_OK) return; + if(*res != RES_OK) goto exit; segments_enc = darray_segment_enc_data_get(&desc->segments_enc); /* Build global enclosure information */ @@ -1000,8 +1033,8 @@ build_result == enc->first_component); if(*res != RES_OK) continue; - ASSERT(e <= UINT_MAX); - enc->header.enclosure_id = (unsigned)e; /* Back to API type */ + ASSERT(e <= ENCLOSURE_MAX__); + enc->header.enclosure_id = (unsigned)ee; /* Back to API type */ ASSERT(cc_descriptors[enc->first_component]->enclosure_id == enc->header.enclosure_id); enc->header.is_infinite = (e == 0); @@ -1114,6 +1147,8 @@ build_result #pragma omp single nowait darray_vrtx_id_copy_and_clear(&desc->frontiers, frontiers); /* No barrier here */ +exit: + return; } /******************************************************************************* @@ -1147,6 +1182,7 @@ senc2d_scene_analyze /* Atomic counters to share beetwen threads */ ATOMIC component_count = 0; ATOMIC next_enclosure_id = 1; + enclosure_id_t* ordered_ids = NULL; res_T res = RES_OK; res_T res2 = RES_OK; @@ -1284,17 +1320,21 @@ senc2d_scene_analyze goto error_; } - /* One thread releases some data before going to step 4, - * the others go to step 4 without sync */ - #pragma omp single nowait + /* One thread releases some data and allocate other data before going to + * step 4, the others waiting for alloced data */ +#pragma omp single { if(s2d_view) S2D(scene_view_ref_put(s2d_view)); s2d_view = NULL; - } /* No barrier here */ + ordered_ids = MEM_ALLOC(scn->dev->allocator, + sizeof(*ordered_ids) * desc->enclosures_count); + if(!ordered_ids) res = RES_MEM_ERR; + } /* Implicit barrier here */ + if(res != RES_OK) goto error_; /* Step 4: Build result */ build_result(desc, &connex_components, &segments_comp, &frontiers, - &res); + ordered_ids, &res); /* No barrier at the end of step 4: data used in step 4 cannot be * released / data produced by step 4 cannot be used * until next sync point */ @@ -1315,6 +1355,7 @@ senc2d_scene_analyze { #pragma omp section { + MEM_RM(scn->dev->allocator, ordered_ids); custom_darray_ptr_component_descriptor_release(&connex_components); connex_components_initialized = 0; }