• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

krakjoe / ort / 19174598641

07 Nov 2025 04:07PM UTC coverage: 92.332% (+0.4%) from 91.936%
19174598641

push

github

krakjoe
define f32/f64 when onnxruntime is loaded

12450 of 13484 relevant lines covered (92.33%)

299476.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.23
/src/generators/random.c
1
/*
2
  +----------------------------------------------------------------------+
3
  | ort                                                                  |
4
  +----------------------------------------------------------------------+
5
  | Copyright (c) Joe Watkins 2025                                       |
6
  +----------------------------------------------------------------------+
7
  | This source file is subject to version 3.01 of the PHP license,      |
8
  | that is bundled with this package in the file LICENSE, and is        |
9
  | available through the world-wide-web at the following url:           |
10
  | http://www.php.net/license/3_01.txt                                  |
11
  | If you did not receive a copy of the PHP license and are unable to   |
12
  | obtain it through the world-wide-web, please send a note to          |
13
  | license@php.net so we can mail you a copy immediately.               |
14
  +----------------------------------------------------------------------+
15
  | Author: krakjoe                                                      |
16
  +----------------------------------------------------------------------+
17
 */
18

19

20
 /** 
21
{{{
22
    @file generators/random.c
23
    @brief This API provides random generators for Tensor constructors.
24
    
25
    The constructor is overloaded:
26

27
    We shall determine the min and max derived from type:
28
    Tensor\Generator Tensor\Generator\Random(int $type)
29

30
    We shall determine the max derived from type, verifying the minimum is within range:
31
    Tensor\Generator Tensor\Generator\Random(int $type, mixed $min)
32

33
    We shall verify the min and max are within range:
34
    Tensor\Generator Tensor\Generator\Random(int $type, mixed $min, mixed $max)
35

36
    For example:
37
        $tensor = new Tensor\Transient([24, 24],
38
            new Tensor\Generator\Random(Tensor::FLOAT));
39
        Will generate a 24x24 tensor with float values in the range 0-1 (never inclusive of 1.0)
40

41
        $tensor = new Tensor\Transient([24, 24],
42
            new Tensor\Generator\Random(Tensor::UINT8, 0, 255));
43
        Will generate a 24x24 tensor with UINT8 values in the range 0-255
44

45
        $tensor = new Tensor\Transient([24, 24],
46
            new Tensor\Generator\Random(Tensor::INT8));
47
        Will generate a 24x24 tensor with INT8 values in the range INT8_MIN to INT8_MAX
48

49
        An exception will be thrown if min exceeds max, of if any parameter is out of range.
50
}}} */
51
#include "status.h"
52
#include "generators.h"
53
#include "generators/random.h"
54

55
#if PHP_VERSION_ID >= 80200
56
#include <ext/random/php_random.h>
57
#else
58
#include <ext/standard/php_mt_rand.h>
59
#endif
60

61
#if PHP_VERSION_ID < 80300
62
const char* zend_zval_value_name(const zval* arg) {
63
    if (Z_ISUNDEF_P(arg)) {
64
        return "null";
65
    }
66

67
    if (Z_TYPE_P(arg) == IS_OBJECT) {
68
        return ZSTR_VAL(Z_OBJCE_P(arg)->name);
69
    } else if (Z_TYPE_P(arg) == IS_FALSE) {
70
        return "false";
71
    } else if  (Z_TYPE_P(arg) == IS_TRUE) {
72
        return "true";
73
    }
74

75
    return zend_get_type_by_const(Z_TYPE_P(arg));
76
}
77
#endif
78

79
zend_class_entry* php_ort_generator_random_ce;
80

81
typedef struct _php_ort_generator_random_context_t{
82
    zend_long type;
83
    zval min;
84
    zval max;
85
} php_ort_generator_random_context_t;
86

87
static zend_always_inline void
88
    php_ort_generator_random_invoke(
16,524✔
89
        php_ort_generator_t* generator, zval* zv) {
90
    php_ort_generator_random_context_t* context =
21,384✔
91
        (php_ort_generator_random_context_t*) generator->context;
4,860✔
92

93
    switch (context->type) {
16,524✔
94
        case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16:
2,592✔
95
        case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT32:
96
        case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT64: {
97
            float64 min = Z_DVAL(context->min);
3,672✔
98
            float64 max = Z_DVAL(context->max);
3,672✔
99
            float64 scale =
7,344✔
100
                (float64) php_mt_rand() /
3,672✔
101
                    ((float64) PHP_MT_RAND_MAX + 1.0);
102

103
            if (scale > 0.999999) {
3,672✔
104
                scale = 0.999999;
567✔
105
            }
567✔
106

107
            if (scale < 0.0) {
2,379✔
108
                scale = 0;
109
            }
110

111
            ZVAL_DOUBLE(zv, min + scale * (max - min));
3,672✔
112
            break;
2,592✔
113
        }
1,080✔
114

115
        default: {
9,072✔
116
            ZVAL_LONG(zv, php_mt_rand_range(
12,852✔
117
                Z_LVAL(context->min), Z_LVAL(context->max)));
118
            break;
12,852✔
119
        }
120
    }
121
}
16,524✔
122

123
static zend_object* php_ort_generator_random_create(
459✔
124
    zend_class_entry* ce) {
125
    php_ort_generator_t* generator =
594✔
126
        zend_object_alloc(
459✔
127
            sizeof(php_ort_generator_t), ce);
135✔
128

129
    zend_object_std_init(&generator->std, ce);
459✔
130
    object_properties_init(&generator->std, ce);
459✔
131

132
    generator->std.handlers =
459✔
133
        &php_ort_generator_handlers;
134

135
    generator->invoke = php_ort_generator_random_invoke;
459✔
136
    generator->context =
783✔
137
        ecalloc(1, sizeof(php_ort_generator_random_context_t));
459✔
138

139
    return &generator->std;
594✔
140
}
135✔
141

142
ZEND_BEGIN_ARG_INFO_EX(
143
    php_ort_generator_random__construct_arginfo, 0, 0, 1)
144
    ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0)
145
    ZEND_ARG_TYPE_INFO(0, min, IS_LONG, 0)
146
    ZEND_ARG_TYPE_INFO(0, max, IS_LONG, 0)
147
ZEND_END_ARG_INFO()
148

149
#define ORT_GENERATOR_RANDOM_CHECK_TYPE(type, var, name) \
150
do {                                                     \
151
    if (Z_TYPE_P(var) != IS_##type) {                    \
152
        zend_throw_exception_ex(                         \
153
            php_ort_status_error_ce, 0,                  \
154
            "Expected "#type" for "#name", got %s",      \
155
            zend_zval_value_name(var));                  \
156
        return;                                          \
157
    }                                                    \
158
} while(0)
159

160
#define ORT_GENERATOR_RANDOM_CHECK_SIGNED_RANGE(var, name, min, max)\
161
do {                                                                  \
162
    if (Z_LVAL_P(var) < min || Z_LVAL_P(var) > max) {                 \
163
        zend_throw_exception_ex(                                      \
164
            php_ort_status_error_ce, 0,                               \
165
            "Value for "#name" must be between "                      \
166
                ZEND_LONG_FMT" and "                                  \
167
                ZEND_LONG_FMT", got "ZEND_LONG_FMT"",                 \
168
            (zend_long) min,                                          \
169
            (zend_long) max,                                          \
170
            Z_LVAL_P(var));                                           \
171
        return;                                                       \
172
    }                                                                 \
173
} while(0)
174

175
#define ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_RANGE(var, name, max)     \
176
do {                                                                  \
177
    if (Z_LVAL_P(var) < 0 || Z_LVAL_P(var) > max) {                   \
178
        zend_throw_exception_ex(                                      \
179
            php_ort_status_error_ce, 0,                               \
180
            "Value for "#name" must be between 0 and "                \
181
            "%d, got "ZEND_LONG_FMT"",                                \
182
            max,                                                      \
183
            Z_LVAL_P(var));                                           \
184
        return;                                                       \
185
    }                                                                 \
186
} while(0)
187

188
PHP_METHOD(Generator_Random, __construct) {
459✔
189
    php_ort_generator_t* generator =
594✔
190
        php_ort_generator_fetch(
459✔
191
            Z_OBJ_P(getThis()));
459✔
192
    php_ort_generator_random_context_t* context =
594✔
193
        (php_ort_generator_random_context_t*)
194
            generator->context;
135✔
195

196
    memset(context, 0, sizeof(
459✔
197
        php_ort_generator_random_context_t));
198

199
    zval* min = NULL;
459✔
200
    zval* max = NULL;
459✔
201

202
    ZEND_PARSE_PARAMETERS_START(1, 3)
459✔
203
        Z_PARAM_LONG(context->type)
513✔
204
        Z_PARAM_OPTIONAL
459✔
205
        Z_PARAM_ZVAL(min)
459✔
206
        Z_PARAM_ZVAL(max)
306✔
207
    ZEND_PARSE_PARAMETERS_END();
279✔
208

209
    if (ZEND_NUM_ARGS() == 1) {
459✔
210
        /* only a type provided, we set range */
211
        switch (context->type) {
153✔
212
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16:
24✔
213
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT32:
214
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT64:
215
                ZVAL_DOUBLE(&context->min, 0.0);
34✔
216
                ZVAL_DOUBLE(&context->max, 1.0);
34✔
217
                break;
34✔
218

219
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8:
12✔
220
                ZVAL_LONG(&context->min, INT8_MIN);
17✔
221
                ZVAL_LONG(&context->max, INT8_MAX);
17✔
222
                break;
17✔
223

224
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT16:
12✔
225
                ZVAL_LONG(&context->min, INT16_MIN);
17✔
226
                ZVAL_LONG(&context->max, INT16_MAX);
17✔
227
                break;
17✔
228

229
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32:
12✔
230
                ZVAL_LONG(&context->min, INT32_MIN);
17✔
231
                ZVAL_LONG(&context->max, INT32_MAX);
17✔
232
                break;
17✔
233

234
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64:
12✔
235
                ZVAL_LONG(&context->min, INT64_MIN);
17✔
236
                ZVAL_LONG(&context->max, INT64_MAX);
17✔
237
                break;
17✔
238

239
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8:
12✔
240
                ZVAL_LONG(&context->min, 0);
17✔
241
                ZVAL_LONG(&context->max, UINT8_MAX);
17✔
242
                break;
17✔
243

244
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT16:
12✔
245
                ZVAL_LONG(&context->min, 0);
17✔
246
                ZVAL_LONG(&context->max, UINT16_MAX);
17✔
247
                break;
17✔
248

249
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32:
12✔
250
                ZVAL_LONG(&context->min, 0);
17✔
251
                ZVAL_LONG(&context->max, UINT32_MAX);
17✔
252
                break;
17✔
253

254
            default:
255
                zend_throw_exception_ex(
×
256
                    php_ort_status_error_ce, 0,
257
                    "Unsupported type for Random generator: %s",
258
                    php_ort_type_name(context->type));
259
                return;
×
260
        }
261
    } else if (ZEND_NUM_ARGS() == 2) {
351✔
262
        /* type and min provided */
263

264
#define ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE(          \
265
    type, minimum, maximum) do {                         \
266
    ORT_GENERATOR_RANDOM_CHECK_TYPE(type, min, "min");   \
267
    ORT_GENERATOR_RANDOM_CHECK_SIGNED_RANGE(             \
268
        min, "min", minimum, maximum);                   \
269
    ZVAL_COPY(&context->min, min);                       \
270
    ZVAL_LONG(&context->max, maximum);                   \
271
} while(0)
272

273
#define ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_CASE(        \
274
    type, maximum) do {                                  \
275
    ORT_GENERATOR_RANDOM_CHECK_TYPE(type, min, "min");   \
276
    ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_RANGE(           \
277
        min, "min", maximum);                            \
278
    ZVAL_COPY(&context->min, min);                       \
279
    ZVAL_LONG(&context->max, maximum);                   \
280
} while(0)
281

282
        switch (context->type) {
153✔
283
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16:
24✔
284
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT32:
285
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT64:
286
                ORT_GENERATOR_RANDOM_CHECK_TYPE(
34✔
287
                    DOUBLE, min, "min");
288
                ZVAL_COPY(&context->min, min);
34✔
289
                ZVAL_DOUBLE(&context->max, 1.0);
34✔
290
                break;
34✔
291

292
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8:
12✔
293
                ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE(LONG, INT8_MIN, INT8_MAX);
17✔
294
                break;
17✔
295

296
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT16:
12✔
297
                ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE(LONG, INT16_MIN, INT16_MAX);
17✔
298
                break;
17✔
299

300
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32:
12✔
301
                ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE(LONG, INT32_MIN, INT32_MAX);
17✔
302
                break;
17✔
303

304
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64:
12✔
305
                ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE(LONG, INT64_MIN, INT64_MAX);
17✔
306
                break;
17✔
307

308
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8:
12✔
309
                ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_CASE(LONG, UINT8_MAX);
17✔
310
                break;
17✔
311

312
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT16:
12✔
313
                ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_CASE(LONG, UINT16_MAX);
17✔
314
                break;
17✔
315

316
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32:
12✔
317
                ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_CASE(LONG, UINT32_MAX);
17✔
318
                break;
17✔
319

320
            default:
321
                zend_throw_exception_ex(
×
322
                    php_ort_status_error_ce, 0,
323
                    "Unsupported type for Random generator: %s",
324
                    php_ort_type_name(context->type));
325
                return;
×
326
        }
327

328
#undef ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE
329
#undef ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_CASE
330
    } else if (ZEND_NUM_ARGS() == 3) {
198✔
331
        /* type, min and max provided */
332

333
#define ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE(        \
334
    type, minimum, maximum) do {                       \
335
    ORT_GENERATOR_RANDOM_CHECK_TYPE(                   \
336
        type, min, "min");                             \
337
    ORT_GENERATOR_RANDOM_CHECK_TYPE(                   \
338
        type, max, "max");                             \
339
    ORT_GENERATOR_RANDOM_CHECK_SIGNED_RANGE(           \
340
        min, "min", minimum, maximum);                 \
341
    ORT_GENERATOR_RANDOM_CHECK_SIGNED_RANGE(           \
342
        max, "max", minimum, maximum);                 \
343
    if (Z_LVAL_P(min) > Z_LVAL_P(max)) {               \
344
        zend_throw_exception_ex(                       \
345
            php_ort_status_error_ce, 0,                \
346
            "Min value must be less than or equal to " \
347
            "max value for Random generator");         \
348
        return;                                        \
349
    }                                                  \
350
    ZVAL_COPY(&context->min, min);                     \
351
    ZVAL_COPY(&context->max, max);                     \
352
} while(0)
353

354
#define ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_CASE(      \
355
    type,  maximum) do {                               \
356
    ORT_GENERATOR_RANDOM_CHECK_TYPE(                   \
357
        type, min, "min");                             \
358
    ORT_GENERATOR_RANDOM_CHECK_TYPE(                   \
359
        type, max, "max");                             \
360
    ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_RANGE(         \
361
        min, "min", maximum);                          \
362
    ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_RANGE(         \
363
        max, "max", maximum);                          \
364
    if (Z_LVAL_P(min) > Z_LVAL_P(max)) {               \
365
        zend_throw_exception_ex(                       \
366
            php_ort_status_error_ce, 0,                \
367
            "Min value must be less than or equal to " \
368
            "max value for Random generator");         \
369
        return;                                        \
370
    }                                                  \
371
    ZVAL_COPY(&context->min, min);                     \
372
    ZVAL_COPY(&context->max, max);                     \
373
} while(0)
374

375
        switch (context->type) {
153✔
376
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16:
24✔
377
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT32:
378
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT64:
379
                ORT_GENERATOR_RANDOM_CHECK_TYPE(
34✔
380
                    DOUBLE, min, "min");
381
                ORT_GENERATOR_RANDOM_CHECK_TYPE(
34✔
382
                    DOUBLE, max, "max");
383
                ZVAL_COPY(&context->min, min);
34✔
384
                ZVAL_COPY(&context->max, max);
34✔
385
            break;
10✔
386

387
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8:
12✔
388
                ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE(LONG, INT8_MIN, INT8_MAX);
17✔
389
                break;
5✔
390
            
391
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT16:
12✔
392
                ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE(LONG, INT16_MIN, INT16_MAX);
17✔
393
                break;
5✔
394

395
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32:
12✔
396
                ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE(LONG, INT32_MIN, INT32_MAX);
17✔
397
                break;
5✔
398

399
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64:
12✔
400
                ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE(LONG, INT64_MIN, INT64_MAX);
17✔
401
                break;
5✔
402

403
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8:
12✔
404
                ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_CASE(LONG, UINT8_MAX);
17✔
405
                break;
5✔
406

407
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT16:
12✔
408
                ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_CASE(LONG, UINT16_MAX);
17✔
409
                break;
5✔
410

411
            case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32:
12✔
412
                ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_CASE(LONG, UINT32_MAX);
17✔
413
                break;
5✔
414

415
            default:
416
                zend_throw_exception_ex(
×
417
                    php_ort_status_error_ce, 0,
418
                    "Unsupported type for Random generator: %s",
419
                    php_ort_type_name(context->type));
420
                return;
×
421
        }
422
#undef ORT_GENERATOR_RANDOM_CHECK_SIGNED_CASE
423
#undef ORT_GENERATOR_RANDOM_CHECK_UNSIGNED_CASE
424
    }
45✔
425
}
135✔
426

427
#undef ORT_GENERATOR_RANDOM_CHECK_TYPE
428

429
zend_function_entry php_ort_generator_random_methods[] = {
430
    PHP_ME(Generator_Random, __construct,
431
        php_ort_generator_random__construct_arginfo, ZEND_ACC_PUBLIC)
432
    PHP_FE_END
433
};
434

435
PHP_MINIT_FUNCTION(ORT_GENERATORS_RANDOM)
4,089✔
436
{
437
    zend_class_entry ce;
4,089✔
438

439
    INIT_NS_CLASS_ENTRY(ce,
4,089✔
440
        "ORT\\Tensor\\Generator",
441
        "Random", php_ort_generator_random_methods);
2,994✔
442
    php_ort_generator_random_ce =
7,083✔
443
        zend_register_internal_class_ex(
4,089✔
444
            &ce, php_ort_generator_internal_ce);
1,095✔
445
    php_ort_generator_random_ce->create_object =
4,089✔
446
        php_ort_generator_random_create;
447
    php_ort_generator_random_ce->ce_flags |= ZEND_ACC_FINAL;
4,089✔
448

449
    return SUCCESS;
4,089✔
450
}
1,095✔
451

452
PHP_MSHUTDOWN_FUNCTION(ORT_GENERATORS_RANDOM) 
4,089✔
453
{
454
    return SUCCESS;
4,089✔
455
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc