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

krakjoe / ort / 21622477622

03 Feb 2026 05:26AM UTC coverage: 96.427% (+0.3%) from 96.115%
21622477622

push

github

krakjoe
skip fresh checkouts

13763 of 14273 relevant lines covered (96.43%)

477629.18 hits per line

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

94.95
/src/model.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

21
#include "env.h"
22
#include "status.h"
23
#include "model.h"
24
#include "iterator.h"
25
#include "tensor.h"
26

27
#ifdef ZTS
28
static MUTEX_T php_ort_model_mutex;
29
#endif
30

31
static HashTable php_ort_models;
32

33
zend_class_entry *php_ort_model_ce;
34
zend_object_handlers php_ort_model_handlers;
35

36
static void php_ort_model_free(ort_model_t *model) {
435✔
37
    OrtStatus* status;
435✔
38
    size_t idx;
435✔
39

40
    if (model->metadata) {
435✔
41
        api->ReleaseModelMetadata(model->metadata);
435✔
42
    }
145✔
43

44
    if (model->session) {
435✔
45
        api->ReleaseSession(model->session);
435✔
46
    }
145✔
47

48
    switch (model->kind) {
435✔
49
        case ORT_MODEL_SOURCE_FILE:
290✔
50
            zend_string_free(model->source.file);
435✔
51
        break;
145✔
52

53
        case ORT_MODEL_SOURCE_MEMORY:
54
            zend_string_free(model->source.memory);
×
55
        break;
56
    }
57

58
    zend_string_free(model->name);
435✔
59

60
    if (model->names.input) {
435✔
61
        for (idx = 0; idx < model->counters.input; idx++) {
1,305✔
62
            php_ort_status_flow(
870✔
63
                (status = api->AllocatorFree(
64
                    model->allocator, model->names.input[idx])),
65
                {
66
                    api->ReleaseStatus(status);
67
                    return;
68
                },
69
                php_ort_status_model_invalidmemory_ce,
70
                "failed to release input name at %zu for Model, something is terribly wrong",
71
                idx
72
            );
73
        }
290✔
74
        pefree(model->names.input, 1);
435✔
75
    }
145✔
76

77
    if (model->names.output) {
435✔
78
        for (idx = 0; idx < model->counters.output; idx++) {
870✔
79
            php_ort_status_flow(
435✔
80
                (status = api->AllocatorFree(
81
                    model->allocator, model->names.output[idx])),
82
                {
83
                    api->ReleaseStatus(status);
84
                    return;
85
                },
86
                php_ort_status_model_invalidmemory_ce,
87
                "failed to release output name at %zu for Model, something is terribly wrong",
88
                idx
89
            );
90
        }
145✔
91
        pefree(model->names.output, 1);
435✔
92
    }
145✔
93

94
    pefree(model, 1);
435✔
95
}
145✔
96

97
void php_ort_model_release(ort_model_t *model) {
1,035✔
98
    if (!model) {
1,035✔
99
        return;
15✔
100
    }
101

102
    if (php_ort_atomic_delref(&model->refcount) == 0){
990✔
103
        php_ort_model_free(model);
435✔
104
    }
145✔
105
}
345✔
106

107
static void php_ort_model_del(zval *zv) {
435✔
108
    php_ort_model_release(
435✔
109
        ((ort_model_t*) Z_PTR_P(zv)));
435✔
110
}
435✔
111

112
static zend_bool php_ort_model_construct_complete(ort_model_t *model) {
435✔
113
    OrtStatus* status;
435✔
114

115
    php_ort_status_flow(
435✔
116
        (status = api->GetAllocatorWithDefaultOptions(&model->allocator)),
117
        {
118
            api->ReleaseStatus(status);
119

120
            return 0;
121
        },
122
        php_ort_status_model_invalidmemory_ce,
123
        "failed to allocate Allocator* for Model: %s",
124
        api->GetErrorMessage(status));
125

126
    php_ort_status_flow(
435✔
127
        (status = api->SessionGetModelMetadata(
128
            model->session,
129
            &model->metadata)),
130
        {
131
            api->ReleaseStatus(status);
132

133
            return 0;
134
        },
135
        php_ort_status_model_invalidmodel_ce,
136
        "failed to get metadata for Model: %s",
137
        api->GetErrorMessage(status));
138

139
    php_ort_status_flow(
435✔
140
        (status = api->SessionGetInputCount(
141
            model->session,
142
            &model->counters.input)),
143
        {
144
            api->ReleaseStatus(status);
145

146
            return 0;
147
        },
148
        php_ort_status_model_invalidmodel_ce,
149
        "failed to get input counter for Model: %s",
150
        api->GetErrorMessage(status));
151

152
    size_t idx;
435✔
153

154
    model->names.input = pecalloc(model->counters.input, sizeof(char*), 1);
435✔
155

156
    for (idx = 0; idx < model->counters.input; idx++) {
1,305✔
157
        php_ort_status_flow(
870✔
158
            (status = api->SessionGetInputName(
159
                model->session, idx, 
160
                model->allocator,
161
                &model->names.input[idx])),
162
            {
163
                api->ReleaseStatus(status);
164

165
                return 0;
166
            },
167
            php_ort_status_model_invalidinput_ce,
168
            "failed to get input name at %d for Model: %s",
169
            idx,
170
            api->GetErrorMessage(status));
171
    }
290✔
172

173
    php_ort_status_flow(
435✔
174
        (status = api->SessionGetOutputCount(
175
            model->session,
176
            &model->counters.output)),
177
        {
178
            api->ReleaseStatus(status);
179

180
            return 0;
181
        },
182
        php_ort_status_model_invalidmodel_ce,
183
        "failed to get output counter for Model: %s",
184
        api->GetErrorMessage(status));
185

186
    model->names.output = pecalloc(model->counters.output, sizeof(char*), 1);
435✔
187

188
    for (idx = 0; idx < model->counters.output; idx++) {
870✔
189
        php_ort_status_flow(
435✔
190
            (status = api->SessionGetOutputName(
191
                model->session, idx,
192
                model->allocator,
193
                &model->names.output[idx])),
194
            {
195
                api->ReleaseStatus(status);
196

197
                return 0;
198
            },
199
            php_ort_status_model_invalidoutput_ce,
200
            "failed to get output name at %d for Model: %s",
201
            idx,
202
            api->GetErrorMessage(status));
203
    }
145✔
204

205
    return 1;
145✔
206
}
145✔
207

208
static void php_ort_model_construct_options(ort_model_t *model, zend_object *options) {
435✔
209
    if (!options) {
435✔
210
        model->options = php_ort_options_default();
420✔
211
    } else {
140✔
212
        php_ort_options_t* zo =
20✔
213
            php_ort_options_fetch(options);
15✔
214
        model->options = zo->object;
15✔
215
    }
5✔
216

217
    php_ort_atomic_addref(&model->options->refcount);
435✔
218
}
435✔
219

220
static zend_bool php_ort_model_construct_from_file(ort_model_t *model,  zend_string *name, zend_string *file, zend_object* options){
435✔
221
    OrtStatus* status;
435✔
222

223
    model->kind = ORT_MODEL_SOURCE_FILE;
435✔
224
    model->name = php_ort_string_copy(name);
435✔
225
    model->source.file = php_ort_string_copy(file);
435✔
226

227
    php_ort_model_construct_options(model, options);
435✔
228

229
    php_ort_string_temp_t pass =
580✔
230
        php_ort_string_pass(ZSTR_VAL(file));
435✔
231

232
    php_ort_status_flow(
435✔
233
        (status = api->CreateSession(php_ort_environment(),
234
            pass, model->options->options, &model->session)),
235
        {
236
            api->ReleaseStatus(status);
237
            php_ort_string_free(pass);
238
            return 0;
239
        },
240
        php_ort_status_model_invalidmemory_ce,
241
        "failed to allocate OrtSession* for Model: %s",
242
        api->GetErrorMessage(status));
243

244
    php_ort_string_free(pass);
435✔
245

246
    return php_ort_model_construct_complete(model);
435✔
247
}
145✔
248

249
static zend_bool php_ort_model_construct_from_array(ort_model_t *model,  zend_string *name, zend_string *file, zend_object* options){
×
250
    OrtStatus* status;
×
251

252
    model->kind = ORT_MODEL_SOURCE_MEMORY;
×
253
    model->name = php_ort_string_copy(name);
×
254
    model->source.memory = php_ort_string_copy(file);
×
255

256
    php_ort_model_construct_options(model, options);
×
257

258
    php_ort_status_flow(
×
259
        (status = api->CreateSessionFromArray(php_ort_environment(),
260
            ZSTR_VAL(model->source.memory),
261
            ZSTR_LEN(model->source.memory),
262
            model->options->options, &model->session)),
263
        {
264
            api->ReleaseStatus(status);
265
            return 0;
266
        },
267
        php_ort_status_model_invalidmemory_ce,
268
        "failed to allocate OrtSession* for Model: %s",
269
        api->GetErrorMessage(status));
270

271
    return php_ort_model_construct_complete(model);
×
272
}
273

274
ZEND_BEGIN_ARG_INFO_EX(php_ort_model_construct_arginfo, 0, 0, 1)
275
    ZEND_ARG_TYPE_INFO(0, name,   IS_STRING, 0)
276
    ZEND_ARG_TYPE_INFO(0, source,  IS_STRING, 0)
277
    ZEND_ARG_TYPE_INFO(0, array,  _IS_BOOL,  0)
278
    ZEND_ARG_OBJ_INFO(0, options, \\ORT\\Options, 1)
279
ZEND_END_ARG_INFO()
280

281
PHP_METHOD(ONNX_Model, __construct)
495✔
282
{
283
    php_ort_model_t *ort = php_ort_model_fetch(Z_OBJ(EX(This)));
495✔
284

285
    zend_string *name;
495✔
286
    zend_string *source = NULL;
495✔
287
    zend_bool array = 0;
495✔
288
    zend_object *options = NULL;
495✔
289

290
    ZEND_PARSE_PARAMETERS_START(1, 4);
495✔
291
        Z_PARAM_STR(name)
495✔
292
        Z_PARAM_OPTIONAL
495✔
293
        Z_PARAM_STR(source)
495✔
294
        Z_PARAM_BOOL(array)
465✔
295
        Z_PARAM_OBJ_OF_CLASS_EX(options, php_ort_options_ce, 0, 0)
15✔
296
    ZEND_PARSE_PARAMETERS_END();
175✔
297

298
#ifdef ZTS
299
        php_ort_status_flow(
495✔
300
            tsrm_mutex_lock(php_ort_model_mutex) != SUCCESS,
301
            return,
302
            php_ort_status_safetyerror_ce,
303
            "it was not possible to acquire the model mutex, something is terribly wrong");
304
#endif
305

306
    if (!(ort->object = zend_hash_find_ptr(&php_ort_models, name))) {
825✔
307
        if (!array) {
465✔
308
            char path[4096];
465✔
309

310
            php_ort_status_flow(
475✔
311
                !source,
312
                return,
313
                php_ort_status_model_invalidfile_ce,
314
                "model %s could not be loaded and no file provided",
315
                ZSTR_VAL(name));
316

317
            php_ort_status_flow(
450✔
318
                (ZSTR_LEN(source) > 4096),
319
                return,
320
                php_ort_status_model_invalidfile_ce,
321
                "model %s could not be created: file name too long",
322
                ZSTR_VAL(name));
323

324
            php_ort_status_flow(
450✔
325
                (NULL == VCWD_REALPATH(ZSTR_VAL(source), path)),
326
                return,
327
                php_ort_status_model_invalidfile_ce,
328
                "model %s could not be found, %s is not a valid path",
329
                ZSTR_VAL(name), ZSTR_VAL(source));
330
        }
155✔
331

332
        ort_model_t *model = pecalloc(1, sizeof(ort_model_t), 1);
435✔
333

334
        model->refcount = 1;
435✔
335

336
        zend_bool result = array ?
725✔
337
            php_ort_model_construct_from_array(model, name, source, options) :
×
338
            php_ort_model_construct_from_file(model, name, source, options) ;
435✔
339
        if (!result) {
435✔
340
            php_ort_model_free(model);
×
341
#ifdef ZTS
342
            php_ort_status_flow(
×
343
                tsrm_mutex_unlock(php_ort_model_mutex) != SUCCESS,
344
                return,
345
                php_ort_status_safetyerror_ce,
346
                "it was not possible to release the model mutex, something is terribly wrong");
347
#endif
348
            return;
349
        }
350

351
        ort->object = zend_hash_add_ptr(
435✔
352
            &php_ort_models,
353
            model->name,
145✔
354
            model);
145✔
355
        php_ort_atomic_addref(&ort->object->refcount);
435✔
356
    } else if (ort->object->kind == ORT_MODEL_SOURCE_FILE) {
175✔
357

358
#ifdef ZTS
359
        php_ort_status_flow(
40✔
360
            source && !zend_string_equals(ort->object->source.file, source),
361
            {
362
                php_ort_status_flow(
363
                    tsrm_mutex_unlock(php_ort_model_mutex) != SUCCESS,
364
                    return,
365
                    php_ort_status_safetyerror_ce,
366
                    "it was not possible to release the model mutex, something is terribly wrong");
367
                ort->object = NULL;
368
                return;
369
            },
370
            php_ort_status_model_invalidfile_ce,
371
            "a model with the name %s is already loaded from %s, the file %s does not match",
372
            ZSTR_VAL(ort->object->name), ZSTR_VAL(ort->object->source.file), ZSTR_VAL(source));
373
#else
374
        php_ort_status_flow(
375
            source && !zend_string_equals(ort->object->source.file, source),
376
            {
377
                ort->object = NULL;
378
                return;
379
            },
380
            php_ort_status_model_invalidfile_ce,
381
            "a model with the name %s is already loaded from %s, the file %s does not match",
382
            ZSTR_VAL(ort->object->name), ZSTR_VAL(ort->object->source.file), ZSTR_VAL(source));
383
#endif
384
        php_ort_atomic_addref(&ort->object->refcount);
15✔
385
    } else {
5✔
386
        /* Created from array, we can't validate this in the same way
387
            it doesn't make much sense to compare what could be several
388
            gb of memory */
389
        php_ort_atomic_addref(&ort->object->refcount);
×
390
    }
391

392
#ifdef ZTS
393
    php_ort_status_flow(
450✔
394
        tsrm_mutex_unlock(php_ort_model_mutex) != SUCCESS,
395
        return,
396
        php_ort_status_safetyerror_ce,
397
        "it was not possible to release the model mutex, something is terribly wrong");
398
#endif
399
}
165✔
400

401
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getName_arginfo, 0, 0, IS_STRING, 0)
402
ZEND_END_ARG_INFO()
403

404
PHP_METHOD(ONNX_Model, getName)
45✔
405
{
406
    php_ort_model_t *ort =
60✔
407
        php_ort_model_fetch(Z_OBJ(EX(This)));
45✔
408

409
    ZEND_PARSE_PARAMETERS_NONE();
45✔
410

411
    RETURN_STR_COPY(ort->object->name);
45✔
412
}
15✔
413

414
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getFile_arginfo, 0, 0, IS_STRING, 0)
415
ZEND_END_ARG_INFO()
416

417
PHP_METHOD(ONNX_Model, getFile)
45✔
418
{
419
    php_ort_model_t *ort =
60✔
420
        php_ort_model_fetch(Z_OBJ(EX(This)));
45✔
421

422
    ZEND_PARSE_PARAMETERS_NONE();
45✔
423

424
    if (ort->object->kind == ORT_MODEL_SOURCE_FILE) {
45✔
425
        RETURN_STR_COPY(ort->object->source.file);
45✔
426
    }
427
}
15✔
428

429
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getInput_arginfo, 0, 1, IS_STRING, 0)
430
     ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
431
ZEND_END_ARG_INFO()
432

433
PHP_METHOD(ONNX_Model, getInput)
45✔
434
{
435
    php_ort_model_t *ort =
60✔
436
        php_ort_model_fetch(Z_OBJ(EX(This)));
45✔
437
    zend_long index;
45✔
438

439
    ZEND_PARSE_PARAMETERS_START(1, 1);
45✔
440
        Z_PARAM_LONG(index)
45✔
441
    ZEND_PARSE_PARAMETERS_END();
15✔
442

443
    php_ort_status_flow(
45✔
444
        (index < 0 || index >= ort->object->counters.input),
445
        return,
446
        php_ort_status_model_invalidindex_ce,
447
        "index %zd is out of range for input",
448
        index);
449

450
    RETURN_STRING(ort->object->names.input[index]);
25✔
451
}
15✔
452

453
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getInputCount_arginfo, 0, 0, IS_LONG, 0)
454
ZEND_END_ARG_INFO()
455

456
PHP_METHOD(ONNX_Model, getInputCount)
45✔
457
{
458
    php_ort_model_t *ort =
60✔
459
        php_ort_model_fetch(Z_OBJ(EX(This)));
45✔
460

461
    ZEND_PARSE_PARAMETERS_NONE();
45✔
462

463
    RETURN_LONG(ort->object->counters.input);
45✔
464
}
15✔
465

466
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getOutput_arginfo, 0, 1, IS_STRING, 0)
467
     ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
468
ZEND_END_ARG_INFO()
469

470
PHP_METHOD(ONNX_Model, getOutput)
30✔
471
{
472
    php_ort_model_t *ort =
40✔
473
        php_ort_model_fetch(Z_OBJ(EX(This)));
30✔
474
    zend_long index;
30✔
475

476
    ZEND_PARSE_PARAMETERS_START(1, 1);
30✔
477
        Z_PARAM_LONG(index)
30✔
478
    ZEND_PARSE_PARAMETERS_END();
10✔
479

480
    php_ort_status_flow(
30✔
481
        (index < 0 || index >= ort->object->counters.output),
482
        return,
483
        php_ort_status_model_invalidindex_ce,
484
        "index %zd is out of range for output",
485
        index);
486

487
    RETURN_STRING(ort->object->names.output[index]);
25✔
488
}
10✔
489

490
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getOutputCount_arginfo, 0, 0, IS_LONG, 0)
491
ZEND_END_ARG_INFO()
492

493
PHP_METHOD(ONNX_Model, getOutputCount)
45✔
494
{
495
    php_ort_model_t *ort =
60✔
496
        php_ort_model_fetch(Z_OBJ(EX(This)));
45✔
497

498
    ZEND_PARSE_PARAMETERS_NONE();
45✔
499

500
    RETURN_LONG(ort->object->counters.output);
45✔
501
}
15✔
502

503
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_unload_arginfo, 0, 1, _IS_BOOL, 0)
504
    ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0)
505
ZEND_END_ARG_INFO()
506

507
PHP_METHOD(ONNX_Model, unload)
45✔
508
{
509
    zend_string *name;
45✔
510

511
    ZEND_PARSE_PARAMETERS_START(1, 1)
45✔
512
        Z_PARAM_STR(name)
45✔
513
    ZEND_PARSE_PARAMETERS_END();
15✔
514

515
#ifdef ZTS
516
    php_ort_status_flow(
45✔
517
        tsrm_mutex_lock(php_ort_model_mutex) != SUCCESS,
518
        return,
519
    php_ort_status_safetyerror_ce,
520
    "it was not possible to acquire the model mutex, something is terribly wrong");
521
#endif
522

523
    RETVAL_BOOL(zend_hash_del(&php_ort_models, name) == SUCCESS);
45✔
524

525
#ifdef ZTS
526
    php_ort_status_flow(
45✔
527
        tsrm_mutex_unlock(php_ort_model_mutex) != SUCCESS,
528
        return,
529
    php_ort_status_safetyerror_ce,
530
    "it was not possible to release the model mutex, something is terribly wrong");
531
#endif
532
}
15✔
533

534
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(php_ort_model_getInputIterator_arginfo, 0, 0, ORT\\Model\\Iterator, 0)
535
ZEND_END_ARG_INFO()
536

537
PHP_METHOD(ONNX_Model, getInputIterator)
30✔
538
{
539
    php_ort_model_t *ort =
40✔
540
        php_ort_model_fetch(Z_OBJ(EX(This)));
30✔
541
    ZEND_PARSE_PARAMETERS_NONE();
30✔
542

543
    php_ort_iterator_model(ort->object,
40✔
544
        (const char * const*) ort->object->names.input,
30✔
545
            ort->object->counters.input, return_value);
26✔
546
}
10✔
547

548
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(php_ort_model_getOutputIterator_arginfo, 0, 0, ORT\\Model\\Iterator, 0)
549
ZEND_END_ARG_INFO()
550

551
PHP_METHOD(ONNX_Model, getOutputIterator)
30✔
552
{
553
    php_ort_model_t *ort =
40✔
554
        php_ort_model_fetch(Z_OBJ(EX(This)));
30✔
555
    ZEND_PARSE_PARAMETERS_NONE();
30✔
556

557
    php_ort_iterator_model(ort->object,
40✔
558
        (const char * const*) ort->object->names.output,
30✔
559
            ort->object->counters.output, return_value);
26✔
560
}
10✔
561

562
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getMeta_arginfo, 0, 1, IS_MIXED, 0)
563
    ZEND_ARG_TYPE_INFO(0, property, IS_STRING, 0)
564
ZEND_END_ARG_INFO()
565

566
PHP_METHOD(ONNX_Model, getMeta)
105✔
567
{
568
    php_ort_model_t* ort = php_ort_model_fetch(Z_OBJ(EX(This)));
105✔
569
    zend_string *property = NULL;
105✔
570
    char *str_value = NULL;
105✔
571
    int64_t int_value;
105✔
572
    OrtStatus* status;
105✔
573

574
    ZEND_PARSE_PARAMETERS_START(1, 1);
105✔
575
        Z_PARAM_STR(property)
105✔
576
    ZEND_PARSE_PARAMETERS_END();
35✔
577

578
    const char *prop = ZSTR_VAL(property);
105✔
579
    
580
    if (strcmp(prop, "version") == 0) {
105✔
581
        php_ort_status_flow(
15✔
582
            (status = api->ModelMetadataGetVersion(ort->object->metadata, &int_value)),
583
            {
584
                api->ReleaseStatus(status);
585
                return;
586
            },
587
            php_ort_status_model_invalidmodel_ce,
588
            "failed to get version for Model: %s",
589
            api->GetErrorMessage(status));
590
        RETURN_LONG(int_value);
15✔
591
    } else if (strcmp(prop, "producer") == 0) {
90✔
592
        php_ort_status_flow(
15✔
593
            (status = api->ModelMetadataGetProducerName(ort->object->metadata, ort->object->allocator, &str_value)),
594
            {
595
                api->ReleaseStatus(status);
596
                return;
597
            },
598
            php_ort_status_model_invalidmodel_ce,
599
            "failed to get producer name for Model: %s",
600
            api->GetErrorMessage(status));
601
        if (str_value) {
15✔
602
            RETVAL_STRING(str_value);
15✔
603
            php_ort_status_flow(
15✔
604
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
605
                {
606
                    api->ReleaseStatus(status);
607
                    return;
608
                },
609
                php_ort_status_model_invalidmemory_ce,
610
                "failed to release producer name memory for Model: %s",
611
                api->GetErrorMessage(status));
612
            return;
5✔
613
        }
614
    } else if (strcmp(prop, "description") == 0) {
75✔
615
        php_ort_status_flow(
15✔
616
            (status = api->ModelMetadataGetDescription(ort->object->metadata, ort->object->allocator, &str_value)),
617
            {
618
                api->ReleaseStatus(status);
619
                return;
620
            },
621
            php_ort_status_model_invalidmodel_ce,
622
            "failed to get description for Model: %s",
623
            api->GetErrorMessage(status));
624
        if (str_value) {
15✔
625
            RETVAL_STRING(str_value);
15✔
626
            php_ort_status_flow(
15✔
627
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
628
                {
629
                    api->ReleaseStatus(status);
630
                    return;
631
                },
632
                php_ort_status_model_invalidmemory_ce,
633
                "failed to release description memory for Model: %s",
634
                api->GetErrorMessage(status));
635
            return;
5✔
636
        }
637
    } else if (strcmp(prop, "domain") == 0) {
60✔
638
        php_ort_status_flow(
15✔
639
            (status = api->ModelMetadataGetDomain(ort->object->metadata, ort->object->allocator, &str_value)),
640
            {
641
                api->ReleaseStatus(status);
642
                return;
643
            },
644
            php_ort_status_model_invalidmodel_ce,
645
            "failed to get domain for Model: %s",
646
            api->GetErrorMessage(status));
647
        if (str_value) {
15✔
648
            RETVAL_STRING(str_value);
15✔
649
            php_ort_status_flow(
15✔
650
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
651
                {
652
                    api->ReleaseStatus(status);
653
                    return;
654
                },
655
                php_ort_status_model_invalidmemory_ce,
656
                "failed to release domain memory for Model: %s",
657
                api->GetErrorMessage(status));
658
            return;
5✔
659
        }
660
    } else if (strcmp(prop, "graph_name") == 0) {
45✔
661
        php_ort_status_flow(
15✔
662
            (status = api->ModelMetadataGetGraphName(ort->object->metadata, ort->object->allocator, &str_value)),
663
            {
664
                api->ReleaseStatus(status);
665
                return;
666
            },
667
            php_ort_status_model_invalidmodel_ce,
668
            "failed to get graph name for Model: %s",
669
            api->GetErrorMessage(status));
670
        if (str_value) {
15✔
671
            RETVAL_STRING(str_value);
15✔
672
            php_ort_status_flow(
15✔
673
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
674
                {
675
                    api->ReleaseStatus(status);
676
                    return;
677
                },
678
                php_ort_status_model_invalidmemory_ce,
679
                "failed to release graph name memory for Model: %s",
680
                api->GetErrorMessage(status));
681
            return;
5✔
682
        }
683
    } else if (strcmp(prop, "graph_description") == 0) {
30✔
684
        php_ort_status_flow(
15✔
685
            (status = api->ModelMetadataGetGraphDescription(ort->object->metadata, ort->object->allocator, &str_value)),
686
            {
687
                api->ReleaseStatus(status);
688
                return;
689
            },
690
            php_ort_status_model_invalidmodel_ce,
691
            "failed to get graph description for Model: %s",
692
            api->GetErrorMessage(status));
693
        if (str_value) {
15✔
694
            RETVAL_STRING(str_value);
15✔
695
            php_ort_status_flow(
15✔
696
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
697
                {
698
                    api->ReleaseStatus(status);
699
                    return;
700
                },
701
                php_ort_status_model_invalidmemory_ce,
702
                "failed to release graph description memory for Model: %s",
703
                api->GetErrorMessage(status));
704
            return;
5✔
705
        }
706
    } else {
707
        /* Try to get custom metadata */
708
        php_ort_status_flow(
15✔
709
            (status = api->ModelMetadataLookupCustomMetadataMap(ort->object->metadata, ort->object->allocator, prop, &str_value)),
710
            {
711
                api->ReleaseStatus(status);
712
                return;
713
            },
714
            php_ort_status_model_invalidmodel_ce,
715
            "failed to get custom metadata for Model: %s",
716
            api->GetErrorMessage(status));
717
        if (str_value) {
15✔
718
            RETVAL_STRING(str_value);
×
719
            php_ort_status_flow(
×
720
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
721
                {
722
                    api->ReleaseStatus(status);
723
                    return;
724
                },
725
                php_ort_status_model_invalidmemory_ce,
726
                "failed to release custom metadata memory for Model: %s",
727
                api->GetErrorMessage(status));
728
            return;
729
        }
730
    }
731
    
732
    RETURN_NULL();
15✔
733
}
35✔
734

735
zend_function_entry php_ort_model_methods[] = {
736
    PHP_ME(ONNX_Model, __construct,       php_ort_model_construct_arginfo,             ZEND_ACC_PUBLIC)
737
    PHP_ME(ONNX_Model, getName,           php_ort_model_getName_arginfo,               ZEND_ACC_PUBLIC)
738
    PHP_ME(ONNX_Model, getFile,           php_ort_model_getFile_arginfo,               ZEND_ACC_PUBLIC)
739
    PHP_ME(ONNX_Model, getInput,          php_ort_model_getInput_arginfo,              ZEND_ACC_PUBLIC)
740
    PHP_ME(ONNX_Model, getInputCount,     php_ort_model_getInputCount_arginfo,         ZEND_ACC_PUBLIC)
741
    PHP_ME(ONNX_Model, getInputIterator,  php_ort_model_getInputIterator_arginfo,      ZEND_ACC_PUBLIC)
742
    PHP_ME(ONNX_Model, getOutput,         php_ort_model_getOutput_arginfo,             ZEND_ACC_PUBLIC)
743
    PHP_ME(ONNX_Model, getOutputCount,    php_ort_model_getOutputCount_arginfo,        ZEND_ACC_PUBLIC)
744
    PHP_ME(ONNX_Model, getOutputIterator, php_ort_model_getOutputIterator_arginfo,     ZEND_ACC_PUBLIC)
745
    PHP_ME(ONNX_Model, getMeta,           php_ort_model_getMeta_arginfo,               ZEND_ACC_PUBLIC)
746
    PHP_ME(ONNX_Model, unload,            php_ort_model_unload_arginfo,                ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
747
    PHP_FE_END
748
};
749

750
zend_object* php_ort_model_create(zend_class_entry *type) {
495✔
751
  php_ort_model_t *ort = ecalloc(1,
495✔
752
     sizeof(php_ort_model_t) + zend_object_properties_size(type));
753

754
   zend_object_std_init(&ort->std, type);
495✔
755

756
   ort->std.handlers = &php_ort_model_handlers;
495✔
757
   ort->object       = NULL;
495✔
758

759
   return &ort->std;
660✔
760
}
165✔
761

762
static HashTable* php_ort_model_debug(zend_object *zo, int *temp) {
30✔
763
    php_ort_model_t *ort = php_ort_model_fetch(zo);
30✔
764
    HashTable *debug;
30✔
765

766
    ALLOC_HASHTABLE(debug);
30✔
767
    zend_hash_init(debug, 3, NULL, ZVAL_PTR_DTOR, 0);
30✔
768

769
    if (!ort->object) {
30✔
770
      goto __php_ort_model_debug_return;
×
771
    }
772

773
    if (ort->object->name) {
30✔
774
      zval name;
30✔
775
  
776
      ZVAL_STR_COPY(&name, ort->object->name);
30✔
777
      zend_hash_add(debug,
40✔
778
        ZSTR_KNOWN(ZEND_STR_NAME), &name);
30✔
779
    }
10✔
780

781
    if (ort->object->kind == ORT_MODEL_SOURCE_FILE && ort->object->source.file) {
30✔
782
      zval file;
30✔
783
  
784
      ZVAL_STR_COPY(&file, ort->object->source.file);
30✔
785
      zend_hash_add(debug,
40✔
786
        ZSTR_KNOWN(ZEND_STR_FILE), &file);
10✔
787
    }
10✔
788

789
    size_t idx;
20✔
790
    zval   arr;
20✔
791

792
    array_init(&arr);
30✔
793
    zend_hash_str_add(debug, "inputs", sizeof("inputs")-1, &arr);
30✔
794
    for (idx = 0; idx < ort->object->counters.input; idx++) {
110✔
795
      add_next_index_string(&arr, ort->object->names.input[idx]);
60✔
796
    }
20✔
797

798
    array_init(&arr);
30✔
799
    zend_hash_str_add(debug, "outputs", sizeof("outputs")-1, &arr);
30✔
800
    for (idx = 0; idx < ort->object->counters.output; idx++) {
80✔
801
      add_next_index_string(&arr, ort->object->names.output[idx]);
30✔
802
    }
20✔
803

804
__php_ort_model_debug_return:
20✔
805
    *temp = 1;
30✔
806

807
    return debug;
40✔
808
}
10✔
809

810
void php_ort_model_destroy(zend_object *o) {
495✔
811
    php_ort_model_t *ort =
660✔
812
        php_ort_model_fetch(o);
495✔
813

814
    php_ort_model_release(ort->object);
495✔
815

816
    zend_object_std_dtor(o);
495✔
817
}
495✔
818

819
PHP_MINIT_FUNCTION(ORT_MODEL)
3,817✔
820
{
821
    zend_class_entry ce;
3,817✔
822

823
#ifdef ZTS
824
    php_ort_model_mutex = tsrm_mutex_alloc();
3,817✔
825
#endif
826

827
    zend_hash_init(&php_ort_models, 16, NULL, php_ort_model_del, 1);
3,817✔
828

829
    memcpy(&php_ort_model_handlers,
3,817✔
830
        zend_get_std_object_handlers(), sizeof(zend_object_handlers));
831

832
    php_ort_model_handlers.offset = XtOffsetOf(php_ort_model_t, std);
3,817✔
833
    php_ort_model_handlers.get_debug_info = php_ort_model_debug;
3,817✔
834
    php_ort_model_handlers.free_obj = php_ort_model_destroy;
3,817✔
835
    php_ort_model_handlers.clone_obj = NULL;
3,817✔
836

837
    INIT_NS_CLASS_ENTRY(ce, "ORT", "Model", php_ort_model_methods);
3,817✔
838

839
    php_ort_model_ce = zend_register_internal_class(&ce);
3,817✔
840
    php_ort_model_ce->create_object = php_ort_model_create;
3,817✔
841

842
#ifdef ZEND_ACC_NOT_SERIALIZABLE
843
    php_ort_model_ce->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE;
3,817✔
844
  #else
845
    php_ort_model_ce->serialize = zend_class_serialize_deny;
846
    php_ort_model_ce->unserialize = zend_class_unserialize_deny;
847
#endif
848

849
  return SUCCESS;
3,817✔
850
}
1,135✔
851

852
PHP_MSHUTDOWN_FUNCTION(ORT_MODEL)
3,817✔
853
{
854
    zend_hash_destroy(&php_ort_models);
3,817✔
855
  
856
#ifdef ZTS
857
    tsrm_mutex_free(php_ort_model_mutex);
3,817✔
858
#endif
859

860
   return SUCCESS;
3,817✔
861
}
862
 
863
PHP_RINIT_FUNCTION(ORT_MODEL)
3,817✔
864
{
865
   return SUCCESS;
3,817✔
866
}
867
 
868
PHP_RSHUTDOWN_FUNCTION(ORT_MODEL)
3,817✔
869
{
870
   return SUCCESS;
3,817✔
871
}
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