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

krakjoe / ort / 16471861891

23 Jul 2025 01:21PM UTC coverage: 92.895% (-0.9%) from 93.769%
16471861891

push

github

krakjoe
show diff in ci

5831 of 6277 relevant lines covered (92.89%)

41484.57 hits per line

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

91.72
/src/maths.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
#include "ort.h"
20
#include "status.h"
21

22
#include "maths.h"
23
#include "maths/api.h"
24
#include "maths/cast.h"
25
#include "maths/result.h"
26
#include "maths/pool.h"
27
#include "maths/promotion.h"
28

29
#include "maths/schema/abs.h"
30
#include "maths/schema/acos.h"
31
#include "maths/schema/arccos.h"
32
#include "maths/schema/arccosh.h"
33
#include "maths/schema/arcsin.h"
34
#include "maths/schema/arcsinh.h"
35
#include "maths/schema/arctan.h"
36
#include "maths/schema/arctanh.h"
37
#include "maths/schema/atan.h"
38
#include "maths/schema/add.h"
39
#include "maths/schema/asin.h"
40
#include "maths/schema/cbrt.h"
41
#include "maths/schema/ceil.h"
42
#include "maths/schema/cos.h"
43
#include "maths/schema/cosh.h"
44
#include "maths/schema/div.h"
45
#include "maths/schema/dot.h"
46
#include "maths/schema/exp.h"
47
#include "maths/schema/exp2.h"
48
#include "maths/schema/floor.h"
49
#include "maths/schema/log.h"
50
#include "maths/schema/log2.h"
51
#include "maths/schema/log10.h"
52
#include "maths/schema/matmul.h"
53
#include "maths/schema/max.h"
54
#include "maths/schema/mean.h"
55
#include "maths/schema/min.h"
56
#include "maths/schema/mod.h"
57
#include "maths/schema/mul.h"
58
#include "maths/schema/neg.h"
59
#include "maths/schema/pow.h"
60
#include "maths/schema/recip.h"
61
#include "maths/schema/round.h"
62
#include "maths/schema/sign.h"
63
#include "maths/schema/sin.h"
64
#include "maths/schema/sinh.h"
65
#include "maths/schema/softmax.h"
66
#include "maths/schema/sqrt.h"
67
#include "maths/schema/sub.h"
68
#include "maths/schema/sum.h"
69
#include "maths/schema/tan.h"
70
#include "maths/schema/tanh.h"
71
#include "maths/schema/trunc.h"
72

73
typedef struct _php_ort_math_schema_t {
74
    const ort_math_promotion_schema_t* schema;
75
    zend_string*                            symbol;
76
    zend_object std;
77
} php_ort_math_schema_t;
78

79
zend_class_entry *php_ort_math_schema_ce;
80
zend_object_handlers php_ort_math_schema_handlers;
81

82
static zend_always_inline php_ort_math_schema_t* php_ort_math_schema_fetch(zend_object *o) {
83
    return (php_ort_math_schema_t*) (((char*) o) - XtOffsetOf(php_ort_math_schema_t, std));
84
}
85

86
static zend_object* php_ort_math_schema_create(zend_class_entry *ce) {
368✔
87
    php_ort_math_schema_t *ort = 
368✔
88
        zend_object_alloc(sizeof(php_ort_math_schema_t), ce);
368✔
89
        
90
    zend_object_std_init(&ort->std, ce);
368✔
91
    object_properties_init(&ort->std, ce);
368✔
92

93
    ort->std.handlers = &php_ort_math_schema_handlers;
368✔
94
    return &ort->std;
368✔
95
}
96

97
static HashTable* php_ort_math_schema_debug(zend_object *zo, int *temp) {
×
98
    php_ort_math_schema_t *ort = php_ort_math_schema_fetch(zo);
×
99
    HashTable *debug;
×
100

101
    ALLOC_HASHTABLE(debug);
×
102
    zend_hash_init(debug, 3, NULL, ZVAL_PTR_DTOR, 0);
×
103

104
    if (ort->symbol) {
×
105
        zval symbol;
×
106

107
        ZVAL_STR_COPY(&symbol, ort->symbol);
×
108

109
        zend_hash_str_update(debug,
×
110
            "symbol", sizeof("symbol") - 1,
111
            &symbol);
112
    }
113

114
__php_ort_tensor_debug_return:
×
115
    *temp = 1;
×
116

117
    return debug;
×
118
}
119

120
void php_ort_math_schema_free(zend_object *zo) {
368✔
121
    php_ort_math_schema_t* ort = php_ort_math_schema_fetch(zo);
368✔
122

123
    if (ort->symbol) {
368✔
124
        zend_string_release(ort->symbol);
368✔
125
    }
126

127
    zend_object_std_dtor(zo);
368✔
128
}
368✔
129

130
#define ORT_MATH_UNARY_FUNCTION_IMPL(fname)                    \
131
    ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(                    \
132
        php_ort_math_##fname##_arginfo, 0, 1, ORT\\Tensor, 0) \
133
        ZEND_ARG_OBJ_INFO(0, tensor, ORT\\Tensor, 0)          \
134
    ZEND_END_ARG_INFO()                                        \
135
    PHP_FUNCTION(fname)                                        \
136
    {                                                          \
137
        zval *tensor_zv;                                       \
138
        ZEND_PARSE_PARAMETERS_START(1, 1)                      \
139
            Z_PARAM_OBJECT_OF_CLASS(tensor_zv,                 \
140
                php_ort_tensor_interface_ce)                   \
141
        ZEND_PARSE_PARAMETERS_END();                           \
142
        php_ort_tensor_t* tensor_ort =                         \
143
            php_ort_tensor_fetch(Z_OBJ_P(tensor_zv));          \
144
        ort_tensor_t* result =                                 \
145
            ort_math_result_##fname(tensor_ort->object);       \
146
        object_init_ex(return_value,                           \
147
            php_ort_tensor_transient_ce);                      \
148
        php_ort_tensor_t* rv =                                 \
149
            php_ort_tensor_fetch(Z_OBJ_P(return_value));       \
150
        rv->object = result;                                   \
151
    }
152

153
#define ORT_MATH_BINARY_FUNCTION_IMPL(fname)                    \
154
    ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(                     \
155
        php_ort_math_##fname##_arginfo, 0, 2, ORT\\Tensor, 0)  \
156
        ZEND_ARG_OBJ_INFO(0, tensor_a, ORT\\Tensor, 0)         \
157
        ZEND_ARG_INFO(0, tensor_b_or_scalar)                    \
158
    ZEND_END_ARG_INFO()                                         \
159
    PHP_FUNCTION(fname)                                         \
160
    {                                                           \
161
        zval *tensor_a_zv, *tensor_b_or_scalar;                 \
162
        ZEND_PARSE_PARAMETERS_START(2, 2)                       \
163
            Z_PARAM_OBJECT_OF_CLASS(tensor_a_zv,                \
164
                php_ort_tensor_interface_ce)                    \
165
            Z_PARAM_ZVAL(tensor_b_or_scalar)                    \
166
        ZEND_PARSE_PARAMETERS_END();                            \
167
        php_ort_tensor_t* tensor_a_ort =                        \
168
            php_ort_tensor_fetch(Z_OBJ_P(tensor_a_zv));         \
169
        ort_tensor_t* result = NULL;                            \
170
        if (Z_TYPE_P(tensor_b_or_scalar) == IS_OBJECT &&        \
171
            instanceof_function(Z_OBJCE_P(tensor_b_or_scalar),  \
172
                php_ort_tensor_interface_ce)) {                 \
173
            php_ort_tensor_t* tensor_b_ort =                    \
174
                php_ort_tensor_fetch(Z_OBJ_P(tensor_b_or_scalar)); \
175
            result = ort_math_result_##fname(                   \
176
                tensor_a_ort->object, tensor_b_ort->object);    \
177
        } else if (Z_TYPE_P(tensor_b_or_scalar) == IS_LONG ||   \
178
                   Z_TYPE_P(tensor_b_or_scalar) == IS_DOUBLE || \
179
                   (Z_TYPE_P(tensor_b_or_scalar) == IS_TRUE ||  \
180
                    Z_TYPE_P(tensor_b_or_scalar) == IS_FALSE)) { \
181
            result = ort_math_result_##fname##_scalar(          \
182
                tensor_a_ort->object, tensor_b_or_scalar);      \
183
        } else {                                                \
184
            php_ort_status_throw(                               \
185
                php_ort_status_math_invalidtype_ce,             \
186
                #fname ": second argument must be a Tensor or numeric value"); \
187
            return;                                             \
188
        }                                                       \
189
        object_init_ex(return_value,                            \
190
            php_ort_tensor_transient_ce);                       \
191
        php_ort_tensor_t* rv =                                  \
192
            php_ort_tensor_fetch(Z_OBJ_P(return_value));        \
193
        rv->object = result;                                    \
194
    }
195

196

197
#define ORT_MATH_REDUCTION_TENSOR_FUNCTION_IMPL(fname)             \
198
    ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(                        \
199
            php_ort_math_reduce_tensor_##fname##_arginfo,          \
200
                0, 1, ORT\\Tensor, 0)                             \
201
        ZEND_ARG_OBJ_INFO(0, tensor, ORT\\Tensor, 0)              \
202
    ZEND_END_ARG_INFO()                                            \
203
    PHP_NAMED_FUNCTION(php_ort_math_reduce_tensor_##fname)         \
204
    {                                                              \
205
        zval *tensor_zv;                                           \
206
        ZEND_PARSE_PARAMETERS_START(1, 1)                          \
207
            Z_PARAM_OBJECT_OF_CLASS(tensor_zv,                     \
208
                php_ort_tensor_interface_ce)                       \
209
        ZEND_PARSE_PARAMETERS_END();                               \
210
        php_ort_tensor_t* tensor_ort =                             \
211
            php_ort_tensor_fetch(Z_OBJ_P(tensor_zv));              \
212
        ort_tensor_t* result =                                     \
213
            ort_math_result_reduce_tensor_##fname(                 \
214
                tensor_ort->object);                               \
215
        object_init_ex(return_value,                               \
216
            php_ort_tensor_transient_ce);                          \
217
        php_ort_tensor_t* rv =                                     \
218
            php_ort_tensor_fetch(Z_OBJ_P(return_value));           \
219
        rv->object = result;                                       \
220
    }
221

222
// Macro for reduction functions (Tensor, axis, keepdims)
223
#define ORT_MATH_REDUCTION_AXIS_FUNCTION_IMPL(fname)               \
224
    ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(                        \
225
            php_ort_math_reduce_axis_##fname##_arginfo, 0, 2, ORT\\Tensor, 0) \
226
        ZEND_ARG_OBJ_INFO(0, tensor, ORT\\Tensor, 0)              \
227
        ZEND_ARG_TYPE_INFO(0, axis, IS_LONG, 0)                    \
228
        ZEND_ARG_TYPE_INFO(0, keepdims, _IS_BOOL, 0)               \
229
    ZEND_END_ARG_INFO()                                            \
230
    PHP_NAMED_FUNCTION(php_ort_math_reduce_axis_##fname)           \
231
    {                                                              \
232
        zval *tensor_zv;                                           \
233
        zend_long axis = 0;                                        \
234
        zend_bool keepdims = 0;                                    \
235
        ZEND_PARSE_PARAMETERS_START(2, 3)                          \
236
            Z_PARAM_OBJECT_OF_CLASS(tensor_zv,                     \
237
                php_ort_tensor_interface_ce)                       \
238
            Z_PARAM_LONG(axis)                                     \
239
            Z_PARAM_OPTIONAL                                       \
240
            Z_PARAM_BOOL(keepdims)                                 \
241
        ZEND_PARSE_PARAMETERS_END();                               \
242
        php_ort_tensor_t* tensor_ort =                             \
243
            php_ort_tensor_fetch(Z_OBJ_P(tensor_zv));              \
244
        ort_tensor_t* result = ort_math_result_reduce_axis_##fname(\
245
            tensor_ort->object, axis, keepdims);                   \
246
        object_init_ex(return_value,                               \
247
            php_ort_tensor_transient_ce);                          \
248
        php_ort_tensor_t* rv =                                     \
249
            php_ort_tensor_fetch(Z_OBJ_P(return_value));           \
250
        rv->object = result;                                       \
251
    }
252
/* Mathematical functions in ORT\Math namespace */
253

254
ORT_MATH_BINARY_FUNCTION_IMPL(add)
8,376✔
255
ORT_MATH_BINARY_FUNCTION_IMPL(multiply)
2,032✔
256
ORT_MATH_BINARY_FUNCTION_IMPL(subtract)
1,520✔
257
ORT_MATH_BINARY_FUNCTION_IMPL(divide)
1,728✔
258

259
ORT_MATH_BINARY_FUNCTION_IMPL(pow)
1,224✔
260
ORT_MATH_BINARY_FUNCTION_IMPL(mod)
1,248✔
261

262
ORT_MATH_UNARY_FUNCTION_IMPL(sin)
368✔
263
ORT_MATH_UNARY_FUNCTION_IMPL(cos)
368✔
264
ORT_MATH_UNARY_FUNCTION_IMPL(tan)
368✔
265
ORT_MATH_UNARY_FUNCTION_IMPL(asin)
352✔
266
ORT_MATH_UNARY_FUNCTION_IMPL(acos)
352✔
267
ORT_MATH_UNARY_FUNCTION_IMPL(arccos)
32✔
268
ORT_MATH_UNARY_FUNCTION_IMPL(arcsin)
32✔
269
ORT_MATH_UNARY_FUNCTION_IMPL(arctan)
32✔
270
ORT_MATH_UNARY_FUNCTION_IMPL(arccosh)
32✔
271
ORT_MATH_UNARY_FUNCTION_IMPL(arcsinh)
32✔
272
ORT_MATH_UNARY_FUNCTION_IMPL(arctanh)
32✔
273
ORT_MATH_UNARY_FUNCTION_IMPL(atan)
352✔
274
ORT_MATH_UNARY_FUNCTION_IMPL(sinh)
352✔
275
ORT_MATH_UNARY_FUNCTION_IMPL(cosh)
352✔
276
ORT_MATH_UNARY_FUNCTION_IMPL(tanh)
352✔
277
ORT_MATH_UNARY_FUNCTION_IMPL(exp)
368✔
278
ORT_MATH_UNARY_FUNCTION_IMPL(exp2)
368✔
279
ORT_MATH_UNARY_FUNCTION_IMPL(log)
368✔
280
ORT_MATH_UNARY_FUNCTION_IMPL(log2)
368✔
281
ORT_MATH_UNARY_FUNCTION_IMPL(log10)
368✔
282
ORT_MATH_UNARY_FUNCTION_IMPL(abs)
160✔
283
ORT_MATH_UNARY_FUNCTION_IMPL(recip)
352✔
284
ORT_MATH_UNARY_FUNCTION_IMPL(neg)
304✔
285
ORT_MATH_UNARY_FUNCTION_IMPL(cbrt)
368✔
286
ORT_MATH_UNARY_FUNCTION_IMPL(ceil)
160✔
287
ORT_MATH_UNARY_FUNCTION_IMPL(floor)
160✔
288
ORT_MATH_UNARY_FUNCTION_IMPL(round)
160✔
289
ORT_MATH_UNARY_FUNCTION_IMPL(trunc)
160✔
290
ORT_MATH_UNARY_FUNCTION_IMPL(sign)
208✔
291
ORT_MATH_UNARY_FUNCTION_IMPL(sqrt)
752✔
292

293
ORT_MATH_REDUCTION_TENSOR_FUNCTION_IMPL(min)
160✔
294
ORT_MATH_REDUCTION_AXIS_FUNCTION_IMPL(min)
1,088✔
295

296
ORT_MATH_REDUCTION_TENSOR_FUNCTION_IMPL(max)
160✔
297
ORT_MATH_REDUCTION_AXIS_FUNCTION_IMPL(max)
1,088✔
298

299
ORT_MATH_REDUCTION_TENSOR_FUNCTION_IMPL(mean)
160✔
300
ORT_MATH_REDUCTION_AXIS_FUNCTION_IMPL(mean)
1,088✔
301

302
ORT_MATH_REDUCTION_TENSOR_FUNCTION_IMPL(sum)
112✔
303
ORT_MATH_REDUCTION_AXIS_FUNCTION_IMPL(sum)
1,152✔
304

305
ORT_MATH_REDUCTION_AXIS_FUNCTION_IMPL(softmax)
416✔
306

307
ORT_MATH_REDUCTION_TENSOR_FUNCTION_IMPL(argmax)
176✔
308
ORT_MATH_REDUCTION_AXIS_FUNCTION_IMPL(argmax)
1,088✔
309

310
/* Dot reduction function */
311
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(php_ort_math_dot_arginfo, 0, 1, ORT\\Tensor, 0)
312
    ZEND_ARG_OBJ_INFO(0, tensor_a, ORT\\Tensor, 0)
313
    ZEND_ARG_OBJ_INFO(0, tensor_b, ORT\\Tensor, 0)
314
ZEND_END_ARG_INFO()
315

316
PHP_FUNCTION(dot)
144✔
317
{
318
    zval *tensor_a, *tensor_b;
144✔
319

320
    ZEND_PARSE_PARAMETERS_START(2, 2)
144✔
321
        Z_PARAM_OBJECT_OF_CLASS(tensor_a, php_ort_tensor_interface_ce)
288✔
322
        Z_PARAM_OBJECT_OF_CLASS(tensor_b, php_ort_tensor_interface_ce)
288✔
323
    ZEND_PARSE_PARAMETERS_END();
144✔
324

325
    php_ort_tensor_t* tensor_a_ort = php_ort_tensor_fetch(Z_OBJ_P(tensor_a));
144✔
326
    php_ort_tensor_t* tensor_b_ort = php_ort_tensor_fetch(Z_OBJ_P(tensor_b));
144✔
327
    ort_tensor_t* result = ort_math_result_dot(
144✔
328
        tensor_a_ort->object, tensor_b_ort->object);
329

330
    /* Create PHP tensor object for result */
331
    object_init_ex(return_value,
144✔
332
        php_ort_tensor_transient_ce);
333
    php_ort_tensor_t* rv =
144✔
334
        php_ort_tensor_fetch(Z_OBJ_P(return_value));
144✔
335
    rv->object = result;
144✔
336
}
337

338
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(php_ort_math_matmul_arginfo, 0, 2, ORT\\Tensor, 0)
339
    ZEND_ARG_OBJ_INFO(0, matrix_a, ORT\\Tensor, 0)
340
    ZEND_ARG_OBJ_INFO(0, matrix_b, ORT\\Tensor, 0)
341
ZEND_END_ARG_INFO()
342

343
PHP_FUNCTION(matmul)
336✔
344
{
345
    zval *matrix_a_zv, *matrix_b_zv;
336✔
346

347
    ZEND_PARSE_PARAMETERS_START(2, 2)
336✔
348
        Z_PARAM_OBJECT_OF_CLASS(matrix_a_zv, php_ort_tensor_interface_ce)
672✔
349
        Z_PARAM_OBJECT_OF_CLASS(matrix_b_zv, php_ort_tensor_interface_ce)
672✔
350
    ZEND_PARSE_PARAMETERS_END();
336✔
351

352
    php_ort_tensor_t* matrix_a_ort = php_ort_tensor_fetch(Z_OBJ_P(matrix_a_zv));
336✔
353
    php_ort_tensor_t* matrix_b_ort = php_ort_tensor_fetch(Z_OBJ_P(matrix_b_zv));
336✔
354
    
355
    ort_tensor_t* result = ort_math_result_matmul(matrix_a_ort->object, matrix_b_ort->object);
336✔
356

357
    object_init_ex(return_value,
336✔
358
        php_ort_tensor_transient_ce);
359
    php_ort_tensor_t* rv =
336✔
360
        php_ort_tensor_fetch(Z_OBJ_P(return_value));
336✔
361
    rv->object = result;
336✔
362
}
363

364
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(php_ort_math_backend_arginfo, 0, 0, MAY_BE_STRING|MAY_BE_FALSE)
365
ZEND_END_ARG_INFO()
366

367
PHP_FUNCTION(backend)
8✔
368
{
369
    ZEND_PARSE_PARAMETERS_NONE();
8✔
370

371
#ifdef ORT_BACKEND_ENABLED
372
    RETURN_STRING(ORT_BACKEND_NAME);
7✔
373
#else
374
    RETURN_FALSE;
1✔
375
#endif
376
}
377

378
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_math_cores_arginfo, 0, 0, IS_LONG, 0)
379
    ZEND_ARG_TYPE_INFO(0, max, _IS_BOOL, 0)
380
ZEND_END_ARG_INFO()
381

382
PHP_FUNCTION(cores)
48✔
383
{
384
    zend_bool max = false;
48✔
385

386
    ZEND_PARSE_PARAMETERS_START(0, 1);
48✔
387
        Z_PARAM_OPTIONAL
48✔
388
        Z_PARAM_BOOL(max)
56✔
389
    ZEND_PARSE_PARAMETERS_END();
48✔
390

391
    if (max) {
48✔
392
        RETURN_LONG(
8✔
393
            ort_pool_max());
394
    }
395

396
    RETURN_LONG(
40✔
397
        ort_pool_cores());
398
}
399

400
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_math_threshold_arginfo, 0, 0, IS_LONG, 0)
401
    ZEND_ARG_TYPE_INFO(0, default, _IS_BOOL, 0)
402
ZEND_END_ARG_INFO()
403

404
PHP_FUNCTION(threshold)
40✔
405
{
406
    zend_bool _default = false;
40✔
407

408
    ZEND_PARSE_PARAMETERS_START(0, 1);
40✔
409
        Z_PARAM_OPTIONAL
40✔
410
        Z_PARAM_BOOL(_default)
56✔
411
    ZEND_PARSE_PARAMETERS_END();
40✔
412

413
    if (_default) {
40✔
414
        RETURN_LONG(ORT_SCALE_THRESHOLD);
16✔
415
    }
416

417
    RETURN_LONG(
24✔
418
        ort_pool_threshold());
419
}
420

421
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_math_scale_arginfo, 0, 2, IS_MIXED, 0)
422
    ZEND_ARG_TYPE_INFO(0, cores, IS_LONG, 0)
423
    ZEND_ARG_CALLABLE_INFO(0, code, 0)
424
    ZEND_ARG_TYPE_INFO(0, threshold, IS_LONG, 0)
425
ZEND_END_ARG_INFO()
426

427
PHP_FUNCTION(scale)
16✔
428
{
429
    ort_pool_scale_t scale =
16✔
430
        (ort_pool_scale_t) {
431
            .kind = ORT_POOL_SCALE_CORES
432
    };
433

434
    zval *code;
16✔
435
    zend_fcall_info fci = empty_fcall_info;
16✔
436
    zend_fcall_info_cache fcc = empty_fcall_info_cache;
16✔
437

438
    ZEND_PARSE_PARAMETERS_START(2, 3);
16✔
439
        Z_PARAM_LONG(scale.cores)
32✔
440
        Z_PARAM_FUNC(fci, fcc)
32✔
441
        Z_PARAM_OPTIONAL
16✔
442
        Z_PARAM_LONG(scale.threshold)
24✔
443
    ZEND_PARSE_PARAMETERS_END();
16✔
444

445
    if (ZEND_NUM_ARGS() > 2) {
16✔
446
        /* Request threshold scaling */
447
        scale.kind |=
8✔
448
            ORT_POOL_SCALE_THRESHOLD;
449
    }
450

451
    scale = ort_pool_scale(&scale);
16✔
452

453
    php_ort_status_flow(
16✔
454
        (scale.kind & ORT_POOL_SCALE_ERROR),
455
        {
456
            return;
457
        },
458
        php_ort_status_scaling_error_ce,
459
        "Scaling error occured, please review API usage");
460

461
    fci.retval = return_value;
16✔
462
    zend_call_function(
16✔
463
        &fci, &fcc);
464

465
    ort_pool_scale(&scale);
16✔
466
}
467

468
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(php_ort_math_cast_arginfo, 0, 2, ORT\\Tensor, 0)
469
    ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0)
470
    ZEND_ARG_OBJ_INFO(0, tensor, ORT\\Tensor, 0)
471
ZEND_END_ARG_INFO()
472

473
PHP_FUNCTION(cast)
24✔
474
{
475
    zend_long type;
24✔
476
    zval *tensor;
24✔
477
    zend_long count = 0;
24✔
478

479
    ZEND_PARSE_PARAMETERS_START(2, 2)
24✔
480
        Z_PARAM_LONG(type)
48✔
481
        Z_PARAM_OBJECT_OF_CLASS(tensor, php_ort_tensor_interface_ce)
48✔
482
    ZEND_PARSE_PARAMETERS_END();
24✔
483

484
    php_ort_tensor_t* iv = php_ort_tensor_fetch(Z_OBJ_P(tensor));
24✔
485

486
    object_init_ex(return_value,
24✔
487
        php_ort_tensor_transient_ce);
488

489
    php_ort_tensor_t* rv =
24✔
490
        php_ort_tensor_fetch(Z_OBJ_P(return_value));
24✔
491
    
492
    rv->object =
48✔
493
        ort_math_result_tensor(
24✔
494
            iv->object->shape,
24✔
495
            iv->object->dimensions, 
24✔
496
            (ONNXTensorElementDataType) type,
497
            "cast");
498
    
499
    ort_math_cast_buffer(
24✔
500
        iv->object->data,
24✔
501
        rv->object->data,
502
        iv->object->type,
503
        type,
504
        iv->object->elements);
24✔
505
}
506

507
/* Function table for ORT\Math namespace */
508
static const zend_function_entry php_ort_math_functions[] = {
509
    ZEND_NS_FE("ORT\\Math", add, php_ort_math_add_arginfo)
510
    ZEND_NS_FE("ORT\\Math", multiply, php_ort_math_multiply_arginfo) 
511
    ZEND_NS_FE("ORT\\Math", subtract, php_ort_math_subtract_arginfo)
512
    ZEND_NS_FE("ORT\\Math", divide, php_ort_math_divide_arginfo)
513
    ZEND_NS_FE("ORT\\Math", sqrt, php_ort_math_sqrt_arginfo)
514
    ZEND_NS_FE("ORT\\Math", sin, php_ort_math_sin_arginfo)
515
    ZEND_NS_FE("ORT\\Math", cos, php_ort_math_cos_arginfo)
516
    ZEND_NS_FE("ORT\\Math", exp, php_ort_math_exp_arginfo)
517
    ZEND_NS_FE("ORT\\Math", log, php_ort_math_log_arginfo)
518
    ZEND_NS_FE("ORT\\Math", matmul, php_ort_math_matmul_arginfo)
519
    ZEND_NS_FE("ORT\\Math", asin, php_ort_math_asin_arginfo)
520
    ZEND_NS_FE("ORT\\Math", acos, php_ort_math_acos_arginfo)
521
    ZEND_NS_FE("ORT\\Math", atan, php_ort_math_atan_arginfo)
522
    ZEND_NS_FE("ORT\\Math", sinh, php_ort_math_sinh_arginfo)
523
    ZEND_NS_FE("ORT\\Math", cosh, php_ort_math_cosh_arginfo)
524
    ZEND_NS_FE("ORT\\Math", tanh, php_ort_math_tanh_arginfo)
525
    ZEND_NS_FE("ORT\\Math", exp2, php_ort_math_exp2_arginfo)
526
    ZEND_NS_FE("ORT\\Math", log2, php_ort_math_log2_arginfo)
527
    ZEND_NS_FE("ORT\\Math", log10, php_ort_math_log10_arginfo)
528
    ZEND_NS_FE("ORT\\Math", cbrt, php_ort_math_cbrt_arginfo)
529
    ZEND_NS_FE("ORT\\Math", ceil, php_ort_math_ceil_arginfo)
530
    ZEND_NS_FE("ORT\\Math", floor, php_ort_math_floor_arginfo)
531
    ZEND_NS_FE("ORT\\Math", round, php_ort_math_round_arginfo)
532
    ZEND_NS_FE("ORT\\Math", sign, php_ort_math_sign_arginfo)
533
    ZEND_NS_FE("ORT\\Math", tan, php_ort_math_tan_arginfo)
534
    ZEND_NS_FE("ORT\\Math", abs, php_ort_math_abs_arginfo)
535
    ZEND_NS_FE("ORT\\Math", pow, php_ort_math_pow_arginfo)
536
    ZEND_NS_FE("ORT\\Math", mod, php_ort_math_mod_arginfo)
537

538
    ZEND_NS_FE("ORT\\Math", neg,     php_ort_math_neg_arginfo)
539
    ZEND_NS_FE("ORT\\Math", recip,   php_ort_math_recip_arginfo)
540
    ZEND_NS_FE("ORT\\Math", trunc,   php_ort_math_trunc_arginfo)
541

542
    ZEND_NS_FE("ORT\\Math", arccos, php_ort_math_arccos_arginfo)
543
    ZEND_NS_FE("ORT\\Math", arccosh, php_ort_math_arccosh_arginfo)
544
    ZEND_NS_FE("ORT\\Math", arcsin, php_ort_math_arcsin_arginfo)
545
    ZEND_NS_FE("ORT\\Math", arcsinh, php_ort_math_arcsinh_arginfo)
546
    ZEND_NS_FE("ORT\\Math", arctan, php_ort_math_arctan_arginfo)
547
    ZEND_NS_FE("ORT\\Math", arctanh, php_ort_math_arctanh_arginfo)
548

549
    ZEND_NS_NAMED_FE("ORT\\Math\\reduce\\tensor", min, php_ort_math_reduce_tensor_min, php_ort_math_reduce_tensor_min_arginfo)
550
    ZEND_NS_NAMED_FE("ORT\\Math\\reduce\\axis",   min, php_ort_math_reduce_axis_min,   php_ort_math_reduce_axis_min_arginfo)
551
    ZEND_NS_NAMED_FE("ORT\\Math\\reduce\\tensor", max, php_ort_math_reduce_tensor_max, php_ort_math_reduce_tensor_max_arginfo)
552
    ZEND_NS_NAMED_FE("ORT\\Math\\reduce\\axis",   max, php_ort_math_reduce_axis_max,   php_ort_math_reduce_axis_max_arginfo)
553
    ZEND_NS_NAMED_FE("ORT\\Math\\reduce\\tensor", mean, php_ort_math_reduce_tensor_mean, php_ort_math_reduce_tensor_mean_arginfo)
554
    ZEND_NS_NAMED_FE("ORT\\Math\\reduce\\axis",   mean, php_ort_math_reduce_axis_mean,   php_ort_math_reduce_axis_mean_arginfo)
555
    ZEND_NS_NAMED_FE("ORT\\Math\\reduce\\tensor", sum, php_ort_math_reduce_tensor_sum, php_ort_math_reduce_tensor_sum_arginfo)
556
    ZEND_NS_NAMED_FE("ORT\\Math\\reduce\\axis",   sum, php_ort_math_reduce_axis_sum,   php_ort_math_reduce_axis_sum_arginfo)
557
    ZEND_NS_NAMED_FE("ORT\\Math\\reduce\\tensor", argmax, php_ort_math_reduce_tensor_argmax, php_ort_math_reduce_tensor_argmax_arginfo)
558
    ZEND_NS_NAMED_FE("ORT\\Math\\reduce\\axis",   argmax, php_ort_math_reduce_axis_argmax,   php_ort_math_reduce_axis_argmax_arginfo)
559
    ZEND_NS_NAMED_FE("ORT\\Math\\reduce\\axis",   softmax, php_ort_math_reduce_axis_softmax,   php_ort_math_reduce_axis_softmax_arginfo)
560

561
    ZEND_NS_FE("ORT\\Math\\reduce", dot, php_ort_math_dot_arginfo)
562

563
    ZEND_NS_FE("ORT\\Math", backend,   php_ort_math_backend_arginfo)
564
    ZEND_NS_FE("ORT\\Math", cast,      php_ort_math_cast_arginfo)
565

566
    ZEND_NS_FE("ORT\\Math", scale,            php_ort_math_scale_arginfo)
567
    ZEND_NS_FE("ORT\\Math\\scale", cores,     php_ort_math_cores_arginfo)
568
    ZEND_NS_FE("ORT\\Math\\scale", threshold, php_ort_math_threshold_arginfo)
569
    ZEND_FE_END
570
};
571

572
/* {{{ */
573
ZEND_BEGIN_ARG_INFO_EX(php_ort_math_schema___construct_arginfo, 0, 0, 1)
574
    ZEND_ARG_TYPE_INFO(0, symbol, IS_STRING, 0)
575
ZEND_END_ARG_INFO()
576

577
PHP_METHOD(ONNX_Math_Schema, __construct)
368✔
578
{
579
    php_ort_math_schema_t *ort = php_ort_math_schema_fetch(Z_OBJ_P(getThis()));
368✔
580
    zend_string *symbol;
368✔
581

582
    ZEND_PARSE_PARAMETERS_START(1, 1)
368✔
583
        Z_PARAM_STR(symbol)
736✔
584
    ZEND_PARSE_PARAMETERS_END();
368✔
585

586
    if (zend_string_equals_literal_ci(symbol, "abs")) {
368✔
587
        ort->schema = &ort_math_promotion_schema_abs;
8✔
588
    } else if (zend_string_equals_literal_ci(symbol, "acos")) {
360✔
589
        ort->schema = &ort_math_promotion_schema_acos;
8✔
590
    } else if (zend_string_equals_literal_ci(symbol, "add")) {
352✔
591
        ort->schema = &ort_math_promotion_schema_add;
32✔
592
    } else if (zend_string_equals_literal_ci(symbol, "arccos")) {
320✔
593
        ort->schema = &ort_math_promotion_schema_arccos;
8✔
594
    } else if (zend_string_equals_literal_ci(symbol, "arccosh")) {
312✔
595
        ort->schema = &ort_math_promotion_schema_arccosh;
8✔
596
    } else if (zend_string_equals_literal_ci(symbol, "arcsin")) {
304✔
597
        ort->schema = &ort_math_promotion_schema_arcsin;
8✔
598
    } else if (zend_string_equals_literal_ci(symbol, "arcsinh")) {
296✔
599
        ort->schema = &ort_math_promotion_schema_arcsinh;
8✔
600
    } else if (zend_string_equals_literal_ci(symbol, "arctan")) {
288✔
601
        ort->schema = &ort_math_promotion_schema_arctan;
8✔
602
    } else if (zend_string_equals_literal_ci(symbol, "arctanh")) {
280✔
603
        ort->schema = &ort_math_promotion_schema_arctanh;
8✔
604
    } else if (zend_string_equals_literal_ci(symbol, "asin")) {
272✔
605
        ort->schema = &ort_math_promotion_schema_asin;
8✔
606
    } else if (zend_string_equals_literal_ci(symbol, "atan")) {
264✔
607
        ort->schema = &ort_math_promotion_schema_atan;
8✔
608
    } else if (zend_string_equals_literal_ci(symbol, "cos")) {
256✔
609
        ort->schema = &ort_math_promotion_schema_cos;
8✔
610
    } else if (zend_string_equals_literal_ci(symbol, "cbrt")) {
248✔
611
        ort->schema = &ort_math_promotion_schema_cbrt;
8✔
612
    } else if (zend_string_equals_literal_ci(symbol, "ceil")) {
240✔
613
        ort->schema = &ort_math_promotion_schema_ceil;
8✔
614
    } else if (zend_string_equals_literal_ci(symbol, "cosh")) {
232✔
615
        ort->schema = &ort_math_promotion_schema_cosh;
8✔
616
    } else if (zend_string_equals_literal_ci(symbol, "div")) {
224✔
617
        ort->schema = &ort_math_promotion_schema_div;
8✔
618
    } else if (zend_string_equals_literal_ci(symbol, "dot")) {
216✔
619
        ort->schema = &ort_math_promotion_schema_dot;
8✔
620
    } else if (zend_string_equals_literal_ci(symbol, "exp")) {
208✔
621
        ort->schema = &ort_math_promotion_schema_exp;
8✔
622
    } else if (zend_string_equals_literal_ci(symbol, "exp2")) {
200✔
623
        ort->schema = &ort_math_promotion_schema_exp2;
8✔
624
    } else if (zend_string_equals_literal_ci(symbol, "floor")) {
192✔
625
        ort->schema = &ort_math_promotion_schema_floor;
8✔
626
    } else if (zend_string_equals_literal_ci(symbol, "log")) {
184✔
627
        ort->schema = &ort_math_promotion_schema_log;
8✔
628
    } else if (zend_string_equals_literal_ci(symbol, "log2")) {
176✔
629
        ort->schema = &ort_math_promotion_schema_log2;
8✔
630
    } else if (zend_string_equals_literal_ci(symbol, "log10")) {
168✔
631
        ort->schema = &ort_math_promotion_schema_log10;
8✔
632
    } else if (zend_string_equals_literal_ci(symbol, "matmul")) {
160✔
633
        ort->schema = &ort_math_promotion_schema_matmul;
8✔
634
    } else if (zend_string_equals_literal_ci(symbol, "max")) {
152✔
635
        ort->schema = &ort_math_promotion_schema_max;
8✔
636
    } else if (zend_string_equals_literal_ci(symbol, "mean")) {
144✔
637
        ort->schema = &ort_math_promotion_schema_mean;
8✔
638
    } else if (zend_string_equals_literal_ci(symbol, "min")) {
136✔
639
        ort->schema = &ort_math_promotion_schema_min;
8✔
640
    } else if (zend_string_equals_literal_ci(symbol, "mod")) {
128✔
641
        ort->schema = &ort_math_promotion_schema_mod;
8✔
642
    } else if (zend_string_equals_literal_ci(symbol, "mul")) {
120✔
643
        ort->schema = &ort_math_promotion_schema_mul;
8✔
644
    } else if (zend_string_equals_literal_ci(symbol, "neg")) {
112✔
645
        ort->schema = &ort_math_promotion_schema_neg;
8✔
646
    } else if (zend_string_equals_literal_ci(symbol, "pow")) {
104✔
647
        ort->schema = &ort_math_promotion_schema_pow;
8✔
648
    } else if (zend_string_equals_literal_ci(symbol, "recip")) {
96✔
649
        ort->schema = &ort_math_promotion_schema_recip;
8✔
650
    } else if (zend_string_equals_literal_ci(symbol, "round")) {
88✔
651
        ort->schema = &ort_math_promotion_schema_round;
8✔
652
    } else if (zend_string_equals_literal_ci(symbol, "sign")) {
80✔
653
        ort->schema = &ort_math_promotion_schema_sign;
8✔
654
    } else if (zend_string_equals_literal_ci(symbol, "sin")) {
72✔
655
        ort->schema = &ort_math_promotion_schema_sin;
8✔
656
    } else if (zend_string_equals_literal_ci(symbol, "sinh")) {
64✔
657
        ort->schema = &ort_math_promotion_schema_sinh;
8✔
658
    } else if (zend_string_equals_literal_ci(symbol, "softmax")) {
56✔
659
        ort->schema = &ort_math_promotion_schema_softmax;
8✔
660
    } else if (zend_string_equals_literal_ci(symbol, "sqrt")) {
48✔
661
        ort->schema = &ort_math_promotion_schema_sqrt;
8✔
662
    } else if (zend_string_equals_literal_ci(symbol, "sub")) {
40✔
663
        ort->schema = &ort_math_promotion_schema_sub;
8✔
664
    } else if (zend_string_equals_literal_ci(symbol, "sum")) {
32✔
665
        ort->schema = &ort_math_promotion_schema_sum;
8✔
666
    } else if (zend_string_equals_literal_ci(symbol, "tan")) {
24✔
667
        ort->schema = &ort_math_promotion_schema_tan;
8✔
668
    } else if (zend_string_equals_literal_ci(symbol, "tanh")) {
16✔
669
        ort->schema = &ort_math_promotion_schema_tanh;
8✔
670
    } else if (zend_string_equals_literal_ci(symbol, "trunc")) {
8✔
671
        ort->schema = &ort_math_promotion_schema_trunc;
8✔
672
    } else {
673
        /* throw */
674
        return;
×
675
    }
676

677
    ort->symbol = zend_string_copy(symbol);
712✔
678
}
679

680
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(php_ort_math_schema_getSymbol_arginfo, 0, 0, MAY_BE_STRING|MAY_BE_NULL)
681
ZEND_END_ARG_INFO()
682

683
PHP_METHOD(ONNX_Math_Schema, getSymbol)
8✔
684
{
685
    php_ort_math_schema_t *ort = php_ort_math_schema_fetch(Z_OBJ_P(getThis()));
8✔
686

687
    if (!ort->symbol) {
8✔
688
        return;
689
    }
690

691
    RETURN_STR_COPY(ort->symbol);
8✔
692
}
693

694
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_math_schema_getKind_arginfo, 0, 0, IS_LONG, 0)
695
ZEND_END_ARG_INFO()
696

697
PHP_METHOD(ONNX_Math_Schema, getKind)
8✔
698
{
699
    php_ort_math_schema_t *ort =
8✔
700
        php_ort_math_schema_fetch(Z_OBJ_P(getThis()));
8✔
701

702
    ZEND_PARSE_PARAMETERS_NONE();
8✔
703

704
    RETURN_LONG(ort->schema->kind);
8✔
705
}
706

707
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_math_schema_resolve_arginfo, 0, 1, IS_LONG, 0)
708
    ZEND_ARG_VARIADIC_INFO(0, types)
709
ZEND_END_ARG_INFO()
710

711
PHP_METHOD(ONNX_Math_Schema, resolve)
8✔
712
{
713
    php_ort_math_schema_t *ort = php_ort_math_schema_fetch(Z_OBJ_P(getThis()));
8✔
714
    zval *types;
8✔
715
    size_t count;
8✔
716

717
    ZEND_PARSE_PARAMETERS_START(1, -1)
8✔
718
        Z_PARAM_VARIADIC('+', types, count)
8✔
719
    ZEND_PARSE_PARAMETERS_END();
8✔
720

721
    /* TODO(krakjoe) exceptions */
722

723
    if (count == 0) {
8✔
724
        /* throw */
725
        RETURN_LONG(-1);
×
726
    }
727

728
    if (ort->schema->kind == ORT_MATH_PROMOTION_SCHEMA_KIND_BINARY) {
8✔
729
        if (count != 2) {
8✔
730
            /* throw */
731
            RETURN_LONG(-1);
×
732
        }
733

734
        if (Z_TYPE(types[0]) != IS_LONG || Z_TYPE(types[1]) != IS_LONG) {
8✔
735
            /* throw */
736
            RETURN_LONG(-1);
×
737
        }
738

739
        ONNXTensorElementDataType result =
8✔
740
            ort_math_promotion_resolve_binary(
16✔
741
                ort->schema,
742
                (ONNXTensorElementDataType) Z_LVAL(types[0]),
8✔
743
                (ONNXTensorElementDataType) Z_LVAL(types[1]));
8✔
744
        RETURN_LONG(result);
8✔
745
    } else if (ort->schema->kind == ORT_MATH_PROMOTION_SCHEMA_KIND_UNARY) {
×
746
        if (count != 1) {
×
747
            RETURN_LONG(-1);
×
748
        }
749

750
        if (Z_TYPE(types[0]) != IS_LONG) {
×
751
            /* throw */
752
            RETURN_LONG(-1);
×
753
        }
754

755
        ONNXTensorElementDataType result =
×
756
            ort_math_promotion_resolve_unary(
×
757
                ort->schema,
758
                (ONNXTensorElementDataType) Z_LVAL(types[0]));
×
759
        RETURN_LONG(result);
×
760
    } else {
761
        /* throw */
762
        RETURN_LONG(-1);
×
763
    }
764
}
765

766
static const zend_function_entry php_ort_math_schema_methods[] = {
767
    PHP_ME(ONNX_Math_Schema, __construct, php_ort_math_schema___construct_arginfo, ZEND_ACC_PUBLIC)
768
    PHP_ME(ONNX_Math_Schema, getSymbol,   php_ort_math_schema_getSymbol_arginfo,   ZEND_ACC_PUBLIC)
769
    PHP_ME(ONNX_Math_Schema, getKind,     php_ort_math_schema_getKind_arginfo,     ZEND_ACC_PUBLIC)
770
    PHP_ME(ONNX_Math_Schema, resolve,     php_ort_math_schema_resolve_arginfo,     ZEND_ACC_PUBLIC)
771
    PHP_FE_END
772
}; /* }}} */
773

774
PHP_MINIT_FUNCTION(ORT_MATH)
1,672✔
775
{
776
    ort_math_startup();
1,672✔
777

778
    zend_class_entry ce;
1,672✔
779

780
    INIT_NS_CLASS_ENTRY(ce, "ORT\\Math", "Schema", php_ort_math_schema_methods);
1,672✔
781
    php_ort_math_schema_ce = zend_register_internal_class(&ce);
1,672✔
782
    php_ort_math_schema_ce->create_object = php_ort_math_schema_create;
1,672✔
783
    php_ort_math_schema_ce->ce_flags |= ZEND_ACC_FINAL;
1,672✔
784

785
    zend_declare_class_constant_long(
1,672✔
786
        php_ort_math_schema_ce,
787
        ZEND_STRL("BINARY"),
788
        ORT_MATH_PROMOTION_SCHEMA_KIND_BINARY);
789
    zend_declare_class_constant_long(
1,672✔
790
        php_ort_math_schema_ce,
791
        ZEND_STRL("UNARY"),
792
        ORT_MATH_PROMOTION_SCHEMA_KIND_UNARY);
793

794
    memcpy(&php_ort_math_schema_handlers,
1,672✔
795
        zend_get_std_object_handlers(), sizeof(zend_object_handlers));
796
    php_ort_math_schema_handlers.offset = XtOffsetOf(php_ort_math_schema_t, std);
1,672✔
797
    php_ort_math_schema_handlers.free_obj = php_ort_math_schema_free;
1,672✔
798
    php_ort_math_schema_handlers.get_debug_info = php_ort_math_schema_debug;
1,672✔
799
    php_ort_math_schema_handlers.clone_obj = NULL; // No cloning support
1,672✔
800

801
    zend_register_functions(NULL,
1,672✔
802
        php_ort_math_functions, NULL, MODULE_PERSISTENT);
803

804
    return SUCCESS;
1,672✔
805
}
806

807
PHP_RINIT_FUNCTION(ORT_MATH)
1,672✔
808
{
809
    ort_math_activate();
1,672✔
810

811
    return SUCCESS;
1,672✔
812
}
813

814
PHP_RSHUTDOWN_FUNCTION(ORT_MATH)
1,672✔
815
{
816
    ort_math_deactivate();
1,672✔
817

818
    return SUCCESS;
1,672✔
819
}
820

821
PHP_MSHUTDOWN_FUNCTION(ORT_MATH)
1,672✔
822
{
823
    ort_math_shutdown();
1,672✔
824

825
    return SUCCESS;
1,672✔
826
}
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