smc.h (6291B)
1 /* Copyright (C) 2015-2018, 2021-2023 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #ifndef SMC_H 17 #define SMC_H 18 19 #include <star/ssp.h> 20 #include <rsys/rsys.h> 21 #include <limits.h> 22 23 /* Library symbol management */ 24 #if defined(SMC_SHARED_BUILD) /* Build shared library */ 25 #define SMC_API extern EXPORT_SYM 26 #elif defined(SMC_STATIC) /* Use/build static library */ 27 #define SMC_API extern LOCAL_SYM 28 #else /* Use shared library */ 29 #define SMC_API extern IMPORT_SYM 30 #endif 31 32 /* Helper macro that asserts if the invocation of the smc function `Func' 33 * returns an error. One should use this macro on smc function calls for which 34 * no explicit error checking is performed */ 35 #ifndef NDEBUG 36 #define SMC(Func) ASSERT(smc_ ## Func == RES_OK) 37 #else 38 #define SMC(Func) smc_ ## Func 39 #endif 40 41 #define SMC_NTHREADS_DEFAULT (~0u) 42 43 /* Forward declaration of external types */ 44 struct logger; 45 struct mem_allocator; 46 struct ssp_rng; 47 48 /* Generic type descriptor */ 49 struct smc_type { 50 void* (*create)(struct mem_allocator* allocator, void* ctx); 51 void (*destroy)(struct mem_allocator* allocator, void* data); 52 53 void (*set)(void* result, const void* value); 54 void (*zero)(void* result); 55 void (*add)(void* result, const void* op0, const void* op1); 56 void (*sub)(void* result, const void* op0, const void* op1); 57 void (*mul)(void* result, const void* op0, const void* op1); 58 void (*divi)(void* result, const void* op0, const size_t op1); 59 void (*sqrt)(void* result, const void* value); 60 }; 61 #define SMC_TYPE_NULL__ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL} 62 static const struct smc_type SMC_TYPE_NULL = SMC_TYPE_NULL__; 63 64 struct smc_estimator_status { 65 void* E; /* Expected value */ 66 void* V; /* Variance */ 67 void* SE; /* Standard error, i.e. sqrt(V / N) */ 68 size_t N; /* OK samples count */ 69 size_t NF; /* Failed samples count */ 70 }; 71 #define SMC_ESTIMATOR_STATUS_NULL__ {NULL, NULL, NULL, 0, 0} 72 static const struct smc_estimator_status SMC_ESTIMATOR_STATUS_NULL = 73 SMC_ESTIMATOR_STATUS_NULL__; 74 75 struct smc_integrator { 76 res_T (*integrand) 77 (void* value, 78 struct ssp_rng* rng, 79 const unsigned ithread, 80 const uint64_t irealisation, 81 void* ctx); 82 const struct smc_type* type; 83 size_t max_realisations; /* Maximum # of realisations */ 84 size_t max_failures; /* Cancel integration past # failed samples */ 85 }; 86 #define SMC_INTEGRATOR_NULL__ {NULL, NULL, 0, 0} 87 static const struct smc_integrator SMC_INTEGRATOR_NULL = SMC_INTEGRATOR_NULL__; 88 89 struct smc_device_create_args { 90 struct mem_allocator* allocator; /* May NULL <=> Default allocator */ 91 struct logger* logger; /* May NULL <=> default logger */ 92 unsigned nthreads_hint; /* Hint on the number of threads to use */ 93 enum ssp_rng_type rng_type; /* SSP_RNG_TYPE_NULL <=> use default RNG type */ 94 int verbose; /* Verbosity level */ 95 }; 96 #define SMC_DEVICE_CREATE_ARGS_DEFAULT__ { \ 97 NULL, NULL, SMC_NTHREADS_DEFAULT, SSP_RNG_TYPE_NULL, 0 \ 98 } 99 static const struct smc_device_create_args SMC_DEVICE_CREATE_ARGS_DEFAULT = 100 SMC_DEVICE_CREATE_ARGS_DEFAULT__; 101 102 /* Forward declaration of opaque types */ 103 struct smc_device; /* Entry point of the library */ 104 struct smc_estimator; /* Estimator of an integrator */ 105 106 BEGIN_DECLS 107 108 /* Pre-declared SMC types */ 109 SMC_API const struct smc_type smc_float; 110 SMC_API const struct smc_type smc_double; 111 SMC_API const struct smc_type smc_doubleN; 112 113 /* Context of a list of double precision floating point data. Must be set as 114 * the context parameter of the smc_solve function when the integrator type is 115 * smc_doubleN. */ 116 struct smc_doubleN_context { 117 size_t count; /* Number of floating point values */ 118 void* integrand_data; /* User defined data used by the integrand */ 119 }; 120 #define SMC_DOUBLEN_CONTEXT_NULL__ {0, NULL} 121 static const struct smc_doubleN_context SMC_DOUBLEN_CONTEXT_NULL = 122 SMC_DOUBLEN_CONTEXT_NULL__; 123 124 /* Syntactic sugar macros and functions */ 125 #define SMC_FLOAT(Val) (*(float*)(Val)) 126 #define SMC_DOUBLE(Val) (*(double*)(Val)) 127 SMC_API double* SMC_DOUBLEN(void* val); 128 129 /******************************************************************************* 130 * Device API 131 ******************************************************************************/ 132 SMC_API res_T 133 smc_device_create 134 (const struct smc_device_create_args* args, 135 struct smc_device** dev); 136 137 SMC_API res_T 138 smc_device_ref_get 139 (struct smc_device* dev); 140 141 SMC_API res_T 142 smc_device_ref_put 143 (struct smc_device* dev); 144 145 SMC_API res_T 146 smc_device_set_rng_type 147 (struct smc_device* dev, 148 const enum ssp_rng_type type); 149 150 SMC_API res_T 151 smc_device_get_rng_type 152 (struct smc_device* dev, 153 enum ssp_rng_type* type); 154 155 /* Return the maximum number of threads internally used by the device */ 156 SMC_API res_T 157 smc_device_get_threads_count 158 (const struct smc_device* dev, 159 unsigned* nthreads); 160 161 /******************************************************************************* 162 * Integration API 163 ******************************************************************************/ 164 SMC_API res_T 165 smc_solve 166 (struct smc_device* dev, 167 struct smc_integrator* integrator, 168 void* ctx, 169 struct smc_estimator** estimator); 170 171 SMC_API res_T 172 smc_solve_N 173 (struct smc_device* dev, 174 struct smc_integrator* integrator, 175 const size_t count, 176 void* contexts, 177 const size_t sizeof_context, 178 struct smc_estimator* estimators[]); 179 180 SMC_API res_T 181 smc_estimator_ref_get 182 (struct smc_estimator* estimator); 183 184 SMC_API res_T 185 smc_estimator_ref_put 186 (struct smc_estimator* estimator); 187 188 SMC_API res_T 189 smc_estimator_get_status 190 (struct smc_estimator* estimator, 191 struct smc_estimator_status* status); 192 193 END_DECLS 194 195 #endif /* SMC_H */ 196