提交 77a5c336 编写于 作者: J Jacek Czaja 提交者: Tao Luo

[MKL-DNN] Document on MKL-DNN objects Caching (#1532)

上级 9e4845ad
# Design Doc: MKL-DNN Data Caching
Fluid MKL-DNN integration is having caching mechanism to store MKL-DNN objects. Purpose of storing MKL-DNN objects is:
* Transfer of MKL-DNN objects from Forward ops to Grad ops.
* Store once created MKL-DNN objects in order To avoid MKL-DNN recreation
### 1. General architecture
Basic idea is that MKL-DNN cache is hash map where key name is pointing to MKL-DNN object stored in mentioned hash map.
In more detail MKL-DNN Cache is stored inside MKL-DNN Device Context and it consists of three level of unordered maps based structure. Picture below outlines mentioned architecture:
![](images/cache.svg)
MKL-DNN cache is to work in both single-threaded and multi-threaded execution scenarios (both inference and training) as well as in a situation when memory constraints are applied. To address memory constraint problem, clear cache mode was introduced.
To make MKL-DNN cache working with multi-threading scenarios:
* Top level cache separates entries per session
* reading and modifying operations on MKL-DNN cache are ensured to be thread safe
* cache key contains Thread ID (when applicable)
The design of MKL-DNN cache is to support dynamic shapes scenario (BERT model for example). Since MKLDNN primitives are sensitive to src/dst shape, if new input shape comes, new primitive needs to be created. That means there will be many primitives cached and MKL-DNN cache would consume lots of memory. By introducing second level cache, we can consider these kind of primitive as a group, once reach memory limitation, we can clear a whole group instead of just one primitive, and release more memory.
Performance-wise it is better to clear group of primitives at once rather than to erase one primitive based on FIFO. More over when searching a cache it is also more efficient to have grouped primitives via input shape , so
we referring to specific primitive we consider only primitives in a group not all registered MKL-DNN cached objects.
Currently model's input shape that is a key for second level cache is not related to input shape which is part of key in first level cache.
##### a. Operational modes of MKL-DNN cache
Cache default mode is normal operating mode of MKL-DNN cache, suitable for single and multi-threaded execution e.g. Thread ID is part of cache key name that is used for referring cached objects.
Cache clearing mode is a special operation mode designed for single threaded usage e.g. (Thread ID is not part of cache key). In this mode when set capacity of cache is to be exceeded (by adding next entry) then the registered entries corresponding to oldest input shape used by PaddlePaddle in given session , are erased (Refer to _section b._ for details on erasing cache entries based on input shape). Input shape is registered as a key for second level cache in _AnalysisPredictor::MkldnnPreSet()_.
##### b. Adding object to MKL-DNN cache
Picture | Description
---------------|---------------------------------------------------
![](images/set_blob.svg) | Updating an object to be stored by given key (name) is done via <br/>_SetBlob_ method. As mentioned earlier MKL-DNN cache is a <br/>three level based architecture(session, input shape and name), <br/>hence we start by getting current session ID and right after that<br/> critical section is set to make sure no two threads are updating<br/> MKL-DNN cache at the same time. Having session ID we check if <br/>there exists cache for given session ID (third level cache). If <br/>answer is negative then new cache object is created. Inside cache <br/>object corresponding to running session, a check if currently used<br/> *input shape* is having its own cache object (second level cache).<br/>In a situation that no cache object for currently used object <br/>exists, then corresponding cache object has to be created. If <br/>MKL-DNN cache is operating in cache clear mode, then when number<br/>of cached objects (second level cache) within currently active <br/>session, exceeds set capacity then the cache entries for the oldest<br/>input shape are removed e.g. one cached object (second level cache)<br/>corresponding to oldest input shape ,that contains number of first<br/>level cache objects , are erased and then cache object for current<br/>input shape is created. Finally when second level cache object for<br/>given input shape was acquired, then we look for cached object<br/>pointed by hash key (name) inside of it (first level cache). If<br/>requesting object does not exist then it is created and if it does exist then given **data** is assigned as a cached object pointed by **name**.
##### c. Getting object from MKL-DNN cache
Picture | Description
---------------|---------------------------------------------------
![](images/get_blob.svg) | Getting an cached objected (given by key (name) is done via <br/>_GetBlob_ method. General idea e.g. traversing through three <br/>level cache is the same as in _SetBlob_ it is just in case of when cached object (of any cache level) does not exist then null object is returned.
### 2. Clearing MKL-DNN cache
MKL-DNN cache clearing is a solution created to address situation when memory consumed by cache outgrown physically available resources on given instance (Virtual Machine running PaddlePaddle).
MKL-DNN Device context provide a method for erasing cache entries eg. _MKLDNNDeviceContext::ResetBlobMap()_. Currently _ResetBlobMap()_ is used in two situations:
* Inference of integer based MKL-DNN models
* Releasing Executor object.
* Cache clear mode
##### a. Inference of integer based MKL-DNN models
Execution of Int8 MKL-DNN models consists of two stages:
* Warm-up up run
* Int8 inference execution
At warm-up stage FP32 inference is performed and range of signal and weights is gathered for MKL-DNN kernels that are having int8 implementation. Based on recorded ranges , scale parameters are determined to be passed to MKL-DNN
int8 primitives. This stage is executed by FP32 kernels and once Int8 inference execution starts we no longer need to have cached FP32 MKL-DNN primitives. This is the reason why clearing of cache is called after warm-up run stage.
##### b. Releasing Executor object
Additionally erasing MKL-DNN cache is performed when Executor object is to be destroyed. Here clearing procedure was introduced to enforce having empty MKL-DNN cache when starting to execute MKL-DNN unit tests.
To be more precise MKL-DNN unit tests file like *test_conv2d_mkldnn_op.py* are containing number of testing scenarios. Without clearing the MKL-DNN cache all of those tests are sharing cached primitives. This is totally not needed
and made an impact on shape of hashing key, which was modified (extended) to make sure cached primitive is not reused for a situation when it should be recreated. In other words unit tests are sharing input and output
names of Tensors which require that hash key is equipped with attributes data of given MKL-DNN primitive to avoid false reusing of MKL-DNN primitives. Hence in order not too complicate hashing key Clearing of cache was
introduced when Executor object is destroyed, that way testing scenarios are isolated from each other e.g. Each scenario is executed with cleared MKL-DNN cache.
##### c. Cache clearing mode
Another situation is when clearing of cache does happen is cache clearing mode: *platform::kMKLDNNSessionID_CacheClearing*. At that mode when new Entry to be added to cache then size of cache is compared with given capacity and once
no space for next objects is in a cache , then MKL-DNN cache is partially cleared. By default cache is NOT working in clearing mode e.g. cache will store all objects it was given. To enable MKL-DNN cache clearing mode one needs to
set capacity of MKL-DNN cache with *SetMkldnnCacheCapacity* (by default capacity is set to 0, meaning no clearing depending on size of cache, any non-negative value is allowed and its meaning is: size of second level cache e.g. number of different input shapes cached groups that can be cached).
Cache clearing mode is to use in single-threaded scenario where available memory resources are limited. In particular it is to be used when executed model accept inputs of various shapes (NLP models).
### 3. Transfer of MKL-DNN objects & Tensors from Forward ops to Grad ops.
Best performance of MKL-DNN kernels is achieved when efficient data arrangement (memory layout) is used as a holder for input/output memory objects and when
number of conversions (reorders) among memory objects is limited to minimum (Not much time is wasted on rearranging data).
Choosing optimal memory layout is done by allowing MKL-DNN computationally heavy primitives (convolution, Inner Product) to choose best memory arrangement based on requested size of data, attributes of algorithm to be executed and architecture of platform. To help limit number of conversions (reorders), information on chosen memory layout and chosen MKL-DNN implementation, is shared among Forward and backward (grad) kernels of given operator instance. In particular forward MKL-DNN kernel decides which MKL-DNN implementation to use and then its decision (in a form of MKL-DNN primitive descriptor) is send to backward MKL-DNN operator. Transfer of MKL-DNN primitive descriptor from
Forward to backward kernel is done via Caching mechanism.
Also MKL-DNN caching mechanism is used for transferring whole MKL-DNN memory allocations when there is no Tensor connecting Forward and Backward kernels available to be used for that purpose. An example could be a workspace MKL-DNN memory object in pooling (Max pooling) MKL-DNN kernel which transfers indices of maximal values (inside each pooling window) to the backward kernel where those indices are utilized for fast backward pooling computation.
##### Note on multi threading execution scenario
PaddlePaddle's program(models) can be executed by single thread as well as multiple threads. Graph's operators can be executed by different threads . In particular forward kernel of given operator may be executed by different thread
than backward kernel of the same instance of operator. In that situation hashing keys used for transferring MKL-DNN primitive descriptors cannot contain Thread ID specific values as key has to be shared among forward and backward kernel. Hence primitive descriptors (to be transfered to backward kernel) are using hashing key that does not contain any thread ID based value. As a result thread safety mechanics (critical section etc.) was employed to
ensure MKL-DNN cache consistency.
### 4. Store once created MKL-DNN objects in order To avoid MKL-DNN recreation
While MKL-DNN computational algorithms are fast to be executed, preparing to execution e.g. Creation of computational primitives and its primitive descriptors takes significant time (From 2% up to 40% for latency mode inference, depends on Platform instruction sets and MKL-DNN version). We can save some time on recreation
of computational MKL-DNN primitives and its primitive descriptors, by storing once created MKL-DNN objects in a cache and refer to them in subsequent iterations when needed.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
-->
<!-- Title: Q Pages: 1 -->
<svg width="1032pt" height="178pt"
viewBox="0.00 0.00 1032.00 178.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 174)">
<title>Q</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-174 1028,-174 1028,4 -4,4"/>
<g id="clust1" class="cluster"><title>cluster_bm</title>
<polygon fill="none" stroke="black" points="8,-8 8,-162 1016,-162 1016,-8 8,-8"/>
<text text-anchor="middle" x="512" y="-146.8" font-family="Times,serif" font-size="14.00">BlobMap</text>
</g>
<g id="clust2" class="cluster"><title>cluster_sm2</title>
<polygon fill="none" stroke="black" points="840,-16 840,-131 1008,-131 1008,-16 840,-16"/>
<text text-anchor="middle" x="924" y="-115.8" font-family="Times,serif" font-size="14.00">ShapeMap of Session ID=1</text>
</g>
<g id="clust3" class="cluster"><title>cluster_km</title>
<polygon fill="none" stroke="black" points="860,-24 860,-100 988,-100 988,-24 860,-24"/>
<text text-anchor="middle" x="924" y="-84.8" font-family="Times,serif" font-size="14.00">KeyMap of X shape</text>
</g>
<g id="clust4" class="cluster"><title>cluster_sm</title>
<polygon fill="none" stroke="black" points="16,-16 16,-131 832,-131 832,-16 16,-16"/>
<text text-anchor="middle" x="424" y="-115.8" font-family="Times,serif" font-size="14.00">ShapeMap of Session ID=0</text>
</g>
<g id="clust5" class="cluster"><title>cluster_km</title>
<polygon fill="none" stroke="black" points="428,-24 428,-100 824,-100 824,-24 428,-24"/>
<text text-anchor="middle" x="626" y="-84.8" font-family="Times,serif" font-size="14.00">KeyMap of X shape</text>
</g>
<g id="clust6" class="cluster"><title>cluster_km2</title>
<polygon fill="none" stroke="black" points="24,-24 24,-100 420,-100 420,-24 24,-24"/>
<text text-anchor="middle" x="222" y="-84.8" font-family="Times,serif" font-size="14.00">KeyMap of Y shape</text>
</g>
<!-- G -->
<g id="node1" class="node"><title>G</title>
<polygon fill="none" stroke="black" points="897,-32.5 897,-68.5 951,-68.5 951,-32.5 897,-32.5"/>
<text text-anchor="middle" x="924" y="-46.8" font-family="Times,serif" font-size="14.00">...</text>
</g>
<!-- C -->
<g id="node2" class="node"><title>C</title>
<polygon fill="none" stroke="black" points="762,-32.5 762,-68.5 816,-68.5 816,-32.5 762,-32.5"/>
<text text-anchor="middle" x="789" y="-46.8" font-family="Times,serif" font-size="14.00">...</text>
</g>
<!-- B -->
<g id="node3" class="node"><title>B</title>
<polygon fill="none" stroke="black" points="592,-32.5 592,-68.5 744,-68.5 744,-32.5 592,-32.5"/>
<text text-anchor="middle" x="668" y="-46.8" font-family="Times,serif" font-size="14.00">second object of ShapeX</text>
</g>
<!-- A -->
<g id="node4" class="node"><title>A</title>
<polygon fill="none" stroke="black" points="436.5,-32.5 436.5,-68.5 573.5,-68.5 573.5,-32.5 436.5,-32.5"/>
<text text-anchor="middle" x="505" y="-46.8" font-family="Times,serif" font-size="14.00">first object of ShapeX</text>
</g>
<!-- F -->
<g id="node5" class="node"><title>F</title>
<polygon fill="none" stroke="black" points="358,-32.5 358,-68.5 412,-68.5 412,-32.5 358,-32.5"/>
<text text-anchor="middle" x="385" y="-46.8" font-family="Times,serif" font-size="14.00">...</text>
</g>
<!-- E -->
<g id="node6" class="node"><title>E</title>
<polygon fill="none" stroke="black" points="188,-32.5 188,-68.5 340,-68.5 340,-32.5 188,-32.5"/>
<text text-anchor="middle" x="264" y="-46.8" font-family="Times,serif" font-size="14.00">second object of ShapeY</text>
</g>
<!-- D -->
<g id="node7" class="node"><title>D</title>
<polygon fill="none" stroke="black" points="32.5,-32.5 32.5,-68.5 169.5,-68.5 169.5,-32.5 32.5,-32.5"/>
<text text-anchor="middle" x="101" y="-46.8" font-family="Times,serif" font-size="14.00">first object of ShapeY</text>
</g>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
-->
<!-- Title: G Pages: 1 -->
<svg width="430pt" height="662pt"
viewBox="0.00 0.00 430.00 662.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 658)">
<title>G</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-658 426,-658 426,4 -4,4"/>
<g id="clust1" class="cluster"><title>cluster_A</title>
<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-577 414,-577 414,-8 8,-8"/>
<text text-anchor="middle" x="364.5" y="-561.8" font-family="Times,serif" font-size="14.00">Critical section</text>
</g>
<!-- A0 -->
<g id="node1" class="node"><title>A0</title>
<ellipse fill="none" stroke="black" cx="269" cy="-636" rx="63.0888" ry="18"/>
<text text-anchor="middle" x="269" y="-632.3" font-family="Times,serif" font-size="14.00">Get session ID</text>
</g>
<!-- A1 -->
<g id="node2" class="node"><title>A1</title>
<polygon fill="none" stroke="black" points="269,-546 166.947,-528 269,-510 371.053,-528 269,-546"/>
<text text-anchor="middle" x="269" y="-524.3" font-family="Times,serif" font-size="14.00">cache[ID] exists?</text>
</g>
<!-- A0&#45;&gt;A1 -->
<g id="edge1" class="edge"><title>A0&#45;&gt;A1</title>
<path fill="none" stroke="black" d="M269,-617.969C269,-601.378 269,-575.883 269,-556.431"/>
<polygon fill="black" stroke="black" points="272.5,-556.341 269,-546.341 265.5,-556.341 272.5,-556.341"/>
<text text-anchor="middle" x="276.5" y="-588.8" font-family="Times,serif" font-size="14.00">ID</text>
</g>
<!-- A3 -->
<g id="node3" class="node"><title>A3</title>
<ellipse fill="none" stroke="black" cx="247" cy="-441" rx="61.1893" ry="18"/>
<text text-anchor="middle" x="247" y="-437.3" font-family="Times,serif" font-size="14.00">Get cache[ID]</text>
</g>
<!-- A1&#45;&gt;A3 -->
<g id="edge3" class="edge"><title>A1&#45;&gt;A3</title>
<path fill="none" stroke="black" d="M264.758,-510.611C261.713,-498.848 257.541,-482.727 254.006,-469.067"/>
<polygon fill="black" stroke="black" points="257.349,-468.018 251.455,-459.214 250.573,-469.772 257.349,-468.018"/>
<text text-anchor="middle" x="268.5" y="-480.8" font-family="Times,serif" font-size="14.00">yes</text>
</g>
<!-- B -->
<g id="node6" class="node"><title>B</title>
<ellipse fill="none" stroke="black" cx="335" cy="-107" rx="71.4873" ry="18"/>
<text text-anchor="middle" x="335" y="-103.3" font-family="Times,serif" font-size="14.00">return null object</text>
</g>
<!-- A1&#45;&gt;B -->
<g id="edge2" class="edge"><title>A1&#45;&gt;B</title>
<path fill="none" stroke="black" d="M286.156,-512.705C312.647,-489.397 362.485,-440.322 382,-386 413.556,-298.162 398.501,-267.679 381,-176 378.101,-160.814 378.128,-156.151 370,-143 367.597,-139.112 364.682,-135.329 361.571,-131.775"/>
<polygon fill="black" stroke="black" points="363.997,-129.246 354.571,-124.408 358.922,-134.068 363.997,-129.246"/>
<text text-anchor="middle" x="406" y="-320.8" font-family="Times,serif" font-size="14.00">no</text>
</g>
<!-- A4 -->
<g id="node4" class="node"><title>A4</title>
<polygon fill="none" stroke="black" points="234,-386 95.4142,-368 234,-350 372.586,-368 234,-386"/>
<text text-anchor="middle" x="234" y="-364.3" font-family="Times,serif" font-size="14.00">cache[ID][shape] exists?</text>
</g>
<!-- A3&#45;&gt;A4 -->
<g id="edge4" class="edge"><title>A3&#45;&gt;A4</title>
<path fill="none" stroke="black" d="M243.853,-422.813C242.384,-414.789 240.6,-405.047 238.956,-396.069"/>
<polygon fill="black" stroke="black" points="242.362,-395.235 237.118,-386.029 235.476,-396.496 242.362,-395.235"/>
</g>
<!-- A5 -->
<g id="node5" class="node"><title>A5</title>
<ellipse fill="none" stroke="black" cx="207" cy="-281" rx="87.1846" ry="18"/>
<text text-anchor="middle" x="207" y="-277.3" font-family="Times,serif" font-size="14.00">Get cache[ID][shape]</text>
</g>
<!-- A4&#45;&gt;A5 -->
<g id="edge6" class="edge"><title>A4&#45;&gt;A5</title>
<path fill="none" stroke="black" d="M228.794,-350.611C225.057,-338.848 219.937,-322.727 215.598,-309.067"/>
<polygon fill="black" stroke="black" points="218.831,-307.685 212.468,-299.214 212.16,-309.804 218.831,-307.685"/>
<text text-anchor="middle" x="231.5" y="-320.8" font-family="Times,serif" font-size="14.00">yes</text>
</g>
<!-- A4&#45;&gt;B -->
<g id="edge5" class="edge"><title>A4&#45;&gt;B</title>
<path fill="none" stroke="black" d="M254.988,-352.654C288.373,-328.353 352.136,-275.49 375,-212 384.75,-184.926 369.664,-154.202 355.313,-133.211"/>
<polygon fill="black" stroke="black" points="357.971,-130.912 349.282,-124.849 352.293,-135.007 357.971,-130.912"/>
<text text-anchor="middle" x="373" y="-233.8" font-family="Times,serif" font-size="14.00">no</text>
</g>
<!-- B1 -->
<g id="node7" class="node"><title>B1</title>
<polygon fill="none" stroke="black" points="191,-212 16.2201,-194 191,-176 365.78,-194 191,-212"/>
<text text-anchor="middle" x="191" y="-190.3" font-family="Times,serif" font-size="14.00">cache[ID][shape][name] exists?</text>
</g>
<!-- A5&#45;&gt;B1 -->
<g id="edge7" class="edge"><title>A5&#45;&gt;B1</title>
<path fill="none" stroke="black" d="M203.762,-262.799C201.557,-251.086 198.594,-235.342 196.078,-221.974"/>
<polygon fill="black" stroke="black" points="199.468,-221.065 194.178,-211.885 192.589,-222.36 199.468,-221.065"/>
</g>
<!-- B1&#45;&gt;B -->
<g id="edge9" class="edge"><title>B1&#45;&gt;B</title>
<path fill="none" stroke="black" d="M215.754,-178.388C238.773,-164.801 273.326,-144.405 299.321,-129.061"/>
<polygon fill="black" stroke="black" points="301.293,-131.961 308.126,-123.863 297.735,-125.932 301.293,-131.961"/>
<text text-anchor="middle" x="278" y="-146.8" font-family="Times,serif" font-size="14.00">no</text>
</g>
<!-- B3 -->
<g id="node8" class="node"><title>B3</title>
<ellipse fill="none" stroke="black" cx="133" cy="-107" rx="112.38" ry="18"/>
<text text-anchor="middle" x="133" y="-103.3" font-family="Times,serif" font-size="14.00">Get cache[ID][shape][name]</text>
</g>
<!-- B1&#45;&gt;B3 -->
<g id="edge8" class="edge"><title>B1&#45;&gt;B3</title>
<path fill="none" stroke="black" d="M180.091,-177.012C171.721,-164.746 160.004,-147.574 150.351,-133.429"/>
<polygon fill="black" stroke="black" points="153.184,-131.37 144.657,-125.083 147.402,-135.316 153.184,-131.37"/>
<text text-anchor="middle" x="174.5" y="-146.8" font-family="Times,serif" font-size="14.00">yes</text>
</g>
<!-- B4 -->
<g id="node9" class="node"><title>B4</title>
<ellipse fill="none" stroke="black" cx="170" cy="-34" rx="154.073" ry="18"/>
<text text-anchor="middle" x="170" y="-30.3" font-family="Times,serif" font-size="14.00">return object of cache[ID][shape][name]</text>
</g>
<!-- B3&#45;&gt;B4 -->
<g id="edge10" class="edge"><title>B3&#45;&gt;B4</title>
<path fill="none" stroke="black" d="M141.957,-88.8129C146.32,-80.4407 151.658,-70.1971 156.501,-60.9026"/>
<polygon fill="black" stroke="black" points="159.608,-62.5144 161.126,-52.0288 153.401,-59.2794 159.608,-62.5144"/>
</g>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.38.0 (20140413.2041)
-->
<!-- Title: G Pages: 1 -->
<svg width="390pt" height="1114pt"
viewBox="0.00 0.00 390.00 1114.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1110)">
<title>G</title>
<polygon fill="white" stroke="none" points="-4,4 -4,-1110 386,-1110 386,4 -4,4"/>
<g id="clust1" class="cluster"><title>cluster_A</title>
<polygon fill="none" stroke="black" stroke-dasharray="1,5" points="8,-8 8,-1029 374,-1029 374,-8 8,-8"/>
<text text-anchor="middle" x="324.5" y="-1013.8" font-family="Times,serif" font-size="14.00">Critical section</text>
</g>
<!-- A0 -->
<g id="node1" class="node"><title>A0</title>
<ellipse fill="none" stroke="black" cx="162" cy="-1088" rx="63.0888" ry="18"/>
<text text-anchor="middle" x="162" y="-1084.3" font-family="Times,serif" font-size="14.00">Get session ID</text>
</g>
<!-- A1 -->
<g id="node3" class="node"><title>A1</title>
<polygon fill="none" stroke="black" points="162,-998 59.9471,-980 162,-962 264.053,-980 162,-998"/>
<text text-anchor="middle" x="162" y="-976.3" font-family="Times,serif" font-size="14.00">cache[ID] exists?</text>
</g>
<!-- A0&#45;&gt;A1 -->
<g id="edge1" class="edge"><title>A0&#45;&gt;A1</title>
<path fill="none" stroke="black" d="M162,-1069.97C162,-1053.38 162,-1027.88 162,-1008.43"/>
<polygon fill="black" stroke="black" points="165.5,-1008.34 162,-998.341 158.5,-1008.34 165.5,-1008.34"/>
<text text-anchor="middle" x="169.5" y="-1040.8" font-family="Times,serif" font-size="14.00">ID</text>
</g>
<!-- A -->
<g id="node2" class="node"><title>A</title>
<ellipse fill="none" stroke="black" cx="150" cy="-413" rx="96.6831" ry="18"/>
<text text-anchor="middle" x="150" y="-409.3" font-family="Times,serif" font-size="14.00">Create cache[ID][shape]</text>
</g>
<!-- A5 -->
<g id="node7" class="node"><title>A5</title>
<ellipse fill="none" stroke="black" cx="150" cy="-340" rx="87.1846" ry="18"/>
<text text-anchor="middle" x="150" y="-336.3" font-family="Times,serif" font-size="14.00">Get cache[ID][shape]</text>
</g>
<!-- A&#45;&gt;A5 -->
<g id="edge7" class="edge"><title>A&#45;&gt;A5</title>
<path fill="none" stroke="black" d="M150,-394.813C150,-386.789 150,-377.047 150,-368.069"/>
<polygon fill="black" stroke="black" points="153.5,-368.029 150,-358.029 146.5,-368.029 153.5,-368.029"/>
</g>
<!-- A2 -->
<g id="node4" class="node"><title>A2</title>
<ellipse fill="none" stroke="black" cx="108" cy="-893" rx="71.4873" ry="18"/>
<text text-anchor="middle" x="108" y="-889.3" font-family="Times,serif" font-size="14.00">Create cache[ID]</text>
</g>
<!-- A1&#45;&gt;A2 -->
<g id="edge2" class="edge"><title>A1&#45;&gt;A2</title>
<path fill="none" stroke="black" d="M152.096,-963.41C144.353,-951.222 133.424,-934.019 124.383,-919.788"/>
<polygon fill="black" stroke="black" points="127.084,-917.513 118.768,-910.949 121.176,-921.267 127.084,-917.513"/>
<text text-anchor="middle" x="145" y="-932.8" font-family="Times,serif" font-size="14.00">no</text>
</g>
<!-- A3 -->
<g id="node5" class="node"><title>A3</title>
<ellipse fill="none" stroke="black" cx="159" cy="-820" rx="61.1893" ry="18"/>
<text text-anchor="middle" x="159" y="-816.3" font-family="Times,serif" font-size="14.00">Get cache[ID]</text>
</g>
<!-- A1&#45;&gt;A3 -->
<g id="edge3" class="edge"><title>A1&#45;&gt;A3</title>
<path fill="none" stroke="black" d="M170.725,-963.491C181.049,-943.164 195.899,-906.405 188,-875 185.56,-865.299 181.002,-855.442 176.21,-846.851"/>
<polygon fill="black" stroke="black" points="179.124,-844.903 171.008,-838.093 173.106,-848.478 179.124,-844.903"/>
<text text-anchor="middle" x="199.5" y="-889.3" font-family="Times,serif" font-size="14.00">yes</text>
</g>
<!-- A2&#45;&gt;A3 -->
<g id="edge4" class="edge"><title>A2&#45;&gt;A3</title>
<path fill="none" stroke="black" d="M120.086,-875.174C126.374,-866.42 134.183,-855.549 141.152,-845.847"/>
<polygon fill="black" stroke="black" points="144.009,-847.869 147,-837.705 138.324,-843.785 144.009,-847.869"/>
</g>
<!-- A4 -->
<g id="node6" class="node"><title>A4</title>
<polygon fill="none" stroke="black" points="159,-765 20.4142,-747 159,-729 297.586,-747 159,-765"/>
<text text-anchor="middle" x="159" y="-743.3" font-family="Times,serif" font-size="14.00">cache[ID][shape] exists?</text>
</g>
<!-- A3&#45;&gt;A4 -->
<g id="edge5" class="edge"><title>A3&#45;&gt;A4</title>
<path fill="none" stroke="black" d="M159,-801.813C159,-793.789 159,-784.047 159,-775.069"/>
<polygon fill="black" stroke="black" points="162.5,-775.029 159,-765.029 155.5,-775.029 162.5,-775.029"/>
</g>
<!-- A4&#45;&gt;A5 -->
<g id="edge8" class="edge"><title>A4&#45;&gt;A5</title>
<path fill="none" stroke="black" d="M113.164,-734.831C77.4895,-723.08 34,-700.628 34,-661 34,-661 34,-661 34,-412 34,-384.872 57.364,-367.794 83.1209,-357.208"/>
<polygon fill="black" stroke="black" points="84.5629,-360.405 92.6797,-353.595 82.0881,-353.857 84.5629,-360.405"/>
<text text-anchor="middle" x="43.5" y="-525.8" font-family="Times,serif" font-size="14.00">yes</text>
</g>
<!-- B -->
<g id="node8" class="node"><title>B</title>
<polygon fill="none" stroke="black" points="164,-678 52.5635,-660 164,-642 275.436,-660 164,-678"/>
<text text-anchor="middle" x="164" y="-656.3" font-family="Times,serif" font-size="14.00">Clear cache mode?</text>
</g>
<!-- A4&#45;&gt;B -->
<g id="edge6" class="edge"><title>A4&#45;&gt;B</title>
<path fill="none" stroke="black" d="M160.012,-728.799C160.701,-717.086 161.627,-701.342 162.413,-687.974"/>
<polygon fill="black" stroke="black" points="165.913,-688.074 163.007,-677.885 158.925,-687.663 165.913,-688.074"/>
<text text-anchor="middle" x="168" y="-699.8" font-family="Times,serif" font-size="14.00">no</text>
</g>
<!-- B1 -->
<g id="node9" class="node"><title>B1</title>
<polygon fill="none" stroke="black" points="191,-285 16.2201,-267 191,-249 365.78,-267 191,-285"/>
<text text-anchor="middle" x="191" y="-263.3" font-family="Times,serif" font-size="14.00">cache[ID][shape][name] exists?</text>
</g>
<!-- A5&#45;&gt;B1 -->
<g id="edge14" class="edge"><title>A5&#45;&gt;B1</title>
<path fill="none" stroke="black" d="M159.925,-321.813C164.954,-313.105 171.151,-302.372 176.686,-292.788"/>
<polygon fill="black" stroke="black" points="179.759,-294.466 181.728,-284.056 173.697,-290.965 179.759,-294.466"/>
</g>
<!-- B&#45;&gt;A -->
<g id="edge9" class="edge"><title>B&#45;&gt;A</title>
<path fill="none" stroke="black" d="M139.944,-645.826C121.358,-634.148 97.0088,-615.202 86,-591 73.845,-564.278 93.9104,-484.635 101,-468 105.76,-456.831 113.831,-446.452 122.064,-437.838"/>
<polygon fill="black" stroke="black" points="124.594,-440.259 129.261,-430.747 119.681,-435.272 124.594,-440.259"/>
<text text-anchor="middle" x="94" y="-525.8" font-family="Times,serif" font-size="14.00">no</text>
</g>
<!-- D -->
<g id="node13" class="node"><title>D</title>
<polygon fill="none" stroke="black" points="168,-591 95.273,-573 168,-555 240.727,-573 168,-591"/>
<text text-anchor="middle" x="168" y="-569.3" font-family="Times,serif" font-size="14.00">Cache full?</text>
</g>
<!-- B&#45;&gt;D -->
<g id="edge10" class="edge"><title>B&#45;&gt;D</title>
<path fill="none" stroke="black" d="M164.809,-641.799C165.361,-630.086 166.102,-614.342 166.731,-600.974"/>
<polygon fill="black" stroke="black" points="170.231,-601.039 167.205,-590.885 163.239,-600.71 170.231,-601.039"/>
<text text-anchor="middle" x="175.5" y="-612.8" font-family="Times,serif" font-size="14.00">yes</text>
</g>
<!-- B2 -->
<g id="node10" class="node"><title>B2</title>
<ellipse fill="none" stroke="black" cx="161" cy="-180" rx="122.379" ry="18"/>
<text text-anchor="middle" x="161" y="-176.3" font-family="Times,serif" font-size="14.00">Create cache[ID][shape][name]</text>
</g>
<!-- B1&#45;&gt;B2 -->
<g id="edge15" class="edge"><title>B1&#45;&gt;B2</title>
<path fill="none" stroke="black" d="M185.073,-249.207C180.909,-237.409 175.251,-221.378 170.467,-207.822"/>
<polygon fill="black" stroke="black" points="173.646,-206.314 167.017,-198.049 167.045,-208.644 173.646,-206.314"/>
<text text-anchor="middle" x="184" y="-219.8" font-family="Times,serif" font-size="14.00">no</text>
</g>
<!-- B3 -->
<g id="node11" class="node"><title>B3</title>
<ellipse fill="none" stroke="black" cx="180" cy="-107" rx="112.38" ry="18"/>
<text text-anchor="middle" x="180" y="-103.3" font-family="Times,serif" font-size="14.00">Get cache[ID][shape][name]</text>
</g>
<!-- B1&#45;&gt;B3 -->
<g id="edge17" class="edge"><title>B1&#45;&gt;B3</title>
<path fill="none" stroke="black" d="M222.618,-252.24C260.261,-233.804 315.291,-199.087 292,-162 281.926,-145.959 265.599,-134.57 248.489,-126.529"/>
<polygon fill="black" stroke="black" points="249.506,-123.155 238.938,-122.398 246.727,-129.58 249.506,-123.155"/>
<text text-anchor="middle" x="306.5" y="-176.3" font-family="Times,serif" font-size="14.00">yes</text>
</g>
<!-- B2&#45;&gt;B3 -->
<g id="edge16" class="edge"><title>B2&#45;&gt;B3</title>
<path fill="none" stroke="black" d="M165.599,-161.813C167.77,-153.702 170.41,-143.836 172.834,-134.777"/>
<polygon fill="black" stroke="black" points="176.239,-135.594 175.443,-125.029 169.477,-133.784 176.239,-135.594"/>
</g>
<!-- B4 -->
<g id="node12" class="node"><title>B4</title>
<ellipse fill="none" stroke="black" cx="180" cy="-34" rx="147.574" ry="18"/>
<text text-anchor="middle" x="180" y="-30.3" font-family="Times,serif" font-size="14.00">assign data to cache[ID][shape][name]</text>
</g>
<!-- B3&#45;&gt;B4 -->
<g id="edge18" class="edge"><title>B3&#45;&gt;B4</title>
<path fill="none" stroke="black" d="M180,-88.8129C180,-80.7895 180,-71.0475 180,-62.0691"/>
<polygon fill="black" stroke="black" points="183.5,-62.0288 180,-52.0288 176.5,-62.0289 183.5,-62.0288"/>
</g>
<!-- D&#45;&gt;A -->
<g id="edge11" class="edge"><title>D&#45;&gt;A</title>
<path fill="none" stroke="black" d="M151.374,-558.956C137.06,-546.577 117.419,-526.55 109,-504 103.404,-489.011 103.896,-483.164 109,-468 112.586,-457.348 119.2,-447.129 126.086,-438.503"/>
<polygon fill="black" stroke="black" points="128.862,-440.641 132.68,-430.758 123.532,-436.103 128.862,-440.641"/>
<text text-anchor="middle" x="116" y="-482.3" font-family="Times,serif" font-size="14.00">no</text>
</g>
<!-- F -->
<g id="node14" class="node"><title>F</title>
<ellipse fill="none" stroke="black" cx="249" cy="-486" rx="116.979" ry="18"/>
<text text-anchor="middle" x="249" y="-482.3" font-family="Times,serif" font-size="14.00">Erase cache[ID][oldest shape]</text>
</g>
<!-- D&#45;&gt;F -->
<g id="edge12" class="edge"><title>D&#45;&gt;F</title>
<path fill="none" stroke="black" d="M181.376,-557.964C193.39,-545.356 211.3,-526.562 225.67,-511.482"/>
<polygon fill="black" stroke="black" points="228.447,-513.641 232.812,-503.987 223.38,-508.812 228.447,-513.641"/>
<text text-anchor="middle" x="222.5" y="-525.8" font-family="Times,serif" font-size="14.00">yes</text>
</g>
<!-- F&#45;&gt;A -->
<g id="edge13" class="edge"><title>F&#45;&gt;A</title>
<path fill="none" stroke="black" d="M225.789,-468.354C212.507,-458.829 195.669,-446.753 181.239,-436.404"/>
<polygon fill="black" stroke="black" points="183.232,-433.526 173.066,-430.542 179.152,-439.214 183.232,-433.526"/>
</g>
</g>
</svg>
MKL-DNN Data Caching
--------------------------------------
.. toctree::
:maxdepth: 1
caching.md
digraph Q {
node[shape=record]
subgraph cluster_bm {
label="BlobMap";
subgraph cluster_sm2 {
label="ShapeMap of Session ID=1";
subgraph cluster_km {
label="KeyMap of X shape";
G[label="..."];
}
}
subgraph cluster_sm {
label="ShapeMap of Session ID=0";
subgraph cluster_km {
label="KeyMap of X shape";
C[label="..."];
B[label="second object of ShapeX"];
A[label="first object of ShapeX"];
}
subgraph cluster_km2 {
label="KeyMap of Y shape";
F[label="..."];
E[label="second object of ShapeY"];
D[label="first object of ShapeY"];
}
}
}
}
// For DefaultSessionID Key is having TID inside, for anything else eg. clearing mode , named session ID. no TID in key. ParallelExecutor is workign in default mode
//
//
digraph G {
node[weight=100]
// Session ID
A0[label="Get session ID"]
subgraph cluster_A {
label="Critical section"
style=dotted
labeljust="r"
A1[shape=diamond,label="cache[ID] exists?"]
A3[label="Get cache[ID]"]
A4[shape=diamond,label="cache[ID][shape] exists?"]
A5[label="Get cache[ID][shape]"]
B[label="return null object"]
B1[shape=diamond,label="cache[ID][shape][name] exists?"]
B3[label="Get cache[ID][shape][name]"]
B4[label="return object of cache[ID][shape][name]"]
}
A0 -> A1 [label="ID"]
A1 -> B [label="no"]
A1 -> A3 [label="yes"]
A3 -> A4
A4 -> B [label="no"]
A4 -> A5 [label="yes"]
A5 -> B1
B1 -> B3 [label="yes"]
B1 -> B [label="no"]
B3 -> B4
}
digraph G {
// Session ID
A0[label="Get session ID"]
subgraph cluster_A {
label="Critical section"
style=dotted
labeljust="r"
A[label="Create cache[ID][shape]"]
A1[shape=diamond,label="cache[ID] exists?"]
A2[label="Create cache[ID]"]
A3[label="Get cache[ID]"]
A4[shape=diamond,label="cache[ID][shape] exists?"]
A5[label="Get cache[ID][shape]"]
B[shape=diamond,label="Clear cache mode?"]
B1[shape=diamond,label="cache[ID][shape][name] exists?"]
B2[label="Create cache[ID][shape][name]"]
B3[label="Get cache[ID][shape][name]"]
B4[label="assign data to cache[ID][shape][name]"]
D[shape=diamond,label="Cache full?"]
F[label="Erase cache[ID][oldest shape]"]
}
A0 -> A1 [label="ID"]
A1 -> A2 [label="no"]
A1 -> A3 [label="yes"]
A2 -> A3
A3 -> A4
A4 -> B [label="no"]
A -> A5
A4 -> A5 [label="yes"]
// Shape
// Get blob
B -> A [label="no"]
B -> D [label="yes"]
D -> A [label="no"]
D -> F [label="yes"]
F -> A
A5 -> B1
B1 -> B2 [label="no"]
B2 -> B3
B1 -> B3 [label="yes"]
B3 -> B4
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册