summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Zhao2020-02-28 10:51:15 -0600
committerYuan Zhao2020-02-28 10:51:15 -0600
commiteeb4c457c8881a81fbf59a60b2ee070d2450a935 (patch)
treea43389d42eaab757e71707a3658356f2f55ef64d
parent21faf4b36a0ae9ee5b5c6aaf90d067728ff4f78b (diff)
parent05e0f1519e697cc82859651063c490d71a741132 (diff)
downloadtidl-api-eeb4c457c8881a81fbf59a60b2ee070d2450a935.tar.gz
tidl-api-eeb4c457c8881a81fbf59a60b2ee070d2450a935.tar.xz
tidl-api-eeb4c457c8881a81fbf59a60b2ee070d2450a935.zip
Merge branch 'release/v01.05.00'v01.05.00
-rw-r--r--docs/source/changelog.rst6
-rw-r--r--docs/source/conf.py6
-rw-r--r--docs/source/using_api.rst24
-rwxr-xr-xexamples/mcbench/scripts/all_5729.sh9
-rw-r--r--examples/mobilenet_subgraph/subgraph0.cfg7
-rw-r--r--tidl_api/Makefile13
-rw-r--r--tidl_api/inc/configuration.h33
-rw-r--r--tidl_api/make.buildid2
-rw-r--r--tidl_api/src/configuration.cpp65
-rw-r--r--tidl_api/src/configuration_parser.cpp5
-rw-r--r--tidl_api/src/subgraph_runtime.cpp4
-rw-r--r--tidl_api_manifest.html8
12 files changed, 132 insertions, 50 deletions
diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst
index 38910d8..42c4cf1 100644
--- a/docs/source/changelog.rst
+++ b/docs/source/changelog.rst
@@ -2,6 +2,12 @@
2Changelog 2Changelog
3######### 3#########
4 4
51.5.0 [Processor Linux SDK 6.3]
6===============================
7**Changed**
8
9#. Cleaned up subgraph cfg file entries. Added TIDL_SUBGRAPH_DIR env var.
10
51.4.0 [Processor Linux SDK 6.2] 111.4.0 [Processor Linux SDK 6.2]
6=============================== 12===============================
7**Added** 13**Added**
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 203aabf..60de98a 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -53,16 +53,16 @@ master_doc = 'index'
53 53
54# General information about the project. 54# General information about the project.
55project = u'TIDL API User\'s Guide' 55project = u'TIDL API User\'s Guide'
56copyright = u'2018, Texas Instruments Incorporated' 56copyright = u'2018-2019, Texas Instruments Incorporated'
57 57
58# The version info for the project you're documenting, acts as replacement for 58# The version info for the project you're documenting, acts as replacement for
59# |version| and |release|, also used in various other places throughout the 59# |version| and |release|, also used in various other places throughout the
60# built documents. 60# built documents.
61# 61#
62# The short X.Y version. 62# The short X.Y version.
63version = '1.2.x' 63version = '1.5.x'
64# The full version, including alpha/beta/rc tags. 64# The full version, including alpha/beta/rc tags.
65release = '1.2.x' 65release = '1.5.x'
66 66
67# The language for content autogenerated by Sphinx. Refer to documentation 67# The language for content autogenerated by Sphinx. Refer to documentation
68# for a list of supported languages. 68# for a list of supported languages.
diff --git a/docs/source/using_api.rst b/docs/source/using_api.rst
index 80d8a74..d56bd52 100644
--- a/docs/source/using_api.rst
+++ b/docs/source/using_api.rst
@@ -313,3 +313,27 @@ See ``examples/layer_output/main.cpp, ProcessTrace()`` for examples of using the
313 313
314.. _Processor SDK Linux Software Developer's Guide: http://software-dl.ti.com/processor-sdk-linux/esd/docs/latest/linux/index.html 314.. _Processor SDK Linux Software Developer's Guide: http://software-dl.ti.com/processor-sdk-linux/esd/docs/latest/linux/index.html
315.. _Processor SDK Linux Software Developer's Guide (TIDL chapter): http://software-dl.ti.com/processor-sdk-linux/esd/docs/latest/linux/Foundational_Components_TIDL.html 315.. _Processor SDK Linux Software Developer's Guide (TIDL chapter): http://software-dl.ti.com/processor-sdk-linux/esd/docs/latest/linux/Foundational_Components_TIDL.html
316
317Subgraph runtime
318++++++++++++++++
319
320TIDL API subgraph runtime are intended for interfacing with external inference
321frameworks. Subgraph runtime are not intended for direct use in user
322applications.
323
324Subgraph config file
325====================
326
327Subgraph config file are named as "subgraph<number>.cfg", while <number>
328is the subgraph index in the original graph/network. The environment
329variable `TIDL_SUBGRAPH_DIR` speicifies the directory where subgraph config
330files reside. If not specified, the current directory is assumed.
331
332Subgraph config file requires extra parameters to describe data conversion
333at the subgraph boundaries. Please see
334`examples/mobilenet_subgraph/subgraph0.cfg` for an example of minimal
335set of required parameters.
336
337Subgraph runtime API
338====================
339Please see `tidl_api/inc/subgraph_runtime.h` for details.
diff --git a/examples/mcbench/scripts/all_5729.sh b/examples/mcbench/scripts/all_5729.sh
index defec72..0fee8a1 100755
--- a/examples/mcbench/scripts/all_5729.sh
+++ b/examples/mcbench/scripts/all_5729.sh
@@ -7,8 +7,7 @@ export TIDL_NETWORK_HEAP_SIZE_DSP=56623104
7export TIDL_NETWORK_HEAP_SIZE_EVE=67108864 7export TIDL_NETWORK_HEAP_SIZE_EVE=67108864
8export TIDL_NETWORK_HEAP_SIZE_DSP=8388608 8export TIDL_NETWORK_HEAP_SIZE_DSP=8388608
9./mcbench -g 2 -d 1 -e 4 -c ../test/testvecs/config/infer/tidl_config_mobileNet1_lg2.txt -f 50 -i ../test/testvecs/input/preproc_2_224x224_multi.y 9./mcbench -g 2 -d 1 -e 4 -c ../test/testvecs/config/infer/tidl_config_mobileNet1_lg2.txt -f 50 -i ../test/testvecs/input/preproc_2_224x224_multi.y
10./mcbench -g 2 -d 2 -e 4 -c ../test/testvecs/config/infer/tidl_config_mobileNet1_lg2.txt -f 50 -i ../test/testvecs/input/preproc_2_224x224_multi.y 10./mcbench -g 2 -d 1 -e 4 -c ../test/testvecs/config/infer/tidl_config_mobileNet2_lg2.txt -f 50 -i ../test/testvecs/input/preproc_2_224x224_multi.y
11./mcbench -g 2 -d 2 -e 4 -c ../test/testvecs/config/infer/tidl_config_mobileNet2_lg2.txt -f 50 -i ../test/testvecs/input/preproc_2_224x224_multi.y 11./mcbench -g 2 -d 1 -e 4 -c ../test/testvecs/config/infer/tidl_config_inceptionNetv1_lg2.txt -f 50 -i ../test/testvecs/input/preproc_0_224x224_multi.y
12./mcbench -g 2 -d 2 -e 4 -c ../test/testvecs/config/infer/tidl_config_inceptionNetv1_lg2.txt -f 50 -i ../test/testvecs/input/preproc_0_224x224_multi.y 12./mcbench -g 2 -d 1 -e 4 -c ../test/testvecs/config/infer/tidl_config_j11_v2_lg2.txt -f 50 -i ../test/testvecs/input/preproc_0_224x224_multi.y
13./mcbench -g 2 -d 2 -e 4 -c ../test/testvecs/config/infer/tidl_config_j11_v2_lg2.txt -f 50 -i ../test/testvecs/input/preproc_0_224x224_multi.y 13./mcbench -g 2 -d 1 -e 4 -c ../test/testvecs/config/infer/tidl_config_j11_v2_dense_lg2.txt -f 50 -i ../test/testvecs/input/preproc_0_224x224_multi.y
14./mcbench -g 2 -d 2 -e 4 -c ../test/testvecs/config/infer/tidl_config_j11_v2_dense_lg2.txt -f 50 -i ../test/testvecs/input/preproc_0_224x224_multi.y
diff --git a/examples/mobilenet_subgraph/subgraph0.cfg b/examples/mobilenet_subgraph/subgraph0.cfg
index 404c70d..fac8180 100644
--- a/examples/mobilenet_subgraph/subgraph0.cfg
+++ b/examples/mobilenet_subgraph/subgraph0.cfg
@@ -1,12 +1,5 @@
1numFrames = 1
2preProcType = 2
3inData = "../test/testvecs/input/preproc_2_224x224.y"
4outData = "./stats_tool_out.bin"
5netBinFile = "../test/testvecs/config/tidl_models/tidl_net_mobilenet_1_224.bin" 1netBinFile = "../test/testvecs/config/tidl_models/tidl_net_mobilenet_1_224.bin"
6paramsBinFile = "../test/testvecs/config/tidl_models/tidl_param_mobilenet_1_224.bin" 2paramsBinFile = "../test/testvecs/config/tidl_models/tidl_param_mobilenet_1_224.bin"
7inWidth = 224
8inHeight = 224
9inNumChannels = 3
10# The following information should be space separated list, 3# The following information should be space separated list,
11# corresponding to vector of inputs and vector of outputs 4# corresponding to vector of inputs and vector of outputs
12# Quant_value = float_value * scaleF2Q 5# Quant_value = float_value * scaleF2Q
diff --git a/tidl_api/Makefile b/tidl_api/Makefile
index a04e604..3a5ea69 100644
--- a/tidl_api/Makefile
+++ b/tidl_api/Makefile
@@ -37,6 +37,8 @@ all: $(LIB_NAME) $(LIB_IMGUTIL_NAME) $(PY_LIB_NAME) \
37include make.inc 37include make.inc
38include make.buildid 38include make.buildid
39 39
40SO_VER=$(MAJOR_VER).$(MINOR_VER).$(PATCH_VER)
41
40RM = rm 42RM = rm
41AR = ar 43AR = ar
42 44
@@ -95,7 +97,10 @@ $(LIB_NAME): $(HOST_OBJ_FILES)
95 $(AR) cr $@ $(HOST_OBJ_FILES) 97 $(AR) cr $@ $(HOST_OBJ_FILES)
96 98
97$(SHARED_LIB_NAME): $(HOST_OBJ_FILES) 99$(SHARED_LIB_NAME): $(HOST_OBJ_FILES)
98 $(CXX) $(CXXFLAGS) -Wl,-Bsymbolic -shared -lOpenCL $(HOST_OBJ_FILES) -o $@ 100 $(CXX) $(CXXFLAGS) -Wl,-Bsymbolic -shared -Wl,-soname,$@.$(MAJOR_VER) \
101 -lOpenCL $(HOST_OBJ_FILES) -o $@.$(SO_VER)
102 ln -sf $@.$(SO_VER) $@.$(MAJOR_VER)
103 ln -sf $@.$(MAJOR_VER) $@
99 104
100$(PY_LIB_NAME): $(HOST_OBJ_PYBIND_FILES) $(LIB_NAME) 105$(PY_LIB_NAME): $(HOST_OBJ_PYBIND_FILES) $(LIB_NAME)
101 $(CXX) $(CXXFLAGS) -Wl,-Bsymbolic -shared -lOpenCL -locl_util $^ -o $@ 106 $(CXX) $(CXXFLAGS) -Wl,-Bsymbolic -shared -lOpenCL -locl_util $^ -o $@
@@ -104,10 +109,14 @@ $(LIB_IMGUTIL_NAME): $(HOST_OBJ_IMGUTIL_FILES)
104 $(AR) cr $@ $(HOST_OBJ_IMGUTIL_FILES) 109 $(AR) cr $@ $(HOST_OBJ_IMGUTIL_FILES)
105 110
106$(SHARED_LIB_IMGUTIL_NAME): $(HOST_OBJ_IMGUTIL_FILES) 111$(SHARED_LIB_IMGUTIL_NAME): $(HOST_OBJ_IMGUTIL_FILES)
107 $(CXX) $(CXXFLAGS) -Wl,-Bsymbolic -shared $(HOST_OBJ_IMGUTIL_FILES) -o $@ 112 $(CXX) $(CXXFLAGS) -Wl,-Bsymbolic -shared -Wl,-soname,$@.$(MAJOR_VER) \
113 $(HOST_OBJ_IMGUTIL_FILES) -o $@.$(SO_VER)
114 ln -sf $@.$(SO_VER) $@.$(MAJOR_VER)
115 ln -sf $@.$(MAJOR_VER) $@
108 116
109clean:: 117clean::
110 $(RM) -f $(LIB_NAME) $(PY_LIB_NAME) 118 $(RM) -f $(LIB_NAME) $(PY_LIB_NAME)
111 $(RM) -f $(LIB_IMGUTIL_NAME) 119 $(RM) -f $(LIB_IMGUTIL_NAME)
120 $(RM) -f $(SHARED_LIB_NAME)* $(SHARED_LIB_IMGUTIL_NAME)*
112 $(RM) -rf obj 121 $(RM) -rf obj
113 122
diff --git a/tidl_api/inc/configuration.h b/tidl_api/inc/configuration.h
index c76ba7f..5de89f2 100644
--- a/tidl_api/inc/configuration.h
+++ b/tidl_api/inc/configuration.h
@@ -146,30 +146,43 @@ class Configuration
146 //! Margin added to the average in percentage. 146 //! Margin added to the average in percentage.
147 int quantMargin; 147 int quantMargin;
148 148
149 //! subgraph data conversion type at subgraph inputs 149 //! Subgraph: config file for subgraph runtime, default to false
150 //! 0: float <-> Q, 1: float <-> float, 2: Q <-> Q 150 //! (intended for interfacing with external inference frameworks,
151 //! not intended for direct use in user applications)
152 //! The following {in,out}* parameters describe the tensor(s) value/layout
153 //! conversion at the subgraph boundaries for subgraph runtime.
154 //! Each parameter (vector) can be a space separated list, corresponding to
155 //! multiple input tensors and multiple output tensors, if applicable.
156 bool isSubgraphCfg;
157
158 //! subgraph: data value conversion type at subgraph input boundary,
159 //! between external tensors and TIDL tensors
160 //! 0: float -> Q, 1: float -> float, 2: Q -> Q
151 std::vector<int> inConvType; 161 std::vector<int> inConvType;
152 162
153 //! subgraph is signed data at subgraph inputs 163 //! subgraph: are external input tensors signed data
154 std::vector<int> inIsSigned; 164 std::vector<int> inIsSigned;
155 165
156 //! subgraph scaleF2Q factor at subgraph inputs 166 //! subgraph: scaleF2Q factor for converting values of input tensors
167 //! saturation(float_value * inScaleF2Q) = quantized_value
157 std::vector<float> inScaleF2Q; 168 std::vector<float> inScaleF2Q;
158 169
159 //! subgraph is external tensor NCHW layout at subgraph inputs 170 //! subgraph: are external input tensors in NCHW layout
160 std::vector<int> inIsNCHW; 171 std::vector<int> inIsNCHW;
161 172
162 //! subgraph data conversion type at subgraph outputs 173 //! subgraph: data value conversion type at subgraph output boundary,
163 //! 0: float <-> Q, 1: float <-> float, 2: Q <-> Q 174 //! between TIDL tensors and external tensors
175 //! 0: Q -> float, 1: float -> float, 2: Q -> Q
164 std::vector<int> outConvType; 176 std::vector<int> outConvType;
165 177
166 //! subgraph is signed data at subgraph outputs 178 //! subgraph: are external output tensors signed data
167 std::vector<int> outIsSigned; 179 std::vector<int> outIsSigned;
168 180
169 //! subgraph scaleF2Q factor at subgraph outputs 181 //! subgraph: scaleF2Q factor for converting values of output tensors
182 //! quantized_value / outScaleF2Q = float_value
170 std::vector<float> outScaleF2Q; 183 std::vector<float> outScaleF2Q;
171 184
172 //! subgraph is external tensor NCHW layout at subgraph outputs 185 //! subgraph: are external output tensors in NCHW layout
173 std::vector<int> outIsNCHW; 186 std::vector<int> outIsNCHW;
174 187
175 //! Default constructor. 188 //! Default constructor.
diff --git a/tidl_api/make.buildid b/tidl_api/make.buildid
index c2efbc5..9d8ec36 100644
--- a/tidl_api/make.buildid
+++ b/tidl_api/make.buildid
@@ -25,7 +25,7 @@
25# THE POSSIBILITY OF SUCH DAMAGE. 25# THE POSSIBILITY OF SUCH DAMAGE.
26 26
27MAJOR_VER=1 27MAJOR_VER=1
28MINOR_VER=4 28MINOR_VER=5
29PATCH_VER=0 29PATCH_VER=0
30 30
31ifeq ($(shell git rev-parse --short HEAD 2>&1 1>/dev/null; echo $$?),0) 31ifeq ($(shell git rev-parse --short HEAD 2>&1 1>/dev/null; echo $$?),0)
diff --git a/tidl_api/src/configuration.cpp b/tidl_api/src/configuration.cpp
index c67b22c..3ec242e 100644
--- a/tidl_api/src/configuration.cpp
+++ b/tidl_api/src/configuration.cpp
@@ -46,7 +46,16 @@ Configuration::Configuration(): numFrames(0), inHeight(0), inWidth(0),
46 showHeapStats(false), 46 showHeapStats(false),
47 quantHistoryParam1(20), 47 quantHistoryParam1(20),
48 quantHistoryParam2(5), 48 quantHistoryParam2(5),
49 quantMargin(0) 49 quantMargin(0),
50 isSubgraphCfg(false),
51 inConvType(),
52 inIsSigned(),
53 inScaleF2Q(),
54 inIsNCHW(),
55 outConvType(),
56 outIsSigned(),
57 outScaleF2Q(),
58 outIsNCHW()
50{ 59{
51} 60}
52 61
@@ -70,35 +79,57 @@ void Configuration::Print(std::ostream &os) const
70bool Configuration::Validate() const 79bool Configuration::Validate() const
71{ 80{
72 int errors = 0; 81 int errors = 0;
82 struct stat buffer;
73 83
74 if (inHeight == 0 || inWidth == 0) 84 if (! isSubgraphCfg)
75 { 85 {
76 std::cerr << "inHeight, inWidth must be > 0" << std::endl; 86 if (inHeight == 0 || inWidth == 0)
77 errors++; 87 {
78 } 88 std::cerr << "cfg: inHeight, inWidth must be > 0" << std::endl;
89 errors++;
90 }
79 91
80 if (inNumChannels < 1) 92 if (inNumChannels < 1)
93 {
94 std::cerr << "cfg: inNumChannels must be > 1" << std::endl;
95 errors++;
96 }
97
98 if (!inData.empty() && stat(inData.c_str(), &buffer) != 0)
99 {
100 std::cerr << "cfg: inData not found: " << inData << std::endl;
101 errors++;
102 }
103 }
104 else
81 { 105 {
82 std::cerr << "inNumChannels must be > 1" << std::endl; 106 if (inConvType.size() == 0 || inIsSigned.size() == 0 ||
83 errors++; 107 inScaleF2Q.size() == 0 || inIsNCHW.size() == 0 ||
108 outConvType.size() == 0 || outIsSigned.size() == 0 ||
109 outScaleF2Q.size() == 0 || outIsNCHW.size() == 0)
110 {
111 std::cerr << "cfg: subgraph data info not found" << std::endl;
112 errors++;
113 }
114
115 if (inConvType.size() != inIsNCHW.size() ||
116 outConvType.size() != outIsNCHW.size())
117 {
118 std::cerr << "cfg: Mismatching subgraph data info" << std::endl;
119 errors++;
120 }
84 } 121 }
85 122
86 struct stat buffer;
87 if (stat(netBinFile.c_str(), &buffer) != 0) 123 if (stat(netBinFile.c_str(), &buffer) != 0)
88 { 124 {
89 std::cerr << "netBinFile not found: " << netBinFile << std::endl; 125 std::cerr << "cfg: netBinFile not found: " << netBinFile << std::endl;
90 errors++; 126 errors++;
91 } 127 }
92 128
93 if (stat(paramsBinFile.c_str(), &buffer) != 0) 129 if (stat(paramsBinFile.c_str(), &buffer) != 0)
94 { 130 {
95 std::cerr << "paramsBinFile not found: " << paramsBinFile << std::endl; 131 std::cerr << "cfg: paramsBinFile not found: " << paramsBinFile
96 errors++; 132 << std::endl;
97 }
98
99 if (!inData.empty() && stat(inData.c_str(), &buffer) != 0)
100 {
101 std::cerr << "inData not found: " << inData << std::endl;
102 errors++; 133 errors++;
103 } 134 }
104 135
diff --git a/tidl_api/src/configuration_parser.cpp b/tidl_api/src/configuration_parser.cpp
index 3ad0d2c..e0db7bb 100644
--- a/tidl_api/src/configuration_parser.cpp
+++ b/tidl_api/src/configuration_parser.cpp
@@ -118,7 +118,10 @@ bool Configuration::ReadFromFile(const std::string &file_name)
118 std::ifstream IFS(file_name); 118 std::ifstream IFS(file_name);
119 119
120 if (!IFS.good()) 120 if (!IFS.good())
121 {
122 std::cerr << "cfg: cannot read file: " << file_name << std::endl;
121 return false; 123 return false;
124 }
122 125
123 typedef ConfigParser<std::string::const_iterator> ConfigParser; 126 typedef ConfigParser<std::string::const_iterator> ConfigParser;
124 127
@@ -141,7 +144,7 @@ bool Configuration::ReadFromFile(const std::string &file_name)
141 144
142 if (!result) 145 if (!result)
143 { 146 {
144 std::cout << "Parsing failed on line " << line_num 147 std::cout << "cfg: parsing failed on line " << line_num
145 << ": " << str << std::endl; 148 << ": " << str << std::endl;
146 break; 149 break;
147 } 150 }
diff --git a/tidl_api/src/subgraph_runtime.cpp b/tidl_api/src/subgraph_runtime.cpp
index 9d068b2..5ac6e97 100644
--- a/tidl_api/src/subgraph_runtime.cpp
+++ b/tidl_api/src/subgraph_runtime.cpp
@@ -250,6 +250,10 @@ void ResM::InitSubgraph(uint32_t subgraph_id)
250 250
251 // Read config file 251 // Read config file
252 std::string cfg_file = "subgraph" + std::to_string(subgraph_id) + ".cfg"; 252 std::string cfg_file = "subgraph" + std::to_string(subgraph_id) + ".cfg";
253 char *subgraph_dir = getenv("TIDL_SUBGRAPH_DIR");
254 if (subgraph_dir != nullptr)
255 cfg_file = std::string(subgraph_dir) + "/" + cfg_file;
256 cs_m[subgraph_id].isSubgraphCfg = true;
253 bool status = cs_m[subgraph_id].ReadFromFile(cfg_file); 257 bool status = cs_m[subgraph_id].ReadFromFile(cfg_file);
254 assert(status); 258 assert(status);
255 259
diff --git a/tidl_api_manifest.html b/tidl_api_manifest.html
index e4a5577..57d4f89 100644
--- a/tidl_api_manifest.html
+++ b/tidl_api_manifest.html
@@ -197,7 +197,7 @@ Publicly Available
197 TIDL API 197 TIDL API
198 </td> 198 </td>
199 <td id="version" name="version" rowspan="2"> 199 <td id="version" name="version" rowspan="2">
200 1.3.x 200 1.5.x
201 </td> 201 </td>
202 <td id="license" name="license" rowspan="2"> 202 <td id="license" name="license" rowspan="2">
203 BSD-3-Clause 203 BSD-3-Clause
@@ -226,7 +226,7 @@ Publicly Available
226 TIDL examples 226 TIDL examples
227 </td> 227 </td>
228 <td id="version" name="version" rowspan="2"> 228 <td id="version" name="version" rowspan="2">
229 1.3.x 229 1.5.x
230 </td> 230 </td>
231 <td id="license" name="license" rowspan="2"> 231 <td id="license" name="license" rowspan="2">
232 BSD-3-Clause 232 BSD-3-Clause
@@ -255,7 +255,7 @@ Publicly Available
255 TIDL viewer 255 TIDL viewer
256 </td> 256 </td>
257 <td id="version" name="version" rowspan="2"> 257 <td id="version" name="version" rowspan="2">
258 1.3.x 258 1.5.x
259 </td> 259 </td>
260 <td id="license" name="license" rowspan="2"> 260 <td id="license" name="license" rowspan="2">
261 BSD-3-Clause 261 BSD-3-Clause
@@ -471,4 +471,4 @@ Publicly Available
471 with 100,000+ analog ICs and embedded processors, along with software, tools 471 with 100,000+ analog ICs and embedded processors, along with software, tools
472 and the industry's largest sales/support staff.</p> 472 and the industry's largest sales/support staff.</p>
473</footer> 473</footer>
474</body></html> \ No newline at end of file 474</body></html>