test_ssf_phase.c (5192B)
1 /* Copyright (C) 2016-2018, 2021-2025 |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 #include "ssf.h" 17 #include "test_ssf_utils.h" 18 19 static int phase_is_init = 0; 20 21 struct ALIGN(64) phase { 22 uint32_t id; 23 struct ssp_rng* rng; 24 double wi[3]; 25 double wo[3]; 26 double pdf; 27 double value; 28 }; 29 30 static res_T 31 phase_init(struct mem_allocator* allocator, void* phase) 32 { 33 CHK(allocator != NULL); 34 CHK(phase != NULL); 35 CHK(IS_ALIGNED(phase, 64) == 1); 36 ((struct phase*)phase)->id = 0xDECAFBAD; 37 phase_is_init = 1; 38 return RES_OK; 39 } 40 41 static void 42 phase_release(void* phase) 43 { 44 CHK(phase != NULL); 45 CHK(((struct phase*)phase)->id == 0xDECAFBAD); 46 phase_is_init = 0; 47 } 48 49 static void 50 phase_sample 51 (void* data, 52 struct ssp_rng* rng, 53 const double wo[3], 54 double wi[3], 55 double* pdf) 56 { 57 struct phase* phase = data; 58 CHK(phase != NULL); 59 CHK(phase->rng == rng); 60 CHK(d3_eq(phase->wo, wo) == 1); 61 d3(wi, 1.0, 2.0, 3.0); 62 if(pdf) *pdf = phase->pdf; 63 } 64 65 static double 66 phase_eval 67 (void* data, 68 const double wo[3], 69 const double wi[3]) 70 { 71 struct phase* phase = data; 72 CHK(phase != NULL); 73 CHK(wi != NULL); 74 CHK(wo != NULL); 75 CHK(d3_eq(phase->wo, wo) == 1); 76 CHK(d3_eq(phase->wi, wi) == 1); 77 return phase->value; 78 } 79 80 static double 81 phase_pdf 82 (void* data, 83 const double wo[3], 84 const double wi[3]) 85 { 86 struct phase* phase = data; 87 CHK(phase != NULL); 88 CHK(wi != NULL); 89 CHK(wo != NULL); 90 CHK(d3_eq(phase->wo, wo) == 1); 91 CHK(d3_eq(phase->wi, wi) == 1); 92 return phase->pdf; 93 } 94 95 int 96 main(int argc, char** argv) 97 { 98 struct mem_allocator allocator; 99 struct ssp_rng* rng; 100 struct ssf_phase* phase = NULL; 101 struct ssf_phase_type type = SSF_PHASE_TYPE_NULL; 102 struct ssf_phase_type type2 = phase_dummy; 103 struct phase* data = NULL; 104 double wi[3]; 105 double pdf; 106 (void)argc, (void)argv; 107 108 mem_init_proxy_allocator(&allocator, &mem_default_allocator); 109 CHK(ssp_rng_create(&allocator, SSP_RNG_THREEFRY, &rng) == RES_OK); 110 111 type.init = phase_init; 112 type.release = phase_release; 113 type.sample = phase_sample; 114 type.eval = phase_eval; 115 type.pdf = phase_pdf; 116 type.sizeof_phase = sizeof(struct phase); 117 type.alignof_phase = ALIGNOF(struct phase); 118 119 CHK(ssf_phase_create(NULL, NULL, NULL) == RES_BAD_ARG); 120 CHK(ssf_phase_create(&allocator, NULL, NULL) == RES_BAD_ARG); 121 CHK(ssf_phase_create(NULL, &type, NULL) == RES_BAD_ARG); 122 CHK(ssf_phase_create(&allocator, &type, NULL) == RES_BAD_ARG); 123 CHK(ssf_phase_create(NULL, NULL, &phase) == RES_BAD_ARG); 124 CHK(ssf_phase_create(&allocator, NULL, &phase) == RES_BAD_ARG); 125 126 CHK(phase_is_init == 0); 127 CHK(ssf_phase_create(NULL, &type, &phase) == RES_OK); 128 CHK(phase_is_init == 1); 129 130 CHK(ssf_phase_ref_get(NULL) == RES_BAD_ARG); 131 CHK(ssf_phase_ref_get(phase) == RES_OK); 132 CHK(ssf_phase_ref_put(NULL) == RES_BAD_ARG); 133 CHK(ssf_phase_ref_put(phase) == RES_OK); 134 CHK(phase_is_init == 1); 135 CHK(ssf_phase_ref_put(phase) == RES_OK); 136 CHK(phase_is_init == 0); 137 138 type2.init = NULL; 139 CHK(ssf_phase_create(&allocator, &type2, &phase) == RES_OK); 140 CHK(ssf_phase_ref_put(phase) == RES_OK); 141 type2.init = phase_dummy.init; 142 type2.release = NULL; 143 CHK(ssf_phase_create(&allocator, &type2, &phase) == RES_OK); 144 CHK(ssf_phase_ref_put(phase) == RES_OK); 145 146 type.sample = NULL; 147 CHK(ssf_phase_create(&allocator, &type, &phase) == RES_BAD_ARG); 148 CHK(phase_is_init == 0); 149 type.sample = phase_sample; 150 type.alignof_phase = 3; 151 CHK(ssf_phase_create(&allocator, &type, &phase) == RES_BAD_ARG); 152 CHK(phase_is_init == 0); 153 type.alignof_phase = ALIGNOF(struct phase); 154 CHK(ssf_phase_create(&allocator, &type, &phase) == RES_OK); 155 CHK(phase_is_init == 1); 156 157 CHK(ssf_phase_get_data(NULL, NULL) == RES_BAD_ARG); 158 CHK(ssf_phase_get_data(phase, NULL) == RES_BAD_ARG); 159 CHK(ssf_phase_get_data(NULL, (void**)&data) == RES_BAD_ARG); 160 CHK(ssf_phase_get_data(phase, (void**)&data) == RES_OK); 161 162 CHK(data->id == 0xDECAFBAD); 163 164 d3_normalize(data->wo, d3(data->wo, -1, -1, 0)); 165 data->rng = rng; 166 data->value = 0.1234; 167 data->pdf = 4; 168 169 pdf = 0; 170 ssf_phase_sample(phase, rng, data->wo, wi, NULL); 171 ssf_phase_sample(phase, rng, data->wo, wi, &pdf); 172 CHK(pdf == 4); 173 174 d3_normalize(data->wi, wi); 175 data->value = 0.4567; 176 CHK(ssf_phase_eval(phase, data->wo, data->wi) == data->value); 177 data->pdf = 0.890; 178 CHK(ssf_phase_pdf(phase, data->wo, data->wi) == data->pdf); 179 180 CHK(ssf_phase_ref_put(phase) == RES_OK); 181 182 CHK(ssp_rng_ref_put(rng) == RES_OK); 183 184 check_memory_allocator(&allocator); 185 mem_shutdown_proxy_allocator(&allocator); 186 CHK(mem_allocated_size() == 0); 187 return 0; 188 } 189