solstice-solver

Solver library of the solstice app
git clone git://git.meso-star.com/solstice-solver.git
Log | Files | Refs | README | LICENSE

ssol_device.c (4940B)


      1 /* Copyright (C) 2018-2026 |Meso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2016, 2018 CNRS
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU General Public License as published by
      6  * the Free Software Foundation, either version 3 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     16 
     17 #include "ssol.h"
     18 #include "ssol_device_c.h"
     19 
     20 #include <rsys/logger.h>
     21 #include <rsys/mem_allocator.h>
     22 
     23 #include <star/s3d.h>
     24 #include <star/scpr.h>
     25 
     26 #include <omp.h>
     27 
     28 /*******************************************************************************
     29  * Helper functions
     30  ******************************************************************************/
     31 static INLINE void
     32 log_msg
     33   (struct ssol_device* dev,
     34    const enum log_type stream,
     35    const char* msg,
     36    va_list vargs)
     37 {
     38   ASSERT(dev && msg);
     39   if(dev->verbose) {
     40     res_T res; (void)res;
     41     res = logger_vprint(dev->logger, stream, msg, vargs);
     42     ASSERT(res == RES_OK);
     43   }
     44 }
     45 
     46 static void
     47 device_release(ref_T* ref)
     48 {
     49   struct ssol_device* dev;
     50   ASSERT(ref);
     51   dev = CONTAINER_OF(ref, struct ssol_device, ref);
     52   darray_tile_release(&dev->tiles);
     53   if(dev->bsdf_allocators) {
     54     unsigned i;
     55     FOR_EACH(i, 0, dev->nthreads) {
     56       mem_shutdown_lifo_allocator(&dev->bsdf_allocators[i]);
     57     }
     58     MEM_RM(dev->allocator, dev->bsdf_allocators);
     59   }
     60   if(dev->s3d) S3D(device_ref_put(dev->s3d));
     61   if(dev->scpr_mesh) SCPR(mesh_ref_put(dev->scpr_mesh));
     62   if(dev->scpr_device) SCPR(device_ref_put(dev->scpr_device));
     63   MEM_RM(dev->allocator, dev);
     64 }
     65 
     66 /*******************************************************************************
     67  * Exported ssol_device functions
     68  ******************************************************************************/
     69 res_T
     70 ssol_device_create
     71   (struct logger* logger,
     72    struct mem_allocator* mem_allocator,
     73    const unsigned nthreads_hint,
     74    const int verbose,
     75    struct ssol_device** out_dev)
     76 {
     77   struct ssol_device* dev = NULL;
     78   struct mem_allocator* allocator;
     79   unsigned i;
     80   struct scpr_device_create_args scpr_args = SCPR_DEVICE_CREATE_ARGS_DEFAULT;
     81   res_T res = RES_OK;
     82 
     83   if(nthreads_hint == 0 || !out_dev) {
     84     res = RES_BAD_ARG;
     85     goto error;
     86   }
     87 
     88   allocator = mem_allocator ? mem_allocator : &mem_default_allocator;
     89   dev = MEM_CALLOC(allocator, 1, sizeof(struct ssol_device));
     90   if(!dev) {
     91     res = RES_MEM_ERR;
     92     goto error;
     93   }
     94   ref_init(&dev->ref);
     95   darray_tile_init(allocator, &dev->tiles);
     96   dev->logger = logger ? logger : LOGGER_DEFAULT;
     97   dev->allocator = allocator;
     98   dev->verbose = verbose; /* TODO: check if verbosity levels match */
     99   dev->nthreads = MMIN(nthreads_hint, (unsigned)omp_get_num_procs());
    100   omp_set_num_threads((int)dev->nthreads);
    101 
    102   dev->bsdf_allocators = MEM_CALLOC
    103     (dev->allocator, dev->nthreads, sizeof(struct mem_allocator));
    104   if(!dev->bsdf_allocators) {
    105     res = RES_MEM_ERR;
    106     goto error;
    107   }
    108 
    109   FOR_EACH(i, 0, dev->nthreads) {
    110     res = mem_init_lifo_allocator
    111       (&dev->bsdf_allocators[i], dev->allocator, 4096);
    112     if(res != RES_OK) goto error;
    113   }
    114 
    115   res = darray_tile_resize(&dev->tiles, dev->nthreads);
    116   if(res != RES_OK) goto error;
    117   res = s3d_device_create(logger, mem_allocator, 0, &dev->s3d);
    118   if(res != RES_OK) goto error;
    119   scpr_args.allocator = allocator;
    120   scpr_args.logger = logger;
    121   scpr_args.verbosity_level = dev->verbose;
    122   res = scpr_device_create(&scpr_args, &dev->scpr_device);
    123   if(res != RES_OK) goto error;
    124   res = scpr_mesh_create(dev->scpr_device, &dev->scpr_mesh);
    125   if(res != RES_OK) goto error;
    126 
    127 exit:
    128   if(out_dev) *out_dev = dev;
    129   return res;
    130 error:
    131   if(dev) {
    132     SSOL(device_ref_put(dev));
    133     dev = NULL;
    134   }
    135   goto exit;
    136 }
    137 
    138 res_T
    139 ssol_device_ref_get(struct ssol_device* dev)
    140 {
    141   if(!dev) return RES_BAD_ARG;
    142   ref_get(&dev->ref);
    143   return RES_OK;
    144 }
    145 
    146 res_T
    147 ssol_device_ref_put(struct ssol_device* dev)
    148 {
    149   if(!dev) return RES_BAD_ARG;
    150   ref_put(&dev->ref, device_release);
    151   return RES_OK;
    152 }
    153 
    154 /*******************************************************************************
    155  * Local functions
    156  ******************************************************************************/
    157 void
    158 log_error(struct ssol_device* dev, const char* msg, ...)
    159 {
    160   va_list vargs_list;
    161   ASSERT(dev && msg);
    162 
    163   va_start(vargs_list, msg);
    164   log_msg(dev, LOG_ERROR, msg, vargs_list);
    165   va_end(vargs_list);
    166 }
    167 
    168 void
    169 log_warning(struct ssol_device* dev, const char* msg, ...)
    170 {
    171   va_list vargs_list;
    172   ASSERT(dev && msg);
    173 
    174   va_start(vargs_list, msg);
    175   log_msg(dev, LOG_WARNING, msg, vargs_list);
    176   va_end(vargs_list);
    177 }
    178