commit 051843e1a9032660bf2a7ff35030e39bbaa9d5c3
parent 89b83bee0801f0b36c17f56ea5d3e099f11af7d4
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 1 May 2020 16:46:25 +0200
Make enclosure IDs reproducible
Diffstat:
1 file changed, 52 insertions(+), 10 deletions(-)
diff --git a/src/senc3d_scene_analyze.c b/src/senc3d_scene_analyze.c
@@ -616,7 +616,7 @@ group_connex_components
*res = s3d_scene_view_get_aabb(s3d_view, lower, upper);
if(*res != RES_OK) return;
/* 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;
@@ -981,12 +981,23 @@ tmp_error:
darray_neighbourhood_release(&neighbourhood_by_edge);
}
+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 senc3d_scene* scn,
const struct darray_ptr_component_descriptor* connex_components,
const struct darray_triangle_comp* triangles_comp_array,
struct darray_frontier_edge* frontiers,
+ enclosure_id_t* ordered_ids,
/* Shared error status.
* We accept to overwrite an error with a different error */
res_T* res)
@@ -1022,11 +1033,33 @@ build_result
#pragma omp single
{
+ enclosure_id_t e;
+ size_t d;
res_T tmp_res =
darray_triangle_enc_resize(&scn->analyze.triangles_enc, scn->ntris);
- 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, scn->analyze.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, scn->analyze.enclosures_count - 1,
+ sizeof(*enclosures), compare_enclosures);
+ /* Make conversion table */
+ FOR_EACH(e, 0, scn->analyze.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;
triangles_enc = darray_triangle_enc_data_get(&scn->analyze.triangles_enc);
/* Build global enclosure information */
@@ -1054,7 +1087,7 @@ build_result
#pragma omp for schedule(dynamic) nowait
for(ee = 0; ee < (int64_t)scn->analyze.enclosures_count; ee++) {
const enclosure_id_t e = (enclosure_id_t)ee;
- struct enclosure_data* enc = enclosures + e;
+ struct enclosure_data* enc = enclosures + ee;
trg_id_t fst_idx = 0;
trg_id_t sgd_idx = enc->side_count;
trg_id_t t;
@@ -1067,7 +1100,7 @@ build_result
if(*res != RES_OK) continue;
ASSERT(e <= ENCLOSURE_MAX__);
- enc->header.enclosure_id = (enclosure_id_t)e; /* Back to API type */
+ 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);
@@ -1180,6 +1213,8 @@ build_result
#pragma omp single nowait
darray_frontier_edge_copy_and_clear(&scn->analyze.frontiers, frontiers);
/* No barrier here */
+exit:
+ return;
}
/******************************************************************************
@@ -1208,6 +1243,7 @@ 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;
@@ -1321,16 +1357,21 @@ 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(s3d_view) S3D(scene_view_ref_put(s3d_view));
s3d_view = NULL;
- } /* No barrier here */
+ ordered_ids = MEM_ALLOC(scn->dev->allocator,
+ sizeof(*ordered_ids) * scn->analyze.enclosures_count);
+ if(!ordered_ids) res = RES_MEM_ERR;
+ } /* Implicit barrier here */
+ if(res != RES_OK) goto error_;
/* Step 4: Build result */
- build_result(scn, &connex_components, &triangles_comp, &frontiers, &res);
+ build_result(scn, &connex_components, &triangles_comp, &frontiers,
+ 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 */
@@ -1351,6 +1392,7 @@ scene_analyze
{
#pragma omp section
{
+ MEM_RM(scn->dev->allocator, ordered_ids);
custom_darray_ptr_component_descriptor_release(&connex_components);
connex_components_initialized = 0;
}