Skip to content

Commit 3a98d77

Browse files
committed
[add] added mobilenet model use case to quickly check for leaks on modelruns with large tensors (dagrun and modelrun variations)
1 parent fcdf0d2 commit 3a98d77

10 files changed

+207
-16
lines changed

test/includes.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
except:
1717
pass
1818

19+
MAX_ITERATIONS = 2 if os.environ.get("MAX_ITERATIONS") == None else os.environ.get("MAX_ITERATIONS")
1920
TEST_TF = os.environ.get("TEST_TF") != "0" and os.environ.get("WITH_TF") != "0"
2021
TEST_TFLITE = os.environ.get("TEST_TFLITE") != "0" and os.environ.get("WITH_TFLITE") != "0"
2122
TEST_PT = os.environ.get("TEST_PT") != "0" and os.environ.get("WITH_PT") != "0"
@@ -24,7 +25,7 @@
2425
DEVICE = os.environ.get('DEVICE', 'CPU').upper().encode('utf-8', 'ignore').decode('utf-8')
2526
VALGRIND = os.environ.get("VALGRIND") == "1"
2627
print(f"Running tests on {DEVICE}\n")
27-
28+
print(f"Using a max of {MAX_ITERATIONS} iterations per test\n")
2829
# change this to make inference tests longer
2930
MAX_TRANSACTIONS=100
3031

@@ -91,12 +92,35 @@ def load_resnet_test_data():
9192

9293
return model_pb, script, labels, img
9394

95+
def load_mobilenet_v1_test_data():
96+
test_data_path = os.path.join(os.path.dirname(__file__), 'test_data')
97+
labels_filename = os.path.join(test_data_path, 'imagenet_class_index.json')
98+
image_filename = os.path.join(test_data_path, 'panda.jpg')
99+
model_filename = os.path.join(test_data_path, 'mobilenet/mobilenet_v1_100_224_cpu_NxHxWxC.pb')
100+
input_var = 'input'
101+
output_var = 'MobilenetV1/Predictions/Reshape_1'
102+
103+
with open(model_filename, 'rb') as f:
104+
model_pb = f.read()
105+
106+
with open(labels_filename, 'r') as f:
107+
labels = json.load(f)
108+
109+
img_height, img_width = 224, 224
110+
111+
img = imread(image_filename)
112+
img = resize(img, (img_height, img_width), mode='constant', anti_aliasing=True)
113+
img = img.astype(np.float32)
114+
115+
return model_pb, input_var, output_var, labels, img
94116

95-
def load_mobilenet_test_data():
117+
def load_mobilenet_v2_test_data():
96118
test_data_path = os.path.join(os.path.dirname(__file__), 'test_data')
97119
labels_filename = os.path.join(test_data_path, 'imagenet_class_index.json')
98120
image_filename = os.path.join(test_data_path, 'panda.jpg')
99-
model_filename = os.path.join(test_data_path, 'mobilenet_v2_1.4_224_frozen.pb')
121+
model_filename = os.path.join(test_data_path, 'mobilenet/mobilenet_v2_1.4_224_frozen.pb')
122+
input_var = 'input'
123+
output_var = 'MobilenetV2/Predictions/Reshape_1'
100124

101125
with open(model_filename, 'rb') as f:
102126
model_pb = f.read()
@@ -110,7 +134,7 @@ def load_mobilenet_test_data():
110134
img = resize(img, (img_height, img_width), mode='constant', anti_aliasing=True)
111135
img = img.astype(np.float32)
112136

113-
return model_pb, labels, img
137+
return model_pb, input_var, output_var, labels, img
114138

115139
def load_creditcardfraud_data(env,max_tensors=10000):
116140
test_data_path = os.path.join(os.path.dirname(__file__), 'test_data')
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:bbb2752038ff1749d2b55988bb5f6e999a799c19413a0691b82d29f7aec0bab3
3+
size 17198345
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:f1fe206dfd3cff261cf403b5757abec886da445a80056e55310ddac0b2805a3b
3+
size 17198345
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:fd925f4b59d8d5035ccb2ecdfbf9b0f47a5ba3acfa81bd5a18536f69021df74a
3+
size 34277746
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:111479258f3841c93d0a7a377c976c24e8281077818991931429d2277dd88590
3+
size 24508794
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import tensorflow as tf
2+
import tensorflow_hub as hub
3+
import ml2rt
4+
import argparse
5+
import sys
6+
7+
url = 'https://tfhub.dev/google/imagenet/mobilenet_v1_100_224/quantops/classification/3'
8+
model_name = 'mobilenet_v1_100_224'
9+
module = hub.Module(url)
10+
batch_size = 1
11+
number_channels = 3
12+
height, width = hub.get_expected_image_size(module)
13+
input_var = 'input'
14+
output_var = 'MobilenetV1/Predictions/Reshape_1'
15+
16+
parser = argparse.ArgumentParser()
17+
parser.add_argument('--gpu', action="store_true", default=False)
18+
parser.add_argument('--input-shape', default="NxHxWxC", type=str)
19+
args = parser.parse_args()
20+
device = 'gpu' if args.gpu else 'cpu'
21+
22+
gpu_available = tf.test.is_gpu_available(
23+
cuda_only=True, min_cuda_compute_capability=None
24+
)
25+
26+
if gpu_available is False and args.gpu:
27+
print("No CUDA GPUs found. Exiting...")
28+
sys.exit(1)
29+
30+
var_converter = tf.compat.v1.graph_util.convert_variables_to_constants
31+
32+
if args.input_shape == "NxHxWxC":
33+
print("Saving N x H x W x C (1, 224, 224, 3) (with channels_last data format)")
34+
images = tf.compat.v1.placeholder(tf.float32, shape=(
35+
batch_size, height, width, number_channels), name=input_var)
36+
elif args.input_shape == "NxHxWxC":
37+
print("Saving N x C x H x W (1, 3, 224, 224)")
38+
images = tf.placeholder(tf.float32, shape=(
39+
batch_size, number_channels, height, width), name=input_var)
40+
else:
41+
print("inputs shape is either NxHxWxC or NxCxHxW. Exiting...")
42+
sys.exit(1)
43+
44+
logits = module(images)
45+
logits = tf.identity(logits, output_var)
46+
with tf.compat.v1.Session() as sess:
47+
sess.run([tf.compat.v1.global_variables_initializer()])
48+
ml2rt.save_tensorflow(sess, '{model_name}_{device}_{input_shape}.pb'.format(
49+
model_name=model_name, device=device, input_shape=args.input_shape), output=[output_var])

test/tests_sanitizer.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import redis
2+
from functools import wraps
3+
import multiprocessing as mp
4+
from includes import *
5+
6+
'''
7+
python -m RLTest --test tests_sanitizer.py --module path/to/redisai.so
8+
'''
9+
10+
11+
def test_sanitizer_dagrun_mobilenet_v1(env):
12+
if (not TEST_TF or not TEST_PT):
13+
return
14+
con = env.getConnection()
15+
mem_allocator = con.execute_command('info', 'memory')['mem_allocator']
16+
if 'jemalloc' in mem_allocator:
17+
print("exiting sanitizer test given we're not using stdlib allocator")
18+
return
19+
20+
model_name = 'mobilenet_v1'
21+
model_pb, input_var, output_var, labels, img = load_mobilenet_v1_test_data()
22+
23+
ret = con.execute_command('AI.MODELSET', model_name, 'TF', DEVICE,
24+
'INPUTS', input_var,
25+
'OUTPUTS', output_var,
26+
'BLOB', model_pb)
27+
env.assertEqual(ret, b'OK')
28+
29+
for opnumber in range(1, MAX_ITERATIONS):
30+
image_key = 'image'
31+
temp_key1 = 'temp_key1'
32+
temp_key2 = 'temp_key2'
33+
class_key = 'output'
34+
35+
ret = con.execute_command(
36+
'AI.DAGRUN', '|>',
37+
'AI.TENSORSET', image_key, 'FLOAT', 1, 224, 224, 3, 'BLOB', img.tobytes(), '|>',
38+
'AI.MODELRUN', model_name,
39+
'INPUTS', image_key,
40+
'OUTPUTS', class_key, '|>',
41+
'AI.TENSORGET', class_key, 'blob'
42+
)
43+
env.assertEqual([b'OK', b'OK'], ret[:2])
44+
env.assertEqual(1001.0, len(ret[2])/4)
45+
46+
47+
def test_sanitizer_modelrun_mobilenet_v1(env):
48+
if (not TEST_TF or not TEST_PT):
49+
return
50+
con = env.getConnection()
51+
mem_allocator = con.execute_command('info', 'memory')['mem_allocator']
52+
if 'jemalloc' in mem_allocator:
53+
print("exiting sanitizer test given we're not using stdlib allocator")
54+
return
55+
56+
model_name = 'mobilenet_v1'
57+
model_pb, input_var, output_var, labels, img = load_mobilenet_v1_test_data()
58+
59+
ret = con.execute_command('AI.MODELSET', model_name, 'TF', DEVICE,
60+
'INPUTS', input_var,
61+
'OUTPUTS', output_var,
62+
'BLOB', model_pb)
63+
env.assertEqual(ret, b'OK')
64+
65+
for opnumber in range(1, MAX_ITERATIONS):
66+
image_key = 'image'
67+
temp_key1 = 'temp_key1'
68+
temp_key2 = 'temp_key2'
69+
class_key = 'output'
70+
ret = con.execute_command(
71+
'AI.TENSORSET', image_key, 'FLOAT', 1, 224, 224, 3, 'BLOB', img.tobytes()
72+
)
73+
env.assertEqual(b'OK', ret)
74+
75+
ret = con.execute_command(
76+
'AI.MODELRUN', model_name,
77+
'INPUTS', image_key,
78+
'OUTPUTS', class_key
79+
)
80+
81+
env.assertEqual(b'OK', ret)
82+
83+
ret = con.execute_command(
84+
'AI.TENSORGET', class_key, 'blob'
85+
)
86+
87+
env.assertEqual(1001.0, len(ret)/4)

test/tests_tensorflow.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@ def wrapper(env, *args, **kwargs):
2424
def test_run_mobilenet(env):
2525
con = env.getConnection()
2626

27-
input_var = 'input'
28-
output_var = 'MobilenetV2/Predictions/Reshape_1'
29-
30-
model_pb, labels, img = load_mobilenet_test_data()
27+
model_pb, input_var, output_var, labels, img = load_mobilenet_v2_test_data()
3128

3229
con.execute_command('AI.MODELSET', 'mobilenet', 'TF', DEVICE,
3330
'INPUTS', input_var, 'OUTPUTS', output_var, 'BLOB', model_pb)
@@ -94,10 +91,7 @@ def test_run_mobilenet_multiproc(env):
9491

9592
con = env.getConnection()
9693

97-
input_var = 'input'
98-
output_var = 'MobilenetV2/Predictions/Reshape_1'
99-
100-
model_pb, labels, img = load_mobilenet_test_data()
94+
model_pb, input_var, output_var, labels, img = load_mobilenet_v2_test_data()
10195
con.execute_command('AI.MODELSET', 'mobilenet', 'TF', DEVICE,
10296
'INPUTS', input_var, 'OUTPUTS', output_var, 'BLOB', model_pb)
10397
ensureSlaveSynced(con, env)
@@ -627,10 +621,7 @@ def test_tensorflow_modelrun_with_batch_and_minbatch(env):
627621
minbatch_size = 2
628622
model_name = 'model'
629623
another_model_name = 'another_model'
630-
inputvar = 'input'
631-
outputvar = 'MobilenetV2/Predictions/Reshape_1'
632-
633-
model_pb, labels, img = load_mobilenet_test_data()
624+
model_pb, input_var, output_var, labels, img = load_mobilenet_v2_test_data()
634625

635626
con.execute_command('AI.MODELSET', model_name, 'TF', DEVICE,
636627
'BATCHSIZE', batch_size, 'MINBATCHSIZE', minbatch_size,

test/unit/.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Unit test binaries
2+
*.run
3+
4+
# Object files
5+
*.o
6+
*.ko
7+
*.obj
8+
*.elf

test/unit/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
add_subdirectory("${PROJECT_SOURCE_DIR}/deps/googletest" "deps/googletest")
3+
4+
macro(package_add_test TESTNAME)
5+
# create an exectuable in which the tests will be stored
6+
add_executable(${TESTNAME} ${ARGN})
7+
# link the Google test infrastructure, mocking library, and a default main fuction to
8+
# the test executable. Remove g_test_main if writing your own main function.
9+
target_link_libraries(${TESTNAME} gtest gmock gtest_main)
10+
# gtest_discover_tests replaces gtest_add_tests,
11+
# see https://cmake.org/cmake/help/v3.10/module/GoogleTest.html for more options to pass to it
12+
gtest_discover_tests(${TESTNAME}
13+
# set a working directory so your project root so that you can find test data via paths relative to the project root
14+
WORKING_DIRECTORY ${PROJECT_DIR}
15+
PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_DIR}"
16+
)
17+
set_target_properties(${TESTNAME} PROPERTIES FOLDER tests)
18+
endmacro()
19+
20+
package_add_test(test1 test1.cpp)

0 commit comments

Comments
 (0)