htrdr

Solving radiative transfer in heterogeneous media
git clone git://git.meso-star.fr/htrdr.git
Log | Files | Refs | README | LICENSE

commit 278761ebd12ce69bad65bb791511f4f2aa4c17b1
parent f6080cb9576a54572bf68f1b680b766df344d892
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 19 Feb 2021 09:51:33 +0100

Setup the core CMakeLists.txt file and fix its compilation

Diffstat:
Mcmake/CMakeLists.txt | 136+++++--------------------------------------------------------------------------
Acmake/core/CMakeLists.txt | 143+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/atmosphere/htrdr_atmosphere.c | 84++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/core/htrdr.c | 66++++++++++++++++++++++--------------------------------------------
Msrc/core/htrdr.h | 25++++++++++++++-----------
Msrc/core/htrdr_args.c | 97+++++++++++++++++++++++++++++--------------------------------------------------
Dsrc/core/htrdr_args.h | 106-------------------------------------------------------------------------------
Asrc/core/htrdr_args.h.in | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/core/htrdr_buffer.c | 6++++--
Msrc/core/htrdr_c.h | 72+++---------------------------------------------------------------------
Msrc/core/htrdr_camera.c | 1+
Msrc/core/htrdr_cie_xyz.c | 20++++++--------------
Msrc/core/htrdr_draw_map.c | 89+++++++++++++++++++++++++++++++------------------------------------------------
Msrc/core/htrdr_draw_map.h | 6+++---
Msrc/core/htrdr_log.c | 13+++++++++++++
Msrc/core/htrdr_main.c | 12++++++------
Msrc/core/htrdr_materials.c | 19++++++++++---------
Msrc/core/htrdr_ran_wlen.c | 30+++++++++++++-----------------
Msrc/core/htrdr_rectangle.c | 1+
Dsrc/core/htrdr_sensor.c | 79-------------------------------------------------------------------------------
Msrc/core/htrdr_slab.c | 1+
Msrc/core/htrdr_spectral.c | 3++-
Msrc/core/htrdr_spectral.h | 19++++++++++++++++---
23 files changed, 516 insertions(+), 619 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -14,149 +14,27 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.1) project(htrdr C) -enable_testing() set(HTRDR_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src) -option(NO_TEST "Do not build the tests" OFF) -################################################################################ -# Check dependencies -################################################################################ -find_package(AW 2.0 REQUIRED) -find_package(HTSky 0.2 REQUIRED) -find_package(MruMtl 0.0 REQUIRED) -find_package(RCMake 0.3 REQUIRED) -find_package(RSys 0.11 REQUIRED) -find_package(Star3D 0.7.1 REQUIRED) -find_package(StarSF 0.6 REQUIRED) -find_package(StarSP 0.8 REQUIRED) -find_package(StarVX 0.1 REQUIRED) -find_package(OpenMP 1.2 REQUIRED) -find_package(MPI 1 REQUIRED) - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) -include(rcmake) -include(rcmake_runtime) - -set(CMAKE_C_COMPILER ${MPI_C_COMPILER}) - -include_directories( - ${AW_INCLUDE_DIR} - ${MruMtl_INCLUDE_DIR} - ${RSys_INCLUDE_DIR} - ${Star3D_INCLUDE_DIR} - ${StarSF_INCLUDE_DIR} - ${StarSP_INCLUDE_DIR} - ${StarVX_INCLUDE_DIR} - ${HTSky} - ${HTRDR_SOURCE_DIR} - ${MPI_INCLUDE_PATH} - ${CMAKE_CURRENT_BINARY_DIR}) - -################################################################################ -# Generate files -################################################################################ set(VERSION_MAJOR 0) -set(VERSION_MINOR 6) -set(VERSION_PATCH 1) +set(VERSION_MINOR 7) +set(VERSION_PATCH 0) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) -set(HTRDR_ARGS_DEFAULT_CAMERA_POS "0,0,0") -set(HTRDR_ARGS_DEFAULT_CAMERA_TGT "0,1,0") -set(HTRDR_ARGS_DEFAULT_CAMERA_UP "0,0,1") -set(HTRDR_ARGS_DEFAULT_CAMERA_FOV "70") -set(HTRDR_ARGS_DEFAULT_RECTANGLE_POS "0,0,0") -set(HTRDR_ARGS_DEFAULT_RECTANGLE_TGT "0,0,1") -set(HTRDR_ARGS_DEFAULT_RECTANGLE_UP "0,1,0") -set(HTRDR_ARGS_DEFAULT_RECTANGLE_SZ "1,1") -set(HTRDR_ARGS_DEFAULT_IMG_WIDTH "320") -set(HTRDR_ARGS_DEFAULT_IMG_HEIGHT "240") -set(HTRDR_ARGS_DEFAULT_IMG_SPP "1") -set(HTRDR_ARGS_DEFAULT_OPTICAL_THICKNESS_THRESHOLD "1") -set(HTRDR_ARGS_DEFAULT_SKY_MTL_NAME "\"air\"") - -configure_file(${HTRDR_SOURCE_DIR}/htrdr_version.h.in - ${CMAKE_CURRENT_BINARY_DIR}/htrdr_version.h @ONLY) - -configure_file(${HTRDR_SOURCE_DIR}/htrdr_args.h.in - ${CMAKE_CURRENT_BINARY_DIR}/htrdr_args.h @ONLY) - ################################################################################ # Add sub projects ################################################################################ +add_subdirectory(core) add_subdirectory(doc) ################################################################################ -# Configure and define targets -################################################################################ -set(HTRDR_FILES_SRC - htrdr.c - htrdr_args.c - htrdr_buffer.c - htrdr_camera.c - htrdr_cie_xyz.c - htrdr_compute_radiance_sw.c - htrdr_compute_radiance_lw.c - htrdr_draw_map.c - htrdr_grid.c - htrdr_ground.c - htrdr_main.c - htrdr_materials.c - htrdr_ran_wlen.c - htrdr_rectangle.c - htrdr_sensor.c - htrdr_slab.c - htrdr_spectral.c - htrdr_sun.c) -set(HTRDR_FILES_INC - htrdr.h - htrdr_c.h - htrdr_buffer.h - htrdr_camera.h - htrdr_cie_xyz.h - htrdr_grid.h - htrdr_ground.h - htrdr_interface.h - htrdr_materials.h - htrdr_ran_wlen.h - htrdr_rectangle.h - htrdr_sensor.h - htrdr_slab.h - htrdr_spectral.h - htrdr_sun.h - htrdr_solve.h) -set(HTRDR_FILES_INC2 # Generated files - htrdr_args.h - htrdr_version.h) -set(HTRDR_FILES_DOC COPYING README.md) - -# Prepend each file in the `HTRDR_FILES_<SRC|INC>' list by `HTRDR_SOURCE_DIR' -rcmake_prepend_path(HTRDR_FILES_SRC ${HTRDR_SOURCE_DIR}) -rcmake_prepend_path(HTRDR_FILES_INC ${HTRDR_SOURCE_DIR}) -rcmake_prepend_path(HTRDR_FILES_INC2 ${CMAKE_CURRENT_BINARY_DIR}) -rcmake_prepend_path(HTRDR_FILES_DOC ${PROJECT_SOURCE_DIR}/../) - -add_executable(htrdr ${HTRDR_FILES_SRC} ${HTRDR_FILES_INC} ${HTRDR_FILES_INC2}) -target_link_libraries(htrdr AW HTSky MruMtl RSys Star3D StarSF StarSP) - -if(CMAKE_COMPILER_IS_GNUCC) - target_link_libraries(htrdr m) - set_target_properties(htrdr PROPERTIES LINK_FLAGS "${OpenMP_C_FLAGS}") -endif() - -set_target_properties(htrdr PROPERTIES - COMPILE_FLAGS "${OpenMP_C_FLAGS}" - VERSION ${VERSION} - SOVERSION ${VERSION_MAJOR}) - -################################################################################ # Define output & install directories ################################################################################ -install(TARGETS htrdr - ARCHIVE DESTINATION bin - LIBRARY DESTINATION lib - RUNTIME DESTINATION bin) +set(HTRDR_FILES_DOC + ${PROJECT_SOURCE_DIR}/../COPYING + ${PROJECT_SOURCE_DIR}/../README.md) install(FILES ${HTRDR_FILES_DOC} DESTINATION share/doc/htrdr) diff --git a/cmake/core/CMakeLists.txt b/cmake/core/CMakeLists.txt @@ -0,0 +1,143 @@ +# Copyright (C) 2018, 2019, 2020 |Meso|Star> (contact@meso-star.com) +# Copyright (C) 2018, 2019 CNRS, Université Paul Sabatier +# +# 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/>. + +cmake_minimum_required(VERSION 2.8) +project(htrdr-core C) + +message(STATUS "${HTRDR_SOURCE_DIR}") + +################################################################################ +# Check dependencies +################################################################################ +find_package(AW 2.0 REQUIRED) +find_package(MruMtl 0.0 REQUIRED) +find_package(RCMake 0.3 REQUIRED) +find_package(RSys 0.11 REQUIRED) +find_package(Star3D 0.7.1 REQUIRED) +find_package(StarSF 0.6 REQUIRED) +find_package(StarSP 0.8 REQUIRED) +find_package(OpenMP 1.2 REQUIRED) +find_package(MPI 1 REQUIRED) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR}) +include(rcmake) +include(rcmake_runtime) + +set(CMAKE_C_COMPILER ${MPI_C_COMPILER}) + +include_directories( + ${AW_INCLUDE_DIR} + ${MruMtl_INCLUDE_DIR} + ${RSys_INCLUDE_DIR} + ${Star3D_INCLUDE_DIR} + ${StarSF_INCLUDE_DIR} + ${StarSP_INCLUDE_DIR} + ${StarVX_INCLUDE_DIR} + ${HTSky} + ${HTRDR_SOURCE_DIR}/core + ${MPI_INCLUDE_PATH} + ${CMAKE_CURRENT_BINARY_DIR}) + +################################################################################ +# Generate files +################################################################################ +set(HTRDR_ARGS_DEFAULT_CAMERA_POS "0,0,0") +set(HTRDR_ARGS_DEFAULT_CAMERA_TGT "0,1,0") +set(HTRDR_ARGS_DEFAULT_CAMERA_UP "0,0,1") +set(HTRDR_ARGS_DEFAULT_CAMERA_FOV "70") +set(HTRDR_ARGS_DEFAULT_RECTANGLE_POS "0,0,0") +set(HTRDR_ARGS_DEFAULT_RECTANGLE_TGT "0,0,1") +set(HTRDR_ARGS_DEFAULT_RECTANGLE_UP "0,1,0") +set(HTRDR_ARGS_DEFAULT_RECTANGLE_SZ "1,1") +set(HTRDR_ARGS_DEFAULT_IMG_WIDTH "320") +set(HTRDR_ARGS_DEFAULT_IMG_HEIGHT "240") +set(HTRDR_ARGS_DEFAULT_IMG_SPP "1") + +configure_file(${HTRDR_SOURCE_DIR}/core/htrdr_args.h.in + ${CMAKE_CURRENT_BINARY_DIR}/htrdr_args.h @ONLY) +configure_file(${HTRDR_SOURCE_DIR}/core/htrdr_version.h.in + ${CMAKE_CURRENT_BINARY_DIR}/htrdr_version.h @ONLY) + +################################################################################ +# Configure and define targets +################################################################################ +set(HTRDR_CORE_FILES_SRC + htrdr_args.c + htrdr_buffer.c + htrdr.c + htrdr_camera.c + htrdr_cie_xyz.c + htrdr_draw_map.c + htrdr_log.c + htrdr_materials.c + htrdr_ran_wlen.c + htrdr_rectangle.c + htrdr_slab.c + htrdr_spectral.c) +set(HTRDR_CORE_FILES_INC + htrdr_accum.h + htrdr_buffer.h + htrdr_camera.h + htrdr_c.h + htrdr_cie_xyz.h + htrdr_draw_map.h + htrdr.h + htrdr_interface.h + htrdr_log.h + htrdr_materials.h + htrdr_ran_wlen.h + htrdr_rectangle.h + htrdr_sensor.h + htrdr_slab.h + htrdr_spectral.h) +set(HTRDR_CORE_FILES_INC2 # Generated files + htrdr_args.h + htrdr_version.h) + +# Prepend each file in the `HTRDR_FILES_<SRC|INC>' list by `HTRDR_SOURCE_DIR' +rcmake_prepend_path(HTRDR_CORE_FILES_SRC ${HTRDR_SOURCE_DIR}/core) +rcmake_prepend_path(HTRDR_CORE_FILES_INC ${HTRDR_SOURCE_DIR}/core) +rcmake_prepend_path(HTRDR_CORE_FILES_INC2 ${CMAKE_CURRENT_BINARY_DIR}) + +# Core library +add_library(htrdr-core SHARED + ${HTRDR_CORE_FILES_SRC} + ${HTRDR_CORE_FILES_INC} + ${HTRDR_CORE_FILES_INC2}) +target_link_libraries(htrdr-core AW MruMtl RSys Star3D StarSF StarSP) + +if(CMAKE_COMPILER_IS_GNUCC) + target_link_libraries(htrdr-core m) + set_target_properties(htrdr-core PROPERTIES LINK_FLAGS "${OpenMP_C_FLAGS}") +endif() + +set_target_properties(htrdr-core PROPERTIES + COMPILE_FLAGS "${OpenMP_C_FLAGS}" + DEFINE_SYMBOL HTRDR_SHARED_BUILD + VERSION ${VERSION} + SOVERSION ${VERSION_MAJOR}) + +# Main command +add_executable(htrdr ${HTRDR_SOURCE_DIR}/core/htrdr_main.c) + +################################################################################ +# Define output & install directories +################################################################################ +install(TARGETS htrdr htrdr-core + ARCHIVE DESTINATION bin + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) + diff --git a/src/atmosphere/htrdr_atmosphere.c b/src/atmosphere/htrdr_atmosphere.c @@ -38,6 +38,72 @@ static const struct pixel_format PIXEL_FORMAT_NULL = PIXEL_FORMAT_NULL__; /******************************************************************************* * Helper functions ******************************************************************************/ +static double +compute_sky_min_band_len(struct htsky* sky, const double range[2]) +{ + double min_band_len = DBL_MAX; + size_t nbands; + ASSERT(sky && range && range[0] <= range[1]); + + nbands = htsky_get_spectral_bands_count(sky); + + if(eq_eps(range[0], range[1], 1.e-6)) { + ASSERT(nbands == 1); + min_band_len = 0; + } else { + size_t i = 0; + + /* Compute the length of the current band clamped to the submitted range */ + FOR_EACH(i, 0, nbands) { + const size_t iband = htsky_get_spectral_band_id(sky, i); + double wlens[2]; + HTSKY(get_spectral_band_bounds(sky, iband, wlens)); + + /* Adjust band boundaries to the submitted range */ + wlens[0] = MMAX(wlens[0], range[0]); + wlens[1] = MMIN(wlens[1], range[1]); + + min_band_len = MMIN(wlens[1] - wlens[0], min_band_len); + } + } + return min_band_len; +} + +/* Compute the number of fixed size bands used to discretized the spectral + * range */ +static size_t +compute_spectral_bands_count(const struct htrdr_atmosphere* cmd) +{ + double wlen_range[2]; + double wlen_size; + const size_t nbands; + const double band_len; + const double band_len_max; + ASSERT(cmd); + + /* Compute size of the spectral range in nanometers */ + wlen_range[0] = cmd->wlen_range_m[0]*1.e9; + wlen_range[1] = cmd->wlen_range_m[1]*1.e9; + wlen_range_size = wlen_range[1] - wlen_range[0]; + + /* Define as many intervals as wavelengths count in the spectral range */ + nbands = (size_t)rint(wlen_range_size); + + /* Compute the size in nanometers of an interval */ + band_len = wlen_range_size / (double)nbands; + + /* Compute the minimum band length of the sky spectral data and define it + * as the maximum length that the bands can have */ + band_len_max = compute_sky_min_band_len(cmd->sky, wlen_range); + + /* Adjust the bands count to ensure that each sky spectral interval is + * overlapped by at least one band */ + if(band_len > band_len_max) { + nbands = (size_t)ceil(wlen_range_size / band_len_max); + } + return nbands +} + static enum htsky_spectral_type htrdr_to_sky_spectral_type(const enum htrdr_spectral_type type) { @@ -347,6 +413,7 @@ htrdr_atmosphere_create double sun_dir[3]; double spectral_range[2]; const char* output_name = NULL; + size_t nintervals; /* #bands used to discretized the spectral curve */ res_T res = RES_OK; ASSERT(htrdr && args && out_cmd); @@ -451,27 +518,22 @@ htrdr_atmosphere_create cmd->wlen_range_m[0] = spectral_range[0]*1e-9; /* Convert in meters */ cmd->wlen_range_m[1] = spectral_range[1]*1e-9; /* Convert in meters */ + /* Compute the number of fixed sized bands used to descrised to the spectral + * data */ + nintervals = compute_spectral_bands_count(cmd); + if(cmd->spectral_type == HTRDR_SPECTRAL_SW_CIE_XYZ) { - size_t n; - n = (size_t)(spectral_range[1] - spectral_range[0]); - res = htrdr_cie_xyz_create(htrdr, spectral_range, n, &cmd->cie); + res = htrdr_cie_xyz_create(htrdr, spectral_range, nintervals, &cmd->cie); if(res != RES_OK) goto error; - } else { - size_t n; - if(cmd->ref_temperature <= 0) { htrdr_log_err(htrdr, "%s: invalid reference temperature %g K.\n", FUNC_NAME, cmd->ref_temperature); res = RES_BAD_ARG; goto error; } - - ASSERT(cmd->wlen_range_m[0] <= cmd->wlen_range_m[1]); - n = (size_t)(spectral_range[1] - spectral_range[0]); - res = htrdr_ran_wlen_create - (htrdr, spectral_range, n, cmd->ref_temperature, &cmd->ran_wlen); + (htrdr, spectral_range, nintervals, cmd->ref_temperature, &cmd->ran_wlen); if(res != RES_OK) goto error; } diff --git a/src/core/htrdr.c b/src/core/htrdr.c @@ -237,7 +237,7 @@ error: goto exit; } -void +static void release_htrdr(ref_T* ref) { struct htrdr* htrdr = CONTAINER_OF(ref, struct htrdr, ref); @@ -251,7 +251,6 @@ release_htrdr(ref_T* ref) } MEM_RM(htrdr->allocator, htrdr->lifo_allocators); } - str_release(&htrdr->output_name); logger_release(&htrdr->logger); MEM_RM(htrdr->allocator, htrdr); @@ -264,6 +263,7 @@ res_T htrdr_mpi_init(int argc, char** argv) { char str[MPI_MAX_ERROR_STRING]; + int thread_support; int len; int err = 0; res_T res = RES_OK; @@ -290,7 +290,7 @@ error: goto exit; } -res_T +void htrdr_mpi_finalize(void) { MPI_Finalize(); @@ -323,10 +323,7 @@ htrdr_create htrdr->verbose = args->verbose; htrdr->nthreads = MMIN(args->nthreads, (unsigned)nthreads_max); - logger_init(htrdr->allocator, &htrdr->logger); - logger_set_stream(&htrdr->logger, LOG_OUTPUT, print_out, NULL); - logger_set_stream(&htrdr->logger, LOG_ERROR, print_err, NULL); - logger_set_stream(&htrdr->logger, LOG_WARNING, print_warn, NULL); + setup_logger(htrdr); res = init_mpi(htrdr); if(res != RES_OK) goto error; @@ -388,7 +385,7 @@ size_t htrdr_get_procs_count(const struct htrdr* htrdr) { ASSERT(htrdr); - return htrdr->mpi_nprocs; + return (size_t)htrdr->mpi_nprocs; } int @@ -399,17 +396,31 @@ htrdr_get_mpi_rank(const struct htrdr* htrdr) } struct mem_allocator* -htrdr_get_allocator(const struct htrdr* htrdr) +htrdr_get_allocator(struct htrdr* htrdr) { ASSERT(htrdr); return htrdr->allocator; } struct mem_allocator* -htrdr_get_lifo_allocator(const struct htrdr* htrdr, const unsigned ithread) +htrdr_get_thread_allocator(struct htrdr* htrdr, const size_t ithread) { ASSERT(htrdr && ithread < htrdr_get_threads_count(htrdr)); - return htrdr->lifo_allocators[ithread]; + return htrdr->lifo_allocators + ithread; +} + +struct logger* +htrdr_get_logger(struct htrdr* htrdr) +{ + ASSERT(htrdr); + return &htrdr->logger; +} + +int +htrdr_get_verbosity_level(const struct htrdr* htrdr) +{ + ASSERT(htrdr); + return htrdr->verbose; } const char* @@ -505,39 +516,6 @@ htrdr_fflush(struct htrdr* htrdr, FILE* stream) /******************************************************************************* * Local functions ******************************************************************************/ -double -compute_sky_min_band_len - (struct htsky* sky, - const double range[2]) -{ - double min_band_len = DBL_MAX; - size_t nbands; - ASSERT(sky && range && range[0] <= range[1]); - - nbands = htsky_get_spectral_bands_count(sky); - - if(eq_eps(range[0], range[1], 1.e-6)) { - ASSERT(nbands == 1); - min_band_len = 0; - } else { - size_t i = 0; - - /* Compute the length of the current band clamped to the submitted range */ - FOR_EACH(i, 0, nbands) { - const size_t iband = htsky_get_spectral_band_id(sky, i); - double wlens[2]; - HTSKY(get_spectral_band_bounds(sky, iband, wlens)); - - /* Adjust band boundaries to the submitted range */ - wlens[0] = MMAX(wlens[0], range[0]); - wlens[1] = MMIN(wlens[1], range[1]); - - min_band_len = MMIN(wlens[1] - wlens[0], min_band_len); - } - } - return min_band_len; -} - void send_mpi_progress (struct htrdr* htrdr, const enum htrdr_mpi_message msg, int32_t percent) diff --git a/src/core/htrdr.h b/src/core/htrdr.h @@ -39,6 +39,7 @@ #endif /* Forward declarations */ +struct htrdr_buffer; struct mem_allocator; struct mutex; @@ -82,7 +83,7 @@ htrdr_mpi_init char** argv); /* Terminate the MPI execution environment */ -HTRDR_API res_T +HTRDR_API void htrdr_mpi_finalize (void); @@ -103,12 +104,6 @@ HTRDR_API void htrdr_ref_put (struct htrdr* htrdr); -HTRDR_API void -htrdr_draw_map - (struct htrdr* htrdr, - const struct htrdr_draw_map_args* args, - struct htrdr_buffer* buffer); - /* Return the number of threads used by the process */ HTRDR_API size_t htrdr_get_threads_count @@ -117,7 +112,7 @@ htrdr_get_threads_count /* Return the number of running processes for the current htrdr instance */ HTRDR_API size_t htrdr_get_procs_count - (const struct + (const struct htrdr* htrdr); HTRDR_API int htrdr_get_mpi_rank @@ -125,13 +120,21 @@ htrdr_get_mpi_rank HTRDR_API struct mem_allocator* htrdr_get_allocator - (const struct htrdr* htrdr); + (struct htrdr* htrdr); HTRDR_API struct mem_allocator* -htrdr_get_lifo_allocator - (const struct htrdr* htrdr, +htrdr_get_thread_allocator + (struct htrdr* htrdr, const size_t ithread); +HTRDR_API struct logger* +htrdr_get_logger + (struct htrdr* htrdr); + +HTRDR_API int +htrdr_get_verbosity_level + (const struct htrdr* htrdr); + HTRDR_API res_T htrdr_open_output_stream (struct htrdr* htrdr, diff --git a/src/core/htrdr_args.c b/src/core/htrdr_args.c @@ -75,9 +75,10 @@ parse_fov(const char* str, double* out_fov) } static res_T -parse_image_parameter(struct htrdr_args_image* img, const char* str) +parse_image_parameter(void* args, const char* str) { char buf[128]; + struct htrdr_args_image* img = args; char* key; char* val; char* ctx; @@ -136,14 +137,15 @@ error: } static res_T -parse_camera_parameter(struct htrdr_args_camera* cam, const char* str) +parse_camera_parameter(void* args, const char* str) { char buf[128]; + struct htrdr_args_camera* cam = args; char* key; char* val; char* ctx; res_T res = RES_OK; - ASSERT(cam); + ASSERT(cam && str); if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { fprintf(stderr, @@ -175,7 +177,7 @@ parse_camera_parameter(struct htrdr_args_camera* cam, const char* str) } else if(!strcmp(key, "up")) { PARSE("up vector", parse_doubleX(val, cam->up, 3)); } else if(!strcmp(key, "fov")) { - PARSE("field-of-view", parse_fov(val, cam->fov_y)); + PARSE("field-of-view", parse_fov(val, &cam->fov_y)); } else { fprintf(stderr, "Invalid camera parameter `%s'.\n", key); res = RES_BAD_ARG; @@ -189,14 +191,15 @@ error: } static res_T -parse_rectangle_parameter(struct htrdr_args_rectangle* rect, const char* str) +parse_rectangle_parameter(void* args, const char* str) { char buf[128]; + struct htrdr_args_rectangle* rect = args; char* key; char* val; char* ctx; res_T res = RES_OK; - ASSERT(rect); + ASSERT(rect && str); if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { fprintf(stderr, @@ -239,7 +242,7 @@ parse_rectangle_parameter(struct htrdr_args_rectangle* rect, const char* str) exit: return res; error: - goto EXIT; + goto exit; } static res_T @@ -267,14 +270,15 @@ error: } static res_T -parse_spectral_parameter(struct htrdr_args_spectral* args, const char* str) +parse_spectral_parameter(void* ptr, const char* str) { char buf[128]; + struct htrdr_args_spectral* args = ptr; char* key; char* val; char* ctx; res_T res = RES_OK; - ASSERT(args); + ASSERT(args && str); if(strlen(str) >= sizeof(buf) -1/*NULL char*/) { fprintf(stderr, @@ -327,9 +331,9 @@ error: static res_T parse_multiple_parameters - (struct htrdr_args* args, + (void* args, const char* str, - res_T (*parse_parameter)(struct htrdr_args* args, const char* str)) + res_T (*parse_parameter)(void* args, const char* str)) { char buf[512]; char* tk; @@ -358,62 +362,33 @@ error: } /******************************************************************************* - * Local functions + * Exported functions ******************************************************************************/ res_T -htrdr_args_init(struct htrdr_args* args, int argc, char** argv) +htrdr_args_camera_parse(struct htrdr_args_camera* cam, const char* str) { - res_T res = RES_OK; - ASSERT(args && argc && argv); - *args = HTRDR_ARGS_DEFAULT; - - /* Atmosphere mode */ - if(!strcmp(argv[1], "atmosphere")) { - args->mode_type = HTRDR_ATMOSPHERE; - res = parse_atmosphere_options(args, argc, argv); - if(res != RES_OK) goto error; - - /* Combustion mode */ - } else if(!strcmp(argv[1], "combustion")) { - args->mode_type = HTRDR_COMBUSTION; - res = parse_combustion_options(args, argc, argv); - if(res != RES_OK) goto error; - - /* Version */ - } else if(!strcmp(argv[1], "--version")) { - printf("%s version %d.%d.%d\n", - argv[0], - HTRDR_VERSION_MAJOR, - HTRDR_VERSION_MINOR, - HTRDR_VERSION_PATCH); - args->quit = 1; - goto exit; - - /* Help */ - } else if(!strcmp(argv[1], "--help")) { - print_usage(argv[0]); - args->quit = 1; - goto exit; - - /* Fallback */ - } else { - fprintf(stderr, "Unknown option: %s\n", argv[1]); - print_usage(argv[0]); - res = RES_BAD_ARG; - goto error; - } + if(!cam || !str) return RES_BAD_ARG; + return parse_multiple_parameters(cam, str, parse_camera_parameter); +} -exit: - return res; -error: - htrdr_args_release(args); - goto exit; +res_T +htrdr_args_rectangle_parse(struct htrdr_args_rectangle* rect, const char* str) +{ + if(!rect || !str) return RES_BAD_ARG; + return parse_multiple_parameters(rect, str, parse_rectangle_parameter); +} + +res_T +htrdr_args_image_parse(struct htrdr_args_image* img, const char* str) +{ + if(!img || !str) return RES_BAD_ARG; + return parse_multiple_parameters(img, str, parse_image_parameter); } -void -htrdr_args_release(struct htrdr_args* args) +res_T +htrdr_args_spectral_parse(struct htrdr_args_spectral* spectral, const char* str) { - ASSERT(args); - *args = HTRDR_ARGS_DEFAULT; + if(!spectral || !str) return RES_BAD_ARG; + return parse_multiple_parameters(spectral, str, parse_spectral_parameter); } diff --git a/src/core/htrdr_args.h b/src/core/htrdr_args.h @@ -1,106 +0,0 @@ -/* Copyright (C) 2018, 2019, 2020, 2021 |Meso|Star> (contact@meso-star.com) - * Copyright (C) 2018, 2019, 2021 CNRS - * Copyright (C) 2018, 2019, Université Paul Sabatier - * - * 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 HTRDR_ARGS_H -#define HTRDR_ARGS_H - -#include "htrdr_cie_xyz.h" - -#include <rsys/rsys.h> - -/* Arguments of a pinhole camera sensor */ -struct htrdr_args_camera { - double position[3]; /* Focal point */ - double target[3]; /* Targeted position */ - double up[3]; /* Up vector of the camera */ - double fov_y; /* Vertical field of view of the camera, in degrees */ -}; -#define HTRDR_ARGS_CAMERA_DEFAULT__ { \ - {@HTRDR_ARGS_DEFAULT_CAMERA_POS@}, /* position */ \ - {@HTRDR_ARGS_DEFAULT_CAMERA_TGT@}, /* target */ \ - {@HTRDR_ARGS_DEFAULT_CAMERA_UP@}, /* Camera up */ \ - @HTRDR_ARGS_DEFAULT_CAMERA_FOV@, /* Vertical field of view */ \ -} -static const struct htrdr_args_camera HTRDR_ARGS_CAMERA_DEFAULT = - HTRDR_ARGS_CAMERA_DEFAULT__; - -/* Arguments of a rectangular sensor */ -struct htrdr_args_rectangle { - double position[3]; /* Center of the renctangle */ - double target[3]; /* Targeted point (rectangle.normal = target - position) */ - double up[3]; /* Up vector of the rectangle */ - double size[2]; /* Plane size */ -}; -#define HTRDR_ARGS_RECTANGLE_DEFAULT__ { \ - {@HTRDR_ARGS_DEFAULT_RECTANGLE_POS@}, /* Rectangle center */ \ - {@HTRDR_ARGS_DEFAULT_RECTANGLE_TGT@}, /* Rectangle target */ \ - {@HTRDR_ARGS_DEFAULT_RECTANGLE_UP@}, /* Rectangle up */ \ - {@HTRDR_ARGS_DEFAULT_RECTANGLE_SZ@}, /* Rectangle size */ \ -} -static const struct htrdr_args_rectangle HTRDR_ARGS_RECTANGLE_DEFAULT = - HTRDR_ARGS_RECTANGLE_DEFAULT__; - -/* Arguments of an image */ -struct htrdr_args_image { - unsigned definition[2]; /* #pixels in X and Y */ - unsigned spp; /* #samples per pixel */ -}; -#define HTRDR_ARGS_IMAGE_DEFAULT__ { \ - {@HTRDR_ARGS_DEFAULT_IMG_WIDTH@, @HTRDR_ARGS_DEFAULT_IMG_HEIGHT@}, \ - @HTRDR_ARGS_DEFAULT_IMG_SPP@ \ -} -static const struct htrdr_args_image HTRDR_ARGS_IMAGE_DEFAULT = - HTRDR_ARGS_IMAGE_DEFAULT__; - -/* Arguments of the spectral domain */ -struct htrdr_args_spectral { - double wlen_range[2]; /* Spectral range of integration in nm */ - double ref_temperature; /* Planck reference temperature in Kelvin */ - enum htrdr_spectral_type spectral_type; -}; -#define HTRDR_ARGS_SPECTRAL_DEFAULT__ { \ - HTRDR_CIE_XYZ_RANGE_DEFAULT__, /* Spectral range */ \ - -1, /* Reference temperature */ \ - HTRDR_SPECTRAL_SW_CIE_XYZ, /* Spectral type */ \ -} -static const struct htrdr_args_spectral HTRDR_ARGS_SPECTRAL_DEFAULT = - HTRDR_ARGS_SPECTRAL_DEFAULT__; - -/******************************************************************************* - * Exported functions - ******************************************************************************/ -HTRDR_API res_T -htrdr_args_camera_parse - (struct htrdr_args_camera* cam, - const char* str); - -HTRDR_API res_T -htrdr_args_rectangle_parse - (struct htrdr_args_rectangle* rect, - const char* str); - -HTRDR_API res_T -htrdr_args_image_parse - (struct htrdr_args_image* img, - const char* str); - -HTRDR_API res_T -htrdr_args_spectral_parse - (struct htrdr_args_spectral* spectral, - const char* str); - -#endif /* HTRDR_ARGS_H */ diff --git a/src/core/htrdr_args.h.in b/src/core/htrdr_args.h.in @@ -0,0 +1,107 @@ +/* Copyright (C) 2018, 2019, 2020, 2021 |Meso|Star> (contact@meso-star.com) + * Copyright (C) 2018, 2019, 2021 CNRS + * Copyright (C) 2018, 2019, Université Paul Sabatier + * + * 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 HTRDR_ARGS_H +#define HTRDR_ARGS_H + +#include "htrdr_cie_xyz.h" +#include "htrdr_spectral.h" + +#include <rsys/rsys.h> + +/* Arguments of a pinhole camera sensor */ +struct htrdr_args_camera { + double position[3]; /* Focal point */ + double target[3]; /* Targeted position */ + double up[3]; /* Up vector of the camera */ + double fov_y; /* Vertical field of view of the camera, in degrees */ +}; +#define HTRDR_ARGS_CAMERA_DEFAULT__ { \ + {@HTRDR_ARGS_DEFAULT_CAMERA_POS@}, /* position */ \ + {@HTRDR_ARGS_DEFAULT_CAMERA_TGT@}, /* target */ \ + {@HTRDR_ARGS_DEFAULT_CAMERA_UP@}, /* Camera up */ \ + @HTRDR_ARGS_DEFAULT_CAMERA_FOV@, /* Vertical field of view */ \ +} +static const struct htrdr_args_camera HTRDR_ARGS_CAMERA_DEFAULT = + HTRDR_ARGS_CAMERA_DEFAULT__; + +/* Arguments of a rectangular sensor */ +struct htrdr_args_rectangle { + double position[3]; /* Center of the renctangle */ + double target[3]; /* Targeted point (rectangle.normal = target - position) */ + double up[3]; /* Up vector of the rectangle */ + double size[2]; /* Plane size */ +}; +#define HTRDR_ARGS_RECTANGLE_DEFAULT__ { \ + {@HTRDR_ARGS_DEFAULT_RECTANGLE_POS@}, /* Rectangle center */ \ + {@HTRDR_ARGS_DEFAULT_RECTANGLE_TGT@}, /* Rectangle target */ \ + {@HTRDR_ARGS_DEFAULT_RECTANGLE_UP@}, /* Rectangle up */ \ + {@HTRDR_ARGS_DEFAULT_RECTANGLE_SZ@}, /* Rectangle size */ \ +} +static const struct htrdr_args_rectangle HTRDR_ARGS_RECTANGLE_DEFAULT = + HTRDR_ARGS_RECTANGLE_DEFAULT__; + +/* Arguments of an image */ +struct htrdr_args_image { + unsigned definition[2]; /* #pixels in X and Y */ + unsigned spp; /* #samples per pixel */ +}; +#define HTRDR_ARGS_IMAGE_DEFAULT__ { \ + {@HTRDR_ARGS_DEFAULT_IMG_WIDTH@, @HTRDR_ARGS_DEFAULT_IMG_HEIGHT@}, \ + @HTRDR_ARGS_DEFAULT_IMG_SPP@ \ +} +static const struct htrdr_args_image HTRDR_ARGS_IMAGE_DEFAULT = + HTRDR_ARGS_IMAGE_DEFAULT__; + +/* Arguments of the spectral domain */ +struct htrdr_args_spectral { + double wlen_range[2]; /* Spectral range of integration in nm */ + double ref_temperature; /* Planck reference temperature in Kelvin */ + enum htrdr_spectral_type spectral_type; +}; +#define HTRDR_ARGS_SPECTRAL_DEFAULT__ { \ + HTRDR_CIE_XYZ_RANGE_DEFAULT__, /* Spectral range */ \ + -1, /* Reference temperature */ \ + HTRDR_SPECTRAL_SW_CIE_XYZ, /* Spectral type */ \ +} +static const struct htrdr_args_spectral HTRDR_ARGS_SPECTRAL_DEFAULT = + HTRDR_ARGS_SPECTRAL_DEFAULT__; + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +HTRDR_API res_T +htrdr_args_camera_parse + (struct htrdr_args_camera* cam, + const char* str); + +HTRDR_API res_T +htrdr_args_rectangle_parse + (struct htrdr_args_rectangle* rect, + const char* str); + +HTRDR_API res_T +htrdr_args_image_parse + (struct htrdr_args_image* img, + const char* str); + +HTRDR_API res_T +htrdr_args_spectral_parse + (struct htrdr_args_spectral* spectral, + const char* str); + +#endif /* HTRDR_ARGS_H */ diff --git a/src/core/htrdr_buffer.c b/src/core/htrdr_buffer.c @@ -16,7 +16,9 @@ #include "htrdr.h" #include "htrdr_buffer.h" +#include "htrdr_log.h" +#include <rsys/math.h> #include <rsys/mem_allocator.h> #include <rsys/ref_count.h> @@ -43,8 +45,8 @@ buffer_release(ref_T* ref) struct htrdr* htrdr = NULL; ASSERT(ref); buf = CONTAINER_OF(ref, struct htrdr_buffer, ref); - if(buf->mem) MEM_RM(buf->htrdr->allocator, buf->mem); htrdr = buf->htrdr; + if(buf->mem) MEM_RM(htrdr_get_allocator(htrdr), buf->mem); MEM_RM(htrdr_get_allocator(htrdr), buf); htrdr_ref_put(htrdr); } @@ -110,7 +112,7 @@ htrdr_buffer_create buf->htrdr = htrdr; memsz = buf->pitch * buf->height; - buf->mem = MEM_ALLOC_ALIGNED(htrdr->allocator, memsz, align); + buf->mem = MEM_ALLOC_ALIGNED(htrdr_get_allocator(htrdr), memsz, align); if(!buf->mem) { res = RES_MEM_ERR; goto error; diff --git a/src/core/htrdr_c.h b/src/core/htrdr_c.h @@ -58,78 +58,12 @@ struct htrdr { ref_T ref; }; -/* In nanometer */ -static FINLINE double -wavenumber_to_wavelength(const double nu/*In cm^-1*/) -{ - return 1.e7 / nu; -} - -/* In cm^-1 */ -static FINLINE double -wavelength_to_wavenumber(const double lambda/*In nanometer*/) -{ - return wavenumber_to_wavelength(lambda); -} - -static INLINE uint64_t -morton3D_encode_u21(const uint32_t u21) -{ - uint64_t u64 = u21 & ((1<<21) - 1); - ASSERT(u21 <= ((1 << 21) - 1)); - u64 = (u64 | (u64 << 32)) & 0xFFFF00000000FFFF; - u64 = (u64 | (u64 << 16)) & 0x00FF0000FF0000FF; - u64 = (u64 | (u64 << 8)) & 0xF00F00F00F00F00F; - u64 = (u64 | (u64 << 4)) & 0x30C30C30C30C30C3; - u64 = (u64 | (u64 << 2)) & 0x9249249249249249; - return u64; -} - -static INLINE uint32_t -morton3D_decode_u21(const uint64_t u64) -{ - uint64_t tmp = (u64 & 0x9249249249249249); - tmp = (tmp | (tmp >> 2)) & 0x30C30C30C30C30C3; - tmp = (tmp | (tmp >> 4)) & 0xF00F00F00F00F00F; - tmp = (tmp | (tmp >> 8)) & 0x00FF0000FF0000FF; - tmp = (tmp | (tmp >> 16)) & 0xFFFF00000000FFFF; - tmp = (tmp | (tmp >> 32)) & 0x00000000FFFFFFFF; - ASSERT(tmp <= ((1<<21)-1)); - return (uint32_t)tmp; -} - -static INLINE uint64_t -morton_xyz_encode_u21(const uint32_t xyz[3]) -{ - return (morton3D_encode_u21(xyz[0]) << 2) - | (morton3D_encode_u21(xyz[1]) << 1) - | (morton3D_encode_u21(xyz[2]) << 0); -} - -static INLINE void -morton_xyz_decode_u21(const uint64_t code, uint32_t xyz[3]) -{ - ASSERT(xyz && code < ((1ull << 63)-1)); - xyz[0] = (uint32_t)morton3D_decode_u21(code >> 2); - xyz[1] = (uint32_t)morton3D_decode_u21(code >> 1); - xyz[2] = (uint32_t)morton3D_decode_u21(code >> 0); -} +extern LOCAL_SYM void +setup_logger + (struct htrdr* htrdr); /* Return the minimum length in nanometer of the sky spectral bands * clamped to in [range[0], range[1]]. */ -extern LOCAL_SYM double -compute_sky_min_band_len - (struct htsky* sky, - const double range[2]); - -extern LOCAL_SYM res_T -open_output_stream - (struct htrdr* htrdr, - const char* filename, - const int read, /* Enable read access */ - int force_overwrite, - FILE** out_fp); - extern LOCAL_SYM void send_mpi_progress (struct htrdr* htrdr, diff --git a/src/core/htrdr_camera.c b/src/core/htrdr_camera.c @@ -16,6 +16,7 @@ #include "htrdr.h" #include "htrdr_camera.h" +#include "htrdr_log.h" #include <rsys/double3.h> #include <rsys/mem_allocator.h> diff --git a/src/core/htrdr_cie_xyz.c b/src/core/htrdr_cie_xyz.c @@ -16,7 +16,9 @@ #define _POSIX_C_SOURCE 200112L /* nextafter */ #include "htrdr.h" +#include "htrdr_c.h" #include "htrdr_cie_xyz.h" +#include "htrdr_log.h" #include <high_tune/htsky.h> @@ -293,11 +295,10 @@ res_T htrdr_cie_xyz_create (struct htrdr* htrdr, const double range[2], /* Must be included in [380, 780] nanometers */ - const size_t bands_count, /* # bands used to discretisze the CIE tristimulus */ + const size_t bands_count, /* # bands used to discretize the CIE tristimulus */ struct htrdr_cie_xyz** out_cie) { struct htrdr_cie_xyz* cie = NULL; - double min_band_len = 0; size_t nbands = bands_count; res_T res = RES_OK; ASSERT(htrdr && range && nbands && out_cie); @@ -311,25 +312,16 @@ htrdr_cie_xyz_create goto error; } ref_init(&cie->ref); - darray_double_init(htrdr->allocator, &cie->cdf_X); - darray_double_init(htrdr->allocator, &cie->cdf_Y); - darray_double_init(htrdr->allocator, &cie->cdf_Z); + darray_double_init(htrdr_get_allocator(htrdr), &cie->cdf_X); + darray_double_init(htrdr_get_allocator(htrdr), &cie->cdf_Y); + darray_double_init(htrdr_get_allocator(htrdr), &cie->cdf_Z); cie->range[0] = range[0]; cie->range[1] = range[1]; htrdr_ref_get(htrdr); cie->htrdr = htrdr; - min_band_len = compute_sky_min_band_len(cie->htrdr->sky, range); cie->band_len = (range[1] - range[0]) / (double)nbands; - /* Adjust the band length to ensure that each sky spectral interval is - * overlapped by at least one band */ - if(cie->band_len > min_band_len) { - cie->band_len = min_band_len; - nbands = (size_t)ceil((range[1] - range[0]) / cie->band_len); - printf("%lu\n", nbands); - } - res = setup_cie_xyz(cie, FUNC_NAME, nbands); if(res != RES_OK) goto error; diff --git a/src/core/htrdr_draw_map.c b/src/core/htrdr_draw_map.c @@ -14,27 +14,23 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define _POSIX_C_SOURCE 200112L /* nanosleep && nextafter */ +#define _POSIX_C_SOURCE 200112L /* nanosleep */ #include "htrdr.h" #include "htrdr_c.h" #include "htrdr_buffer.h" -#include "htrdr_camera.h" -#include "htrdr_cie_xyz.h" #include "htrdr_draw_map.h" -#include "htrdr_ran_wlen.h" -#include "htrdr_rectangle.h" -#include "htrdr_solve.h" -#include "htrdr_sun.h" +#include "htrdr_log.h" -#include <high_tune/htsky.h> - -#include <rsys/algorithm.h> #include <rsys/clock_time.h> #include <rsys/cstr.h> #include <rsys/dynamic_array_u32.h> +#include <rsys/list.h> #include <rsys/math.h> +#include <rsys/morton.h> #include <rsys/mutex.h> +#include <rsys/ref_count.h> + #include <star/ssp.h> #include <omp.h> @@ -48,18 +44,6 @@ #define TILE_SIZE 32 /* Definition in X & Y of a tile */ STATIC_ASSERT(IS_POW2(TILE_SIZE), TILE_SIZE_must_be_a_power_of_2); -enum pixel_format { - PIXEL_FLUX, - PIXEL_IMAGE, - PIXEL_XWAVE -}; - -union pixel { - struct htrdr_pixel_flux flux; - struct htrdr_pixel_xwave xwave; - struct htrdr_pixel_image image; -}; - /* Tile of row ordered image pixels */ struct tile { struct list_node node; @@ -124,7 +108,7 @@ tile_create const size_t buf_sz = TILE_SIZE*TILE_SIZE*pixel_size; ASSERT(allocator); ASSERT(IS_ALIGNED(pixel_size, pixel_alignment)); - ASSERT(is_pow2(pixel_alignment)); + ASSERT(IS_POW2(pixel_alignment)); tile = MEM_ALLOC_ALIGNED(allocator, tile_sz + buf_sz, 16); if(!tile) goto error; @@ -147,20 +131,19 @@ error: goto exit; } -static FINLINE union pixel* +static FINLINE void* tile_at (struct tile* tile, const size_t x, /* In tile space */ const size_t y) /* In tile space */ { ASSERT(tile && x < TILE_SIZE && y < TILE_SIZE); - return tile->data.pixels + (y*TILE_SIZE + x)*tile->data.pixsz; + return (void*)(tile->data.pixels + (y*TILE_SIZE + x)*tile->data.pixsz); } static void write_tile_data (struct htrdr* htrdr, - const struct htrdr_sensor* sensor, struct htrdr_buffer* buf, const struct tile_data* tile_data) { @@ -170,8 +153,8 @@ write_tile_data size_t ncols_tile, nrows_tile; size_t tile_pitch; char* buf_mem; - ASSERT(htrdr && sensor && buf && tile_data); - (void)htrdr, (void)sensor; + ASSERT(htrdr && buf && tile_data); + (void)htrdr; htrdr_buffer_get_layout(buf, &layout); buf_mem = htrdr_buffer_get_data(buf); @@ -193,7 +176,7 @@ write_tile_data char* dst_tile_row = buf_row + icol * layout.elmt_size; const char* src_tile_row = tile_data->pixels + irow_tile*tile_pitch; - memcpy(dst_tile_row, src_tile_row, tile_pitch); + memcpy(dst_tile_row, src_tile_row, ncols_tile*tile_data->pixsz); } } @@ -412,7 +395,6 @@ mpi_steal_work static res_T mpi_gather_tiles (struct htrdr* htrdr, - const struct htrdr_sensor* sensor, struct htrdr_buffer* buf, const size_t ntiles, struct list_node* tiles) @@ -447,22 +429,20 @@ mpi_gather_tiles LIST_FOR_EACH(node, tiles) { struct tile* t = CONTAINER_OF(node, struct tile, node); - write_tile_data(htrdr, sensor, buf, &t->data); + write_tile_data(htrdr, buf, &t->data); ++itile; } if(itile != ntiles) { - enum pixel_format pixfmt; ASSERT(htrdr->mpi_nprocs > 1); /* Create a temporary tile to receive the tile data computed by the * concurrent MPI processes */ - pixfmt = spectral_type_to_pixfmt(htrdr->spectral_type); tile = tile_create(htrdr->allocator, layout.elmt_size, layout.alignment); if(!tile) { res = RES_MEM_ERR; htrdr_log_err(htrdr, - "could not allocate the temporary tile used to gather the process " + "Could not allocate the temporary tile used to gather the process " "output data -- %s.\n", res_to_cstr(res)); goto error; } @@ -471,7 +451,7 @@ mpi_gather_tiles FOR_EACH(itile, itile, ntiles) { MPI(Recv(&tile->data, (int)msg_sz, MPI_CHAR, MPI_ANY_SOURCE, HTRDR_MPI_TILE_DATA, MPI_COMM_WORLD, MPI_STATUS_IGNORE)); - write_tile_data(htrdr, sensor, buf, &tile->data); + write_tile_data(htrdr, buf, &tile->data); } } } @@ -489,7 +469,7 @@ draw_tile const struct htrdr_draw_map_args* args, const size_t ithread, const int64_t tile_mcode, /* For debug only */ - const size_t tile_org[2], /* Origin of the tile in pixel space */ + const uint16_t tile_org[2], /* Origin of the tile in pixel space */ const size_t tile_sz[2], /* Definition of the tile */ const double pix_sz[2], /* Size of a pixel in the normalized image plane */ struct ssp_rng* rng, @@ -498,7 +478,8 @@ draw_tile struct htrdr_draw_pixel_args pix_args = HTRDR_DRAW_PIXEL_ARGS_NULL; size_t npixels; size_t mcode; /* Morton code of tile pixel */ - ASSERT(htrdr && tile_org && tile_sz && pix_sz && sensor && spp && tile); + ASSERT(htrdr && tile_org && tile_sz && pix_sz && rng && tile); + ASSERT(check_draw_map_args(args)); (void)tile_mcode; /* Adjust the #pixels to process them wrt a morton order */ @@ -514,11 +495,11 @@ draw_tile pix_args.context = args->context; FOR_EACH(mcode, 0, npixels) { - union pixel* pixel; - size_t ipix_tile[2]; /* Pixel coord in the tile */ - size_t ipix[2]; /* Pixel coord in the buffer */ + void* pixel = NULL; + uint16_t ipix_tile[2]; /* Pixel coord in the tile */ + ASSERT(mcode <= UINT32_MAX); - morton_xy_decode_u16(mcode, ipix_tile); + morton_xy_decode_u16((uint32_t)mcode, ipix_tile); if(ipix_tile[0] >= tile_sz[0] || ipix_tile[1] >= tile_sz[1]) continue; /* Pixel is out of tile */ @@ -526,11 +507,11 @@ draw_tile pixel = tile_at(tile, ipix_tile[0], ipix_tile[1]); /* Compute the pixel coordinate */ - pix_args.pixel_coord[0] = tile_org[0] + ipix_tile[0]; - pix_args.pixel_coord[1] = tile_org[1] + ipix_tile[1]; + pix_args.pixel_coord[0] = (size_t)(tile_org[0] + ipix_tile[0]); + pix_args.pixel_coord[1] = (size_t)(tile_org[1] + ipix_tile[1]); /* Invoque the draw pixel functor */ - args->draw_pixel(htrdr, &pix_args, pixel.data); + args->draw_pixel(htrdr, &pix_args, pixel); } return RES_OK; } @@ -559,7 +540,7 @@ draw_map res = ssp_rng_create(htrdr->allocator, &ssp_rng_mt19937_64, &rng_proc); if(res != RES_OK) { - htrdr_log_err(htrdr, "could not create the RNG used to sample a process " + htrdr_log_err(htrdr, "Could not create the RNG used to sample a process " "to steal -- %s.\n", res_to_cstr((res_T)res)); goto error; } @@ -624,8 +605,8 @@ draw_map tile->data.y = (uint16_t)tile_org[1]; /* Define the tile origin in pixel space */ - tile_org[0] *= TILE_SIZE; - tile_org[1] *= TILE_SIZE; + tile_org[0] = (uint16_t)(tile_org[0] * TILE_SIZE); + tile_org[1] = (uint16_t)(tile_org[1] * TILE_SIZE); /* Compute the size of the tile clamped by the borders of the buffer */ tile_sz[0] = MMIN(TILE_SIZE, buf_layout->width - tile_org[0]); @@ -699,7 +680,7 @@ error: res_T htrdr_draw_map (struct htrdr* htrdr, - struct htrdr_draw_map_args* args, + const struct htrdr_draw_map_args* args, struct htrdr_buffer* buf) { char strbuf[128]; @@ -723,20 +704,20 @@ htrdr_draw_map proc_work_init(htrdr->allocator, &work); /* Compute the overall number of tiles */ - ntiles_x = (width + (TILE_SIZE-1)/*ceil*/)/TILE_SIZE; - ntiles_y = (height+ (TILE_SIZE-1)/*ceil*/)/TILE_SIZE; + ntiles_x = (layout.width + (TILE_SIZE-1)/*ceil*/)/TILE_SIZE; + ntiles_y = (layout.height+ (TILE_SIZE-1)/*ceil*/)/TILE_SIZE; ntiles = ntiles_x * ntiles_y; /* Compute the pixel size in the normalized image plane */ - pix_sz[0] = 1.0 / (double)width; - pix_sz[1] = 1.0 / (double)height; + pix_sz[0] = 1.0 / (double)layout.width; + pix_sz[1] = 1.0 / (double)layout.height; /* Adjust the #tiles for the morton-encoding procedure */ ntiles_adjusted = round_up_pow2(MMAX(ntiles_x, ntiles_y)); ntiles_adjusted *= ntiles_adjusted; /* Define the initial number of tiles of the current process */ - proc_ntiles_adjusted = ntiles_ajusted / (size_t)htrdr->mpi_nprocs; + proc_ntiles_adjusted = ntiles_adjusted / (size_t)htrdr->mpi_nprocs; if(htrdr->mpi_rank == 0) { /* Affect the remaining tiles to the master proc */ proc_ntiles_adjusted += ntiles_adjusted - proc_ntiles_adjusted*(size_t)htrdr->mpi_nprocs; @@ -786,7 +767,7 @@ htrdr_draw_map /* Gather accum buffers from the group of processes */ time_current(&t0); - res = mpi_gather_tiles(htrdr, sensor, buf, ntiles, &tiles); + res = mpi_gather_tiles(htrdr, buf, ntiles, &tiles); if(res != RES_OK) goto error; time_sub(&t0, time_current(&t1), &t0); time_dump(&t0, TIME_ALL, NULL, strbuf, sizeof(strbuf)); diff --git a/src/core/htrdr_draw_map.h b/src/core/htrdr_draw_map.h @@ -44,7 +44,7 @@ typedef void (*htrdr_draw_pixel_T) (struct htrdr* htrdr, const struct htrdr_draw_pixel_args* args, - void* pixel) /* Output data */ + void* pixel); /* Output data */ struct htrdr_draw_map_args { htrdr_draw_pixel_T draw_pixel; @@ -80,10 +80,10 @@ htrdr_draw_pixel_args_check(struct htrdr_draw_pixel_args* args) BEGIN_DECLS HTRDR_API res_T -htrdr_draw_map_args +htrdr_draw_map (struct htrdr* htrdr, const struct htrdr_draw_map_args* args, - struct htrdr_buffer* buf; + struct htrdr_buffer* buf); END_DECLS diff --git a/src/core/htrdr_log.c b/src/core/htrdr_log.c @@ -16,6 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "htrdr.h" +#include "htrdr_c.h" #include "htrdr_log.h" #include <rsys/logger.h> @@ -99,3 +100,15 @@ htrdr_log_warn(struct htrdr* htrdr, const char* msg, ...) va_end(vargs_list); } } + +/******************************************************************************* + * Local function + ******************************************************************************/ +void +setup_logger(struct htrdr* htrdr) +{ + logger_init(htrdr->allocator, &htrdr->logger); + logger_set_stream(&htrdr->logger, LOG_OUTPUT, print_out, NULL); + logger_set_stream(&htrdr->logger, LOG_ERROR, print_err, NULL); + logger_set_stream(&htrdr->logger, LOG_WARNING, print_warn, NULL); +} diff --git a/src/core/htrdr_main.c b/src/core/htrdr_main.c @@ -17,6 +17,8 @@ #include "htrdr.h" #include "htrdr_version.h" +#include <string.h> + /******************************************************************************* * Helper functions ******************************************************************************/ @@ -24,7 +26,7 @@ static void print_usage(const char* cmd) { ASSERT(cmd); - printf("Usage: %s [--version] [--help] <mode> [<args>].\n"); + printf("Usage: %s [--version] [--help] <mode> [<args>].\n", cmd); } static void @@ -41,14 +43,14 @@ print_help(const char* cmd) " --help display this help and exit.\n"); printf("\n"); - printf("These are %s available modes:\n"); + printf("These are %s available modes:\n", cmd); + printf("\n"); printf( " atmosphere Radiative transfer computations in a cloudy atmosphere.\n"); printf( " combustion Radiative transfer computations in a combustion medium.\n"); printf("\n"); - htrdr_fprint_copyright(cmd, stdout); htrdr_fprint_license(cmd, stdout); } @@ -80,13 +82,11 @@ main(int argc, char** argv) HTRDR_VERSION_MAJOR, HTRDR_VERSION_MINOR, HTRDR_VERSION_PATCH); - args->quit = 1; goto exit; /* Help */ } else if(!strcmp(argv[1], "--help")) { - print_usage(argv[0]); - args->quit = 1; + print_help(argv[0]); goto exit; /* Fallback */ diff --git a/src/core/htrdr_materials.c b/src/core/htrdr_materials.c @@ -17,6 +17,7 @@ #define _POSIX_C_SOURCE 200112L /* strtok_r and wordexp support */ #include "htrdr.h" +#include "htrdr_log.h" #include "htrdr_materials.h" #include <modradurb/mrumtl.h> @@ -119,8 +120,11 @@ parse_material /* Parse the mrumtl file if any */ if(strcmp(wexp.we_wordv[0], "none")) { - res = mrumtl_create(&mats->htrdr->logger, htrdr_get_allocator(mats->htrdr), - mats->htrdr->verbose, &mtl.mrumtl); + res = mrumtl_create + (htrdr_get_logger(mats->htrdr), + htrdr_get_allocator(mats->htrdr), + htrdr_get_verbosity_level(mats->htrdr), + &mtl.mrumtl); if(res != RES_OK) { htrdr_log_err(mats->htrdr, "%s:%lu: error creating the MruMtl loader for the material `%s'-- %s.\n", @@ -258,9 +262,8 @@ create_bsdf_diffuse res_T res = RES_OK; ASSERT(htrdr && brdf && out_bsdf); ASSERT(mrumtl_brdf_get_type(brdf) == MRUMTL_BRDF_LAMBERTIAN); - ASSERT(ithread < htrdr->nthreads); - res = ssf_bsdf_create(htrdr_get_lifo_allocator(htrdr, ithread), + res = ssf_bsdf_create(htrdr_get_thread_allocator(htrdr, ithread), &ssf_lambertian_reflection, &bsdf); if(res != RES_OK) goto error; @@ -290,11 +293,10 @@ create_bsdf_specular res_T res = RES_OK; ASSERT(htrdr && brdf && out_bsdf); ASSERT(mrumtl_brdf_get_type(brdf) == MRUMTL_BRDF_SPECULAR); - ASSERT(ithread < htrdr->nthreads); - allocator = htrdr_get_lifo_allocator(htrdr, ithread); + allocator = htrdr_get_thread_allocator(htrdr, ithread); - res = ssf_bsdf_create(allocator &ssf_specular_reflection, &bsdf); + res = ssf_bsdf_create(allocator, &ssf_specular_reflection, &bsdf); if(res != RES_OK) goto error; res = ssf_fresnel_create(allocator, &ssf_fresnel_constant, &fresnel); @@ -381,7 +383,7 @@ htrdr_materials_find_mtl int found = 0; ASSERT(mats && name && htrdr_mtl); - str_init(htrdr_get_allocator(htrdr), &str); + str_init(htrdr_get_allocator(mats->htrdr), &str); CHK(str_set(&str, name) == RES_OK); htable_name2mtl_find_iterator(&mats->name2mtl, &str, &it); @@ -416,7 +418,6 @@ htrdr_mtl_create_bsdf double r; res_T res = RES_OK; ASSERT(htrdr && mtl && wavelength && rng && out_bsdf); - ASSERT(ithread < htrdr->nthreads); r = ssp_rng_canonical(rng); diff --git a/src/core/htrdr_ran_wlen.c b/src/core/htrdr_ran_wlen.c @@ -18,7 +18,9 @@ #include "htrdr.h" #include "htrdr_c.h" +#include "htrdr_log.h" #include "htrdr_ran_wlen.h" +#include "htrdr_spectral.h" #include <high_tune/htsky.h> @@ -84,15 +86,18 @@ setup_wlen_ran_cdf double lambda_lo = wlen_ran->range[0] + (double)i * wlen_ran->band_len; double lambda_hi = MMIN(lambda_lo + wlen_ran->band_len, wlen_ran->range[1]); ASSERT(lambda_lo<= lambda_hi); - ASSERT(lambda_lo > wlen_ran->range[0] || eq_eps(lambda_lo, wlen_ran->range[0], 1.e-6)); - ASSERT(lambda_lo < wlen_ran->range[1] || eq_eps(lambda_lo, wlen_ran->range[1], 1.e-6)); + ASSERT(lambda_lo > wlen_ran->range[0] + || eq_eps(lambda_lo, wlen_ran->range[0], 1.e-6)); + ASSERT(lambda_lo < wlen_ran->range[1] + || eq_eps(lambda_lo, wlen_ran->range[1], 1.e-6)); /* Convert from nanometer to meter */ lambda_lo *= 1.e-9; lambda_hi *= 1.e-9; /* Compute the probability of the current band */ - pdf[i] = blackbody_fraction(lambda_lo, lambda_hi, wlen_ran->ref_temperature); + pdf[i] = htrdr_blackbody_fraction + (lambda_lo, lambda_hi, wlen_ran->ref_temperature); /* Update the norm */ sum += pdf[i]; @@ -158,7 +163,7 @@ wlen_ran_sample_continue /* Setup the dichotomy search */ lambda_m_min = range_m[0]; lambda_m_max = range_m[1]; - bf_min_max = blackbody_fraction + bf_min_max = htrdr_blackbody_fraction (range_m[0], range_m[1], wlen_ran->ref_temperature); /* Numerically search the lambda corresponding to the submitted canonical @@ -166,7 +171,8 @@ wlen_ran_sample_continue FOR_EACH(i, 0, MAX_ITER) { double r_test; lambda_m = (lambda_m_min + lambda_m_max) * 0.5; - bf = blackbody_fraction(range_m[0], lambda_m, wlen_ran->ref_temperature); + bf = htrdr_blackbody_fraction + (range_m[0], lambda_m, wlen_ran->ref_temperature); r_test = bf / bf_min_max; if(r_test < r) { @@ -191,8 +197,8 @@ wlen_ran_sample_continue if(pdf) { const double Tref = wlen_ran->ref_temperature; - const double B_lambda = planck(lambda_m, lambda_m, Tref); - const double B_mean = planck(range_m[0], range_m[1], Tref); + const double B_lambda = htrdr_planck(lambda_m, lambda_m, Tref); + const double B_mean = htrdr_planck(range_m[0], range_m[1], Tref); *pdf = B_lambda / (B_mean * (range_m[1]-range_m[0])); } @@ -279,7 +285,6 @@ htrdr_ran_wlen_create struct htrdr_ran_wlen** out_wlen_ran) { struct htrdr_ran_wlen* wlen_ran = NULL; - double min_band_len = 0; res_T res = RES_OK; ASSERT(htrdr && range && out_wlen_ran && ref_temperature > 0); ASSERT(ref_temperature > 0); @@ -304,20 +309,11 @@ htrdr_ran_wlen_create wlen_ran->ref_temperature = ref_temperature; wlen_ran->nbands = nbands; - min_band_len = compute_sky_min_band_len(wlen_ran->htrdr->sky, wlen_ran->range); - if(nbands == HTRDR_WLEN_RAN_CONTINUE) { wlen_ran->band_len = 0; } else { wlen_ran->band_len = (range[1] - range[0]) / (double)wlen_ran->nbands; - /* Adjust the band length to ensure that each sky spectral interval is - * overlapped by at least one band */ - if(wlen_ran->band_len > min_band_len) { - wlen_ran->band_len = min_band_len; - wlen_ran->nbands = (size_t)ceil((range[1] - range[0]) / wlen_ran->band_len); - } - res = setup_wlen_ran_cdf(wlen_ran, FUNC_NAME); if(res != RES_OK) goto error; } diff --git a/src/core/htrdr_rectangle.c b/src/core/htrdr_rectangle.c @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "htrdr.h" +#include "htrdr_log.h" #include "htrdr_rectangle.h" #include <rsys/double3.h> diff --git a/src/core/htrdr_sensor.c b/src/core/htrdr_sensor.c @@ -1,79 +0,0 @@ -/* Copyright (C) 2018, 2019, 2020 |Meso|Star> (contact@meso-star.com) - * Copyright (C) 2018, 2019 CNRS, Université Paul Sabatier - * - * 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 "htrdr.h" -#include "htrdr_camera.h" -#include "htrdr_ground.h" -#include "htrdr_interface.h" -#include "htrdr_rectangle.h" -#include "htrdr_sensor.h" - -#include <star/s3d.h> -#include <star/ssp.h> - -/******************************************************************************* - * Helper functions - ******************************************************************************/ -static res_T -sample_camera_ray - (struct htrdr_camera* cam, - const size_t ipix[2], - const double pix_sz[2], - struct ssp_rng* rng, - double ray_org[3], - double ray_dir[3]) -{ - double pix_samp[2]; - ASSERT(cam && ipix && pix_sz && rng && ray_org && ray_dir); - - /* Sample a position into the pixel, in the normalized image plane */ - pix_samp[0] = ((double)ipix[0] + ssp_rng_canonical(rng)) * pix_sz[0]; - pix_samp[1] = ((double)ipix[1] + ssp_rng_canonical(rng)) * pix_sz[1]; - - /* Generate a ray starting from the pinhole camera and passing through the - * pixel sample */ - htrdr_camera_ray(cam, pix_samp, ray_org, ray_dir); - - return RES_OK; -} - -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T -htrdr_sensor_sample_primary_ray - (const struct htrdr_sensor* sensor, - struct htrdr* htrdr, - const size_t ipix[2], - const double pix_sz[2], - struct ssp_rng* rng, - double ray_org[3], - double ray_dir[3]) -{ - res_T res = RES_OK; - switch(sensor->type) { - case HTRDR_SENSOR_CAMERA: - res = sample_camera_ray(sensor->camera, ipix, pix_sz, rng, ray_org, ray_dir); - break; - case HTRDR_SENSOR_RECTANGLE: - res = sample_rectangle_ray(sensor->rectangle, htrdr, ipix, - pix_sz, rng, ray_org, ray_dir); - break; - default: FATAL("Unreachable code.\n"); break; - } - return res; -} - diff --git a/src/core/htrdr_slab.c b/src/core/htrdr_slab.c @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "htrdr.h" +#include "htrdr_log.h" #include "htrdr_slab.h" #include <rsys/cstr.h> diff --git a/src/core/htrdr_spectral.c b/src/core/htrdr_spectral.c @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "htrdr.h" +#include "htrdr_log.h" #include "htrdr_spectral.h" /******************************************************************************* @@ -104,7 +105,7 @@ htrdr_radiance_temperature radiance_avg, &temperature); if(res != RES_OK) { - htrdr_log_warn(cmd->htrdr, + htrdr_log_warn(htrdr, "Could not compute the brightness temperature for the radiance %g.\n", radiance_avg); temperature = 0; diff --git a/src/core/htrdr_spectral.h b/src/core/htrdr_spectral.h @@ -31,8 +31,21 @@ enum htrdr_spectral_type { HTRDR_SPECTRAL_SW_CIE_XYZ /* Shortwave wrt the CIE XYZ tristimulus */ }; +/* Forwar declaration */ struct htrdr; +static FINLINE double /* In nanometer */ +htrdr_wavenumber_to_wavelength(const double nu/*In cm^-1*/) +{ + return 1.e7 / nu; +} + +static FINLINE double /* In cm^-1 */ +wavelength_to_wavenumber(const double lambda/*In nanometer*/) +{ + return htrdr_wavenumber_to_wavelength(lambda); +} + static INLINE double htrdr_wiebelt(const double v) { @@ -127,7 +140,7 @@ htrdr_planck } } -BEGIN_DECL +BEGIN_DECLS HTRDR_API res_T htrdr_brightness_temperature @@ -143,8 +156,8 @@ htrdr_radiance_temperature (struct htrdr* htrdr, const double lambda_min, /* In meters */ const double lambda_max, /* In meters */ - const double radiance) /* In W/m^2/sr */ + const double radiance); /* In W/m^2/sr */ -END_DECL +END_DECLS #endif /* HTRDR_SPECTRAL_H */