Skip to content

Commit 5972370

Browse files
committed
Remove onnx from valgrind suppressions, and fix leaks that were found.
Extend tests to make a more precise check of the allocator usage.
1 parent dd19238 commit 5972370

File tree

3 files changed

+45
-21
lines changed

3 files changed

+45
-21
lines changed

opt/redis_valgrind.sup

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,6 @@
1212
obj:*/libtensorflow_framework.so.*
1313
}
1414

15-
{
16-
ignore_unversioned_libs
17-
Memcheck:Leak
18-
...
19-
obj:*/libonnxruntime.so.*
20-
}
21-
2215
{
2316
ignore_unversioned_libs
2417
Memcheck:Leak

src/backends/onnxruntime.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,19 @@
1717
OrtEnv *env = NULL;
1818

1919
// For model that run on GPU, onnx will not use the custom allocator (redis allocator), but
20-
// the onnx allocator for GPU. But for the auxilery allocations of the input and output names,
21-
// we will use the custom global allocator for models that run on GPU as well
20+
// the onnx allocator for GPU. But for the auxiliary allocations of the input and output names,
21+
// we will use the custom global allocator for models that run on GPU as well.
22+
OrtMemoryInfo *mem_info = NULL;
2223
OrtAllocator *global_allocator = NULL;
2324
unsigned long long OnnxMemory = 0;
2425
unsigned long long OnnxMemoryAccessCounter = 0;
2526

2627
const OrtMemoryInfo *AllocatorInfo(const OrtAllocator *allocator) {
2728
(void)allocator;
2829
const OrtApi *ort = OrtGetApiBase()->GetApi(1);
29-
OrtMemoryInfo *mem_info;
30+
if (mem_info != NULL) {
31+
return mem_info;
32+
}
3033
if (ort->CreateCpuMemoryInfo(OrtDeviceAllocator, OrtMemTypeDefault, &mem_info) != NULL) {
3134
return NULL;
3235
}
@@ -369,6 +372,7 @@ RAI_Model *RAI_ModelCreateORT(RAI_Backend backend, const char *devicestr, RAI_Mo
369372

370373
ONNX_VALIDATE_STATUS(
371374
ort->CreateSessionFromArray(env, modeldef, modellen, session_options, &session))
375+
ort->ReleaseSessionOptions(session_options);
372376

373377
size_t n_input_nodes;
374378
ONNX_VALIDATE_STATUS(ort->SessionGetInputCount(session, &n_input_nodes))
@@ -550,7 +554,14 @@ int RAI_ModelRunORT(RAI_ModelRunCtx **mctxs, RAI_Error *error) {
550554
OrtRunOptions *run_options = NULL;
551555
ONNX_VALIDATE_STATUS(ort->Run(session, run_options, input_names,
552556
(const OrtValue *const *)inputs, n_input_nodes, output_names,
553-
n_output_nodes, outputs))
557+
n_output_nodes, outputs));
558+
559+
for (uint32_t i = 0; i < ninputs; i++) {
560+
status = ort->AllocatorFree(global_allocator, (void *)input_names[i]);
561+
}
562+
for (uint32_t i = 0; i < noutputs; i++) {
563+
status = ort->AllocatorFree(global_allocator, (void *)output_names[i]);
564+
}
554565

555566
for (size_t i = 0; i < n_output_nodes; i++) {
556567
if (nbatches > 1) {

tests/flow/tests_onnx.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -478,16 +478,28 @@ def test_onnx_use_custom_allocator(env):
478478
for k in con.execute_command("INFO MODULES").decode().split("#")[4].split()[1:]}
479479

480480
# Expect using at least 130+63+(size of an address) + 2*(2+63+(size of an address)) bytes.
481-
env.assertTrue(int(ai_memory_config["ai_onnxruntime_memory"]) > 334)
481+
model_allocation_bytes_used = int(ai_memory_config["ai_onnxruntime_memory"])
482+
env.assertTrue(model_allocation_bytes_used > 334)
482483
env.assertEqual(int(ai_memory_config["ai_onnxruntime_memory_access_num"]), 3)
484+
con.execute_command('AI.TENSORSET', 'a_mul{1}', 'FLOAT', 3, 2, 'VALUES', 1.0, 2.0, 3.0, 4.0, 5.0, 6.0)
483485

484-
# Expect using the allocator free function when releasing the model and input and output names.
486+
# Running the model should access the allocator 6 times: allocating+freeing input+output names,
487+
# and allocating+freeing the output as OrtValue.
488+
con.execute_command('AI.MODELRUN', 'm{1}', 'INPUTS', 'a_mul{1}', 'OUTPUTS', 'b{1}')
489+
values = con.execute_command('AI.TENSORGET', 'b{1}', 'VALUES')
490+
env.assertEqual(values, [b'1', b'4', b'9', b'16', b'25', b'36'])
491+
ai_memory_config = {k.split(":")[0]: k.split(":")[1]
492+
for k in con.execute_command("INFO MODULES").decode().split("#")[4].split()[1:]}
493+
env.assertEqual(int(ai_memory_config["ai_onnxruntime_memory_access_num"]), 9)
494+
env.assertEqual(int(ai_memory_config["ai_onnxruntime_memory"]), model_allocation_bytes_used)
495+
496+
# Expect using the allocator free function 3 times: when releasing the model, input name and output name.
485497
con.execute_command('AI.MODELDEL', 'm{1}')
486498
env.assertFalse(con.execute_command('EXISTS', 'm{1}'))
487499
ai_memory_config = {k.split(":")[0]: k.split(":")[1]
488500
for k in con.execute_command("INFO MODULES").decode().split("#")[4].split()[1:]}
489501
env.assertEqual(int(ai_memory_config["ai_onnxruntime_memory"]), 0)
490-
env.assertEqual(int(ai_memory_config["ai_onnxruntime_memory_access_num"]), 6)
502+
env.assertEqual(int(ai_memory_config["ai_onnxruntime_memory_access_num"]), 12)
491503

492504
# test the use of Redis allocator in model run op.
493505
model_filename = os.path.join(test_data_path, 'mnist.onnx')
@@ -502,7 +514,7 @@ def test_onnx_use_custom_allocator(env):
502514
env.assertEqual(ret, b'OK')
503515
con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 1, 1, 28, 28, 'BLOB', sample_raw)
504516

505-
# Expect 16 allocator's access from onnx during the run (in addition to the allocations that were made while
517+
# Expect 18 allocator's access from onnx during the run (in addition to the allocations that were made while
506518
# creating the model).
507519
ai_memory_config = {k.split(":")[0]: k.split(":")[1]
508520
for k in con.execute_command("INFO MODULES").decode().split("#")[4].split()[1:]}
@@ -511,7 +523,7 @@ def test_onnx_use_custom_allocator(env):
511523
ai_memory_config = {k.split(":")[0]: k.split(":")[1]
512524
for k in con.execute_command("INFO MODULES").decode().split("#")[4].split()[1:]}
513525
allocator_access_num_after = ai_memory_config["ai_onnxruntime_memory_access_num"]
514-
env.assertEqual(int(allocator_access_num_after) - int(allocator_access_num_before), 16)
526+
env.assertEqual(int(allocator_access_num_after) - int(allocator_access_num_before), 18)
515527

516528
values = con.execute_command('AI.TENSORGET', 'b{1}', 'VALUES')
517529
argmax = max(range(len(values)), key=lambda i: values[i])
@@ -549,18 +561,26 @@ def test_onnx_use_custom_allocator_with_GPU(env):
549561
for k in con.execute_command("INFO MODULES").decode().split("#")[4].split()[1:]}
550562

551563
# Expect using at least 130+63+(size of an address) + 4*(2+63+(size of an address)) bytes.
552-
env.assertTrue(int(ai_memory_config["ai_onnxruntime_memory"]) > 472)
553-
env.assertTrue(int(ai_memory_config["ai_onnxruntime_memory"]) < 705)
564+
model_allocation_bytes_used = int(ai_memory_config["ai_onnxruntime_memory"])
565+
env.assertTrue(model_allocation_bytes_used > 472)
566+
env.assertTrue(model_allocation_bytes_used < 705)
554567
env.assertEqual(int(ai_memory_config["ai_onnxruntime_memory_access_num"]), 5)
555568

556-
# Make sure that allocator is not used for running and freeing the GPU model.
569+
# Make sure that allocator is not used for running and freeing the GPU model, except for
570+
# the input and output names allocations (and deallocations).
557571
con.execute_command('AI.TENSORSET', 'a{1}', 'FLOAT', 3, 2, 'VALUES', 1.0, 2.0, 3.0, 4.0, 5.0, 6.0)
558572
con.execute_command('AI.MODELRUN', 'm_gpu{1}', 'INPUTS', 'a{1}', 'OUTPUTS', 'b{1}')
559573
values = con.execute_command('AI.TENSORGET', 'b{1}', 'VALUES')
560574
env.assertEqual(values, [b'1', b'4', b'9', b'16', b'25', b'36'])
575+
# Expect that memory usage didn't change, and for another 4 accesses to the allocator (input and output names
576+
# allocation and free)
577+
env.assertEqual(int(ai_memory_config["ai_onnxruntime_memory"]), model_allocation_bytes_used)
578+
env.assertEqual(int(ai_memory_config["ai_onnxruntime_memory_access_num"]), 9)
579+
580+
# Expect only 2 more accesses in delete - for deallocating input and output names
561581
con.execute_command('AI.MODELDEL', 'm_gpu{1}')
562582
env.assertFalse(con.execute_command('EXISTS', 'm_gpu{1}'))
563583
ai_memory_config = {k.split(":")[0]: k.split(":")[1]
564584
for k in con.execute_command("INFO MODULES").decode().split("#")[4].split()[1:]}
565-
env.assertTrue(int(ai_memory_config["ai_onnxruntime_memory"]) < 705)
566-
env.assertEqual(int(ai_memory_config["ai_onnxruntime_memory_access_num"]), 5)
585+
env.assertEqual(int(ai_memory_config["ai_onnxruntime_memory_access_num"]), 11)
586+

0 commit comments

Comments
 (0)