Skip to content
This repository was archived by the owner on Aug 5, 2022. It is now read-only.

Commit 3bbc9f1

Browse files
committed
Merge remote-tracking branch 'internal/release_1.0.2'
2 parents 5b13124 + 329b554 commit 3bbc9f1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+4879
-384
lines changed

Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,13 @@ ifeq ($(CAFFE_PER_LAYER_TIMINGS), 1)
7777
endif
7878

7979
ifeq ($(CAFFE_MLSL_SHUFFLE), 1)
80-
COMMON_FLAGS += -DCAFFE_MLSL_SHUFFLE
80+
COMMON_FLAGS += -DCAFFE_MLSL_SHUFFLE
8181
endif
8282

83+
ifeq ($(FW_OVERLAP_OPT), 1)
84+
COMMON_FLAGS += -DFW_OVERLAP_OPT
85+
endif
8386
endif
84-
8587
#################### MLSL ####################
8688

8789

Makefile.mkldnn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ mkldnn_download:
3232

3333
mkldnn_build: mkldnn_download
3434
cmake $(MKLDNN_CMAKE_FLAGS)
35-
make -C $(CAFFE_ROOTDIR)/$(MKLDNN_BUILDDIR)
35+
make -C $(CAFFE_ROOTDIR)/$(MKLDNN_BUILDDIR) -j$(shell cat /proc/cpuinfo |grep 'processor'|wc -l)
3636
make -C $(CAFFE_ROOTDIR)/$(MKLDNN_BUILDDIR) install
3737
else
3838
mkldnn_download:

cmake/Dependencies.cmake

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,17 @@ if(USE_MLSL)
115115
include_directories(SYSTEM "${MLSL_ROOT}/intel64/include")
116116
link_directories(SYSTEM "${MLSL_ROOT}/intel64/lib")
117117
list(APPEND Caffe_LINKER_LIBS mlsl)
118+
119+
if(CAFFE_PER_LAYER_TIMINGS)
120+
add_definitions("-DCAFFE_PER_LAYER_TIMINGS")
121+
endif()
122+
if(CAFFE_MLSL_SHUFFLE)
123+
add_definitions("-DCAFFE_MLSL_SHUFFLE")
124+
endif()
125+
if(FW_OVERLAP_OPT)
126+
message(STATUS "Forward overlapping optimization is enabled!")
127+
add_definitions("-DFW_OVERLAP_OPT")
128+
endif()
118129
endif()
119130

120131
# ---[ BLAS

cmake/MKLDNN.cmake

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,14 @@ function(Download_MKLDNN)
88
execute_process(COMMAND cat mkldnn.commit
99
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
1010
OUTPUT_VARIABLE MKLDNN_COMMIT)
11-
11+
12+
include(ProcessorCount)
13+
ProcessorCount(NCORE)
14+
if(NOT NCORE EQUAL 0)
15+
set(CTEST_BUILD_FLAGS -j${NCORE})
16+
set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${NCORE})
17+
endif()
18+
1219
ExternalProject_add(MKLDNN_Build
1320
SOURCE_DIR ${MKLDNN_SOURCE_DIR}
1421
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${MKLDNN_INSTALL_DIR} -DMKLROOT=${MKL_ROOT_DIR}
@@ -20,7 +27,7 @@ function(Download_MKLDNN)
2027
BUILD_COMMAND cmake ${MKLDNN_SOURCE_DIR}
2128
#--Install step
2229
INSTALL_DIR ${MKLDNN_INSTALL_DIR}
23-
INSTALL_COMMAND make install
30+
INSTALL_COMMAND make install -j${NCORE}
2431
LOG_CONFIGURE 1
2532
LOG_BUILD 1
2633
LOG_INSTALL 1

examples/LRCN_activity_recognition/train_test_singleFrame_RGB.prototxt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ layer {
1313
mean_value: 103.939
1414
mean_value: 116.779
1515
mean_value: 123.68
16-
flow: false
1716
}
1817
image_data_param {
1918
source: "ucf101_singleFrame_RGB_train_split1.txt"
@@ -38,7 +37,6 @@ layer {
3837
mean_value: 103.939
3938
mean_value: 116.779
4039
mean_value: 123.68
41-
flow: false
4240
}
4341
image_data_param {
4442
source: "ucf101_singleFrame_RGB_test_split1.txt"

examples/pycaffe/tune_engine.py

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
import os
2+
import sys
3+
import copy
4+
import argparse
5+
6+
from caffe.proto import caffe_pb2
7+
import google.protobuf.text_format as txtf
8+
9+
def readFile(filePath):
10+
lines = []
11+
file = open(filePath, 'r')
12+
for line in file.readlines():
13+
lines.append(line)
14+
file.close()
15+
16+
return lines
17+
18+
def writeFile(filePath, lines):
19+
file = open(filePath, 'w+')
20+
file.write(lines)
21+
file.close()
22+
23+
def parseLog(log):
24+
lines = readFile(log)
25+
model_start = False
26+
time_start = False
27+
model_lines = []
28+
time_lines = []
29+
for line in lines:
30+
trim_line = line.strip()
31+
if trim_line.endswith("Initializing net from parameters:"):
32+
model_start = True
33+
continue
34+
if model_start:
35+
if trim_line.find("Creating layer") <> -1:
36+
model_start = False
37+
continue
38+
model_lines.append(line)
39+
40+
if trim_line.endswith("Average time per layer:"):
41+
time_start = True
42+
continue
43+
if time_start:
44+
if trim_line.find("Average Forward pass") <> -1:
45+
time_start = False
46+
break
47+
time_lines.append(line)
48+
49+
model_lines = model_lines[1:]
50+
model_str = ""
51+
for line in model_lines:
52+
model_str = model_str + line
53+
54+
return (model_str, time_lines)
55+
56+
def parseTimeLines(timeLines):
57+
layer_map = {}
58+
for line in timeLines:
59+
trim_line = line.strip()
60+
items = trim_line.split("\t")
61+
layer_items = items[0].split(" ")
62+
layer_name = layer_items[-1]
63+
time_items = items[1].split(" ")
64+
if layer_name not in layer_map.keys():
65+
layer_map[layer_name] = (float)(time_items[1])
66+
else:
67+
layer_map[layer_name] = layer_map[layer_name] + (float)(time_items[1])
68+
69+
return layer_map
70+
71+
def parseModelStr(modelStr):
72+
net = caffe_pb2.NetParameter()
73+
txtf.Merge(modelStr, net)
74+
layer_model_map = {}
75+
global_engine = "CAFFE"
76+
if net.engine != "":
77+
global_engine = net.engine
78+
for index in range(0, len(net.layer)):
79+
engine = global_engine
80+
l = net.layer[index]
81+
if l.engine != "":
82+
engine = l.engine
83+
param_engine = -1
84+
if l.type == "Convolution" or l.type == "Deconvolution":
85+
if l.convolution_param.engine != "":
86+
param_engine = l.convolution_param.engine
87+
elif l.type == "BatchNorm":
88+
if l.batch_norm_param.engine != "":
89+
param_engine = l.batch_norm_param.engine
90+
elif l.type == "Concat":
91+
if l.concat_param.engine != "":
92+
param_engine = l.concat_param.engine
93+
elif l.type == "Eltwise":
94+
if l.eltwise_param.engine != "":
95+
param_engine = l.eltwise_param.engine
96+
elif l.type == "InnerProduct":
97+
if l.inner_product_param.engine != "":
98+
param_engine = l.inner_product_param.engine
99+
elif l.type == "LRN":
100+
if l.lrn_param.engine != "":
101+
param_engine = l.lrn_param.engine
102+
elif l.type == "Pooling":
103+
if l.pooling_param.engine != "":
104+
param_engine = l.pooling_param.engine
105+
elif l.type == "ReLU":
106+
if l.relu_param.engine != "":
107+
param_engine = l.relu_param.engine
108+
109+
if param_engine == 0 or param_engine == 1:
110+
engine = "CAFFE"
111+
elif param_engine == 3:
112+
engine = "MKL2017"
113+
elif param_engine == 4:
114+
engine = "MKLDNN"
115+
layer_model_map[l.name] = (index, engine, l)
116+
117+
return (net, layer_model_map)
118+
119+
def selectOptimalEngine(layers):
120+
optimal_layer = None
121+
min_time = sys.float_info.max
122+
for layer in layers:
123+
if layer[2] < min_time:
124+
min_time = layer[2]
125+
optimal_layer = layer
126+
127+
return optimal_layer
128+
129+
def tuneEngine(logs, model):
130+
if len(logs) <= 1:
131+
print "[ERROR] Please specify two or more log files"
132+
exit(1)
133+
134+
for log in logs:
135+
if not os.path.exists(log):
136+
print "[ERROR] Please specify valid log file:", log
137+
exit(1)
138+
139+
layer_map = {}
140+
net = None
141+
for log in logs:
142+
log_name = os.path.basename(log)
143+
(model_str, time_lines) = parseLog(log)
144+
(net, layer_model_map) = parseModelStr(model_str)
145+
layer_time_map = parseTimeLines(time_lines)
146+
for k, v in layer_model_map.items():
147+
if k not in layer_map.keys():
148+
layer_map[k] = [(v[0], v[1], layer_time_map[k], v[2])]
149+
else:
150+
layer_map_v = layer_map[k]
151+
layer_map_v.append((v[0], v[1], layer_time_map[k], v[2]))
152+
layer_map[k] = layer_map_v
153+
154+
optimal_layer_map = {}
155+
for k, v in layer_map.items():
156+
optimal_layer = selectOptimalEngine(v)
157+
assert(optimal_layer != None)
158+
optimal_layer_map[optimal_layer[0]] = optimal_layer[3]
159+
160+
genModel(net, model, optimal_layer_map)
161+
162+
def genModel(net, model, optimal_layer_map):
163+
net_str = ""
164+
net_str += "name: \"" + net.name + "\"\n"
165+
for index in range(0, len(net.layer)):
166+
net_str += "layer {\n"
167+
l = net.layer[index]
168+
if l.type.endswith("Data"):
169+
net_str += str(l) + "\n}\n"
170+
continue
171+
l = optimal_layer_map[index]
172+
net_str += str(l) + "\n}\n"
173+
with open(model, 'w') as f:
174+
net = caffe_pb2.NetParameter()
175+
txtf.Merge(net_str, net)
176+
f.write(str(net))
177+
print "[INFO] Complete model engine tuning:", model
178+
179+
if __name__ == '__main__':
180+
parser = argparse.ArgumentParser()
181+
182+
parser.add_argument('-l', '--logs', nargs='+', help='require the caffe time logs', required=True)
183+
184+
parser.add_argument('-o', '--output', action='store', dest='output', default="",
185+
help='require the model output')
186+
187+
parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0')
188+
189+
params = parser.parse_args()
190+
tuneEngine(params.logs, params.output)

examples/pycaffe/tune_model.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import os
2+
import datetime
3+
import copy
4+
import argparse
5+
6+
from caffe.proto import caffe_pb2
7+
import google.protobuf.text_format as txtf
8+
import caffe
9+
10+
def isWinogradApplicable(ic, oc, stride, kernel_size):
11+
if ic % 16 != 0:
12+
return False
13+
if oc % 16 != 0:
14+
return False
15+
if stride != 1:
16+
return False
17+
if kernel_size != 3:
18+
return False
19+
20+
return True
21+
22+
def genHybridModel(net, winogradLayers, modelName):
23+
newNet = copy.deepcopy(net)
24+
newNetName = modelName.split(".")[0] + "_hybrid.prototxt"
25+
for layer in winogradLayers:
26+
newNet.layer[layer].convolution_param.conv_algorithm = "winograd"
27+
with open(newNetName, 'w') as f:
28+
f.write(str(newNet))
29+
print "[INFO] Complete model tuning with Winograd:", newNetName
30+
31+
def tuneModelDefinition(model):
32+
net = caffe_pb2.NetParameter()
33+
with open(model) as f:
34+
s = f.read()
35+
txtf.Merge(s, net)
36+
37+
net.name = 'Tuned model of ' + net.name
38+
output_layer_map = {}
39+
for index in range(0, len(net.layer)):
40+
l = net.layer[index]
41+
if l.type == ("Convolution"):
42+
stride = 0
43+
kernel_size = 0
44+
if len(l.convolution_param.stride) == 0:
45+
stride = 1
46+
else:
47+
stride = l.convolution_param.stride[0]
48+
kernel_size = l.convolution_param.kernel_size[0]
49+
ic = 0
50+
if l.bottom[0] in output_layer_map.keys():
51+
ic = output_layer_map[l.bottom[0]][4]
52+
oc = l.convolution_param.num_output
53+
output_layer_map[l.name] = (index, stride, kernel_size, ic, oc, True)
54+
elif l.type == ("InnerProduct"):
55+
oc = l.inner_product_param.num_output
56+
ic = 0
57+
if l.bottom[0] in output_layer_map.keys():
58+
ic = output_layer_map[l.bottom[0]][4]
59+
output_layer_map[l.name] = (index, 0, 0, ic, oc, False)
60+
elif l.type.endswith("Data") or l.type.endswith("Input"):
61+
# TODO: correct the output
62+
# dynamic_net = caffe.Net(model, caffe.TEST)
63+
# for k, v in dynamic_net.blobs.items():
64+
# dynamic_net_map[k] = v.data.shape
65+
ic = oc = 3
66+
output_layer_map[l.name] = (index, 0, 0, ic, oc, False)
67+
else:
68+
ic = 0
69+
if l.bottom[0] in output_layer_map.keys():
70+
ic = output_layer_map[l.bottom[0]][4]
71+
oc = ic
72+
output_layer_map[l.name] = (index, 0, 0, ic, oc, False)
73+
74+
winograd_convolutions = []
75+
for k,v in output_layer_map.items():
76+
if v[5] and isWinogradApplicable(v[3], v[4], v[1], v[2]):
77+
winograd_convolutions.append(v[0])
78+
79+
if len(winograd_convolutions) > 0:
80+
genHybridModel(net, winograd_convolutions, model)
81+
else:
82+
print "[INFO] No need to tune model with Winograd:", model
83+
84+
if __name__ == '__main__':
85+
parser = argparse.ArgumentParser()
86+
87+
parser.add_argument('-m', '--model', action='store', dest='model', default="",
88+
help='require the model definition (prototxt)')
89+
90+
parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0')
91+
92+
params = parser.parse_args()
93+
94+
model = params.model
95+
if not os.path.exists(params.model):
96+
print "[ERROR] Please specify the model definition file with -m"
97+
exit(1)
98+
99+
tuneModelDefinition(model)

include/caffe/data_reader.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class DataReader {
129129

130130
const LayerParameter param_;
131131
BlockingQueue<shared_ptr<QueuePair> > new_queue_pairs_;
132+
bool first_read_;
132133

133134
friend class DataReader;
134135

include/caffe/data_transformer.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,11 @@ class DataTransformer {
396396
bool has_mean_values>
397397
void Transform(const Datum& datum, Dtype* transformed_data,
398398
NormalizedBBox* crop_bbox, RandNumbers& rand_num);
399+
400+
#ifdef USE_OPENCV
401+
void RandomResizeImage(const Datum& datum, Datum *resized_datum);
402+
void RandomResizeImage(const cv::Mat& img, cv::Mat *resized_img);
403+
#endif
399404
};
400405

401406
} // namespace caffe

0 commit comments

Comments
 (0)