commit afcaf41d20acedd247a969b1387f38ca6807de44
parent aff0cf67939db10a2cb5261dc1eadf82c0b425a6
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 22 Jul 2022 17:24:30 +0200
Continue the building of the octrees
Diffstat:
5 files changed, 423 insertions(+), 31 deletions(-)
diff --git a/src/rnatm.h b/src/rnatm.h
@@ -50,6 +50,7 @@ struct mem_allocator;
enum rnatm_radcoef {
RNATM_RADCOEF_Ka, /* Absorption coefficient */
RNATM_RADCOEF_Ks, /* Scattering coefficient */
+ RNATM_RADCOEF_Kext, /* Extinction coefficient */
RNATM_RADCOEFS_COUNT__
};
diff --git a/src/rnatm_c.h b/src/rnatm_c.h
@@ -21,7 +21,7 @@
#ifndef RNATM_C_H
#define RNATM_C_H
-#include <rsys/dynamic_array.h>
+#include <rsys/dynamic_array_size_t.h>
#include <rsys/logger.h>
#include <rsys/ref_count.h>
#include <rsys/str.h>
@@ -29,6 +29,15 @@
struct rnatm_create_args;
struct rnsf;
+/* Generate the dynamic array of dynamic array of size_t */
+#define DARRAY_NAME size_t_list
+#define DARRAY_DATA struct darray_size_t
+#define DARRAY_FUNCTOR_INIT darray_size_t_init
+#define DARRAY_FUNCTOR_RELEASE darray_size_t_release
+#define DARRAY_FUNCTOR_COPY darray_size_t_copy
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE darray_size_t_copy_and_release
+#include <rsys/dynamic_array.h>
+
/*******************************************************************************
* Phase function
******************************************************************************/
diff --git a/src/rnatm_octree.c b/src/rnatm_octree.c
@@ -29,6 +29,7 @@
#include <rsys/cstr.h>
#include <rsys/math.h>
+#include <rsys/morton.h>
#include <rsys/rsys.h>
#include <math.h> /* lround */
@@ -59,6 +60,22 @@ round_pow2(const unsigned val)
}
}
+static INLINE void
+register_tetra
+ (const struct suvm_primitive* prim,
+ const double low[3],
+ const double upp[3],
+ void* context)
+{
+ struct darray_size_t* tetra_ids = context;
+ ASSERT(prim && low && upp && context);
+ ASSERT(low[0] < upp[0]);
+ ASSERT(low[1] < upp[1]);
+ ASSERT(low[2] < upp[2]);
+ (void)low, (void)upp;
+ CHK(darray_size_t_push_back(tetra_ids, &prim->iprim) == RES_OK);
+}
+
static res_T
compute_grid_definition(struct rnatm* atm, const struct rnatm_create_args* args)
{
@@ -114,7 +131,336 @@ compute_grid_definition(struct rnatm* atm, const struct rnatm_create_args* args)
}
static res_T
-build_octrees(struct rnatm* atm, const struct rnatm_create_args* args)
+update_voxel
+ (struct rnatm* atm,
+ const struct suvm_primitive* tetra,
+ struct partition* part,
+ const uint64_t vx_mcode)
+{
+ size_t iquad_pt;
+ size_t iband;
+ size_t nbands;
+ float* vx = NULL;
+ ASSERT(atm && tetra && part);
+ ASSERT(tetra->nvertices == 4);
+
+ nbands = sck_get_bands_count(atm->gas.ck);
+
+ #define REDUX_MIN(V4) MMIN(MMIN((V4)[0], (V4)[1]), MMIN((V4)[2], V4[3]))
+ #define REDUX_MAX(V4) MMAX(MMAX((V4)[0], (V4)[1]), MMAX((V4)[2], V4[3]))
+
+ FOR_EACH(iband, 0, nbands) {
+ struct sck_band band;
+ float tetra_ks[4];
+ float tetra_ks_min, tetra_ks_max;
+
+ /* Compute the scattering coefficient range of the tetrahedron */
+ SCK(get_band(atm->gas.ck, iband, &band));
+ tetra_ks[0] = band.ks_list[tetra->indices[0]];
+ tetra_ks[1] = band.ks_list[tetra->indices[1]];
+ tetra_ks[2] = band.ks_list[tetra->indices[2]];
+ tetra_ks[3] = band.ks_list[tetra->indices[3]];
+ tetra_ks_min = REDUX_MIN(tetra_ks);
+ tetra_ks_max = REDUX_MAX(tetra_ks);
+
+ FOR_EACH(iquad_pt, 0, band.quad_pts_count) {
+ struct sck_quad_pt quad_pt;
+ float tetra_ka[4];
+ float tetra_kext[4];
+ float tetra_ka_min, tetra_ka_max;
+ float tetra_kext_min, tetra_kext_max;
+ float vx_ka_min, vx_ka_max;
+ float vx_ks_min, vx_ks_max;
+ float vx_kext_min, vx_kext_max;
+
+ /* Compute the absorption coefficient range of the tetrahedron */
+ SCK(band_get_quad_pt(&band, iquad_pt, &quad_pt));
+ tetra_ka[0] = quad_pt.ka_list[tetra->indices[0]];
+ tetra_ka[1] = quad_pt.ka_list[tetra->indices[1]];
+ tetra_ka[2] = quad_pt.ka_list[tetra->indices[2]];
+ tetra_ka[3] = quad_pt.ka_list[tetra->indices[3]];
+ tetra_ka_min = REDUX_MIN(tetra_ka);
+ tetra_ka_max = REDUX_MAX(tetra_ka);
+
+ /* Compute the extinction coefficient range of the tetrahedron */
+ tetra_kext[0] = tetra_ka[0] + tetra_ks[0];
+ tetra_kext[1] = tetra_ka[1] + tetra_ks[1];
+ tetra_kext[2] = tetra_ka[2] + tetra_ks[2];
+ tetra_kext[3] = tetra_ka[3] + tetra_ks[3];
+ tetra_kext_min = REDUX_MIN(tetra_kext);
+ tetra_kext_max = REDUX_MAX(tetra_kext);
+
+ vx = partition_get_voxel(part, iband, iquad_pt, vx_mcode);
+
+ /* Update the range of the radiative coefficients of the voxel */
+ vx_ka_min = vx[voxel_idata(RNATM_RADCOEF_Ka, RNATM_SVX_OP_MIN)];
+ vx_ka_max = vx[voxel_idata(RNATM_RADCOEF_Ka, RNATM_SVX_OP_MAX)];
+ vx_ks_min = vx[voxel_idata(RNATM_RADCOEF_Ks, RNATM_SVX_OP_MIN)];
+ vx_ks_max = vx[voxel_idata(RNATM_RADCOEF_Ks, RNATM_SVX_OP_MAX)];
+ vx_kext_min = vx[voxel_idata(RNATM_RADCOEF_Kext, RNATM_SVX_OP_MIN)];
+ vx_kext_max = vx[voxel_idata(RNATM_RADCOEF_Kext, RNATM_SVX_OP_MAX)];
+ vx_ka_min = MMIN(vx_ka_min, tetra_ka_min);
+ vx_ka_max = MMAX(vx_ka_max, tetra_ka_max);
+ vx_ks_min = MMIN(vx_ks_min, tetra_ks_min);
+ vx_ks_max = MMAX(vx_ks_max, tetra_ks_max);
+ vx_kext_min = MMIN(vx_kext_min, tetra_kext_min);
+ vx_kext_max = MMAX(vx_kext_max, tetra_kext_max);
+ vx[voxel_idata(RNATM_RADCOEF_Ka, RNATM_SVX_OP_MIN)] = vx_ka_min;
+ vx[voxel_idata(RNATM_RADCOEF_Ka, RNATM_SVX_OP_MAX)] = vx_ka_max;
+ vx[voxel_idata(RNATM_RADCOEF_Ks, RNATM_SVX_OP_MIN)] = vx_ks_min;
+ vx[voxel_idata(RNATM_RADCOEF_Ks, RNATM_SVX_OP_MAX)] = vx_ks_max;
+ vx[voxel_idata(RNATM_RADCOEF_Kext, RNATM_SVX_OP_MIN)] = vx_kext_min;
+ vx[voxel_idata(RNATM_RADCOEF_Kext, RNATM_SVX_OP_MAX)] = vx_kext_max;
+ }
+ }
+ #undef REDUX_MIN
+ #undef REDUX_MAX
+
+ return RES_OK;
+}
+
+static res_T
+voxelize_gas
+ (struct rnatm* atm,
+ const double part_low[3],
+ const double part_upp[3],
+ const double vxsz[3],
+ const struct darray_size_t* tetra_ids,
+ struct partition* part)
+{
+ size_t i;
+ res_T res = RES_OK;
+ ASSERT(atm && part_low && part_upp && tetra_ids && part);
+ ASSERT(vxsz[0] > 0 && vxsz[1] > 0 && vxsz[2] > 0);
+ ASSERT(part_low[0] < part_upp[0]);
+ ASSERT(part_low[1] < part_upp[1]);
+ ASSERT(part_low[2] < part_upp[2]);
+
+ partition_clear_voxels(part);
+
+ FOR_EACH(i, 0, darray_size_t_size_get(tetra_ids)) {
+ struct suvm_primitive tetra;
+ struct suvm_polyhedron poly;
+ double poly_low[3];
+ double poly_upp[3];
+ float vx_low[3];
+ float vx_upp[3];
+ uint32_t ivx_low[3];
+ uint32_t ivx_upp[3];
+ uint32_t ivx[3];
+ uint64_t mcode[3]; /* Cache of 3D morton code */
+ const size_t itetra = darray_size_t_cdata_get(tetra_ids)[i];
+ enum suvm_intersection_type intersect;
+
+ /* Recover the tetrahedron and setup its polyhedron */
+ SUVM(volume_get_primitive(atm->gas.volume, itetra, &tetra));
+ SUVM(primitive_setup_polyhedron(&tetra, &poly));
+ ASSERT(poly.lower[0] <= part_upp[0] && poly.upper[0] >= part_low[0]);
+ ASSERT(poly.lower[1] <= part_upp[1] && poly.upper[1] >= part_low[1]);
+ ASSERT(poly.lower[2] <= part_upp[2] && poly.upper[2] >= part_low[2]);
+
+ /* Clamp the AABB of the polyhedra to the partition bounds */
+ poly_low[0] = MMAX(poly.lower[0], part_low[0]);
+ poly_low[1] = MMAX(poly.lower[1], part_low[1]);
+ poly_low[2] = MMAX(poly.lower[2], part_low[2]);
+ poly_upp[0] = MMIN(poly.upper[0], part_upp[0]);
+ poly_upp[1] = MMIN(poly.upper[1], part_upp[1]);
+ poly_upp[2] = MMIN(poly.upper[2], part_upp[2]);
+
+ /* Transform the AABB of the polyhedron in voxel space of the partition */
+ ivx_low[0] = (uint32_t)((poly_low[0] - part_low[0]) / vxsz[0]);
+ ivx_low[1] = (uint32_t)((poly_low[1] - part_low[1]) / vxsz[1]);
+ ivx_low[2] = (uint32_t)((poly_low[2] - part_low[2]) / vxsz[2]);
+ ivx_upp[0] = (uint32_t)ceil((poly_upp[0] - part_low[0]) / vxsz[0]);
+ ivx_upp[1] = (uint32_t)ceil((poly_upp[1] - part_low[1]) / vxsz[1]);
+ ivx_upp[2] = (uint32_t)ceil((poly_upp[2] - part_low[2]) / vxsz[2]);
+ ASSERT(ivx_upp[0] <= partition_get_definition(part));
+ ASSERT(ivx_upp[1] <= partition_get_definition(part));
+ ASSERT(ivx_upp[2] <= partition_get_definition(part));
+
+ /* Iterate voxels intersected by the AABB of the polyedron */
+ FOR_EACH(ivx[2], ivx_low[2], ivx_upp[2]) {
+ vx_low[2] = (float)((double)ivx[2]*vxsz[2] + part_low[2]);
+ vx_upp[2] = vx_low[2] + (float)vxsz[2];
+ mcode[2] = morton3D_encode_u21(ivx[2]);
+
+ FOR_EACH(ivx[1], ivx_low[1], ivx_upp[1]) {
+ vx_low[1] = (float)((double)ivx[1]*vxsz[1] + part_low[1]);
+ vx_upp[1] = vx_low[1] + (float)vxsz[1];
+ mcode[1] = (morton3D_encode_u21(ivx[1]) << 1) | mcode[2];
+
+ FOR_EACH(ivx[0], ivx_low[0], ivx_upp[0]) {
+ vx_low[0] = (float)((double)ivx[0]*vxsz[0] + part_low[0]);
+ vx_upp[0] = vx_low[0] + (float)vxsz[0];
+ mcode[0] = (morton3D_encode_u21(ivx[0]) << 2) | mcode[1];
+
+ intersect = suvm_polyhedron_intersect_aabb(&poly, vx_low, vx_upp);
+ if(intersect == SUVM_INTERSECT_NONE) continue;
+
+ res = update_voxel(atm, &tetra, part, mcode[0]);
+ if(res != RES_OK) goto error;
+ }
+ }
+ }
+ }
+exit:
+ return res;
+error:
+ partition_clear_voxels(part);
+ goto exit;
+}
+
+static res_T
+voxelize_partition
+ (struct rnatm* atm,
+ const double part_low[3],
+ const double part_upp[3],
+ const double vxsz[3],
+ struct darray_size_t* tetra_ids,
+ struct partition* part)
+{
+ res_T res = RES_OK;
+ ASSERT(atm && part_low && part_upp && tetra_ids && part);
+ ASSERT(part_low[0] < part_upp[0]);
+ ASSERT(part_low[1] < part_upp[1]);
+ ASSERT(part_low[2] < part_upp[2]);
+
+ /* Find the list of gas tetrahedra that overlap the partition */
+ darray_size_t_clear(tetra_ids);
+ res = suvm_volume_intersect_aabb
+ (atm->gas.volume, part_low, part_upp, register_tetra, tetra_ids);
+ if(res != RES_OK) goto error;
+
+ res = voxelize_gas(atm, part_low, part_upp, vxsz, tetra_ids, part);
+ if(res != RES_OK) goto error;
+
+ /* TODO voxelise aerosols */
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+voxelize_atmosphere(struct rnatm* atm, struct pool* pool)
+{
+ struct darray_size_t_list per_thread_tetra_list;
+ double atm_low[3];
+ double atm_upp[3];
+ double vxsz[3];
+ size_t nparts[3]; /* #partitions along the 3 axis */
+ size_t nparts_adjusted;
+ size_t part_def; /* Definition of a partition */
+ int64_t i;
+ int progress = 0;
+ ATOMIC nparts_voxelized = 0;
+ ATOMIC res = RES_OK;
+ ASSERT(atm);
+
+ /* Allocate the per thread list of tetra list */
+ darray_size_t_list_init(atm->allocator, &per_thread_tetra_list);
+ res = darray_size_t_list_resize(&per_thread_tetra_list, atm->nthreads);
+ if(res != RES_OK) goto error;
+
+ /* Recover the AABB atmosphere and compute the size of a voxel */
+ SUVM(volume_get_aabb(atm->gas.volume, atm_low, atm_upp));
+ vxsz[0] = (atm_upp[0] - atm_low[0]) / (double)atm->grid_definition[0];
+ vxsz[1] = (atm_upp[1] - atm_low[1]) / (double)atm->grid_definition[1];
+ vxsz[2] = (atm_upp[2] - atm_low[2]) / (double)atm->grid_definition[2];
+
+ /* Number of partitions required to cover the entire atmosphere grid */
+ part_def = pool_get_partition_definition(pool);
+ nparts[0] = (atm->grid_definition[0] + (part_def-1)/*ceil*/) / part_def;
+ nparts[1] = (atm->grid_definition[1] + (part_def-1)/*ceil*/) / part_def;
+ nparts[2] = (atm->grid_definition[2] + (part_def-1)/*ceil*/) / part_def;
+
+ /* Adjust the #partitions allowing their indexing by their morton code */
+ nparts_adjusted = MMAX(nparts[0], MMAX(nparts[1], nparts[2]));
+ nparts_adjusted = round_up_pow2(nparts_adjusted);
+ nparts_adjusted = nparts_adjusted * nparts_adjusted * nparts_adjusted;
+
+ /* Print status message */
+ #define LOG_MSG "Voxelization of atmosphere meshes: %3d%%\r"
+ log_info(atm, LOG_MSG, 0);
+
+ /* Iterates over the partitions of the grid according to their Morton order
+ * and voxelizes the tetrahedrons that overlap them */
+ omp_set_num_threads((int)atm->nthreads);
+ #pragma omp parallel for schedule(static, 1/*chunk size*/)
+ for(i = 0; i < (int64_t)nparts_adjusted; ++i) {
+ struct darray_size_t* tetra_ids = NULL;
+ struct partition* part = NULL;
+ double part_low[3];
+ double part_upp[3];
+ uint32_t part_ids[3];
+ size_t n;
+ const int ithread = omp_get_thread_num();
+ int pcent;
+ res_T res_local = RES_OK;
+
+ if(ATOMIC_GET(&res) != RES_OK) continue;
+
+ /* Recover current partition */
+ part = pool_next_partition(pool);
+ if(!part) { ATOMIC_SET(&res, RES_UNKNOWN_ERR); continue; };
+
+ /* Is the partition out of bounds of the atmosphere grid*/
+ morton_xyz_decode_u21((uint64_t)partition_get_id(part), part_ids);
+ if(part_ids[0] >= nparts[0]
+ || part_ids[1] >= nparts[1]
+ || part_ids[2] >= nparts[2]) {
+ pool_free_partition(pool, part);
+ continue;
+ }
+
+ /* Compute the AABB of the partition */
+ part_low[0] = (double)(part_ids[0] * part_def) * vxsz[0] + atm_low[0];
+ part_low[1] = (double)(part_ids[1] * part_def) * vxsz[1] + atm_low[1];
+ part_low[2] = (double)(part_ids[2] * part_def) * vxsz[2] + atm_low[2];
+ part_upp[0] = part_low[0] + (double)part_def * vxsz[0];
+ part_upp[1] = part_low[1] + (double)part_def * vxsz[1];
+ part_upp[2] = part_low[2] + (double)part_def * vxsz[2];
+
+ /* Retrieves the array where to store the indices of tetrahedra that
+ * overlap the partition */
+ tetra_ids = darray_size_t_list_data_get(&per_thread_tetra_list) + ithread;
+
+ /* Voxelizes the partition and once done, commits */
+ res_local = voxelize_partition
+ (atm, part_low, part_upp, vxsz, tetra_ids, part);
+ if(res_local == RES_OK) {
+ pool_commit_partition(pool, part);
+ } else {
+ pool_free_partition(pool, part);
+ ATOMIC_SET(&res, res_local);
+ continue;
+ };
+
+ /* Update progress bar */
+ n = (size_t)ATOMIC_INCR(&nparts_voxelized);
+ pcent = (int)((n * 100) / (nparts[0]*nparts[1]*nparts[2]));
+ #pragma omp critical
+ if(pcent > progress) {
+ progress = pcent;
+ log_info(atm, LOG_MSG, pcent);
+ }
+ }
+ if(res != RES_OK) goto error;
+
+ /* Print final status message */
+ log_info(atm, LOG_MSG"\n", 100);
+ #undef LOG_MSG
+
+exit:
+ darray_size_t_list_release(&per_thread_tetra_list);
+ return (res_T)res;
+error:
+ goto exit;
+}
+
+static res_T
+build_octrees(struct rnatm* atm)
{
/* Empirical constant that defines the number of voxel partitions to
* pre-allocate per thread to avoid contension between the thread building the
@@ -124,8 +470,8 @@ build_octrees(struct rnatm* atm, const struct rnatm_create_args* args)
struct pool_create_args pool_args = POOL_CREATE_ARGS_DEFAULT;
struct pool* pool = NULL;
- res_T res = RES_OK;
- ASSERT(atm && args);
+ ATOMIC res = RES_OK;
+ ASSERT(atm);
/* Create the vortex partition pool */
pool_args.npartitions = NPARTITIONS_PER_THREAD * atm->nthreads;
@@ -137,7 +483,7 @@ build_octrees(struct rnatm* atm, const struct rnatm_create_args* args)
res = pool_create(&pool_args, &pool);
if(res != RES_OK) {
log_err(atm, "Failed to create the voxel partition pool -- %s\n",
- res_to_cstr(res));
+ res_to_cstr((res_T)res));
goto error;
}
@@ -148,12 +494,30 @@ build_octrees(struct rnatm* atm, const struct rnatm_create_args* args)
* properties */
omp_set_nested(1);
- /* TODO build the octrees */
- (void)args;
+ #pragma omp parallel sections num_threads(2)
+ {
+ #pragma omp section
+ {
+ const res_T res_local = voxelize_atmosphere(atm, pool);
+ if(res_local != RES_OK) {
+ log_err(atm, "Atmosphere voxelization error -- %s\n",
+ res_to_cstr(res_local));
+ pool_invalidate(pool);
+ ATOMIC_SET(&res, res_local);
+ }
+ }
+
+ #pragma omp section
+ {
+ /* TODO Build the octreese */
+ FATAL("Not fully implemented yet\n");
+ }
+ }
+ if(res != RES_OK) goto error;
exit:
if(pool) pool_ref_put(pool);
- return res;
+ return (res_T)res;
error:
goto exit;
}
@@ -169,7 +533,7 @@ setup_octrees(struct rnatm* atm, const struct rnatm_create_args* args)
res = compute_grid_definition(atm, args);
if(res != RES_OK) goto error;
- res = build_octrees(atm, args);
+ res = build_octrees(atm);
if(res != RES_OK) goto error;
exit:
diff --git a/src/rnatm_voxel_partition.c b/src/rnatm_voxel_partition.c
@@ -18,25 +18,18 @@
* 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 "rnatm_c.h"
#include "rnatm_log.h"
#include "rnatm_voxel_partition.h"
#include <rsys/condition.h>
-#include <rsys/dynamic_array_size_t.h>
#include <rsys/mem_allocator.h>
#include <rsys/mutex.h>
#include <rsys/ref_count.h>
-/* Generate the dynamic array of dynamic array of size_t */
-#define DARRAY_NAME size_t_list
-#define DARRAY_DATA struct darray_size_t
-#define DARRAY_FUNCTOR_INIT darray_size_t_init
-#define DARRAY_FUNCTOR_RELEASE darray_size_t_release
-#define DARRAY_FUNCTOR_COPY darray_size_t_copy
-#define DARRAY_FUNCTOR_COPY_AND_RELEASE darray_size_t_copy_and_release
-#include <rsys/dynamic_array.h>
-
struct partition {
+ size_t definition;
+
/* Size of a cluster in bytes. A cluster is a list of voxels for a quadrature
* point of a spectral band */
size_t cluster_size;
@@ -72,6 +65,7 @@ struct pool {
struct cond* cond_fetch;
size_t next_part_id; /* Indentifier of the next partition */
+ size_t partition_definition; /* #voxels along the 3 axis */
struct mem_allocator* allocator;
ATOMIC error; /* Is the pool not valid? */
@@ -118,6 +112,7 @@ setup_partition_clusters
/* Compute the size of a cluster. Ensure a multiple of 64 bytes, i.e. align
* the cluster of voxels on the size of a cache line */
+ partition->definition = args->partition_definition;
partition->cluster_nvoxels =
args->partition_definition
* args->partition_definition
@@ -253,6 +248,20 @@ partition_ref_put(struct partition* partition)
ref_put(&partition->ref, release_partition);
}
+size_t
+partition_get_id(const struct partition* partition)
+{
+ ASSERT(partition);
+ return partition->id;
+}
+
+size_t
+partition_get_definition(const struct partition* partition)
+{
+ ASSERT(partition);
+ return partition->definition;
+}
+
float*
partition_get_voxel
(struct partition* part,
@@ -322,6 +331,7 @@ pool_create
goto error;
}
pool->allocator = allocator;
+ pool->partition_definition = args->partition_definition;
ref_init(&pool->ref);
list_init(&pool->parts_free);
list_init(&pool->parts_commit);
@@ -366,6 +376,13 @@ pool_ref_put(struct pool* pool)
ref_put(&pool->ref, release_pool);
}
+size_t
+pool_get_partition_definition(const struct pool* pool)
+{
+ ASSERT(pool);
+ return pool->partition_definition;
+}
+
struct partition*
pool_next_partition(struct pool* pool)
{
diff --git a/src/rnatm_voxel_partition.h b/src/rnatm_voxel_partition.h
@@ -26,17 +26,6 @@
#include <rsys/list.h>
#include <rsys/rsys.h>
-/* TODO remove this */
-#if 0
-/* Definition of a partition along the 3 axes */
-#define PARTITION_LOG2_DEFINITION 5 /* 5 */
-#define PARTITION_DEFINITION BIT(PARTITION_LOG2_DEFINITION) /* 2^5 = 32 */
-#define PARTITION_NVOXELS \
- ( PARTITION_DEFINITION \
- * PARTITION_DEFINITION \
- * PARTITION_DEFINITION)
-#endif
-
struct pool_create_args {
size_t npartitions; /* Number of partitions to preallocate */
@@ -56,7 +45,15 @@ static const struct pool_create_args POOL_CREATE_ARGS_DEFAULT =
******************************************************************************/
struct partition;
-extern LOCAL_SYM FINLINE float*
+extern LOCAL_SYM size_t
+partition_get_id
+ (const struct partition* partition);
+
+extern LOCAL_SYM size_t
+partition_get_definition
+ (const struct partition* partition);
+
+extern LOCAL_SYM float*
partition_get_voxel
(struct partition* partition,
const size_t iband,
@@ -86,6 +83,10 @@ extern LOCAL_SYM void
pool_ref_put
(struct pool* pool);
+extern LOCAL_SYM size_t
+pool_get_partition_definition
+ (const struct pool* pool);
+
/* Returns a free partition. Waits for a free partition to be available.
* Returns NULL if an error occurs */
extern LOCAL_SYM struct partition*