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

krakjoe / ort / 18880448672

28 Oct 2025 03:38PM UTC coverage: 92.092% (-0.6%) from 92.707%
18880448672

push

github

krakjoe
[ci skip] clean checkouts

5159 of 5602 relevant lines covered (92.09%)

153022.46 hits per line

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

90.64
/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) {
638✔
37
    OrtStatus* status;
638✔
38
    size_t idx;
638✔
39

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

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

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

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

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

60
    if (model->names.input) {
638✔
61
        for (idx = 0; idx < model->counters.input; idx++) {
1,914✔
62
            php_ort_status_flow(
1,276✔
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
        }
74
        pefree(model->names.input, 1);
638✔
75
    }
76

77
    if (model->names.output) {
638✔
78
        for (idx = 0; idx < model->counters.output; idx++) {
1,276✔
79
            php_ort_status_flow(
638✔
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
        }
91
        pefree(model->names.output, 1);
638✔
92
    }
93

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

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

102
    if (php_ort_atomic_delref(&model->refcount) == 0){
1,474✔
103
        php_ort_model_free(model);
638✔
104
    }
105
}
106

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

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

115
    php_ort_status_flow(
638✔
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(
638✔
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(
638✔
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;
638✔
153

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

156
    for (idx = 0; idx < model->counters.input; idx++) {
1,914✔
157
        php_ort_status_flow(
1,276✔
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
    }
172

173
    php_ort_status_flow(
638✔
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);
638✔
187

188
    for (idx = 0; idx < model->counters.output; idx++) {
1,276✔
189
        php_ort_status_flow(
638✔
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
    }
204

205
    return 1;
206
}
207

208
static zend_bool php_ort_model_construct_from_file(ort_model_t *model,  zend_string *name, zend_string *file){
638✔
209
    OrtSessionOptions* options = NULL;
638✔
210
    OrtStatus* status;
638✔
211

212
    model->kind = ORT_MODEL_SOURCE_FILE;
638✔
213
    model->name = php_ort_string_copy(name);
638✔
214
    model->source.file = php_ort_string_copy(file);
638✔
215
    
216
    php_ort_status_flow(
638✔
217
        (status = api->CreateSessionOptions(&options)),
218
        {
219
            api->ReleaseStatus(status);
220

221
            return 0;
222
        },
223
        php_ort_status_model_invalidoptions_ce,
224
        "failed to allocate SessionOptions* for Model: %s",
225
        api->GetErrorMessage(status));
226

227
    php_ort_status_flow(
638✔
228
        (status = api->SetSessionGraphOptimizationLevel(options, ORT_ENABLE_ALL)),
229
        {
230
            api->ReleaseStatus(status);
231

232
            return 0;
233
        },
234
        php_ort_status_model_invalidoptions_ce,
235
        "failed to set graph optimization level in SessionOptions* for Model: %s",
236
        api->GetErrorMessage(status));
237

238
    php_ort_string_temp_t pass = php_ort_string_pass(ZSTR_VAL(file));
638✔
239

240
    php_ort_status_flow(
638✔
241
        (status = api->CreateSession(php_ort_environment(),
242
            pass, options, &model->session)),
243
        {
244
            api->ReleaseStatus(status);
245
            php_ort_string_free(pass);
246
            return 0;
247
        },
248
        php_ort_status_model_invalidmemory_ce,
249
        "failed to allocate OrtSession* for Model: %s",
250
        api->GetErrorMessage(status));
251

252
    php_ort_string_free(pass);
638✔
253

254
    api->ReleaseSessionOptions(options);
638✔
255

256
    return php_ort_model_construct_complete(model);
638✔
257
}
258

259
static zend_bool php_ort_model_construct_from_array(ort_model_t *model,  zend_string *name, zend_string *file){
×
260
    OrtSessionOptions* options = NULL;
×
261
    OrtStatus* status;
×
262

263
    model->kind = ORT_MODEL_SOURCE_MEMORY;
×
264
    model->name = php_ort_string_copy(name);
×
265
    model->source.memory = php_ort_string_copy(file);
×
266

267
    php_ort_status_flow(
×
268
        (status = api->CreateSessionOptions(&options)),
269
        {
270
            api->ReleaseStatus(status);
271

272
            return 0;
273
        },
274
        php_ort_status_model_invalidoptions_ce,
275
        "failed to allocate SessionOptions* for Model: %s",
276
        api->GetErrorMessage(status));
277

278
    php_ort_status_flow(
×
279
        (status = api->SetSessionGraphOptimizationLevel(options, ORT_ENABLE_ALL)),
280
        {
281
            api->ReleaseStatus(status);
282

283
            return 0;
284
        },
285
        php_ort_status_model_invalidoptions_ce,
286
        "failed to set graph optimization level in SessionOptions* for Model: %s",
287
        api->GetErrorMessage(status));
288

289
    php_ort_status_flow(
×
290
        (status = api->CreateSessionFromArray(php_ort_environment(),
291
            ZSTR_VAL(model->source.memory),
292
            ZSTR_LEN(model->source.memory),
293
            options, &model->session)),
294
        {
295
            api->ReleaseStatus(status);
296
            return 0;
297
        },
298
        php_ort_status_model_invalidmemory_ce,
299
        "failed to allocate OrtSession* for Model: %s",
300
        api->GetErrorMessage(status));
301

302
    api->ReleaseSessionOptions(options);
×
303

304
    return php_ort_model_construct_complete(model);
×
305
}
306

307
ZEND_BEGIN_ARG_INFO_EX(php_ort_model_construct_arginfo, 0, 0, 1)
308
     ZEND_ARG_TYPE_INFO(0, name,   IS_STRING, 0)
309
     ZEND_ARG_TYPE_INFO(0, source,  IS_STRING, 0)
310
     ZEND_ARG_TYPE_INFO(0, array,  _IS_BOOL,  0)
311
ZEND_END_ARG_INFO()
312

313
PHP_METHOD(ONNX_Model, __construct)
726✔
314
{
315
    php_ort_model_t *ort = php_ort_model_fetch(Z_OBJ(EX(This)));
726✔
316

317
    zend_string *name;
726✔
318
    zend_string *source = NULL;
726✔
319
    zend_bool array = 0;
726✔
320

321
    ZEND_PARSE_PARAMETERS_START(1, 3);
726✔
322
        Z_PARAM_STR(name)
726✔
323
        Z_PARAM_OPTIONAL
726✔
324
        Z_PARAM_STR(source)
726✔
325
        Z_PARAM_BOOL(array)
682✔
326
    ZEND_PARSE_PARAMETERS_END();
×
327

328
#ifdef ZTS
329
        php_ort_status_flow(
726✔
330
            tsrm_mutex_lock(php_ort_model_mutex) != SUCCESS,
331
            return,
332
            php_ort_status_safetyerror_ce,
333
            "it was not possible to acquire the model mutex, something is terribly wrong");
334
#endif
335

336
    if (!(ort->object = zend_hash_find_ptr(&php_ort_models, name))) {
1,452✔
337
        if (!array) {
682✔
338
            char path[4096];
682✔
339

340
            php_ort_status_flow(
704✔
341
                !source,
342
                return,
343
                php_ort_status_model_invalidfile_ce,
344
                "model %s could not be loaded and no file provided",
345
                ZSTR_VAL(name));
346

347
            php_ort_status_flow(
660✔
348
                (ZSTR_LEN(source) > 4096),
349
                return,
350
                php_ort_status_model_invalidfile_ce,
351
                "model %s could not be created: file name too long",
352
                ZSTR_VAL(name));
353

354
            php_ort_status_flow(
660✔
355
                (NULL == VCWD_REALPATH(ZSTR_VAL(source), path)),
356
                return,
357
                php_ort_status_model_invalidfile_ce,
358
                "model %s could not be found, %s is not a valid path",
359
                ZSTR_VAL(name), ZSTR_VAL(source));
360
        }
361

362
        ort_model_t *model = pecalloc(1, sizeof(ort_model_t), 1);
638✔
363

364
        model->refcount = 1;
638✔
365

366
        zend_bool result = array ?
1,276✔
367
            php_ort_model_construct_from_array(model, name, source) :
×
368
            php_ort_model_construct_from_file(model, name, source) ;
638✔
369
        if (!result) {
638✔
370
            php_ort_model_free(model);
×
371
#ifdef ZTS
372
            php_ort_status_flow(
×
373
                tsrm_mutex_unlock(php_ort_model_mutex) != SUCCESS,
374
                return,
375
                php_ort_status_safetyerror_ce,
376
                "it was not possible to release the model mutex, something is terribly wrong");
377
#endif
378
            return;
379
        }
380

381
        ort->object = zend_hash_add_ptr(
638✔
382
            &php_ort_models,
383
            model->name,
384
            model);
385
        php_ort_atomic_addref(&ort->object->refcount);
638✔
386
    } else if (ort->object->kind == ORT_MODEL_SOURCE_FILE) {
44✔
387

388
#ifdef ZTS
389
        php_ort_status_flow(
66✔
390
            source && !zend_string_equals(ort->object->source.file, source),
391
            {
392
                php_ort_status_flow(
393
                    tsrm_mutex_unlock(php_ort_model_mutex) != SUCCESS,
394
                    return,
395
                    php_ort_status_safetyerror_ce,
396
                    "it was not possible to release the model mutex, something is terribly wrong");
397
                ort->object = NULL;
398
                return;
399
            },
400
            php_ort_status_model_invalidfile_ce,
401
            "a model with the name %s is already loaded from %s, the file %s does not match",
402
            ZSTR_VAL(ort->object->name), ZSTR_VAL(ort->object->source.file), ZSTR_VAL(source));
403
#else
404
        php_ort_status_flow(
405
            source && !zend_string_equals(ort->object->source.file, source),
406
            {
407
                ort->object = NULL;
408
                return;
409
            },
410
            php_ort_status_model_invalidfile_ce,
411
            "a model with the name %s is already loaded from %s, the file %s does not match",
412
            ZSTR_VAL(ort->object->name), ZSTR_VAL(ort->object->source.file), ZSTR_VAL(source));
413
#endif
414
        php_ort_atomic_addref(&ort->object->refcount);
22✔
415
    } else {
416
        /* Created from array, we can't validate this in the same way
417
            it doesn't make much sense to compare what could be several
418
            gb of memory */
419
        php_ort_atomic_addref(&ort->object->refcount);
×
420
    }
421

422
#ifdef ZTS
423
    php_ort_status_flow(
660✔
424
        tsrm_mutex_unlock(php_ort_model_mutex) != SUCCESS,
425
        return,
426
        php_ort_status_safetyerror_ce,
427
        "it was not possible to release the model mutex, something is terribly wrong");
428
#endif
429
}
430

431
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getName_arginfo, 0, 0, IS_STRING, 0)
432
ZEND_END_ARG_INFO()
433

434
PHP_METHOD(ONNX_Model, getName)
66✔
435
{
436
    php_ort_model_t *ort =
66✔
437
        php_ort_model_fetch(Z_OBJ(EX(This)));
66✔
438

439
    ZEND_PARSE_PARAMETERS_NONE();
66✔
440

441
    RETURN_STR_COPY(ort->object->name);
66✔
442
}
443

444
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getFile_arginfo, 0, 0, IS_STRING, 0)
445
ZEND_END_ARG_INFO()
446

447
PHP_METHOD(ONNX_Model, getFile)
66✔
448
{
449
    php_ort_model_t *ort =
66✔
450
        php_ort_model_fetch(Z_OBJ(EX(This)));
66✔
451

452
    ZEND_PARSE_PARAMETERS_NONE();
66✔
453

454
    if (ort->object->kind == ORT_MODEL_SOURCE_FILE) {
66✔
455
        RETURN_STR_COPY(ort->object->source.file);
66✔
456
    }
457
}
458

459
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getInput_arginfo, 0, 1, IS_STRING, 0)
460
     ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
461
ZEND_END_ARG_INFO()
462

463
PHP_METHOD(ONNX_Model, getInput)
66✔
464
{
465
    php_ort_model_t *ort =
66✔
466
        php_ort_model_fetch(Z_OBJ(EX(This)));
66✔
467
    zend_long index;
66✔
468

469
    ZEND_PARSE_PARAMETERS_START(1, 1);
66✔
470
        Z_PARAM_LONG(index)
66✔
471
    ZEND_PARSE_PARAMETERS_END();
×
472

473
    php_ort_status_flow(
66✔
474
        (index < 0 || index >= ort->object->counters.input),
475
        return,
476
        php_ort_status_model_invalidindex_ce,
477
        "index %zd is out of range for input",
478
        index);
479

480
    RETURN_STRING(ort->object->names.input[index]);
44✔
481
}
482

483
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getInputCount_arginfo, 0, 0, IS_LONG, 0)
484
ZEND_END_ARG_INFO()
485

486
PHP_METHOD(ONNX_Model, getInputCount)
66✔
487
{
488
    php_ort_model_t *ort =
66✔
489
        php_ort_model_fetch(Z_OBJ(EX(This)));
66✔
490

491
    ZEND_PARSE_PARAMETERS_NONE();
66✔
492

493
    RETURN_LONG(ort->object->counters.input);
66✔
494
}
495

496
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getOutput_arginfo, 0, 1, IS_STRING, 0)
497
     ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0)
498
ZEND_END_ARG_INFO()
499

500
PHP_METHOD(ONNX_Model, getOutput)
44✔
501
{
502
    php_ort_model_t *ort =
44✔
503
        php_ort_model_fetch(Z_OBJ(EX(This)));
44✔
504
    zend_long index;
44✔
505

506
    ZEND_PARSE_PARAMETERS_START(1, 1);
44✔
507
        Z_PARAM_LONG(index)
44✔
508
    ZEND_PARSE_PARAMETERS_END();
×
509

510
    php_ort_status_flow(
44✔
511
        (index < 0 || index >= ort->object->counters.output),
512
        return,
513
        php_ort_status_model_invalidindex_ce,
514
        "index %zd is out of range for output",
515
        index);
516

517
    RETURN_STRING(ort->object->names.output[index]);
44✔
518
}
519

520
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getOutputCount_arginfo, 0, 0, IS_LONG, 0)
521
ZEND_END_ARG_INFO()
522

523
PHP_METHOD(ONNX_Model, getOutputCount)
66✔
524
{
525
    php_ort_model_t *ort =
66✔
526
        php_ort_model_fetch(Z_OBJ(EX(This)));
66✔
527

528
    ZEND_PARSE_PARAMETERS_NONE();
66✔
529

530
    RETURN_LONG(ort->object->counters.output);
66✔
531
}
532

533
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_unload_arginfo, 0, 1, _IS_BOOL, 0)
534
    ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0)
535
ZEND_END_ARG_INFO()
536

537
PHP_METHOD(ONNX_Model, unload)
66✔
538
{
539
    zend_string *name;
66✔
540

541
    ZEND_PARSE_PARAMETERS_START(1, 1)
66✔
542
        Z_PARAM_STR(name)
66✔
543
    ZEND_PARSE_PARAMETERS_END();
×
544

545
#ifdef ZTS
546
    php_ort_status_flow(
66✔
547
        tsrm_mutex_lock(php_ort_model_mutex) != SUCCESS,
548
        return,
549
    php_ort_status_safetyerror_ce,
550
    "it was not possible to acquire the model mutex, something is terribly wrong");
551
#endif
552

553
    RETVAL_BOOL(zend_hash_del(&php_ort_models, name) == SUCCESS);
66✔
554

555
#ifdef ZTS
556
    php_ort_status_flow(
66✔
557
        tsrm_mutex_unlock(php_ort_model_mutex) != SUCCESS,
558
        return,
559
    php_ort_status_safetyerror_ce,
560
    "it was not possible to release the model mutex, something is terribly wrong");
561
#endif
562
}
563

564
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(php_ort_model_getInputIterator_arginfo, 0, 0, ORT\\Model\\Iterator, 0)
565
ZEND_END_ARG_INFO()
566

567
PHP_METHOD(ONNX_Model, getInputIterator)
44✔
568
{
569
    php_ort_model_t *ort =
44✔
570
        php_ort_model_fetch(Z_OBJ(EX(This)));
44✔
571
    ZEND_PARSE_PARAMETERS_NONE();
44✔
572

573
    php_ort_iterator_model(ort->object,
44✔
574
        (const char * const*) ort->object->names.input,
44✔
575
            ort->object->counters.input, return_value);
30✔
576
}
577

578
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(php_ort_model_getOutputIterator_arginfo, 0, 0, ORT\\Model\\Iterator, 0)
579
ZEND_END_ARG_INFO()
580

581
PHP_METHOD(ONNX_Model, getOutputIterator)
44✔
582
{
583
    php_ort_model_t *ort =
44✔
584
        php_ort_model_fetch(Z_OBJ(EX(This)));
44✔
585
    ZEND_PARSE_PARAMETERS_NONE();
44✔
586

587
    php_ort_iterator_model(ort->object,
44✔
588
        (const char * const*) ort->object->names.output,
44✔
589
            ort->object->counters.output, return_value);
30✔
590
}
591

592
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(php_ort_model_getMeta_arginfo, 0, 1, IS_MIXED, 0)
593
    ZEND_ARG_TYPE_INFO(0, property, IS_STRING, 0)
594
ZEND_END_ARG_INFO()
595

596
PHP_METHOD(ONNX_Model, getMeta)
154✔
597
{
598
    php_ort_model_t* ort = php_ort_model_fetch(Z_OBJ(EX(This)));
154✔
599
    zend_string *property = NULL;
154✔
600
    char *str_value = NULL;
154✔
601
    int64_t int_value;
154✔
602
    OrtStatus* status;
154✔
603

604
    ZEND_PARSE_PARAMETERS_START(1, 1);
154✔
605
        Z_PARAM_STR(property)
154✔
606
    ZEND_PARSE_PARAMETERS_END();
×
607

608
    const char *prop = ZSTR_VAL(property);
154✔
609
    
610
    if (strcmp(prop, "version") == 0) {
154✔
611
        php_ort_status_flow(
22✔
612
            (status = api->ModelMetadataGetVersion(ort->object->metadata, &int_value)),
613
            {
614
                api->ReleaseStatus(status);
615
                return;
616
            },
617
            php_ort_status_model_invalidmodel_ce,
618
            "failed to get version for Model: %s",
619
            api->GetErrorMessage(status));
620
        RETURN_LONG(int_value);
22✔
621
    } else if (strcmp(prop, "producer") == 0) {
132✔
622
        php_ort_status_flow(
22✔
623
            (status = api->ModelMetadataGetProducerName(ort->object->metadata, ort->object->allocator, &str_value)),
624
            {
625
                api->ReleaseStatus(status);
626
                return;
627
            },
628
            php_ort_status_model_invalidmodel_ce,
629
            "failed to get producer name for Model: %s",
630
            api->GetErrorMessage(status));
631
        if (str_value) {
22✔
632
            RETVAL_STRING(str_value);
22✔
633
            php_ort_status_flow(
22✔
634
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
635
                {
636
                    api->ReleaseStatus(status);
637
                    return;
638
                },
639
                php_ort_status_model_invalidmemory_ce,
640
                "failed to release producer name memory for Model: %s",
641
                api->GetErrorMessage(status));
642
            return;
643
        }
644
    } else if (strcmp(prop, "description") == 0) {
110✔
645
        php_ort_status_flow(
22✔
646
            (status = api->ModelMetadataGetDescription(ort->object->metadata, ort->object->allocator, &str_value)),
647
            {
648
                api->ReleaseStatus(status);
649
                return;
650
            },
651
            php_ort_status_model_invalidmodel_ce,
652
            "failed to get description for Model: %s",
653
            api->GetErrorMessage(status));
654
        if (str_value) {
22✔
655
            RETVAL_STRING(str_value);
22✔
656
            php_ort_status_flow(
22✔
657
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
658
                {
659
                    api->ReleaseStatus(status);
660
                    return;
661
                },
662
                php_ort_status_model_invalidmemory_ce,
663
                "failed to release description memory for Model: %s",
664
                api->GetErrorMessage(status));
665
            return;
666
        }
667
    } else if (strcmp(prop, "domain") == 0) {
88✔
668
        php_ort_status_flow(
22✔
669
            (status = api->ModelMetadataGetDomain(ort->object->metadata, ort->object->allocator, &str_value)),
670
            {
671
                api->ReleaseStatus(status);
672
                return;
673
            },
674
            php_ort_status_model_invalidmodel_ce,
675
            "failed to get domain for Model: %s",
676
            api->GetErrorMessage(status));
677
        if (str_value) {
22✔
678
            RETVAL_STRING(str_value);
22✔
679
            php_ort_status_flow(
22✔
680
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
681
                {
682
                    api->ReleaseStatus(status);
683
                    return;
684
                },
685
                php_ort_status_model_invalidmemory_ce,
686
                "failed to release domain memory for Model: %s",
687
                api->GetErrorMessage(status));
688
            return;
689
        }
690
    } else if (strcmp(prop, "graph_name") == 0) {
66✔
691
        php_ort_status_flow(
22✔
692
            (status = api->ModelMetadataGetGraphName(ort->object->metadata, ort->object->allocator, &str_value)),
693
            {
694
                api->ReleaseStatus(status);
695
                return;
696
            },
697
            php_ort_status_model_invalidmodel_ce,
698
            "failed to get graph name for Model: %s",
699
            api->GetErrorMessage(status));
700
        if (str_value) {
22✔
701
            RETVAL_STRING(str_value);
22✔
702
            php_ort_status_flow(
22✔
703
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
704
                {
705
                    api->ReleaseStatus(status);
706
                    return;
707
                },
708
                php_ort_status_model_invalidmemory_ce,
709
                "failed to release graph name memory for Model: %s",
710
                api->GetErrorMessage(status));
711
            return;
712
        }
713
    } else if (strcmp(prop, "graph_description") == 0) {
44✔
714
        php_ort_status_flow(
22✔
715
            (status = api->ModelMetadataGetGraphDescription(ort->object->metadata, ort->object->allocator, &str_value)),
716
            {
717
                api->ReleaseStatus(status);
718
                return;
719
            },
720
            php_ort_status_model_invalidmodel_ce,
721
            "failed to get graph description for Model: %s",
722
            api->GetErrorMessage(status));
723
        if (str_value) {
22✔
724
            RETVAL_STRING(str_value);
22✔
725
            php_ort_status_flow(
22✔
726
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
727
                {
728
                    api->ReleaseStatus(status);
729
                    return;
730
                },
731
                php_ort_status_model_invalidmemory_ce,
732
                "failed to release graph description memory for Model: %s",
733
                api->GetErrorMessage(status));
734
            return;
735
        }
736
    } else {
737
        /* Try to get custom metadata */
738
        php_ort_status_flow(
22✔
739
            (status = api->ModelMetadataLookupCustomMetadataMap(ort->object->metadata, ort->object->allocator, prop, &str_value)),
740
            {
741
                api->ReleaseStatus(status);
742
                return;
743
            },
744
            php_ort_status_model_invalidmodel_ce,
745
            "failed to get custom metadata for Model: %s",
746
            api->GetErrorMessage(status));
747
        if (str_value) {
22✔
748
            RETVAL_STRING(str_value);
×
749
            php_ort_status_flow(
×
750
                (status = api->AllocatorFree(ort->object->allocator, str_value)),
751
                {
752
                    api->ReleaseStatus(status);
753
                    return;
754
                },
755
                php_ort_status_model_invalidmemory_ce,
756
                "failed to release custom metadata memory for Model: %s",
757
                api->GetErrorMessage(status));
758
            return;
759
        }
760
    }
761
    
762
    RETURN_NULL();
22✔
763
}
764

765
zend_function_entry php_ort_model_methods[] = {
766
    PHP_ME(ONNX_Model, __construct,       php_ort_model_construct_arginfo,             ZEND_ACC_PUBLIC)
767
    PHP_ME(ONNX_Model, getName,           php_ort_model_getName_arginfo,               ZEND_ACC_PUBLIC)
768
    PHP_ME(ONNX_Model, getFile,           php_ort_model_getFile_arginfo,               ZEND_ACC_PUBLIC)
769
    PHP_ME(ONNX_Model, getInput,          php_ort_model_getInput_arginfo,              ZEND_ACC_PUBLIC)
770
    PHP_ME(ONNX_Model, getInputCount,     php_ort_model_getInputCount_arginfo,         ZEND_ACC_PUBLIC)
771
    PHP_ME(ONNX_Model, getInputIterator,  php_ort_model_getInputIterator_arginfo,      ZEND_ACC_PUBLIC)
772
    PHP_ME(ONNX_Model, getOutput,         php_ort_model_getOutput_arginfo,             ZEND_ACC_PUBLIC)
773
    PHP_ME(ONNX_Model, getOutputCount,    php_ort_model_getOutputCount_arginfo,        ZEND_ACC_PUBLIC)
774
    PHP_ME(ONNX_Model, getOutputIterator, php_ort_model_getOutputIterator_arginfo,     ZEND_ACC_PUBLIC)
775
    PHP_ME(ONNX_Model, getMeta,           php_ort_model_getMeta_arginfo,               ZEND_ACC_PUBLIC)
776
    PHP_ME(ONNX_Model, unload,            php_ort_model_unload_arginfo,                ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
777
    PHP_FE_END
778
};
779

780
zend_object* php_ort_model_create(zend_class_entry *type) {
726✔
781
  php_ort_model_t *ort = ecalloc(1,
726✔
782
     sizeof(php_ort_model_t) + zend_object_properties_size(type));
783

784
   zend_object_std_init(&ort->std, type);
726✔
785

786
   ort->std.handlers = &php_ort_model_handlers;
726✔
787
   ort->object       = NULL;
726✔
788

789
   return &ort->std;
726✔
790
}
791

792
static HashTable* php_ort_model_debug(zend_object *zo, int *temp) {
22✔
793
    php_ort_model_t *ort = php_ort_model_fetch(zo);
22✔
794
    HashTable *debug;
22✔
795

796
    ALLOC_HASHTABLE(debug);
22✔
797
    zend_hash_init(debug, 3, NULL, ZVAL_PTR_DTOR, 0);
22✔
798

799
    if (!ort->object) {
22✔
800
      goto __php_ort_model_debug_return;
×
801
    }
802

803
    if (ort->object->name) {
22✔
804
      zval name;
22✔
805
  
806
      ZVAL_STR_COPY(&name, ort->object->name);
22✔
807
      zend_hash_add(debug,
22✔
808
        ZSTR_KNOWN(ZEND_STR_NAME), &name);
22✔
809
    }
810

811
    if (ort->object->kind == ORT_MODEL_SOURCE_FILE && ort->object->source.file) {
22✔
812
      zval file;
22✔
813
  
814
      ZVAL_STR_COPY(&file, ort->object->source.file);
22✔
815
      zend_hash_add(debug,
22✔
816
        ZSTR_KNOWN(ZEND_STR_FILE), &file);
817
    }
818

819
    size_t idx;
22✔
820
    zval   arr;
22✔
821

822
    array_init(&arr);
22✔
823
    zend_hash_str_add(debug, "inputs", sizeof("inputs")-1, &arr);
22✔
824
    for (idx = 0; idx < ort->object->counters.input; idx++) {
88✔
825
      add_next_index_string(&arr, ort->object->names.input[idx]);
44✔
826
    }
827

828
    array_init(&arr);
22✔
829
    zend_hash_str_add(debug, "outputs", sizeof("outputs")-1, &arr);
22✔
830
    for (idx = 0; idx < ort->object->counters.output; idx++) {
66✔
831
      add_next_index_string(&arr, ort->object->names.output[idx]);
22✔
832
    }
833

834
__php_ort_model_debug_return:
22✔
835
    *temp = 1;
22✔
836

837
    return debug;
22✔
838
}
839

840
void php_ort_model_destroy(zend_object *o) {
726✔
841
    php_ort_model_t *ort =
726✔
842
        php_ort_model_fetch(o);
726✔
843

844
    php_ort_model_release(ort->object);
726✔
845

846
    zend_object_std_dtor(o);
726✔
847
}
726✔
848

849
PHP_MINIT_FUNCTION(ORT_MODEL)
4,620✔
850
{
851
    zend_class_entry ce;
4,620✔
852

853
#ifdef ZTS
854
    php_ort_model_mutex = tsrm_mutex_alloc();
4,620✔
855
#endif
856

857
    zend_hash_init(&php_ort_models, 16, NULL, php_ort_model_del, 1);
4,620✔
858

859
    memcpy(&php_ort_model_handlers,
4,620✔
860
        zend_get_std_object_handlers(), sizeof(zend_object_handlers));
861

862
    php_ort_model_handlers.offset = XtOffsetOf(php_ort_model_t, std);
4,620✔
863
    php_ort_model_handlers.get_debug_info = php_ort_model_debug;
4,620✔
864
    php_ort_model_handlers.free_obj = php_ort_model_destroy;
4,620✔
865
    php_ort_model_handlers.clone_obj = NULL;
4,620✔
866

867
    INIT_NS_CLASS_ENTRY(ce, "ORT", "Model", php_ort_model_methods);
4,620✔
868

869
    php_ort_model_ce = zend_register_internal_class(&ce);
4,620✔
870
    php_ort_model_ce->create_object = php_ort_model_create;
4,620✔
871

872
#ifdef ZEND_ACC_NOT_SERIALIZABLE
873
    php_ort_model_ce->ce_flags |= ZEND_ACC_NOT_SERIALIZABLE;
4,620✔
874
  #else
875
    php_ort_model_ce->serialize = zend_class_serialize_deny;
876
    php_ort_model_ce->unserialize = zend_class_unserialize_deny;
877
#endif
878

879
  return SUCCESS;
4,620✔
880
}
881

882
PHP_MSHUTDOWN_FUNCTION(ORT_MODEL)
4,620✔
883
{
884
    zend_hash_destroy(&php_ort_models);
4,620✔
885
  
886
#ifdef ZTS
887
    tsrm_mutex_free(php_ort_model_mutex);
4,620✔
888
#endif
889

890
   return SUCCESS;
4,620✔
891
}
892
 
893
PHP_RINIT_FUNCTION(ORT_MODEL)
4,620✔
894
{
895
   return SUCCESS;
4,620✔
896
}
897
 
898
PHP_RSHUTDOWN_FUNCTION(ORT_MODEL)
4,620✔
899
{
900
   return SUCCESS;
4,620✔
901
}
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